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