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