0023841: Redundant assignment to itself.
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands.cxx
1 // Created on: 1998-09-01
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 // Robert Boehne 30 May 2000 : Dec Osf
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #ifdef WNT
29 #include <windows.h>
30 #endif
31
32 #include <Graphic3d_AspectMarker3d.hxx>
33 #include <Graphic3d_GraphicDriver.hxx>
34 #include <Graphic3d_ExportFormat.hxx>
35 #include <Graphic3d_NameOfTextureEnv.hxx>
36 #include <Graphic3d_TextureEnv.hxx>
37 #include <Graphic3d_TextureParams.hxx>
38 #include <Graphic3d_TypeOfTextureFilter.hxx>
39 #include <ViewerTest.hxx>
40 #include <ViewerTest_EventManager.hxx>
41 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
42 #include <Visual3d_View.hxx>
43 #include <Visual3d_ViewManager.hxx>
44 #include <V3d_LayerMgr.hxx>
45 #include <NIS_View.hxx>
46 #include <NIS_Triangulated.hxx>
47 #include <NIS_InteractiveContext.hxx>
48 #include <AIS_InteractiveContext.hxx>
49 #include <Draw_Interpretor.hxx>
50 #include <Draw.hxx>
51 #include <Draw_Appli.hxx>
52 #include <Aspect_PrintAlgo.hxx>
53 #include <Image_AlienPixMap.hxx>
54 #include <OSD_Timer.hxx>
55 #include <TColStd_SequenceOfInteger.hxx>
56 #include <TColStd_HSequenceOfReal.hxx>
57 #include <TColgp_Array1OfPnt2d.hxx>
58 #include <Visual3d_LayerItem.hxx>
59 #include <V3d_LayerMgr.hxx>
60 #include <V3d_LayerMgrPointer.hxx>
61 #include <Aspect_TypeOfLine.hxx>
62 #include <Image_Diff.hxx>
63 #include <Aspect_DisplayConnection.hxx>
64 #include <Graphic3d.hxx>
65
66 #ifdef WNT
67 #undef DrawText
68 #endif
69
70 #include <Visual3d_Layer.hxx>
71 #include <cstdlib>
72
73 #if defined(_WIN32) || defined(__WIN32__)
74   #include <WNT_WClass.hxx>
75   #include <WNT_Window.hxx>
76
77   #if defined(_MSC_VER)
78     #define _CRT_SECURE_NO_DEPRECATE
79     #pragma warning (disable:4996)
80   #endif
81 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
82   #include <Cocoa_Window.hxx>
83   #include <tk.h>
84 #else
85   #include <Xw_WindowQuality.hxx>
86   #include <Xw_Window.hxx>
87   #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
88   #include <X11/Xutil.h>
89   #include <tk.h>
90 #endif
91
92 //==============================================================================
93
94 //==============================================================================
95 //  VIEWER GLOBAL VARIABLES
96 //==============================================================================
97
98 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
99
100 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
101 extern const Handle(NIS_InteractiveContext)& TheNISContext();
102 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
103
104 #if defined(_WIN32) || defined(__WIN32__)
105 static Handle(WNT_Window)& VT_GetWindow() {
106   static Handle(WNT_Window) WNTWin;
107   return WNTWin;
108 }
109 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
110 static Handle(Cocoa_Window)& VT_GetWindow()
111 {
112   static Handle(Cocoa_Window) aWindow;
113   return aWindow;
114 }
115 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
116 #else
117 static Handle(Xw_Window)& VT_GetWindow(){
118   static Handle(Xw_Window) XWWin;
119   return XWWin;
120 }
121 static Display *display;
122
123 static void VProcessEvents(ClientData,int);
124 #endif
125
126 static Handle(Graphic3d_GraphicDriver)& GetGraphicDriver()
127 {
128   static Handle(Graphic3d_GraphicDriver) aGraphicDriver;
129   return aGraphicDriver;
130 }
131
132 static Standard_Boolean DegenerateMode = Standard_True;
133
134 #define ZCLIPWIDTH 1.
135
136 static void OSWindowSetup();
137
138 //==============================================================================
139 //  EVENT GLOBAL VARIABLES
140 //==============================================================================
141
142 static int Start_Rot = 0;
143 static int ZClipIsOn = 0;
144 int X_Motion = 0; // Current cursor position
145 int Y_Motion = 0;
146 int X_ButtonPress = 0; // Last ButtonPress position
147 int Y_ButtonPress = 0;
148 Standard_Boolean IsDragged = Standard_False;
149 Standard_Boolean DragFirst;
150
151 //==============================================================================
152
153 #ifdef WNT
154 static LRESULT WINAPI ViewerWindowProc(
155                                        HWND hwnd,
156                                        UINT uMsg,
157                                        WPARAM wParam,
158                                        LPARAM lParam );
159 static LRESULT WINAPI AdvViewerWindowProc(
160   HWND hwnd,
161   UINT uMsg,
162   WPARAM wParam,
163   LPARAM lParam );
164 #endif
165
166
167 //==============================================================================
168 //function : WClass
169 //purpose  :
170 //==============================================================================
171
172 const Handle(MMgt_TShared)& ViewerTest::WClass()
173 {
174   static Handle(MMgt_TShared) theWClass;
175 #if defined(_WIN32) || defined(__WIN32__)
176   if (theWClass.IsNull())
177   {
178     theWClass = new WNT_WClass ("GW3D_Class", AdvViewerWindowProc,
179       CS_VREDRAW | CS_HREDRAW, 0, 0,
180       ::LoadCursor (NULL, IDC_ARROW));
181   }
182 #endif
183   return theWClass;
184 }
185
186 //==============================================================================
187 //function : ViewerInit
188 //purpose  : Create the window viewer and initialize all the global variable
189 //==============================================================================
190
191 void ViewerTest::ViewerInit (const Standard_Integer thePxLeft,  const Standard_Integer thePxTop,
192                              const Standard_Integer thePxWidth, const Standard_Integer thePxHeight)
193 {
194   static Standard_Boolean isFirst = Standard_True;
195
196   // Default position and dimension of the viewer window.
197   // Note that left top corner is set to be sufficiently small to have
198   // window fit in the small screens (actual for remote desktops, see #23003).
199   // The position corresponds to the window's client area, thus some
200   // gap is added for window frame to be visible.
201   Standard_Integer aPxLeft   = 20;
202   Standard_Integer aPxTop    = 40;
203   Standard_Integer aPxWidth  = 409;
204   Standard_Integer aPxHeight = 409;
205   if (thePxWidth != 0 && thePxHeight != 0)
206   {
207     aPxLeft   = thePxLeft;
208     aPxTop    = thePxTop;
209     aPxWidth  = thePxWidth;
210     aPxHeight = thePxHeight;
211   }
212
213   if (isFirst)
214   {
215     Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection();
216     if (GetGraphicDriver().IsNull())
217     {
218       GetGraphicDriver() = Graphic3d::InitGraphicDriver (aDisplayConnection);
219     }
220 #if defined(_WIN32) || defined(__WIN32__)
221     if (VT_GetWindow().IsNull())
222     {
223       VT_GetWindow() = new WNT_Window ("Test3d",
224                                        Handle(WNT_WClass)::DownCast (WClass()),
225                                        WS_OVERLAPPEDWINDOW,
226                                        aPxLeft, aPxTop,
227                                        aPxWidth, aPxHeight,
228                                        Quantity_NOC_BLACK);
229     }
230 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
231     if (VT_GetWindow().IsNull())
232     {
233       VT_GetWindow() = new Cocoa_Window ("Test3d",
234                                          aPxLeft, aPxTop,
235                                          aPxWidth, aPxHeight);
236       ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
237     }
238 #else
239     if (VT_GetWindow().IsNull())
240     {
241       VT_GetWindow() = new Xw_Window (aDisplayConnection,
242                                       "Test3d",
243                                       aPxLeft, aPxTop,
244                                       aPxWidth, aPxHeight,
245                                       Quantity_NOC_BLACK);
246     }
247 #endif
248     VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
249
250     Handle(V3d_Viewer) a3DViewer, a3DCollector;
251     // Viewer and View creation
252
253     TCollection_ExtendedString NameOfWindow("Visu3D");
254
255     a3DViewer = new V3d_Viewer(GetGraphicDriver(), NameOfWindow.ToExtString());
256     NameOfWindow = TCollection_ExtendedString("Collector");
257     a3DCollector = new V3d_Viewer(GetGraphicDriver(), NameOfWindow.ToExtString());
258     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
259     a3DCollector->SetDefaultBackgroundColor(Quantity_NOC_STEELBLUE);
260     Handle(NIS_View) aView = Handle(NIS_View)::DownCast(ViewerTest::CurrentView());
261     if (aView.IsNull())
262     {
263       //Handle(V3d_View) a3DViewCol = a3DViewer->CreateView();
264       aView = new NIS_View (a3DViewer, VT_GetWindow());
265       ViewerTest::CurrentView(aView);
266       TheNISContext()->AttachView (aView);
267     }
268
269     // AIS setup
270     if ( ViewerTest::GetAISContext().IsNull() ) {
271       Handle(AIS_InteractiveContext) C =
272         new AIS_InteractiveContext(a3DViewer,a3DCollector);
273       ViewerTest::SetAISContext(C);
274     }
275
276     // Setup for X11 or NT
277     OSWindowSetup();
278     // Viewer and View creation
279
280     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
281
282     Handle (V3d_View) V = ViewerTest::CurrentView();
283
284     V->SetDegenerateModeOn();
285     DegenerateMode = V->DegenerateModeIsOn();
286     //    V->SetWindow(VT_GetWindow(), NULL, MyViewProc, NULL);
287
288     V->SetZClippingDepth(0.5);
289     V->SetZClippingWidth(ZCLIPWIDTH/2.);
290     a3DViewer->SetDefaultLights();
291     a3DViewer->SetLightOn();
292
293   #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
294   #if TCL_MAJOR_VERSION  < 8
295     Tk_CreateFileHandler((void*)ConnectionNumber(display),
296       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
297   #else
298     Tk_CreateFileHandler(ConnectionNumber(display),
299       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
300   #endif
301   #endif
302
303     isFirst = Standard_False;
304   }
305
306   VT_GetWindow()->Map();
307   ViewerTest::CurrentView()->Redraw();
308 }
309
310 //==============================================================================
311 //function : Vinit
312 //purpose  : Create the window viewer and initialize all the global variable
313 //    Use Tk_CreateFileHandler on UNIX to cath the X11 Viewer event
314 //==============================================================================
315
316 static int VInit (Draw_Interpretor& , Standard_Integer argc, const char** argv)
317 {
318   Standard_Integer aPxLeft   = (argc > 1) ? Draw::Atoi (argv[1]) : 0;
319   Standard_Integer aPxTop    = (argc > 2) ? Draw::Atoi (argv[2]) : 0;
320   Standard_Integer aPxWidth  = (argc > 3) ? Draw::Atoi (argv[3]) : 0;
321   Standard_Integer aPxHeight = (argc > 4) ? Draw::Atoi (argv[4]) : 0;
322   ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight);
323   return 0;
324 }
325
326 //==============================================================================
327 //function : VT_ProcessKeyPress
328 //purpose  : Handle KeyPress event from a CString
329 //==============================================================================
330 void VT_ProcessKeyPress (const char* buf_ret)
331 {
332   //cout << "KeyPress" << endl;
333   const Handle(V3d_View) aView = ViewerTest::CurrentView();
334   const Handle(NIS_View) aNisView = Handle(NIS_View)::DownCast (aView);
335   // Letter in alphabetic order
336
337   if ( !strcasecmp(buf_ret, "A") ) {
338     // AXO
339     aView->SetProj(V3d_XposYnegZpos);
340   }
341   else if ( !strcasecmp(buf_ret, "D") ) {
342     // Reset
343     aView->Reset();
344   }
345   else if ( !strcasecmp(buf_ret, "F") ) {
346     // FitAll
347     if (aNisView.IsNull())
348       aView->FitAll();
349     else
350       aNisView->FitAll3d();
351   }
352   else if ( !strcasecmp(buf_ret, "H") ) {
353     // HLR
354     cout << "HLR" << endl;
355
356     if (aView->DegenerateModeIsOn()) ViewerTest::CurrentView()->SetDegenerateModeOff();
357     else aView->SetDegenerateModeOn();
358     DegenerateMode = aView->DegenerateModeIsOn();
359   }
360   else if ( !strcasecmp(buf_ret, "S") ) {
361     // SHADING
362     cout << "passage en mode 1 (shading pour les shapes)" << endl;
363
364     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
365     if(Ctx->NbCurrents()==0 ||
366       Ctx->NbSelected()==0)
367       Ctx->SetDisplayMode(AIS_Shaded);
368     else{
369       if(Ctx->HasOpenedContext()){
370         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
371           Ctx->SetDisplayMode(Ctx->Interactive(),1,Standard_False);
372       }
373       else{
374         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
375           Ctx->SetDisplayMode(Ctx->Current(),1,Standard_False);
376       }
377       Ctx->UpdateCurrentViewer();
378     }
379   }
380   else if ( !strcasecmp(buf_ret, "U") ) {
381     // Unset display mode
382     cout<<"passage au mode par defaut"<<endl;
383
384     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
385     if(Ctx->NbCurrents()==0 ||
386       Ctx->NbSelected()==0)
387       Ctx->SetDisplayMode(AIS_WireFrame);
388     else{
389       if(Ctx->HasOpenedContext()){
390         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
391           Ctx->UnsetDisplayMode(Ctx->Interactive(),Standard_False);
392       }
393       else{
394         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
395           Ctx->UnsetDisplayMode(Ctx->Current(),Standard_False);
396       }
397       Ctx->UpdateCurrentViewer();
398     }
399
400   }
401   else if ( !strcasecmp(buf_ret, "T") ) {
402     // Top
403     aView->SetProj(V3d_Zpos);
404   }
405   else if ( !strcasecmp(buf_ret, "B") ) {
406     // Bottom
407     aView->SetProj(V3d_Zneg);
408   }
409   else if ( !strcasecmp(buf_ret, "L") ) {
410     // Left
411     aView->SetProj(V3d_Xneg);
412   }
413   else if ( !strcasecmp(buf_ret, "R") ) {
414     // Right
415     aView->SetProj(V3d_Xpos);
416   }
417
418   else if ( !strcasecmp(buf_ret, "W") ) {
419     // WIREFRAME
420     cout << "passage en mode 0 (filaire pour les shapes)" << endl;
421     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
422     if(Ctx->NbCurrents()==0 ||
423       Ctx->NbSelected()==0)
424       Ctx->SetDisplayMode(AIS_WireFrame);
425     else{
426       if(Ctx->HasOpenedContext()){
427         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
428           Ctx->SetDisplayMode(Ctx->Interactive(),0,Standard_False);
429       }
430       else{
431         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
432           Ctx->SetDisplayMode(Ctx->Current(),0,Standard_False);
433       }
434       Ctx->UpdateCurrentViewer();
435     }
436   }
437   else if ( !strcasecmp(buf_ret, "Z") ) {
438     // ZCLIP
439
440     if ( ZClipIsOn ) {
441       cout << "ZClipping OFF" << endl;
442       ZClipIsOn = 0;
443
444       aView->SetZClippingType(V3d_OFF);
445       aView->Redraw();
446     }
447     else {
448       cout << "ZClipping ON" << endl;
449       ZClipIsOn = 1;
450
451       aView->SetZClippingType(V3d_FRONT);
452       aView->Redraw();
453     }
454   }
455   else if ( !strcasecmp(buf_ret, ",") ) {
456     ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
457
458
459   }
460   else if ( !strcasecmp(buf_ret, ".") ) {
461     ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
462   }
463   // Number
464   else{
465     Standard_Integer Num = Draw::Atoi(buf_ret);
466     if(Num>=0 && Num<=7)
467       ViewerTest::StandardModeActivation(Num);
468   }
469 }
470
471 //==============================================================================
472 //function : VT_ProcessExpose
473 //purpose  : Redraw the View on an Expose Event
474 //==============================================================================
475 void VT_ProcessExpose()
476 {
477   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
478   if (!aView3d.IsNull())
479   {
480     aView3d->Redraw();
481   }
482 }
483
484 //==============================================================================
485 //function : VT_ProcessConfigure
486 //purpose  : Resize the View on an Configure Event
487 //==============================================================================
488 void VT_ProcessConfigure()
489 {
490   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
491   if (aView3d.IsNull())
492   {
493     return;
494   }
495
496   aView3d->MustBeResized();
497   aView3d->Update();
498   aView3d->Redraw();
499 }
500
501 //==============================================================================
502 //function : VT_ProcessButton1Press
503 //purpose  : Picking
504 //==============================================================================
505 Standard_Boolean VT_ProcessButton1Press(
506   Standard_Integer ,
507   const char**     argv,
508   Standard_Boolean pick,
509   Standard_Boolean shift)
510 {
511   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
512   if ( pick ) {
513     Standard_Real X, Y, Z;
514
515     ViewerTest::CurrentView()->Convert(X_Motion, Y_Motion, X, Y, Z);
516
517     Draw::Set(argv[1], X);
518     Draw::Set(argv[2], Y);
519     Draw::Set(argv[3], Z);}
520
521   if(shift)
522     EM->ShiftSelect();
523   else
524     EM->Select();
525
526   pick = 0;
527   return pick;
528 }
529
530 //==============================================================================
531 //function : VT_ProcessButton1Release
532 //purpose  : End selecting
533 //==============================================================================
534 void VT_ProcessButton1Release (Standard_Boolean theIsShift)
535 {
536   if (IsDragged)
537   {
538     IsDragged = Standard_False;
539     Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
540     if (theIsShift)
541     {
542       EM->ShiftSelect (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
543                        Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
544     }
545     else
546     {
547       EM->Select (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
548                   Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
549     }
550   }
551 }
552
553 //==============================================================================
554 //function : VT_ProcessButton3Press
555 //purpose  : Start Rotation
556 //==============================================================================
557 void VT_ProcessButton3Press()
558 {
559   Start_Rot = 1;
560   ViewerTest::CurrentView()->SetDegenerateModeOn();
561   ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
562 }
563
564 //==============================================================================
565 //function : VT_ProcessButton3Release
566 //purpose  : End rotation
567 //==============================================================================
568 void VT_ProcessButton3Release()
569 {
570   if (Start_Rot)
571   {
572     Start_Rot = 0;
573     if (!DegenerateMode) ViewerTest::CurrentView()->SetDegenerateModeOff();
574   }
575 }
576
577 //==============================================================================
578 //function : ProcessZClipMotion
579 //purpose  : Zoom
580 //==============================================================================
581
582 void ProcessZClipMotion()
583 {
584   Handle(V3d_View)  a3DView = ViewerTest::CurrentView();
585   if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
586     static Standard_Real CurZPos = 0.;
587
588     //Quantity_Length VDX, VDY;
589     //a3DView->Size(VDX,VDY);
590     //Standard_Real VDZ = a3DView->ZSize();
591     //printf("View size (%lf,%lf,%lf)\n", VDX, VDY, VDZ);
592
593     Quantity_Length dx = a3DView->Convert(X_Motion - X_ButtonPress);
594
595     // Front = Depth + width/2.
596     Standard_Real D = 0.5;
597     Standard_Real W = 0.1;
598
599     CurZPos += (dx);
600
601     D += CurZPos;
602
603     //printf("dx %lf Depth %lf Width %lf\n", dx, D, W);
604
605     a3DView->SetZClippingType(V3d_OFF);
606     a3DView->SetZClippingDepth(D);
607     a3DView->SetZClippingWidth(W);
608     a3DView->SetZClippingType(V3d_FRONT);
609
610     a3DView->Redraw();
611
612     X_ButtonPress = X_Motion;
613     Y_ButtonPress = Y_Motion;
614   }
615 }
616
617 //==============================================================================
618 //function : ProcessControlButton1Motion
619 //purpose  : Zoom
620 //==============================================================================
621
622 static void ProcessControlButton1Motion()
623 {
624   ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
625
626   X_ButtonPress = X_Motion;
627   Y_ButtonPress = Y_Motion;
628 }
629
630 //==============================================================================
631 //function : VT_ProcessControlButton2Motion
632 //purpose  : Panning
633 //==============================================================================
634 void VT_ProcessControlButton2Motion()
635 {
636   Quantity_Length dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
637   Quantity_Length dy = ViewerTest::CurrentView()->Convert(Y_Motion - Y_ButtonPress);
638
639   dy = -dy; // Xwindow Y axis is from top to Bottom
640
641   ViewerTest::CurrentView()->Panning( dx, dy );
642
643   X_ButtonPress = X_Motion;
644   Y_ButtonPress = Y_Motion;
645 }
646
647 //==============================================================================
648 //function : VT_ProcessControlButton3Motion
649 //purpose  : Rotation
650 //==============================================================================
651 void VT_ProcessControlButton3Motion()
652 {
653   if (Start_Rot)
654   {
655     ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
656   }
657 }
658
659 //==============================================================================
660 //function : VT_ProcessMotion
661 //purpose  :
662 //==============================================================================
663 void VT_ProcessMotion()
664 {
665   //pre-hilights detected objects at mouse position
666
667   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
668   EM->MoveTo(X_Motion, Y_Motion);
669 }
670
671
672 void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
673 {
674   Xpix = X_Motion;Ypix=Y_Motion;
675 }
676
677 //==============================================================================
678 //function : ViewProject: implements VAxo, VTop, VLeft, ...
679 //purpose  : Switches to an axonometric, top, left and other views
680 //==============================================================================
681
682 static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
683 {
684   if ( ViewerTest::CurrentView().IsNull() )
685   {
686     di<<"Call vinit before this command, please"<<"\n";
687     return 1;
688   }
689
690   ViewerTest::CurrentView()->SetProj(ori);
691   return 0;
692 }
693
694 //==============================================================================
695 //function : VAxo
696 //purpose  : Switch to an Axonometric view
697 //Draw arg : No args
698 //==============================================================================
699
700 static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
701 {
702   return ViewProject(di, V3d_XposYnegZpos);
703 }
704
705 //==============================================================================
706 //function : VTop
707 //purpose  : Switch to a Top View
708 //Draw arg : No args
709 //==============================================================================
710
711 static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
712 {
713   return ViewProject(di, V3d_Zpos);
714 }
715
716 //==============================================================================
717 //function : VBottom
718 //purpose  : Switch to a Bottom View
719 //Draw arg : No args
720 //==============================================================================
721
722 static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
723 {
724   return ViewProject(di, V3d_Zneg);
725 }
726
727 //==============================================================================
728 //function : VLeft
729 //purpose  : Switch to a Left View
730 //Draw arg : No args
731 //==============================================================================
732
733 static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
734 {
735   return ViewProject(di, V3d_Ypos);
736 }
737
738 //==============================================================================
739 //function : VRight
740 //purpose  : Switch to a Right View
741 //Draw arg : No args
742 //==============================================================================
743
744 static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
745 {
746   return ViewProject(di, V3d_Yneg);
747 }
748
749 //==============================================================================
750 //function : VFront
751 //purpose  : Switch to a Front View
752 //Draw arg : No args
753 //==============================================================================
754
755 static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
756 {
757   return ViewProject(di, V3d_Xpos);
758 }
759
760 //==============================================================================
761 //function : VBack
762 //purpose  : Switch to a Back View
763 //Draw arg : No args
764 //==============================================================================
765
766 static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
767 {
768   return ViewProject(di, V3d_Xneg);
769 }
770
771 //==============================================================================
772 //function : VHelp
773 //purpose  : Dsiplay help on viewer Keyboead and mouse commands
774 //Draw arg : No args
775 //==============================================================================
776
777 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
778 {
779
780   di << "Q : Quit the application" << "\n";
781
782   di << "========================="<<"\n";
783   di << "F : FitAll" << "\n";
784   di << "T : TopView" << "\n";
785   di << "B : BottomView" << "\n";
786   di << "R : RightView" << "\n";
787   di << "L : LeftView" << "\n";
788   di << "A : AxonometricView" << "\n";
789   di << "D : ResetView" << "\n";
790
791   di << "========================="<<"\n";
792   di << "S : Shading" << "\n";
793   di << "W : Wireframe" << "\n";
794   di << "H : HidelLineRemoval" << "\n";
795   di << "U : Unset display mode" << "\n";
796
797   di << "========================="<<"\n";
798   di << "Selection mode "<<"\n";
799   di << "0 : Shape" <<"\n";
800   di << "1 : Vertex" <<"\n";
801   di << "2 : Edge" <<"\n";
802   di << "3 : Wire" <<"\n";
803   di << "4 : Face" <<"\n";
804   di << "5 : Shell" <<"\n";
805   di << "6 : Solid" <<"\n";
806   di << "7 : Compound" <<"\n";
807
808   di << "========================="<<"\n";
809   di << "Z : Switch Z clipping On/Off" << "\n";
810   di << ", : Hilight next detected" << "\n";
811   di << ". : Hilight previous detected" << "\n";
812
813   return 0;
814 }
815
816 #ifdef WNT
817
818 static Standard_Boolean Ppick = 0;
819 static Standard_Integer Pargc = 0;
820 static const char**           Pargv = NULL;
821
822
823 static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
824                                           UINT Msg,
825                                           WPARAM wParam,
826                                           LPARAM lParam )
827 {
828   if ( !ViewerTest::CurrentView().IsNull() ) {
829
830     WPARAM fwKeys = wParam;
831
832     switch( Msg ) {
833
834     case WM_LBUTTONUP:
835       IsDragged = Standard_False;
836       if( !DragFirst )
837       {
838         HDC hdc = GetDC( hwnd );
839         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
840         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
841         SetROP2( hdc, R2_NOT );
842         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
843         ReleaseDC( hwnd, hdc );
844
845         const Handle(ViewerTest_EventManager) EM =
846           ViewerTest::CurrentEventManager();
847         if ( fwKeys & MK_SHIFT )
848           EM->ShiftSelect( min( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
849           max( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ));
850         else
851           EM->Select( min( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
852           max( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ));
853       }
854       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
855
856     case WM_LBUTTONDOWN:
857       if( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) )
858       {
859         IsDragged = Standard_True;
860         DragFirst = Standard_True;
861         X_ButtonPress = LOWORD(lParam);
862         Y_ButtonPress = HIWORD(lParam);
863       }
864       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
865
866       break;
867
868     case WM_MOUSEMOVE:
869       if( IsDragged )
870       {
871         HDC hdc = GetDC( hwnd );
872
873         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
874         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
875         SetROP2( hdc, R2_NOT );
876
877         if( !DragFirst )
878           Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
879
880         DragFirst = Standard_False;
881         X_Motion = LOWORD(lParam);
882         Y_Motion = HIWORD(lParam);
883
884         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
885
886         SelectObject( hdc, anObj );
887
888         ReleaseDC( hwnd, hdc );
889       }
890       else
891         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
892       break;
893
894     default:
895       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
896     }
897     return 0;
898   }
899   return ViewerWindowProc( hwnd, Msg, wParam, lParam );
900 }
901
902
903 static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
904                                        UINT Msg,
905                                        WPARAM wParam,
906                                        LPARAM lParam )
907 {
908   /*static Standard_Boolean Ppick = 0;
909   static Standard_Integer Pargc = 0;
910   static char**           Pargv = NULL;*/
911
912   static int Up = 1;
913
914   if ( !ViewerTest::CurrentView().IsNull() ) {
915     PAINTSTRUCT    ps;
916
917     switch( Msg ) {
918     case WM_CLOSE:
919       // do not destroy the window - just hide it!
920       VT_GetWindow()->Unmap();
921       return 0;
922     case WM_PAINT:
923       BeginPaint(hwnd, &ps);
924       EndPaint(hwnd, &ps);
925       VT_ProcessExpose();
926       break;
927
928     case WM_SIZE:
929       VT_ProcessConfigure();
930       break;
931
932     case WM_KEYDOWN:
933       if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
934       {
935         char c[2];
936         c[0] = (char) wParam;
937         c[1] = '\0';
938         VT_ProcessKeyPress (c);
939       }
940       break;
941
942     case WM_LBUTTONUP:
943     case WM_MBUTTONUP:
944     case WM_RBUTTONUP:
945       Up = 1;
946       VT_ProcessButton3Release();
947       break;
948
949     case WM_LBUTTONDOWN:
950     case WM_MBUTTONDOWN:
951     case WM_RBUTTONDOWN:
952       {
953         WPARAM fwKeys = wParam;
954
955         Up = 0;
956
957         X_ButtonPress = LOWORD(lParam);
958         Y_ButtonPress = HIWORD(lParam);
959
960         if (Msg == WM_LBUTTONDOWN)
961         {
962           if (fwKeys & MK_CONTROL)
963           {
964             Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
965           }
966           else
967           {
968             VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
969           }
970         }
971         else if (Msg == WM_RBUTTONDOWN)
972         {
973           // Start rotation
974           VT_ProcessButton3Press();
975         }
976       }
977       break;
978
979     case WM_MOUSEMOVE:
980       {
981         //cout << "\t WM_MOUSEMOVE" << endl;
982         WPARAM fwKeys = wParam;
983         X_Motion = LOWORD(lParam);
984         Y_Motion = HIWORD(lParam);
985
986         if ( Up &&
987           fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON ) ) {
988             Up = 0;
989             X_ButtonPress = LOWORD(lParam);
990             Y_ButtonPress = HIWORD(lParam);
991
992             if ( fwKeys & MK_RBUTTON ) {
993               // Start rotation
994               VT_ProcessButton3Press();
995             }
996           }
997
998           if ( fwKeys & MK_CONTROL ) {
999             if ( fwKeys & MK_LBUTTON ) {
1000               ProcessControlButton1Motion();
1001             }
1002             else if ( fwKeys & MK_MBUTTON ||
1003               ((fwKeys&MK_LBUTTON) &&
1004               (fwKeys&MK_RBUTTON) ) ){
1005                 VT_ProcessControlButton2Motion();
1006               }
1007             else if ( fwKeys & MK_RBUTTON ) {
1008               VT_ProcessControlButton3Motion();
1009             }
1010           }
1011 #ifdef BUG
1012           else if ( fwKeys & MK_SHIFT ) {
1013             if ( fwKeys & MK_MBUTTON ||
1014               ((fwKeys&MK_LBUTTON) &&
1015               (fwKeys&MK_RBUTTON) ) ) {
1016                 cout << "ProcessZClipMotion()" << endl;
1017                 ProcessZClipMotion();
1018               }
1019           }
1020 #endif
1021           else
1022             if ((fwKeys & MK_MBUTTON
1023             || ((fwKeys & MK_LBUTTON) && (fwKeys & MK_RBUTTON))))
1024             {
1025               ProcessZClipMotion();
1026             }
1027             else
1028             {
1029               VT_ProcessMotion();
1030             }
1031       }
1032       break;
1033
1034     default:
1035       return( DefWindowProc( hwnd, Msg, wParam, lParam ));
1036     }
1037     return 0L;
1038   }
1039
1040   return DefWindowProc( hwnd, Msg, wParam, lParam );
1041 }
1042
1043
1044
1045
1046 //==============================================================================
1047 //function : ViewerMainLoop
1048 //purpose  : Get a Event on the view and dispatch it
1049 //==============================================================================
1050
1051
1052 static int ViewerMainLoop(Standard_Integer argc, const char** argv)
1053 {
1054
1055   //cout << "No yet implemented on WNT" << endl;
1056   /*static Standard_Boolean Ppick = 0;
1057   static Standard_Integer Pargc = 0;
1058   static char**           Pargv = NULL;*/
1059
1060   //Ppick = (argc > 0)? -1 : 0;
1061   Ppick = (argc > 0)? 1 : 0;
1062   Pargc = argc;
1063   Pargv = argv;
1064
1065   if ( Ppick ) {
1066     MSG msg;
1067     msg.wParam = 1;
1068
1069     cout << "Start picking" << endl;
1070
1071     //while ( Ppick == -1 ) {
1072     while ( Ppick == 1 ) {
1073       // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
1074       if (GetMessage(&msg, NULL, 0, 0) ) {
1075         TranslateMessage(&msg);
1076         DispatchMessage(&msg);
1077       }
1078     }
1079
1080     cout << "Picking done" << endl;
1081   }
1082
1083   return Ppick;
1084 }
1085
1086 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
1087
1088 int min( int a, int b )
1089 {
1090   if( a<b )
1091     return a;
1092   else
1093     return b;
1094 }
1095
1096 int max( int a, int b )
1097 {
1098   if( a>b )
1099     return a;
1100   else
1101     return b;
1102 }
1103
1104 int ViewerMainLoop(Standard_Integer argc, const char** argv)
1105
1106 { Standard_Boolean pick = argc > 0;
1107
1108 // X11 Event loop
1109
1110 static XEvent report;
1111
1112 XNextEvent( display, &report );
1113 //    cout << "rep type = " << report.type << endl;
1114 //    cout << "rep button = " << report.xbutton.button << endl;
1115
1116 switch ( report.type ) {
1117       case Expose:
1118         {
1119           VT_ProcessExpose();
1120         }
1121         break;
1122       case ConfigureNotify:
1123         {
1124           VT_ProcessConfigure();
1125         }
1126         break;
1127       case KeyPress:
1128         {
1129
1130           KeySym ks_ret ;
1131           char buf_ret[11] ;
1132           int ret_len ;
1133           XComposeStatus status_in_out;
1134
1135           ret_len = XLookupString( ( XKeyEvent *)&report ,
1136             (char *) buf_ret , 10 ,
1137             &ks_ret , &status_in_out ) ;
1138
1139
1140           buf_ret[ret_len] = '\0' ;
1141
1142           if (ret_len)
1143           {
1144             VT_ProcessKeyPress (buf_ret);
1145           }
1146         }
1147         break;
1148       case ButtonPress:
1149         //  cout << "ButtonPress" << endl;
1150         {
1151           X_ButtonPress = report.xbutton.x;
1152           Y_ButtonPress = report.xbutton.y;
1153
1154           if (report.xbutton.button == Button1)
1155           {
1156             if (report.xbutton.state & ControlMask)
1157             {
1158               pick = VT_ProcessButton1Press (argc, argv, pick, (report.xbutton.state & ShiftMask));
1159             }
1160             else
1161             {
1162               IsDragged = Standard_True;
1163               DragFirst = Standard_True;
1164             }
1165           }
1166           else if (report.xbutton.button == Button3)
1167           {
1168             // Start rotation
1169             VT_ProcessButton3Press();
1170           }
1171         }
1172         break;
1173       case ButtonRelease:
1174         {
1175           //    cout<<"relachement du bouton "<<(report.xbutton.button==3 ? "3": "on s'en fout") <<endl;
1176           //    cout << IsDragged << endl;
1177           //    cout << DragFirst << endl;
1178
1179           if( IsDragged )
1180           {
1181             if( !DragFirst )
1182             {
1183               Aspect_Handle aWindow = VT_GetWindow()->XWindow();
1184               GC gc = XCreateGC( display, aWindow, 0, 0 );
1185               //  XSetFunction( display, gc, GXinvert );
1186               XDrawRectangle( display, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
1187             }
1188
1189             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1190             if( aContext.IsNull() )
1191             {
1192               cout << "The context is null. Please use vinit before createmesh" << endl;
1193               return 0;
1194             }
1195
1196             Standard_Boolean ShiftPressed = ( report.xbutton.state & ShiftMask );
1197             if( report.xbutton.button==1 )
1198               if( DragFirst )
1199                 if( ShiftPressed )
1200                 {
1201                   aContext->ShiftSelect();
1202                   //                   cout << "shift select" << endl;
1203                 }
1204                 else
1205                 {
1206                   aContext->Select();
1207                   //                   cout << "select" << endl;
1208                 }
1209               else
1210                 if( ShiftPressed )
1211                 {
1212                   aContext->ShiftSelect( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
1213                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
1214                     ViewerTest::CurrentView());
1215                   //                   cout << "shift select" << endl;
1216                 }
1217                 else
1218                 {
1219                   aContext->Select( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
1220                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
1221                     ViewerTest::CurrentView() );
1222                   //                   cout << "select" << endl;
1223                 }
1224             else
1225               VT_ProcessButton3Release();
1226
1227             IsDragged = Standard_False;
1228           }
1229           else
1230             VT_ProcessButton3Release();
1231         }
1232         break;
1233       case MotionNotify:
1234         {
1235           if( IsDragged )
1236           {
1237             Aspect_Handle aWindow = VT_GetWindow()->XWindow();
1238             GC gc = XCreateGC( display, aWindow, 0, 0 );
1239             XSetFunction( display, gc, GXinvert );
1240
1241             if( !DragFirst )
1242               XDrawRectangle( display, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
1243
1244             X_Motion = report.xmotion.x;
1245             Y_Motion = report.xmotion.y;
1246             DragFirst = Standard_False;
1247
1248             XDrawRectangle( display, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
1249           }
1250           else
1251           {
1252             X_Motion = report.xmotion.x;
1253             Y_Motion = report.xmotion.y;
1254
1255             // remove all the ButtonMotionMask
1256             while( XCheckMaskEvent( display, ButtonMotionMask, &report) ) ;
1257
1258             if ( ZClipIsOn && report.xmotion.state & ShiftMask ) {
1259               if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
1260
1261                 Quantity_Length VDX, VDY;
1262
1263                 ViewerTest::CurrentView()->Size(VDX,VDY);
1264                 Standard_Real VDZ =0 ;
1265                 VDZ = ViewerTest::CurrentView()->ZSize();
1266
1267                 //          printf("%lf,%lf,%lf\n", VDX, VDY, VDZ);
1268                 printf("%f,%f,%f\n", VDX, VDY, VDZ);
1269
1270                 Quantity_Length dx = 0 ;
1271                 dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
1272
1273                 cout << dx << endl;
1274
1275                 dx = dx / VDX * VDZ;
1276
1277                 cout << dx << endl;
1278
1279                 // Front = Depth + width/2.
1280                 //ViewerTest::CurrentView()->SetZClippingDepth(dx);
1281                 //ViewerTest::CurrentView()->SetZClippingWidth(0.);
1282
1283                 ViewerTest::CurrentView()->Redraw();
1284               }
1285             }
1286
1287             if ( report.xmotion.state & ControlMask ) {
1288               if ( report.xmotion.state & Button1Mask ) {
1289                 ProcessControlButton1Motion();
1290               }
1291               else if ( report.xmotion.state & Button2Mask ) {
1292                 VT_ProcessControlButton2Motion();
1293               }
1294               else if ( report.xmotion.state & Button3Mask ) {
1295                 VT_ProcessControlButton3Motion();
1296               }
1297             }
1298             else
1299             {
1300               VT_ProcessMotion();
1301             }
1302           }
1303         }
1304         break;
1305 }
1306
1307
1308 return pick;
1309 }
1310
1311 //==============================================================================
1312 //function : VProcessEvents
1313 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
1314 //       event in the Viewer window
1315 //==============================================================================
1316
1317 static void VProcessEvents(ClientData,int)
1318 {
1319   //cout << "VProcessEvents" << endl;
1320
1321   // test for X Event
1322   while (XPending(display)) {
1323     ViewerMainLoop( 0, NULL);
1324   }
1325 }
1326 #endif
1327
1328 //==============================================================================
1329 //function : OSWindowSetup
1330 //purpose  : Setup for the X11 window to be able to cath the event
1331 //==============================================================================
1332
1333
1334 static void OSWindowSetup()
1335 {
1336 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1337   // X11
1338
1339   Window  window   = VT_GetWindow()->XWindow();
1340
1341   display = GetGraphicDriver()->GetDisplayConnection()->GetDisplay();
1342   //  display = (Display *)GetG3dDevice()->XDisplay();
1343
1344   XSynchronize(display, 1);
1345
1346   VT_GetWindow()->Map();
1347
1348   // X11 : For keyboard on SUN
1349   XWMHints wmhints;
1350   wmhints.flags = InputHint;
1351   wmhints.input = 1;
1352
1353   XSetWMHints( display, window, &wmhints);
1354
1355   XSelectInput( display, window,  ExposureMask | KeyPressMask |
1356     ButtonPressMask | ButtonReleaseMask |
1357     StructureNotifyMask |
1358     PointerMotionMask |
1359     Button1MotionMask | Button2MotionMask |
1360     Button3MotionMask
1361     );
1362
1363   XSynchronize(display, 0);
1364
1365 #else
1366   // WNT
1367 #endif
1368
1369 }
1370
1371
1372 //==============================================================================
1373 //function : VFit
1374
1375 //purpose  : Fitall, no DRAW arguments
1376 //Draw arg : No args
1377 //==============================================================================
1378
1379 static int VFit(Draw_Interpretor& , Standard_Integer , const char** )
1380 {
1381   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1382   Handle(NIS_View) V = Handle(NIS_View)::DownCast(aView);
1383   if (V.IsNull() == Standard_False) {
1384     V->FitAll3d();
1385   } else if (aView.IsNull() == Standard_False) {
1386     aView->FitAll();
1387   }
1388   return 0;
1389 }
1390
1391 //==============================================================================
1392 //function : VZFit
1393 //purpose  : ZFitall, no DRAW arguments
1394 //Draw arg : No args
1395 //==============================================================================
1396
1397 static int VZFit(Draw_Interpretor& , Standard_Integer , const char** )
1398 {
1399   Handle(V3d_View) V = ViewerTest::CurrentView();
1400   if ( !V.IsNull() ) V->ZFitAll(); return 0; }
1401
1402
1403 static int VRepaint(Draw_Interpretor& , Standard_Integer , const char** )
1404 {
1405   Handle(V3d_View) V = ViewerTest::CurrentView();
1406   if ( !V.IsNull() ) V->Redraw(); return 0;
1407 }
1408
1409
1410 //==============================================================================
1411 //function : VClear
1412 //purpose  : Remove all the object from the viewer
1413 //Draw arg : No args
1414 //==============================================================================
1415
1416 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
1417 {
1418   Handle(V3d_View) V = ViewerTest::CurrentView();
1419   if(!V.IsNull())
1420     ViewerTest::Clear();
1421   return 0;
1422 }
1423
1424 //==============================================================================
1425 //function : VPick
1426 //purpose  :
1427 //==============================================================================
1428
1429 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1430 { if (ViewerTest::CurrentView().IsNull() ) return 1;
1431
1432 if ( argc < 4 ) {
1433   di << argv[0] << "Invalid number of arguments" << "\n";
1434   return 1;
1435 }
1436
1437 while (ViewerMainLoop( argc, argv)) {
1438 }
1439
1440 return 0;
1441 }
1442
1443 //==============================================================================
1444 //function : InitViewerTest
1445 //purpose  : initialisation de toutes les variables static de  ViewerTest (dp)
1446 //==============================================================================
1447
1448 void ViewerTest_InitViewerTest (const Handle(AIS_InteractiveContext)& context)
1449 {
1450   Handle(V3d_Viewer) viewer = context->CurrentViewer();
1451   ViewerTest::SetAISContext(context);
1452   viewer->InitActiveViews();
1453   Handle(V3d_View) view = viewer->ActiveView();
1454   if (viewer->MoreActiveViews()) ViewerTest::CurrentView(view);
1455   ViewerTest::ResetEventManager();
1456   Handle(Aspect_Window) window = view->Window();
1457 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1458   // X11
1459   VT_GetWindow() = Handle(Xw_Window)::DownCast(window);
1460   GetGraphicDriver() = viewer->Driver();
1461   OSWindowSetup();
1462   static int first = 1;
1463   if ( first ) {
1464 #if TCL_MAJOR_VERSION  < 8
1465     Tk_CreateFileHandler((void*)ConnectionNumber(display),
1466       TK_READABLE, VProcessEvents, (ClientData) 0);
1467 #else
1468     Tk_CreateFileHandler(ConnectionNumber(display),
1469       TK_READABLE, VProcessEvents, (ClientData) 0);
1470 #endif
1471     first = 0;
1472   }
1473 #endif
1474 }
1475
1476 //==============================================================================
1477 //function : VSetBg
1478 //purpose  : Load image as background
1479 //==============================================================================
1480
1481 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1482 {
1483   if (argc < 2 || argc > 3)
1484   {
1485     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background" << "\n";
1486     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1487     return 1;
1488   }
1489
1490   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1491   if(AISContext.IsNull())
1492   {
1493     di << "use 'vinit' command before " << argv[0] << "\n";
1494     return 1;
1495   }
1496
1497   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
1498   if (argc == 3)
1499   {
1500     const char* szType = argv[2];
1501     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
1502     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
1503     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
1504     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
1505     else
1506     {
1507       di << "Wrong fill type : " << szType << "\n";
1508       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1509       return 1;
1510     }
1511   }
1512
1513   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1514   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
1515
1516   return 0;
1517 }
1518
1519 //==============================================================================
1520 //function : VSetBgMode
1521 //purpose  : Change background image fill type
1522 //==============================================================================
1523
1524 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1525 {
1526   if (argc != 2)
1527   {
1528     di << "Usage : " << argv[0] << " filltype : Change background image mode" << "\n";
1529     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1530     return 1;
1531   }
1532
1533   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1534   if(AISContext.IsNull())
1535   {
1536     di << "use 'vinit' command before " << argv[0] << "\n";
1537     return 1;
1538   }
1539
1540   Aspect_FillMethod aFillType;
1541   if (argc == 2)
1542   {
1543     const char* szType = argv[1];
1544     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
1545     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
1546     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
1547     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
1548     else
1549     {
1550       di << "Wrong fill type : " << szType << "\n";
1551       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1552       return 1;
1553     }
1554   }
1555
1556   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1557   V3dView->SetBgImageStyle(aFillType, Standard_True);
1558
1559   return 0;
1560 }
1561
1562 //==============================================================================
1563 //function : VSetGradientBg
1564 //purpose  : Mount gradient background
1565 //==============================================================================
1566 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1567 {
1568   if (argc != 8 )
1569   {
1570     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background" << "\n";
1571     di << "R1,G1,B1,R2,G2,B2 = [0..255]" << "\n";
1572     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1573     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1574     return 1;
1575   }
1576
1577   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1578   if(AISContext.IsNull())
1579   {
1580     di << "use 'vinit' command before " << argv[0] << "\n";
1581     return 1;
1582   }
1583   if (argc == 8)
1584   {
1585
1586     Standard_Real R1 = Draw::Atof(argv[1])/255.;
1587     Standard_Real G1 = Draw::Atof(argv[2])/255.;
1588     Standard_Real B1 = Draw::Atof(argv[3])/255.;
1589     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
1590
1591     Standard_Real R2 = Draw::Atof(argv[4])/255.;
1592     Standard_Real G2 = Draw::Atof(argv[5])/255.;
1593     Standard_Real B2 = Draw::Atof(argv[6])/255.;
1594
1595     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
1596     int aType = Draw::Atoi(argv[7]);
1597     if( aType < 0 || aType > 8 )
1598     {
1599       di << "Wrong fill type " << "\n";
1600       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1601       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1602       return 1;
1603     }
1604
1605     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
1606
1607     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1608     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
1609   }
1610
1611   return 0;
1612 }
1613
1614 //==============================================================================
1615 //function : VSetGradientBgMode
1616 //purpose  : Change gradient background fill style
1617 //==============================================================================
1618 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1619 {
1620   if (argc != 2 )
1621   {
1622     di << "Usage : " << argv[0] << " Type : Change gradient background fill type" << "\n";
1623     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1624     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1625     return 1;
1626   }
1627
1628   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1629   if(AISContext.IsNull())
1630   {
1631     di << "use 'vinit' command before " << argv[0] << "\n";
1632     return 1;
1633   }
1634   if (argc == 2)
1635   {
1636     int aType = Draw::Atoi(argv[1]);
1637     if( aType < 0 || aType > 8 )
1638     {
1639       di << "Wrong fill type " << "\n";
1640       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1641       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1642       return 1;
1643     }
1644
1645     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
1646
1647     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1648     V3dView->SetBgGradientStyle( aMethod, 1 );
1649   }
1650
1651   return 0;
1652 }
1653
1654 //==============================================================================
1655 //function : VSetColorBg
1656 //purpose  : Set color background
1657 //==============================================================================
1658 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1659 {
1660   if (argc != 4 )
1661   {
1662     di << "Usage : " << argv[0] << " R G B : Set color background" << "\n";
1663     di << "R,G,B = [0..255]" << "\n";
1664     return 1;
1665   }
1666
1667   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1668   if(AISContext.IsNull())
1669   {
1670     di << "use 'vinit' command before " << argv[0] << "\n";
1671     return 1;
1672   }
1673   if (argc == 4)
1674   {
1675
1676     Standard_Real R = Draw::Atof(argv[1])/255.;
1677     Standard_Real G = Draw::Atof(argv[2])/255.;
1678     Standard_Real B = Draw::Atof(argv[3])/255.;
1679     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
1680
1681     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1682     V3dView->SetBackgroundColor( aColor );
1683     V3dView->Update();
1684   }
1685
1686   return 0;
1687 }
1688
1689 //==============================================================================
1690 //function : VScale
1691 //purpose  : View Scaling
1692 //==============================================================================
1693
1694 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1695 {
1696   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1697   if ( V3dView.IsNull() ) return 1;
1698
1699   if ( argc != 4 ) {
1700     di << argv[0] << "Invalid number of arguments" << "\n";
1701     return 1;
1702   }
1703   V3dView->SetAxialScale( Draw::Atof(argv[1]),  Draw::Atof(argv[2]),  Draw::Atof(argv[3]) );
1704   return 0;
1705 }
1706 //==============================================================================
1707 //function : VTestZBuffTrihedron
1708 //purpose  : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron
1709 //==============================================================================
1710
1711 static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1712 {
1713   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1714   if ( V3dView.IsNull() ) return 1;
1715
1716   V3dView->ZBufferTriedronSetup();
1717
1718   if ( argc == 1 ) {
1719     // Set up default trihedron parameters
1720     V3dView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.1, V3d_ZBUFFER );
1721   } else
1722   if ( argc == 7 )
1723   {
1724     Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
1725     const char* aPosType = argv[1];
1726
1727     if ( strcmp(aPosType, "center") == 0 )
1728     {
1729       aPosition = Aspect_TOTP_CENTER;
1730     } else
1731     if (strcmp(aPosType, "left_lower") == 0)
1732     {
1733       aPosition = Aspect_TOTP_LEFT_LOWER;
1734     } else
1735     if (strcmp(aPosType, "left_upper") == 0)
1736     {
1737       aPosition = Aspect_TOTP_LEFT_UPPER;
1738     } else
1739     if (strcmp(aPosType, "right_lower") == 0)
1740     {
1741       aPosition = Aspect_TOTP_RIGHT_LOWER;
1742     } else
1743     if (strcmp(aPosType, "right_upper") == 0)
1744     {
1745       aPosition = Aspect_TOTP_RIGHT_UPPER;
1746     } else
1747     {
1748       di << argv[1] << " Invalid type of alignment"  << "\n";
1749       di << "Must be one of [ center, left_lower,"   << "\n";
1750       di << "left_upper, right_lower, right_upper ]" << "\n";
1751       return 1;
1752     }
1753
1754     Standard_Real R = Draw::Atof(argv[2])/255.;
1755     Standard_Real G = Draw::Atof(argv[3])/255.;
1756     Standard_Real B = Draw::Atof(argv[4])/255.;
1757     Quantity_Color aColor(R, G, B, Quantity_TOC_RGB);
1758
1759     Standard_Real aScale = Draw::Atof(argv[5]);
1760
1761     if( aScale <= 0.0 )
1762     {
1763       di << argv[5] << " Invalid value. Must be > 0" << "\n";
1764       return 1;
1765     }
1766
1767     V3d_TypeOfVisualization aPresentation = V3d_ZBUFFER;
1768     const char* aPresType = argv[6];
1769
1770     if ( strcmp(aPresType, "wireframe") == 0 )
1771     {
1772       aPresentation = V3d_WIREFRAME;
1773     } else
1774     if (strcmp(aPresType, "zbuffer") == 0)
1775     {
1776       aPresentation = V3d_ZBUFFER;
1777     } else
1778     {
1779       di << argv[6] << " Invalid type of visualization" << "\n";
1780       di << "Must be one of [ wireframe, zbuffer ]"     << "\n";
1781       return 1;
1782     }
1783
1784     V3dView->TriedronDisplay( aPosition, aColor.Name(), aScale, aPresentation );
1785
1786   } else
1787   {
1788     di << argv[0] << " Invalid number of arguments" << "\n";
1789     return 1;
1790   }
1791
1792   V3dView->ZFitAll();
1793
1794   return 0;
1795 }
1796
1797 //==============================================================================
1798 //function : VRotate
1799 //purpose  : Camera Rotating
1800 //==============================================================================
1801
1802 static int VRotate( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1803   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1804   if ( V3dView.IsNull() ) {
1805     return 1;
1806   }
1807
1808   if ( argc == 4 ) {
1809     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
1810     return 0;
1811   } else if ( argc == 7 ) {
1812     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]), Draw::Atof(argv[4]), Draw::Atof(argv[5]), Draw::Atof(argv[6]) );
1813     return 0;
1814   } else {
1815     di << argv[0] << " Invalid number of arguments" << "\n";
1816     return 1;
1817   }
1818 }
1819
1820 //==============================================================================
1821 //function : VZoom
1822 //purpose  : View zoom in / out (relative to current zoom)
1823 //==============================================================================
1824
1825 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1826   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1827   if ( V3dView.IsNull() ) {
1828     return 1;
1829   }
1830
1831   if ( argc == 2 ) {
1832     Standard_Real coef = Draw::Atof(argv[1]);
1833     if ( coef <= 0.0 ) {
1834       di << argv[1] << "Invalid value" << "\n";
1835       return 1;
1836     }
1837     V3dView->SetZoom( Draw::Atof(argv[1]) );
1838     return 0;
1839   } else {
1840     di << argv[0] << " Invalid number of arguments" << "\n";
1841     return 1;
1842   }
1843 }
1844
1845 //==============================================================================
1846 //function : VPan
1847 //purpose  : View panning (in pixels)
1848 //==============================================================================
1849
1850 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1851   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1852   if ( V3dView.IsNull() ) return 1;
1853
1854   if ( argc == 3 ) {
1855     V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
1856     return 0;
1857   } else {
1858     di << argv[0] << " Invalid number of arguments" << "\n";
1859     return 1;
1860   }
1861 }
1862
1863
1864 //==============================================================================
1865 //function : VExport
1866 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
1867 //==============================================================================
1868
1869 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1870 {
1871   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1872   if (V3dView.IsNull())
1873     return 1;
1874
1875   if (argc == 1)
1876   {
1877     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
1878     return 1;
1879   }
1880
1881   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
1882   TCollection_AsciiString aFormatStr;
1883
1884   TCollection_AsciiString aFileName (argv[1]);
1885   Standard_Integer aLen = aFileName.Length();
1886
1887   if (argc > 2)
1888   {
1889     aFormatStr = TCollection_AsciiString (argv[2]);
1890   }
1891   else if (aLen >= 4)
1892   {
1893     if (aFileName.Value (aLen - 2) == '.')
1894     {
1895       aFormatStr = aFileName.SubString (aLen - 1, aLen);
1896     }
1897     else if (aFileName.Value (aLen - 3) == '.')
1898     {
1899       aFormatStr = aFileName.SubString (aLen - 2, aLen);
1900     }
1901     else
1902     {
1903       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
1904       return 1;
1905     }
1906   }
1907   else
1908   {
1909     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
1910     return 1;
1911   }
1912
1913   aFormatStr.UpperCase();
1914   if (aFormatStr == "PS")
1915     anExpFormat = Graphic3d_EF_PostScript;
1916   else if (aFormatStr == "EPS")
1917     anExpFormat = Graphic3d_EF_EnhPostScript;
1918   else if (aFormatStr == "TEX")
1919     anExpFormat = Graphic3d_EF_TEX;
1920   else if (aFormatStr == "PDF")
1921     anExpFormat = Graphic3d_EF_PDF;
1922   else if (aFormatStr == "SVG")
1923     anExpFormat = Graphic3d_EF_SVG;
1924   else if (aFormatStr == "PGF")
1925     anExpFormat = Graphic3d_EF_PGF;
1926   else if (aFormatStr == "EMF")
1927     anExpFormat = Graphic3d_EF_EMF;
1928   else
1929   {
1930     std::cout << "Invalid export format '" << aFormatStr << "'\n";
1931     return 1;
1932   }
1933
1934   if (!V3dView->View()->Export (argv[1], anExpFormat))
1935   {
1936     std::cout << "Export failed!\n";
1937     return 1;
1938   }
1939   return 0;
1940 }
1941
1942 //==============================================================================
1943 //function : VColorScale
1944 //purpose  : representation color scale
1945 //==============================================================================
1946 #include <V3d_ColorScale.hxx>
1947
1948 static int VColorScale (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
1949 {
1950   if ( argc != 1 && argc != 4 && argc != 5 && argc != 6 && argc != 8 )
1951   {
1952     di << "Usage : " << argv[0] << " [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = Right X = 0 Y = 0]  " << "\n";
1953     return 1;
1954   }
1955
1956   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1957   if(aContext.IsNull()) {
1958     di << argv[0] << " ERROR : use 'vinit' command before " << "\n";
1959     return -1;
1960   }
1961
1962   Standard_Real minRange = 0. , maxRange = 100. ;
1963
1964   Standard_Integer numIntervals = 10 ;
1965   Standard_Integer textHeight = 16;
1966   Aspect_TypeOfColorScalePosition position = Aspect_TOCSP_RIGHT;
1967   Standard_Real X = 0., Y = 0. ;
1968
1969   if ( argc < 9 )
1970   {
1971      if( argc > 3 )
1972      {
1973        minRange = Draw::Atof( argv[1] );
1974        maxRange = Draw::Atof( argv[2] );
1975        numIntervals = Draw::Atoi( argv[3] );
1976      }
1977      if ( argc > 4 )
1978        textHeight = Draw::Atoi( argv[4] );
1979      if ( argc > 5 )
1980        position = (Aspect_TypeOfColorScalePosition)Draw::Atoi( argv[5] );
1981      if ( argc > 7 )
1982      {
1983        X = Draw::Atof( argv[6] );
1984        Y = Draw::Atof( argv[7] );
1985      }
1986   }
1987   Handle(V3d_View) curView = ViewerTest::CurrentView( );
1988   if ( curView.IsNull( ) )
1989     return 1;
1990   Handle(Aspect_ColorScale) aCSV = curView->ColorScale( );
1991   Handle(V3d_ColorScale) aCS = ( Handle( V3d_ColorScale )::DownCast( aCSV ) );
1992   if( ! aCS.IsNull( ) )
1993   {
1994     aCS->SetPosition( X , Y );
1995     aCS->SetHeight( 0.95) ;
1996     aCS->SetTextHeight( textHeight );
1997     aCS->SetRange( minRange , maxRange );
1998     aCS->SetNumberOfIntervals( numIntervals );
1999     aCS->SetLabelPosition( position );
2000     if( !curView->ColorScaleIsDisplayed() )
2001       curView->ColorScaleDisplay( );
2002   }
2003   return 0;
2004 }
2005
2006 //==============================================================================
2007 //function : VGraduatedTrihedron
2008 //purpose  : Displays a graduated trihedron
2009 //==============================================================================
2010
2011 static void AddMultibyteString (TCollection_ExtendedString &name, const char *arg)
2012 {
2013   const char *str = arg;
2014   while (*str)
2015   {
2016     unsigned short c1 = *str++;
2017     unsigned short c2 = *str++;
2018     if (!c1 || !c2) break;
2019     name += (Standard_ExtCharacter)((c1 << 8) | c2);
2020   }
2021 }
2022
2023 static int VGraduatedTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2024 {
2025   // Check arguments
2026   if (argc != 2 && argc < 5)
2027   {
2028     di<<"Error: "<<argv[0]<<" - invalid number of arguments\n";
2029     di<<"Usage: type help "<<argv[0]<<"\n";
2030     return 1; //TCL_ERROR
2031   }
2032
2033   Handle(V3d_View) aV3dView = ViewerTest::CurrentView();
2034
2035   // Create 3D view if it doesn't exist
2036   if ( aV3dView.IsNull() )
2037   {
2038     ViewerTest::ViewerInit();
2039     aV3dView = ViewerTest::CurrentView();
2040     if( aV3dView.IsNull() )
2041     {
2042       di << "Error: Cannot create a 3D view\n";
2043       return 1; //TCL_ERROR
2044     }
2045   }
2046
2047   // Erase (==0) or display (!=0)
2048   const int display = Draw::Atoi(argv[1]);
2049
2050   if (display)
2051   {
2052     // Text font
2053     TCollection_AsciiString font;
2054     if (argc < 6)
2055       font.AssignCat("Courier");
2056     else
2057       font.AssignCat(argv[5]);
2058
2059     // Text is multibyte
2060     const Standard_Boolean isMultibyte = (argc < 7)? Standard_False : (Draw::Atoi(argv[6]) != 0);
2061
2062     // Set axis names
2063     TCollection_ExtendedString xname, yname, zname;
2064     if (argc >= 5)
2065     {
2066       if (isMultibyte)
2067       {
2068         AddMultibyteString(xname, argv[2]);
2069         AddMultibyteString(yname, argv[3]);
2070         AddMultibyteString(zname, argv[4]);
2071       }
2072       else
2073       {
2074         xname += argv[2];
2075         yname += argv[3];
2076         zname += argv[4];
2077       }
2078     }
2079     else
2080     {
2081       xname += "X (mm)";
2082       yname += "Y (mm)";
2083       zname += "Z (mm)";
2084     }
2085
2086     aV3dView->GraduatedTrihedronDisplay(xname, yname, zname,
2087                                         Standard_True/*xdrawname*/, Standard_True/*ydrawname*/, Standard_True/*zdrawname*/,
2088                                         Standard_True/*xdrawvalues*/, Standard_True/*ydrawvalues*/, Standard_True/*zdrawvalues*/,
2089                                         Standard_True/*drawgrid*/,
2090                                         Standard_True/*drawaxes*/,
2091                                         5/*nbx*/, 5/*nby*/, 5/*nbz*/,
2092                                         10/*xoffset*/, 10/*yoffset*/, 10/*zoffset*/,
2093                                         30/*xaxisoffset*/, 30/*yaxisoffset*/, 30/*zaxisoffset*/,
2094                                         Standard_True/*xdrawtickmarks*/, Standard_True/*ydrawtickmarks*/, Standard_True/*zdrawtickmarks*/,
2095                                         10/*xtickmarklength*/, 10/*ytickmarklength*/, 10/*ztickmarklength*/,
2096                                         Quantity_NOC_WHITE/*gridcolor*/,
2097                                         Quantity_NOC_RED/*xnamecolor*/,Quantity_NOC_GREEN/*ynamecolor*/,Quantity_NOC_BLUE1/*znamecolor*/,
2098                                         Quantity_NOC_RED/*xcolor*/,Quantity_NOC_GREEN/*ycolor*/,Quantity_NOC_BLUE1/*zcolor*/,font);
2099   }
2100   else
2101     aV3dView->GraduatedTrihedronErase();
2102
2103   ViewerTest::GetAISContext()->UpdateCurrentViewer();
2104   aV3dView->Redraw();
2105
2106   return 0;
2107 }
2108
2109 //==============================================================================
2110 //function : VPrintView
2111 //purpose  : Test printing algorithm, print the view to image file with given
2112 //           width and height. Printing implemented only for WNT.
2113 //==============================================================================
2114 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
2115                        const char** argv)
2116 {
2117 #ifndef WNT
2118   di << "Printing implemented only for wnt!\n";
2119   return 1;
2120 #else
2121
2122   Handle(AIS_InteractiveContext) aContextAIS = NULL;
2123   Handle(V3d_View) aView = NULL;
2124   aContextAIS = ViewerTest::GetAISContext();
2125   if (!aContextAIS.IsNull())
2126   {
2127     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
2128     Vwr->InitActiveViews();
2129     if(Vwr->MoreActiveViews())
2130       aView = Vwr->ActiveView();
2131   }
2132
2133   // check for errors
2134   if (aView.IsNull())
2135   {
2136     di << "Call vinit before!\n";
2137     return 1;
2138   }
2139   else if (argc < 4)
2140   {
2141     di << "Use: " << argv[0];
2142     di << " width height filename [print algo=0]\n";
2143     di << "width, height of the intermediate buffer for operation\n";
2144     di << "algo : {0|1}\n";
2145     di << "        0 - stretch algorithm\n";
2146     di << "        1 - tile algorithm\n";
2147     di << "test printing algorithms into an intermediate buffer\n";
2148     di << "with saving output to an image file\n";
2149     return 1;
2150   }
2151
2152   // get the input params
2153   Standard_Integer aWidth  = Draw::Atoi (argv[1]);
2154   Standard_Integer aHeight = Draw::Atoi (argv[2]);
2155   Standard_Integer aMode   = 0;
2156   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
2157   if (argc==5)
2158     aMode = Draw::Atoi (argv[4]);
2159
2160   // check the input parameters
2161   if (aWidth <= 0 || aHeight <= 0)
2162   {
2163     di << "Width and height must be positive values!\n";
2164     return 1;
2165   }
2166   if (aMode != 0 && aMode != 1)
2167     aMode = 0;
2168
2169   // define compatible bitmap
2170   HDC anDC = CreateCompatibleDC(0);
2171   BITMAPINFO aBitmapData;
2172   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
2173   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
2174   aBitmapData.bmiHeader.biWidth         = aWidth ;
2175   aBitmapData.bmiHeader.biHeight        = aHeight;
2176   aBitmapData.bmiHeader.biPlanes        = 1;
2177   aBitmapData.bmiHeader.biBitCount      = 24;
2178   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
2179   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
2180   aBitmapData.bmiHeader.biClrUsed       = 0;
2181   aBitmapData.bmiHeader.biClrImportant  = 0;
2182   aBitmapData.bmiHeader.biCompression   = BI_RGB;
2183   aBitmapData.bmiHeader.biSizeImage     = 0;
2184
2185   // Create Device Independent Bitmap
2186   void* aBitsOut = NULL;
2187   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
2188                                             &aBitsOut, NULL, 0);
2189   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
2190
2191   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
2192   if (aBitsOut != NULL)
2193   {
2194     if (aMode == 0)
2195       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
2196     else
2197       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_TILE);
2198
2199     // succesfully printed into an intermediate buffer
2200     if (isPrinted)
2201     {
2202       Image_PixMap aWrapper;
2203       aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
2204       aWrapper.SetTopDown (false);
2205
2206       Image_AlienPixMap anImageBitmap;
2207       anImageBitmap.InitCopy (aWrapper);
2208       isSaved = anImageBitmap.Save (aFileName);
2209     }
2210     else
2211     {
2212       di << "Print operation failed due to printing errors or\n";
2213       di << "insufficient memory available\n";
2214       di << "Please, try to use smaller dimensions for this test\n";
2215       di << "command, as it allocates intermediate buffer for storing\n";
2216       di << "the result\n";
2217     }
2218   }
2219   else
2220   {
2221     di << "Can't allocate memory for intermediate buffer\n";
2222     di << "Please use smaller dimensions\n";
2223   }
2224
2225   if (aMemoryBitmap)
2226   {
2227     SelectObject (anDC, anOldBitmap);
2228     DeleteObject (aMemoryBitmap);
2229     DeleteDC(anDC);
2230   }
2231
2232   if (!isSaved)
2233   {
2234     di << "Save to file operation failed. This operation may fail\n";
2235     di << "if you don't have enough available memory, then you can\n";
2236     di << "use smaller dimensions for the output file\n";
2237     return 1;
2238   }
2239
2240   return 0;
2241
2242 #endif
2243 }
2244
2245 //==============================================================================
2246 //function : VZLayer
2247 //purpose  : Test z layer operations for v3d viewer
2248 //==============================================================================
2249 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2250 {
2251   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
2252   if (aContextAIS.IsNull())
2253   {
2254     di << "Call vinit before!\n";
2255     return 1;
2256   }
2257   else if (argc < 2)
2258   {
2259     di << "Use: vzlayer " << argv[0];
2260     di << " add/del/get [id]\n";
2261     di << " add - add new z layer to viewer and print its id\n";
2262     di << " del - del z layer by its id\n";
2263     di << " get - print sequence of z layers in increasing order of their overlay level\n";
2264     di << "id - the layer identificator value defined when removing z layer\n";
2265     return 1;
2266   }
2267
2268   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
2269   if (aViewer.IsNull())
2270   {
2271     di << "No active viewer!\n";
2272     return 1;
2273   }
2274
2275   // perform operation
2276   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
2277   if (anOp == "add")
2278   {
2279     Standard_Integer aNewId;
2280     if (!aViewer->AddZLayer (aNewId))
2281     {
2282       di << "Impossible to add new z layer!\n";
2283       return 1;
2284     }
2285
2286     di << "New z layer added with index: " << aNewId << "\n";
2287   }
2288   else if (anOp == "del")
2289   {
2290     if (argc < 3)
2291     {
2292       di << "Please also provide as argument id of z layer to remove\n";
2293       return 1;
2294     }
2295
2296     Standard_Integer aDelId = Draw::Atoi (argv[2]);
2297     if (!aViewer->RemoveZLayer (aDelId))
2298     {
2299       di << "Impossible to remove the z layer or invalid id!\n";
2300       return 1;
2301     }
2302
2303     di << "Z layer " << aDelId << " has been removed\n";
2304   }
2305   else if (anOp == "get")
2306   {
2307     TColStd_SequenceOfInteger anIds;
2308     aViewer->GetAllZLayers (anIds);
2309     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
2310     {
2311       di << anIds.Value (aSeqIdx) << " ";
2312     }
2313
2314     di << "\n";
2315   }
2316   else
2317   {
2318     di << "Invalid operation, please use { add / del / get }\n";
2319     return 1;
2320   }
2321
2322   return 0;
2323 }
2324
2325 DEFINE_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
2326
2327 // this class provides a presentation of text item in v3d view under-/overlayer
2328 class V3d_TextItem : public Visual3d_LayerItem
2329 {
2330 public:
2331
2332   // CASCADE RTTI
2333   DEFINE_STANDARD_RTTI(V3d_TextItem)
2334
2335   // constructor
2336   Standard_EXPORT V3d_TextItem(const TCollection_AsciiString& theText,
2337                                const Standard_Real theX1,
2338                                const Standard_Real theY1,
2339                                const Standard_Real theHeight,
2340                                const TCollection_AsciiString& theFontName,
2341                                const Quantity_Color& theColor,
2342                                const Quantity_Color& theSubtitleColor,
2343                                const Aspect_TypeOfDisplayText& theTypeOfDisplay,
2344                                const Handle(Visual3d_Layer)& theLayer);
2345
2346   // redraw method
2347   Standard_EXPORT void RedrawLayerPrs();
2348
2349 private:
2350
2351   Standard_Real            myX1;
2352   Standard_Real            myY1;
2353   Standard_Real            myHeight;
2354   TCollection_AsciiString  myText;
2355   TCollection_AsciiString  myFontName;
2356   Quantity_Color           myColor;
2357   Quantity_Color           mySubtitleColor;
2358   Aspect_TypeOfDisplayText myType;
2359   Handle(Visual3d_Layer)   myLayer;
2360
2361 };
2362
2363 IMPLEMENT_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
2364 IMPLEMENT_STANDARD_RTTIEXT(V3d_TextItem, Visual3d_LayerItem)
2365
2366 // create and add to display the text item
2367 V3d_TextItem::V3d_TextItem (const TCollection_AsciiString& theText,
2368                             const Standard_Real theX1,
2369                             const Standard_Real theY1,
2370                             const Standard_Real theHeight,
2371                             const TCollection_AsciiString& theFontName,
2372                             const Quantity_Color& theColor,
2373                             const Quantity_Color& theSubtitleColor,
2374                             const Aspect_TypeOfDisplayText& theTypeOfDisplay,
2375                             const Handle(Visual3d_Layer)& theLayer)
2376  : myX1 (theX1), myY1 (theY1),
2377    myText (theText),
2378    myHeight (theHeight),
2379    myLayer (theLayer),
2380    myColor (theColor),
2381    mySubtitleColor (theSubtitleColor),
2382    myType (theTypeOfDisplay),
2383    myFontName (theFontName)
2384 {
2385   if (!myLayer.IsNull ())
2386     myLayer->AddLayerItem (this);
2387 }
2388
2389 // render item
2390 void V3d_TextItem::RedrawLayerPrs ()
2391 {
2392   if (myLayer.IsNull ())
2393     return;
2394
2395   myLayer->SetColor (myColor);
2396   myLayer->SetTextAttributes (myFontName.ToCString (), myType, mySubtitleColor);
2397   myLayer->DrawText (myText.ToCString (), myX1, myY1, myHeight);
2398 }
2399
2400 DEFINE_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
2401
2402 // The Visual3d_LayerItem line item for "vlayerline" command
2403 // it provides a presentation of line with user-defined
2404 // linewidth, linetype and transparency.
2405 class V3d_LineItem : public Visual3d_LayerItem
2406 {
2407 public:
2408   // CASCADE RTTI
2409   DEFINE_STANDARD_RTTI(V3d_LineItem)
2410
2411   // constructor
2412   Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
2413                                Standard_Real X2, Standard_Real Y2,
2414                                V3d_LayerMgrPointer theLayerMgr,
2415                                Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
2416                                Standard_Real theWidth    = 0.5,
2417                                Standard_Real theTransp   = 1.0);
2418
2419   // redraw method
2420   Standard_EXPORT   void RedrawLayerPrs();
2421
2422 private:
2423
2424   Standard_Real       myX1, myY1, myX2, myY2;
2425   Standard_Real       myWidth;
2426   Standard_Real       myTransparency;
2427   Aspect_TypeOfLine   myType;
2428   V3d_LayerMgrPointer myLayerMgr;
2429 };
2430
2431 IMPLEMENT_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
2432 IMPLEMENT_STANDARD_RTTIEXT(V3d_LineItem, Visual3d_LayerItem)
2433
2434 // default constructor for line item
2435 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
2436                            Standard_Real X2, Standard_Real Y2,
2437                            V3d_LayerMgrPointer theLayerMgr,
2438                            Aspect_TypeOfLine theType,
2439                            Standard_Real theWidth,
2440                            Standard_Real theTransp) :
2441   myX1(X1), myY1(Y1), myX2(X2), myY2(Y2), myLayerMgr(theLayerMgr),
2442   myType(theType), myWidth(theWidth), myTransparency(theTransp)
2443 {
2444   if (myLayerMgr && !myLayerMgr->Overlay().IsNull())
2445     myLayerMgr->Overlay()->AddLayerItem (this);
2446 }
2447
2448 // render line
2449 void V3d_LineItem::RedrawLayerPrs ()
2450 {
2451   Handle (Visual3d_Layer) aOverlay;
2452
2453   if (myLayerMgr)
2454     aOverlay = myLayerMgr->Overlay();
2455
2456   if (!aOverlay.IsNull())
2457   {
2458     Quantity_Color aColor(1.0, 0, 0, Quantity_TOC_RGB);
2459     aOverlay->SetColor(aColor);
2460     aOverlay->SetTransparency((Standard_ShortReal)myTransparency);
2461     aOverlay->SetLineAttributes((Aspect_TypeOfLine)myType, myWidth);
2462     aOverlay->BeginPolyline();
2463     aOverlay->AddVertex(myX1, myY1);
2464     aOverlay->AddVertex(myX2, myY2);
2465     aOverlay->ClosePrimitive();
2466   }
2467 }
2468
2469 //=============================================================================
2470 //function : VLayerLine
2471 //purpose  : Draws line in the v3d view layer with given attributes: linetype,
2472 //         : linewidth, transparency coefficient
2473 //============================================================================
2474 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2475 {
2476   // get the active view
2477   Handle(V3d_View) aView = ViewerTest::CurrentView();
2478   if (aView.IsNull())
2479   {
2480     di << "Call vinit before!\n";
2481     return 1;
2482   }
2483   else if (argc < 5)
2484   {
2485     di << "Use: " << argv[0];
2486     di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
2487     di << " linetype : { 0 | 1 | 2 | 3 } \n";
2488     di << "              0 - solid  \n";
2489     di << "              1 - dashed \n";
2490     di << "              2 - dot    \n";
2491     di << "              3 - dashdot\n";
2492     di << " transparency : { 0.0 - 1.0 } \n";
2493     di << "                  0.0 - transparent\n";
2494     di << "                  1.0 - visible    \n";
2495     return 1;
2496   }
2497
2498   // get the input params
2499   Standard_Real X1 = Draw::Atof(argv[1]);
2500   Standard_Real Y1 = Draw::Atof(argv[2]);
2501   Standard_Real X2 = Draw::Atof(argv[3]);
2502   Standard_Real Y2 = Draw::Atof(argv[4]);
2503
2504   Standard_Real    aWidth = 0.5;
2505   Standard_Integer aType  = 0;
2506   Standard_Real    aTransparency = 1.0;
2507
2508   // has width
2509   if (argc > 5)
2510     aWidth = Draw::Atof(argv[5]);
2511
2512   // has type
2513   if (argc > 6)
2514      aType = (Standard_Integer) Draw::Atoi(argv[6]);
2515
2516   // has transparency
2517   if (argc > 7)
2518   {
2519     aTransparency = Draw::Atof(argv[7]);
2520     if (aTransparency < 0 || aTransparency > 1.0)
2521       aTransparency = 1.0;
2522   }
2523
2524   // select appropriate line type
2525   Aspect_TypeOfLine aLineType;
2526   switch (aType)
2527   {
2528     case 1:
2529       aLineType = Aspect_TOL_DASH;
2530     break;
2531
2532     case 2:
2533       aLineType = Aspect_TOL_DOT;
2534     break;
2535
2536     case 3:
2537       aLineType = Aspect_TOL_DOTDASH;
2538     break;
2539
2540     default:
2541       aLineType = Aspect_TOL_SOLID;
2542   }
2543
2544   // replace layer manager
2545   Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr(aView);
2546   aView->SetLayerMgr(aMgr);
2547
2548   // add line item
2549   Handle (V3d_LineItem) anItem = new V3d_LineItem(X1, Y1, X2, Y2,
2550                                                   aMgr.operator->(),
2551                                                   aLineType, aWidth,
2552                                                   aTransparency);
2553
2554   // update view
2555   aView->MustBeResized();
2556   aView->Redraw();
2557
2558   return 0;
2559 }
2560
2561 //=======================================================================
2562 //function : VOverlayText
2563 //purpose  : Test text displaying in view overlay
2564 //=======================================================================
2565 static int VOverlayText (Draw_Interpretor& di, Standard_Integer argc, const char**argv)
2566 {
2567   // get the active view
2568   Handle(V3d_View) aView = ViewerTest::CurrentView();
2569   if (aView.IsNull())
2570   {
2571     di << "No active view. Please call vinit.\n";
2572     return 1;
2573   }
2574   else if (argc < 4 || argc > 13)
2575   {
2576     di << "Use: " << argv[0];
2577     di << " text x y [height] [font_name] [text_color: R G B] [displayType]\n";
2578     di << "[background_color: R G B]\n";
2579     di << "  height - pixel height of the text (default=10.0)\n";
2580     di << "  font_name - name of font (default=courier)\n";
2581     di << "  text_color - R G B values of text color (default=255.0 255.0 255.0)\n";
2582     di << "  display_type = {normal/subtitle/decal/blend}, (default=normal)\n";
2583     di << "  background_color- R G B values used for subtitle and decal text\n";
2584     di << "(default=255.0 255.0 255.0)\n";
2585     return 1;
2586   }
2587
2588   TCollection_AsciiString aText (argv[1]);
2589   Standard_Real aPosX = Draw::Atof(argv[2]);
2590   Standard_Real aPosY = Draw::Atof(argv[3]);
2591   Standard_Real aHeight = (argc >= 5) ? Draw::Atof (argv[4]) : 10.0;
2592
2593   // font name
2594   TCollection_AsciiString aFontName = "Courier";
2595   if (argc >= 6)
2596     aFontName = TCollection_AsciiString (argv[5]);
2597
2598   // text colors
2599   Quantity_Parameter aColorRed   = 1.0;
2600   Quantity_Parameter aColorGreen = 1.0;
2601   Quantity_Parameter aColorBlue  = 1.0;
2602   if (argc >= 9)
2603   {
2604     aColorRed   = Draw::Atof (argv[6])/255.;
2605     aColorGreen = Draw::Atof (argv[7])/255.;
2606     aColorBlue  = Draw::Atof (argv[8])/255.;
2607   }
2608
2609   // display type
2610   TCollection_AsciiString aDispStr;
2611   if (argc >= 10)
2612     aDispStr = TCollection_AsciiString (argv[9]);
2613
2614   Aspect_TypeOfDisplayText aTextType = Aspect_TODT_NORMAL;
2615   if (aDispStr.IsEqual ("subtitle"))
2616     aTextType = Aspect_TODT_SUBTITLE;
2617   else if (aDispStr.IsEqual ("decal"))
2618     aTextType = Aspect_TODT_DEKALE;
2619   else if (aDispStr.IsEqual ("blend"))
2620     aTextType = Aspect_TODT_BLEND;
2621
2622   // subtitle color
2623   Quantity_Parameter aSubRed   = 1.0;
2624   Quantity_Parameter aSubGreen = 1.0;
2625   Quantity_Parameter aSubBlue  = 1.0;
2626   if (argc == 13)
2627   {
2628     aSubRed   = Draw::Atof (argv[10])/255.;
2629     aSubGreen = Draw::Atof (argv[11])/255.;
2630     aSubBlue  = Draw::Atof (argv[12])/255.;
2631   }
2632
2633   // check fo current overlay
2634   Handle(Visual3d_Layer) anOverlay = aView->Viewer()->Viewer()->OverLayer ();
2635   if (anOverlay.IsNull ())
2636   {
2637     Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr (aView);
2638     anOverlay = aMgr->Overlay ();
2639     aView->SetLayerMgr (aMgr);
2640   }
2641
2642   Quantity_Color aTextColor (aColorRed, aColorGreen,
2643     aColorBlue, Quantity_TOC_RGB);
2644   Quantity_Color aSubtColor (aSubRed, aSubGreen,
2645     aSubBlue, Quantity_TOC_RGB);
2646
2647   // add text item
2648   Handle(V3d_TextItem) anItem = new V3d_TextItem (aText, aPosX, aPosY,
2649     aHeight, aFontName, aTextColor, aSubtColor, aTextType, anOverlay);
2650
2651   // update view
2652   aView->MustBeResized();
2653   aView->Redraw();
2654
2655   return 0;
2656 }
2657
2658 //==============================================================================
2659 //function : VGrid
2660 //purpose  :
2661 //==============================================================================
2662
2663 static int VGrid (Draw_Interpretor& theDI,
2664                   Standard_Integer  theArgNb,
2665                   const char**      theArgVec)
2666 {
2667   // get the active view
2668   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
2669   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
2670   if (aView.IsNull() || aViewer.IsNull())
2671   {
2672     std::cerr << "No active view. Please call vinit.\n";
2673     return 1;
2674   }
2675
2676   Aspect_GridType     aType = aViewer->GridType();
2677   Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
2678
2679   Standard_Integer anIter = 1;
2680   for (; anIter < theArgNb; ++anIter)
2681   {
2682     const char* aValue = theArgVec[anIter];
2683     if (*aValue == 'r')
2684     {
2685       aType = Aspect_GT_Rectangular;
2686     }
2687     else if (*aValue == 'c')
2688     {
2689       aType = Aspect_GT_Circular;
2690     }
2691     else if (*aValue == 'l')
2692     {
2693       aMode = Aspect_GDM_Lines;
2694     }
2695     else if (*aValue == 'p')
2696     {
2697       aMode = Aspect_GDM_Points;
2698     }
2699     else if (strcmp (aValue, "off" ) == 0)
2700     {
2701       aViewer->DeactivateGrid();
2702       return 0;
2703     }
2704     else
2705     {
2706       break;
2707     }
2708   }
2709
2710   Standard_Integer aTail = (theArgNb - anIter);
2711   if (aTail == 0)
2712   {
2713     aViewer->ActivateGrid (aType, aMode);
2714     return 0;
2715   }
2716   else if (aTail != 2 && aTail != 5)
2717   {
2718     std::cerr << "Incorrect arguments number! Usage:\n"
2719               << "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]\n";
2720     return 1;
2721   }
2722
2723   Quantity_Length anOriginX, anOriginY;
2724   Quantity_PlaneAngle aRotAngle;
2725   if (aType == Aspect_GT_Rectangular)
2726   {
2727     Quantity_Length aRStepX, aRStepY;
2728     aViewer->RectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
2729
2730     anOriginX = Draw::Atof (theArgVec[anIter++]);
2731     anOriginY = Draw::Atof (theArgVec[anIter++]);
2732     if (aTail == 5)
2733     {
2734       aRStepX   = Draw::Atof (theArgVec[anIter++]);
2735       aRStepY   = Draw::Atof (theArgVec[anIter++]);
2736       aRotAngle = Draw::Atof (theArgVec[anIter++]);
2737     }
2738     aViewer->SetRectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
2739     aViewer->ActivateGrid (aType, aMode);
2740   }
2741   else if (aType == Aspect_GT_Circular)
2742   {
2743     Quantity_Length aRadiusStep;
2744     Standard_Integer aDivisionNumber;
2745     aViewer->CircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
2746
2747     anOriginX = Draw::Atof (theArgVec[anIter++]);
2748     anOriginY = Draw::Atof (theArgVec[anIter++]);
2749     if (aTail == 5)
2750     {
2751       aRadiusStep     = Draw::Atof (theArgVec[anIter++]);
2752       aDivisionNumber = Draw::Atoi (theArgVec[anIter++]);
2753       aRotAngle       = Draw::Atof (theArgVec[anIter++]);
2754     }
2755
2756     aViewer->SetCircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
2757     aViewer->ActivateGrid (aType, aMode);
2758   }
2759
2760   return 0;
2761 }
2762
2763 //==============================================================================
2764 //function : VFps
2765 //purpose  :
2766 //==============================================================================
2767
2768 static int VFps (Draw_Interpretor& theDI,
2769                  Standard_Integer  theArgNb,
2770                  const char**      theArgVec)
2771 {
2772   // get the active view
2773   Handle(V3d_View) aView = ViewerTest::CurrentView();
2774   if (aView.IsNull())
2775   {
2776     std::cerr << "No active view. Please call vinit.\n";
2777     return 1;
2778   }
2779
2780   Standard_Integer aFramesNb = (theArgNb > 1) ? Draw::Atoi(theArgVec[1]) : 100;
2781   if (aFramesNb <= 0)
2782   {
2783     std::cerr << "Incorrect arguments!\n";
2784     return 1;
2785   }
2786
2787   // the time is meaningless for first call
2788   // due to async OpenGl rendering
2789   aView->Redraw();
2790
2791   // redraw view in loop to estimate average values
2792   OSD_Timer aTimer;
2793   aTimer.Start();
2794   for (Standard_Integer anInter = 0; anInter < aFramesNb; ++anInter)
2795   {
2796     aView->Redraw();
2797   }
2798   aTimer.Stop();
2799   Standard_Real aCpu;
2800   const Standard_Real aTime = aTimer.ElapsedTime();
2801   aTimer.OSD_Chronometer::Show (aCpu);
2802
2803   const Standard_Real aFpsAver = Standard_Real(aFramesNb) / aTime;
2804   const Standard_Real aCpuAver = aCpu / Standard_Real(aFramesNb);
2805
2806   // return statistics
2807   theDI << "FPS: " << aFpsAver << "\n"
2808         << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
2809
2810   return 0;
2811 }
2812
2813
2814 //==============================================================================
2815 //function : VVbo
2816 //purpose  :
2817 //==============================================================================
2818
2819 static int VVbo (Draw_Interpretor& theDI,
2820                  Standard_Integer  theArgNb,
2821                  const char**      theArgVec)
2822 {
2823   // get the context
2824   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2825   if (aContextAIS.IsNull())
2826   {
2827     std::cerr << "No active view. Please call vinit.\n";
2828     return 1;
2829   }
2830
2831   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
2832
2833   if (aDriver.IsNull())
2834   {
2835     std::cerr << "Graphic driver not available.\n";
2836     return 1;
2837   }
2838
2839   if (theArgNb < 2)
2840   {
2841     //theDI << "VBO: " << aDriver->ToUseVBO() << "\n";
2842     //return 0;
2843     std::cerr << "Wrong number of arguments.\n";
2844     return 1;
2845   }
2846
2847   aDriver->EnableVBO (Draw::Atoi(theArgVec[1]) != 0);
2848   return 0;
2849 }
2850
2851 //==============================================================================
2852 //function : VMemGpu
2853 //purpose  :
2854 //==============================================================================
2855
2856 static int VMemGpu (Draw_Interpretor& theDI,
2857                     Standard_Integer  theArgNb,
2858                     const char**      theArgVec)
2859 {
2860   // get the context
2861   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2862   if (aContextAIS.IsNull())
2863   {
2864     std::cerr << "No active view. Please call vinit.\n";
2865     return 1;
2866   }
2867
2868   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
2869
2870   if (aDriver.IsNull())
2871   {
2872     std::cerr << "Graphic driver not available.\n";
2873     return 1;
2874   }
2875
2876   Standard_Size aFreeBytes = 0;
2877   TCollection_AsciiString anInfo;
2878   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
2879   {
2880     std::cerr << "Information not available.\n";
2881     return 1;
2882   }
2883
2884   if (theArgNb > 1 && *theArgVec[1] == 'f')
2885   {
2886     theDI << Standard_Real (aFreeBytes);
2887   }
2888   else
2889   {
2890     theDI << anInfo;
2891   }
2892
2893   return 0;
2894 }
2895
2896 // ==============================================================================
2897 // function : VReadPixel
2898 // purpose  :
2899 // ==============================================================================
2900 static int VReadPixel (Draw_Interpretor& theDI,
2901                        Standard_Integer  theArgNb,
2902                        const char**      theArgVec)
2903 {
2904   // get the active view
2905   Handle(V3d_View) aView = ViewerTest::CurrentView();
2906   if (aView.IsNull())
2907   {
2908     std::cerr << "No active view. Please call vinit.\n";
2909     return 1;
2910   }
2911   else if (theArgNb < 3)
2912   {
2913     std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
2914     return 1;
2915   }
2916
2917   Image_PixMap::ImgFormat aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
2918   Graphic3d_BufferType    aBufferType = Graphic3d_BT_RGBA;
2919
2920   Standard_Integer aWidth, aHeight;
2921   aView->Window()->Size (aWidth, aHeight);
2922   const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
2923   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
2924   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
2925   {
2926     std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
2927     return 1;
2928   }
2929
2930   Standard_Boolean toShowName = Standard_False;
2931   Standard_Boolean toShowHls  = Standard_False;
2932   for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
2933   {
2934     TCollection_AsciiString aParam (theArgVec[anIter]);
2935     if (TCollection_AsciiString::ISSIMILAR      (aParam, TCollection_AsciiString ("rgb")))
2936     {
2937       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
2938       aBufferType = Graphic3d_BT_RGB;
2939     }
2940     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("hls")))
2941     {
2942       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
2943       aBufferType = Graphic3d_BT_RGB;
2944       toShowHls   = Standard_True;
2945     }
2946     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbf")))
2947     {
2948       aFormat     = Image_PixMap::ImgRGBF;
2949       aBufferType = Graphic3d_BT_RGB;
2950     }
2951     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgba")))
2952     {
2953       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
2954       aBufferType = Graphic3d_BT_RGBA;
2955     }
2956     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("rgbaf")))
2957     {
2958       aFormat     = Image_PixMap::ImgRGBAF;
2959       aBufferType = Graphic3d_BT_RGBA;
2960     }
2961     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("depth")))
2962     {
2963       aFormat     = Image_PixMap::ImgGrayF;
2964       aBufferType = Graphic3d_BT_Depth;
2965     }
2966     else if (TCollection_AsciiString::ISSIMILAR (aParam, TCollection_AsciiString ("name")))
2967     {
2968       toShowName = Standard_True;
2969     }
2970   }
2971
2972   Image_PixMap anImage;
2973   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
2974   {
2975     std::cerr << "Image allocation failed\n";
2976     return 1;
2977   }
2978   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
2979   {
2980     std::cerr << "Image dump failed\n";
2981     return 1;
2982   }
2983
2984   Quantity_Parameter anAlpha;
2985   Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
2986   if (toShowName)
2987   {
2988     if (aBufferType == Graphic3d_BT_RGBA)
2989     {
2990       theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha << "\n";
2991     }
2992     else
2993     {
2994       theDI << Quantity_Color::StringName (aColor.Name()) << "\n";
2995     }
2996   }
2997   else
2998   {
2999     switch (aBufferType)
3000     {
3001       default:
3002       case Graphic3d_BT_RGB:
3003       {
3004         if (toShowHls)
3005         {
3006           theDI << aColor.Hue() << " " << aColor.Light() << " " << aColor.Saturation() << "\n";
3007         }
3008         else
3009         {
3010           theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << "\n";
3011         }
3012         break;
3013       }
3014       case Graphic3d_BT_RGBA:
3015       {
3016         theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha << "\n";
3017         break;
3018       }
3019       case Graphic3d_BT_Depth:
3020       {
3021         theDI << aColor.Red() << "\n";
3022         break;
3023       }
3024     }
3025   }
3026
3027   return 0;
3028 }
3029
3030 //==============================================================================
3031 //function : VDiffImage
3032 //purpose  : The draw-command compares two images.
3033 //==============================================================================
3034
3035 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3036 {
3037   if (theArgNb < 6)
3038   {
3039     theDI << "Not enough arguments.\n";
3040     return 1;
3041   }
3042
3043   // image file names
3044   const char* anImgPathRef = theArgVec[1];
3045   const char* anImgPathNew = theArgVec[2];
3046
3047   // get string tolerance and check its validity
3048   Standard_Real aTolColor = Draw::Atof (theArgVec[3]);
3049   if (aTolColor < 0.0)
3050     aTolColor = 0.0;
3051   if (aTolColor > 1.0)
3052     aTolColor = 1.0;
3053
3054   Standard_Boolean toBlackWhite     = (Draw::Atoi (theArgVec[4]) == 1);
3055   Standard_Boolean isBorderFilterOn = (Draw::Atoi (theArgVec[5]) == 1);
3056
3057   // image file of difference
3058   const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
3059
3060   // compare the images
3061   Image_Diff aComparer;
3062   if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
3063   {
3064     return 1;
3065   }
3066
3067   aComparer.SetColorTolerance (aTolColor);
3068   aComparer.SetBorderFilterOn (isBorderFilterOn);
3069   Standard_Integer aDiffColorsNb = aComparer.Compare();
3070   theDI << aDiffColorsNb << "\n";
3071
3072   // save image of difference
3073   if (aDiffImagePath != NULL)
3074   {
3075     aComparer.SaveDiffImage (aDiffImagePath);
3076   }
3077
3078   return 0;
3079 }
3080
3081 //=======================================================================
3082 //function : VSelect
3083 //purpose  : Emulates different types of selection by mouse:
3084 //           1) single click selection
3085 //           2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
3086 //           3) selection with polygon having corners at
3087 //           pixel positions (x1,y1),...,(xn,yn)
3088 //           4) any of these selections with shift button pressed
3089 //=======================================================================
3090 static Standard_Integer VSelect (Draw_Interpretor& di,
3091                                  Standard_Integer argc,
3092                                  const char ** argv)
3093 {
3094   if(argc < 3)
3095   {
3096     di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]" << "\n";
3097     return 1;
3098   }
3099
3100   Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
3101   if(myAIScontext.IsNull())
3102   {
3103     di << "use 'vinit' command before " << argv[0] << "\n";
3104     return 1;
3105   }
3106   const Standard_Boolean isShiftSelection = (argc>3 && !(argc%2) && (atoi(argv[argc-1])==1));
3107   Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
3108   aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
3109   if(argc <= 4)
3110   {
3111     if(isShiftSelection)
3112       aCurrentEventManager->ShiftSelect();
3113     else
3114       aCurrentEventManager->Select();
3115   }
3116   else if(argc <= 6)
3117   {
3118     if(isShiftSelection)
3119       aCurrentEventManager->ShiftSelect(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
3120     else
3121       aCurrentEventManager->Select(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
3122   }
3123   else
3124   {
3125     Standard_Integer anUpper = 0;
3126
3127     if(isShiftSelection)
3128       anUpper = (argc-1)/2;
3129     else
3130       anUpper = argc/2;
3131     TColgp_Array1OfPnt2d aPolyline(1,anUpper);
3132
3133     for(Standard_Integer i=1;i<=anUpper;++i)
3134       aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
3135
3136     if(isShiftSelection)
3137       aCurrentEventManager->ShiftSelect(aPolyline);
3138     else
3139       aCurrentEventManager->Select(aPolyline);
3140   }
3141   return 0;
3142 }
3143
3144 //=======================================================================
3145 //function : VMoveTo
3146 //purpose  : Emulates cursor movement to defined pixel position
3147 //=======================================================================
3148 static Standard_Integer VMoveTo (Draw_Interpretor& di,
3149                                 Standard_Integer argc,
3150                                 const char ** argv)
3151 {
3152   if(argc != 3)
3153   {
3154     di << "Usage : " << argv[0] << " x y" << "\n";
3155     return 1;
3156   }
3157
3158   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3159   if(aContext.IsNull())
3160   {
3161     di << "use 'vinit' command before " << argv[0] << "\n";
3162     return 1;
3163   }
3164   ViewerTest::CurrentEventManager()->MoveTo(atoi(argv[1]),atoi(argv[2]));
3165   return 0;
3166 }
3167
3168 //=======================================================================
3169 //function : VViewParams
3170 //purpose  : Gets or sets AIS View characteristics
3171 //=======================================================================
3172 static Standard_Integer VViewParams (Draw_Interpretor& di,
3173                                 Standard_Integer argc,
3174                                 const char ** argv)
3175 {
3176   if ( argc != 1 && argc != 13)
3177   {
3178     di << "Usage : " << argv[0] << "\n";
3179     return 1;
3180   }
3181   Handle (V3d_View) anAISView = ViewerTest::CurrentView ();
3182   if ( anAISView.IsNull () )
3183   {
3184     di << "use 'vinit' command before " << argv[0] << "\n";
3185     return 1;
3186   }
3187   if(argc==1){
3188     Quantity_Factor anAISViewScale = anAISView -> V3d_View::Scale ();
3189     Standard_Real anAISViewCenterCoordinateX = 0.0;
3190     Standard_Real anAISViewCenterCoordinateY = 0.0;
3191     anAISView -> V3d_View::Center (anAISViewCenterCoordinateX, anAISViewCenterCoordinateY);
3192     Standard_Real anAISViewProjX = 0.0;
3193     Standard_Real anAISViewProjY = 0.0;
3194     Standard_Real anAISViewProjZ = 0.0;
3195     anAISView -> V3d_View::Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
3196     Standard_Real anAISViewUpX = 0.0;
3197     Standard_Real anAISViewUpY = 0.0;
3198     Standard_Real anAISViewUpZ = 0.0;
3199     anAISView -> V3d_View::Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
3200     Standard_Real anAISViewAtX = 0.0;
3201     Standard_Real anAISViewAtY = 0.0;
3202     Standard_Real anAISViewAtZ = 0.0;
3203     anAISView -> V3d_View::At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
3204     di << "Scale of current view: " << anAISViewScale << "\n";
3205     di << "Center on X : "<< anAISViewCenterCoordinateX << "; on Y: " << anAISViewCenterCoordinateY << "\n";
3206     di << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
3207     di << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
3208     di << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
3209   }
3210   else
3211   {
3212     Quantity_Factor anAISViewScale = atof (argv [1]);
3213     Standard_Real anAISViewCenterCoordinateX = atof (argv [2]);
3214     Standard_Real anAISViewCenterCoordinateY = atof (argv [3]);
3215     Standard_Real anAISViewProjX = atof (argv [4]);
3216     Standard_Real anAISViewProjY = atof (argv [5]);
3217     Standard_Real anAISViewProjZ = atof (argv [6]);
3218     Standard_Real anAISViewUpX = atof (argv [7]);
3219     Standard_Real anAISViewUpY = atof (argv [8]);
3220     Standard_Real anAISViewUpZ = atof (argv [9]);
3221     Standard_Real anAISViewAtX = atof (argv [10]);
3222     Standard_Real anAISViewAtY = atof (argv [11]);
3223     Standard_Real anAISViewAtZ = atof (argv [12]);
3224     anAISView -> V3d_View::SetScale (anAISViewScale);
3225     anAISView -> V3d_View::SetCenter (anAISViewCenterCoordinateX, anAISViewCenterCoordinateY);
3226     anAISView -> V3d_View::SetAt (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
3227     anAISView -> V3d_View::SetProj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
3228     anAISView -> V3d_View::SetUp (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
3229   }
3230   return 0;
3231 }
3232
3233 //=======================================================================
3234 //function : VChangeSelected
3235 //purpose  : Adds the shape to selection or remove one from it
3236 //=======================================================================
3237 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
3238                                 Standard_Integer argc,
3239                                 const char ** argv)
3240 {
3241   if(argc != 2)
3242   {
3243     di<<"Usage : " << argv[0] << " shape \n";
3244     return 1;
3245   }
3246   //get AIS_Shape:
3247   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3248   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3249   TCollection_AsciiString aName(argv[1]);
3250   Handle(AIS_InteractiveObject) anAISObject;
3251
3252   if(!aMap.IsBound2(aName))
3253   {
3254     di<<"Use 'vdisplay' before";
3255     return 1;
3256   }
3257   else
3258   {
3259     anAISObject = Handle(AIS_InteractiveObject)::DownCast(aMap.Find2(aName));
3260     if(anAISObject.IsNull()){
3261       di<<"No interactive object \n";
3262       return 1;
3263     }
3264
3265     if(aContext->HasOpenedContext())
3266     {
3267       aContext->AddOrRemoveSelected(anAISObject);
3268     }
3269     else
3270     {
3271       aContext->AddOrRemoveCurrentObject(anAISObject);
3272     }
3273   }
3274   return 0;
3275 }
3276
3277 //=======================================================================
3278 //function : VZClipping
3279 //purpose  : Gets or sets ZClipping mode, width and depth
3280 //=======================================================================
3281 static Standard_Integer VZClipping (Draw_Interpretor& di,
3282                                 Standard_Integer argc,
3283                                 const char ** argv)
3284 {
3285   if(argc>4)
3286   {
3287     di << "Usage : " << argv[0] << " [mode] [depth  width]" << "\n"
3288       <<"mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
3289     return -1;
3290   }
3291   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3292   if(aContext.IsNull())
3293   {
3294     di << "use 'vinit' command before " << argv[0] << "\n";
3295     return 1;
3296   }
3297   Handle(V3d_View) aView = ViewerTest::CurrentView();
3298   V3d_TypeOfZclipping aZClippingMode;
3299   if(argc==1)
3300   {
3301     TCollection_AsciiString aZClippingModeString;
3302     Quantity_Length aDepth, aWidth;
3303     aZClippingMode = aView->ZClipping(aDepth, aWidth);
3304     switch (aZClippingMode)
3305     {
3306     case V3d_OFF:
3307       aZClippingModeString.Copy("OFF");
3308       break;
3309     case V3d_BACK:
3310       aZClippingModeString.Copy("BACK");
3311       break;
3312     case V3d_FRONT:
3313       aZClippingModeString.Copy("FRONT");
3314       break;
3315     case V3d_SLICE:
3316       aZClippingModeString.Copy("SLICE");
3317       break;
3318     default:
3319       aZClippingModeString.Copy(TCollection_AsciiString(aZClippingMode));
3320       break;
3321     }
3322     di << "ZClippingMode = " << aZClippingModeString.ToCString() << "\n"
3323       << "ZClipping depth = " << aDepth << "\n"
3324       << "ZClipping width = " << aWidth << "\n";
3325   }
3326   else
3327   {
3328     if(argc !=3)
3329     {
3330       Standard_Integer aStatus = 0;
3331       if ( strcmp (argv [1], "OFF") == 0 ) {
3332         aStatus = 1;
3333         aZClippingMode = V3d_OFF;
3334       }
3335       if ( strcmp (argv [1], "BACK") == 0 ) {
3336         aStatus = 1;
3337         aZClippingMode = V3d_BACK;
3338       }
3339       if ( strcmp (argv [1], "FRONT") == 0 ) {
3340         aStatus = 1;
3341         aZClippingMode = V3d_FRONT;
3342       }
3343       if ( strcmp (argv [1], "SLICE") == 0 ) {
3344         aStatus = 1;
3345         aZClippingMode = V3d_SLICE;
3346       }
3347       if (aStatus != 1)
3348       {
3349         di << "Bad mode; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
3350           << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
3351         return 1;
3352       }
3353       aView->SetZClippingType(aZClippingMode);
3354     }
3355     if(argc >2)
3356     {
3357       Quantity_Length aDepth = 0., aWidth = 1.;
3358       if(argc == 3)
3359       {
3360         aDepth = atof(argv[1]);
3361         aWidth = atof(argv[2]);
3362       }
3363       else if(argc == 4)
3364       {
3365         aDepth = atof(argv[2]);
3366         aWidth = atof(argv[3]);
3367       }
3368
3369       if(aDepth<0. || aDepth>1.)
3370       {
3371         di << "Bad depth; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
3372         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
3373         return 1;
3374       }
3375       if(aWidth<0. || aWidth>1.)
3376       {
3377         di << "Bad width; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
3378         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
3379         return 1;
3380       }
3381
3382       aView->SetZClippingDepth(aDepth);
3383       aView->SetZClippingWidth(aWidth);
3384     }
3385     aView->Redraw();
3386   }
3387   return 0;
3388 }
3389
3390 //=======================================================================
3391 //function : VNbSelected
3392 //purpose  : Returns number of selected objects
3393 //=======================================================================
3394 static Standard_Integer VNbSelected (Draw_Interpretor& di,
3395                                 Standard_Integer argc,
3396                                 const char ** argv)
3397 {
3398   if(argc != 1)
3399   {
3400     di << "Usage : " << argv[0] << "\n";
3401     return 1;
3402   }
3403   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3404   if(aContext.IsNull())
3405   {
3406     di << "use 'vinit' command before " << argv[0] << "\n";
3407     return 1;
3408   }
3409   di << aContext->NbSelected() << "\n";
3410   return 0;
3411 }
3412
3413 //=======================================================================
3414 //function : VAntialiasing
3415 //purpose  : Switches altialiasing on or off
3416 //=======================================================================
3417 static Standard_Integer VAntialiasing (Draw_Interpretor& di,
3418                                 Standard_Integer argc,
3419                                 const char ** argv)
3420 {
3421   if(argc > 2)
3422   {
3423     di << "Usage : " << argv[0] << " [1|0]" << "\n";
3424     return 1;
3425   }
3426
3427   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3428   if(aContext.IsNull())
3429   {
3430     di << "use 'vinit' command before " << argv[0] << "\n";
3431     return 1;
3432   }
3433
3434   Handle(V3d_View) aView = ViewerTest::CurrentView();
3435
3436   if((argc == 2) && (atof(argv[1]) == 0))
3437     aView->SetAntialiasingOff();
3438   else
3439     aView->SetAntialiasingOn();
3440   aView->Update();
3441   return 0;
3442 }
3443
3444 //=======================================================================
3445 //function : VPurgeDisplay
3446 //purpose  : Switches altialiasing on or off
3447 //=======================================================================
3448 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
3449                                 Standard_Integer argc,
3450                                 const char ** argv)
3451 {
3452   if (argc > 2)
3453   {
3454     di << "Usage : " << argv[0] << " [CollectorToo = 0|1]" << "\n";
3455     return 1;
3456   }
3457   Standard_Boolean isCollectorToo = Standard_False;
3458   if (argc == 2)
3459   {
3460       isCollectorToo = (atoi(argv [1]) != 0);
3461   }
3462   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3463   if (aContext.IsNull())
3464   {
3465     di << "use 'vinit' command before " << argv[0] << "\n";
3466     return 1;
3467   }
3468   aContext->CloseAllContexts(Standard_False);
3469   di << aContext->PurgeDisplay(isCollectorToo) << "\n";
3470   return 0;
3471 }
3472
3473 //=======================================================================
3474 //function : VSetViewSize
3475 //purpose  :
3476 //=======================================================================
3477 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
3478                                 Standard_Integer argc,
3479                                 const char ** argv)
3480 {
3481   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3482   if(aContext.IsNull())
3483   {
3484     di << "use 'vinit' command before " << argv[0] << "\n";
3485     return 1;
3486   }
3487   if(argc != 2)
3488   {
3489     di<<"Usage : " << argv[0] << " Size\n";
3490     return 1;
3491   }
3492   Standard_Real aSize = atof(argv[1]);
3493   if (aSize <= 0.)
3494   {
3495     di<<"Bad Size value  : " << aSize << "\n";
3496     return 1;