52b032edb00c331cf7caaa30f55a43cccad54250
[occt.git] / samples / qt / VoxelDemo / src / Application.cpp
1 #include "Application.h"
2 #include "ConversionThread.h"
3 #include "Timer.h"
4
5 #include <QPixmap.h>
6 #include <QToolButton.h>
7 #include <QWhatsThis.h>
8 #include <QMenu.h>
9 #include <QMenuBar.h>
10 #include <QStatusBar.h>
11 #include <QApplication.h>
12 #include <QFileDialog.h>
13 #include <QMessageBox.h>
14 #include <QInputDialog.h>
15 #include <QCloseEvent>
16
17 #include <Voxel_BoolDS.hxx>
18 #include <Voxel_ColorDS.hxx>
19 #include <Voxel_FloatDS.hxx>
20 #include <Voxel_OctBoolDS.hxx>
21 #include <Voxel_ROctBoolDS.hxx>
22 #include <Voxel_BooleanOperation.hxx>
23 #include <Voxel_CollisionDetection.hxx>
24 #include <Voxel_FastConverter.hxx>
25 #include <Voxel_Writer.hxx>
26 #include <Voxel_Reader.hxx>
27 #include <VoxelClient_VisDrawer.h>
28
29 #include <BRepTools.hxx>
30 #include <BRepBndLib.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRepPrimAPI_MakeBox.hxx>
33 #include <BRepPrimAPI_MakeTorus.hxx>
34 #include <BRepPrimAPI_MakeSphere.hxx>
35 #include <BRepPrimAPI_MakeCylinder.hxx>
36 #include <Aspect_ColorScale.hxx>
37
38 #include <Windows.h>
39
40 Application::Application()
41     : QMainWindow( 0 )
42 {
43     // File
44     QMenu * file = menuBar()->addMenu( "&File" );
45
46     QAction* a;
47     // Box
48     a = new QAction("Box", this);
49     connect(a, SIGNAL(triggered()), this, SLOT(box()));
50     file->addAction(a);
51     // Cylinder
52     a = new QAction("Cylinder", this);
53     connect(a, SIGNAL(triggered()), this, SLOT(cylinder()));
54     file->addAction(a);
55     // Torus
56     a = new QAction("Torus", this);
57     connect(a, SIGNAL(triggered()), this, SLOT(torus()));
58     file->addAction(a);
59     // Sphere
60     a = new QAction("Sphere", this);
61     connect(a, SIGNAL(triggered()), this, SLOT(sphere()));
62     file->addAction(a);
63     // Load shape...
64     a = new QAction("Load shape...", this);
65     a->setShortcut(tr("Ctrl+O"));
66     connect(a, SIGNAL(triggered()), this, SLOT(choose()));
67     file->addAction(a);
68
69     file->addSeparator();
70
71     // Open
72     a = new QAction("Open", this);
73     connect(a, SIGNAL(triggered()), this, SLOT(open()));
74     file->addAction(a);
75
76     // Save
77     a = new QAction("Save", this);
78     connect(a, SIGNAL(triggered()), this, SLOT(save()));
79     file->addAction(a);
80
81     file->addSeparator();
82
83     // Quit
84     a = new QAction("&Quit", this);
85     a->setShortcut(tr("Ctrl+Q"));
86     connect(a, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
87     file->addAction(a);
88
89     menuBar()->addSeparator();
90
91
92 #ifdef TEST
93     QMenu * test = menuBar()->addMenu( "Test" );
94
95     a = new QAction("Test boolean", this);
96     connect(a, SIGNAL(triggered()), this, SLOT(testBoolDS()));
97     test->addAction(a);
98
99     a = new QAction("Test color", this);
100     connect(a, SIGNAL(triggered()), this, SLOT(testColorDS()));
101     test->addAction(a);
102
103     a = new QAction("Test float", this);
104     connect(a, SIGNAL(triggered()), this, SLOT(testFloatDS()));
105     test->addAction(a);
106
107     a = new QAction("Test boolean / 8", this);
108     connect(a, SIGNAL(triggered()), this, SLOT(testOctBoolDS()));
109     test->addAction(a);
110
111     a = new QAction("Test boolean / 8 / 8..", this);
112     connect(a, SIGNAL(triggered()), this, SLOT(testROctBoolDS()));
113     test->addAction(a);
114
115     test->addSeparator();
116
117     a = new QAction("Test fusion of booleans", this);
118     connect(a, SIGNAL(triggered()), this, SLOT(testFuseBoolDS()));
119     test->addAction(a);
120
121     a = new QAction("Test fusion of colors", this);
122     connect(a, SIGNAL(triggered()), this, SLOT(testFuseColorDS()));
123     test->addAction(a);
124
125     a = new QAction("Test fusion of floating-points", this);
126     connect(a, SIGNAL(triggered()), this, SLOT(testFuseFloatDS()));
127     test->addAction(a);
128
129     a = new QAction("Test cutting of booleans", this);
130     connect(a, SIGNAL(triggered()), this, SLOT(testCutBoolDS()));
131     test->addAction(a);
132
133     a = new QAction("Test cutting of booleans", this);
134     connect(a, SIGNAL(triggered()), this, SLOT(testCutColorDS()));
135     test->addAction(a);
136
137     a = new QAction("Test cutting of floating-points", this);
138     connect(a, SIGNAL(triggered()), this, SLOT(testCutFloatDS()));
139     test->addAction(a);
140
141 #endif // TEST
142
143     QMenu * converter = menuBar()->addMenu( "Converter" );
144
145 #ifdef TEST
146     
147     a = new QAction("Number of splits along X", this);
148     connect(a, SIGNAL(triggered()), this, SLOT(setNbX()));
149     converter->addAction(a);
150
151     a = new QAction("Number of splits along Y", this);
152     connect(a, SIGNAL(triggered()), this, SLOT(setNbY()));
153     converter->addAction(a);
154
155     a = new QAction("Number of splits along Z", this);
156     connect(a, SIGNAL(triggered()), this, SLOT(setNbZ()));
157     converter->addAction(a);
158
159     converter->addSeparator();
160
161     a = new QAction("Side of scanning", this);
162     connect(a, SIGNAL(triggered()), this, SLOT(setScanSide()));
163     converter->addAction(a);
164
165     converter->addSeparator();
166
167     a = new QAction("Volumic value of 1bit voxels", this);
168     connect(a, SIGNAL(triggered()), this, SLOT(setVolumicBoolValue()));
169     converter->addAction(a);
170     
171     a = new QAction("Volumic value of 4bit voxels", this);
172     connect(a, SIGNAL(triggered()), this, SLOT(setVolumicColorValue()));
173     converter->addAction(a);
174
175     converter->addSeparator();
176
177 #endif // TEST
178
179     a = new QAction("Convert to 1bit voxels", this);
180     connect(a, SIGNAL(triggered()), this, SLOT(convert2bool()));
181     converter->addAction(a);
182
183     a = new QAction("Convert to 4bit voxels", this);
184     connect(a, SIGNAL(triggered()), this, SLOT(convert2color()));
185     converter->addAction(a);
186
187     QMenu * vis = menuBar()->addMenu( "&Visualization" );
188
189     a = new QAction("Points", this);
190     connect(a, SIGNAL(triggered()), this, SLOT(displayPoints()));
191     vis->addAction(a);
192
193 #ifdef TEST
194     
195     a = new QAction("Nearest points", this);
196     connect(a, SIGNAL(triggered()), this, SLOT(displayNearestPoints()));
197     vis->addAction(a);
198
199 #endif // TEST
200
201     a = new QAction("Boxes", this);
202     connect(a, SIGNAL(triggered()), this, SLOT(displayBoxes()));
203     vis->addAction(a);
204
205 #ifdef TEST
206
207     a = new QAction("Nearest boxes", this);
208     connect(a, SIGNAL(triggered()), this, SLOT(displayNearestBoxes()));
209     vis->addAction(a);
210
211 #endif // TEST
212     
213     vis->addSeparator();
214
215     a = new QAction("Point size", this);
216     connect(a, SIGNAL(triggered()), this, SLOT(setPointSize()));
217     vis->addAction(a);
218     
219     a = new QAction("Quadrangle size (%)", this);
220     connect(a, SIGNAL(triggered()), this, SLOT(setQuadrangleSize()));
221     vis->addAction(a);
222
223     vis->addSeparator();
224
225     a = new QAction("Color min value", this);
226     connect(a, SIGNAL(triggered()), this, SLOT(setColorMinValue()));
227     vis->addAction(a);
228
229     a = new QAction("Color max value", this);
230     connect(a, SIGNAL(triggered()), this, SLOT(setColorMaxValue()));
231     vis->addAction(a);
232
233 #ifdef TEST
234
235     vis->addSeparator();
236
237     a = new QAction("Use GL lists", this);
238     connect(a, SIGNAL(triggered()), this, SLOT(setUsageOfGLlists()));
239     vis->addAction(a);
240
241 #endif // TEST
242
243     vis->addSeparator();
244
245     a = new QAction("Displayed X min", this);
246     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedXMin()));
247     vis->addAction(a);
248
249     a = new QAction("Displayed X max", this);
250     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedXMax()));
251     vis->addAction(a);
252
253     a = new QAction("Displayed Y min", this);
254     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedYMin()));
255     vis->addAction(a);
256
257     a = new QAction("Displayed Y max", this);
258     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedYMax()));
259     vis->addAction(a);
260
261     a = new QAction("Displayed Z min", this);
262     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedZMin()));
263     vis->addAction(a);
264
265     a = new QAction("Displayed Z max", this);
266     connect(a, SIGNAL(triggered()), this, SLOT(setDisplayedZMax()));
267     vis->addAction(a);
268
269
270     QMenu * demo = menuBar()->addMenu( "Demo" );
271
272     a = new QAction("Waves", this);
273     connect(a, SIGNAL(triggered()), this, SLOT(displayWaves()));
274     demo->addAction(a);
275
276     a = new QAction("Cut", this);
277     connect(a, SIGNAL(triggered()), this, SLOT(displayCut()));
278     demo->addAction(a);
279
280     a = new QAction("Collisions", this);
281     connect(a, SIGNAL(triggered()), this, SLOT(displayCollisions()));
282     demo->addAction(a);
283
284
285     QMenu * help = menuBar()->addMenu( "Help" );
286
287     a = new QAction("About", this);
288     a->setShortcut(tr("F1"));
289     connect(a, SIGNAL(triggered()), this, SLOT(about()));
290     help->addAction(a);
291
292
293     myViewer = new Viewer( this );
294     myViewer->setFocus();
295     setCentralWidget( myViewer );
296     statusBar()->showMessage( "Ready", 2000 );
297
298         myNbX = 100;
299         myNbY = 100;
300         myNbZ = 100;
301
302     myScanSide = 7;
303
304     myVolumicBoolValue = false;
305     myVolumicColorValue = 0;
306
307     myQuadrangleSize = 40;
308     
309     myColorMinValue = 1;
310     myColorMaxValue = 15;
311
312         myBoolVoxels = 0;
313         myColorVoxels = 0;
314
315     myDisplayedXMin = -DBL_MAX;
316     myDisplayedXMax =  DBL_MAX;
317     myDisplayedYMin = -DBL_MAX;
318     myDisplayedYMax =  DBL_MAX;
319     myDisplayedZMin = -DBL_MAX;
320     myDisplayedZMax =  DBL_MAX;
321
322         VoxelClient_VisDrawer::Init(myViewer->getGraphicDriver());
323
324     resize( 450, 600 );
325 }
326
327 Application::~Application()
328 {
329         if (myBoolVoxels)
330                 delete myBoolVoxels;
331         if (myColorVoxels)
332                 delete myColorVoxels;
333 }
334
335 void Application::choose()
336 {
337     QString fn = QFileDialog::getOpenFileName( this, QString::null, QString::null, "*.brep");
338     if ( !fn.isEmpty() )
339                 load( fn );
340     else
341                 statusBar()->showMessage( "Loading aborted", 2000 );
342 }
343
344 void Application::load( const QString &fileName )
345 {
346     QFile f( fileName );
347     if ( !f.open( QIODevice::ReadOnly ) )
348                 return;
349
350     // Read shape
351         TopoDS_Shape S;
352         BRep_Builder B;
353         if (!BRepTools::Read(S, (char*) fileName.constData(), B))
354                 statusBar()->showMessage( "Loading failed", 2000 );
355     
356     load(S);
357 }
358
359 void Application::open()
360 {
361     QString fn = QFileDialog::getOpenFileName( this, QString::null, QString::null, "*.vx");
362     if ( fn.isEmpty() || !QFile::exists(fn) )
363     {
364                 statusBar()->showMessage( "Open aborted", 2000 );
365         return;
366     }
367
368     Timer timer;
369     timer.Start();
370
371     // Read the voxels
372     Voxel_Reader reader;
373     if (!reader.Read((char*)fn.constData()))
374     {
375                 statusBar()->showMessage( "Open failed... sorry", 2000 );
376         return;
377     }
378
379     timer.Stop();
380     timer.Print("Open");
381
382     // Release current voxels
383     if (myBoolVoxels)
384     {
385         delete myBoolVoxels;
386         myBoolVoxels = 0;
387     }
388     if (myColorVoxels)
389     {
390         delete myColorVoxels;
391         myColorVoxels = 0;
392     }
393
394     // Take the voxels
395     if (reader.IsBoolVoxels())
396     {
397         myBoolVoxels = (Voxel_BoolDS*) reader.GetBoolVoxels();
398         myViewer->getSelector().SetVoxels(*myBoolVoxels);
399     }
400     else if (reader.IsColorVoxels())
401     {
402         myColorVoxels = (Voxel_ColorDS*) reader.GetColorVoxels();
403         myViewer->getSelector().SetVoxels(*myColorVoxels);
404     }
405     
406     // Display the voxels
407     myViewer->getIC()->EraseAll(false);
408     Voxel_DS* ds = myBoolVoxels;
409     if (!ds)
410         ds = myColorVoxels;
411     if (ds)
412     {
413         myDisplayedXMin = ds->GetX() - 10.0 * Precision::Confusion();
414         myDisplayedXMax = ds->GetX() + ds->GetXLen() + 10.0 * Precision::Confusion();
415         myDisplayedYMin = ds->GetY() - 10.0 * Precision::Confusion();
416         myDisplayedYMax = ds->GetY() + ds->GetYLen() + 10.0 * Precision::Confusion();
417         myDisplayedZMin = ds->GetZ() - 10.0 * Precision::Confusion();
418         myDisplayedZMax = ds->GetZ() + ds->GetZLen() + 10.0 * Precision::Confusion();
419     }
420
421     // Init visual data
422     initPrs();
423
424     // Set voxels and display
425     Handle(Poly_Triangulation) empty;
426     myVoxels->SetBoolVoxels(myBoolVoxels);
427         myVoxels->SetColorVoxels(myColorVoxels);
428     myVoxels->SetTriangulation(empty);
429     if (myViewer->getIC()->IsDisplayed(myVoxels))
430         myViewer->getIC()->Redisplay(myVoxels, false);
431     else
432             myViewer->getIC()->Display(myVoxels, false);
433    
434     // Color scale
435     if (myColorVoxels)
436         displayColorScale();
437     else
438         myViewer->getView()->ColorScaleErase();
439
440         myViewer->getView()->FitAll();
441
442     statusBar()->showMessage( "Ready.", 2000 );
443 }
444
445 void Application::save()
446 {
447     QString fn = QFileDialog::getSaveFileName( this, QString::null, QString::null, "*.vx");
448     if ( fn.isEmpty() )
449     {
450                 statusBar()->showMessage( "Storage aborted", 2000 );
451         return;
452     }
453     if (fn.indexOf(".vx", -1, Qt::CaseInsensitive) == -1)
454         fn += ".vx";
455
456     Timer timer;
457     timer.Start();
458
459     // Write the voxels
460     Voxel_Writer writer;
461     writer.SetFormat(Voxel_VFF_BINARY);
462     if (myBoolVoxels)
463         writer.SetVoxels(*myBoolVoxels);
464     else if (myColorVoxels)
465         writer.SetVoxels(*myColorVoxels);
466     else
467     {
468                 statusBar()->showMessage( "Nothing to store", 2000 );
469         return;
470     }
471     if (!writer.Write((char*)fn.constData()))
472     {
473                 statusBar()->showMessage( "Storage failed... sorry", 2000 );
474         return;
475     }
476
477     timer.Stop();
478     timer.Print("Save");
479
480     statusBar()->showMessage( "Saved.", 2000 );
481 }
482
483 void Application::closeEvent( QCloseEvent* ce )
484 {
485     ce->accept();
486 }
487
488 void Application::about()
489 {
490     QMessageBox::about( this, "Voxel demo-application",
491                         "This example demonstrates simple usage of "
492                         "voxel models of Open CASCADE.");
493 }
494
495 void Application::testBoolDS()
496 {
497         Timer timer;
498         int ix, iy, iz;
499         int nbx = 100, nby = 100, nbz = 100;
500
501
502         // 1. BoolDS:
503
504         timer.Start();
505
506         Voxel_BoolDS ds(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
507
508         for (ix = 0; ix < nbx; ix++)
509         {
510                 for (iy = 0; iy < nby; iy++)
511                 {
512                         for (iz = 0; iz < nbz; iz++)
513                         {
514                                 if (ix & 0x01)
515                                         ds.Set(ix, iy, iz, false);
516                                 else
517                                         ds.Set(ix, iy, iz, true);
518                         }
519                 }
520         }
521
522         for (ix = 0; ix < nbx; ix++)
523         {
524                 for (iy = 0; iy < nby; iy++)
525                 {
526                         for (iz = 0; iz < nbz; iz++)
527                         {
528                                 bool value = ds.Get(ix, iy, iz) == Standard_True;
529                                 if (ix & 0x01)
530                                 {
531                                         if (value != false)
532                                                 cout<<"Wrong value!"<<endl;
533                                 }
534                                 else
535                                 {
536                                         if (value != true)
537                                                 cout<<"Wrong value!"<<endl;
538                                 }
539                         }
540                 }
541         }
542
543         timer.Stop();
544         timer.Print("BoolDS");
545 }
546
547 void Application::testColorDS()
548 {
549         Timer timer;
550         int ix, iy, iz;
551         int nbx = 100, nby = 100, nbz = 100;
552
553
554         // 1. ColorDS:
555
556         timer.Start();
557
558         Voxel_ColorDS ds(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
559
560         for (ix = 0; ix < nbx; ix++)
561         {
562                 for (iy = 0; iy < nby; iy++)
563                 {
564                         for (iz = 0; iz < nbz; iz++)
565                         {
566                 if (ix & 0x01)
567                             ds.Set(ix, iy, iz, 8);
568                 else
569                     ds.Set(ix, iy, iz, 7);
570                         }
571                 }
572         }
573
574         for (ix = 0; ix < nbx; ix++)
575         {
576                 for (iy = 0; iy < nby; iy++)
577                 {
578                         for (iz = 0; iz < nbz; iz++)
579                         {
580                                 unsigned char value = ds.Get(ix, iy, iz);
581                 if (ix & 0x01)
582                 {
583                                     if (value != 8)
584                                             cout<<"Wrong value!"<<endl;
585                 }
586                 else
587                 {
588                                     if (value != 7)
589                                             cout<<"Wrong value!"<<endl;
590                 }
591                         }
592                 }
593         }
594
595         timer.Stop();
596         timer.Print("ColorDS");
597 }
598
599 void Application::testFloatDS()
600 {
601         Timer timer;
602         int ix, iy, iz;
603         int nbx = 100, nby = 100, nbz = 100;
604
605
606         // 1. FloatDS:
607
608         timer.Start();
609
610         Voxel_FloatDS ds(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
611
612         for (ix = 0; ix < nbx; ix++)
613         {
614                 for (iy = 0; iy < nby; iy++)
615                 {
616                         for (iz = 0; iz < nbz; iz++)
617                         {
618                 if (ix & 0x01)
619                             ds.Set(ix, iy, iz, 8.8f);
620                 else
621                     ds.Set(ix, iy, iz, 7.7f);
622                         }
623                 }
624         }
625
626         for (ix = 0; ix < nbx; ix++)
627         {
628                 for (iy = 0; iy < nby; iy++)
629                 {
630                         for (iz = 0; iz < nbz; iz++)
631                         {
632                                 float value = ds.Get(ix, iy, iz);
633                 if (ix & 0x01)
634                 {
635                                     if (value != 8.8f)
636                                             cout<<"Wrong value!"<<endl;
637                 }
638                 else
639                 {
640                                     if (value != 7.7f)
641                                             cout<<"Wrong value!"<<endl;
642                 }
643                         }
644                 }
645         }
646
647         timer.Stop();
648         timer.Print("FloatDS");
649 }
650
651 void Application::testOctBoolDS()
652 {
653         Timer timer;
654         int ix, iy, iz;
655         int nbx = 30, nby = 30, nbz = 30;
656
657
658         // 1. OctBoolDS:
659
660         timer.Start();
661
662         Voxel_OctBoolDS ds(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
663
664         for (ix = 0; ix < nbx; ix++)
665         {
666                 for (iy = 0; iy < nby; iy++)
667                 {
668                         for (iz = 0; iz < nbz; iz++)
669                         {
670                                 if (ix & 0x01)
671                 {
672                                         ds.Set(ix, iy, iz, true);
673                 }
674                                 else
675                 {
676                     for (int i = 0; i < 8; i++)
677                     {
678                         if (i & 0x01)
679                                                 ds.Set(ix, iy, iz, i, true);
680                         else
681                             ds.Set(ix, iy, iz, i, false);
682                     }
683                 }
684                         }
685                 }
686         }
687
688         for (ix = 0; ix < nbx; ix++)
689         {
690                 for (iy = 0; iy < nby; iy++)
691                 {
692                         for (iz = 0; iz < nbz; iz++)
693                         {
694                                 if (ix & 0x01)
695                                 {
696                                 bool value = ds.Get(ix, iy, iz) == Standard_True;
697                                         if (value != true)
698                                                 cout<<"Wrong value!"<<endl;
699                                 }
700                                 else
701                                 {
702                     for (int i = 0; i < 8; i++)
703                     {
704                         if (i & 0x01)
705                         {
706                                         bool value = ds.Get(ix, iy, iz, i) == Standard_True;
707                                                 if (value != true)
708                                                         cout<<"Wrong value!"<<endl;
709                         }
710                         else
711                         {
712                                         bool value = ds.Get(ix, iy, iz, i) == Standard_True;
713                                                 if (value != false)
714                                                         cout<<"Wrong value!"<<endl;
715                         }
716                     }
717                                 }
718                         }
719                 }
720         }
721
722         for (ix = 0; ix < nbx; ix++)
723         {
724                 for (iy = 0; iy < nby; iy++)
725                 {
726                         for (iz = 0; iz < nbz; iz++)
727                         {
728                                 if (ix & 0x01)
729                                 {
730                     for (int i = 0; i < 8; i++)
731                     {
732                         ds.Set(ix, iy, iz, i, true);
733                     }
734                                 }
735                 else
736                 {
737                     for (int i = 0; i < 8; i++)
738                     {
739                         ds.Set(ix, iy, iz, i, false);
740                     }
741                 }
742                         }
743                 }
744         }
745
746     ds.OptimizeMemory();
747
748         timer.Stop();
749         timer.Print("OctBoolDS");
750 }
751
752 void Application::testROctBoolDS()
753 {
754         Timer timer;
755         int ix, iy, iz, i, j;
756         int nbx = 30, nby = 30, nbz = 30;
757
758         // 1. ROctBoolDS:
759
760         timer.Start();
761
762         Voxel_ROctBoolDS ds(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
763
764     for (ix = 0; ix < nbx; ix++)
765         {
766                 for (iy = 0; iy < nby; iy++)
767                 {
768                         for (iz = 0; iz < nbz; iz++)
769                         {
770                 ds.Set(ix, iy, iz, true);
771                         }
772                 }
773         }
774
775     for (ix = 0; ix < nbx; ix++)
776         {
777                 for (iy = 0; iy < nby; iy++)
778                 {
779                         for (iz = 0; iz < nbz; iz++)
780                         {
781                 for (i = 0; i < 8; i++)
782                 {
783                     for (j = 0; j < 8; j++)
784                     {
785                         ds.Set(ix, iy, iz, i, j, true);
786                     }
787                 }
788                         }
789                 }
790         }
791
792     ds.OptimizeMemory();
793
794         for (ix = 0; ix < nbx; ix++)
795         {
796                 for (iy = 0; iy < nby; iy++)
797                 {
798                         for (iz = 0; iz < nbz; iz++)
799                         {
800                 if (ds.Deepness(ix, iy, iz) == 0)
801                 {
802                     bool value = ds.Get(ix, iy, iz);
803                     if (value != true)
804                         cout<<"Wrong value..."<<endl;
805                 }
806                 if (ds.Deepness(ix, iy, iz) == 1)
807                 {
808                     for (i = 0; i < 8; i++)
809                     {
810                         bool value = ds.Get(ix, iy, iz, i);
811                         if (value != true)
812                             cout<<"Wrong value..."<<endl;
813                     }
814                 }
815                 if (ds.Deepness(ix, iy, iz) == 2)
816                 {
817                     for (i = 0; i < 8; i++)
818                     {
819                         for (j = 0; j < 8; j++)
820                         {
821                             bool value = ds.Get(ix, iy, iz, i, j);
822                             if (value != true)
823                                 cout<<"Wrong value..."<<endl;
824                         }
825                     }
826                 }
827                         }
828                 }
829         }
830
831         timer.Stop();
832         timer.Print("ROctBoolDS");
833
834
835     // Test converter
836     TopoDS_Shape S = BRepPrimAPI_MakeSphere(100.0);
837
838     timer.Start();
839
840     int progress = 0;
841     Voxel_ROctBoolDS* ds2 = new Voxel_ROctBoolDS;
842     Voxel_FastConverter converter(S, *ds2, 0.1, myNbX, myNbY, myNbZ, 1);
843     converter.Convert(progress);
844     ds2->OptimizeMemory();
845
846         timer.Stop();
847         timer.Print("ROctBoolDS::converter");
848
849
850     // Display 
851     myViewer->getIC()->EraseAll(false);
852     initPrs();
853     myVoxels->SetBoolVoxels(0);
854         myVoxels->SetColorVoxels(0);
855     Handle(Poly_Triangulation) empty;
856     myVoxels->SetTriangulation(empty);
857     myVoxels->SetROctBoolVoxels(ds2);
858     myViewer->getIC()->Display(myVoxels, false);
859     myViewer->getView()->ColorScaleErase();
860         myViewer->getView()->FitAll();
861     myViewer->getSelector().SetVoxels(*ds2);
862 }
863
864 void Application::testFuseBoolDS()
865 {
866         Timer timer;
867         int ix, iy, iz;
868         int nbx = 100, nby = 100, nbz = 100;
869
870
871         // 1. Set two BoolDS:
872
873         timer.Start();
874
875         Voxel_BoolDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
876         Voxel_BoolDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
877
878         for (ix = 0; ix < nbx; ix++)
879         {
880                 for (iy = 0; iy < nby; iy++)
881                 {
882                         for (iz = 0; iz < nbz; iz++)
883                         {
884                                 if (ix & 0x01)
885                                         ds2.Set(ix, iy, iz, false);
886                                 else
887                                         ds2.Set(ix, iy, iz, true);
888                         }
889                 }
890         }
891
892     // 2. Fuse them
893
894     Voxel_BooleanOperation fuser;
895     if (!fuser.Fuse(ds1, ds2))
896         cout<<"The operation failed..."<<endl;
897
898     // 3. Check result
899
900         for (ix = 0; ix < nbx; ix++)
901         {
902                 for (iy = 0; iy < nby; iy++)
903                 {
904                         for (iz = 0; iz < nbz; iz++)
905                         {
906                                 bool value = ds1.Get(ix, iy, iz) == Standard_True;
907                                 if (ix & 0x01)
908                                 {
909                                         if (value != false)
910                                         cout<<"Wrong value!"<<endl;
911                                 }
912                                 else
913                                 {
914                                         if (value != true)
915                                                 cout<<"Wrong value!"<<endl;
916                                 }
917                         }
918                 }
919         }
920
921         timer.Stop();
922         timer.Print("Fusion of BoolDS");
923 }
924
925 void Application::testFuseColorDS()
926 {
927         Timer timer;
928         int ix, iy, iz;
929         int nbx = 100, nby = 100, nbz = 100;
930
931
932         // 1. Set two ColorDS:
933
934         timer.Start();
935
936         Voxel_ColorDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
937         Voxel_ColorDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
938
939         for (ix = 0; ix < nbx; ix++)
940         {
941                 for (iy = 0; iy < nby; iy++)
942                 {
943                         for (iz = 0; iz < nbz; iz++)
944                         {
945                                 ds1.Set(ix, iy, iz, 11);
946                         }
947                 }
948         }
949         for (ix = 0; ix < nbx; ix++)
950         {
951                 for (iy = 0; iy < nby; iy++)
952                 {
953                         for (iz = 0; iz < nbz; iz++)
954                         {
955                                 if (ix & 0x01)
956                                         ds2.Set(ix, iy, iz, 3);
957                                 else
958                                         ds2.Set(ix, iy, iz, 5);
959                         }
960                 }
961         }
962
963     // 2. Fuse them
964
965     Voxel_BooleanOperation fuser;
966     if (!fuser.Fuse(ds1, ds2))
967         cout<<"The operation failed..."<<endl;
968
969     // 3. Check result
970
971         for (ix = 0; ix < nbx; ix++)
972         {
973                 for (iy = 0; iy < nby; iy++)
974                 {
975                         for (iz = 0; iz < nbz; iz++)
976                         {
977                                 unsigned char value = ds1.Get(ix, iy, iz);
978                                 if (ix & 0x01)
979                                 {
980                                         if (value != 14)
981                                         cout<<"Wrong value!"<<endl;
982                                 }
983                                 else
984                                 {
985                                         if (value != 15)
986                                                 cout<<"Wrong value!"<<endl;
987                                 }
988                         }
989                 }
990         }
991
992         timer.Stop();
993         timer.Print("Fusion of ColorDS");
994 }
995
996 void Application::testFuseFloatDS()
997 {
998         Timer timer;
999         int ix, iy, iz;
1000         int nbx = 100, nby = 100, nbz = 100;
1001
1002
1003         // 1. Set two FloatDS:
1004
1005         timer.Start();
1006
1007         Voxel_FloatDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1008         Voxel_FloatDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1009
1010         for (ix = 0; ix < nbx; ix++)
1011         {
1012                 for (iy = 0; iy < nby; iy++)
1013                 {
1014                         for (iz = 0; iz < nbz; iz++)
1015                         {
1016                                 ds1.Set(ix, iy, iz, 11.1f);
1017                         }
1018                 }
1019         }
1020         for (ix = 0; ix < nbx; ix++)
1021         {
1022                 for (iy = 0; iy < nby; iy++)
1023                 {
1024                         for (iz = 0; iz < nbz; iz++)
1025                         {
1026                                 if (ix & 0x01)
1027                                         ds2.Set(ix, iy, iz, 3.3f);
1028                                 else
1029                                         ds2.Set(ix, iy, iz, 5.5f);
1030                         }
1031                 }
1032         }
1033
1034     // 2. Fuse them
1035
1036     Voxel_BooleanOperation fuser;
1037     if (!fuser.Fuse(ds1, ds2))
1038         cout<<"The operation failed..."<<endl;
1039
1040     // 3. Check result
1041
1042         for (ix = 0; ix < nbx; ix++)
1043         {
1044                 for (iy = 0; iy < nby; iy++)
1045                 {
1046                         for (iz = 0; iz < nbz; iz++)
1047                         {
1048                                 float value = ds1.Get(ix, iy, iz);
1049                                 if (ix & 0x01)
1050                                 {
1051                     if (fabs(value - 14.4f) > 0.001)
1052                                         cout<<"Wrong value!"<<endl;
1053                                 }
1054                                 else
1055                                 {
1056                     if (fabs(value - 16.6f) > 0.001)
1057                                                 cout<<"Wrong value!"<<endl;
1058                                 }
1059                         }
1060                 }
1061         }
1062
1063         timer.Stop();
1064         timer.Print("Fusion of FloatDS");
1065 }
1066
1067 void Application::testCutBoolDS()
1068 {
1069         Timer timer;
1070         int ix, iy, iz;
1071         int nbx = 100, nby = 100, nbz = 100;
1072
1073
1074         // 1. Set two BoolDS:
1075
1076         timer.Start();
1077
1078         Voxel_BoolDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1079         Voxel_BoolDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1080
1081         for (ix = 0; ix < nbx; ix++)
1082         {
1083                 for (iy = 0; iy < nby; iy++)
1084                 {
1085                         for (iz = 0; iz < nbz; iz++)
1086                         {
1087                                 ds1.Set(ix, iy, iz, true);
1088                         }
1089                 }
1090         }
1091         for (ix = 0; ix < nbx; ix++)
1092         {
1093                 for (iy = 0; iy < nby; iy++)
1094                 {
1095                         for (iz = 0; iz < nbz; iz++)
1096                         {
1097                                 if (ix & 0x01)
1098                                         ds2.Set(ix, iy, iz, false);
1099                                 else
1100                                         ds2.Set(ix, iy, iz, true);
1101                         }
1102                 }
1103         }
1104
1105     // 2. Cut them
1106
1107     Voxel_BooleanOperation cutter;
1108     if (!cutter.Cut(ds1, ds2))
1109         cout<<"The operation failed..."<<endl;
1110
1111     // 3. Check result
1112
1113         for (ix = 0; ix < nbx; ix++)
1114         {
1115                 for (iy = 0; iy < nby; iy++)
1116                 {
1117                         for (iz = 0; iz < nbz; iz++)
1118                         {
1119                                 bool value = ds1.Get(ix, iy, iz) == Standard_True;
1120                                 if (ix & 0x01)
1121                                 {
1122                                         if (value != true)
1123                                         cout<<"Wrong value!"<<endl;
1124                                 }
1125                                 else
1126                                 {
1127                                         if (value != false)
1128                                                 cout<<"Wrong value!"<<endl;
1129                                 }
1130                         }
1131                 }
1132         }
1133
1134         timer.Stop();
1135         timer.Print("Cut of BoolDS");
1136 }
1137
1138 void Application::testCutColorDS()
1139 {
1140         Timer timer;
1141         int ix, iy, iz;
1142         int nbx = 100, nby = 100, nbz = 100;
1143
1144
1145         // 1. Set two ColorDS:
1146
1147         timer.Start();
1148
1149         Voxel_ColorDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1150         Voxel_ColorDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1151
1152         for (ix = 0; ix < nbx; ix++)
1153         {
1154                 for (iy = 0; iy < nby; iy++)
1155                 {
1156                         for (iz = 0; iz < nbz; iz++)
1157                         {
1158                                 ds1.Set(ix, iy, iz, 11);
1159                         }
1160                 }
1161         }
1162         for (ix = 0; ix < nbx; ix++)
1163         {
1164                 for (iy = 0; iy < nby; iy++)
1165                 {
1166                         for (iz = 0; iz < nbz; iz++)
1167                         {
1168                                 if (ix & 0x01)
1169                                         ds2.Set(ix, iy, iz, 3);
1170                                 else
1171                                         ds2.Set(ix, iy, iz, 5);
1172                         }
1173                 }
1174         }
1175
1176     // 2. Cut them
1177
1178     Voxel_BooleanOperation cutter;
1179     if (!cutter.Cut(ds1, ds2))
1180         cout<<"The operation failed..."<<endl;
1181
1182     // 3. Check result
1183
1184         for (ix = 0; ix < nbx; ix++)
1185         {
1186                 for (iy = 0; iy < nby; iy++)
1187                 {
1188                         for (iz = 0; iz < nbz; iz++)
1189                         {
1190                                 unsigned char value = ds1.Get(ix, iy, iz);
1191                                 if (ix & 0x01)
1192                                 {
1193                                         if (value != 8)
1194                                         cout<<"Wrong value!"<<endl;
1195                                 }
1196                                 else
1197                                 {
1198                                         if (value != 6)
1199                                                 cout<<"Wrong value!"<<endl;
1200                                 }
1201                         }
1202                 }
1203         }
1204
1205         timer.Stop();
1206         timer.Print("Cut of ColorDS");
1207 }
1208
1209 void Application::testCutFloatDS()
1210 {
1211         Timer timer;
1212         int ix, iy, iz;
1213         int nbx = 100, nby = 100, nbz = 100;
1214
1215
1216         // 1. Set two FloatDS:
1217
1218         timer.Start();
1219
1220         Voxel_FloatDS ds1(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1221         Voxel_FloatDS ds2(0, 0, 0, 1, 1, 1, nbx, nby, nbz);
1222
1223         for (ix = 0; ix < nbx; ix++)
1224         {
1225                 for (iy = 0; iy < nby; iy++)
1226                 {
1227                         for (iz = 0; iz < nbz; iz++)
1228                         {
1229                                 ds1.Set(ix, iy, iz, 11.1f);
1230                         }
1231                 }
1232         }
1233         for (ix = 0; ix < nbx; ix++)
1234         {
1235                 for (iy = 0; iy < nby; iy++)
1236                 {
1237                         for (iz = 0; iz < nbz; iz++)
1238                         {
1239                                 if (ix & 0x01)
1240                                         ds2.Set(ix, iy, iz, 3.3f);
1241                                 else
1242                                         ds2.Set(ix, iy, iz, 5.5f);
1243                         }
1244                 }
1245         }
1246
1247     // 2. Cut them
1248
1249     Voxel_BooleanOperation cutter;
1250     if (!cutter.Cut(ds1, ds2))
1251         cout<<"The operation failed..."<<endl;
1252
1253     // 3. Check result
1254
1255         for (ix = 0; ix < nbx; ix++)
1256         {
1257                 for (iy = 0; iy < nby; iy++)
1258                 {
1259                         for (iz = 0; iz < nbz; iz++)
1260                         {
1261                                 float value = ds1.Get(ix, iy, iz);
1262                                 if (ix & 0x01)
1263                                 {
1264                     if (fabs(value - 7.8f) > 0.001)
1265                                         cout<<"Wrong value!"<<endl;
1266                                 }
1267                                 else
1268                                 {
1269                     if (fabs(value - 5.6f) > 0.001)
1270                                                 cout<<"Wrong value!"<<endl;
1271                                 }
1272                         }
1273                 }
1274         }
1275
1276         timer.Stop();
1277         timer.Print("Cut of FloatDS");
1278 }
1279
1280 void Application::convert2bool()
1281 {
1282     convert(0);
1283 }
1284
1285 void Application::convert2color()
1286 {
1287     convert(1);
1288 }
1289
1290 void Application::convert(const int ivoxel)
1291 {
1292         TopoDS_Shape S;
1293         if (!myShape.IsNull())
1294                 S = myShape->Shape();
1295     if (S.IsNull())
1296         {
1297                 QMessageBox::warning( this, "Voxel demo-application", "No shape for conversion!");
1298                 return;
1299         }
1300
1301     switch (ivoxel)
1302     {
1303         case 0:
1304         {
1305                 if (!myBoolVoxels)
1306                         myBoolVoxels = new Voxel_BoolDS;
1307             if (myColorVoxels)
1308             {
1309                 delete myColorVoxels;
1310                 myColorVoxels = 0;
1311             }
1312             break;
1313         }
1314         case 1:
1315         {
1316                 if (!myColorVoxels)
1317                         myColorVoxels = new Voxel_ColorDS;
1318             if (myBoolVoxels)
1319             {
1320                 delete myBoolVoxels;
1321                 myBoolVoxels = 0;
1322             }
1323             break;
1324         }
1325     }
1326
1327     switch (ivoxel)
1328     {
1329         case 0:
1330         {
1331             Timer timer;
1332             timer.Start();
1333
1334             /*
1335             int progress;
1336             Voxel_Converter converter(S, *myBoolVoxels, myNbX, myNbY, myNbZ);
1337                 if (!converter.Convert(progress, myVolumicBoolValue, myScanSide))
1338                 {
1339                         QMessageBox::warning( this, "Voxel demo-application", "Conversion failed...");
1340                         return;
1341                 }
1342             */
1343
1344             /*
1345             Voxel_Converter converter(S, *myBoolVoxels, myNbX, myNbY, myNbZ, 2);
1346             ConversionThread thread1, thread2;
1347             
1348             thread1.setConverter(&converter);
1349             thread2.setConverter(&converter);
1350
1351             thread1.setVolumicValue(myVolumicBoolValue);
1352             thread2.setVolumicValue(myVolumicBoolValue);
1353
1354             thread1.setScanSide(myScanSide);
1355             thread2.setScanSide(myScanSide);
1356
1357             thread1.setThreadIndex(1);
1358             thread2.setThreadIndex(2);
1359
1360             thread1.start();
1361             thread2.start();
1362
1363             while (thread1.running() || thread2.running())
1364             {
1365                 ::Sleep(100);
1366             }
1367             */
1368
1369             /*
1370             int progress;
1371             Voxel_FastConverter converter(S, *myBoolVoxels, 0.1, myNbX, myNbY, myNbZ, 1);
1372             converter.Convert(progress, 1);
1373             //if (myVolumicBoolValue)
1374             //    converter.FillInVolume(myVolumicBoolValue);
1375             */
1376
1377             Voxel_FastConverter converter(S, *myBoolVoxels, 0.1, myNbX, myNbY, myNbZ, 2);
1378             ConversionThread thread1, thread2;
1379             
1380             thread1.setConverter(&converter);
1381             thread2.setConverter(&converter);
1382
1383             thread1.setThreadIndex(1);
1384             thread2.setThreadIndex(2);
1385
1386             thread1.start();
1387             thread2.start();
1388
1389             while (thread1.isRunning() || thread2.isRunning())
1390             {
1391                 ::Sleep(100);
1392             }
1393
1394             timer.Print("Converter");
1395
1396             myViewer->getSelector().SetVoxels(*myBoolVoxels);
1397             break;
1398         }
1399         case 1:
1400         {
1401
1402             Timer timer;
1403             timer.Start();
1404
1405             /*
1406             int progress;
1407             Voxel_Converter converter(S, *myColorVoxels, myNbX, myNbY, myNbZ);
1408                 if (!converter.Convert(progress, myVolumicColorValue, myScanSide))
1409                 {
1410                         QMessageBox::warning( this, "Voxel demo-application", "Conversion failed...");
1411                         return;
1412                 }
1413             */
1414
1415             /*
1416             Voxel_Converter converter(S, *myColorVoxels, myNbX, myNbY, myNbZ, 2);
1417             ConversionThread thread1, thread2;
1418             
1419             thread1.setConverter(&converter);
1420             thread2.setConverter(&converter);
1421
1422             thread1.setVolumicValue(myVolumicColorValue);
1423             thread2.setVolumicValue(myVolumicColorValue);
1424
1425             thread1.setScanSide(myScanSide);
1426             thread2.setScanSide(myScanSide);
1427
1428             thread1.setThreadIndex(1);
1429             thread2.setThreadIndex(2);
1430
1431             thread1.start();
1432             thread2.start();
1433
1434             while (thread1.running() || thread2.running())
1435             {
1436                 ::Sleep(100);
1437             }
1438             */
1439
1440             /*
1441             int progress;
1442             Voxel_FastConverter converter(S, *myColorVoxels, myNbX, myNbY, myNbZ, 1);
1443             converter.Convert(progress, 1);
1444             if (myVolumicColorValue)
1445                 converter.FillInVolume(myVolumicColorValue);
1446             */
1447
1448             Voxel_FastConverter converter(S, *myColorVoxels, 0.1, myNbX, myNbY, myNbZ, 2);
1449             ConversionThread thread1, thread2;
1450             
1451             thread1.setConverter(&converter);
1452             thread2.setConverter(&converter);
1453
1454             thread1.setThreadIndex(1);
1455             thread2.setThreadIndex(2);
1456
1457             thread1.start();
1458             thread2.start();
1459
1460             while (thread1.isRunning() || thread2.isRunning())
1461             {
1462                 ::Sleep(100);
1463             }
1464
1465             timer.Print("Converter");
1466
1467
1468             // Set color for demonstration
1469             double maxd = 
1470                 fabs(myColorVoxels->GetX()) > fabs(myColorVoxels->GetY()) ? 
1471                 fabs(myColorVoxels->GetX()) : fabs(myColorVoxels->GetY());
1472             maxd = maxd > fabs(myColorVoxels->GetZ()) ? maxd : fabs(myColorVoxels->GetZ());
1473             maxd = maxd > fabs(myColorVoxels->GetX() + myColorVoxels->GetXLen()) ?
1474                 maxd : fabs(myColorVoxels->GetX() + myColorVoxels->GetXLen());
1475             maxd = maxd > fabs(myColorVoxels->GetY() + myColorVoxels->GetYLen()) ?
1476                 maxd : fabs(myColorVoxels->GetY() + myColorVoxels->GetYLen());
1477             maxd = maxd > fabs(myColorVoxels->GetZ() + myColorVoxels->GetZLen()) ?
1478                 maxd : fabs(myColorVoxels->GetZ() + myColorVoxels->GetZLen());
1479             for (int ix = 0; ix < myNbX; ix++)
1480             {
1481                 for (int iy = 0; iy < myNbY; iy++)
1482                 {
1483                     for (int iz = 0; iz < myNbZ; iz++)
1484                     {
1485                         unsigned char value = myColorVoxels->Get(ix, iy, iz);
1486                         if (value)
1487                         {
1488                             double xc, yc, zc, xd, yd, zd;
1489                             myColorVoxels->GetCenter(ix, iy, iz, xc, yc, zc);
1490                             xd = fabs(xc);
1491                             yd = fabs(yc);
1492                             zd = fabs(zc);
1493                             double mind = xd < yd ? xd : yd;
1494                             mind = zd < mind ? zd : mind;
1495                             value = unsigned char(15.0 * (maxd - mind) / maxd);
1496                             if (value <= 0)
1497                                 value = 1;
1498                             myColorVoxels->Set(ix, iy, iz, value);
1499                         }
1500                     }
1501                 }
1502             }
1503
1504             myViewer->getSelector().SetVoxels(*myColorVoxels);
1505             break;
1506         }
1507     }
1508
1509     myViewer->getIC()->EraseAll(false);
1510
1511     Voxel_DS* ds = myBoolVoxels;
1512     if (!ds)
1513         ds = myColorVoxels;
1514     if (ds)
1515     {
1516         myDisplayedXMin = ds->GetX() - 10.0 * Precision::Confusion();
1517         myDisplayedXMax = ds->GetX() + ds->GetXLen() + 10.0 * Precision::Confusion();
1518         myDisplayedYMin = ds->GetY() - 10.0 * Precision::Confusion();
1519         myDisplayedYMax = ds->GetY() + ds->GetYLen() + 10.0 * Precision::Confusion();
1520         myDisplayedZMin = ds->GetZ() - 10.0 * Precision::Confusion();
1521         myDisplayedZMax = ds->GetZ() + ds->GetZLen() + 10.0 * Precision::Confusion();
1522     }
1523
1524     // Init visual data
1525     initPrs();
1526
1527     // Set voxels and display
1528     Handle(Poly_Triangulation) empty;
1529     myVoxels->SetBoolVoxels(myBoolVoxels);
1530         myVoxels->SetColorVoxels(myColorVoxels);
1531     myVoxels->SetTriangulation(empty);
1532     if (myViewer->getIC()->IsDisplayed(myVoxels))
1533         myViewer->getIC()->Redisplay(myVoxels, false);
1534     else
1535             myViewer->getIC()->Display(myVoxels, false);
1536     
1537     // Color scale
1538     if (myColorVoxels)
1539         displayColorScale();
1540     else
1541         myViewer->getView()->ColorScaleErase();
1542
1543         myViewer->getView()->FitAll();
1544 }
1545
1546 void Application::setNbX()
1547 {
1548         bool ok;
1549         myNbX = 
1550                 QInputDialog::getInteger(this, "Voxel demo-application", "Number of splits in X-direction:", myNbX,
1551                                                                                                                  1, 100000, 1, &ok);
1552 }
1553
1554 void Application::setNbY()
1555 {
1556         bool ok;
1557         myNbY = 
1558                 QInputDialog::getInteger(this, "Voxel demo-application", "Number of splits in X-direction:", myNbY,
1559                                                                                                                  1, 100000, 1, &ok);
1560 }
1561
1562 void Application::setNbZ()
1563 {
1564         bool ok;
1565         myNbZ = 
1566                 QInputDialog::getInteger(this, "Voxel demo-application", "Number of splits in X-direction:", myNbZ,
1567                                                                                                                  1, 100000, 1, &ok);
1568 }
1569
1570 void Application::setColorMinValue()
1571 {
1572         bool ok;
1573         myColorMinValue = 
1574                 QInputDialog::getInteger(this, "Voxel demo-application", "Minimum value for color [0 .. 15]:", myColorMinValue,
1575                                                                  0, 15, 1, &ok);
1576     if (!myVoxels.IsNull())
1577         myVoxels->SetColorRange(myColorMinValue, myColorMaxValue);
1578 }
1579
1580 void Application::setColorMaxValue()
1581 {
1582         bool ok;
1583         myColorMaxValue = 
1584                 QInputDialog::getInteger(this, "Voxel demo-application", "Maximum value for color [0 .. 15]:", myColorMaxValue,
1585                                                                  0, 15, 1, &ok);
1586     if (!myVoxels.IsNull())
1587         myVoxels->SetColorRange(myColorMinValue, myColorMaxValue);
1588 }
1589
1590 void Application::setUsageOfGLlists()
1591 {
1592     int res = QMessageBox::question( this, "Voxel demo-application", "Press Yes to use GL lists and No not to use them.", QMessageBox::Yes, QMessageBox::No);
1593     if (!myVoxels.IsNull())
1594         myVoxels->SetUsageOfGLlists(res == QMessageBox::Yes);
1595 }
1596
1597 void Application::setDisplayedXMin()
1598 {
1599         myDisplayedXMin = QInputDialog::getDouble(this, "Voxel demo-application", "Minimum X value:", myDisplayedXMin);
1600     if (!myVoxels.IsNull())
1601     {
1602         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1603                                myDisplayedYMin, myDisplayedYMax,
1604                                myDisplayedZMin, myDisplayedZMax);
1605     }
1606 }
1607
1608 void Application::setDisplayedXMax()
1609 {
1610         myDisplayedXMax = QInputDialog::getDouble(this, "Voxel demo-application", "Maximum X value:", myDisplayedXMax);
1611     if (!myVoxels.IsNull())
1612     {
1613         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1614                                myDisplayedYMin, myDisplayedYMax,
1615                                myDisplayedZMin, myDisplayedZMax);
1616     }
1617 }
1618
1619 void Application::setDisplayedYMin()
1620 {
1621         myDisplayedYMin = QInputDialog::getDouble(this, "Voxel demo-application", "Minimum Y value:", myDisplayedYMin);
1622     if (!myVoxels.IsNull())
1623     {
1624         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1625                                myDisplayedYMin, myDisplayedYMax,
1626                                myDisplayedZMin, myDisplayedZMax);
1627     }
1628 }
1629
1630 void Application::setDisplayedYMax()
1631 {
1632         myDisplayedYMax = QInputDialog::getDouble(this, "Voxel demo-application", "Maximum Y value:", myDisplayedYMax);
1633     if (!myVoxels.IsNull())
1634     {
1635         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1636                                myDisplayedYMin, myDisplayedYMax,
1637                                myDisplayedZMin, myDisplayedZMax);
1638     }
1639 }
1640
1641 void Application::setDisplayedZMin()
1642 {
1643         myDisplayedZMin = QInputDialog::getDouble(this, "Voxel demo-application", "Minimum Z value:", myDisplayedZMin);
1644     if (!myVoxels.IsNull())
1645     {
1646         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1647                                myDisplayedYMin, myDisplayedYMax,
1648                                myDisplayedZMin, myDisplayedZMax);
1649     }
1650 }
1651
1652 void Application::setDisplayedZMax()
1653 {
1654         myDisplayedZMax = QInputDialog::getDouble(this, "Voxel demo-application", "Maximum Z value:", myDisplayedZMax);
1655     if (!myVoxels.IsNull())
1656     {
1657         myVoxels->SetSizeRange(myDisplayedXMin, myDisplayedXMax,
1658                                myDisplayedYMin, myDisplayedYMax,
1659                                myDisplayedZMin, myDisplayedZMax);
1660     }
1661 }
1662
1663 void Application::setScanSide()
1664 {
1665         myScanSide = 
1666                 QInputDialog::getInteger(this, "Voxel demo-application", "Side of scanning (1: +X side, 2: +Y side, 3: +Z side, 4: +X & +Y sides, .. 7: +X, +Y,& +Z sides):", 
1667                                  myScanSide, 1, 7, 1);
1668 }
1669
1670 void Application::setVolumicBoolValue()
1671 {
1672         myVolumicBoolValue = 
1673                 QInputDialog::getInteger(this, "Voxel demo-application", "Volumic value on voxelization [0 .. 1]:", 
1674                                  myVolumicBoolValue, 0, 1, 1);
1675 }
1676
1677 void Application::setVolumicColorValue()
1678 {
1679         myVolumicColorValue = 
1680                 QInputDialog::getInteger(this, "Voxel demo-application", "Volumic value on voxelization [0 .. 15]:", 
1681                                  myVolumicColorValue, 0, 15, 1);
1682 }
1683
1684 void Application::setQuadrangleSize()
1685 {
1686         myQuadrangleSize = 
1687                 QInputDialog::getInteger(this, "Voxel demo-application", "Size of quadrangles (0% .. 100%):", 
1688                                  myQuadrangleSize, 1, 100, 10);
1689     if (!myVoxels.IsNull())
1690     {
1691         myVoxels->SetQuadrangleSize(myQuadrangleSize);
1692     }
1693 }
1694
1695 void Application::setPointSize()
1696 {
1697         myPointSize = 
1698                 QInputDialog::getInteger(this, "Voxel demo-application", "Size of points (1 .. 10):", 
1699                                  myPointSize, 1, 10, 1);
1700     if (!myVoxels.IsNull())
1701     {
1702         myVoxels->SetPointSize(myPointSize);
1703     }
1704 }
1705
1706 void Application::display(Voxel_VoxelDisplayMode mode)
1707 {
1708     if (myVoxels.IsNull() || !myViewer->getIC()->IsDisplayed(myVoxels))
1709     {
1710                 QMessageBox::warning( this, "Voxel demo-application", "Voxels are not displayed");
1711                 return;
1712         }
1713
1714     myVoxels->SetDisplayMode(mode);
1715
1716     if (myColorVoxels)
1717         displayColorScale();
1718     else
1719         myViewer->getView()->ColorScaleErase();
1720
1721     myViewer->getIC()->Redisplay(myVoxels, true);
1722 }
1723
1724 void Application::displayPoints()
1725 {
1726     display(Voxel_VDM_POINTS);
1727 }
1728
1729 void Application::displayNearestPoints()
1730 {
1731     display(Voxel_VDM_NEARESTPOINTS);
1732 }
1733
1734 void Application::displayBoxes()
1735 {
1736     display(Voxel_VDM_BOXES);
1737 }
1738
1739 void Application::displayNearestBoxes()
1740 {
1741     display(Voxel_VDM_NEARESTBOXES);
1742 }
1743
1744 void Application::displayColorScale()
1745 {
1746         Handle(Aspect_ColorScale) color_scale = myViewer->getView()->ColorScale();
1747         if (!color_scale.IsNull())
1748         {
1749         int nb_colors = 1<<4 /* 4 bits */;
1750         color_scale->SetRange(0, nb_colors - 1);
1751         color_scale->SetNumberOfIntervals(nb_colors);
1752                 color_scale->SetPosition(0.01, 0.5 - 0.01);
1753                 color_scale->SetSize(0.5 - 0.01, 0.5 - 0.01);
1754         }
1755     myViewer->getView()->ColorScaleDisplay();
1756 }
1757
1758 void Application::displayWaves()
1759 {
1760     myViewer->getIC()->EraseAll(false);
1761
1762     // Make voxels
1763     if (myBoolVoxels)
1764     {
1765         delete myBoolVoxels;
1766         myBoolVoxels = 0;
1767     }
1768     if (myColorVoxels)
1769         delete myColorVoxels;
1770
1771     int nbx = 500, nby = 50, nbz = 50;
1772     double xlen = 100.0, ylen = 100.0, zlen = 20.0;
1773     double dx = xlen / (double) nbx, dy = ylen / (double) nby, dz = zlen / (double) nbz;
1774     myColorVoxels = new Voxel_ColorDS(0.0, 0.0, 0.0, xlen, ylen, zlen, nbx, nby, nbz);
1775
1776     // Initial state - no colors
1777     int ix, iy, iz;
1778     for (ix = 0; ix < nbx; ix++)
1779     {
1780         for (iy = 0; iy < nby; iy++)
1781         {
1782             for (iz = 0; iz < nbz; iz++)
1783             {
1784                 myColorVoxels->Set(ix, iy, iz, 0);
1785             }
1786         }
1787     }
1788
1789     // Init visual data
1790     initPrs();
1791     myVoxels->SetDisplayMode(Voxel_VDM_POINTS);
1792     myVoxels->SetUsageOfGLlists(false);
1793         myVoxels->SetBoolVoxels(myBoolVoxels);
1794         myVoxels->SetColorVoxels(myColorVoxels);
1795     if (myViewer->getIC()->IsDisplayed(myVoxels))
1796         myViewer->getIC()->Redisplay(myVoxels, false);
1797     else
1798             myViewer->getIC()->Display(myVoxels, false);
1799     myViewer->getView()->FitAll();
1800
1801     // Prepare arrays of values
1802     // X&Z values
1803     int i = 0, di = 5 /* nb waves */;
1804     int* zvalues = new int[nbx];
1805     unsigned char* xvalues = new unsigned char[nbx];
1806     for (ix = 0; ix < nbx; ix++, i += di)
1807     {
1808         if (i > nbx || i < 0)
1809         {
1810             di *= -1;
1811             i += di;
1812         }
1813         double rad = -M_PI / 2.0 + double(i) / (double) nbx * M_PI;
1814         double c = cos(rad);
1815         xvalues[ix] = 15.0 * c;
1816         if (xvalues[ix] == 0)
1817             xvalues[ix] = 1;
1818         zvalues[ix] = (nbz - 2) * c;
1819     }
1820
1821     // Make waves
1822     unsigned char value = 0;
1823     for (i = 0; i <= 100; i++)
1824     {
1825         for (ix = 0; ix < nbx; ix++)
1826         {
1827             int ixi = ix + i;
1828             if (ixi >= nbx)
1829                 ixi -= nbx;
1830             for (iz = 0; iz < nbz; iz++)
1831             {
1832                 value = 0;
1833                 if (iz < zvalues[ixi])
1834                     value = xvalues[ixi];
1835                 for (iy = 0; iy < nby; iy++)
1836                 {
1837                     myColorVoxels->Set(ix, iy, iz, value);
1838                 }
1839             }
1840         }
1841         myViewer->getIC()->Redisplay(myVoxels, true);
1842         qApp->processEvents();
1843     }
1844
1845     delete[] xvalues;
1846     delete[] zvalues;
1847 }
1848
1849 void Application::initPrs()
1850 {
1851         if (myVoxels.IsNull())
1852     {
1853                 myVoxels = new Voxel_Prs;
1854         myVoxels->SetDisplayMode(Voxel_VDM_POINTS);
1855         myVoxels->SetColor(Quantity_NOC_WHITE);
1856         myVoxels->SetPointSize(1.0);
1857         myVoxels->SetSmoothPoints(false);
1858         myVoxels->SetQuadrangleSize(myQuadrangleSize);
1859         myVoxels->SetColorRange(myColorMinValue, myColorMaxValue);
1860         // Colors of ColorDS
1861         int nb_colors = 16 /* 4 bits */;
1862         Handle(Quantity_HArray1OfColor) colors = new Quantity_HArray1OfColor(0, nb_colors - 1);
1863         for (int icolor = 0; icolor < nb_colors; icolor++)
1864         {
1865             Quantity_Color color;
1866             Aspect_ColorScale::FindColor(icolor, 0, nb_colors - 1, nb_colors, color);
1867             colors->SetValue(icolor, color);
1868         }
1869         myVoxels->SetColors(colors);
1870         myViewer->setPrs(myVoxels);
1871     }
1872     else
1873     {
1874         myViewer->getIC()->RecomputePrsOnly(myVoxels, false);
1875     }
1876 }
1877
1878 void Application::box()
1879 {
1880     gp_Ax2 axes(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1));
1881     TopoDS_Shape S = BRepPrimAPI_MakeBox(axes, 100, 100, 100);
1882     load(S);
1883 }
1884
1885 void Application::cylinder()
1886 {
1887     TopoDS_Shape S = BRepPrimAPI_MakeCylinder(50, 100);
1888     load(S);
1889 }
1890
1891 void Application::torus()
1892 {
1893     TopoDS_Shape S = BRepPrimAPI_MakeTorus(100, 20);
1894     load(S);
1895 }
1896
1897 void Application::sphere()
1898 {
1899     TopoDS_Shape S = BRepPrimAPI_MakeSphere(100);
1900     load(S);
1901 }
1902
1903 void Application::load(const TopoDS_Shape& S)
1904 {
1905         myViewer->getIC()->EraseAll(false);
1906
1907     // Delete voxels of previous shape.
1908     if (myBoolVoxels)
1909     {
1910         delete myBoolVoxels;
1911         myBoolVoxels = 0;
1912     }
1913     if (myColorVoxels)
1914     {
1915         delete myColorVoxels;
1916         myColorVoxels = 0;
1917     }
1918     
1919     // Set view size
1920     Bnd_Box box;
1921     double xmin, ymin, zmin, xmax, ymax, zmax, length = 0;
1922     BRepBndLib::Add(S, box);
1923     box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
1924     length = xmax - xmin > ymax - ymin ? xmax - xmin : ymax - ymin;
1925     length = length > zmax - zmin ? length : zmax - zmin;
1926     length *= 2.0;
1927     myViewer->getView()->SetSize(length);
1928     myViewer->getView()->SetZSize(length);
1929
1930     // Display shape
1931         if (myShape.IsNull())
1932         {
1933                 myShape = new AIS_Shape(S);
1934                 myShape->SetDisplayMode(1);
1935         myShape->UnsetSelectionMode();
1936         }
1937         else
1938         {
1939                 myShape->Set(S);
1940         myViewer->getIC()->RecomputePrsOnly(myShape, false);
1941         }
1942     if (myViewer->getIC()->IsDisplayed(myShape))
1943         myViewer->getIC()->Redisplay(myShape, false);
1944     else
1945             myViewer->getIC()->Display(myShape, false);
1946         myViewer->getView()->FitAll();
1947 }
1948
1949 void Application::displayCut()
1950 {
1951     myViewer->getIC()->EraseAll(false);
1952
1953     // Make a sphere with a lot of toruses, 
1954     // cut the toruses from the sphere.
1955     TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(100.0);
1956     TopoDS_Shape torus1 = BRepPrimAPI_MakeTorus(gp_Ax2(gp_Pnt( 80,   0, 20), gp::DZ()), 30, 10);
1957     TopoDS_Shape torus2 = BRepPrimAPI_MakeTorus(gp_Ax2(gp_Pnt(  0,  80, 20), gp::DZ()), 30, 10);
1958     TopoDS_Shape torus3 = BRepPrimAPI_MakeTorus(gp_Ax2(gp_Pnt(-80,   0, 20), gp::DZ()), 30, 10);
1959     TopoDS_Shape torus4 = BRepPrimAPI_MakeTorus(gp_Ax2(gp_Pnt(  0, -80, 20), gp::DZ()), 30, 10);
1960
1961     // Compute bounding box of the shapes
1962     Bnd_Box box;
1963     BRepBndLib::Add(sphere, box);
1964     BRepBndLib::Add(torus1, box);
1965     BRepBndLib::Add(torus2, box);
1966     BRepBndLib::Add(torus3, box);
1967     BRepBndLib::Add(torus4, box);
1968
1969     // Nullify voxels
1970     if (myColorVoxels)
1971     {
1972         delete myColorVoxels;
1973         myColorVoxels = 0;
1974     }
1975     if (myBoolVoxels)
1976     {
1977         delete myBoolVoxels;
1978         myBoolVoxels = 0;
1979     }
1980
1981     Timer timer;
1982     timer.Start();
1983
1984     // Create a cube of voxels
1985     int nbx = 100, nby = 100, nbz = 100;
1986     double xmin, ymin, zmin, xmax, ymax, zmax;
1987     box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
1988     myColorVoxels = new Voxel_ColorDS(xmin, ymin, zmin, 
1989                                       xmax - xmin, ymax - ymin, zmax - zmin,
1990                                       nbx, nby, nbz);
1991     Voxel_ColorDS vtorus(xmin, ymin, zmin, 
1992                          xmax - xmin, ymax - ymin, zmax - zmin,
1993                          nbx, nby, nbz);
1994
1995     // Make a cube of voxels for the sphere.
1996     int progress;
1997     Voxel_FastConverter converter(sphere, *myColorVoxels, 0.1, nbx, nby, nbz);
1998     converter.Convert(progress);
1999     converter.FillInVolume(15);
2000    
2001     // Torus 1
2002     Voxel_FastConverter converter1(torus1, vtorus, 0.1, nbx, nby, nbz);
2003     converter1.Convert(progress);
2004     converter1.FillInVolume(3);
2005    
2006     // Torus 2
2007     Voxel_FastConverter converter2(torus2, vtorus, 0.1, nbx, nby, nbz);
2008     converter2.Convert(progress);
2009     converter2.FillInVolume(7);
2010    
2011     // Torus 3
2012     Voxel_FastConverter converter3(torus3, vtorus, 0.1, nbx, nby, nbz);
2013     converter3.Convert(progress);
2014     converter3.FillInVolume(10);
2015    
2016     // Torus 4
2017     Voxel_FastConverter converter4(torus4, vtorus, 0.1, nbx, nby, nbz);
2018     converter4.Convert(progress);
2019     converter4.FillInVolume(12);
2020
2021     // Cut
2022     Voxel_BooleanOperation cutter;
2023     cutter.Cut(*myColorVoxels, vtorus);
2024
2025     // Remove volumic voxels
2026     converter.FillInVolume(0);
2027
2028     timer.Stop();
2029     timer.Print("Cut");
2030
2031     // Display
2032     initPrs();
2033     myVoxels->SetDisplayMode(Voxel_VDM_POINTS);
2034     myVoxels->SetUsageOfGLlists(true);
2035         myVoxels->SetBoolVoxels(myBoolVoxels);
2036         myVoxels->SetColorVoxels(myColorVoxels);
2037     if (myViewer->getIC()->IsDisplayed(myVoxels))
2038         myViewer->getIC()->Redisplay(myVoxels, false);
2039     else
2040             myViewer->getIC()->Display(myVoxels, false);
2041     myViewer->getView()->FitAll();
2042 }
2043
2044 void Application::displayCollisions()
2045 {
2046     myViewer->getIC()->EraseAll(false);
2047
2048     // Make a big box with a lot of small spheres inside.
2049     double x = 0.0, y = 0.0, z = 0.0, xlen = 100.0, ylen = 100.0, zlen = 100.0, r = 10.0;
2050     gp_Pnt P1(x, y, z); // center point of moving sphere (S1).
2051     TopoDS_Shape B   = BRepPrimAPI_MakeBox(gp_Pnt(x-r, y-r, z-r), gp_Pnt(xlen+r, ylen+r, zlen+r));
2052     TopoDS_Shape S1  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       y,       z),       gp::DZ()), r / 2.0);
2053     TopoDS_Shape S2  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., y,       z),       gp::DZ()), r);
2054     TopoDS_Shape S3  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    y,       z),       gp::DZ()), r);
2055     TopoDS_Shape S4  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen/2., z),       gp::DZ()), r);
2056     TopoDS_Shape S5  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen/2., z),       gp::DZ()), r);
2057     TopoDS_Shape S6  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen/2., z),       gp::DZ()), r);
2058     TopoDS_Shape S7  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen,    z),       gp::DZ()), r);
2059     TopoDS_Shape S8  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen,    z),       gp::DZ()), r);
2060     TopoDS_Shape S9  = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen,    z),       gp::DZ()), r);
2061     TopoDS_Shape S10 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       y,       zlen/2.), gp::DZ()), r);
2062     TopoDS_Shape S11 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., y,       zlen/2.), gp::DZ()), r);
2063     TopoDS_Shape S12 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    y,       zlen/2.), gp::DZ()), r);
2064     TopoDS_Shape S13 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen/2., zlen/2.), gp::DZ()), r);
2065     TopoDS_Shape S14 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen/2., zlen/2.), gp::DZ()), r);
2066     TopoDS_Shape S15 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen/2., zlen/2.), gp::DZ()), r);
2067     TopoDS_Shape S16 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen,    zlen/2.), gp::DZ()), r);
2068     TopoDS_Shape S17 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen,    zlen/2.), gp::DZ()), r);
2069     TopoDS_Shape S18 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen,    zlen/2.), gp::DZ()), r);
2070     TopoDS_Shape S19 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       y,       zlen),    gp::DZ()), r);
2071     TopoDS_Shape S20 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., y,       zlen),    gp::DZ()), r);
2072     TopoDS_Shape S21 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    y,       zlen),    gp::DZ()), r);
2073     TopoDS_Shape S22 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen/2., zlen),    gp::DZ()), r);
2074     TopoDS_Shape S23 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen/2., zlen),    gp::DZ()), r);
2075     TopoDS_Shape S24 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen/2., zlen),    gp::DZ()), r);
2076     TopoDS_Shape S25 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(x,       ylen,    zlen),    gp::DZ()), r);
2077     TopoDS_Shape S26 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen/2., ylen,    zlen),    gp::DZ()), r);
2078     TopoDS_Shape S27 = BRepPrimAPI_MakeSphere(gp_Ax2(gp_Pnt(xlen,    ylen,    zlen),    gp::DZ()), r);
2079
2080     // Planes of the big box
2081     gp_Ax2 xminusPlane(gp_Pnt(x,    y,    z),    gp::DX());
2082     gp_Ax2 xplusPlane (gp_Pnt(xlen, y,    z),    gp::DX());
2083     gp_Ax2 yminusPlane(gp_Pnt(x,    y,    z),    gp::DY());
2084     gp_Ax2 yplusPlane (gp_Pnt(x,    ylen, z),    gp::DY());
2085     gp_Ax2 zminusPlane(gp_Pnt(x,    y,    z),    gp::DZ());
2086     gp_Ax2 zplusPlane (gp_Pnt(x,    y,    zlen), gp::DZ());
2087
2088     // Nullify voxels
2089     if (myColorVoxels)
2090     {
2091         delete myColorVoxels;
2092         myColorVoxels = 0;
2093     }
2094     if (myBoolVoxels)
2095     {
2096         delete myBoolVoxels;
2097         myBoolVoxels = 0;
2098     }
2099
2100     // Prepare visualization
2101     initPrs();
2102     myVoxels->SetDisplayMode(Voxel_VDM_POINTS);
2103     myVoxels->SetColor(Quantity_NOC_RED);
2104     myVoxels->SetPointSize(4);
2105     myVoxels->SetSmoothPoints(false);
2106     myVoxels->SetUsageOfGLlists(false);
2107         myVoxels->SetColorVoxels(myColorVoxels);
2108
2109     // Display all shapes
2110     double transparency = 0.9;
2111     Handle(AIS_Shape) aisB   = new AIS_Shape(B);
2112     Handle(AIS_Shape) aisS1  = new AIS_Shape(S1);
2113     Handle(AIS_Shape) aisS2  = new AIS_Shape(S2);
2114     Handle(AIS_Shape) aisS3  = new AIS_Shape(S3);
2115     Handle(AIS_Shape) aisS4  = new AIS_Shape(S4);
2116     Handle(AIS_Shape) aisS5  = new AIS_Shape(S5);
2117     Handle(AIS_Shape) aisS6  = new AIS_Shape(S6);
2118     Handle(AIS_Shape) aisS7  = new AIS_Shape(S7);
2119     Handle(AIS_Shape) aisS8  = new AIS_Shape(S8);
2120     Handle(AIS_Shape) aisS9  = new AIS_Shape(S9);
2121     Handle(AIS_Shape) aisS10 = new AIS_Shape(S10);
2122     Handle(AIS_Shape) aisS11 = new AIS_Shape(S11);
2123     Handle(AIS_Shape) aisS12 = new AIS_Shape(S12);
2124     Handle(AIS_Shape) aisS13 = new AIS_Shape(S13);
2125     Handle(AIS_Shape) aisS14 = new AIS_Shape(S14);
2126     Handle(AIS_Shape) aisS15 = new AIS_Shape(S15);
2127     Handle(AIS_Shape) aisS16 = new AIS_Shape(S16);
2128     Handle(AIS_Shape) aisS17 = new AIS_Shape(S17);
2129     Handle(AIS_Shape) aisS18 = new AIS_Shape(S18);
2130     Handle(AIS_Shape) aisS19 = new AIS_Shape(S19);
2131     Handle(AIS_Shape) aisS20 = new AIS_Shape(S20);
2132     Handle(AIS_Shape) aisS21 = new AIS_Shape(S21);
2133     Handle(AIS_Shape) aisS22 = new AIS_Shape(S22);
2134     Handle(AIS_Shape) aisS23 = new AIS_Shape(S23);
2135     Handle(AIS_Shape) aisS24 = new AIS_Shape(S24);
2136     Handle(AIS_Shape) aisS25 = new AIS_Shape(S25);
2137     Handle(AIS_Shape) aisS26 = new AIS_Shape(S26);
2138     Handle(AIS_Shape) aisS27 = new AIS_Shape(S27);
2139     aisS1-> SetDisplayMode(1);
2140     aisS2-> SetDisplayMode(1);
2141     aisS3-> SetDisplayMode(1);
2142     aisS4-> SetDisplayMode(1);
2143     aisS5-> SetDisplayMode(1);
2144     aisS6-> SetDisplayMode(1);
2145     aisS7-> SetDisplayMode(1);
2146     aisS8-> SetDisplayMode(1);
2147     aisS9-> SetDisplayMode(1);
2148     aisS10->SetDisplayMode(1);
2149     aisS11->SetDisplayMode(1);
2150     aisS12->SetDisplayMode(1);
2151     aisS13->SetDisplayMode(1);
2152     aisS14->SetDisplayMode(1);
2153     aisS15->SetDisplayMode(1);
2154     aisS16->SetDisplayMode(1);
2155     aisS17->SetDisplayMode(1);
2156     aisS18->SetDisplayMode(1);
2157     aisS19->SetDisplayMode(1);
2158     aisS20->SetDisplayMode(1);
2159     aisS21->SetDisplayMode(1);
2160     aisS22->SetDisplayMode(1);
2161     aisS23->SetDisplayMode(1);
2162     aisS24->SetDisplayMode(1);
2163     aisS25->SetDisplayMode(1);
2164     aisS26->SetDisplayMode(1);
2165     aisS27->SetDisplayMode(1);
2166     aisB->  UnsetSelectionMode();
2167     aisS1-> UnsetSelectionMode();
2168     aisS2-> UnsetSelectionMode();
2169     aisS3-> UnsetSelectionMode();
2170     aisS4-> UnsetSelectionMode();
2171     aisS5-> UnsetSelectionMode();
2172     aisS6-> UnsetSelectionMode();
2173     aisS7-> UnsetSelectionMode();
2174     aisS8-> UnsetSelectionMode();
2175     aisS9-> UnsetSelectionMode();
2176     aisS10->UnsetSelectionMode();
2177     aisS11->UnsetSelectionMode();
2178     aisS12->UnsetSelectionMode();
2179     aisS13->UnsetSelectionMode();
2180     aisS14->UnsetSelectionMode();
2181     aisS15->UnsetSelectionMode();
2182     aisS16->UnsetSelectionMode();
2183     aisS17->UnsetSelectionMode();
2184     aisS18->UnsetSelectionMode();
2185     aisS19->UnsetSelectionMode();
2186     aisS20->UnsetSelectionMode();
2187     aisS21->UnsetSelectionMode();
2188     aisS22->UnsetSelectionMode();
2189     aisS23->UnsetSelectionMode();
2190     aisS24->UnsetSelectionMode();
2191     aisS25->UnsetSelectionMode();
2192     aisS26->UnsetSelectionMode();
2193     aisS27->UnsetSelectionMode();
2194     aisS1-> SetTransparency(2.0 * transparency / 3.0);
2195     aisS2-> SetTransparency(transparency);
2196     aisS3-> SetTransparency(transparency);
2197     aisS4-> SetTransparency(transparency);
2198     aisS5-> SetTransparency(transparency);
2199     aisS6-> SetTransparency(transparency);
2200     aisS7-> SetTransparency(transparency);
2201     aisS8-> SetTransparency(transparency);
2202     aisS9-> SetTransparency(transparency);
2203     aisS10->SetTransparency(transparency);
2204     aisS11->SetTransparency(transparency);
2205     aisS12->SetTransparency(transparency);
2206     aisS13->SetTransparency(transparency);
2207     aisS14->SetTransparency(transparency);
2208     aisS15->SetTransparency(transparency);
2209     aisS16->SetTransparency(transparency);
2210     aisS17->SetTransparency(transparency);
2211     aisS18->SetTransparency(transparency);
2212     aisS19->SetTransparency(transparency);
2213     aisS20->SetTransparency(transparency);
2214     aisS21->SetTransparency(transparency);
2215     aisS22->SetTransparency(transparency);
2216     aisS23->SetTransparency(transparency);
2217     aisS24->SetTransparency(transparency);
2218     aisS25->SetTransparency(transparency);
2219     aisS26->SetTransparency(transparency);
2220     aisS27->SetTransparency(transparency);
2221     myViewer->getIC()->Display(aisB, false);
2222     myViewer->getIC()->Display(aisS1, false);
2223     myViewer->getIC()->Display(aisS2, false);
2224     myViewer->getIC()->Display(aisS3, false);
2225     myViewer->getIC()->Display(aisS4, false);
2226     myViewer->getIC()->Display(aisS5, false);
2227     myViewer->getIC()->Display(aisS6, false);
2228     myViewer->getIC()->Display(aisS7, false);
2229     myViewer->getIC()->Display(aisS8, false);
2230     myViewer->getIC()->Display(aisS9, false);
2231     myViewer->getIC()->Display(aisS10, false);
2232     myViewer->getIC()->Display(aisS11, false);
2233     myViewer->getIC()->Display(aisS12, false);
2234     myViewer->getIC()->Display(aisS13, false);
2235     myViewer->getIC()->Display(aisS14, false);
2236     myViewer->getIC()->Display(aisS15, false);
2237     myViewer->getIC()->Display(aisS16, false);
2238     myViewer->getIC()->Display(aisS17, false);
2239     myViewer->getIC()->Display(aisS18, false);
2240     myViewer->getIC()->Display(aisS19, false);
2241     myViewer->getIC()->Display(aisS20, false);
2242     myViewer->getIC()->Display(aisS21, false);
2243     myViewer->getIC()->Display(aisS22, false);
2244     myViewer->getIC()->Display(aisS23, false);
2245     myViewer->getIC()->Display(aisS24, false);
2246     myViewer->getIC()->Display(aisS25, false);
2247     myViewer->getIC()->Display(aisS26, false);
2248     myViewer->getIC()->Display(aisS27, false);
2249
2250     // Prepare computer of collisions
2251     double deflection = 0.1;
2252     int nbx = 100, nby = 100, nbz = 100;
2253     
2254     Voxel_CollisionDetection coldet(deflection, nbx, nby, nbz);
2255     coldet.SetUsageOfVolume(false);
2256     coldet.KeepCollisions(false);
2257     coldet.AddShape(S1);
2258     coldet.AddShape(S2);
2259     coldet.AddShape(S3);
2260     coldet.AddShape(S4);
2261     coldet.AddShape(S5);
2262     coldet.AddShape(S6);
2263     coldet.AddShape(S7);
2264     coldet.AddShape(S8);
2265     coldet.AddShape(S9);
2266     coldet.AddShape(S10);
2267     coldet.AddShape(S11);
2268     coldet.AddShape(S12);
2269     coldet.AddShape(S13);
2270     coldet.AddShape(S14);
2271     coldet.AddShape(S15);
2272     coldet.AddShape(S16);
2273     coldet.AddShape(S17);
2274     coldet.AddShape(S18);
2275     coldet.AddShape(S19);
2276     coldet.AddShape(S20);
2277     coldet.AddShape(S21);
2278     coldet.AddShape(S22);
2279     coldet.AddShape(S23);
2280     coldet.AddShape(S24);
2281     coldet.AddShape(S25);
2282     coldet.AddShape(S26);
2283     coldet.AddShape(S27);
2284     //coldet.AddShape(BRepPrimAPI_MakeBox(gp_Pnt(x, y, z), gp_Pnt(xlen, ylen, zlen)));
2285     
2286     Bnd_Box box;
2287     BRepBndLib::Add(B, box);
2288     coldet.SetBoundaryBox(box);
2289
2290     coldet.Voxelize();
2291
2292     // Move one of the spheres inside the box
2293     // and compute collisions
2294     gp_Trsf trsf;
2295     gp_Vec vmove(1, 0.5, 0.25);
2296
2297     int imove = 0, nb_moves = 900;
2298     while (imove < nb_moves)
2299     {
2300         // Move
2301         trsf.SetTranslation(vmove);
2302         TopLoc_Location loc(trsf);
2303         S1.Move(loc);
2304         P1.Translate(vmove);
2305         
2306         // Check whether S1 is inside the big box
2307         // Detect the plane S1 touches to.
2308         if (P1.X() < x)
2309             vmove.Mirror(xminusPlane);
2310         else if (P1.X() > xlen)
2311             vmove.Mirror(xplusPlane);
2312         else if (P1.Y() < y)
2313             vmove.Mirror(yminusPlane);
2314         else if (P1.Y() > ylen)
2315             vmove.Mirror(yplusPlane);
2316         else if (P1.Z() < z)
2317             vmove.Mirror(zminusPlane);
2318         else if (P1.Z() > zlen)
2319             vmove.Mirror(zplusPlane);
2320
2321         // Compute collisions
2322         coldet.ReplaceShape(1, S1);
2323         coldet.Voxelize(1); // only the first sphere (S1)
2324         coldet.Compute();
2325         myBoolVoxels = &((Voxel_BoolDS&) coldet.GetCollisions());
2326
2327         // Redisplay S1
2328         aisS1->Set(S1);
2329         myViewer->getIC()->Redisplay(aisS1, false);
2330
2331         // Display the collisions
2332         myVoxels->SetBoolVoxels(myBoolVoxels);
2333         if (myViewer->getIC()->IsDisplayed(myVoxels))
2334             myViewer->getIC()->Redisplay(myVoxels, true);
2335         else
2336         {
2337                 myViewer->getIC()->Display(myVoxels, false);
2338             myViewer->getView()->FitAll();
2339         }
2340
2341         imove++;
2342         qApp->processEvents();
2343     }
2344
2345     // Copy the result of collision detection
2346     int ix, iy, iz;
2347     myBoolVoxels = new Voxel_BoolDS(coldet.GetCollisions().GetX(), 
2348                                     coldet.GetCollisions().GetY(), 
2349                                     coldet.GetCollisions().GetZ(), 
2350                                     coldet.GetCollisions().GetXLen(), 
2351                                     coldet.GetCollisions().GetYLen(), 
2352                                     coldet.GetCollisions().GetZLen(), 
2353                                     nbx, nby, nbz);
2354     for (ix = 0; ix < nbx; ix++)
2355     {
2356         for (iy = 0; iy < nby; iy++)
2357         {
2358             for (iz = 0; iz < nbz; iz++)
2359             {
2360                 if (coldet.GetCollisions().Get(ix, iy, iz))
2361                     myBoolVoxels->Set(ix, iy, iz, Standard_True);
2362             }
2363         }
2364     }
2365     myVoxels->SetBoolVoxels(myBoolVoxels);
2366 }