0026636: BRepOffsetAPI_ThruSections algorithm crashes on two inconsistent wires
[occt.git] / samples / qt / VoxelDemo / src / VoxelClient_VisDrawer.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include "VoxelClient_VisDrawer.h"
15
16 #include <OpenGl_GlCore11.hxx>
17
18 #include <ElSLib.hxx>
19 #include <gp_Dir.hxx>
20 #include <Geom_Plane.hxx>
21 #include <gce_MakePln.hxx>
22 #include <Quantity_Color.hxx>
23 #include <Aspect_TypeOfLine.hxx>
24 #include <Graphic3d_CUserDraw.hxx>
25
26 #include <InterfaceGraphic_telem.hxx>
27 #include <OpenGl_Element.hxx>
28 #include <OpenGl_GraphicDriver.hxx>
29 #include <OpenGl_NamedStatus.hxx>
30 #include <OpenGl_Workspace.hxx>
31
32 /**************************************************************************/
33
34 class VoxelClient_VisDrawer::VisElement : public OpenGl_Element
35 {
36 public:
37
38   VisElement (Voxel_VisData*);
39   virtual ~VisElement();
40
41   void EvaluateBounds (Graphic3d_BndBox4f& theMinMax);
42
43   void Render (const Handle(OpenGl_Workspace) &theWorkspace) const;
44
45   virtual void Release (OpenGl_Context* theContext)
46   {
47     //
48   }
49
50 private:
51
52   VoxelClient_VisDrawer* myHandler;
53
54 public:
55
56   DEFINE_STANDARD_ALLOC
57
58 };
59
60 //=======================================================================
61 //function : VisElement
62 //purpose  : Constructor
63 //=======================================================================
64
65 VoxelClient_VisDrawer::VisElement::VisElement (Voxel_VisData* theData)
66 {
67   myHandler = new VoxelClient_VisDrawer (theData);
68 }
69
70 //=======================================================================
71 //function : ~VisElement
72 //purpose  : Destructor
73 //=======================================================================
74
75 VoxelClient_VisDrawer::VisElement::~VisElement ()
76 {
77   delete myHandler;
78 }
79
80 //=======================================================================
81 //function : EvaluateBounds
82 //purpose  :
83 //=======================================================================
84
85 void VoxelClient_VisDrawer::VisElement::EvaluateBounds
86   (Graphic3d_BndBox4f& theMinMax)
87 {
88   myHandler->EvalMinMax (theMinMax);
89 }
90
91 //=======================================================================
92 //function : Render
93 //purpose  : display element
94 //=======================================================================
95
96 void VoxelClient_VisDrawer::VisElement::Render
97   (const Handle (OpenGl_Workspace) &theWorkspace) const
98 {
99   const Standard_Boolean aHl = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT);
100   myHandler->Display (aHl);
101 }
102
103 //=======================================================================
104 //function : VisDrawerCallBack
105 //purpose  : visdrawer element create callback, adds an element to graphic
106 //           driver's structure
107 //=======================================================================
108
109 static OpenGl_Element* VisDrawerCallBack (const Graphic3d_CUserDraw* theUserDraw)
110 {
111   if (theUserDraw == 0)
112     return 0;
113
114   // Retrieve the user structure
115   Voxel_VisData* aUserData = (Voxel_VisData*) (theUserDraw->Data);
116
117   if (aUserData == 0)
118     return 0;
119
120   VoxelClient_VisDrawer::VisElement *aElem = 
121     new VoxelClient_VisDrawer::VisElement (aUserData);
122
123   if (theUserDraw->Bounds != 0)
124     aElem->EvaluateBounds (*(theUserDraw->Bounds));
125
126   return aElem;
127 }
128
129 /**************************************************************************/
130 void VoxelClient_VisDrawer::Init (Handle(OpenGl_GraphicDriver)& theDriver)
131 {
132     static Standard_Boolean isInitializeded(Standard_False);
133
134     if (!isInitializeded)
135     {
136         isInitializeded = Standard_True;
137         theDriver->UserDrawCallback() = VisDrawerCallBack;
138     }
139 }
140
141 /**************************************************************************/
142 VoxelClient_VisDrawer::VoxelClient_VisDrawer(Voxel_VisData * theData):myData(theData)
143 {
144
145 }
146
147 /**************************************************************************/
148 VoxelClient_VisDrawer::~VoxelClient_VisDrawer()
149 {
150     if (myData)
151     {
152         // Because a pointer to the data is copied, 
153         // it is possible to make an attempt to delete GL lists for
154         // a structure, which is already deleted.
155         // Such a situation may happen on close of the application.
156         // Therefore, this try / catch is used.
157
158         try
159         {
160             Standard_Integer idir;
161
162             // Points
163
164             // BoolDS
165             if (myData->myDisplay.myBoolPointsList > 0)
166             {
167                 glDeleteLists(myData->myDisplay.myBoolPointsList, 1);
168                 myData->myDisplay.myBoolPointsList = -1;
169             }
170             for (idir = Xminus; idir <= Zplus; idir++)
171             {
172                 if (myData->myDisplay.myBoolNearestPointsList[idir] > 0)
173                 {
174                     glDeleteLists(myData->myDisplay.myBoolNearestPointsList[idir], 1);
175                     myData->myDisplay.myBoolNearestPointsList[idir] = -1;
176                 }
177             }
178
179             // ColorDS
180             if (myData->myDisplay.myColorPointsList > 0)
181             {
182                 glDeleteLists(myData->myDisplay.myColorPointsList, 1);
183                 myData->myDisplay.myColorPointsList = -1;
184             }
185             for (idir = Xminus; idir <= Zplus; idir++)
186             {
187                 if (myData->myDisplay.myColorNearestPointsList[idir] > 0)
188                 {
189                     glDeleteLists(myData->myDisplay.myColorNearestPointsList[idir], 1);
190                     myData->myDisplay.myColorNearestPointsList[idir] = -1;
191                 }
192             }
193
194             // ROctBoolDS
195             if (myData->myDisplay.myROctBoolPointsList > 0)
196             {
197                 glDeleteLists(myData->myDisplay.myROctBoolPointsList, 1);
198                 myData->myDisplay.myROctBoolPointsList = -1;
199             }
200             for (idir = Xminus; idir <= Zplus; idir++)
201             {
202                 if (myData->myDisplay.myROctBoolNearestPointsList[idir] > 0)
203                 {
204                     glDeleteLists(myData->myDisplay.myROctBoolNearestPointsList[idir], 1);
205                     myData->myDisplay.myROctBoolNearestPointsList[idir] = -1;
206                 }
207             }
208
209             // Triangulation
210             if (myData->myDisplay.myTriangulationList > 0)
211             {
212                 glDeleteLists(myData->myDisplay.myTriangulationList, 1);
213                 myData->myDisplay.myTriangulationList = -1;
214             }
215         }
216         catch (...)
217         {
218
219         }
220     }
221 }
222
223 /**************************************************************************/
224 void VoxelClient_VisDrawer::EvalMinMax(Graphic3d_BndBox4f& theMinMax) const
225 {
226     Graphic3d_Vec4 aMinPt (FLT_MAX, FLT_MAX, FLT_MAX, 1.0f);
227     Graphic3d_Vec4 aMaxPt (-FLT_MAX, -FLT_MAX, -FLT_MAX, 1.0f);
228
229     if(!myData)
230         return;
231     if(myData->myBoolVoxels)
232     {
233         Graphic3d_Vec4 aBoolVoxelsMin (RealToShortReal (myData->myBoolVoxels->GetX()),
234                                        RealToShortReal (myData->myBoolVoxels->GetY()),
235                                        RealToShortReal (myData->myBoolVoxels->GetZ()),
236                                        1.0f);
237         Graphic3d_Vec4 aBoolVoxelsMax (
238           RealToShortReal (myData->myBoolVoxels->GetX() + myData->myBoolVoxels->GetXLen()),
239           RealToShortReal (myData->myBoolVoxels->GetY() + myData->myBoolVoxels->GetYLen()),
240           RealToShortReal (myData->myBoolVoxels->GetZ() + myData->myBoolVoxels->GetZLen()),
241           1.0f);
242
243         aMinPt = aMinPt.cwiseMin (aBoolVoxelsMin);
244         aMaxPt = aMaxPt.cwiseMax (aBoolVoxelsMax);
245     }
246     if(myData->myColorVoxels)
247     {
248         Graphic3d_Vec4 aColorVoxelsMin (RealToShortReal (myData->myColorVoxels->GetX()),
249                                         RealToShortReal (myData->myColorVoxels->GetY()),
250                                         RealToShortReal (myData->myColorVoxels->GetZ()),
251                                         1.0f);
252         Graphic3d_Vec4 aColorVoxelsMax (
253           RealToShortReal (myData->myColorVoxels->GetX() + myData->myColorVoxels->GetXLen()),
254           RealToShortReal (myData->myColorVoxels->GetY() + myData->myColorVoxels->GetYLen()),
255           RealToShortReal (myData->myColorVoxels->GetZ() + myData->myColorVoxels->GetZLen()),
256           1.0f);
257
258         aMinPt = aMinPt.cwiseMin (aColorVoxelsMin);
259         aMaxPt = aMaxPt.cwiseMax (aColorVoxelsMax);
260     }
261     if(myData->myROctBoolVoxels)
262     {
263         Graphic3d_Vec4 aROctBoolVoxelsMin (RealToShortReal (myData->myROctBoolVoxels->GetX()),
264                                            RealToShortReal (myData->myROctBoolVoxels->GetY()),
265                                            RealToShortReal (myData->myROctBoolVoxels->GetZ()),
266                                            1.0f);
267         Graphic3d_Vec4 aROctBoolVoxelsMax (
268           RealToShortReal (myData->myROctBoolVoxels->GetX() + myData->myROctBoolVoxels->GetXLen()),
269           RealToShortReal (myData->myROctBoolVoxels->GetY() + myData->myROctBoolVoxels->GetYLen()),
270           RealToShortReal (myData->myROctBoolVoxels->GetZ() + myData->myROctBoolVoxels->GetZLen()),
271           1.0f);
272
273         aMinPt = aMinPt.cwiseMin (aROctBoolVoxelsMin);
274         aMaxPt = aMaxPt.cwiseMax (aROctBoolVoxelsMax);
275     }
276     if (!myData->myTriangulation.IsNull())
277     {
278         Standard_Real x, y, z;
279         const TColgp_Array1OfPnt& nodes = myData->myTriangulation->Nodes();
280         Standard_Integer inode = nodes.Lower(), nb_nodes = nodes.Upper();
281         for (; inode <= nb_nodes; inode++)
282         {
283             nodes.Value(inode).Coord(x, y, z);
284             Graphic3d_Vec4 aNodeCoord (RealToShortReal (x),
285                                        RealToShortReal (y),
286                                        RealToShortReal (z),
287                                        1.0f);
288             aMinPt = aMinPt.cwiseMin (aNodeCoord);
289             aMaxPt = aMaxPt.cwiseMax (aNodeCoord);
290         }
291     }
292
293     if (theMinMax.IsValid())
294     {
295       theMinMax.CornerMin() = aMinPt;
296       theMinMax.CornerMax() = aMaxPt;
297     }
298     else
299     {
300       theMinMax.Add (aMinPt);
301       theMinMax.Add (aMaxPt);
302     }
303 }
304
305 /**************************************************************************/
306 void VoxelClient_VisDrawer::Display(const Standard_Boolean theHighlight)
307 {
308     if (!myData)
309         return;
310     if (myData->myBoolVoxels)
311         DisplayVoxels(theHighlight);
312     if (myData->myColorVoxels)
313         DisplayVoxels(theHighlight);
314     if (myData->myROctBoolVoxels)
315         DisplayVoxels(theHighlight);
316     if (!myData->myTriangulation.IsNull())
317         DisplayTriangulation(theHighlight);
318 }
319
320 // Some static method to define Open GL visual attributes
321 // COlor
322 static void setColor(const Quantity_Color& color, const Standard_Boolean highlight)
323 {
324     static Quantity_Color highlight_color(Quantity_NOC_BLUE1);
325                 if(highlight)
326         glColor3f((GLfloat)highlight_color.Red(), (GLfloat)highlight_color.Green(), (GLfloat)highlight_color.Blue());
327     else
328         glColor3d(color.Red(), color.Green(), color.Blue());
329 }
330
331 // Type of Line
332 static void setTypeOfLine(const Aspect_TypeOfLine type)
333 {
334     if(type == Aspect_TOL_SOLID)
335     {
336         glDisable(GL_LINE_STIPPLE);
337     }
338     else
339     {
340         glEnable(GL_LINE_STIPPLE);
341         if(type == Aspect_TOL_DOT)
342             glLineStipple(1, 0xCCCC);
343         else if(type == Aspect_TOL_DASH)
344             glLineStipple(1, 0xFFC0);
345         else if(type == Aspect_TOL_DOTDASH)
346             glLineStipple(1, 0xFF18);
347     }
348 }
349
350 // Width of Line
351 static void setWidthOfLine(const Standard_Integer width)
352 {
353     glLineWidth((Standard_ShortReal) width);
354 }
355
356 // Normal of the view
357 static void getNormal(gp_Dir& normal) 
358 {
359         Standard_Real x, y, z;
360         GLint viewport[4];
361         GLdouble model_matrix[16], proj_matrix[16];
362
363         glGetDoublev(GL_MODELVIEW_MATRIX,  model_matrix);
364         glGetDoublev(GL_PROJECTION_MATRIX, proj_matrix);
365         glGetIntegerv(GL_VIEWPORT, viewport);
366
367         gluUnProject(viewport[0], viewport[1], 0., model_matrix, proj_matrix, viewport, &x, &y, &z);
368         gp_Pnt p1(x, y, z);
369         gluUnProject(viewport[0] + viewport[2], viewport[1], 0., model_matrix, proj_matrix, viewport, &x, &y, &z);
370         gp_Pnt p2(x, y, z);
371         gluUnProject(viewport[0], viewport[1] + viewport[3], 0., model_matrix, proj_matrix, viewport, &x, &y, &z);
372         gp_Pnt p3(x, y, z);
373
374         gce_MakePln mkNormal(p1, p2, p3);
375         if (mkNormal.IsDone()) 
376         {
377                 const gp_Pln& normal_plane = mkNormal.Value();
378                 normal = normal_plane.Axis().Direction();
379         }
380         else
381         {
382                 normal = gp::DZ();
383         }
384 }
385
386 // Normal 2 VoxelDirection converter
387 static VoxelDirection getVoxelDirection(const gp_Dir& viewnormal)
388 {
389     VoxelDirection vdir;
390         Standard_Real fabsviewnormalx = fabs(viewnormal.X());
391         Standard_Real fabsviewnormaly = fabs(viewnormal.Y());
392         Standard_Real fabsviewnormalz = fabs(viewnormal.Z());
393         if (fabsviewnormalx >= fabsviewnormaly &&
394                 fabsviewnormalx >= fabsviewnormalz)
395         {
396                 if (viewnormal.X() > 0)
397                         vdir = Xminus;
398                 else
399                         vdir = Xplus;
400         }
401         else if (fabsviewnormaly >= fabsviewnormalx &&
402                          fabsviewnormaly >= fabsviewnormalz)
403         {
404                 if (viewnormal.Y() > 0)
405                         vdir = Yminus;
406                 else
407                         vdir = Yplus;
408         }
409         else if (fabsviewnormalz >= fabsviewnormalx &&
410                          fabsviewnormalz >= fabsviewnormaly)
411         {
412                 if (viewnormal.Z() > 0)
413                         vdir = Zminus;
414                 else
415                         vdir = Zplus;
416         }
417     return vdir;
418 }
419
420 // Normal 2 VoxelDirection 3 converter
421 static void getVoxel3Directions(const gp_Dir& viewnormal,
422                                 VoxelDirection& vdir1,
423                                 VoxelDirection& vdir2,
424                                 VoxelDirection& vdir3)
425 {
426     Standard_Boolean vdir1_set = Standard_False, vdir2_set = Standard_False, vdir3_set = Standard_False;
427
428     // Test X minus
429     Standard_Real dot = viewnormal.Dot(-gp::DX());
430     if (dot >= 0.0)
431     {
432         if (!vdir1_set)
433         {
434             vdir1 = Xminus;
435             vdir1_set = Standard_True;
436         }
437         else if (!vdir2_set)
438         {
439             vdir2 = Xminus;
440             vdir2_set = Standard_True;
441         }
442         else if (!vdir3_set)
443         {
444             vdir3 = Xminus;
445             vdir3_set = Standard_True;
446         }
447     }
448
449     // Test X plus
450     dot = viewnormal.Dot(gp::DX());
451     if (dot >= 0.0)
452     {
453         if (!vdir1_set)
454         {
455             vdir1 = Xplus;
456             vdir1_set = Standard_True;
457         }
458         else if (!vdir2_set)
459         {
460             vdir2 = Xplus;
461             vdir2_set = Standard_True;
462         }
463         else if (!vdir3_set)
464         {
465             vdir3 = Xplus;
466             vdir3_set = Standard_True;
467         }
468     }
469
470     // Test Y minus
471     dot = viewnormal.Dot(-gp::DY());
472     if (dot >= 0.0)
473     {
474         if (!vdir1_set)
475         {
476             vdir1 = Yminus;
477             vdir1_set = Standard_True;
478         }
479         else if (!vdir2_set)
480         {
481             vdir2 = Yminus;
482             vdir2_set = Standard_True;
483         }
484         else if (!vdir3_set)
485         {
486             vdir3 = Yminus;
487             vdir3_set = Standard_True;
488         }
489     }
490
491     // Test Y plus
492     dot = viewnormal.Dot(gp::DY());
493     if (dot >= 0.0)
494     {
495         if (!vdir1_set)
496         {
497             vdir1 = Yplus;
498             vdir1_set = Standard_True;
499         }
500         else if (!vdir2_set)
501         {
502             vdir2 = Yplus;
503             vdir2_set = Standard_True;
504         }
505         else if (!vdir3_set)
506         {
507             vdir3 = Yplus;
508             vdir3_set = Standard_True;
509         }
510     }
511
512     // Test Z minus
513     dot = viewnormal.Dot(-gp::DZ());
514     if (dot >= 0.0)
515     {
516         if (!vdir1_set)
517         {
518             vdir1 = Zminus;
519             vdir1_set = Standard_True;
520         }
521         else if (!vdir2_set)
522         {
523             vdir2 = Zminus;
524             vdir2_set = Standard_True;
525         }
526         else if (!vdir3_set)
527         {
528             vdir3 = Zminus;
529             vdir3_set = Standard_True;
530         }
531     }
532
533     // Test Y plus
534     dot = viewnormal.Dot(gp::DZ());
535     if (dot >= 0.0)
536     {
537         if (!vdir1_set)
538         {
539             vdir1 = Zplus;
540             vdir1_set = Standard_True;
541         }
542         else if (!vdir2_set)
543         {
544             vdir2 = Zplus;
545             vdir2_set = Standard_True;
546         }
547         else if (!vdir3_set)
548         {
549             vdir3 = Zplus;
550             vdir3_set = Standard_True;
551         }
552     }
553 }
554
555 static Standard_Boolean CheckSize(Voxel_DS* voxels, 
556                       const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz, 
557                       const Standard_Real xmin, const Standard_Real xmax,
558                       const Standard_Real ymin, const Standard_Real ymax,
559                       const Standard_Real zmin, const Standard_Real zmax,
560                       Standard_Real& xc, Standard_Real& yc, Standard_Real& zc)
561 {
562     voxels->GetCenter(ix, iy, iz, xc, yc, zc);
563     if (xc < xmin || xc > xmax)
564         return Standard_False;
565     if (yc < ymin || yc > ymax)
566         return Standard_False;
567     if (zc < zmin || zc > zmax)
568         return Standard_False;
569     return Standard_True;
570 }
571
572 static Standard_Boolean CheckSize(Voxel_ROctBoolDS* voxels, 
573                       const Standard_Integer ix, const Standard_Integer iy, const Standard_Integer iz, 
574                       const Standard_Integer i, const Standard_Integer j,
575                       const Standard_Real xmin, const Standard_Real xmax,
576                       const Standard_Real ymin, const Standard_Real ymax,
577                       const Standard_Real zmin, const Standard_Real zmax,
578                       Standard_Real& xc, Standard_Real& yc, Standard_Real& zc)
579 {
580     if (j == -1)
581         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
582     else
583         voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
584     if (xc < xmin || xc > xmax)
585         return Standard_False;
586     if (yc < ymin || yc > ymax)
587         return Standard_False;
588     if (zc < zmin || zc > zmax)
589         return Standard_False;
590     return Standard_True;
591 }
592
593 static void drawBoolPoints(const VoxelDirection vdir, const Standard_Boolean nearest,
594                            Voxel_BoolDS* voxels,
595                            const Standard_Real xmin, const Standard_Real xmax,
596                            const Standard_Real ymin, const Standard_Real ymax,
597                            const Standard_Real zmin, const Standard_Real zmax)
598 {
599         Standard_Real xc, yc, zc;
600         Standard_Integer ix = 0, nbx = voxels->GetNbX();
601         Standard_Integer iy = 0, nby = voxels->GetNbY();
602         Standard_Integer iz = 0, nbz = voxels->GetNbZ();
603
604     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
605                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
606                        zmin <= DBL_MAX && zmax >= DBL_MAX);
607     check_size = !check_size;
608
609     glBegin(GL_POINTS);
610     switch (vdir)
611         {
612                 case Xminus:
613                 {
614                         for (iy = 0; iy < nby; iy++)
615                         {
616                                 for (iz = 0; iz < nbz; iz++)
617                                 {
618                                         for (ix = 0; ix < nbx; ix++)
619                                         {
620                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
621                             continue;
622                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
623                                                 if (value)
624                                                 {
625                             if (!check_size)
626                                                             voxels->GetCenter(ix, iy, iz, xc, yc, zc);
627                                                         glVertex3d(xc, yc, zc);
628                             if (nearest)
629                                 break;
630                                                 }
631                                         }
632                                 }
633                         }
634                         break;
635                 }
636                 case Xplus:
637                 {
638                         for (iy = 0; iy < nby; iy++)
639                         {
640                                 for (iz = 0; iz < nbz; iz++)
641                                 {
642                                         for (ix = nbx - 1; ix >= 0; ix--)
643                                         {
644                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
645                             continue;
646                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
647                                                 if (value)
648                                                 {
649                             if (!check_size)
650                                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
651                                                         glVertex3d(xc, yc, zc);
652                             if (nearest)
653                                 break;
654                                                 }
655                                         }
656                                 }
657                         }
658                         break;
659                 }
660                 case Yminus:
661                 {
662                         for (ix = 0; ix < nbx; ix++)
663                         {
664                                 for (iz = 0; iz < nbz; iz++)
665                                 {
666                                         for (iy = 0; iy < nby; iy++)
667                                         {
668                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
669                             continue;
670                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
671                                                 if (value)
672                                                 {
673                             if (!check_size)
674                                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
675                                                         glVertex3d(xc, yc, zc);
676                             if (nearest)
677                                 break;
678                                                 }
679                                         }
680                                 }
681                         }
682                         break;
683                 }
684                 case Yplus:
685                 {
686                         for (ix = 0; ix < nbx; ix++)
687                         {
688                                 for (iz = 0; iz < nbz; iz++)
689                                 {
690                                         for (iy = nby - 1; iy >= 0; iy--)
691                                         {
692                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
693                             continue;
694                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
695                                                 if (value)
696                                                 {
697                             if (!check_size)
698                                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
699                                                         glVertex3d(xc, yc, zc);
700                             if (nearest)
701                                 break;
702                                                 }
703                                         }
704                                 }
705                         }
706                         break;
707                 }
708                 case Zminus:
709                 {
710                         for (ix = 0; ix < nbx; ix++)
711                         {
712                                 for (iy = 0; iy < nby; iy++)
713                                 {
714                                         for (iz = 0; iz < nbz; iz++)
715                                         {
716                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
717                             continue;
718                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
719                                                 if (value)
720                                                 {
721                             if (!check_size)
722                                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
723                                                         glVertex3d(xc, yc, zc);
724                             if (nearest)
725                                 break;
726                                                 }
727                                         }
728                                 }
729                         }
730                         break;
731                 }
732                 case Zplus:
733                 {
734                         for (ix = 0; ix < nbx; ix++)
735                         {
736                                 for (iy = 0; iy < nby; iy++)
737                                 {
738                                         for (iz = nbz - 1; iz >= 0; iz--)
739                                         {
740                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
741                             continue;
742                                                 Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
743                                                 if (value)
744                                                 {
745                             if (!check_size)
746                                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
747                                                         glVertex3d(xc, yc, zc);
748                             if (nearest)
749                                 break;
750                                                 }
751                                         }
752                                 }
753                         }
754                         break;
755                 }
756         }
757     glEnd();
758 }
759
760 static void drawROctBoolPoints(const VoxelDirection vdir, const Standard_Boolean nearest,
761                                Voxel_ROctBoolDS* voxels,
762                                const Standard_Real xmin, const Standard_Real xmax,
763                                const Standard_Real ymin, const Standard_Real ymax,
764                                const Standard_Real zmin, const Standard_Real zmax)
765 {
766         Standard_Real xc, yc, zc;
767         Standard_Integer ix = 0, nbx = voxels->GetNbX();
768         Standard_Integer iy = 0, nby = voxels->GetNbY();
769         Standard_Integer iz = 0, nbz = voxels->GetNbZ();
770     Standard_Integer i, j;
771
772     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
773                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
774                        zmin <= DBL_MAX && zmax >= DBL_MAX);
775     check_size = !check_size;
776
777     glBegin(GL_POINTS);
778     switch (vdir)
779         {
780                 case Xminus:
781                 {
782                         for (iy = 0; iy < nby; iy++)
783                         {
784                                 for (iz = 0; iz < nbz; iz++)
785                                 {
786                                         for (ix = 0; ix < nbx; ix++)
787                                         {
788                         switch (voxels->Deepness(ix, iy, iz))
789                         {
790                             case 0:
791                             {
792                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
793                                     continue;
794                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
795                                                         if (value)
796                                                         {
797                                     if (!check_size)
798                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
799                                                                 glVertex3d(xc, yc, zc);
800                                     if (nearest)
801                                         break;
802                                                         }
803                                 break;
804                             }
805                             case 1:
806                             {
807                                 for (i = 0; i < 8; i++)
808                                 {
809                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
810                                         continue;
811                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
812                                                             if (value)
813                                                             {
814                                         if (!check_size)
815                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
816                                                                     glVertex3d(xc, yc, zc);
817                                         if (nearest)
818                                             break;
819                                                             }
820                                 }
821                                 break;
822                             }
823                             case 2:
824                             {
825                                 for (i = 0; i < 8; i++)
826                                 {
827                                     for (j = 0; j < 8; j++)
828                                     {
829                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
830                                             continue;
831                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
832                                                                 if (value)
833                                                                 {
834                                             if (!check_size)
835                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
836                                                                         glVertex3d(xc, yc, zc);
837                                             if (nearest)
838                                                 break;
839                                                                 }
840                                     }
841                                 }
842                                 break;
843                             }
844                         }
845                                         }
846                                 }
847                         }
848                         break;
849                 }
850                 case Xplus:
851                 {
852                         for (iy = 0; iy < nby; iy++)
853                         {
854                                 for (iz = 0; iz < nbz; iz++)
855                                 {
856                                         for (ix = nbx - 1; ix >= 0; ix--)
857                                         {
858                         switch (voxels->Deepness(ix, iy, iz))
859                         {
860                             case 0:
861                             {
862                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
863                                     continue;
864                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
865                                                         if (value)
866                                                         {
867                                     if (!check_size)
868                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
869                                                                 glVertex3d(xc, yc, zc);
870                                     if (nearest)
871                                         break;
872                                                         }
873                                 break;
874                             }
875                             case 1:
876                             {
877                                 for (i = 0; i < 8; i++)
878                                 {
879                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
880                                         continue;
881                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
882                                                             if (value)
883                                                             {
884                                         if (!check_size)
885                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
886                                                                     glVertex3d(xc, yc, zc);
887                                         if (nearest)
888                                             break;
889                                                             }
890                                 }
891                                 break;
892                             }
893                             case 2:
894                             {
895                                 for (i = 0; i < 8; i++)
896                                 {
897                                     for (j = 0; j < 8; j++)
898                                     {
899                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
900                                             continue;
901                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
902                                                                 if (value)
903                                                                 {
904                                             if (!check_size)
905                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
906                                                                         glVertex3d(xc, yc, zc);
907                                             if (nearest)
908                                                 break;
909                                                                 }
910                                     }
911                                 }
912                                 break;
913                             }
914                         }
915                                         }
916                                 }
917                         }
918                         break;
919                 }
920                 case Yminus:
921                 {
922                         for (ix = 0; ix < nbx; ix++)
923                         {
924                                 for (iz = 0; iz < nbz; iz++)
925                                 {
926                                         for (iy = 0; iy < nby; iy++)
927                                         {
928                         switch (voxels->Deepness(ix, iy, iz))
929                         {
930                             case 0:
931                             {
932                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
933                                     continue;
934                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
935                                                         if (value)
936                                                         {
937                                     if (!check_size)
938                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
939                                                                 glVertex3d(xc, yc, zc);
940                                     if (nearest)
941                                         break;
942                                                         }
943                                 break;
944                             }
945                             case 1:
946                             {
947                                 for (i = 0; i < 8; i++)
948                                 {
949                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
950                                         continue;
951                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
952                                                             if (value)
953                                                             {
954                                         if (!check_size)
955                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
956                                                                     glVertex3d(xc, yc, zc);
957                                         if (nearest)
958                                             break;
959                                                             }
960                                 }
961                                 break;
962                             }
963                             case 2:
964                             {
965                                 for (i = 0; i < 8; i++)
966                                 {
967                                     for (j = 0; j < 8; j++)
968                                     {
969                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
970                                             continue;
971                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
972                                                                 if (value)
973                                                                 {
974                                             if (!check_size)
975                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
976                                                                         glVertex3d(xc, yc, zc);
977                                             if (nearest)
978                                                 break;
979                                                                 }
980                                     }
981                                 }
982                                 break;
983                             }
984                         }
985                                         }
986                                 }
987                         }
988                         break;
989                 }
990                 case Yplus:
991                 {
992                         for (ix = 0; ix < nbx; ix++)
993                         {
994                                 for (iz = 0; iz < nbz; iz++)
995                                 {
996                                         for (iy = nby - 1; iy >= 0; iy--)
997                                         {
998                         switch (voxels->Deepness(ix, iy, iz))
999                         {
1000                             case 0:
1001                             {
1002                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1003                                     continue;
1004                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1005                                                         if (value)
1006                                                         {
1007                                     if (!check_size)
1008                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1009                                                                 glVertex3d(xc, yc, zc);
1010                                     if (nearest)
1011                                         break;
1012                                                         }
1013                                 break;
1014                             }
1015                             case 1:
1016                             {
1017                                 for (i = 0; i < 8; i++)
1018                                 {
1019                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1020                                         continue;
1021                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
1022                                                             if (value)
1023                                                             {
1024                                         if (!check_size)
1025                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1026                                                                     glVertex3d(xc, yc, zc);
1027                                         if (nearest)
1028                                             break;
1029                                                             }
1030                                 }
1031                                 break;
1032                             }
1033                             case 2:
1034                             {
1035                                 for (i = 0; i < 8; i++)
1036                                 {
1037                                     for (j = 0; j < 8; j++)
1038                                     {
1039                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1040                                             continue;
1041                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1042                                                                 if (value)
1043                                                                 {
1044                                             if (!check_size)
1045                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1046                                                                         glVertex3d(xc, yc, zc);
1047                                             if (nearest)
1048                                                 break;
1049                                                                 }
1050                                     }
1051                                 }
1052                                 break;
1053                             }
1054                         }
1055                                         }
1056                                 }
1057                         }
1058                         break;
1059                 }
1060                 case Zminus:
1061                 {
1062                         for (ix = 0; ix < nbx; ix++)
1063                         {
1064                                 for (iy = 0; iy < nby; iy++)
1065                                 {
1066                                         for (iz = 0; iz < nbz; iz++)
1067                                         {
1068                         switch (voxels->Deepness(ix, iy, iz))
1069                         {
1070                             case 0:
1071                             {
1072                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1073                                     continue;
1074                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1075                                                         if (value)
1076                                                         {
1077                                     if (!check_size)
1078                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1079                                                                 glVertex3d(xc, yc, zc);
1080                                     if (nearest)
1081                                         break;
1082                                                         }
1083                                 break;
1084                             }
1085                             case 1:
1086                             {
1087                                 for (i = 0; i < 8; i++)
1088                                 {
1089                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1090                                         continue;
1091                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
1092                                                             if (value)
1093                                                             {
1094                                         if (!check_size)
1095                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1096                                                                     glVertex3d(xc, yc, zc);
1097                                         if (nearest)
1098                                             break;
1099                                                             }
1100                                 }
1101                                 break;
1102                             }
1103                             case 2:
1104                             {
1105                                 for (i = 0; i < 8; i++)
1106                                 {
1107                                     for (j = 0; j < 8; j++)
1108                                     {
1109                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1110                                             continue;
1111                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1112                                                                 if (value)
1113                                                                 {
1114                                             if (!check_size)
1115                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1116                                                                         glVertex3d(xc, yc, zc);
1117                                             if (nearest)
1118                                                 break;
1119                                                                 }
1120                                     }
1121                                 }
1122                                 break;
1123                             }
1124                         }
1125                                         }
1126                                 }
1127                         }
1128                         break;
1129                 }
1130                 case Zplus:
1131                 {
1132                         for (ix = 0; ix < nbx; ix++)
1133                         {
1134                                 for (iy = 0; iy < nby; iy++)
1135                                 {
1136                                         for (iz = nbz - 1; iz >= 0; iz--)
1137                                         {
1138                         switch (voxels->Deepness(ix, iy, iz))
1139                         {
1140                             case 0:
1141                             {
1142                                 if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1143                                     continue;
1144                                                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1145                                                         if (value)
1146                                                         {
1147                                     if (!check_size)
1148                                                                     ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1149                                                                 glVertex3d(xc, yc, zc);
1150                                     if (nearest)
1151                                         break;
1152                                                         }
1153                                 break;
1154                             }
1155                             case 1:
1156                             {
1157                                 for (i = 0; i < 8; i++)
1158                                 {
1159                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1160                                         continue;
1161                                                             Standard_Boolean value = voxels->Get(ix, iy, iz, i) == Standard_True;
1162                                                             if (value)
1163                                                             {
1164                                         if (!check_size)
1165                                                                         voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1166                                                                     glVertex3d(xc, yc, zc);
1167                                         if (nearest)
1168                                             break;
1169                                                             }
1170                                 }
1171                                 break;
1172                             }
1173                             case 2:
1174                             {
1175                                 for (i = 0; i < 8; i++)
1176                                 {
1177                                     for (j = 0; j < 8; j++)
1178                                     {
1179                                         if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1180                                             continue;
1181                                                                 Standard_Boolean value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1182                                                                 if (value)
1183                                                                 {
1184                                             if (!check_size)
1185                                                                             voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1186                                                                         glVertex3d(xc, yc, zc);
1187                                             if (nearest)
1188                                                 break;
1189                                                                 }
1190                                     }
1191                                 }
1192                                 break;
1193                             }
1194                         }
1195                                         }
1196                                 }
1197                         }
1198                         break;
1199                 }
1200         }
1201     glEnd();
1202 }
1203
1204
1205
1206 static void drawColorPoints(const VoxelDirection vdir, const Standard_Boolean nearest,
1207                             Voxel_ColorDS* voxels, const Handle(Quantity_HArray1OfColor)& hcolors,
1208                             const Standard_Byte minvalue, const Standard_Byte maxvalue,
1209                             const Standard_Real xmin, const Standard_Real xmax,
1210                             const Standard_Real ymin, const Standard_Real ymax,
1211                             const Standard_Real zmin, const Standard_Real zmax)
1212 {
1213         Standard_Real xc, yc, zc;
1214         Standard_Integer ix = 0, nbx = voxels->GetNbX();
1215         Standard_Integer iy = 0, nby = voxels->GetNbY();
1216         Standard_Integer iz = 0, nbz = voxels->GetNbZ();
1217     Standard_Byte value;
1218
1219     // Colors
1220     const Quantity_Array1OfColor& colors = hcolors->Array1();
1221
1222     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
1223                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
1224                        zmin <= DBL_MAX && zmax >= DBL_MAX);
1225     check_size = !check_size;
1226
1227     glBegin(GL_POINTS);
1228     switch (vdir)
1229         {
1230                 case Xminus:
1231                 {
1232                         for (iy = 0; iy < nby; iy++)
1233                         {
1234                                 for (iz = 0; iz < nbz; iz++)
1235                                 {
1236                                         for (ix = 0; ix < nbx; ix++)
1237                                         {
1238                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1239                             continue;
1240                             value = voxels->Get(ix, iy, iz);
1241                             if (value >= minvalue && value <= maxvalue)
1242                             {
1243                             if (!check_size)
1244                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1245                             setColor(colors.Value(value), Standard_False);
1246                                     glVertex3d(xc, yc, zc);
1247                             if (nearest)
1248                                 break;
1249                         }
1250                                         }
1251                                 }
1252                         }
1253                         break;
1254                 }
1255                 case Xplus:
1256                 {
1257                         for (iy = 0; iy < nby; iy++)
1258                         {
1259                                 for (iz = 0; iz < nbz; iz++)
1260                                 {
1261                                         for (ix = nbx - 1; ix >= 0; ix--)
1262                                         {
1263                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1264                             continue;
1265                             value = voxels->Get(ix, iy, iz);
1266                             if (value >= minvalue && value <= maxvalue)
1267                             {
1268                             if (!check_size)
1269                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1270                             setColor(colors.Value(value), Standard_False);
1271                                     glVertex3d(xc, yc, zc);
1272                             if (nearest)
1273                                 break;
1274                         }
1275                                         }
1276                                 }
1277                         }
1278                         break;
1279                 }
1280                 case Yminus:
1281                 {
1282                         for (ix = 0; ix < nbx; ix++)
1283                         {
1284                                 for (iz = 0; iz < nbz; iz++)
1285                                 {
1286                                         for (iy = 0; iy < nby; iy++)
1287                                         {
1288                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1289                             continue;
1290                             value = voxels->Get(ix, iy, iz);
1291                             if (value >= minvalue && value <= maxvalue)
1292                             {
1293                             if (!check_size)
1294                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1295                             setColor(colors.Value(value), Standard_False);
1296                                     glVertex3d(xc, yc, zc);
1297                             if (nearest)
1298                                 break;
1299                         }
1300                                         }
1301                                 }
1302                         }
1303                         break;
1304                 }
1305                 case Yplus:
1306                 {
1307                         for (ix = 0; ix < nbx; ix++)
1308                         {
1309                                 for (iz = 0; iz < nbz; iz++)
1310                                 {
1311                                         for (iy = nby - 1; iy >= 0; iy--)
1312                                         {
1313                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1314                             continue;
1315                             value = voxels->Get(ix, iy, iz);
1316                             if (value >= minvalue && value <= maxvalue)
1317                             {
1318                             if (!check_size)
1319                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1320                             setColor(colors.Value(value), Standard_False);
1321                                     glVertex3d(xc, yc, zc);
1322                             if (nearest)
1323                                 break;
1324                         }
1325                                         }
1326                                 }
1327                         }
1328                         break;
1329                 }
1330                 case Zminus:
1331                 {
1332                         for (ix = 0; ix < nbx; ix++)
1333                         {
1334                                 for (iy = 0; iy < nby; iy++)
1335                                 {
1336                                         for (iz = 0; iz < nbz; iz++)
1337                                         {
1338                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1339                             continue;
1340                             value = voxels->Get(ix, iy, iz);
1341                             if (value >= minvalue && value <= maxvalue)
1342                             {
1343                             if (!check_size)
1344                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1345                             setColor(colors.Value(value), Standard_False);
1346                                     glVertex3d(xc, yc, zc);
1347                             if (nearest)
1348                                 break;
1349                         }
1350                                         }
1351                                 }
1352                         }
1353                         break;
1354                 }
1355                 case Zplus:
1356                 {
1357                         for (ix = 0; ix < nbx; ix++)
1358                         {
1359                                 for (iy = 0; iy < nby; iy++)
1360                                 {
1361                                         for (iz = nbz - 1; iz >= 0; iz--)
1362                                         {
1363                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1364                             continue;
1365                             value = voxels->Get(ix, iy, iz);
1366                             if (value >= minvalue && value <= maxvalue)
1367                             {
1368                             if (!check_size)
1369                                         voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1370                             setColor(colors.Value(value), Standard_False);
1371                                     glVertex3d(xc, yc, zc);
1372                             if (nearest)
1373                                 break;
1374                         }
1375                                         }
1376                                 }
1377                         }
1378                         break;
1379                 }
1380     }
1381     glEnd();
1382 }
1383
1384 static void drawBoolQuadrangles(Voxel_BoolDS* voxels, const VoxelDirection vdir, 
1385                                 const gp_Dir& viewnormal, const Standard_Boolean nearest,
1386                                 const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3, const gp_Pnt& p4,
1387                                 const Standard_Real xmin, const Standard_Real xmax,
1388                                 const Standard_Real ymin, const Standard_Real ymax,
1389                                 const Standard_Real zmin, const Standard_Real zmax)
1390 {
1391     gp_Vec vc;
1392     gp_Pnt pc1, pc2, pc3, pc4;
1393     Standard_Real xc, yc, zc, xn = 0.0, yn = 0.0, zn = 1.0;
1394     Standard_Integer ix, iy, iz, nbx = voxels->GetNbX(), nby = voxels->GetNbY(), nbz = voxels->GetNbZ();
1395
1396     // Normal
1397     viewnormal.Coord(xn, yn, zn);
1398
1399     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
1400                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
1401                        zmin <= DBL_MAX && zmax >= DBL_MAX);
1402     check_size = !check_size;
1403
1404     glBegin(GL_QUADS);
1405     switch (vdir)
1406         {
1407                 case Xminus:
1408                 {
1409                         for (iy = 0; iy < nby; iy++)
1410                         {
1411                                 for (iz = 0; iz < nbz; iz++)
1412                                 {
1413                                         for (ix = 0; ix < nbx; ix++)
1414                                         {
1415                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1416                             continue;
1417                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1418                         if (value)
1419                         {
1420                             // Define translation vector
1421                             if (!check_size)
1422                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1423                             vc.SetCoord(xc, yc, zc);
1424
1425                             // Translate
1426                             pc1 = p1.Translated(vc);
1427                             pc2 = p2.Translated(vc);
1428                             pc3 = p3.Translated(vc);
1429                             pc4 = p4.Translated(vc);
1430
1431                             // Display
1432                             glNormal3d(xn, yn, zn);
1433                             pc1.Coord(xc, yc, zc);
1434                             glVertex3d(xc, yc, zc);
1435                             pc2.Coord(xc, yc, zc);
1436                             glVertex3d(xc, yc, zc);
1437                             pc3.Coord(xc, yc, zc);
1438                             glVertex3d(xc, yc, zc);
1439                             pc4.Coord(xc, yc, zc);
1440                             glVertex3d(xc, yc, zc);
1441
1442                             if (nearest)
1443                                 break;
1444                         }
1445                     }
1446                                 }
1447                         }
1448                         break;
1449                 }
1450                 case Xplus:
1451                 {
1452                         for (iy = 0; iy < nby; iy++)
1453                         {
1454                                 for (iz = 0; iz < nbz; iz++)
1455                                 {
1456                                         for (ix = nbx - 1; ix >= 0; ix--)
1457                                         {
1458                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1459                             continue;
1460                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1461                         if (value)
1462                         {
1463                             // Define translation vector
1464                             if (!check_size)
1465                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1466                             vc.SetCoord(xc, yc, zc);
1467
1468                             // Translate
1469                             pc1 = p1.Translated(vc);
1470                             pc2 = p2.Translated(vc);
1471                             pc3 = p3.Translated(vc);
1472                             pc4 = p4.Translated(vc);
1473
1474                             // Display
1475                             glNormal3d(xn, yn, zn);
1476                             pc1.Coord(xc, yc, zc);
1477                             glVertex3d(xc, yc, zc);
1478                             pc2.Coord(xc, yc, zc);
1479                             glVertex3d(xc, yc, zc);
1480                             pc3.Coord(xc, yc, zc);
1481                             glVertex3d(xc, yc, zc);
1482                             pc4.Coord(xc, yc, zc);
1483                             glVertex3d(xc, yc, zc);
1484
1485                             if (nearest)
1486                                 break;
1487                         }
1488                                         }
1489                                 }
1490                         }
1491                         break;
1492                 }
1493                 case Yminus:
1494                 {
1495                         for (ix = 0; ix < nbx; ix++)
1496                         {
1497                                 for (iz = 0; iz < nbz; iz++)
1498                                 {
1499                                         for (iy = 0; iy < nby; iy++)
1500                                         {
1501                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1502                             continue;
1503                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1504                         if (value)
1505                         {
1506                             // Define translation vector
1507                             if (!check_size)
1508                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1509                             vc.SetCoord(xc, yc, zc);
1510
1511                             // Translate
1512                             pc1 = p1.Translated(vc);
1513                             pc2 = p2.Translated(vc);
1514                             pc3 = p3.Translated(vc);
1515                             pc4 = p4.Translated(vc);
1516
1517                             // Display
1518                             glNormal3d(xn, yn, zn);
1519                             pc1.Coord(xc, yc, zc);
1520                             glVertex3d(xc, yc, zc);
1521                             pc2.Coord(xc, yc, zc);
1522                             glVertex3d(xc, yc, zc);
1523                             pc3.Coord(xc, yc, zc);
1524                             glVertex3d(xc, yc, zc);
1525                             pc4.Coord(xc, yc, zc);
1526                             glVertex3d(xc, yc, zc);
1527
1528                             if (nearest)
1529                                 break;
1530                         }
1531                                         }
1532                                 }
1533                         }
1534                         break;
1535                 }
1536                 case Yplus:
1537                 {
1538                         for (ix = 0; ix < nbx; ix++)
1539                         {
1540                                 for (iz = 0; iz < nbz; iz++)
1541                                 {
1542                                         for (iy = nby - 1; iy >= 0; iy--)
1543                                         {
1544                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1545                             continue;
1546                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1547                         if (value)
1548                         {
1549                             // Define translation vector
1550                             if (!check_size)
1551                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1552                             vc.SetCoord(xc, yc, zc);
1553
1554                             // Translate
1555                             pc1 = p1.Translated(vc);
1556                             pc2 = p2.Translated(vc);
1557                             pc3 = p3.Translated(vc);
1558                             pc4 = p4.Translated(vc);
1559
1560                             // Display
1561                             glNormal3d(xn, yn, zn);
1562                             pc1.Coord(xc, yc, zc);
1563                             glVertex3d(xc, yc, zc);
1564                             pc2.Coord(xc, yc, zc);
1565                             glVertex3d(xc, yc, zc);
1566                             pc3.Coord(xc, yc, zc);
1567                             glVertex3d(xc, yc, zc);
1568                             pc4.Coord(xc, yc, zc);
1569                             glVertex3d(xc, yc, zc);
1570
1571                             if (nearest)
1572                                 break;
1573                         }
1574                                         }
1575                                 }
1576                         }
1577                         break;
1578                 }
1579                 case Zminus:
1580                 {
1581                         for (ix = 0; ix < nbx; ix++)
1582                         {
1583                                 for (iy = 0; iy < nby; iy++)
1584                                 {
1585                                         for (iz = 0; iz < nbz; iz++)
1586                                         {
1587                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1588                             continue;
1589                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1590                         if (value)
1591                         {
1592                             // Define translation vector
1593                             if (!check_size)
1594                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1595                             vc.SetCoord(xc, yc, zc);
1596
1597                             // Translate
1598                             pc1 = p1.Translated(vc);
1599                             pc2 = p2.Translated(vc);
1600                             pc3 = p3.Translated(vc);
1601                             pc4 = p4.Translated(vc);
1602
1603                             // Display
1604                             glNormal3d(xn, yn, zn);
1605                             pc1.Coord(xc, yc, zc);
1606                             glVertex3d(xc, yc, zc);
1607                             pc2.Coord(xc, yc, zc);
1608                             glVertex3d(xc, yc, zc);
1609                             pc3.Coord(xc, yc, zc);
1610                             glVertex3d(xc, yc, zc);
1611                             pc4.Coord(xc, yc, zc);
1612                             glVertex3d(xc, yc, zc);
1613
1614                             if (nearest)
1615                                 break;
1616                         }
1617                                         }
1618                                 }
1619                         }
1620                         break;
1621                 }
1622                 case Zplus:
1623                 {
1624                         for (ix = 0; ix < nbx; ix++)
1625                         {
1626                                 for (iy = 0; iy < nby; iy++)
1627                                 {
1628                                         for (iz = nbz - 1; iz >= 0; iz--)
1629                                         {
1630                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1631                             continue;
1632                         Standard_Boolean value = voxels->Get(ix, iy, iz) == Standard_True;
1633                         if (value)
1634                         {
1635                             // Define translation vector
1636                             if (!check_size)
1637                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
1638                             vc.SetCoord(xc, yc, zc);
1639
1640                             // Translate
1641                             pc1 = p1.Translated(vc);
1642                             pc2 = p2.Translated(vc);
1643                             pc3 = p3.Translated(vc);
1644                             pc4 = p4.Translated(vc);
1645
1646                             // Display
1647                             glNormal3d(xn, yn, zn);
1648                             pc1.Coord(xc, yc, zc);
1649                             glVertex3d(xc, yc, zc);
1650                             pc2.Coord(xc, yc, zc);
1651                             glVertex3d(xc, yc, zc);
1652                             pc3.Coord(xc, yc, zc);
1653                             glVertex3d(xc, yc, zc);
1654                             pc4.Coord(xc, yc, zc);
1655                             glVertex3d(xc, yc, zc);
1656
1657                             if (nearest)
1658                                 break;
1659                         }
1660                                         }
1661                                 }
1662                         }
1663                         break;
1664                 }
1665     }
1666     glEnd();
1667 }
1668
1669 static void drawROctBoolQuadrangles(Voxel_ROctBoolDS* voxels, const VoxelDirection vdir, 
1670                                     const gp_Dir& viewnormal, const Standard_Boolean nearest,
1671                                     const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3, const gp_Pnt& p4,
1672                                     const Standard_Real xmin, const Standard_Real xmax,
1673                                     const Standard_Real ymin, const Standard_Real ymax,
1674                                     const Standard_Real zmin, const Standard_Real zmax)
1675 {
1676     gp_Vec vc;
1677     gp_Pnt pc1, pc2, pc3, pc4;
1678     Standard_Real xc, yc, zc, xn = 0.0, yn = 0.0, zn = 1.0;
1679     Standard_Integer ix, iy, iz, nbx = voxels->GetNbX(), nby = voxels->GetNbY(), nbz = voxels->GetNbZ(), i, j, deepness;
1680
1681     // Normal
1682     viewnormal.Coord(xn, yn, zn);
1683
1684     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
1685                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
1686                        zmin <= DBL_MAX && zmax >= DBL_MAX);
1687     check_size = !check_size;
1688
1689     glBegin(GL_QUADS);
1690     switch (vdir)
1691         {
1692                 case Xminus:
1693                 {
1694                         for (iy = 0; iy < nby; iy++)
1695                         {
1696                                 for (iz = 0; iz < nbz; iz++)
1697                                 {
1698                                         for (ix = 0; ix < nbx; ix++)
1699                                         {
1700                         deepness = voxels->Deepness(ix, iy, iz);
1701                         for (i = 0; i < 8; i++)
1702                         {
1703                             for (j = 0; j < 8; j++)
1704                             {
1705                                 if (deepness == 0 && j)
1706                                 {
1707                                     i = 8;
1708                                     break;
1709                                 }
1710                                 if (deepness == 1 && j)
1711                                     break;
1712                                 if (deepness == 0)
1713                                 {
1714                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1715                                         continue;
1716                                 }
1717                                 else if (deepness == 1)
1718                                 {
1719                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1720                                         continue;
1721                                 }
1722                                 else if (deepness == 2)
1723                                 {
1724                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1725                                         continue;
1726                                 }
1727
1728                                 Standard_Boolean value;
1729                                 switch (deepness)
1730                                 {
1731                                     case 0:
1732                                         value = voxels->Get(ix, iy, iz) == Standard_True;
1733                                         break;
1734                                     case 1:
1735                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
1736                                         break;
1737                                     case 2:
1738                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1739                                         break;
1740                                 }
1741                                 
1742                                 if (value)
1743                                 {
1744                                     // Define translation vector
1745                                     if (!check_size)
1746                                     {
1747                                         switch (deepness)
1748                                         {
1749                                             case 0:
1750                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1751                                                 break;
1752                                             case 1:
1753                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1754                                                 break;
1755                                             case 2:
1756                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1757                                                 break;
1758                                         }
1759                                     }
1760                                     vc.SetCoord(xc, yc, zc);
1761
1762                                     // Translate
1763                                     pc1 = p1.Translated(vc);
1764                                     pc2 = p2.Translated(vc);
1765                                     pc3 = p3.Translated(vc);
1766                                     pc4 = p4.Translated(vc);
1767
1768                                     // Display
1769                                     glNormal3d(xn, yn, zn);
1770                                     pc1.Coord(xc, yc, zc);
1771                                     glVertex3d(xc, yc, zc);
1772                                     pc2.Coord(xc, yc, zc);
1773                                     glVertex3d(xc, yc, zc);
1774                                     pc3.Coord(xc, yc, zc);
1775                                     glVertex3d(xc, yc, zc);
1776                                     pc4.Coord(xc, yc, zc);
1777                                     glVertex3d(xc, yc, zc);
1778
1779                                     if (nearest)
1780                                         break;
1781                                 }
1782                             }
1783                         }
1784                     }
1785                                 }
1786                         }
1787                         break;
1788                 }
1789                 case Xplus:
1790                 {
1791                         for (iy = 0; iy < nby; iy++)
1792                         {
1793                                 for (iz = 0; iz < nbz; iz++)
1794                                 {
1795                                         for (ix = nbx - 1; ix >= 0; ix--)
1796                                         {
1797                         deepness = voxels->Deepness(ix, iy, iz);
1798                         for (i = 0; i < 8; i++)
1799                         {
1800                             for (j = 0; j < 8; j++)
1801                             {
1802                                 if (deepness == 0 && j)
1803                                 {
1804                                     i = 8;
1805                                     break;
1806                                 }
1807                                 if (deepness == 1 && j)
1808                                     break;
1809                                 if (deepness == 0)
1810                                 {
1811                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1812                                         continue;
1813                                 }
1814                                 else if (deepness == 1)
1815                                 {
1816                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1817                                         continue;
1818                                 }
1819                                 else if (deepness == 2)
1820                                 {
1821                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1822                                         continue;
1823                                 }
1824
1825                                 Standard_Boolean value;
1826                                 switch (deepness)
1827                                 {
1828                                     case 0:
1829                                         value = voxels->Get(ix, iy, iz) == Standard_True;
1830                                         break;
1831                                     case 1:
1832                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
1833                                         break;
1834                                     case 2:
1835                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1836                                         break;
1837                                 }
1838                                 
1839                                 if (value)
1840                                 {
1841                                     // Define translation vector
1842                                     if (!check_size)
1843                                     {
1844                                         switch (deepness)
1845                                         {
1846                                             case 0:
1847                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1848                                                 break;
1849                                             case 1:
1850                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1851                                                 break;
1852                                             case 2:
1853                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1854                                                 break;
1855                                         }
1856                                     }
1857                                     vc.SetCoord(xc, yc, zc);
1858
1859                                     // Translate
1860                                     pc1 = p1.Translated(vc);
1861                                     pc2 = p2.Translated(vc);
1862                                     pc3 = p3.Translated(vc);
1863                                     pc4 = p4.Translated(vc);
1864
1865                                     // Display
1866                                     glNormal3d(xn, yn, zn);
1867                                     pc1.Coord(xc, yc, zc);
1868                                     glVertex3d(xc, yc, zc);
1869                                     pc2.Coord(xc, yc, zc);
1870                                     glVertex3d(xc, yc, zc);
1871                                     pc3.Coord(xc, yc, zc);
1872                                     glVertex3d(xc, yc, zc);
1873                                     pc4.Coord(xc, yc, zc);
1874                                     glVertex3d(xc, yc, zc);
1875
1876                                     if (nearest)
1877                                         break;
1878                                 }
1879                             }
1880                         }
1881                                         }
1882                                 }
1883                         }
1884                         break;
1885                 }
1886                 case Yminus:
1887                 {
1888                         for (ix = 0; ix < nbx; ix++)
1889                         {
1890                                 for (iz = 0; iz < nbz; iz++)
1891                                 {
1892                                         for (iy = 0; iy < nby; iy++)
1893                                         {
1894                         deepness = voxels->Deepness(ix, iy, iz);
1895                         for (i = 0; i < 8; i++)
1896                         {
1897                             for (j = 0; j < 8; j++)
1898                             {
1899                                 if (deepness == 0 && j)
1900                                 {
1901                                     i = 8;
1902                                     break;
1903                                 }
1904                                 if (deepness == 1 && j)
1905                                     break;
1906                                 if (deepness == 0)
1907                                 {
1908                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1909                                         continue;
1910                                 }
1911                                 else if (deepness == 1)
1912                                 {
1913                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1914                                         continue;
1915                                 }
1916                                 else if (deepness == 2)
1917                                 {
1918                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
1919                                         continue;
1920                                 }
1921
1922                                 Standard_Boolean value;
1923                                 switch (deepness)
1924                                 {
1925                                     case 0:
1926                                         value = voxels->Get(ix, iy, iz) == Standard_True;
1927                                         break;
1928                                     case 1:
1929                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
1930                                         break;
1931                                     case 2:
1932                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
1933                                         break;
1934                                 }
1935                                 
1936                                 if (value)
1937                                 {
1938                                     // Define translation vector
1939                                     if (!check_size)
1940                                     {
1941                                         switch (deepness)
1942                                         {
1943                                             case 0:
1944                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
1945                                                 break;
1946                                             case 1:
1947                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
1948                                                 break;
1949                                             case 2:
1950                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
1951                                                 break;
1952                                         }
1953                                     }
1954                                     vc.SetCoord(xc, yc, zc);
1955
1956                                     // Translate
1957                                     pc1 = p1.Translated(vc);
1958                                     pc2 = p2.Translated(vc);
1959                                     pc3 = p3.Translated(vc);
1960                                     pc4 = p4.Translated(vc);
1961
1962                                     // Display
1963                                     glNormal3d(xn, yn, zn);
1964                                     pc1.Coord(xc, yc, zc);
1965                                     glVertex3d(xc, yc, zc);
1966                                     pc2.Coord(xc, yc, zc);
1967                                     glVertex3d(xc, yc, zc);
1968                                     pc3.Coord(xc, yc, zc);
1969                                     glVertex3d(xc, yc, zc);
1970                                     pc4.Coord(xc, yc, zc);
1971                                     glVertex3d(xc, yc, zc);
1972
1973                                     if (nearest)
1974                                         break;
1975                                 }
1976                             }
1977                         }
1978                                         }
1979                                 }
1980                         }
1981                         break;
1982                 }
1983                 case Yplus:
1984                 {
1985                         for (ix = 0; ix < nbx; ix++)
1986                         {
1987                                 for (iz = 0; iz < nbz; iz++)
1988                                 {
1989                                         for (iy = nby - 1; iy >= 0; iy--)
1990                                         {
1991                         deepness = voxels->Deepness(ix, iy, iz);
1992                         for (i = 0; i < 8; i++)
1993                         {
1994                             for (j = 0; j < 8; j++)
1995                             {
1996                                 if (deepness == 0 && j)
1997                                 {
1998                                     i = 8;
1999                                     break;
2000                                 }
2001                                 if (deepness == 1 && j)
2002                                     break;
2003                                 if (deepness == 0)
2004                                 {
2005                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2006                                         continue;
2007                                 }
2008                                 else if (deepness == 1)
2009                                 {
2010                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2011                                         continue;
2012                                 }
2013                                 else if (deepness == 2)
2014                                 {
2015                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2016                                         continue;
2017                                 }
2018
2019                                 Standard_Boolean value;
2020                                 switch (deepness)
2021                                 {
2022                                     case 0:
2023                                         value = voxels->Get(ix, iy, iz) == Standard_True;
2024                                         break;
2025                                     case 1:
2026                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
2027                                         break;
2028                                     case 2:
2029                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
2030                                         break;
2031                                 }
2032                                 
2033                                 if (value)
2034                                 {
2035                                     // Define translation vector
2036                                     if (!check_size)
2037                                     {
2038                                         switch (deepness)
2039                                         {
2040                                             case 0:
2041                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
2042                                                 break;
2043                                             case 1:
2044                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
2045                                                 break;
2046                                             case 2:
2047                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
2048                                                 break;
2049                                         }
2050                                     }
2051                                     vc.SetCoord(xc, yc, zc);
2052
2053                                     // Translate
2054                                     pc1 = p1.Translated(vc);
2055                                     pc2 = p2.Translated(vc);
2056                                     pc3 = p3.Translated(vc);
2057                                     pc4 = p4.Translated(vc);
2058
2059                                     // Display
2060                                     glNormal3d(xn, yn, zn);
2061                                     pc1.Coord(xc, yc, zc);
2062                                     glVertex3d(xc, yc, zc);
2063                                     pc2.Coord(xc, yc, zc);
2064                                     glVertex3d(xc, yc, zc);
2065                                     pc3.Coord(xc, yc, zc);
2066                                     glVertex3d(xc, yc, zc);
2067                                     pc4.Coord(xc, yc, zc);
2068                                     glVertex3d(xc, yc, zc);
2069
2070                                     if (nearest)
2071                                         break;
2072                                 }
2073                             }
2074                         }
2075                                         }
2076                                 }
2077                         }
2078                         break;
2079                 }
2080                 case Zminus:
2081                 {
2082                         for (ix = 0; ix < nbx; ix++)
2083                         {
2084                                 for (iy = 0; iy < nby; iy++)
2085                                 {
2086                                         for (iz = 0; iz < nbz; iz++)
2087                                         {
2088                         deepness = voxels->Deepness(ix, iy, iz);
2089                         for (i = 0; i < 8; i++)
2090                         {
2091                             for (j = 0; j < 8; j++)
2092                             {
2093                                 if (deepness == 0 && j)
2094                                 {
2095                                     i = 8;
2096                                     break;
2097                                 }
2098                                 if (deepness == 1 && j)
2099                                     break;
2100                                 if (deepness == 0)
2101                                 {
2102                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2103                                         continue;
2104                                 }
2105                                 else if (deepness == 1)
2106                                 {
2107                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2108                                         continue;
2109                                 }
2110                                 else if (deepness == 2)
2111                                 {
2112                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2113                                         continue;
2114                                 }
2115
2116                                 Standard_Boolean value;
2117                                 switch (deepness)
2118                                 {
2119                                     case 0:
2120                                         value = voxels->Get(ix, iy, iz) == Standard_True;
2121                                         break;
2122                                     case 1:
2123                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
2124                                         break;
2125                                     case 2:
2126                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
2127                                         break;
2128                                 }
2129                                 
2130                                 if (value)
2131                                 {
2132                                     // Define translation vector
2133                                     if (!check_size)
2134                                     {
2135                                         switch (deepness)
2136                                         {
2137                                             case 0:
2138                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
2139                                                 break;
2140                                             case 1:
2141                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
2142                                                 break;
2143                                             case 2:
2144                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
2145                                                 break;
2146                                         }
2147                                     }
2148                                     vc.SetCoord(xc, yc, zc);
2149
2150                                     // Translate
2151                                     pc1 = p1.Translated(vc);
2152                                     pc2 = p2.Translated(vc);
2153                                     pc3 = p3.Translated(vc);
2154                                     pc4 = p4.Translated(vc);
2155
2156                                     // Display
2157                                     glNormal3d(xn, yn, zn);
2158                                     pc1.Coord(xc, yc, zc);
2159                                     glVertex3d(xc, yc, zc);
2160                                     pc2.Coord(xc, yc, zc);
2161                                     glVertex3d(xc, yc, zc);
2162                                     pc3.Coord(xc, yc, zc);
2163                                     glVertex3d(xc, yc, zc);
2164                                     pc4.Coord(xc, yc, zc);
2165                                     glVertex3d(xc, yc, zc);
2166
2167                                     if (nearest)
2168                                         break;
2169                                 }
2170                             }
2171                         }
2172                                         }
2173                                 }
2174                         }
2175                         break;
2176                 }
2177                 case Zplus:
2178                 {
2179                         for (ix = 0; ix < nbx; ix++)
2180                         {
2181                                 for (iy = 0; iy < nby; iy++)
2182                                 {
2183                                         for (iz = nbz - 1; iz >= 0; iz--)
2184                                         {
2185                         deepness = voxels->Deepness(ix, iy, iz);
2186                         for (i = 0; i < 8; i++)
2187                         {
2188                             for (j = 0; j < 8; j++)
2189                             {
2190                                 if (deepness == 0 && j)
2191                                 {
2192                                     i = 8;
2193                                     break;
2194                                 }
2195                                 if (deepness == 1 && j)
2196                                     break;
2197                                 if (deepness == 0)
2198                                 {
2199                                     if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2200                                         continue;
2201                                 }
2202                                 else if (deepness == 1)
2203                                 {
2204                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, -1, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2205                                         continue;
2206                                 }
2207                                 else if (deepness == 2)
2208                                 {
2209                                     if (check_size && !CheckSize(voxels, ix, iy, iz, i, j, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2210                                         continue;
2211                                 }
2212
2213                                 Standard_Boolean value;
2214                                 switch (deepness)
2215                                 {
2216                                     case 0:
2217                                         value = voxels->Get(ix, iy, iz) == Standard_True;
2218                                         break;
2219                                     case 1:
2220                                         value = voxels->Get(ix, iy, iz, i) == Standard_True;
2221                                         break;
2222                                     case 2:
2223                                         value = voxels->Get(ix, iy, iz, i, j) == Standard_True;
2224                                         break;
2225                                 }
2226                                 
2227                                 if (value)
2228                                 {
2229                                     // Define translation vector
2230                                     if (!check_size)
2231                                     {
2232                                         switch (deepness)
2233                                         {
2234                                             case 0:
2235                                                 ((Voxel_DS*)voxels)->GetCenter(ix, iy, iz, xc, yc, zc);
2236                                                 break;
2237                                             case 1:
2238                                                 voxels->GetCenter(ix, iy, iz, i, xc, yc, zc);
2239                                                 break;
2240                                             case 2:
2241                                                 voxels->GetCenter(ix, iy, iz, i, j, xc, yc, zc);
2242                                                 break;
2243                                         }
2244                                     }
2245                                     vc.SetCoord(xc, yc, zc);
2246
2247                                     // Translate
2248                                     pc1 = p1.Translated(vc);
2249                                     pc2 = p2.Translated(vc);
2250                                     pc3 = p3.Translated(vc);
2251                                     pc4 = p4.Translated(vc);
2252
2253                                     // Display
2254                                     glNormal3d(xn, yn, zn);
2255                                     pc1.Coord(xc, yc, zc);
2256                                     glVertex3d(xc, yc, zc);
2257                                     pc2.Coord(xc, yc, zc);
2258                                     glVertex3d(xc, yc, zc);
2259                                     pc3.Coord(xc, yc, zc);
2260                                     glVertex3d(xc, yc, zc);
2261                                     pc4.Coord(xc, yc, zc);
2262                                     glVertex3d(xc, yc, zc);
2263
2264                                     if (nearest)
2265                                         break;
2266                                 }
2267                             }
2268                         }
2269                                         }
2270                                 }
2271                         }
2272                         break;
2273                 }
2274     }
2275     glEnd();
2276 }
2277
2278
2279
2280 static void drawColorQuadrangles(Voxel_ColorDS* voxels, const VoxelDirection vdir, 
2281                                  const gp_Dir& viewnormal, const Standard_Boolean nearest,
2282                                  const Handle(Quantity_HArray1OfColor)& hcolors,
2283                                  const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3, const gp_Pnt& p4,
2284                                  const Standard_Byte minvalue, const Standard_Byte maxvalue,
2285                                  const Standard_Real xmin, const Standard_Real xmax,
2286                                  const Standard_Real ymin, const Standard_Real ymax,
2287                                  const Standard_Real zmin, const Standard_Real zmax)
2288 {
2289     gp_Vec vc;
2290     gp_Pnt pc1, pc2, pc3, pc4;
2291     Standard_Real xc, yc, zc, xn = 0.0, yn = 0.0, zn = 0.0;
2292     Standard_Integer ix, iy, iz, nbx = voxels->GetNbX(), nby = voxels->GetNbY(), nbz = voxels->GetNbZ();
2293     Standard_Byte value;
2294
2295     // Normal
2296     //viewnormal.Coord(xn, yn, zn);
2297     glNormal3d(xn, yn, zn);
2298
2299     // Colors
2300     const Quantity_Array1OfColor& colors = hcolors->Array1();
2301
2302     Standard_Boolean check_size = (xmin <= DBL_MAX && xmax >= DBL_MAX &&
2303                        ymin <= DBL_MAX && ymax >= DBL_MAX &&
2304                        zmin <= DBL_MAX && zmax >= DBL_MAX);
2305     check_size = !check_size;
2306
2307     glBegin(GL_QUADS);
2308     switch (vdir)
2309         {
2310                 case Xminus:
2311                 {
2312                         for (iy = 0; iy < nby; iy++)
2313                         {
2314                                 for (iz = 0; iz < nbz; iz++)
2315                                 {
2316                                         for (ix = 0; ix < nbx; ix++)
2317                                         {
2318                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2319                             continue;
2320                         value = voxels->Get(ix, iy, iz);
2321                         if (value >= minvalue && value <= maxvalue)
2322                         {
2323                             // Define translation vector
2324                             if (!check_size)
2325                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2326                             vc.SetCoord(xc, yc, zc);
2327
2328                             // Translate
2329                             pc1 = p1.Translated(vc);
2330                             pc2 = p2.Translated(vc);
2331                             pc3 = p3.Translated(vc);
2332                             pc4 = p4.Translated(vc);
2333
2334                             // Color
2335                             setColor(colors.Value(value), Standard_False);
2336
2337                             // Display
2338                             //glNormal3d(xn, yn, zn);
2339                             pc1.Coord(xc, yc, zc);
2340                             glVertex3d(xc, yc, zc);
2341                             pc2.Coord(xc, yc, zc);
2342                             glVertex3d(xc, yc, zc);
2343                             pc3.Coord(xc, yc, zc);
2344                             glVertex3d(xc, yc, zc);
2345                             pc4.Coord(xc, yc, zc);
2346                             glVertex3d(xc, yc, zc);
2347
2348                             if (nearest)
2349                                 break;
2350                         }
2351                     }
2352                                 }
2353                         }
2354                         break;
2355                 }
2356                 case Xplus:
2357                 {
2358                         for (iy = 0; iy < nby; iy++)
2359                         {
2360                                 for (iz = 0; iz < nbz; iz++)
2361                                 {
2362                                         for (ix = nbx - 1; ix >= 0; ix--)
2363                                         {
2364                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2365                             continue;
2366                         value = voxels->Get(ix, iy, iz);
2367                         if (value >= minvalue && value <= maxvalue)
2368                         {
2369                             // Define translation vector
2370                             if (!check_size)
2371                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2372                             vc.SetCoord(xc, yc, zc);
2373
2374                             // Translate
2375                             pc1 = p1.Translated(vc);
2376                             pc2 = p2.Translated(vc);
2377                             pc3 = p3.Translated(vc);
2378                             pc4 = p4.Translated(vc);
2379
2380                             // Color
2381                             setColor(colors.Value(value), Standard_False);
2382
2383                             // Display
2384                             //glNormal3d(xn, yn, zn);
2385                             pc1.Coord(xc, yc, zc);
2386                             glVertex3d(xc, yc, zc);
2387                             pc2.Coord(xc, yc, zc);
2388                             glVertex3d(xc, yc, zc);
2389                             pc3.Coord(xc, yc, zc);
2390                             glVertex3d(xc, yc, zc);
2391                             pc4.Coord(xc, yc, zc);
2392                             glVertex3d(xc, yc, zc);
2393
2394                             if (nearest)
2395                                 break;
2396                         }
2397                                         }
2398                                 }
2399                         }
2400                         break;
2401                 }
2402                 case Yminus:
2403                 {
2404                         for (ix = 0; ix < nbx; ix++)
2405                         {
2406                                 for (iz = 0; iz < nbz; iz++)
2407                                 {
2408                                         for (iy = 0; iy < nby; iy++)
2409                                         {
2410                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2411                             continue;
2412                         value = voxels->Get(ix, iy, iz);
2413                         if (value >= minvalue && value <= maxvalue)
2414                         {
2415                             // Define translation vector
2416                             if (!check_size)
2417                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2418                             vc.SetCoord(xc, yc, zc);
2419
2420                             // Translate
2421                             pc1 = p1.Translated(vc);
2422                             pc2 = p2.Translated(vc);
2423                             pc3 = p3.Translated(vc);
2424                             pc4 = p4.Translated(vc);
2425
2426                             // Color
2427                             setColor(colors.Value(value), Standard_False);
2428
2429                             // Display
2430                             //glNormal3d(xn, yn, zn);
2431                             pc1.Coord(xc, yc, zc);
2432                             glVertex3d(xc, yc, zc);
2433                             pc2.Coord(xc, yc, zc);
2434                             glVertex3d(xc, yc, zc);
2435                             pc3.Coord(xc, yc, zc);
2436                             glVertex3d(xc, yc, zc);
2437                             pc4.Coord(xc, yc, zc);
2438                             glVertex3d(xc, yc, zc);
2439
2440                             if (nearest)
2441                                 break;
2442                         }
2443                                         }
2444                                 }
2445                         }
2446                         break;
2447                 }
2448                 case Yplus:
2449                 {
2450                         for (ix = 0; ix < nbx; ix++)
2451                         {
2452                                 for (iz = 0; iz < nbz; iz++)
2453                                 {
2454                                         for (iy = nby - 1; iy >= 0; iy--)
2455                                         {
2456                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2457                             continue;
2458                         value = voxels->Get(ix, iy, iz);
2459                         if (value >= minvalue && value <= maxvalue)
2460                         {
2461                             // Define translation vector
2462                             if (!check_size)
2463                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2464                             vc.SetCoord(xc, yc, zc);
2465
2466                             // Translate
2467                             pc1 = p1.Translated(vc);
2468                             pc2 = p2.Translated(vc);
2469                             pc3 = p3.Translated(vc);
2470                             pc4 = p4.Translated(vc);
2471
2472                             // Color
2473                             setColor(colors.Value(value), Standard_False);
2474
2475                             // Display
2476                             //glNormal3d(xn, yn, zn);
2477                             pc1.Coord(xc, yc, zc);
2478                             glVertex3d(xc, yc, zc);
2479                             pc2.Coord(xc, yc, zc);
2480                             glVertex3d(xc, yc, zc);
2481                             pc3.Coord(xc, yc, zc);
2482                             glVertex3d(xc, yc, zc);
2483                             pc4.Coord(xc, yc, zc);
2484                             glVertex3d(xc, yc, zc);
2485
2486                             if (nearest)
2487                                 break;
2488                         }
2489                                         }
2490                                 }
2491                         }
2492                         break;
2493                 }
2494                 case Zminus:
2495                 {
2496                         for (ix = 0; ix < nbx; ix++)
2497                         {
2498                                 for (iy = 0; iy < nby; iy++)
2499                                 {
2500                                         for (iz = 0; iz < nbz; iz++)
2501                                         {
2502                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2503                             continue;
2504                         value = voxels->Get(ix, iy, iz);
2505                         if (value >= minvalue && value <= maxvalue)
2506                         {
2507                             // Define translation vector
2508                             if (!check_size)
2509                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2510                             vc.SetCoord(xc, yc, zc);
2511
2512                             // Translate
2513                             pc1 = p1.Translated(vc);
2514                             pc2 = p2.Translated(vc);
2515                             pc3 = p3.Translated(vc);
2516                             pc4 = p4.Translated(vc);
2517
2518                             // Color
2519                             setColor(colors.Value(value), Standard_False);
2520
2521                             // Display
2522                             //glNormal3d(xn, yn, zn);
2523                             pc1.Coord(xc, yc, zc);
2524                             glVertex3d(xc, yc, zc);
2525                             pc2.Coord(xc, yc, zc);
2526                             glVertex3d(xc, yc, zc);
2527                             pc3.Coord(xc, yc, zc);
2528                             glVertex3d(xc, yc, zc);
2529                             pc4.Coord(xc, yc, zc);
2530                             glVertex3d(xc, yc, zc);
2531
2532                             if (nearest)
2533                                 break;
2534                         }
2535                                         }
2536                                 }
2537                         }
2538                         break;
2539                 }
2540                 case Zplus:
2541                 {
2542                         for (ix = 0; ix < nbx; ix++)
2543                         {
2544                                 for (iy = 0; iy < nby; iy++)
2545                                 {
2546                                         for (iz = nbz - 1; iz >= 0; iz--)
2547                                         {
2548                         if (check_size && !CheckSize(voxels, ix, iy, iz, xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc))
2549                             continue;
2550                         value = voxels->Get(ix, iy, iz);
2551                         if (value >= minvalue && value <= maxvalue)
2552                         {
2553                             // Define translation vector
2554                             if (!check_size)
2555                                 voxels->GetCenter(ix, iy, iz, xc, yc, zc);
2556                             vc.SetCoord(xc, yc, zc);
2557
2558                             // Translate
2559                             pc1 = p1.Translated(vc);
2560                             pc2 = p2.Translated(vc);
2561                             pc3 = p3.Translated(vc);
2562                             pc4 = p4.Translated(vc);
2563
2564                             // Color
2565                             setColor(colors.Value(value), Standard_False);
2566
2567                             // Display
2568                             //glNormal3d(xn, yn, zn);
2569                             pc1.Coord(xc, yc, zc);
2570                             glVertex3d(xc, yc, zc);
2571                             pc2.Coord(xc, yc, zc);
2572                             glVertex3d(xc, yc, zc);
2573                             pc3.Coord(xc, yc, zc);
2574                             glVertex3d(xc, yc, zc);
2575                             pc4.Coord(xc, yc, zc);
2576                             glVertex3d(xc, yc, zc);
2577
2578                             if (nearest)
2579                                 break;
2580                         }
2581                                         }
2582                                 }
2583                         }
2584                         break;
2585                 }
2586     }
2587     glEnd();
2588 }
2589
2590 static void genListIndex(GLint& index)
2591 {
2592     GLint i = 0;
2593     while (++i <= INT_MAX)
2594     {
2595         if (!glIsList(i))
2596         {
2597             index = i;
2598             break;
2599         }
2600     }
2601 }
2602
2603 static void setPlaneNormal(const VoxelDirection& dir, 
2604                            const Standard_Real dx, const Standard_Real dy, const Standard_Real dz,
2605                            gp_Pln& plane, gp_Pnt& p1, gp_Pnt& p2, gp_Pnt& p3, gp_Pnt& p4)
2606 {
2607     gp_Ax3 axes = plane.Position();
2608     Standard_Real dx2 = 0.5 * dx, dy2 = 0.5 * dy, dz2 = 0.5 * dz;
2609     switch (dir)
2610     {
2611         case Xminus:
2612             p1.SetCoord(-dx2, -dy2, dz2);
2613             p2.SetCoord(-dx2, -dy2, -dz2);
2614             p3.SetCoord(-dx2, dy2, -dz2);
2615             p4.SetCoord(-dx2, dy2, dz2);
2616             axes.SetDirection(-gp::DX());
2617             break;
2618         case Xplus:
2619             p1.SetCoord(dx2, -dy2, dz2);
2620             p2.SetCoord(dx2, -dy2, -dz2);
2621             p3.SetCoord(dx2, dy2, -dz2);
2622             p4.SetCoord(dx2, dy2, dz2);
2623             axes.SetDirection(gp::DX());
2624             break;
2625         case Yminus:
2626             p1.SetCoord(dx2, -dy2, dz2);
2627             p2.SetCoord(dx2, -dy2, -dz2);
2628             p3.SetCoord(-dx2, -dy2, -dz2);
2629             p4.SetCoord(-dx2, -dy2, dz2);
2630             axes.SetDirection(-gp::DY());
2631             break;
2632         case Yplus:
2633             p1.SetCoord(dx2, dy2, dz2);
2634             p2.SetCoord(dx2, dy2, -dz2);
2635             p3.SetCoord(-dx2, dy2, -dz2);
2636             p4.SetCoord(-dx2, dy2, dz2);
2637             axes.SetDirection(gp::DY());
2638             break;
2639         case Zminus:
2640             p1.SetCoord(dx2, dy2, -dz2);
2641             p2.SetCoord(-dx2, dy2, -dz2);
2642             p3.SetCoord(-dx2, -dy2, -dz2);
2643             p4.SetCoord(dx2, -dy2, -dz2);
2644             axes.SetDirection(-gp::DZ());
2645             break;
2646         case Zplus:
2647             p1.SetCoord(dx2, dy2, dz2);
2648             p2.SetCoord(-dx2, dy2, dz2);
2649             p3.SetCoord(-dx2, -dy2, dz2);
2650             p4.SetCoord(dx2, -dy2, dz2);
2651             axes.SetDirection(gp::DZ());
2652             break;
2653     }
2654 }
2655
2656 /**************************************************************************/
2657 void VoxelClient_VisDrawer::DisplayVoxels(const Standard_Boolean theHighlight)
2658 {
2659     if(!myData)
2660         return;
2661
2662     glEnable(GL_DEPTH_TEST);
2663
2664         // Boolean voxels
2665         if (myData->myBoolVoxels)
2666     {
2667                 // Points
2668                 if (myData->myDisplay.myDisplayMode == Voxel_VDM_POINTS ||
2669             myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS)
2670                 {
2671                         glDisable(GL_LIGHTING);
2672             if (myData->myDisplay.mySmoothPoints)
2673                             glEnable(GL_POINT_SMOOTH);
2674             else
2675                 glDisable(GL_POINT_SMOOTH);
2676
2677                         // Draw the points of voxels (center points of the voxels)
2678                         // starting visualization from the side looking out from the user.
2679                         setColor(myData->myDisplay.myColor, theHighlight);
2680                         glPointSize((Standard_ShortReal) myData->myDisplay.myPointSize);
2681
2682             // Display
2683             DisplayPoints(myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS);
2684         }
2685         }
2686
2687     // Color values
2688         if (myData->myColorVoxels)
2689     {
2690                 // Points
2691                 if (myData->myDisplay.myDisplayMode == Voxel_VDM_POINTS ||
2692             myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS)
2693                 {
2694                         glDisable(GL_LIGHTING);
2695             if (myData->myDisplay.mySmoothPoints)
2696                             glEnable(GL_POINT_SMOOTH);
2697             else
2698                 glDisable(GL_POINT_SMOOTH);
2699
2700                         // Draw the points of voxels (center points of the voxels)
2701                         // starting visualization from the side looking out from the user.
2702                         glPointSize((Standard_ShortReal) myData->myDisplay.myPointSize);
2703
2704             // Display
2705             DisplayPoints(myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS);
2706         }
2707         }
2708
2709         // Recursive Octree Boolean voxels
2710         if (myData->myROctBoolVoxels)
2711     {
2712                 // Points
2713                 if (myData->myDisplay.myDisplayMode == Voxel_VDM_POINTS ||
2714             myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS)
2715                 {
2716                         glDisable(GL_LIGHTING);
2717             if (myData->myDisplay.mySmoothPoints)
2718                             glEnable(GL_POINT_SMOOTH);
2719             else
2720                 glDisable(GL_POINT_SMOOTH);
2721
2722                         // Draw the points of voxels (center points of the voxels)
2723                         // starting visualization from the side looking out from the user.
2724                         setColor(myData->myDisplay.myColor, theHighlight);
2725                         glPointSize((Standard_ShortReal) myData->myDisplay.myPointSize);
2726
2727             // Display
2728             DisplayPoints(myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTPOINTS);
2729         }
2730         }
2731
2732     // Shading drawn by boxes
2733     if (myData->myDisplay.myDisplayMode == Voxel_VDM_BOXES || 
2734         myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTBOXES)
2735     {
2736                 glEnable(GL_LIGHTING);
2737         glEnable(GL_COLOR_MATERIAL);
2738
2739                 // Draw quadrangles of voxels looking to the user.
2740                 setColor(myData->myDisplay.myColor, theHighlight);
2741
2742         // Display
2743         DisplayBoxes(myData->myDisplay.myDisplayMode == Voxel_VDM_NEARESTBOXES);
2744
2745         glDisable(GL_COLOR_MATERIAL);
2746     }
2747
2748     // Highlighted voxel
2749     HighlightVoxel();
2750 }
2751
2752 /**************************************************************************/
2753 void VoxelClient_VisDrawer::DisplayPoints(const Standard_Boolean nearest)
2754 {
2755     //OSD_Timer timer;
2756     //timer.Start();
2757
2758     // Find the side of the cube which normal looks to (or out) the user's eye.
2759         gp_Dir viewnormal;
2760         getNormal(viewnormal);
2761
2762     // Range of displayed data
2763     Standard_Real xmin = myData->myDisplay.myDisplayedXMin;
2764     Standard_Real xmax = myData->myDisplay.myDisplayedXMax;
2765     Standard_Real ymin = myData->myDisplay.myDisplayedYMin;
2766     Standard_Real ymax = myData->myDisplay.myDisplayedYMax;
2767     Standard_Real zmin = myData->myDisplay.myDisplayedZMin;
2768     Standard_Real zmax = myData->myDisplay.myDisplayedZMax;
2769
2770     // Boolean points
2771         if (myData->myBoolVoxels)
2772     {
2773         if (nearest || myData->myDisplay.myDegenerateMode)
2774         {
2775                 VoxelDirection vdir1, vdir2, vdir3;
2776             getVoxel3Directions(viewnormal, vdir1, vdir2, vdir3);
2777
2778             if (myData->myDisplay.myUsageOfGLlists)
2779             {
2780                 // Clean all allocated GL lists for the case of first call.
2781                 if (myData->myDisplay.myBoolNearestPointsFirst)
2782                 {
2783                     for (Standard_Integer idir = Xminus; idir <= Zplus; idir++)
2784                     {
2785                         if (myData->myDisplay.myBoolNearestPointsList[idir] > 0)
2786                         {
2787                             glDeleteLists(myData->myDisplay.myBoolNearestPointsList[idir], 1);
2788                             myData->myDisplay.myBoolNearestPointsList[idir] = -1;
2789                         }
2790                     }
2791                     myData->myDisplay.myBoolNearestPointsFirst = Standard_False;
2792                 }
2793
2794                 // Generate GL lists if needed.
2795                 if (myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir1] < 0)
2796                 {
2797                     genListIndex(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir1]);
2798                     glNewList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir1], GL_COMPILE);
2799                     drawBoolPoints(vdir1, Standard_True, myData->myBoolVoxels,
2800                                    xmin, xmax, ymin, ymax, zmin, zmax);
2801                     glEndList();
2802                 }
2803                 if (myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir2] < 0)
2804                 {
2805                     genListIndex(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir2]);
2806                     glNewList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir2], GL_COMPILE);
2807                     drawBoolPoints(vdir2, Standard_True, myData->myBoolVoxels,
2808                                    xmin, xmax, ymin, ymax, zmin, zmax);
2809                     glEndList();
2810                 }
2811                 if (myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir3] < 0)
2812                 {
2813                     genListIndex(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir3]);
2814                     glNewList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir3], GL_COMPILE);
2815                     drawBoolPoints(vdir3, Standard_True, myData->myBoolVoxels,
2816                                    xmin, xmax, ymin, ymax, zmin, zmax);
2817                     glEndList();
2818                 }
2819                 glCallList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir1]);
2820                 glCallList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir2]);
2821                 glCallList(myData->myDisplay.myBoolNearestPointsList[(Standard_Integer) vdir3]);
2822             }
2823             else
2824             {
2825                 drawBoolPoints(vdir1, Standard_True, myData->myBoolVoxels,
2826                                xmin, xmax, ymin, ymax, zmin, zmax);
2827                 drawBoolPoints(vdir2, Standard_True, myData->myBoolVoxels,
2828                                xmin, xmax, ymin, ymax, zmin, zmax);
2829                 drawBoolPoints(vdir3, Standard_True, myData->myBoolVoxels,
2830                                xmin, xmax, ymin, ymax, zmin, zmax);
2831             }
2832         }
2833         else
2834         {
2835             if (myData->myDisplay.myUsageOfGLlists)
2836             {
2837                 if (myData->myDisplay.myBoolPointsFirst)
2838                 {
2839                     // Delete previous GL list.
2840                     if (myData->myDisplay.myBoolPointsList > 0)
2841                     {
2842                         glDeleteLists(myData->myDisplay.myBoolPointsList, 1);
2843                         myData->myDisplay.myBoolPointsList = -1;
2844                     }
2845
2846                     // Generate a new GL list
2847                     genListIndex(myData->myDisplay.myBoolPointsList);
2848                     glNewList(myData->myDisplay.myBoolPointsList, GL_COMPILE);
2849                     VoxelDirection vdir = getVoxelDirection(viewnormal);
2850                     drawBoolPoints(vdir, Standard_False, myData->myBoolVoxels,
2851                                    xmin, xmax, ymin, ymax, zmin, zmax);
2852                     glEndList();
2853
2854                     // The first call has just been passed...
2855                     myData->myDisplay.myBoolPointsFirst = Standard_False;
2856                 }
2857                 glCallList(myData->myDisplay.myBoolPointsList);
2858             }
2859             else
2860             {
2861                 VoxelDirection vdir = getVoxelDirection(viewnormal);
2862                 drawBoolPoints(vdir, Standard_False, myData->myBoolVoxels,
2863                                xmin, xmax, ymin, ymax, zmin, zmax);
2864             }
2865         }
2866         }
2867
2868     // Color points
2869         if (myData->myColorVoxels)
2870     {
2871         if (nearest || myData->myDisplay.myDegenerateMode)
2872         {
2873                 VoxelDirection vdir1, vdir2, vdir3;
2874             getVoxel3Directions(viewnormal, vdir1, vdir2, vdir3);
2875
2876             if (myData->myDisplay.myUsageOfGLlists)
2877             {
2878                 // Clean all allocated GL lists for the case of first call.
2879                 if (myData->myDisplay.myColorNearestPointsFirst)
2880                 {
2881                     for (Standard_Integer idir = Xminus; idir <= Zplus; idir++)
2882                     {
2883                         if (myData->myDisplay.myColorNearestPointsList[idir] > 0)
2884                         {
2885                             glDeleteLists(myData->myDisplay.myColorNearestPointsList[idir], 1);
2886                             myData->myDisplay.myColorNearestPointsList[idir] = -1;
2887                         }
2888                     }
2889                     myData->myDisplay.myColorNearestPointsFirst = Standard_False;
2890                 }
2891
2892                 // Generate GL lists if needed.
2893                 if (myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir1] < 0)
2894                 {
2895                     genListIndex(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir1]);
2896                     glNewList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir1], GL_COMPILE);
2897                     drawColorPoints(vdir1, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2898                                     myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2899                                     xmin, xmax, ymin, ymax, zmin, zmax);
2900                     glEndList();
2901                 }
2902                 if (myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir2] < 0)
2903                 {
2904                     genListIndex(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir2]);
2905                     glNewList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir2], GL_COMPILE);
2906                     drawColorPoints(vdir2, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2907                                     myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2908                                     xmin, xmax, ymin, ymax, zmin, zmax);
2909                     glEndList();
2910                 }
2911                 if (myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir3] < 0)
2912                 {
2913                     genListIndex(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir3]);
2914                     glNewList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir3], GL_COMPILE);
2915                     drawColorPoints(vdir3, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2916                                     myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2917                                     xmin, xmax, ymin, ymax, zmin, zmax);
2918                     glEndList();
2919                 }
2920             
2921                 glCallList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir1]);
2922                 glCallList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir2]);
2923                 glCallList(myData->myDisplay.myColorNearestPointsList[(Standard_Integer) vdir3]);
2924             }
2925             else
2926             {
2927                 drawColorPoints(vdir1, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2928                                 myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2929                                 xmin, xmax, ymin, ymax, zmin, zmax);
2930                 drawColorPoints(vdir2, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2931                                 myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2932                                 xmin, xmax, ymin, ymax, zmin, zmax);
2933                 drawColorPoints(vdir3, Standard_True, myData->myColorVoxels, myData->myDisplay.myColors,
2934                                 myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2935                                 xmin, xmax, ymin, ymax, zmin, zmax);
2936             }
2937         }
2938         else
2939         {
2940             if (myData->myDisplay.myUsageOfGLlists)
2941             {
2942                 if (myData->myDisplay.myColorPointsFirst)
2943                 {
2944                     // Delete previous GL list.
2945                     if (myData->myDisplay.myColorPointsList > 0)
2946                     {
2947                         glDeleteLists(myData->myDisplay.myColorPointsList, 1);
2948                         myData->myDisplay.myColorPointsList = -1;
2949                     }
2950
2951                     // Generate a new GL list
2952                     genListIndex(myData->myDisplay.myColorPointsList);
2953                     glNewList(myData->myDisplay.myColorPointsList, GL_COMPILE);
2954                     VoxelDirection vdir = getVoxelDirection(viewnormal);
2955                     drawColorPoints(vdir, Standard_False, myData->myColorVoxels, myData->myDisplay.myColors,
2956                                     myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2957                                     xmin, xmax, ymin, ymax, zmin, zmax);
2958                     glEndList();
2959
2960                     // The first call has just been passed...
2961                     myData->myDisplay.myColorPointsFirst = Standard_False;
2962                 }
2963                 glCallList(myData->myDisplay.myColorPointsList);
2964             }
2965             else
2966             {
2967                 VoxelDirection vdir = getVoxelDirection(viewnormal);
2968                 drawColorPoints(vdir, Standard_False, myData->myColorVoxels, myData->myDisplay.myColors,
2969                                 myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
2970                                 xmin, xmax, ymin, ymax, zmin, zmax);
2971             }
2972         }
2973         }
2974
2975     // Recursive Octree Boolean points
2976         if (myData->myROctBoolVoxels)
2977     {
2978         if (nearest || myData->myDisplay.myDegenerateMode)
2979         {
2980                 VoxelDirection vdir1, vdir2, vdir3;
2981             getVoxel3Directions(viewnormal, vdir1, vdir2, vdir3);
2982
2983             if (myData->myDisplay.myUsageOfGLlists)
2984             {
2985                 // Clean all allocated GL lists for the case of first call.
2986                 if (myData->myDisplay.myROctBoolNearestPointsFirst)
2987                 {
2988                     for (Standard_Integer idir = Xminus; idir <= Zplus; idir++)
2989                     {
2990                         if (myData->myDisplay.myROctBoolNearestPointsList[idir] > 0)
2991                         {
2992                             glDeleteLists(myData->myDisplay.myROctBoolNearestPointsList[idir], 1);
2993                             myData->myDisplay.myROctBoolNearestPointsList[idir] = -1;
2994                         }
2995                     }
2996                     myData->myDisplay.myROctBoolNearestPointsFirst = Standard_False;
2997                 }
2998
2999                 // Generate GL lists if needed.
3000                 if (myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir1] < 0)
3001                 {
3002                     genListIndex(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir1]);
3003                     glNewList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir1], GL_COMPILE);
3004                     drawROctBoolPoints(vdir1, Standard_True, myData->myROctBoolVoxels,
3005                                        xmin, xmax, ymin, ymax, zmin, zmax);
3006                     glEndList();
3007                 }
3008                 if (myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir2] < 0)
3009                 {
3010                     genListIndex(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir2]);
3011                     glNewList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir2], GL_COMPILE);
3012                     drawROctBoolPoints(vdir2, Standard_True, myData->myROctBoolVoxels,
3013                                        xmin, xmax, ymin, ymax, zmin, zmax);
3014                     glEndList();
3015                 }
3016                 if (myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir3] < 0)
3017                 {
3018                     genListIndex(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir3]);
3019                     glNewList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir3], GL_COMPILE);
3020                     drawROctBoolPoints(vdir3, Standard_True, myData->myROctBoolVoxels,
3021                                        xmin, xmax, ymin, ymax, zmin, zmax);
3022                     glEndList();
3023                 }
3024                 glCallList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir1]);
3025                 glCallList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir2]);
3026                 glCallList(myData->myDisplay.myROctBoolNearestPointsList[(Standard_Integer) vdir3]);
3027             }
3028             else
3029             {
3030                 drawROctBoolPoints(vdir1, Standard_True, myData->myROctBoolVoxels,
3031                                    xmin, xmax, ymin, ymax, zmin, zmax);
3032                 drawROctBoolPoints(vdir2, Standard_True, myData->myROctBoolVoxels,
3033                                    xmin, xmax, ymin, ymax, zmin, zmax);
3034                 drawROctBoolPoints(vdir3, Standard_True, myData->myROctBoolVoxels,
3035                                    xmin, xmax, ymin, ymax, zmin, zmax);
3036             }
3037         }
3038         else
3039         {
3040             if (myData->myDisplay.myUsageOfGLlists)
3041             {
3042                 if (myData->myDisplay.myROctBoolPointsFirst)
3043                 {
3044                     // Delete previous GL list.
3045                     if (myData->myDisplay.myROctBoolPointsList > 0)
3046                     {
3047                         glDeleteLists(myData->myDisplay.myROctBoolPointsList, 1);
3048                         myData->myDisplay.myROctBoolPointsList = -1;
3049                     }
3050
3051                     // Generate a new GL list
3052                     genListIndex(myData->myDisplay.myROctBoolPointsList);
3053                     glNewList(myData->myDisplay.myROctBoolPointsList, GL_COMPILE);
3054                     VoxelDirection vdir = getVoxelDirection(viewnormal);
3055                     drawROctBoolPoints(vdir, Standard_False, myData->myROctBoolVoxels,
3056                                        xmin, xmax, ymin, ymax, zmin, zmax);
3057                     glEndList();
3058
3059                     // The first call has just been passed...
3060                     myData->myDisplay.myROctBoolPointsFirst = Standard_False;
3061                 }
3062                 glCallList(myData->myDisplay.myROctBoolPointsList);
3063             }
3064             else
3065             {
3066                 VoxelDirection vdir = getVoxelDirection(viewnormal);
3067                 drawROctBoolPoints(vdir, Standard_False, myData->myROctBoolVoxels,
3068                                    xmin, xmax, ymin, ymax, zmin, zmax);
3069             }
3070         }
3071         }
3072
3073     //timer.Stop();
3074         //Standard_Real seconds, cpu;
3075         //Standard_Integer minutes, hours;
3076         //timer.Show(seconds, minutes, hours, cpu);
3077     //cout<<"DisplayPoints()"<<" took "<<minutes<<" minutes, "<<seconds<<" seconds"<<endl;
3078 }
3079
3080 /**************************************************************************/
3081 void VoxelClient_VisDrawer::DisplayBoxes(const Standard_Boolean nearest)
3082 {
3083     // Range of displayed data
3084     Standard_Real xmin = myData->myDisplay.myDisplayedXMin;
3085     Standard_Real xmax = myData->myDisplay.myDisplayedXMax;
3086     Standard_Real ymin = myData->myDisplay.myDisplayedYMin;
3087     Standard_Real ymax = myData->myDisplay.myDisplayedYMax;
3088     Standard_Real zmin = myData->myDisplay.myDisplayedZMin;
3089     Standard_Real zmax = myData->myDisplay.myDisplayedZMax;
3090
3091     // Find the side of the cube which normal looks to (or out) the user's eye.
3092         gp_Dir viewnormal;
3093         getNormal(viewnormal);
3094
3095     // Get three sides of the box looking to the user.
3096         VoxelDirection vdir1, vdir2, vdir3;
3097     getVoxel3Directions(viewnormal, vdir1, vdir2, vdir3);
3098
3099     // Three quadrangles with normals looking to the user
3100     gp_Pln plane1(gp::Origin(), viewnormal);
3101     gp_Pln plane2(plane1), plane3(plane1);
3102
3103     // Boolean boxes
3104         if (myData->myBoolVoxels &&
3105         myData->myBoolVoxels->GetNbX() &&
3106         myData->myBoolVoxels->GetNbY() &&
3107         myData->myBoolVoxels->GetNbZ())
3108     {
3109         // Compute size
3110         Standard_Real dx = myData->myBoolVoxels->GetXLen() / (Standard_Real) myData->myBoolVoxels->GetNbX();
3111         Standard_Real dy = myData->myBoolVoxels->GetYLen() / (Standard_Real) myData->myBoolVoxels->GetNbY();
3112         Standard_Real dz = myData->myBoolVoxels->GetZLen() / (Standard_Real) myData->myBoolVoxels->GetNbZ();
3113         Standard_Real d  = 0.01 * (Standard_Real) myData->myDisplay.myQuadrangleSize;
3114         dx *= d;
3115         dy *= d;
3116         dz *= d;
3117
3118         // Translatethe quadrangles to the side of the voxel
3119         gp_Pnt p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34;
3120         setPlaneNormal(vdir1, dx, dy, dz, plane1, p11, p12, p13, p14);
3121         setPlaneNormal(vdir2, dx, dy, dz, plane2, p21, p22, p23, p24);
3122         setPlaneNormal(vdir3, dx, dy, dz, plane3, p31, p32, p33, p34);
3123
3124         // Display
3125         Standard_Boolean skin = nearest || myData->myDisplay.myDegenerateMode;
3126         drawBoolQuadrangles(myData->myBoolVoxels, vdir1, plane1.Axis().Direction(), 
3127                             skin, p11, p12, p13, p14,
3128                             xmin, xmax, ymin, ymax, zmin, zmax);
3129         drawBoolQuadrangles(myData->myBoolVoxels, vdir2, plane2.Axis().Direction(), 
3130                             skin, p21, p22, p23, p24,
3131                             xmin, xmax, ymin, ymax, zmin, zmax);
3132         drawBoolQuadrangles(myData->myBoolVoxels, vdir3, plane3.Axis().Direction(), 
3133                             skin, p31, p32, p33, p34,
3134                             xmin, xmax, ymin, ymax, zmin, zmax);
3135     }
3136     // Color quadrangles
3137         else if (myData->myColorVoxels &&
3138              myData->myColorVoxels->GetNbX() &&
3139              myData->myColorVoxels->GetNbY() &&
3140              myData->myColorVoxels->GetNbZ())
3141     {
3142         // Compute size
3143         Standard_Real dx = myData->myColorVoxels->GetXLen() / (Standard_Real) myData->myColorVoxels->GetNbX();
3144         Standard_Real dy = myData->myColorVoxels->GetYLen() / (Standard_Real) myData->myColorVoxels->GetNbY();
3145         Standard_Real dz = myData->myColorVoxels->GetZLen() / (Standard_Real) myData->myColorVoxels->GetNbZ();
3146         Standard_Real d  = 0.01 * (Standard_Real) myData->myDisplay.myQuadrangleSize;
3147         dx *= d;
3148         dy *= d;
3149         dz *= d;
3150
3151         // Translatethe quadrangles to the side of the voxel
3152         gp_Pnt p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34;
3153         setPlaneNormal(vdir1, dx, dy, dz, plane1, p11, p12, p13, p14);
3154         setPlaneNormal(vdir2, dx, dy, dz, plane2, p21, p22, p23, p24);
3155         setPlaneNormal(vdir3, dx, dy, dz, plane3, p31, p32, p33, p34);
3156
3157         // Display
3158         Standard_Boolean skin = nearest || myData->myDisplay.myDegenerateMode;
3159         drawColorQuadrangles(myData->myColorVoxels, vdir1, plane1.Axis().Direction(), skin, 
3160                              myData->myDisplay.myColors, p11, p12, p13, p14,
3161                              myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
3162                              xmin, xmax, ymin, ymax, zmin, zmax);
3163         drawColorQuadrangles(myData->myColorVoxels, vdir2, plane2.Axis().Direction(), skin, 
3164                              myData->myDisplay.myColors, p21, p22, p23, p24,
3165                              myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
3166                              xmin, xmax, ymin, ymax, zmin, zmax);
3167         drawColorQuadrangles(myData->myColorVoxels, vdir3, plane3.Axis().Direction(), skin, 
3168                              myData->myDisplay.myColors, p31, p32, p33, p34,
3169                              myData->myDisplay.myColorMinValue, myData->myDisplay.myColorMaxValue,
3170                              xmin, xmax, ymin, ymax, zmin, zmax);
3171     }
3172     // Recursive Octree Boolean boxes
3173         else if (myData->myROctBoolVoxels &&
3174              myData->myROctBoolVoxels->GetNbX() &&
3175              myData->myROctBoolVoxels->GetNbY() &&
3176              myData->myROctBoolVoxels->GetNbZ())
3177     {
3178         // Compute size
3179         Standard_Real dx = myData->myROctBoolVoxels->GetXLen() / (Standard_Real) myData->myROctBoolVoxels->GetNbX();
3180         Standard_Real dy = myData->myROctBoolVoxels->GetYLen() / (Standard_Real) myData->myROctBoolVoxels->GetNbY();
3181         Standard_Real dz = myData->myROctBoolVoxels->GetZLen() / (Standard_Real) myData->myROctBoolVoxels->GetNbZ();
3182         Standard_Real d  = 0.01 * (Standard_Real) myData->myDisplay.myQuadrangleSize;
3183         dx *= d;
3184         dy *= d;
3185         dz *= d;
3186
3187         // Translatethe quadrangles to the side of the voxel
3188         gp_Pnt p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34;
3189         setPlaneNormal(vdir1, dx, dy, dz, plane1, p11, p12, p13, p14);
3190         setPlaneNormal(vdir2, dx, dy, dz, plane2, p21, p22, p23, p24);
3191         setPlaneNormal(vdir3, dx, dy, dz, plane3, p31, p32, p33, p34);
3192
3193         // Display
3194         Standard_Boolean skin = nearest || myData->myDisplay.myDegenerateMode;
3195         drawROctBoolQuadrangles(myData->myROctBoolVoxels, vdir1, plane1.Axis().Direction(), 
3196                                 skin, p11, p12, p13, p14,
3197                                 xmin, xmax, ymin, ymax, zmin, zmax);
3198         drawROctBoolQuadrangles(myData->myROctBoolVoxels, vdir2, plane2.Axis().Direction(), 
3199                                 skin, p21, p22, p23, p24,
3200                                 xmin, xmax, ymin, ymax, zmin, zmax);
3201         drawROctBoolQuadrangles(myData->myROctBoolVoxels, vdir3, plane3.Axis().Direction(), 
3202                                 skin, p31, p32, p33, p34,
3203                                 xmin, xmax, ymin, ymax, zmin, zmax);
3204     }
3205 }
3206
3207 /**************************************************************************/
3208 void VoxelClient_VisDrawer::DisplayTriangulation(const Standard_Boolean theHighlight)
3209 {
3210     if(!myData || myData->myTriangulation.IsNull())
3211         return;
3212
3213     glEnable(GL_DEPTH_TEST);
3214     glEnable(GL_LIGHTING);
3215
3216     const TColgp_Array1OfPnt& nodes = myData->myTriangulation->Nodes();
3217     const Poly_Array1OfTriangle& triangles = myData->myTriangulation->Triangles();
3218     Standard_Integer itriangle = triangles.Lower(), nb_triangles = triangles.Upper();
3219
3220     Standard_Boolean compute_normals = Standard_False;
3221     if (myData->myNormalsOfNodes.IsNull())
3222     {
3223         compute_normals = Standard_True;
3224         myData->myNormalsOfNodes = new TColgp_HArray1OfDir(itriangle, nb_triangles);
3225
3226         // Release the GL list
3227         if (myData->myDisplay.myTriangulationList > 0)
3228         {
3229             glDeleteLists(myData->myDisplay.myTriangulationList, 1);
3230             myData->myDisplay.myTriangulationList = -1;
3231         }
3232
3233         // Generate a new GL list
3234         if (myData->myDisplay.myUsageOfGLlists)
3235         {
3236             genListIndex(myData->myDisplay.myTriangulationList);
3237             glNewList(myData->myDisplay.myTriangulationList, GL_COMPILE);
3238         }
3239     }
3240     TColgp_Array1OfDir& normals = myData->myNormalsOfNodes->ChangeArray1();
3241
3242     if (!myData->myDisplay.myUsageOfGLlists || compute_normals)
3243     {
3244
3245         glBegin(GL_TRIANGLES);
3246
3247         Standard_Integer n1, n2, n3;
3248         Standard_Real x, y, z;
3249         for (; itriangle <= nb_triangles; itriangle++)
3250         {
3251             const Poly_Triangle& t = triangles.Value(itriangle);
3252             t.Get(n1, n2, n3);
3253
3254             const gp_Pnt& p1 = nodes.Value(n1);
3255             const gp_Pnt& p2 = nodes.Value(n2);
3256             const gp_Pnt& p3 = nodes.Value(n3);
3257
3258             // Make the normal:
3259             if (compute_normals)
3260             {
3261                 gp_Vec v1(p1, p2), v2(p1, p3);
3262                 v1.Cross(v2);
3263                 if (v1.SquareMagnitude() > 1.e-14)
3264                     v1.Normalize();
3265                 else
3266                     v1.SetCoord(0.0, 0.0, 1.0);
3267                 normals.SetValue(itriangle, v1);
3268                 v1.Coord(x, y, z);
3269             }
3270             else
3271             {
3272                 normals.Value(itriangle).Coord(x, y, z);
3273             }
3274             glNormal3d(x, y, z);
3275
3276             // P1
3277             p1.Coord(x, y, z);
3278             glVertex3d(x, y, z);
3279
3280             // P2
3281             p2.Coord(x, y, z);
3282             glVertex3d(x, y, z);
3283
3284             // P3
3285             p3.Coord(x, y, z);
3286             glVertex3d(x, y, z);
3287         }
3288
3289         glEnd();
3290
3291         if (myData->myDisplay.myUsageOfGLlists)
3292             glEndList();
3293     }
3294
3295     if (myData->myDisplay.myUsageOfGLlists)
3296         glCallList(myData->myDisplay.myTriangulationList);
3297 }
3298
3299 void VoxelClient_VisDrawer::HighlightVoxel()
3300 {
3301     if (myData &&
3302         myData->myDisplay.myHighlightx >= 0 &&
3303         myData->myDisplay.myHighlighty >= 0 &&
3304         myData->myDisplay.myHighlightz >= 0)
3305     {
3306         Standard_Integer nbx, nby, nbz;
3307         Standard_Real xlen, ylen, zlen, xc, yc, zc;
3308         Voxel_DS* ds = (Voxel_DS*) myData->myBoolVoxels;
3309         if (myData->myColorVoxels)
3310             ds = (Voxel_DS*) myData->myColorVoxels;
3311         if (myData->myROctBoolVoxels)
3312             ds = (Voxel_DS*) myData->myROctBoolVoxels;
3313         nbx = ds->GetNbX();
3314         nby = ds->GetNbY();
3315         nbz = ds->GetNbZ();
3316         xlen = ds->GetXLen();
3317         ylen = ds->GetYLen();
3318         zlen = ds->GetZLen();
3319         ds->GetCenter(myData->myDisplay.myHighlightx, 
3320                       myData->myDisplay.myHighlighty, 
3321                       myData->myDisplay.myHighlightz, 
3322                       xc, yc, zc);
3323
3324         Standard_Real half_voxelx = xlen / Standard_Real(nbx) / 2.0;
3325         Standard_Real half_voxely = ylen / Standard_Real(nby) / 2.0;
3326         Standard_Real half_voxelz = zlen / Standard_Real(nbz) / 2.0;
3327         Standard_Real x1 = xc - half_voxelx, y1 = yc - half_voxely, z1 = zc - half_voxelz;
3328         Standard_Real x2 = xc + half_voxelx, y2 = yc + half_voxely, z2 = zc + half_voxelz;
3329
3330         setColor(Quantity_NOC_BLUE1, Standard_True);
3331         setTypeOfLine(Aspect_TOL_SOLID);
3332         setWidthOfLine(3);
3333
3334         glBegin(GL_LINES);
3335
3336         glVertex3d(x1, y1, z1);
3337         glVertex3d(x1, y2, z1);
3338
3339         glVertex3d(x1, y1, z1);
3340         glVertex3d(x2, y1, z1);
3341
3342         glVertex3d(x1, y1, z1);
3343         glVertex3d(x1, y1, z2);
3344
3345         glVertex3d(x1, y2, z1);
3346         glVertex3d(x2, y2, z1);
3347
3348         glVertex3d(x2, y1, z1);
3349         glVertex3d(x2, y2, z1);
3350
3351         glVertex3d(x2, y2, z1);
3352         glVertex3d(x2, y2, z2);
3353
3354         glVertex3d(x1, y1, z2);
3355         glVertex3d(x1, y2, z2);
3356
3357         glVertex3d(x1, y1, z2);
3358         glVertex3d(x2, y1, z2);
3359
3360         glVertex3d(x2, y1, z2);
3361         glVertex3d(x2, y2, z2);
3362
3363         glVertex3d(x2, y2, z2);
3364         glVertex3d(x1, y2, z2);
3365
3366         glVertex3d(x1, y2, z2);
3367         glVertex3d(x1, y2, z1);
3368
3369         glVertex3d(x2, y1, z1);
3370         glVertex3d(x2, y1, z2);
3371
3372         glEnd();
3373     }
3374 }