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