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