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