0022795: Make possible to display some presentable objects in overlay of others,...
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands.cxx
1 // File:  ViewerTest_ViewerCommands.cxx
2 // Created: Tue Sep  1 10:28:35 1998
3 // Author:  Robert COUBLANC
4 //    <rob@robox.paris1.matra-dtv.fr>
5
6 // Robert Boehne 30 May 2000 : Dec Osf
7
8 #ifdef HAVE_CONFIG_H
9 # include <config.h>
10 #endif
11
12 #ifdef WNT
13 #include <windows.h>
14 #endif
15
16 #include <Graphic3d_ExportFormat.hxx>
17 #include <ViewerTest.hxx>
18 #include <ViewerTest_EventManager.hxx>
19 #include <Visual3d_View.hxx>
20 #include <NIS_View.hxx>
21 #include <NIS_Triangulated.hxx>
22 #include <NIS_InteractiveContext.hxx>
23 #include <AIS_InteractiveContext.hxx>
24 #include <Draw_Interpretor.hxx>
25 #include <Draw.hxx>
26 #include <Draw_Appli.hxx>
27 #include <Aspect_PrintAlgo.hxx>
28 #include <Image_PixMap.hxx>
29 #include <TColStd_SequenceOfInteger.hxx>
30
31 #ifndef WNT
32 #include <Graphic3d_GraphicDevice.hxx>
33 #include <Xw_GraphicDevice.hxx>
34 #include <Xw_WindowQuality.hxx>
35 #include <Xw_Window.hxx>
36 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
37 #include <X11/Xutil.h>
38 #include <tk.h>
39
40 #else
41
42 #include <Graphic3d_WNTGraphicDevice.hxx>
43 #include <WNT_WClass.hxx>
44 #include <WNT_Window.hxx>
45
46 #define _CRT_SECURE_NO_DEPRECATE
47 #pragma warning (disable:4996)
48
49 #endif
50
51 #define OCC120
52
53 //==============================================================================
54
55 //==============================================================================
56 //  VIEWER GLOBAL VARIABLES
57 //==============================================================================
58
59 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
60
61 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
62 extern const Handle(NIS_InteractiveContext)& TheNISContext();
63
64 #ifdef WNT
65 static Handle(Graphic3d_WNTGraphicDevice)& GetG3dDevice(){
66   static Handle(Graphic3d_WNTGraphicDevice) GD;
67   return GD;
68 }
69
70 static Handle(WNT_Window)& VT_GetWindow() {
71   static Handle(WNT_Window) WNTWin;
72   return WNTWin;
73 }
74
75 #else
76 static Handle(Graphic3d_GraphicDevice)& GetG3dDevice(){
77   static Handle(Graphic3d_GraphicDevice) GD;
78   return GD;
79 }
80 static Handle(Xw_Window)& VT_GetWindow(){
81   static Handle(Xw_Window) XWWin;
82   return XWWin;
83 }
84 static Display *display;
85
86 static void VProcessEvents(ClientData,int);
87 #endif
88
89 #ifdef OCC120
90 static Standard_Boolean DegenerateMode = Standard_True;
91 #endif
92
93 #define ZCLIPWIDTH 1.
94
95 static void OSWindowSetup();
96
97 //==============================================================================
98 //  EVENT GLOBAL VARIABLES
99 //==============================================================================
100
101 static int Start_Rot = 0;
102 static int ZClipIsOn = 0;
103 static int X_Motion= 0,Y_Motion=0; // Current cursor position
104 static int X_ButtonPress = 0, Y_ButtonPress = 0; // Last ButtonPress position
105
106
107 //==============================================================================
108
109 #ifdef WNT
110 static LRESULT WINAPI ViewerWindowProc(
111                                        HWND hwnd,
112                                        UINT uMsg,
113                                        WPARAM wParam,
114                                        LPARAM lParam );
115 static LRESULT WINAPI AdvViewerWindowProc(
116   HWND hwnd,
117   UINT uMsg,
118   WPARAM wParam,
119   LPARAM lParam );
120 #endif
121
122
123 //==============================================================================
124 //function : WClass
125 //purpose  :
126 //==============================================================================
127
128 const Handle(MMgt_TShared)& ViewerTest::WClass()
129 {
130   static Handle(MMgt_TShared) theWClass;
131 #ifdef WNT
132   if (theWClass.IsNull()) {
133     theWClass = new WNT_WClass ("GW3D_Class", AdvViewerWindowProc,
134       CS_VREDRAW | CS_HREDRAW, 0, 0,
135       ::LoadCursor (NULL, IDC_ARROW));
136   }
137 #endif
138   return theWClass;
139 }
140
141 //==============================================================================
142 //function : ViewerInit
143 //purpose  : Create the window viewer and initialize all the global variable
144 //==============================================================================
145
146 void ViewerTest::ViewerInit (const Standard_Integer thePxLeft,  const Standard_Integer thePxTop,
147                              const Standard_Integer thePxWidth, const Standard_Integer thePxHeight)
148 {
149   static Standard_Boolean isFirst = Standard_True;
150
151   Standard_Integer aPxLeft   = 0;
152   Standard_Integer aPxTop    = 460;
153   Standard_Integer aPxWidth  = 409;
154   Standard_Integer aPxHeight = 409;
155   if (thePxWidth != 0 && thePxHeight != 0)
156   {
157     aPxLeft   = thePxLeft;
158     aPxTop    = thePxTop;
159     aPxWidth  = thePxWidth;
160     aPxHeight = thePxHeight;
161   }
162
163   if (isFirst)
164   {
165     // Create the Graphic device
166 #ifdef WNT
167     if (GetG3dDevice().IsNull()) GetG3dDevice() = new Graphic3d_WNTGraphicDevice();
168     if (VT_GetWindow().IsNull())
169     {
170       // Create the Graphic device and the window
171       Handle(WNT_GraphicDevice) g_Device = new WNT_GraphicDevice();
172
173       VT_GetWindow() = new WNT_Window (g_Device, "Test3d",
174                                        Handle(WNT_WClass)::DownCast (WClass()),
175                                        WS_OVERLAPPEDWINDOW,
176                                        aPxLeft, aPxTop,
177                                        aPxWidth, aPxHeight,
178                                        Quantity_NOC_BLACK);
179       VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
180     }
181 #else
182     if (GetG3dDevice().IsNull()) GetG3dDevice() =
183       new Graphic3d_GraphicDevice (getenv ("DISPLAY"), Xw_TOM_READONLY);
184     if (VT_GetWindow().IsNull())
185     {
186       VT_GetWindow() = new Xw_Window (GetG3dDevice(),
187                                       "Test3d",
188                                       aPxLeft, aPxTop,
189                                       aPxWidth, aPxHeight,
190                                       Xw_WQ_3DQUALITY,
191                                       Quantity_NOC_BLACK);
192       VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
193     }
194 #endif
195
196     Handle(V3d_Viewer) a3DViewer, a3DCollector;
197     // Viewer and View creation
198
199     TCollection_ExtendedString NameOfWindow("Visu3D");
200
201     a3DViewer = new V3d_Viewer(GetG3dDevice(), NameOfWindow.ToExtString());
202     NameOfWindow = TCollection_ExtendedString("Collector");
203     a3DCollector = new V3d_Viewer(GetG3dDevice(), NameOfWindow.ToExtString());
204     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
205     a3DCollector->SetDefaultBackgroundColor(Quantity_NOC_STEELBLUE);
206     Handle(NIS_View) aView =
207       Handle(NIS_View)::DownCast(ViewerTest::CurrentView());
208     if ( aView.IsNull() ) {
209       //       Handle (V3d_View) V = a3DViewer->CreateView();
210       aView = new NIS_View (a3DViewer, VT_GetWindow());
211       ViewerTest::CurrentView(aView);
212       TheNISContext()->AttachView (aView);
213     }
214     Handle(V3d_View) a3DViewCol;
215     if ( a3DViewCol.IsNull() ) a3DViewCol    = a3DViewer->CreateView();
216
217     // AIS setup
218     if ( ViewerTest::GetAISContext().IsNull() ) {
219       Handle(AIS_InteractiveContext) C =
220         new AIS_InteractiveContext(a3DViewer,a3DCollector);
221       ViewerTest::SetAISContext(C);
222     }
223
224     // Setup for X11 or NT
225     OSWindowSetup();
226     // Viewer and View creation
227
228     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
229
230     Handle (V3d_View) V = ViewerTest::CurrentView();
231
232     V->SetDegenerateModeOn();
233 #ifdef OCC120
234     DegenerateMode = V->DegenerateModeIsOn();
235 #endif
236     //    V->SetWindow(VT_GetWindow(), NULL, MyViewProc, NULL);
237
238     V->SetZClippingDepth(0.5);
239     V->SetZClippingWidth(ZCLIPWIDTH/2.);
240     a3DViewer->SetDefaultLights();
241     a3DViewer->SetLightOn();
242
243 #ifndef WNT
244 #if TCL_MAJOR_VERSION  < 8
245     Tk_CreateFileHandler((void*)ConnectionNumber(display),
246       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
247 #else
248     Tk_CreateFileHandler(ConnectionNumber(display),
249       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
250 #endif
251 #endif
252
253     isFirst = Standard_False;
254   }
255   VT_GetWindow()->Map();
256 }
257
258 //==============================================================================
259 //function : Vinit
260 //purpose  : Create the window viewer and initialize all the global variable
261 //    Use Tk_CreateFileHandler on UNIX to cath the X11 Viewer event
262 //==============================================================================
263
264 static int VInit (Draw_Interpretor& , Standard_Integer argc, const char** argv)
265 {
266   Standard_Integer aPxLeft   = (argc > 1) ? atoi (argv[1]) : 0;
267   Standard_Integer aPxTop    = (argc > 2) ? atoi (argv[2]) : 0;
268   Standard_Integer aPxWidth  = (argc > 3) ? atoi (argv[3]) : 0;
269   Standard_Integer aPxHeight = (argc > 4) ? atoi (argv[4]) : 0;
270   ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight);
271   return 0;
272 }
273
274 //==============================================================================
275 //function : ProcessKeyPress
276 //purpose  : Handle KeyPress event from a CString
277 //==============================================================================
278
279 static void ProcessKeyPress( char *buf_ret )
280 {
281   //cout << "KeyPress" << endl;
282   const Handle(V3d_View) aView = ViewerTest::CurrentView();
283   const Handle(NIS_View) aNisView = Handle(NIS_View)::DownCast (aView);
284   // Letter in alphabetic order
285
286   if ( !strcasecmp(buf_ret, "A") ) {
287     // AXO
288     aView->SetProj(V3d_XposYnegZpos);
289   }
290   else if ( !strcasecmp(buf_ret, "D") ) {
291     // Reset
292     aView->Reset();
293   }
294   else if ( !strcasecmp(buf_ret, "F") ) {
295     // FitAll
296     if (aNisView.IsNull())
297       aView->FitAll();
298     else
299       aNisView->FitAll3d();
300   }
301   else if ( !strcasecmp(buf_ret, "H") ) {
302     // HLR
303     cout << "HLR" << endl;
304 #ifdef OCC120
305     if (aView->DegenerateModeIsOn()) ViewerTest::CurrentView()->SetDegenerateModeOff();
306     else aView->SetDegenerateModeOn();
307     DegenerateMode = aView->DegenerateModeIsOn();
308 #else
309     ViewerTest::CurrentView()->SetDegenerateModeOff();
310 #endif
311   }
312   else if ( !strcasecmp(buf_ret, "D") ) {
313     // Reset
314     aView->Reset();
315   }
316   else if ( !strcasecmp(buf_ret, "S") ) {
317     // SHADING
318     cout << "passage en mode 1 (shading pour les shapes)" << endl;
319 #ifndef OCC120
320     ViewerTest::CurrentView()->SetDegenerateModeOn();
321 #endif
322     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
323     if(Ctx->NbCurrents()==0 ||
324       Ctx->NbSelected()==0)
325       Ctx->SetDisplayMode(AIS_Shaded);
326     else{
327       if(Ctx->HasOpenedContext()){
328         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
329           Ctx->SetDisplayMode(Ctx->Interactive(),1,Standard_False);
330       }
331       else{
332         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
333           Ctx->SetDisplayMode(Ctx->Current(),1,Standard_False);
334       }
335       Ctx->UpdateCurrentViewer();
336     }
337   }
338   else if ( !strcasecmp(buf_ret, "U") ) {
339     // SHADING
340     cout<<"passage au mode par defaut"<<endl;
341 #ifndef OCC120
342     ViewerTest::CurrentView()->SetDegenerateModeOn();
343 #endif
344     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
345     if(Ctx->NbCurrents()==0 ||
346       Ctx->NbSelected()==0)
347       Ctx->SetDisplayMode(AIS_WireFrame);
348     else{
349       if(Ctx->HasOpenedContext()){
350         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
351           Ctx->UnsetDisplayMode(Ctx->Interactive(),Standard_False);
352       }
353       else{
354         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
355           Ctx->UnsetDisplayMode(Ctx->Current(),Standard_False);
356       }
357       Ctx->UpdateCurrentViewer();
358     }
359
360   }
361   else if ( !strcasecmp(buf_ret, "T") ) {
362     // Top
363     aView->SetProj(V3d_Zpos);
364   }
365   else if ( !strcasecmp(buf_ret, "B") ) {
366     // Top
367     aView->SetProj(V3d_Zneg);
368   }
369   else if ( !strcasecmp(buf_ret, "L") ) {
370     // Top
371     aView->SetProj(V3d_Xneg);
372   }
373   else if ( !strcasecmp(buf_ret, "R") ) {
374     // Top
375     aView->SetProj(V3d_Xpos);
376   }
377
378   else if ( !strcasecmp(buf_ret, "W") ) {
379     // WIREFRAME
380 #ifndef OCC120
381     ViewerTest::CurrentView()->SetDegenerateModeOn();
382 #endif
383     cout << "passage en mode 0 (filaire pour les shapes)" << endl;
384 #ifndef OCC120
385     ViewerTest::CurrentView()->SetDegenerateModeOn();
386 #endif
387     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
388     if(Ctx->NbCurrents()==0 ||
389       Ctx->NbSelected()==0)
390       Ctx->SetDisplayMode(AIS_WireFrame);
391     else{
392       if(Ctx->HasOpenedContext()){
393         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
394           Ctx->SetDisplayMode(Ctx->Interactive(),0,Standard_False);
395       }
396       else{
397         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
398           Ctx->SetDisplayMode(Ctx->Current(),0,Standard_False);
399       }
400       Ctx->UpdateCurrentViewer();
401     }
402   }
403   else if ( !strcasecmp(buf_ret, "Z") ) {
404     // ZCLIP
405
406     if ( ZClipIsOn ) {
407       cout << "ZClipping OFF" << endl;
408       ZClipIsOn = 0;
409
410       aView->SetZClippingType(V3d_OFF);
411       aView->Redraw();
412     }
413     else {
414       cout << "ZClipping ON" << endl;
415       ZClipIsOn = 1;
416
417       aView->SetZClippingType(V3d_FRONT);
418       aView->Redraw();
419     }
420   }
421   else if ( !strcasecmp(buf_ret, ",") ) {
422     ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
423
424
425   }
426   else if ( !strcasecmp(buf_ret, ".") ) {
427     ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
428   }
429   // Number
430   else{
431     Standard_Integer Num = atoi(buf_ret);
432     if(Num>=0 && Num<=7)
433       ViewerTest::StandardModeActivation(Num);
434   }
435 }
436
437 //==============================================================================
438 //function : ProcessExpose
439 //purpose  : Redraw the View on an Expose Event
440 //==============================================================================
441
442 static void ProcessExpose(  )
443 { //cout << "Expose" << endl;
444   ViewerTest::CurrentView()->Redraw();
445 }
446
447 //==============================================================================
448 //function : ProcessConfigure
449 //purpose  : Resize the View on an Configure Event
450 //==============================================================================
451
452 static void ProcessConfigure()
453 {
454   Handle(V3d_View) V = ViewerTest::CurrentView();
455   V->MustBeResized();
456   V->Update();
457   V->Redraw();
458 }
459
460 //==============================================================================
461 //function : ProcessButton1Press
462 //purpose  : Picking
463 //==============================================================================
464
465 static Standard_Boolean ProcessButton1Press(
466   Standard_Integer ,
467   const char** argv,
468   Standard_Boolean pick,
469   Standard_Boolean shift )
470 {
471   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
472   if ( pick ) {
473     Standard_Real X, Y, Z;
474
475     ViewerTest::CurrentView()->Convert(X_Motion, Y_Motion, X, Y, Z);
476
477     Draw::Set(argv[1], X);
478     Draw::Set(argv[2], Y);
479     Draw::Set(argv[3], Z);}
480
481   if(shift)
482     EM->ShiftSelect();
483   else
484     EM->Select();
485
486   pick = 0;
487   return pick;
488 }
489
490 //==============================================================================
491 //function : ProcessButton3Press
492 //purpose  : Start Rotation
493 //==============================================================================
494
495 static void ProcessButton3Press()
496
497 { // Start rotation
498   Start_Rot = 1;
499   ViewerTest::CurrentView()->SetDegenerateModeOn();
500   ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
501
502 }
503 //==============================================================================
504 //function : ProcessButtonRelease
505 //purpose  : Start Rotation
506 //==============================================================================
507
508 static void ProcessButtonRelease()
509
510 { // End rotation
511 #ifdef OCC120
512   if (Start_Rot) {
513     Start_Rot = 0;
514     if (!DegenerateMode) ViewerTest::CurrentView()->SetDegenerateModeOff();
515   }
516 #else
517   Start_Rot = 0;
518   ViewerTest::CurrentView()->SetDegenerateModeOff();
519 #endif
520 }
521
522 //==============================================================================
523 //function : ProcessZClipMotion
524 //purpose  : Zoom
525 //==============================================================================
526
527 void ProcessZClipMotion()
528 {
529   Handle(V3d_View)  a3DView = ViewerTest::CurrentView();
530   if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
531     static Standard_Real CurZPos = 0.;
532
533     //Quantity_Length VDX, VDY;
534     //a3DView->Size(VDX,VDY);
535     //Standard_Real VDZ = a3DView->ZSize();
536     //printf("View size (%lf,%lf,%lf)\n", VDX, VDY, VDZ);
537
538     Quantity_Length dx = a3DView->Convert(X_Motion - X_ButtonPress);
539
540     // Front = Depth + width/2.
541     Standard_Real D = 0.5;
542     Standard_Real W = 0.1;
543
544     CurZPos += (dx);
545
546     D += CurZPos;
547
548     //printf("dx %lf Depth %lf Width %lf\n", dx, D, W);
549
550     a3DView->SetZClippingType(V3d_OFF);
551     a3DView->SetZClippingDepth(D);
552     a3DView->SetZClippingWidth(W);
553     a3DView->SetZClippingType(V3d_FRONT);
554
555     a3DView->Redraw();
556
557     X_ButtonPress = X_Motion;
558     Y_ButtonPress = Y_Motion;
559   }
560 }
561
562 //==============================================================================
563 //function : ProcessControlButton1Motion
564 //purpose  : Zoom
565 //==============================================================================
566
567 static void ProcessControlButton1Motion()
568 {
569   ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
570
571   X_ButtonPress = X_Motion;
572   Y_ButtonPress = Y_Motion;
573 }
574
575 //==============================================================================
576 //function : ProcessControlButton2Motion
577 //purpose  : Pann
578 //==============================================================================
579
580 static void ProcessControlButton2Motion()
581 {
582   Quantity_Length dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
583   Quantity_Length dy = ViewerTest::CurrentView()->Convert(Y_Motion - Y_ButtonPress);
584
585   dy = -dy; // Xwindow Y axis is from top to Bottom
586
587   ViewerTest::CurrentView()->Panning( dx, dy );
588
589   X_ButtonPress = X_Motion;
590   Y_ButtonPress = Y_Motion;
591 }
592
593 //==============================================================================
594 //function : ProcessControlButton3Motion
595 //purpose  : Rotation
596 //==============================================================================
597
598 static void ProcessControlButton3Motion()
599 {
600   if ( Start_Rot ) ViewerTest::CurrentView()->Rotation( X_Motion, Y_Motion);
601 }
602
603 //==============================================================================
604 //function : ProcessPointerMotion
605 //purpose  : Rotation
606 //==============================================================================
607
608 static void ProcessMotion()
609 {
610   //pre-hilights detected objects at mouse position
611
612   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
613   EM->MoveTo(X_Motion, Y_Motion);
614 }
615
616
617 void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
618 {
619   Xpix = X_Motion;Ypix=Y_Motion;
620 }
621
622 //==============================================================================
623 //function : VAxo
624 //purpose  : Switch to an Axonometric view
625 //Draw arg : No args
626 //==============================================================================
627
628 static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
629 { if ( ViewerTest::CurrentView().IsNull() ) {
630   di<<"La commande vinit n'a pas ete appele avant"<<"\n";
631   //  VInit(di, argc, argv);
632 }
633
634 ViewerTest::CurrentView()->SetProj(V3d_XposYnegZpos);
635
636 return 0;
637 }
638
639 //==============================================================================
640 //function : VTop
641 //purpose  : Switch to a Top View
642 //Draw arg : No args
643 //==============================================================================
644
645 static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
646 {
647
648   if ( ViewerTest::CurrentView().IsNull() ) {
649     di<<"La commande vinit n'a pas ete appele avant"<<"\n";
650
651     //  VInit(di, , argv);
652   }
653
654   ViewerTest::CurrentView()->SetProj(V3d_Zpos);
655   return 0;
656
657 }
658
659 //==============================================================================
660 //function : VHelp
661 //purpose  : Dsiplay help on viewer Keyboead and mouse commands
662 //Draw arg : No args
663 //==============================================================================
664
665 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
666 {
667
668   di << "Q : Quit the application" << "\n";
669
670   di << "========================="<<"\n";
671   di << "F : FitAll" << "\n";
672   di << "T : TopView" << "\n";
673   di << "A : AxonometricView" << "\n";
674   di << "R : ResetView" << "\n";
675
676   di << "========================="<<"\n";
677   di << "S : Shading" << "\n";
678   di << "W : Wireframe" << "\n";
679   di << "H : HidelLineRemoval" << "\n";
680
681   di << "========================="<<"\n";
682   di << "Selection mode "<<"\n";
683   di << "0 : Shape" <<"\n";
684   di << "1 : Vertex" <<"\n";
685   di << "2 : Edge" <<"\n";
686   di << "3 : Wire" <<"\n";
687   di << "4 : Face" <<"\n";
688   di << "5 : Shell" <<"\n";
689   di << "6 : Solid" <<"\n";
690   di << "7 : Compound" <<"\n";
691
692   di << "=========================="<<"\n";
693   di << "D : Remove Selected Object"<<"\n";
694   di << "=========================="<<"\n";
695
696   return 0;
697 }
698
699 Standard_Boolean IsDragged = Standard_False;
700
701 Standard_Integer xx1, yy1, xx2, yy2;
702 //the first and last point in viewer co-ordinates
703
704 Standard_Boolean DragFirst;
705
706
707 #ifdef WNT
708
709 static Standard_Boolean Ppick = 0;
710 static Standard_Integer Pargc = 0;
711 static const char**           Pargv = NULL;
712
713
714 static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
715                                           UINT Msg,
716                                           WPARAM wParam,
717                                           LPARAM lParam )
718 {
719   if ( !ViewerTest::CurrentView().IsNull() ) {
720
721     WPARAM fwKeys = wParam;
722
723     switch( Msg ) {
724
725     case WM_LBUTTONUP:
726       IsDragged = Standard_False;
727       if( !DragFirst )
728       {
729         HDC hdc = GetDC( hwnd );
730         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
731         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
732         SetROP2( hdc, R2_NOT );
733         Rectangle( hdc, xx1, yy1, xx2, yy2 );
734         ReleaseDC( hwnd, hdc );
735
736         const Handle(ViewerTest_EventManager) EM =
737           ViewerTest::CurrentEventManager();
738         if ( fwKeys & MK_SHIFT )
739           EM->ShiftSelect( min( xx1, xx2 ), max( yy1, yy2 ),
740           max( xx1, xx2 ), min( yy1, yy2 ));
741         else
742           EM->Select( min( xx1, xx2 ), max( yy1, yy2 ),
743           max( xx1, xx2 ), min( yy1, yy2 ));
744       }
745       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
746
747     case WM_LBUTTONDOWN:
748       if( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) )
749       {
750         IsDragged = Standard_True;
751         DragFirst = Standard_True;
752         xx1 = LOWORD(lParam);
753         yy1 = HIWORD(lParam);
754       }
755       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
756
757       break;
758
759     case WM_MOUSEMOVE:
760       if( IsDragged )
761       {
762         HDC hdc = GetDC( hwnd );
763
764         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
765         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
766         SetROP2( hdc, R2_NOT );
767
768         if( !DragFirst )
769           Rectangle( hdc, xx1, yy1, xx2, yy2 );
770
771         DragFirst = Standard_False;
772         xx2 = LOWORD(lParam);
773         yy2 = HIWORD(lParam);
774
775         Rectangle( hdc, xx1, yy1, xx2, yy2 );
776
777         SelectObject( hdc, anObj );
778
779         ReleaseDC( hwnd, hdc );
780       }
781       else
782         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
783       break;
784
785     default:
786       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
787     }
788     return 0;
789   }
790   return ViewerWindowProc( hwnd, Msg, wParam, lParam );
791 }
792
793
794 static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
795                                        UINT Msg,
796                                        WPARAM wParam,
797                                        LPARAM lParam )
798 {
799   /*static Standard_Boolean Ppick = 0;
800   static Standard_Integer Pargc = 0;
801   static char**           Pargv = NULL;*/
802
803   static int Up = 1;
804
805   if ( !ViewerTest::CurrentView().IsNull() ) {
806     PAINTSTRUCT    ps;
807
808     switch( Msg ) {
809     case WM_CLOSE:
810       // do not destroy the window - just hide it!
811       VT_GetWindow()->Unmap();
812       return 0;
813     case WM_PAINT:
814       //cout << "\t WM_PAINT" << endl;
815       BeginPaint(hwnd, &ps);
816       EndPaint(hwnd, &ps);
817       ProcessExpose();
818       break;
819
820     case WM_SIZE:
821       //cout << "\t WM_SIZE" << endl;
822       ProcessConfigure();
823       break;
824
825     case WM_KEYDOWN:
826       //cout << "\t WM_KEYDOWN " << (int) wParam << endl;
827
828       if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) ) {
829         char c[2];
830         c[0] = (char) wParam;
831         c[1] = '\0';
832         ProcessKeyPress( c);
833       }
834       break;
835
836     case WM_LBUTTONUP:
837     case WM_MBUTTONUP:
838     case WM_RBUTTONUP:
839       //cout << "\t WM_xBUTTONUP" << endl;
840       Up = 1;
841       ProcessButtonRelease();
842       break;
843
844     case WM_LBUTTONDOWN:
845     case WM_MBUTTONDOWN:
846     case WM_RBUTTONDOWN:
847       {
848         //cout << "\t WM_xBUTTONDOWN" << endl;
849         WPARAM fwKeys = wParam;
850
851         Up = 0;
852
853         X_ButtonPress = LOWORD(lParam);
854         Y_ButtonPress = HIWORD(lParam);
855
856         if ( Msg == WM_LBUTTONDOWN) {
857           if(fwKeys & MK_CONTROL) {
858             Ppick = ProcessButton1Press( Pargc, Pargv, Ppick,  (fwKeys & MK_SHIFT) );
859           } else
860             ProcessButton1Press( Pargc, Pargv, Ppick,  (fwKeys & MK_SHIFT) );
861         }
862         else if ( Msg == WM_RBUTTONDOWN ) {
863           // Start rotation
864           ProcessButton3Press( );
865         }
866       }
867       break;
868
869     case WM_MOUSEMOVE:
870       {
871         //cout << "\t WM_MOUSEMOVE" << endl;
872         WPARAM fwKeys = wParam;
873         X_Motion = LOWORD(lParam);
874         Y_Motion = HIWORD(lParam);
875
876         if ( Up &&
877           fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON ) ) {
878             Up = 0;
879             X_ButtonPress = LOWORD(lParam);
880             Y_ButtonPress = HIWORD(lParam);
881
882             if ( fwKeys & MK_RBUTTON ) {
883               // Start rotation
884               ProcessButton3Press();
885             }
886           }
887
888           if ( fwKeys & MK_CONTROL ) {
889             if ( fwKeys & MK_LBUTTON ) {
890               ProcessControlButton1Motion();
891             }
892             else if ( fwKeys & MK_MBUTTON ||
893               ((fwKeys&MK_LBUTTON) &&
894               (fwKeys&MK_RBUTTON) ) ){
895                 ProcessControlButton2Motion();
896               }
897             else if ( fwKeys & MK_RBUTTON ) {
898               ProcessControlButton3Motion();
899             }
900           }
901 #ifdef BUG
902           else if ( fwKeys & MK_SHIFT ) {
903             if ( fwKeys & MK_MBUTTON ||
904               ((fwKeys&MK_LBUTTON) &&
905               (fwKeys&MK_RBUTTON) ) ) {
906                 cout << "ProcessZClipMotion()" << endl;
907                 ProcessZClipMotion();
908               }
909           }
910 #endif
911           else
912             if (( fwKeys & MK_MBUTTON || ((fwKeys&MK_LBUTTON) && (fwKeys&MK_RBUTTON) ) )){
913               ProcessZClipMotion();
914             }
915             else {
916               ProcessMotion();
917             }
918       }
919       break;
920
921     default:
922       return( DefWindowProc( hwnd, Msg, wParam, lParam ));
923     }
924     return 0L;
925   }
926
927   return DefWindowProc( hwnd, Msg, wParam, lParam );
928 }
929
930
931
932
933 //==============================================================================
934 //function : ViewerMainLoop
935 //purpose  : Get a Event on the view and dispatch it
936 //==============================================================================
937
938
939 static int ViewerMainLoop(Standard_Integer argc, const char** argv)
940 {
941
942   //cout << "No yet implemented on WNT" << endl;
943   /*static Standard_Boolean Ppick = 0;
944   static Standard_Integer Pargc = 0;
945   static char**           Pargv = NULL;*/
946
947   //Ppick = (argc > 0)? -1 : 0;
948   Ppick = (argc > 0)? 1 : 0;
949   Pargc = argc;
950   Pargv = argv;
951
952   if ( Ppick ) {
953     MSG msg;
954     msg.wParam = 1;
955
956     cout << "Start picking" << endl;
957
958     //while ( Ppick == -1 ) {
959     while ( Ppick == 1 ) {
960       // Wait for a ProcessButton1Press() to toggle pick to 1 or 0
961       if (GetMessage(&msg, NULL, 0, 0) ) {
962         TranslateMessage(&msg);
963         DispatchMessage(&msg);
964       }
965     }
966
967     cout << "Picking done" << endl;
968   }
969
970   return Ppick;
971 }
972
973
974 #else
975
976 int min( int a, int b )
977 {
978   if( a<b )
979     return a;
980   else
981     return b;
982 }
983
984 int max( int a, int b )
985 {
986   if( a>b )
987     return a;
988   else
989     return b;
990 }
991
992 int ViewerMainLoop(Standard_Integer argc, const char** argv)
993
994 { Standard_Boolean pick = argc > 0;
995
996 // X11 Event loop
997
998 static XEvent report;
999
1000 XNextEvent( display, &report );
1001 //    cout << "rep type = " << report.type << endl;
1002 //    cout << "rep button = " << report.xbutton.button << endl;
1003
1004 switch ( report.type ) {
1005       case Expose:
1006         {
1007           ProcessExpose();
1008         }
1009         break;
1010       case ConfigureNotify:
1011         {
1012           ProcessConfigure();
1013         }
1014         break;
1015       case KeyPress:
1016         {
1017
1018           KeySym ks_ret ;
1019           char buf_ret[11] ;
1020           int ret_len ;
1021           XComposeStatus status_in_out;
1022
1023           ret_len = XLookupString( ( XKeyEvent *)&report ,
1024             (char *) buf_ret , 10 ,
1025             &ks_ret , &status_in_out ) ;
1026
1027
1028           buf_ret[ret_len] = '\0' ;
1029
1030           if ( ret_len ) {
1031             ProcessKeyPress( buf_ret);
1032           }
1033         }
1034         break;
1035       case ButtonPress:
1036         //  cout << "ButtonPress" << endl;
1037         {
1038           X_ButtonPress = report.xbutton.x;
1039           Y_ButtonPress = report.xbutton.y;
1040
1041           if ( report.xbutton.button == Button1 )
1042             if(  report.xbutton.state & ControlMask )
1043               pick = ProcessButton1Press( argc, argv, pick,
1044               ( report.xbutton.state & ShiftMask) );
1045             else
1046             {
1047               IsDragged = Standard_True;
1048               xx1 = X_ButtonPress;
1049               yy1 = Y_ButtonPress;
1050               DragFirst = Standard_True;
1051             }
1052           else if ( report.xbutton.button == Button3 )
1053             // Start rotation
1054             ProcessButton3Press();
1055         }
1056         break;
1057       case ButtonRelease:
1058         {
1059           //    cout<<"relachement du bouton "<<(report.xbutton.button==3 ? "3": "on s'en fout") <<endl;
1060           //    cout << IsDragged << endl;
1061           //    cout << DragFirst << endl;
1062
1063           if( IsDragged )
1064           {
1065             if( !DragFirst )
1066             {
1067               Aspect_Handle aWindow = VT_GetWindow()->XWindow();
1068               GC gc = XCreateGC( display, aWindow, 0, 0 );
1069               //  XSetFunction( display, gc, GXinvert );
1070               XDrawRectangle( display, aWindow, gc, min( xx1, xx2 ), min( yy1, yy2 ), abs( xx2-xx1 ), abs( yy2-yy1 ) );
1071             }
1072
1073             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1074             if( aContext.IsNull() )
1075             {
1076               cout << "The context is null. Please use vinit before createmesh" << endl;
1077               return 0;
1078             }
1079
1080             Standard_Boolean ShiftPressed = ( report.xbutton.state & ShiftMask );
1081             if( report.xbutton.button==1 )
1082               if( DragFirst )
1083                 if( ShiftPressed )
1084                 {
1085                   aContext->ShiftSelect();
1086                   //                   cout << "shift select" << endl;
1087                 }
1088                 else
1089                 {
1090                   aContext->Select();
1091                   //                   cout << "select" << endl;
1092                 }
1093               else
1094                 if( ShiftPressed )
1095                 {
1096                   aContext->ShiftSelect( min( xx1, xx2 ), min( yy1, yy2 ),
1097                     max( xx1, xx2 ), max( yy1, yy2 ),
1098                     ViewerTest::CurrentView());
1099                   //                   cout << "shift select" << endl;
1100                 }
1101                 else
1102                 {
1103                   aContext->Select( min( xx1, xx2 ), min( yy1, yy2 ),
1104                     max( xx1, xx2 ), max( yy1, yy2 ),
1105                     ViewerTest::CurrentView() );
1106                   //                   cout << "select" << endl;
1107                 }
1108             else
1109               ProcessButtonRelease();
1110
1111             IsDragged = Standard_False;
1112           }
1113           else
1114             ProcessButtonRelease();
1115         }
1116         break;
1117       case MotionNotify:
1118         {
1119           //    XEvent dummy;
1120
1121           X_Motion = report.xmotion.x;
1122           Y_Motion = report.xmotion.y;
1123
1124           if( IsDragged )
1125           {
1126             Aspect_Handle aWindow = VT_GetWindow()->XWindow();
1127             GC gc = XCreateGC( display, aWindow, 0, 0 );
1128             XSetFunction( display, gc, GXinvert );
1129
1130             if( !DragFirst )
1131               XDrawRectangle( display, aWindow, gc, min( xx1, xx2 ), min( yy1, yy2 ), abs( xx2-xx1 ), abs( yy2-yy1 ) );
1132
1133             xx2 = X_Motion;
1134             yy2 = Y_Motion;
1135             DragFirst = Standard_False;
1136
1137             //cout << "draw rect : " << xx2 << ", " << yy2 << endl;
1138             XDrawRectangle( display, aWindow, gc, min( xx1, xx2 ), min( yy1, yy2 ), abs( xx2-xx1 ), abs( yy2-yy1 ) );
1139           }
1140           else
1141           {
1142
1143             //cout << "MotionNotify " << X_Motion << "," << Y_Motion << endl;
1144
1145             // remove all the ButtonMotionMask
1146             while( XCheckMaskEvent( display, ButtonMotionMask, &report) ) ;
1147
1148             if ( ZClipIsOn && report.xmotion.state & ShiftMask ) {
1149               if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
1150
1151                 Quantity_Length VDX, VDY;
1152
1153                 ViewerTest::CurrentView()->Size(VDX,VDY);
1154                 Standard_Real VDZ =0 ;
1155                 VDZ = ViewerTest::CurrentView()->ZSize();
1156
1157                 //          printf("%lf,%lf,%lf\n", VDX, VDY, VDZ);
1158                 printf("%f,%f,%f\n", VDX, VDY, VDZ);
1159
1160                 Quantity_Length dx = 0 ;
1161                 dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
1162
1163                 cout << dx << endl;
1164
1165                 dx = dx / VDX * VDZ;
1166
1167                 cout << dx << endl;
1168
1169                 // Front = Depth + width/2.
1170                 //ViewerTest::CurrentView()->SetZClippingDepth(dx);
1171                 //ViewerTest::CurrentView()->SetZClippingWidth(0.);
1172
1173                 ViewerTest::CurrentView()->Redraw();
1174               }
1175             }
1176
1177             if ( report.xmotion.state & ControlMask ) {
1178               if ( report.xmotion.state & Button1Mask ) {
1179                 ProcessControlButton1Motion();
1180               }
1181               else if ( report.xmotion.state & Button2Mask ) {
1182                 ProcessControlButton2Motion();
1183               }
1184               else if ( report.xmotion.state & Button3Mask ) {
1185                 ProcessControlButton3Motion();
1186               }
1187             }
1188             else {
1189               ProcessMotion();
1190             }
1191           }
1192         }
1193         break;
1194 }
1195
1196
1197 return pick;
1198 }
1199
1200 //==============================================================================
1201 //function : VProcessEvents
1202 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
1203 //       event in the Viewer window
1204 //==============================================================================
1205
1206 static void VProcessEvents(ClientData,int)
1207 {
1208   //cout << "VProcessEvents" << endl;
1209
1210   // test for X Event
1211   while (XPending(display)) {
1212     ViewerMainLoop( 0, NULL);
1213   }
1214 }
1215 #endif
1216
1217 //==============================================================================
1218 //function : OSWindowSetup
1219 //purpose  : Setup for the X11 window to be able to cath the event
1220 //==============================================================================
1221
1222
1223 static void OSWindowSetup()
1224 {
1225 #ifndef WNT
1226   // X11
1227
1228   Window  window   = VT_GetWindow()->XWindow();
1229
1230   Standard_Address theDisplay = GetG3dDevice()->XDisplay();
1231   display = (Display * ) theDisplay;
1232   //  display = (Display *)GetG3dDevice()->XDisplay();
1233
1234   XSynchronize(display, 1);
1235
1236   VT_GetWindow()->Map();
1237
1238   // X11 : For keyboard on SUN
1239   XWMHints wmhints;
1240   wmhints.flags = InputHint;
1241   wmhints.input = 1;
1242
1243   XSetWMHints( display, window, &wmhints);
1244
1245   XSelectInput( display, window,  ExposureMask | KeyPressMask |
1246     ButtonPressMask | ButtonReleaseMask |
1247     StructureNotifyMask |
1248     PointerMotionMask |
1249     Button1MotionMask | Button2MotionMask |
1250     Button3MotionMask
1251     );
1252
1253   XSynchronize(display, 0);
1254
1255 #else
1256   // WNT
1257 #endif
1258
1259 }
1260
1261
1262 //==============================================================================
1263 //function : VFit
1264
1265 //purpose  : Fitall, no DRAW arguments
1266 //Draw arg : No args
1267 //==============================================================================
1268
1269 static int VFit(Draw_Interpretor& , Standard_Integer , const char** )
1270 {
1271   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1272   Handle(NIS_View) V = Handle(NIS_View)::DownCast(aView);
1273   if (V.IsNull() == Standard_False) {
1274     V->FitAll3d();
1275   } else if (aView.IsNull() == Standard_False) {
1276     aView->FitAll();
1277   }
1278   return 0;
1279 }
1280
1281 //==============================================================================
1282 //function : VZFit
1283 //purpose  : ZFitall, no DRAW arguments
1284 //Draw arg : No args
1285 //==============================================================================
1286
1287 static int VZFit(Draw_Interpretor& , Standard_Integer , const char** )
1288 {
1289   Handle(V3d_View) V = ViewerTest::CurrentView();
1290   if ( !V.IsNull() ) V->ZFitAll(); return 0; }
1291
1292
1293 static int VRepaint(Draw_Interpretor& , Standard_Integer , const char** )
1294 {
1295   Handle(V3d_View) V = ViewerTest::CurrentView();
1296   if ( !V.IsNull() ) V->Redraw(); return 0;
1297 }
1298
1299
1300 //==============================================================================
1301 //function : VClear
1302 //purpose  : Remove all the object from the viewer
1303 //Draw arg : No args
1304 //==============================================================================
1305
1306 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
1307 {
1308   Handle(V3d_View) V = ViewerTest::CurrentView();
1309   if(!V.IsNull())
1310     ViewerTest::Clear();
1311   return 0;
1312 }
1313
1314 //==============================================================================
1315 //function : VPick
1316 //purpose  :
1317 //==============================================================================
1318
1319 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1320 { if (ViewerTest::CurrentView().IsNull() ) return 1;
1321
1322 if ( argc < 4 ) {
1323   di << argv[0] << "Invalid number of arguments" << "\n";
1324   return 1;
1325 }
1326
1327 while (ViewerMainLoop( argc, argv)) {
1328 }
1329
1330 return 0;
1331 }
1332
1333
1334
1335 //==============================================================================
1336 //function : InitViewerTest
1337 //purpose  : initialisation de toutes les variables static de  ViewerTest (dp)
1338 //==============================================================================
1339
1340 void ViewerTest_InitViewerTest (const Handle(AIS_InteractiveContext)& context)
1341 {
1342   Handle(V3d_Viewer) viewer = context->CurrentViewer();
1343   ViewerTest::SetAISContext(context);
1344   viewer->InitActiveViews();
1345   Handle(V3d_View) view = viewer->ActiveView();
1346   if (viewer->MoreActiveViews()) ViewerTest::CurrentView(view);
1347   ViewerTest::ResetEventManager();
1348   Handle(Aspect_GraphicDevice) device = viewer->Device();
1349   Handle(Aspect_Window) window = view->Window();
1350 #ifndef WNT
1351   // X11
1352   VT_GetWindow() = Handle(Xw_Window)::DownCast(window);
1353   GetG3dDevice() = Handle(Graphic3d_GraphicDevice)::DownCast(device);
1354   OSWindowSetup();
1355   static int first = 1;
1356   if ( first ) {
1357 #if TCL_MAJOR_VERSION  < 8
1358     Tk_CreateFileHandler((void*)ConnectionNumber(display),
1359       TK_READABLE, VProcessEvents, (ClientData) 0);
1360 #else
1361     Tk_CreateFileHandler(ConnectionNumber(display),
1362       TK_READABLE, VProcessEvents, (ClientData) 0);
1363 #endif
1364     first = 0;
1365   }
1366 #endif
1367 }
1368
1369
1370 //==============================================================================
1371 //function : VSetBg
1372 //purpose  : Load image as background
1373 //==============================================================================
1374
1375 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1376 {
1377   if (argc < 2 || argc > 3)
1378   {
1379     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background" << "\n";
1380     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1381     return 1;
1382   }
1383
1384   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1385   if(AISContext.IsNull())
1386   {
1387     di << "use 'vinit' command before " << argv[0] << "\n";
1388     return 1;
1389   }
1390
1391   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
1392   if (argc == 3)
1393   {
1394     const char* szType = argv[2];
1395     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
1396     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
1397     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
1398     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
1399     else
1400     {
1401       di << "Wrong fill type : " << szType << "\n";
1402       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1403       return 1;
1404     }
1405   }
1406
1407   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1408   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
1409
1410   return 0;
1411 }
1412
1413 //==============================================================================
1414 //function : VSetBgMode
1415 //purpose  : Change background image fill type
1416 //==============================================================================
1417
1418 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1419 {
1420   if (argc != 2)
1421   {
1422     di << "Usage : " << argv[0] << " filltype : Change background image mode" << "\n";
1423     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1424     return 1;
1425   }
1426
1427   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1428   if(AISContext.IsNull())
1429   {
1430     di << "use 'vinit' command before " << argv[0] << "\n";
1431     return 1;
1432   }
1433
1434   Aspect_FillMethod aFillType;
1435   if (argc == 2)
1436   {
1437     const char* szType = argv[1];
1438     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
1439     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
1440     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
1441     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
1442     else
1443     {
1444       di << "Wrong fill type : " << szType << "\n";
1445       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
1446       return 1;
1447     }
1448   }
1449
1450   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1451   V3dView->SetBgImageStyle(aFillType, Standard_True);
1452
1453   return 0;
1454 }
1455
1456 //==============================================================================
1457 //function : VSetGradientBg
1458 //purpose  : Mount gradient background
1459 //==============================================================================
1460 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1461 {
1462   if (argc != 8 )
1463   {
1464     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background" << "\n";
1465     di << "R1,G1,B1,R2,G2,B2 = [0..255]" << "\n";
1466     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1467     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1468     return 1;
1469   }
1470
1471   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1472   if(AISContext.IsNull())
1473   {
1474     di << "use 'vinit' command before " << argv[0] << "\n";
1475     return 1;
1476   }
1477   if (argc == 8)
1478   {
1479
1480     Standard_Real R1 = atof(argv[1])/255.;
1481     Standard_Real G1 = atof(argv[2])/255.;
1482     Standard_Real B1 = atof(argv[3])/255.;
1483     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
1484
1485     Standard_Real R2 = atof(argv[4])/255.;
1486     Standard_Real G2 = atof(argv[5])/255.;
1487     Standard_Real B2 = atof(argv[6])/255.;
1488
1489     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
1490     int aType = atoi(argv[7]);
1491     if( aType < 0 || aType > 8 )
1492     {
1493       di << "Wrong fill type " << "\n";
1494       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1495       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1496       return 1;
1497     }
1498
1499     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
1500
1501     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1502     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
1503   }
1504
1505   return 0;
1506 }
1507
1508 //==============================================================================
1509 //function : VSetGradientBgMode
1510 //purpose  : Change gradient background fill style
1511 //==============================================================================
1512 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1513 {
1514   if (argc != 2 )
1515   {
1516     di << "Usage : " << argv[0] << " Type : Change gradient background fill type" << "\n";
1517     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1518     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1519     return 1;
1520   }
1521
1522   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1523   if(AISContext.IsNull())
1524   {
1525     di << "use 'vinit' command before " << argv[0] << "\n";
1526     return 1;
1527   }
1528   if (argc == 2)
1529   {
1530     int aType = atoi(argv[1]);
1531     if( aType < 0 || aType > 8 )
1532     {
1533       di << "Wrong fill type " << "\n";
1534       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
1535       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
1536       return 1;
1537     }
1538
1539     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
1540
1541     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1542     V3dView->SetBgGradientStyle( aMethod, 1 );
1543   }
1544
1545   return 0;
1546 }
1547
1548 //==============================================================================
1549 //function : VSetColorBg
1550 //purpose  : Set color background
1551 //==============================================================================
1552 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1553 {
1554   if (argc != 4 )
1555   {
1556     di << "Usage : " << argv[0] << " R G B : Set color background" << "\n";
1557     di << "R,G,B = [0..255]" << "\n";
1558     return 1;
1559   }
1560
1561   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
1562   if(AISContext.IsNull())
1563   {
1564     di << "use 'vinit' command before " << argv[0] << "\n";
1565     return 1;
1566   }
1567   if (argc == 4)
1568   {
1569
1570     Standard_Real R = atof(argv[1])/255.;
1571     Standard_Real G = atof(argv[2])/255.;
1572     Standard_Real B = atof(argv[3])/255.;
1573     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
1574
1575     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1576     V3dView->SetBackgroundColor( aColor );
1577     V3dView->Update();
1578   }
1579
1580   return 0;
1581 }
1582
1583 //==============================================================================
1584 //function : VScale
1585 //purpose  : View Scaling
1586 //==============================================================================
1587
1588 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1589 {
1590   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1591   if ( V3dView.IsNull() ) return 1;
1592
1593   if ( argc != 4 ) {
1594     di << argv[0] << "Invalid number of arguments" << "\n";
1595     return 1;
1596   }
1597   V3dView->SetAxialScale( atof(argv[1]),  atof(argv[2]),  atof(argv[3]) );
1598   return 0;
1599 }
1600 //==============================================================================
1601 //function : VTestZBuffTrihedron
1602 //purpose  : Displays a V3d_ZBUFFER'ed trihedron at the bottom left corner of the view
1603 //==============================================================================
1604
1605 static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1606 {
1607   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1608   if ( V3dView.IsNull() ) return 1;
1609
1610   // Set up default trihedron parameters
1611   V3dView->ZBufferTriedronSetup();
1612   V3dView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.1, V3d_ZBUFFER );
1613   V3dView->ZFitAll();
1614   return 0;
1615 }
1616
1617 //==============================================================================
1618 //function : VRotate
1619 //purpose  : Camera Rotating
1620 //==============================================================================
1621
1622 static int VRotate( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1623   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1624   if ( V3dView.IsNull() ) {
1625     return 1;
1626   }
1627
1628   if ( argc == 4 ) {
1629     V3dView->Rotate( atof(argv[1]), atof(argv[2]), atof(argv[3]) );
1630     return 0;
1631   } else if ( argc == 7 ) {
1632     V3dView->Rotate( atof(argv[1]), atof(argv[2]), atof(argv[3]), atof(argv[4]), atof(argv[5]), atof(argv[6]) );
1633     return 0;
1634   } else {
1635     di << argv[0] << " Invalid number of arguments" << "\n";
1636     return 1;
1637   }
1638 }
1639
1640 //==============================================================================
1641 //function : VZoom
1642 //purpose  : View zoom in / out (relative to current zoom)
1643 //==============================================================================
1644
1645 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1646   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1647   if ( V3dView.IsNull() ) {
1648     return 1;
1649   }
1650
1651   if ( argc == 2 ) {
1652     Standard_Real coef = atof(argv[1]);
1653     if ( coef <= 0.0 ) {
1654       di << argv[1] << "Invalid value" << "\n";
1655       return 1;
1656     }
1657     V3dView->SetZoom( atof(argv[1]) );
1658     return 0;
1659   } else {
1660     di << argv[0] << " Invalid number of arguments" << "\n";
1661     return 1;
1662   }
1663 }
1664
1665 //==============================================================================
1666 //function : VPan
1667 //purpose  : View panning (in pixels)
1668 //==============================================================================
1669
1670 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
1671   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1672   if ( V3dView.IsNull() ) return 1;
1673
1674   if ( argc == 3 ) {
1675     V3dView->Pan( atoi(argv[1]), atoi(argv[2]) );
1676     return 0;
1677   } else {
1678     di << argv[0] << " Invalid number of arguments" << "\n";
1679     return 1;
1680   }
1681 }
1682
1683
1684 //==============================================================================
1685 //function : VExport
1686 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
1687 //==============================================================================
1688
1689 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1690 {
1691   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
1692   if (V3dView.IsNull())
1693     return 1;
1694
1695   if (argc == 1)
1696   {
1697     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
1698     return 1;
1699   }
1700
1701   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
1702   TCollection_AsciiString aFormatStr;
1703
1704   TCollection_AsciiString aFileName (argv[1]);
1705   Standard_Integer aLen = aFileName.Length();
1706
1707   if (argc > 2)
1708   {
1709     aFormatStr = TCollection_AsciiString (argv[2]);
1710   }
1711   else if (aLen >= 4)
1712   {
1713     if (aFileName.Value (aLen - 2) == '.')
1714     {
1715       aFormatStr = aFileName.SubString (aLen - 1, aLen);
1716     }
1717     else if (aFileName.Value (aLen - 3) == '.')
1718     {
1719       aFormatStr = aFileName.SubString (aLen - 2, aLen);
1720     }
1721     else
1722     {
1723       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
1724       return 1;
1725     }
1726   }
1727   else
1728   {
1729     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
1730     return 1;
1731   }
1732
1733   aFormatStr.UpperCase();
1734   if (aFormatStr == "PS")
1735     anExpFormat = Graphic3d_EF_PostScript;
1736   else if (aFormatStr == "EPS")
1737     anExpFormat = Graphic3d_EF_EnhPostScript;
1738   else if (aFormatStr == "TEX")
1739     anExpFormat = Graphic3d_EF_TEX;
1740   else if (aFormatStr == "PDF")
1741     anExpFormat = Graphic3d_EF_PDF;
1742   else if (aFormatStr == "SVG")
1743     anExpFormat = Graphic3d_EF_SVG;
1744   else if (aFormatStr == "PGF")
1745     anExpFormat = Graphic3d_EF_PGF;
1746   else if (aFormatStr == "EMF")
1747     anExpFormat = Graphic3d_EF_EMF;
1748   else
1749   {
1750     std::cout << "Invalid export format '" << aFormatStr << "'\n";
1751     return 1;
1752   }
1753
1754   if (!V3dView->View()->Export (argv[1], anExpFormat))
1755   {
1756     std::cout << "Export failed!\n";
1757     return 1;
1758   }
1759   return 0;
1760 }
1761
1762 //==============================================================================
1763 //function : VColorScale
1764 //purpose  : representation color scale
1765 //==============================================================================
1766 #include <V3d_ColorScale.hxx>
1767
1768 static int VColorScale (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
1769 {
1770   if ( argc != 1 && argc != 4 && argc != 5 && argc != 6 && argc != 8 )
1771   {
1772     di << "Usage : " << argv[0] << " [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = Right X = 0 Y = 0]  " << "\n";
1773     return 1;
1774   }
1775
1776   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1777   if(aContext.IsNull()) {
1778     di << argv[0] << " ERROR : use 'vinit' command before " << "\n";
1779     return -1;
1780   }
1781
1782   Standard_Real minRange = 0. , maxRange = 100. ;
1783
1784   Standard_Integer numIntervals = 10 ;
1785   Standard_Real textHeight = 16. ;
1786   Aspect_TypeOfColorScalePosition position = Aspect_TOCSP_RIGHT;
1787   Standard_Real X = 0., Y = 0. ;
1788
1789   if ( argc < 9 )
1790   {
1791      if( argc > 3 )
1792      {
1793        minRange = atof( argv[1] );
1794        maxRange = atof( argv[2] );
1795        numIntervals = atoi( argv[3] );
1796      }
1797      if ( argc > 4 )
1798        textHeight = atof( argv[4] );
1799      if ( argc > 5 )
1800        position = (Aspect_TypeOfColorScalePosition)atoi( argv[5] );
1801      if ( argc > 7 )
1802      {
1803        X = atof( argv[6] );
1804        Y = atof( argv[7] );
1805      }
1806   }
1807   Handle(V3d_View) curView = ViewerTest::CurrentView( );
1808   if ( curView.IsNull( ) )
1809     return 1;
1810   Handle(Aspect_ColorScale) aCSV = curView->ColorScale( );
1811   Handle(V3d_ColorScale) aCS = ( Handle( V3d_ColorScale )::DownCast( aCSV ) );
1812   if( ! aCS.IsNull( ) )
1813   {
1814     aCS->SetPosition( X , Y );
1815     aCS->SetHeight( 0.95) ;
1816     aCS->SetTextHeight( textHeight );
1817     aCS->SetRange( minRange , maxRange );
1818     aCS->SetNumberOfIntervals( numIntervals );
1819     aCS->SetLabelPosition( position );
1820     if( !curView->ColorScaleIsDisplayed() )
1821       curView->ColorScaleDisplay( );
1822   }
1823   return 0;
1824 }
1825
1826 //==============================================================================
1827 //function : VGraduatedTrihedron
1828 //purpose  : Displays a graduated trihedron
1829 //==============================================================================
1830
1831 static void AddMultibyteString (TCollection_ExtendedString &name, const char *arg)
1832 {
1833   const char *str = arg;
1834   while (*str)
1835   {
1836     unsigned short c1 = *str++;
1837     unsigned short c2 = *str++;
1838     if (!c1 || !c2) break;
1839     name += (Standard_ExtCharacter)((c1 << 8) | c2);
1840   }
1841 }
1842
1843 static int VGraduatedTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1844 {
1845   // Check arguments
1846   if (argc != 2 && argc < 5)
1847   {
1848     di<<"Error: "<<argv[0]<<" - invalid number of arguments\n";
1849     di<<"Usage: type help "<<argv[0]<<"\n";
1850     return 1; //TCL_ERROR
1851   }
1852
1853   Handle(V3d_View) aV3dView = ViewerTest::CurrentView();
1854
1855   // Create 3D view if it doesn't exist
1856   if ( aV3dView.IsNull() )
1857   {
1858     ViewerTest::ViewerInit(); 
1859     aV3dView = ViewerTest::CurrentView();
1860     if( aV3dView.IsNull() )
1861     {
1862       di << "Error: Cannot create a 3D view\n";
1863       return 1; //TCL_ERROR
1864     }
1865   }
1866
1867   // Erase (==0) or display (!=0)
1868   const int display = atoi(argv[1]);
1869
1870   if (display)
1871   {
1872     // Text font
1873     TCollection_AsciiString font;
1874     if (argc < 6)
1875       font.AssignCat("Courier");
1876     else
1877       font.AssignCat(argv[5]);
1878
1879     // Text is multibyte
1880     const Standard_Boolean isMultibyte = (argc < 7)? Standard_False : (atoi(argv[6]) != 0);
1881
1882     // Set axis names
1883     TCollection_ExtendedString xname, yname, zname;
1884     if (argc >= 5)
1885     {
1886       if (isMultibyte)
1887       {
1888         AddMultibyteString(xname, argv[2]);
1889         AddMultibyteString(yname, argv[3]);
1890         AddMultibyteString(zname, argv[4]);
1891       }
1892       else
1893       {
1894         xname += argv[2];
1895         yname += argv[3];
1896         zname += argv[4];
1897       }
1898     }
1899     else
1900     {
1901       xname += "X (mm)";
1902       yname += "Y (mm)";
1903       zname += "Z (mm)";
1904     }
1905
1906     aV3dView->GraduatedTrihedronDisplay(xname, yname, zname,
1907                                         Standard_True/*xdrawname*/, Standard_True/*ydrawname*/, Standard_True/*zdrawname*/,
1908                                         Standard_True/*xdrawvalues*/, Standard_True/*ydrawvalues*/, Standard_True/*zdrawvalues*/,
1909                                         Standard_True/*drawgrid*/,
1910                                         Standard_True/*drawaxes*/,
1911                                         5/*nbx*/, 5/*nby*/, 5/*nbz*/,
1912                                         10/*xoffset*/, 10/*yoffset*/, 10/*zoffset*/,
1913                                         30/*xaxisoffset*/, 30/*yaxisoffset*/, 30/*zaxisoffset*/,
1914                                         Standard_True/*xdrawtickmarks*/, Standard_True/*ydrawtickmarks*/, Standard_True/*zdrawtickmarks*/,
1915                                         10/*xtickmarklength*/, 10/*ytickmarklength*/, 10/*ztickmarklength*/,
1916                                         Quantity_NOC_WHITE/*gridcolor*/,
1917                                         Quantity_NOC_RED/*xnamecolor*/,Quantity_NOC_GREEN/*ynamecolor*/,Quantity_NOC_BLUE1/*znamecolor*/,
1918                                         Quantity_NOC_RED/*xcolor*/,Quantity_NOC_GREEN/*ycolor*/,Quantity_NOC_BLUE1/*zcolor*/,font);
1919   }
1920   else
1921     aV3dView->GraduatedTrihedronErase();
1922
1923   ViewerTest::GetAISContext()->UpdateCurrentViewer();
1924   aV3dView->Redraw();
1925
1926   return 0;
1927 }
1928
1929 //==============================================================================
1930 //function : VPrintView
1931 //purpose  : Test printing algorithm, print the view to image file with given
1932 //           width and height. Printing implemented only for WNT.
1933 //==============================================================================
1934 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc, 
1935                        const char** argv)
1936 {
1937 #ifndef WNT
1938   di << "Printing implemented only for wnt!\n";
1939   return 1;
1940 #else
1941
1942   Handle(AIS_InteractiveContext) aContextAIS = NULL;
1943   Handle(V3d_View) aView = NULL;
1944   aContextAIS = ViewerTest::GetAISContext();
1945   if (!aContextAIS.IsNull())
1946   {
1947     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
1948     Vwr->InitActiveViews();
1949     if(Vwr->MoreActiveViews())
1950       aView = Vwr->ActiveView();
1951   }
1952
1953   // check for errors
1954   if (aView.IsNull())
1955   {
1956     di << "Call vinit before!\n";
1957     return 1;
1958   }
1959   else if (argc < 4)
1960   {
1961     di << "Use: " << argv[0];
1962     di << " width height filename [print algo=0]\n";
1963     di << "width, height of the intermediate buffer for operation\n";
1964     di << "algo : {0|1}\n";
1965     di << "        0 - stretch algorithm\n";
1966     di << "        1 - tile algorithm\n";
1967     di << "test printing algorithms into an intermediate buffer\n";
1968     di << "with saving output to an image file\n";
1969     return 1;
1970   }
1971
1972   // get the input params
1973   Standard_Integer aWidth  = atoi (argv[1]);
1974   Standard_Integer aHeight = atoi (argv[2]);
1975   Standard_Integer aMode   = 0;
1976   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
1977   if (argc==5)
1978     aMode = atoi (argv[4]);
1979
1980   // check the input parameters
1981   if (aWidth <= 0 || aHeight <= 0)
1982   {
1983     di << "Width and height must be positive values!\n";
1984     return 1;
1985   }
1986   if (aMode != 0 && aMode != 1)
1987     aMode = 0;
1988
1989   Image_CRawBufferData aRawBuffer;
1990   HDC anDC = CreateCompatibleDC(0);
1991
1992   // define compatible bitmap
1993   BITMAPINFO aBitmapData;
1994   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
1995   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
1996   aBitmapData.bmiHeader.biWidth         = aWidth ;
1997   aBitmapData.bmiHeader.biHeight        = aHeight;
1998   aBitmapData.bmiHeader.biPlanes        = 1;
1999   aBitmapData.bmiHeader.biBitCount      = 24;
2000   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
2001   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
2002   aBitmapData.bmiHeader.biClrUsed       = 0;
2003   aBitmapData.bmiHeader.biClrImportant  = 0;
2004   aBitmapData.bmiHeader.biCompression   = BI_RGB;
2005   aBitmapData.bmiHeader.biSizeImage     = 0;
2006
2007   // Create Device Independent Bitmap
2008   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
2009                                             &aRawBuffer.dataPtr, NULL, 0);
2010   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
2011
2012   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
2013   if (aRawBuffer.dataPtr != 0)
2014   {    
2015     if (aMode == 0)
2016       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
2017     else
2018       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_TILE);
2019
2020     // succesfully printed into an intermediate buffer
2021     if (isPrinted)
2022     {
2023       Handle(Image_PixMap) anImageBitmap =
2024                          new Image_PixMap ((Standard_PByte)aRawBuffer.dataPtr,
2025                                            aWidth, aHeight,
2026                                            aWidth*3 + aWidth%4, 24, 0);
2027       isSaved = anImageBitmap->Dump(aFileName.ToCString());
2028     }
2029     else
2030     {
2031       di << "Print operation failed due to printing errors or\n";
2032       di << "insufficient memory available\n";
2033       di << "Please, try to use smaller dimensions for this test\n";
2034       di << "command, as it allocates intermediate buffer for storing\n";
2035       di << "the result\n";
2036     }
2037   }
2038   else
2039   {
2040     di << "Can't allocate memory for intermediate buffer\n";
2041     di << "Please use smaller dimensions\n";
2042   }
2043
2044   if (aMemoryBitmap)
2045   {
2046     SelectObject (anDC, anOldBitmap);
2047     DeleteObject (aMemoryBitmap);
2048     DeleteDC(anDC);
2049   }
2050
2051   if (!isSaved)
2052   {
2053     di << "Save to file operation failed. This operation may fail\n";
2054     di << "if you don't have enough available memory, then you can\n";
2055     di << "use smaller dimensions for the output file\n";
2056     return 1;
2057   }
2058
2059   return 0;
2060
2061 #endif
2062 }
2063
2064 //==============================================================================
2065 //function : VZLayer
2066 //purpose  : Test z layer operations for v3d viewer
2067 //==============================================================================
2068 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2069 {
2070   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
2071   if (aContextAIS.IsNull())
2072   {
2073     di << "Call vinit before!\n";
2074     return 1;
2075   }
2076   else if (argc < 2)
2077   {
2078     di << "Use: vzlayer " << argv[0];
2079     di << " add/del/get [id]\n";
2080     di << " add - add new z layer to viewer and print its id\n";
2081     di << " del - del z layer by its id\n";
2082     di << " get - print sequence of z layers in increasing order of their overlay level\n";
2083     di << "id - the layer identificator value defined when removing z layer\n";
2084     return 1;
2085   }
2086
2087   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
2088   if (aViewer.IsNull())
2089   {
2090     di << "No active viewer!\n";
2091     return 1;
2092   }
2093
2094   // perform operation
2095   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
2096   if (anOp == "add")
2097   {
2098     Standard_Integer aNewId;
2099     if (!aViewer->AddZLayer (aNewId))
2100     {
2101       di << "Impossible to add new z layer!\n";
2102       return 1;
2103     }
2104
2105     di << "New z layer added with index: " << aNewId << "\n";
2106   }
2107   else if (anOp == "del")
2108   {
2109     if (argc < 3)
2110     {
2111       di << "Please also provide as argument id of z layer to remove\n";
2112       return 1;
2113     }
2114
2115     Standard_Integer aDelId = atoi (argv[2]);
2116     if (!aViewer->RemoveZLayer (aDelId))
2117     {
2118       di << "Impossible to remove the z layer or invalid id!\n";
2119       return 1;
2120     }
2121
2122     di << "Z layer " << aDelId << " has been removed\n";
2123   }
2124   else if (anOp == "get")
2125   {
2126     TColStd_SequenceOfInteger anIds;
2127     aViewer->GetAllZLayers (anIds);
2128     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
2129     {
2130       di << anIds.Value (aSeqIdx) << " ";
2131     }
2132
2133     di << "\n";
2134   }
2135   else
2136   {
2137     di << "Invalid operation, please use { add / del / get }\n";
2138     return 1;
2139   }
2140
2141   return 0;
2142 }
2143
2144 //=======================================================================
2145 //function : ViewerCommands
2146 //purpose  :
2147 //=======================================================================
2148
2149 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
2150 {
2151
2152   const char *group = "ZeViewer";
2153   theCommands.Add("vinit" ,
2154     "vinit            : vinit [leftPx topPx widthPx heightPx] : Create the Viewer window",
2155     __FILE__,VInit,group);
2156   theCommands.Add("vhelp" ,
2157     "vhelp            : display help on the viewer commands",
2158     __FILE__,VHelp,group);
2159   theCommands.Add("vtop" ,
2160     "vtop or <T>         : Top view" ,
2161     __FILE__,VTop,group);
2162   theCommands.Add("vaxo" ,
2163     " vaxo or <A>     : Axonometric view ",
2164     __FILE__,VAxo,group);
2165   theCommands.Add("vpick" ,
2166     "vpick           : vpick X Y Z [shape subshape] ( all variables as string )",
2167     VPick,group);
2168   theCommands.Add("vfit"    ,
2169     "vfit or <F>         : vfit",
2170     __FILE__,VFit,group);
2171   theCommands.Add("vzfit"    ,
2172     "vzfit",
2173     __FILE__,VZFit,group);
2174   theCommands.Add("vrepaint",
2175     "vrepaint        : vrepaint, force redraw",
2176     __FILE__,VRepaint,group);
2177   theCommands.Add("vclear",
2178     "vclear          : vclear",
2179     __FILE__,VClear,group);
2180   theCommands.Add("vsetbg",
2181     "vsetbg          : vsetbg imagefile [filltype] : Load image as background",
2182     __FILE__,VSetBg,group);
2183   theCommands.Add("vsetbgmode",
2184     "vsetbgmode      : vsetbgmode filltype : Change background image fill type",
2185     __FILE__,VSetBgMode,group);
2186   theCommands.Add("vsetgradientbg",
2187     "vsetgradientbg  : vsetgradientbg r1 g1 b1 r2 g2 b2 filltype : Mount gradient background",
2188     __FILE__,VSetGradientBg,group);
2189   theCommands.Add("vsetgrbgmode",
2190     "vsetgrbgmode    : vsetgrbgmode filltype : Change gradient background fill type",
2191     __FILE__,VSetGradientBgMode,group);
2192   theCommands.Add("vsetcolorbg",
2193     "vsetcolorbg     : vsetcolorbg r g b : Set background color",
2194     __FILE__,VSetColorBg,group);
2195   theCommands.Add("vscale",
2196     "vscale          : vscale X Y Z",
2197     __FILE__,VScale,group);
2198   theCommands.Add("vzbufftrihedron",
2199     "vzbufftrihedron : Displays a V3d_ZBUFFER'ed trihedron at the bottom left corner of the view",
2200     __FILE__,VTestZBuffTrihedron,group);
2201   theCommands.Add("vrotate",
2202     "vrotate         : vrotate AX AY AZ [X Y Z]",
2203     __FILE__,VRotate,group);
2204   theCommands.Add("vzoom",
2205     "vzoom           : vzoom coef",
2206     __FILE__,VZoom,group);
2207   theCommands.Add("vpan",
2208     "vpan            : vpan dx dy",
2209     __FILE__,VPan,group);
2210   theCommands.Add("vexport",
2211     "vexport         : vexport full_file_path {PS | EPS | TEX | PDF | SVG | PGF | EMF }"
2212     " : exports the view to a vector file of a given format"
2213     " : notice that EMF format requires patched gl2ps",
2214     __FILE__,VExport,group);
2215   theCommands.Add("vcolorscale",
2216     "vcolorscale     : vcolorscale [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = 2 X = 0 Y = 0]: draw color scale",
2217     __FILE__,VColorScale,group);
2218   theCommands.Add("vgraduatedtrihedron",
2219     "vgraduatedtrihedron : 1/0 (display/erase) [Xname Yname Zname [Font [isMultibyte]]]",
2220     __FILE__,VGraduatedTrihedron,group);
2221   theCommands.Add("vprintview" ,
2222     "vprintview : width height filename [algo=0] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
2223     __FILE__,VPrintView,group);
2224   theCommands.Add("vzlayer",
2225     "vzlayer : add/del/get [id] : Z layer operations in v3d viewer: add new z layer, delete z layer, get z layer ids",
2226     __FILE__,VZLayer,group);
2227 }