60b58c7fec8d3120a5221a75aac9eca51897e482
[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 #include <OpenGl_GlCore20.hxx>
29 #include <AIS_Shape.hxx>
30 #include <AIS_Drawer.hxx>
31 #include <AIS_InteractiveObject.hxx>
32 #include <AIS_ListOfInteractive.hxx>
33 #include <AIS_ListIteratorOfListOfInteractive.hxx>
34 #include <DBRep.hxx>
35 #include <Graphic3d_AspectMarker3d.hxx>
36 #include <Graphic3d_ExportFormat.hxx>
37 #include <Graphic3d_NameOfTextureEnv.hxx>
38 #include <Graphic3d_TextureEnv.hxx>
39 #include <Graphic3d_TextureParams.hxx>
40 #include <Graphic3d_TypeOfTextureFilter.hxx>
41 #include <ViewerTest.hxx>
42 #include <ViewerTest_EventManager.hxx>
43 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
44 #include <Visual3d_View.hxx>
45 #include <Visual3d_ViewManager.hxx>
46 #include <V3d_LayerMgr.hxx>
47 #include <NCollection_DoubleMap.hxx>
48 #include <NCollection_List.hxx>
49 #include <NCollection_Vector.hxx>
50 #include <NIS_View.hxx>
51 #include <NIS_Triangulated.hxx>
52 #include <NIS_InteractiveContext.hxx>
53 #include <AIS_InteractiveContext.hxx>
54 #include <Draw_Interpretor.hxx>
55 #include <Draw.hxx>
56 #include <Draw_Appli.hxx>
57 #include <Aspect_PrintAlgo.hxx>
58 #include <Image_AlienPixMap.hxx>
59 #include <OpenGl_GraphicDriver.hxx>
60 #include <OSD_Timer.hxx>
61 #include <TColStd_SequenceOfInteger.hxx>
62 #include <TColStd_HSequenceOfReal.hxx>
63 #include <TColgp_Array1OfPnt2d.hxx>
64 #include <Visual3d_LayerItem.hxx>
65 #include <V3d_LayerMgr.hxx>
66 #include <V3d_LayerMgrPointer.hxx>
67 #include <Aspect_TypeOfLine.hxx>
68 #include <Image_Diff.hxx>
69 #include <Aspect_DisplayConnection.hxx>
70 #include <Graphic3d.hxx>
71
72 #ifdef WNT
73 #undef DrawText
74 #endif
75
76 #include <Visual3d_Layer.hxx>
77 #include <cstdlib>
78
79 #if defined(_WIN32)
80   #include <WNT_WClass.hxx>
81   #include <WNT_Window.hxx>
82
83   #if defined(_MSC_VER)
84     #define _CRT_SECURE_NO_DEPRECATE
85     #pragma warning (disable:4996)
86   #endif
87 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
88   #include <Cocoa_Window.hxx>
89   #include <tk.h>
90 #else
91   #include <Xw_Window.hxx>
92   #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
93   #include <X11/Xutil.h>
94   #include <tk.h>
95 #endif
96
97 //==============================================================================
98
99 //==============================================================================
100 //  VIEWER GLOBAL VARIABLES
101 //==============================================================================
102
103 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
104
105 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
106 extern const Handle(NIS_InteractiveContext)& TheNISContext();
107 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
108
109 #if defined(_WIN32)
110 static Handle(WNT_Window)& VT_GetWindow() {
111   static Handle(WNT_Window) WNTWin;
112   return WNTWin;
113 }
114 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
115 static Handle(Cocoa_Window)& VT_GetWindow()
116 {
117   static Handle(Cocoa_Window) aWindow;
118   return aWindow;
119 }
120 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
121 extern void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle);
122 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
123
124 #else
125 static Handle(Xw_Window)& VT_GetWindow(){
126   static Handle(Xw_Window) XWWin;
127   return XWWin;
128 }
129
130 static void VProcessEvents(ClientData,int);
131 #endif
132
133 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
134 {
135   static Handle(Aspect_DisplayConnection) aDisplayConnection;
136   return aDisplayConnection;
137 }
138
139 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
140 {
141   GetDisplayConnection() = theDisplayConnection;
142 }
143
144 #if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
145 Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow)
146 {
147   Aspect_Handle aWindowHandle = NULL;
148 #if defined(_WIN32)
149   const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow);
150   if (!aWindow.IsNull())
151     return aWindow->HWindow();
152 #elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
153   const Handle (Xw_Window) aWindow = Handle(Xw_Window)::DownCast (theWindow);
154   if (!aWindow.IsNull())
155   return aWindow->XWindow();
156 #endif
157   return aWindowHandle;
158 }
159 #endif
160
161 static Standard_Boolean MyHLRIsOn = Standard_False;
162
163 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
164 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>  ViewerTest_myContexts;
165 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
166 static OpenGl_Caps ViewerTest_myDefaultCaps;
167
168 #define ZCLIPWIDTH 1.
169
170 static void OSWindowSetup();
171
172 //==============================================================================
173 //  EVENT GLOBAL VARIABLES
174 //==============================================================================
175
176 static int Start_Rot = 0;
177 static int ZClipIsOn = 0;
178 int X_Motion = 0; // Current cursor position
179 int Y_Motion = 0;
180 int X_ButtonPress = 0; // Last ButtonPress position
181 int Y_ButtonPress = 0;
182 Standard_Boolean IsDragged = Standard_False;
183 Standard_Boolean DragFirst;
184
185 //==============================================================================
186
187 #ifdef WNT
188 static LRESULT WINAPI ViewerWindowProc(
189                                        HWND hwnd,
190                                        UINT uMsg,
191                                        WPARAM wParam,
192                                        LPARAM lParam );
193 static LRESULT WINAPI AdvViewerWindowProc(
194   HWND hwnd,
195   UINT uMsg,
196   WPARAM wParam,
197   LPARAM lParam );
198 #endif
199
200
201 //==============================================================================
202 //function : WClass
203 //purpose  :
204 //==============================================================================
205
206 const Handle(MMgt_TShared)& ViewerTest::WClass()
207 {
208   static Handle(MMgt_TShared) theWClass;
209 #if defined(_WIN32)
210   if (theWClass.IsNull())
211   {
212     theWClass = new WNT_WClass ("GW3D_Class", AdvViewerWindowProc,
213       CS_VREDRAW | CS_HREDRAW, 0, 0,
214       ::LoadCursor (NULL, IDC_ARROW));
215   }
216 #endif
217   return theWClass;
218 }
219
220 //==============================================================================
221 //function : CreateName
222 //purpose  : Create numerical name for new object in theMap
223 //==============================================================================
224 template <typename ObjectType>
225 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
226                                     const TCollection_AsciiString& theDefaultString)
227 {
228   if (theObjectMap.IsEmpty())
229     return theDefaultString + TCollection_AsciiString(1);
230
231   Standard_Integer aNextKey = 1;
232   Standard_Boolean isFound = Standard_False;
233   while (!isFound)
234   {
235     TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
236     // Look for objects with default names
237     if (theObjectMap.IsBound1(aStringKey))
238     {
239       aNextKey++;
240     }
241     else
242       isFound = Standard_True;
243   }
244
245   return theDefaultString + TCollection_AsciiString(aNextKey);
246 }
247
248 //==============================================================================
249 //structure : ViewerTest_Names
250 //purpose   : Allow to operate with full view name: driverName/viewerName/viewName
251 //==============================================================================
252 struct ViewerTest_Names
253 {
254 private:
255   TCollection_AsciiString myDriverName;
256   TCollection_AsciiString myViewerName;
257   TCollection_AsciiString myViewName;
258
259 public:
260
261   const TCollection_AsciiString& GetDriverName () const
262   {
263     return myDriverName;
264   }
265   void SetDriverName (const TCollection_AsciiString& theDriverName)
266   {
267     myDriverName = theDriverName;
268   }
269   const TCollection_AsciiString& GetViewerName () const
270   {
271     return myViewerName;
272   }
273   void SetViewerName (const TCollection_AsciiString& theViewerName)
274   {
275     myViewerName = theViewerName;
276   }
277   const TCollection_AsciiString& GetViewName () const
278   {
279     return myViewName;
280   }
281   void SetViewName (const TCollection_AsciiString& theViewName)
282   {
283     myViewName = theViewName;
284   }
285
286   //===========================================================================
287   //function : Constructor for ViewerTest_Names
288   //purpose  : Get view, viewer, driver names from custom string
289   //===========================================================================
290
291   ViewerTest_Names (const TCollection_AsciiString& theInputString)
292   {
293     TCollection_AsciiString aName(theInputString);
294     if (theInputString.IsEmpty())
295     {
296       // Get current configuration
297       if (ViewerTest_myDrivers.IsEmpty())
298         myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
299           (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
300       else
301         myDriverName = ViewerTest_myDrivers.Find2
302         (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
303
304       if(ViewerTest_myContexts.IsEmpty())
305       {
306         myViewerName = CreateName <Handle(AIS_InteractiveContext)>
307           (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
308       }
309       else
310         myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
311
312         myViewName = CreateName <Handle(V3d_View)>
313           (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
314     }
315     else
316     {
317       // There is at least view name
318       Standard_Integer aParserNumber = 0;
319       for (Standard_Integer i = 0; i < 3; ++i)
320       {
321         Standard_Integer aParserPos = aName.SearchFromEnd("/");
322         if(aParserPos != -1)
323         {
324           aParserNumber++;
325           aName.Split(aParserPos-1);
326         }
327         else
328           break;
329       }
330       if (aParserNumber == 0)
331       {
332         // Only view name
333         if (!ViewerTest::GetAISContext().IsNull())
334         {
335           myDriverName = ViewerTest_myDrivers.Find2
336           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
337           myViewerName = ViewerTest_myContexts.Find2
338           (ViewerTest::GetAISContext());
339         }
340         else
341         {
342           // There is no opened contexts here, need to create names for viewer and driver
343           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
344             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
345
346           myViewerName = CreateName <Handle(AIS_InteractiveContext)>
347             (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
348         }
349         myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
350       }
351       else if (aParserNumber == 1)
352       {
353         // Here is viewerName/viewName
354         if (!ViewerTest::GetAISContext().IsNull())
355           myDriverName = ViewerTest_myDrivers.Find2
356           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
357         else
358         {
359           // There is no opened contexts here, need to create name for driver
360           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
361             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
362         }
363         myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
364
365         myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
366       }
367       else
368       {
369         //Here is driverName/viewerName/viewName
370         myDriverName = TCollection_AsciiString(aName);
371
372         TCollection_AsciiString aViewerName(theInputString);
373         aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
374         myViewerName = TCollection_AsciiString(aViewerName);
375
376         myViewName = TCollection_AsciiString(theInputString);
377       }
378     }
379   }
380 };
381
382 //==============================================================================
383 //function : FindContextByView
384 //purpose  : Find AIS_InteractiveContext by View
385 //==============================================================================
386
387 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
388 {
389   Handle(AIS_InteractiveContext) anAISContext;
390
391   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
392        anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
393   {
394     if (anIter.Value()->CurrentViewer() == theView->Viewer())
395        return anIter.Key2();
396   }
397   return anAISContext;
398 }
399
400
401 //==============================================================================
402 //function : SetWindowTitle
403 //purpose  : Set window title
404 //==============================================================================
405
406 void SetWindowTitle (const Handle(Aspect_Window)& theWindow,
407                      Standard_CString theTitle)
408 {
409 #if defined(_WIN32)
410   SetWindowText ((HWND)Handle(WNT_Window)::DownCast(theWindow)->HWindow(),
411     theTitle);
412 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
413   SetCocoaWindowTitle (Handle(Cocoa_Window)::DownCast(theWindow), theTitle);
414 #else
415   if(GetDisplayConnection()->GetDisplay())
416   {
417     Window aWindow =
418       Handle(Xw_Window)::DownCast(theWindow)->XWindow();
419     XStoreName (GetDisplayConnection()->GetDisplay(), aWindow , theTitle);
420   }
421 #endif
422 }
423
424 //==============================================================================
425 //function : IsWindowOverlapped
426 //purpose  : Check if theWindow overlapp another view
427 //==============================================================================
428
429 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
430                                      const Standard_Integer thePxTop,
431                                      const Standard_Integer thePxRight,
432                                      const Standard_Integer thePxBottom,
433                                      TCollection_AsciiString& theViewId)
434 {
435   for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
436       anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
437   {
438     Standard_Integer aTop = 0,
439       aLeft = 0,
440       aRight = 0,
441       aBottom = 0;
442     anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
443     if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
444         (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
445         (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
446         (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
447     {
448       theViewId = anIter.Key1();
449       return Standard_True;
450     }
451   }
452   return Standard_False;
453 }
454
455 // Workaround: to create and delete non-orthographic views outside ViewerTest
456 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
457 {
458   ViewerTest_myViews.UnBind1 (theName);
459 }
460
461 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
462                                const Handle(V3d_View)& theView)
463 {
464   ViewerTest_myViews.Bind (theName, theView);
465 }
466
467 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
468 {
469   return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
470 }
471 //==============================================================================
472 //function : ViewerInit
473 //purpose  : Create the window viewer and initialize all the global variable
474 //==============================================================================
475
476 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
477                                                 const Standard_Integer thePxTop,
478                                                 const Standard_Integer thePxWidth,
479                                                 const Standard_Integer thePxHeight,
480                                                 Standard_CString theViewName,
481                                                 Standard_CString theDisplayName)
482 {
483   // Default position and dimension of the viewer window.
484   // Note that left top corner is set to be sufficiently small to have
485   // window fit in the small screens (actual for remote desktops, see #23003).
486   // The position corresponds to the window's client area, thus some
487   // gap is added for window frame to be visible.
488   Standard_Integer aPxLeft   = 20;
489   Standard_Integer aPxTop    = 40;
490   Standard_Integer aPxWidth  = 409;
491   Standard_Integer aPxHeight = 409;
492   Standard_Boolean toCreateViewer = Standard_False;
493
494   Handle(OpenGl_GraphicDriver) aGraphicDriver;
495   ViewerTest_Names aViewNames(theViewName);
496   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
497     aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
498
499   if (thePxLeft != 0)
500     aPxLeft = thePxLeft;
501   if (thePxTop != 0)
502     aPxTop = thePxTop;
503   if (thePxWidth != 0)
504     aPxWidth = thePxWidth;
505   if (thePxHeight != 0)
506     aPxHeight = thePxHeight;
507  
508   // Get graphic driver (create it or get from another view)
509   if (!ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName()))
510   {
511     // Get connection string
512   #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
513     TCollection_AsciiString aDisplayName(theDisplayName);
514     if (!aDisplayName.IsEmpty())
515       SetDisplayConnection (new Aspect_DisplayConnection ());
516     else
517       SetDisplayConnection (new Aspect_DisplayConnection (aDisplayName));
518   #else
519     (void)theDisplayName; // avoid warning on unused argument
520     SetDisplayConnection (new Aspect_DisplayConnection ());
521   #endif
522     aGraphicDriver = new OpenGl_GraphicDriver();
523     aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
524     aGraphicDriver->Begin (GetDisplayConnection());
525     ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
526     toCreateViewer = Standard_True;
527   }
528   else
529   {
530     aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
531   }
532
533   //Dispose the window if input parameters are default
534   if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
535   {
536     Standard_Integer aTop = 0,
537                      aLeft = 0,
538                      aRight = 0,
539                      aBottom = 0,
540                      aScreenWidth = 0,
541                      aScreenHeight = 0;
542
543     // Get screen resolution
544 #if defined(_WIN32) || defined(__WIN32__)
545     RECT aWindowSize;
546     GetClientRect(GetDesktopWindow(), &aWindowSize);
547     aScreenHeight = aWindowSize.bottom;
548     aScreenWidth = aWindowSize.right;
549 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
550     GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
551 #else
552     Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
553     aScreenWidth = WidthOfScreen(aScreen);
554     aScreenHeight = HeightOfScreen(aScreen);
555 #endif
556
557     TCollection_AsciiString anOverlappedViewId("");
558
559     while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
560     {
561       ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
562
563       if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
564         && aRight + 2*aPxWidth + 40 > aScreenWidth)
565       {
566         if (aBottom + aPxHeight + 40 > aScreenHeight)
567         {
568           aPxLeft = 20;
569           aPxTop = 40;
570           break;
571         }
572         aPxLeft = 20;
573         aPxTop = aBottom + 40;
574       }
575       else
576         aPxLeft = aRight + 20;
577     }
578   }
579
580   // Get viewer name
581   TCollection_AsciiString aTitle("3D View - ");
582   aTitle = aTitle + aViewNames.GetViewName() + "(*)";
583
584   // Change name of current active window
585   if (!ViewerTest::CurrentView().IsNull())
586   {
587     TCollection_AsciiString aTitle("3D View - ");
588     aTitle = aTitle
589       + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
590     SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
591   }
592
593   // Create viewer
594   Handle(V3d_Viewer) a3DViewer, a3DCollector;
595   // If it's the single view, we first look for empty context
596   if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
597   {
598     NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
599       anIter(ViewerTest_myContexts);
600     if (anIter.More())
601       ViewerTest::SetAISContext (anIter.Value());
602     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
603     a3DCollector= ViewerTest::GetAISContext()->Collector();
604   }
605   else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
606   {
607     ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
608     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
609     a3DCollector= ViewerTest::GetAISContext()->Collector();
610   }
611   else if (a3DViewer.IsNull() || a3DCollector.IsNull())
612   {
613     toCreateViewer = Standard_True;
614     TCollection_ExtendedString NameOfWindow("Viewer3D");
615     a3DViewer = new V3d_Viewer(aGraphicDriver, NameOfWindow.ToExtString());
616
617     NameOfWindow = TCollection_ExtendedString("Collector");
618     a3DCollector = new V3d_Viewer(aGraphicDriver, NameOfWindow.ToExtString());
619
620     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
621     a3DCollector->SetDefaultBackgroundColor(Quantity_NOC_STEELBLUE);
622   }
623
624   // AIS context setup
625   if (ViewerTest::GetAISContext().IsNull() ||
626       !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
627   {
628     Handle(AIS_InteractiveContext) aContext =
629       new AIS_InteractiveContext(a3DViewer, a3DCollector);
630     ViewerTest::SetAISContext (aContext);
631     ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
632   }
633   else
634     ViewerTest::ResetEventManager();
635
636   // Create window
637 #if defined(_WIN32) || defined(__WIN32__)
638       VT_GetWindow() = new WNT_Window (aTitle.ToCString(),
639                                        Handle(WNT_WClass)::DownCast (WClass()),
640                                        WS_OVERLAPPEDWINDOW,
641                                        aPxLeft, aPxTop,
642                                        aPxWidth, aPxHeight,
643                                        Quantity_NOC_BLACK);
644 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
645       VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
646                                          aPxLeft, aPxTop,
647                                          aPxWidth, aPxHeight);
648       ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
649 #else
650       VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
651                                       aTitle.ToCString(),
652                                       aPxLeft, aPxTop,
653                                       aPxWidth, aPxHeight);
654 #endif
655   VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
656
657   // NIS setup
658   Handle(NIS_View) aView = new NIS_View (a3DViewer, VT_GetWindow());
659   
660   ViewerTest::CurrentView(aView);
661   ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
662   TheNISContext()->AttachView (aView);
663
664   // Setup for X11 or NT
665   OSWindowSetup();
666
667   // Set parameters for V3d_View and V3d_Viewer
668   const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
669   aV3dView->SetComputedMode(Standard_False);
670   MyHLRIsOn = aV3dView->ComputedMode();
671   aV3dView->SetZClippingDepth(0.5);
672   aV3dView->SetZClippingWidth(ZCLIPWIDTH/2.);
673
674   a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
675   if (toCreateViewer)
676   {
677     a3DViewer->SetDefaultLights();
678     a3DViewer->SetLightOn();
679   }
680
681   #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
682   #if TCL_MAJOR_VERSION  < 8
683   Tk_CreateFileHandler((void*)XConnectionNumber(GetDisplayConnection()->GetDisplay()),
684       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
685   #else
686   Tk_CreateFileHandler(XConnectionNumber(GetDisplayConnection()->GetDisplay()),
687       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
688   #endif
689   #endif
690
691   VT_GetWindow()->Map();
692   
693   // Set the handle of created view in the event manager
694   ViewerTest::ResetEventManager();
695
696   ViewerTest::CurrentView()->Redraw();
697
698   aView.Nullify();
699   a3DViewer.Nullify();
700   a3DCollector.Nullify();
701
702   return aViewNames.GetViewName();
703 }
704
705 //==============================================================================
706 //function : SplitParameter
707 //purpose  : Split parameter string to parameter name an patameter value
708 //==============================================================================
709 Standard_Boolean SplitParameter (const TCollection_AsciiString& theString,
710                                       TCollection_AsciiString& theName,
711                                       TCollection_AsciiString& theValue)
712 {
713   Standard_Integer aParamNameEnd = theString.FirstLocationInSet("=",1, theString.Length());
714   if (aParamNameEnd == 0)
715     return Standard_False;
716   TCollection_AsciiString aString(theString);
717   if (aParamNameEnd != 0)
718   {
719     theValue = aString.Split(aParamNameEnd);
720     aString.Split(aString.Length()-1);
721     theName = aString;
722   }
723   return Standard_True;
724 }
725
726 //==============================================================================
727 //function : Vinit
728 //purpose  : Create the window viewer and initialize all the global variable
729 //    Use Tk_CreateFileHandler on UNIX to cath the X11 Viewer event
730 //==============================================================================
731
732 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
733 {
734 if (theArgsNb > 9)
735   {
736     theDi << theArgVec[0] << ": incorrect number of command arguments.\n"
737       << "Type help for more information.\n";
738     return 1;
739   }
740   TCollection_AsciiString aViewName (""),
741                           aDisplayName ("");
742   Standard_Integer aPxLeft = 0,
743                   aPxTop = 0,
744                   aPxWidth = 0,
745                   aPxHeight = 0;
746
747   for (Standard_Integer i = 1; i < theArgsNb; ++i)
748   {
749     TCollection_AsciiString aName = "", aValue = "";
750     if(!SplitParameter (TCollection_AsciiString(theArgVec[i]),aName,aValue) && theArgsNb == 2)
751     {
752       // In case of syntax: vinit ViewName
753       aViewName = theArgVec[1];
754     }
755     else
756     {
757       if (aName == "name")
758       {
759         aViewName = aValue;
760       }
761       else if (aName == "l" || aName == "left")
762         aPxLeft = aValue.IntegerValue();
763       else if (aName == "t" || aName == "top")
764         aPxTop = aValue.IntegerValue();
765 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
766       else if (aName == "display")
767         aDisplayName = aValue;
768 #endif
769       else if (aName == "w" || aName == "width")
770         aPxWidth = aValue.IntegerValue();
771       else if (aName == "h" || aName == "height")
772         aPxHeight = aValue.IntegerValue();
773       else
774       {
775         theDi << theArgVec[0] << ": Warning: unknown parameter " << aName.ToCString() << ".\n";
776       }
777     }
778   }
779
780   ViewerTest_Names aViewNames (aViewName);
781   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
782   {
783     TCollection_AsciiString aCommand("vactivate ");
784     aCommand = aCommand + aViewNames.GetViewName();
785     theDi.Eval(aCommand.ToCString());
786     return 0;
787   }
788
789   TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
790                                                             aViewName.ToCString(),
791                                                             aDisplayName.ToCString());
792   cout << theArgVec[0] << ": 3D View - " << aViewId << " was created.\n";
793   return 0;
794 }
795
796 //==============================================================================
797 //function : VHLR
798 //purpose  : hidden lines removal algorithm
799 //==============================================================================
800
801 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
802 {
803   if (ViewerTest::CurrentView().IsNull())
804   {
805     di << argv[0] << ": Call vinit before this command, please.\n";
806     return 1;
807   }
808
809   if (argc != 2)
810   {
811     di << argv[0] << ": Wrong number of command arguments.\n"
812       << "Type help " << argv[0] << " for more information.\n";
813     return 1;
814   }
815
816   Standard_Boolean isHLROn =
817     (!strcasecmp (argv[1], "on")) ? Standard_True : Standard_False;
818
819   if (isHLROn == MyHLRIsOn)
820   {
821     return 0;
822   }
823
824   MyHLRIsOn = isHLROn;
825   ViewerTest::CurrentView()->SetComputedMode (MyHLRIsOn);
826
827   return 0;
828 }
829
830 //==============================================================================
831 //function : VHLRType
832 //purpose  : change type of using HLR algorithm
833 //==============================================================================
834
835 static int VHLRType (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
836 {
837   if (ViewerTest::CurrentView().IsNull())
838   {
839     di << argv[0] << ": Call vinit before this command, please.\n";
840     return 1;
841   }
842
843   if (argc < 2)
844   {
845     di << argv[0] << ": Wrong number of command arguments.\n"
846       << "Type help " << argv[0] << " for more information.\n";
847     return 1;
848   }
849
850   Prs3d_TypeOfHLR aTypeOfHLR =
851     (!strcasecmp (argv[1], "algo")) ? Prs3d_TOH_Algo : Prs3d_TOH_PolyAlgo;
852
853   if (argc == 2)
854   {
855     AIS_ListOfInteractive aListOfShapes;
856     ViewerTest::GetAISContext()->DisplayedObjects (aListOfShapes);
857     ViewerTest::GetAISContext()->DefaultDrawer()->SetTypeOfHLR(aTypeOfHLR);
858     for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
859       anIter.More(); anIter.Next())
860     {
861       Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
862       if (aShape.IsNull())
863         continue;
864       if (aShape->TypeOfHLR() != aTypeOfHLR)
865         aShape->SetTypeOfHLR (aTypeOfHLR);
866       if (MyHLRIsOn)
867         aShape->Redisplay();
868     }
869     ViewerTest::CurrentView()->Update();
870     return 0;
871   }
872   else
873   {
874     for (Standard_Integer i = 2; i < argc; ++i)
875     {
876       ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
877       TCollection_AsciiString aName (argv[i]);
878
879       if (!aMap.IsBound2 (aName))
880       {
881         di << argv[0] << ":" << " Wrong shape name:" << aName.ToCString() << ".\n";
882         continue;
883       }
884       Handle(AIS_Shape) anAISObject =
885         Handle(AIS_Shape)::DownCast (aMap.Find2(aName));
886       if (anAISObject.IsNull())
887         continue;
888       anAISObject->SetTypeOfHLR (aTypeOfHLR);
889       if (MyHLRIsOn)
890         anAISObject->Redisplay();
891     }
892     ViewerTest::CurrentView()->Update();
893   }
894
895   return 0;
896 }
897
898 //==============================================================================
899 //function : FindViewIdByWindowHandle
900 //purpose  : Find theView Id in the map of views by window handle
901 //==============================================================================
902 #if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
903 TCollection_AsciiString FindViewIdByWindowHandle(const Aspect_Handle theWindowHandle)
904 {
905   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
906        anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
907   {
908     Aspect_Handle aWindowHandle = GetWindowHandle(anIter.Value()->Window());
909     if (aWindowHandle == theWindowHandle)
910       return anIter.Key1();
911   }
912   return TCollection_AsciiString("");
913 }
914 #endif
915
916 //==============================================================================
917 //function : ActivateView
918 //purpose  : Make the view active
919 //==============================================================================
920
921 void ActivateView (const TCollection_AsciiString& theViewName)
922 {
923   const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
924   if (!aView.IsNull())
925   {
926     Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
927     if (!anAISContext.IsNull())
928     {
929       if (!ViewerTest::CurrentView().IsNull())
930       {
931         TCollection_AsciiString aTitle("3D View - ");
932         aTitle = aTitle + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
933         SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
934       }
935
936       ViewerTest::CurrentView (aView);
937       // Update degenerate mode
938       MyHLRIsOn = ViewerTest::CurrentView()->ComputedMode();
939       ViewerTest::SetAISContext (anAISContext);
940       TCollection_AsciiString aTitle = TCollection_AsciiString("3D View - ");
941       aTitle = aTitle + theViewName + "(*)";
942       SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
943 #if defined(_WIN32) || defined(__WIN32__)
944       VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
945 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
946       VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
947 #else
948       VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
949 #endif
950       SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
951       ViewerTest::CurrentView()->Redraw();
952     }
953   }
954 }
955
956 //==============================================================================
957 //function : RemoveView
958 //purpose  : Close and remove view from display, clear maps if neccessary
959 //==============================================================================
960 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
961 {
962   if (!ViewerTest_myViews.IsBound1(theViewName))
963   {
964     cout << "Wrong view name\n";
965     return;
966   }
967
968   // Activate another view if it's active now
969   if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
970   {
971     if (ViewerTest_myViews.Extent() > 1)
972     {
973       TCollection_AsciiString aNewViewName;
974       for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> :: Iterator
975            anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
976         if (anIter.Key1() != theViewName)
977         {
978           aNewViewName = anIter.Key1();
979           break;
980         }
981         ActivateView (aNewViewName);
982     }
983     else
984     {
985       Handle(V3d_View) anEmptyView;
986 #if defined(_WIN32) || defined(__WIN32__)
987       Handle(WNT_Window) anEmptyWindow;
988 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
989       Handle(Cocoa_Window) anEmptyWindow;
990 #else
991       Handle(Xw_Window) anEmptyWindow;
992 #endif
993       VT_GetWindow() = anEmptyWindow;
994       ViewerTest::CurrentView (anEmptyView);
995       if (isContextRemoved)
996       {
997         Handle(AIS_InteractiveContext) anEmptyContext;
998         ViewerTest::SetAISContext(anEmptyContext);
999       }
1000     }
1001   }
1002
1003   // Delete view
1004   Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1005   Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1006
1007   // Remove view resources
1008   TheNISContext()->DetachView(Handle(NIS_View)::DownCast(aView));
1009   ViewerTest_myViews.UnBind1(theViewName);
1010   aView->Remove();
1011
1012 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1013   XFlush (GetDisplayConnection()->GetDisplay());
1014 #endif
1015
1016   // Keep context opened only if the closed view is last to avoid
1017   // unused empty contexts
1018   if (!aCurrentContext.IsNull())
1019   {
1020     // Check if there are more difined views in the viewer
1021     aCurrentContext->CurrentViewer()->InitDefinedViews();
1022     if ((isContextRemoved || ViewerTest_myContexts.Size() != 1) && !aCurrentContext->CurrentViewer()->MoreDefinedViews())
1023     {
1024       // Remove driver if there is no viewers that use it
1025       Standard_Boolean isRemoveDriver = Standard_True;
1026       for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1027           anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1028       {
1029         if (aCurrentContext != anIter.Key2() &&
1030           aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
1031         {
1032           isRemoveDriver = Standard_False;
1033           break;
1034         }
1035       }
1036       if(isRemoveDriver)
1037       {
1038         ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1039       #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1040         #if TCL_MAJOR_VERSION  < 8
1041         Tk_DeleteFileHandler((void*)XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1042         #else
1043         Tk_DeleteFileHandler(XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1044         #endif
1045       #endif
1046       }
1047
1048       ViewerTest_myContexts.UnBind2(aCurrentContext);
1049     }
1050   }
1051   cout << "3D View - " << theViewName << " was deleted.\n";
1052
1053 }
1054
1055 //==============================================================================
1056 //function : VClose
1057 //purpose  : Remove the view defined by its name
1058 //==============================================================================
1059
1060 static int VClose (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1061 {
1062   if (theArgsNb < 2)
1063   {
1064     theDi << theArgVec[0] << ": incorrect number of command arguments.\n"
1065       << "Type help " << theArgVec[0] << " for more information.\n";
1066     return 1;
1067   }
1068
1069   if (ViewerTest_myViews.IsEmpty())
1070   {
1071     theDi << theArgVec[0] <<": there is no views to close.\n";
1072     return 0;
1073   }
1074
1075   TCollection_AsciiString anInputString(theArgVec[1]);
1076   
1077   // Create list to iterate and remove views from the map of views
1078   NCollection_List<TCollection_AsciiString> aViewList;
1079   if ( strcasecmp( anInputString.ToCString(), "ALL" ) == 0 )
1080   {
1081     for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter(ViewerTest_myViews);
1082          anIter.More(); anIter.Next())
1083     {
1084       aViewList.Append(anIter.Key1());
1085     }
1086   }
1087   else
1088   {
1089     ViewerTest_Names aViewNames(anInputString);
1090     aViewList.Append(aViewNames.GetViewName());
1091   }
1092
1093   Standard_Boolean isContextRemoved = (theArgsNb == 3 && atoi(theArgVec[2])==1) ? Standard_False : Standard_True;
1094   for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1095        anIter.More(); anIter.Next())
1096   {
1097     ViewerTest::RemoveView(anIter.Value(), isContextRemoved);
1098   }
1099
1100   return 0;
1101 }
1102
1103 //==============================================================================
1104 //function : VActivate
1105 //purpose  : Activate the view defined by its ID
1106 //==============================================================================
1107
1108 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1109 {
1110   if (theArgsNb > 2)
1111   {
1112     theDi << theArgVec[0] << ": wrong number of command arguments.\n"
1113     << "Usage: " << theArgVec[0] << " ViewID\n";
1114     return 1;
1115   }
1116   if(theArgsNb == 1)
1117   {
1118     theDi.Eval("vviewlist");
1119     return 0;
1120   }
1121
1122   TCollection_AsciiString aNameString(theArgVec[1]);
1123   if ( strcasecmp( aNameString.ToCString(), "NONE" ) == 0 )
1124   {
1125     TCollection_AsciiString aTitle("3D View - ");
1126     aTitle = aTitle + ViewerTest_myViews.Find2(ViewerTest::CurrentView());
1127     SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1128     Handle(V3d_View) anEmptyView;
1129 #if defined(_WIN32) || defined(__WIN32__)
1130     Handle(WNT_Window) anEmptyWindow;
1131 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1132     Handle(Cocoa_Window) anEmptyWindow;
1133 #else
1134     Handle(Xw_Window) anEmptyWindow;
1135 #endif
1136     VT_GetWindow() = anEmptyWindow;
1137     ViewerTest::CurrentView (anEmptyView);
1138     ViewerTest::ResetEventManager();
1139     theDi << theArgVec[0] << ": all views are inactive\n";
1140     return 0;
1141   }
1142
1143   ViewerTest_Names aViewNames(aNameString);
1144
1145   // Check if this view exists in the viewer with the driver
1146   if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1147   {
1148     theDi << "Wrong view name\n";
1149     return 1;
1150   }
1151
1152   // Check if it is active already
1153   if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1154   {
1155     theDi << theArgVec[0] << ": the view is active already\n";
1156     return 0;
1157   }
1158
1159   ActivateView (aViewNames.GetViewName());
1160   return 0;
1161 }
1162
1163 //==============================================================================
1164 //function : VViewList
1165 //purpose  : Print current list of views per viewer and graphic driver ID
1166 //           shared between viewers
1167 //==============================================================================
1168
1169 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1170 {
1171   if (theArgsNb > 2)
1172   {
1173     theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1174           << "Usage: " << theArgVec[0] << " name";
1175     return 1;
1176   }
1177   if (ViewerTest_myContexts.Size() < 1)
1178     return 0;
1179
1180   Standard_Boolean isTreeView =
1181     (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1182
1183   if (isTreeView)
1184     theDi << theArgVec[0] <<":\n";
1185
1186     for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
1187       aDriverIter(ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
1188     {
1189       if (isTreeView)
1190         theDi << aDriverIter.Key1() << ":\n";
1191
1192       for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1193         aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1194       {
1195         if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1196         {
1197           if (isTreeView)
1198           {
1199             TCollection_AsciiString aContextName(aContextIter.Key1());
1200             theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":" << "\n";
1201           }
1202
1203           for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1204             aViewIter(ViewerTest_myViews); aViewIter.More(); aViewIter.Next())
1205           {
1206             if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1207             {
1208               TCollection_AsciiString aViewName(aViewIter.Key1());
1209               if (isTreeView)
1210               {
1211                 if (aViewIter.Value() == ViewerTest::CurrentView())
1212                   theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)" << "\n";
1213                 else
1214                   theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1215               }
1216               else
1217               {
1218                 theDi << aViewName << " ";
1219               }
1220             }
1221           }
1222         }
1223       }
1224     }
1225   return 0;
1226 }
1227
1228 //==============================================================================
1229 //function : VT_ProcessKeyPress
1230 //purpose  : Handle KeyPress event from a CString
1231 //==============================================================================
1232 void VT_ProcessKeyPress (const char* buf_ret)
1233 {
1234   //cout << "KeyPress" << endl;
1235   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1236   const Handle(NIS_View) aNisView = Handle(NIS_View)::DownCast (aView);
1237   // Letter in alphabetic order
1238
1239   if ( !strcasecmp(buf_ret, "A") ) {
1240     // AXO
1241     aView->SetProj(V3d_XposYnegZpos);
1242   }
1243   else if ( !strcasecmp(buf_ret, "D") ) {
1244     // Reset
1245     aView->Reset();
1246   }
1247   else if ( !strcasecmp(buf_ret, "F") ) {
1248     // FitAll
1249     if (aNisView.IsNull())
1250       aView->FitAll();
1251     else
1252       aNisView->FitAll3d();
1253   }
1254   else if ( !strcasecmp(buf_ret, "H") ) {
1255     // HLR
1256     cout << "HLR" << endl;
1257     aView->SetComputedMode (!aView->ComputedMode());
1258     MyHLRIsOn = aView->ComputedMode();
1259   }
1260   else if ( !strcasecmp(buf_ret, "P") ) {
1261     // Type of HLR
1262     Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1263     if (aContext->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo)
1264       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_PolyAlgo);
1265     else
1266       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_Algo);
1267     if (aContext->NbCurrents()==0 || aContext->NbSelected() == 0)
1268     {
1269       AIS_ListOfInteractive aListOfShapes;
1270       aContext->DisplayedObjects(aListOfShapes);
1271       for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
1272         anIter.More(); anIter.Next())
1273       {
1274         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1275         if (aShape.IsNull())
1276           continue;
1277         if (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1278           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1279         else
1280           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1281         aShape->Redisplay();
1282       }
1283     }
1284     else
1285     {
1286       for (aContext->InitCurrent();aContext->MoreCurrent();aContext->NextCurrent())
1287       {
1288         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aContext->Current());
1289         if (aShape.IsNull())
1290           continue;
1291         if(aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1292           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1293         else
1294           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1295         aShape->Redisplay();
1296       }
1297     }
1298
1299     aContext->UpdateCurrentViewer();
1300     
1301   }
1302   else if ( !strcasecmp(buf_ret, "S") ) {
1303     // SHADING
1304     cout << "passage en mode 1 (shading pour les shapes)" << endl;
1305
1306     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1307     if(Ctx->NbCurrents()==0 ||
1308       Ctx->NbSelected()==0)
1309       Ctx->SetDisplayMode(AIS_Shaded);
1310     else{
1311       if(Ctx->HasOpenedContext()){
1312         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1313           Ctx->SetDisplayMode(Ctx->Interactive(),1,Standard_False);
1314       }
1315       else{
1316         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
1317           Ctx->SetDisplayMode(Ctx->Current(),1,Standard_False);
1318       }
1319       Ctx->UpdateCurrentViewer();
1320     }
1321   }
1322   else if ( !strcasecmp(buf_ret, "U") ) {
1323     // Unset display mode
1324     cout<<"passage au mode par defaut"<<endl;
1325
1326     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1327     if(Ctx->NbCurrents()==0 ||
1328       Ctx->NbSelected()==0)
1329       Ctx->SetDisplayMode(AIS_WireFrame);
1330     else{
1331       if(Ctx->HasOpenedContext()){
1332         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1333           Ctx->UnsetDisplayMode(Ctx->Interactive(),Standard_False);
1334       }
1335       else{
1336         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
1337           Ctx->UnsetDisplayMode(Ctx->Current(),Standard_False);
1338       }
1339       Ctx->UpdateCurrentViewer();
1340     }
1341
1342   }
1343   else if ( !strcasecmp(buf_ret, "T") ) {
1344     // Top
1345     aView->SetProj(V3d_Zpos);
1346   }
1347   else if ( !strcasecmp(buf_ret, "B") ) {
1348     // Bottom
1349     aView->SetProj(V3d_Zneg);
1350   }
1351   else if ( !strcasecmp(buf_ret, "L") ) {
1352     // Left
1353     aView->SetProj(V3d_Xneg);
1354   }
1355   else if ( !strcasecmp(buf_ret, "R") ) {
1356     // Right
1357     aView->SetProj(V3d_Xpos);
1358   }
1359
1360   else if ( !strcasecmp(buf_ret, "W") ) {
1361     // WIREFRAME
1362     cout << "passage en mode 0 (filaire pour les shapes)" << endl;
1363     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1364     if(Ctx->NbCurrents()==0 ||
1365       Ctx->NbSelected()==0)
1366       Ctx->SetDisplayMode(AIS_WireFrame);
1367     else{
1368       if(Ctx->HasOpenedContext()){
1369         for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1370           Ctx->SetDisplayMode(Ctx->Interactive(),0,Standard_False);
1371       }
1372       else{
1373         for(Ctx->InitCurrent();Ctx->MoreCurrent();Ctx->NextCurrent())
1374           Ctx->SetDisplayMode(Ctx->Current(),0,Standard_False);
1375       }
1376       Ctx->UpdateCurrentViewer();
1377     }
1378   }
1379   else if ( !strcasecmp(buf_ret, "Z") ) {
1380     // ZCLIP
1381
1382     if ( ZClipIsOn ) {
1383       cout << "ZClipping OFF" << endl;
1384       ZClipIsOn = 0;
1385
1386       aView->SetZClippingType(V3d_OFF);
1387       aView->Redraw();
1388     }
1389     else {
1390       cout << "ZClipping ON" << endl;
1391       ZClipIsOn = 1;
1392
1393       aView->SetZClippingType(V3d_FRONT);
1394       aView->Redraw();
1395     }
1396   }
1397   else if ( !strcasecmp(buf_ret, ",") ) {
1398     ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
1399
1400
1401   }
1402   else if ( !strcasecmp(buf_ret, ".") ) {
1403     ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
1404   }
1405   // Number
1406   else{
1407     Standard_Integer Num = Draw::Atoi(buf_ret);
1408     if(Num>=0 && Num<=7)
1409       ViewerTest::StandardModeActivation(Num);
1410   }
1411 }
1412
1413 //==============================================================================
1414 //function : VT_ProcessExpose
1415 //purpose  : Redraw the View on an Expose Event
1416 //==============================================================================
1417 void VT_ProcessExpose()
1418 {
1419   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1420   if (!aView3d.IsNull())
1421   {
1422     aView3d->Redraw();
1423   }
1424 }
1425
1426 //==============================================================================
1427 //function : VT_ProcessConfigure
1428 //purpose  : Resize the View on an Configure Event
1429 //==============================================================================
1430 void VT_ProcessConfigure()
1431 {
1432   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1433   if (aView3d.IsNull())
1434   {
1435     return;
1436   }
1437
1438   aView3d->MustBeResized();
1439   aView3d->Update();
1440   aView3d->Redraw();
1441 }
1442
1443 //==============================================================================
1444 //function : VT_ProcessButton1Press
1445 //purpose  : Picking
1446 //==============================================================================
1447 Standard_Boolean VT_ProcessButton1Press(
1448   Standard_Integer ,
1449   const char**     argv,
1450   Standard_Boolean pick,
1451   Standard_Boolean shift)
1452 {
1453   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1454   if ( pick ) {
1455     Standard_Real X, Y, Z;
1456
1457     ViewerTest::CurrentView()->Convert(X_Motion, Y_Motion, X, Y, Z);
1458
1459     Draw::Set(argv[1], X);
1460     Draw::Set(argv[2], Y);
1461     Draw::Set(argv[3], Z);}
1462
1463   if(shift)
1464     EM->ShiftSelect();
1465   else
1466     EM->Select();
1467
1468   pick = 0;
1469   return pick;
1470 }
1471
1472 //==============================================================================
1473 //function : VT_ProcessButton1Release
1474 //purpose  : End selecting
1475 //==============================================================================
1476 void VT_ProcessButton1Release (Standard_Boolean theIsShift)
1477 {
1478   if (IsDragged)
1479   {
1480     IsDragged = Standard_False;
1481     Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1482     if (theIsShift)
1483     {
1484       EM->ShiftSelect (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
1485                        Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
1486     }
1487     else
1488     {
1489       EM->Select (Min (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
1490                   Max (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion));
1491     }
1492   }
1493 }
1494
1495 //==============================================================================
1496 //function : VT_ProcessButton3Press
1497 //purpose  : Start Rotation
1498 //==============================================================================
1499 void VT_ProcessButton3Press()
1500 {
1501   Start_Rot = 1;
1502   if (MyHLRIsOn)
1503   {
1504     ViewerTest::CurrentView()->SetComputedMode (Standard_False);
1505   }
1506   ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
1507 }
1508
1509 //==============================================================================
1510 //function : VT_ProcessButton3Release
1511 //purpose  : End rotation
1512 //==============================================================================
1513 void VT_ProcessButton3Release()
1514 {
1515   if (Start_Rot)
1516   {
1517     Start_Rot = 0;
1518     if (MyHLRIsOn)
1519     {
1520       ViewerTest::CurrentView()->SetComputedMode (Standard_True);
1521     }
1522   }
1523 }
1524
1525 //==============================================================================
1526 //function : ProcessZClipMotion
1527 //purpose  : Zoom
1528 //==============================================================================
1529
1530 void ProcessZClipMotion()
1531 {
1532   Handle(V3d_View)  a3DView = ViewerTest::CurrentView();
1533   if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
1534     static Standard_Real CurZPos = 0.;
1535
1536     //Quantity_Length VDX, VDY;
1537     //a3DView->Size(VDX,VDY);
1538     //Standard_Real VDZ = a3DView->ZSize();
1539     //printf("View size (%lf,%lf,%lf)\n", VDX, VDY, VDZ);
1540
1541     Quantity_Length dx = a3DView->Convert(X_Motion - X_ButtonPress);
1542
1543     // Front = Depth + width/2.
1544     Standard_Real D = 0.5;
1545     Standard_Real W = 0.1;
1546
1547     CurZPos += (dx);
1548
1549     D += CurZPos;
1550
1551     //printf("dx %lf Depth %lf Width %lf\n", dx, D, W);
1552
1553     a3DView->SetZClippingType(V3d_OFF);
1554     a3DView->SetZClippingDepth(D);
1555     a3DView->SetZClippingWidth(W);
1556     a3DView->SetZClippingType(V3d_FRONT);
1557
1558     a3DView->Redraw();
1559
1560     X_ButtonPress = X_Motion;
1561     Y_ButtonPress = Y_Motion;
1562   }
1563 }
1564
1565 //==============================================================================
1566 //function : ProcessControlButton1Motion
1567 //purpose  : Zoom
1568 //==============================================================================
1569
1570 static void ProcessControlButton1Motion()
1571 {
1572   ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
1573
1574   X_ButtonPress = X_Motion;
1575   Y_ButtonPress = Y_Motion;
1576 }
1577
1578 //==============================================================================
1579 //function : VT_ProcessControlButton2Motion
1580 //purpose  : Panning
1581 //==============================================================================
1582 void VT_ProcessControlButton2Motion()
1583 {
1584   Quantity_Length dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
1585   Quantity_Length dy = ViewerTest::CurrentView()->Convert(Y_Motion - Y_ButtonPress);
1586
1587   dy = -dy; // Xwindow Y axis is from top to Bottom
1588
1589   ViewerTest::CurrentView()->Panning( dx, dy );
1590
1591   X_ButtonPress = X_Motion;
1592   Y_ButtonPress = Y_Motion;
1593 }
1594
1595 //==============================================================================
1596 //function : VT_ProcessControlButton3Motion
1597 //purpose  : Rotation
1598 //==============================================================================
1599 void VT_ProcessControlButton3Motion()
1600 {
1601   if (Start_Rot)
1602   {
1603     ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
1604   }
1605 }
1606
1607 //==============================================================================
1608 //function : VT_ProcessMotion
1609 //purpose  :
1610 //==============================================================================
1611 void VT_ProcessMotion()
1612 {
1613   //pre-hilights detected objects at mouse position
1614
1615   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1616   EM->MoveTo(X_Motion, Y_Motion);
1617 }
1618
1619
1620 void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
1621 {
1622   Xpix = X_Motion;Ypix=Y_Motion;
1623 }
1624
1625 //==============================================================================
1626 //function : ViewProject: implements VAxo, VTop, VLeft, ...
1627 //purpose  : Switches to an axonometric, top, left and other views
1628 //==============================================================================
1629
1630 static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
1631 {
1632   if ( ViewerTest::CurrentView().IsNull() )
1633   {
1634     di<<"Call vinit before this command, please"<<"\n";
1635     return 1;
1636   }
1637
1638   ViewerTest::CurrentView()->SetProj(ori);
1639   return 0;
1640 }
1641
1642 //==============================================================================
1643 //function : VAxo
1644 //purpose  : Switch to an Axonometric view
1645 //Draw arg : No args
1646 //==============================================================================
1647
1648 static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
1649 {
1650   return ViewProject(di, V3d_XposYnegZpos);
1651 }
1652
1653 //==============================================================================
1654 //function : VTop
1655 //purpose  : Switch to a Top View
1656 //Draw arg : No args
1657 //==============================================================================
1658
1659 static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
1660 {
1661   return ViewProject(di, V3d_Zpos);
1662 }
1663
1664 //==============================================================================
1665 //function : VBottom
1666 //purpose  : Switch to a Bottom View
1667 //Draw arg : No args
1668 //==============================================================================
1669
1670 static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
1671 {
1672   return ViewProject(di, V3d_Zneg);
1673 }
1674
1675 //==============================================================================
1676 //function : VLeft
1677 //purpose  : Switch to a Left View
1678 //Draw arg : No args
1679 //==============================================================================
1680
1681 static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
1682 {
1683   return ViewProject(di, V3d_Ypos);
1684 }
1685
1686 //==============================================================================
1687 //function : VRight
1688 //purpose  : Switch to a Right View
1689 //Draw arg : No args
1690 //==============================================================================
1691
1692 static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
1693 {
1694   return ViewProject(di, V3d_Yneg);
1695 }
1696
1697 //==============================================================================
1698 //function : VFront
1699 //purpose  : Switch to a Front View
1700 //Draw arg : No args
1701 //==============================================================================
1702
1703 static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
1704 {
1705   return ViewProject(di, V3d_Xpos);
1706 }
1707
1708 //==============================================================================
1709 //function : VBack
1710 //purpose  : Switch to a Back View
1711 //Draw arg : No args
1712 //==============================================================================
1713
1714 static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
1715 {
1716   return ViewProject(di, V3d_Xneg);
1717 }
1718
1719 //==============================================================================
1720 //function : VHelp
1721 //purpose  : Dsiplay help on viewer Keyboead and mouse commands
1722 //Draw arg : No args
1723 //==============================================================================
1724
1725 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
1726 {
1727
1728   di << "Q : Quit the application" << "\n";
1729
1730   di << "========================="<<"\n";
1731   di << "F : FitAll" << "\n";
1732   di << "T : TopView" << "\n";
1733   di << "B : BottomView" << "\n";
1734   di << "R : RightView" << "\n";
1735   di << "L : LeftView" << "\n";
1736   di << "A : AxonometricView" << "\n";
1737   di << "D : ResetView" << "\n";
1738
1739   di << "========================="<<"\n";
1740   di << "S : Shading" << "\n";
1741   di << "W : Wireframe" << "\n";
1742   di << "H : HidelLineRemoval" << "\n";
1743   di << "U : Unset display mode" << "\n";
1744
1745   di << "========================="<<"\n";
1746   di << "Selection mode "<<"\n";
1747   di << "0 : Shape" <<"\n";
1748   di << "1 : Vertex" <<"\n";
1749   di << "2 : Edge" <<"\n";
1750   di << "3 : Wire" <<"\n";
1751   di << "4 : Face" <<"\n";
1752   di << "5 : Shell" <<"\n";
1753   di << "6 : Solid" <<"\n";
1754   di << "7 : Compound" <<"\n";
1755
1756   di << "========================="<<"\n";
1757   di << "Z : Switch Z clipping On/Off" << "\n";
1758   di << ", : Hilight next detected" << "\n";
1759   di << ". : Hilight previous detected" << "\n";
1760
1761   return 0;
1762 }
1763
1764 #ifdef WNT
1765
1766 static Standard_Boolean Ppick = 0;
1767 static Standard_Integer Pargc = 0;
1768 static const char**           Pargv = NULL;
1769
1770
1771 static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
1772                                           UINT Msg,
1773                                           WPARAM wParam,
1774                                           LPARAM lParam )
1775 {
1776   if (!ViewerTest_myViews.IsEmpty()) {
1777
1778     WPARAM fwKeys = wParam;
1779
1780     switch( Msg ) {
1781     case WM_CLOSE:
1782        {
1783          // Delete view from map of views
1784          ViewerTest::RemoveView(FindViewIdByWindowHandle(hwnd));
1785          return 0;
1786        }
1787        break;
1788     case WM_ACTIVATE:
1789       if(LOWORD(wParam) == WA_CLICKACTIVE || LOWORD(wParam) == WA_ACTIVE
1790         || ViewerTest::CurrentView().IsNull())
1791       {
1792         // Activate inactive window
1793         if(GetWindowHandle(VT_GetWindow()) != hwnd)
1794         {
1795           ActivateView (FindViewIdByWindowHandle(hwnd));
1796         }
1797       }
1798       break;
1799     case WM_LBUTTONUP:
1800       IsDragged = Standard_False;
1801       if( !DragFirst )
1802       {
1803         HDC hdc = GetDC( hwnd );
1804         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
1805         SetROP2( hdc, R2_NOT );
1806         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1807         ReleaseDC( hwnd, hdc );
1808
1809         const Handle(ViewerTest_EventManager) EM =
1810           ViewerTest::CurrentEventManager();
1811         if ( fwKeys & MK_SHIFT )
1812           EM->ShiftSelect( min( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
1813           max( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ));
1814         else
1815           EM->Select( min( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
1816           max( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ));
1817       }
1818       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1819
1820     case WM_LBUTTONDOWN:
1821       if( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) )
1822       {
1823         IsDragged = Standard_True;
1824         DragFirst = Standard_True;
1825         X_ButtonPress = LOWORD(lParam);
1826         Y_ButtonPress = HIWORD(lParam);
1827       }
1828       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1829
1830       break;
1831
1832     case WM_MOUSEMOVE:
1833       if( IsDragged )
1834       {
1835         HDC hdc = GetDC( hwnd );
1836
1837         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
1838         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
1839         SetROP2( hdc, R2_NOT );
1840
1841         if( !DragFirst )
1842           Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1843
1844         DragFirst = Standard_False;
1845         X_Motion = LOWORD(lParam);
1846         Y_Motion = HIWORD(lParam);
1847
1848         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1849
1850         SelectObject( hdc, anObj );
1851
1852         ReleaseDC( hwnd, hdc );
1853       }
1854       else
1855         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1856       break;
1857
1858     default:
1859       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1860     }
1861     return 0;
1862   }
1863   return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1864 }
1865
1866
1867 static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
1868                                        UINT Msg,
1869                                        WPARAM wParam,
1870                                        LPARAM lParam )
1871 {
1872   static int Up = 1;
1873
1874   if ( !ViewerTest::CurrentView().IsNull() ) {
1875     PAINTSTRUCT    ps;
1876
1877     switch( Msg ) {
1878     case WM_PAINT:
1879       BeginPaint(hwnd, &ps);
1880       EndPaint(hwnd, &ps);
1881       VT_ProcessExpose();
1882       break;
1883
1884     case WM_SIZE:
1885       VT_ProcessConfigure();
1886       break;
1887
1888     case WM_KEYDOWN:
1889       if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
1890       {
1891         char c[2];
1892         c[0] = (char) wParam;
1893         c[1] = '\0';
1894         VT_ProcessKeyPress (c);
1895       }
1896       break;
1897
1898     case WM_LBUTTONUP:
1899     case WM_MBUTTONUP:
1900     case WM_RBUTTONUP:
1901       Up = 1;
1902       VT_ProcessButton3Release();
1903       break;
1904
1905     case WM_LBUTTONDOWN:
1906     case WM_MBUTTONDOWN:
1907     case WM_RBUTTONDOWN:
1908       {
1909         WPARAM fwKeys = wParam;
1910
1911         Up = 0;
1912
1913         X_ButtonPress = LOWORD(lParam);
1914         Y_ButtonPress = HIWORD(lParam);
1915
1916         if (Msg == WM_LBUTTONDOWN)
1917         {
1918           if (fwKeys & MK_CONTROL)
1919           {
1920             Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
1921           }
1922           else
1923           {
1924             VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
1925           }
1926         }
1927         else if (Msg == WM_RBUTTONDOWN)
1928         {
1929           // Start rotation
1930           VT_ProcessButton3Press();
1931         }
1932       }
1933       break;
1934
1935     case WM_MOUSEMOVE:
1936       {
1937         //cout << "\t WM_MOUSEMOVE" << endl;
1938         WPARAM fwKeys = wParam;
1939         X_Motion = LOWORD(lParam);
1940         Y_Motion = HIWORD(lParam);
1941
1942         if ( Up &&
1943           fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON ) ) {
1944             Up = 0;
1945             X_ButtonPress = LOWORD(lParam);
1946             Y_ButtonPress = HIWORD(lParam);
1947
1948             if ( fwKeys & MK_RBUTTON ) {
1949               // Start rotation
1950               VT_ProcessButton3Press();
1951             }
1952           }
1953
1954           if ( fwKeys & MK_CONTROL ) {
1955             if ( fwKeys & MK_LBUTTON ) {
1956               ProcessControlButton1Motion();
1957             }
1958             else if ( fwKeys & MK_MBUTTON ||
1959               ((fwKeys&MK_LBUTTON) &&
1960               (fwKeys&MK_RBUTTON) ) ){
1961                 VT_ProcessControlButton2Motion();
1962               }
1963             else if ( fwKeys & MK_RBUTTON ) {
1964               VT_ProcessControlButton3Motion();
1965             }
1966           }
1967 #ifdef BUG
1968           else if ( fwKeys & MK_SHIFT ) {
1969             if ( fwKeys & MK_MBUTTON ||
1970               ((fwKeys&MK_LBUTTON) &&
1971               (fwKeys&MK_RBUTTON) ) ) {
1972                 cout << "ProcessZClipMotion()" << endl;
1973                 ProcessZClipMotion();
1974               }
1975           }
1976 #endif
1977           else if (GetWindowHandle (VT_GetWindow()) == hwnd)
1978           {
1979             if ((fwKeys & MK_MBUTTON
1980             || ((fwKeys & MK_LBUTTON) && (fwKeys & MK_RBUTTON))))
1981             {
1982               ProcessZClipMotion();
1983             }
1984             else
1985             {
1986               VT_ProcessMotion();
1987             }
1988           }
1989       }
1990       break;
1991
1992     default:
1993       return( DefWindowProc( hwnd, Msg, wParam, lParam ));
1994     }
1995     return 0L;
1996   }
1997
1998   return DefWindowProc( hwnd, Msg, wParam, lParam );
1999 }
2000
2001
2002
2003
2004 //==============================================================================
2005 //function : ViewerMainLoop
2006 //purpose  : Get a Event on the view and dispatch it
2007 //==============================================================================
2008
2009
2010 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2011 {
2012   Ppick = (argc > 0)? 1 : 0;
2013   Pargc = argc;
2014   Pargv = argv;
2015
2016   if ( Ppick ) {
2017     MSG msg;
2018     msg.wParam = 1;
2019
2020     cout << "Start picking" << endl;
2021
2022     while ( Ppick == 1 ) {
2023       // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2024       if (GetMessage(&msg, NULL, 0, 0) ) {
2025         TranslateMessage(&msg);
2026         DispatchMessage(&msg);
2027       }
2028     }
2029
2030     cout << "Picking done" << endl;
2031   }
2032
2033   return Ppick;
2034 }
2035
2036 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
2037
2038 int min( int a, int b )
2039 {
2040   if( a<b )
2041     return a;
2042   else
2043     return b;
2044 }
2045
2046 int max( int a, int b )
2047 {
2048   if( a>b )
2049     return a;
2050   else
2051     return b;
2052 }
2053
2054 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2055
2056
2057   static XEvent aReport;
2058   Standard_Boolean pick = argc > 0;
2059   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2060   XNextEvent (aDisplay, &aReport);
2061
2062   // Handle event for the chosen display connection
2063   switch (aReport.type) {
2064       case ClientMessage:
2065         {
2066           if(aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2067           {
2068             // Close the window
2069             ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2070           }
2071         }
2072         return 0;
2073      case FocusIn:
2074       {
2075          // Activate inactive view
2076          Window aWindow = GetWindowHandle(VT_GetWindow());
2077          if(aWindow != aReport.xfocus.window)
2078          {
2079            ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2080          }
2081       }
2082       break;
2083       case Expose:
2084         {
2085           VT_ProcessExpose();
2086         }
2087         break;
2088       case ConfigureNotify:
2089         {
2090           VT_ProcessConfigure();
2091         }
2092         break;
2093       case KeyPress:
2094         {
2095
2096           KeySym ks_ret ;
2097           char buf_ret[11] ;
2098           int ret_len ;
2099           XComposeStatus status_in_out;
2100
2101           ret_len = XLookupString( ( XKeyEvent *)&aReport ,
2102             (char *) buf_ret , 10 ,
2103             &ks_ret , &status_in_out ) ;
2104
2105
2106           buf_ret[ret_len] = '\0' ;
2107
2108           if (ret_len)
2109           {
2110             VT_ProcessKeyPress (buf_ret);
2111           }
2112         }
2113         break;
2114       case ButtonPress:
2115         {
2116           X_ButtonPress = aReport.xbutton.x;
2117           Y_ButtonPress = aReport.xbutton.y;
2118
2119           if (aReport.xbutton.button == Button1)
2120           {
2121             if (aReport.xbutton.state & ControlMask)
2122             {
2123               pick = VT_ProcessButton1Press (argc, argv, pick, (aReport.xbutton.state & ShiftMask));
2124             }
2125             else
2126             {
2127               IsDragged = Standard_True;
2128               DragFirst = Standard_True;
2129             }
2130           }
2131           else if (aReport.xbutton.button == Button3)
2132           {
2133             // Start rotation
2134             VT_ProcessButton3Press();
2135           }
2136         }
2137         break;
2138       case ButtonRelease:
2139         {
2140           if( IsDragged )
2141           {
2142             if( !DragFirst )
2143             {
2144               Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2145               GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2146               XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2147             }
2148
2149             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
2150             if( aContext.IsNull() )
2151             {
2152               cout << "The context is null. Please use vinit before createmesh" << endl;
2153               return 0;
2154             }
2155
2156             Standard_Boolean ShiftPressed = ( aReport.xbutton.state & ShiftMask );
2157             if( aReport.xbutton.button==1 )
2158               if( DragFirst )
2159                 if( ShiftPressed )
2160                 {
2161                   aContext->ShiftSelect();
2162                 }
2163                 else
2164                 {
2165                   aContext->Select();
2166                 }
2167               else
2168                 if( ShiftPressed )
2169                 {
2170                   aContext->ShiftSelect( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2171                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2172                     ViewerTest::CurrentView());
2173                 }
2174                 else
2175                 {
2176                   aContext->Select( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2177                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2178                     ViewerTest::CurrentView() );
2179                 }
2180             else
2181               VT_ProcessButton3Release();
2182
2183             IsDragged = Standard_False;
2184           }
2185           else
2186             VT_ProcessButton3Release();
2187         }
2188         break;
2189       case MotionNotify:
2190         {
2191           if (GetWindowHandle (VT_GetWindow()) != aReport.xmotion.window)
2192           {
2193             break;
2194           }
2195           if( IsDragged )
2196           {
2197             Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2198             GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2199             XSetFunction( aDisplay, gc, GXinvert );
2200
2201             if( !DragFirst )
2202               XDrawRectangle(aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2203
2204             X_Motion = aReport.xmotion.x;
2205             Y_Motion = aReport.xmotion.y;
2206             DragFirst = Standard_False;
2207
2208             XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2209           }
2210           else
2211           {
2212             X_Motion = aReport.xmotion.x;
2213             Y_Motion = aReport.xmotion.y;
2214
2215             // remove all the ButtonMotionMaskr
2216             while( XCheckMaskEvent( aDisplay, ButtonMotionMask, &aReport) ) ;
2217
2218             if ( ZClipIsOn && aReport.xmotion.state & ShiftMask ) {
2219               if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
2220
2221                 Quantity_Length VDX, VDY;
2222
2223                 ViewerTest::CurrentView()->Size(VDX,VDY);
2224                 Standard_Real VDZ =0 ;
2225                 VDZ = ViewerTest::CurrentView()->ZSize();
2226
2227                 printf("%f,%f,%f\n", VDX, VDY, VDZ);
2228
2229                 Quantity_Length dx = 0 ;
2230                 dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
2231
2232                 cout << dx << endl;
2233
2234                 dx = dx / VDX * VDZ;
2235
2236                 cout << dx << endl;
2237
2238                 ViewerTest::CurrentView()->Redraw();
2239               }
2240             }
2241
2242             if ( aReport.xmotion.state & ControlMask ) {
2243               if ( aReport.xmotion.state & Button1Mask ) {
2244                 ProcessControlButton1Motion();
2245               }
2246               else if ( aReport.xmotion.state & Button2Mask ) {
2247                 VT_ProcessControlButton2Motion();
2248               }
2249               else if ( aReport.xmotion.state & Button3Mask ) {
2250                 VT_ProcessControlButton3Motion();
2251               }
2252             }
2253             else
2254             {
2255               VT_ProcessMotion();
2256             }
2257           }
2258         }
2259         break;
2260 }
2261 return pick;
2262 }
2263
2264 //==============================================================================
2265 //function : VProcessEvents
2266 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
2267 //       event in the Viewer window
2268 //==============================================================================
2269
2270 static void VProcessEvents(ClientData,int)
2271 {
2272   NCollection_Vector<int> anEventNumbers;
2273   // Get number of messages from every display
2274   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2275        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next())
2276   {
2277     anEventNumbers.Append(XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()));
2278   } 
2279     // Handle events for every display
2280   int anEventIter = 0;
2281   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2282        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next(), anEventIter++)
2283   {
2284     for (int i = 0; i < anEventNumbers.Value(anEventIter) && 
2285          XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()) > 0; ++i)
2286     {
2287       SetDisplayConnection (anIter.Key2()->GetDisplayConnection());
2288       int anEventResult = ViewerMainLoop( 0, NULL);
2289       // If window is closed or context was not found finish current event processing loop
2290       if (!anEventResult)
2291         return;
2292     }
2293   }
2294   
2295   SetDisplayConnection (ViewerTest::GetAISContext()->CurrentViewer()->Driver()->GetDisplayConnection());
2296   
2297 }
2298 #endif
2299
2300 //==============================================================================
2301 //function : OSWindowSetup
2302 //purpose  : Setup for the X11 window to be able to cath the event
2303 //==============================================================================
2304
2305
2306 static void OSWindowSetup()
2307 {
2308 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2309   // X11
2310
2311   Window  window   = VT_GetWindow()->XWindow();
2312   SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2313   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2314   XSynchronize(aDisplay, 1);
2315
2316   // X11 : For keyboard on SUN
2317   XWMHints wmhints;
2318   wmhints.flags = InputHint;
2319   wmhints.input = 1;
2320
2321   XSetWMHints( aDisplay, window, &wmhints);
2322
2323   XSelectInput( aDisplay, window,  ExposureMask | KeyPressMask |
2324     ButtonPressMask | ButtonReleaseMask |
2325     StructureNotifyMask |
2326     PointerMotionMask |
2327     Button1MotionMask | Button2MotionMask |
2328     Button3MotionMask | FocusChangeMask
2329     );
2330   Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
2331   XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
2332
2333   XSynchronize(aDisplay, 0);
2334
2335 #else
2336   // WNT
2337 #endif
2338
2339 }
2340
2341
2342 //==============================================================================
2343 //function : VFit
2344
2345 //purpose  : Fitall, no DRAW arguments
2346 //Draw arg : No args
2347 //==============================================================================
2348
2349 static int VFit(Draw_Interpretor& , Standard_Integer , const char** )
2350 {
2351   const Handle(V3d_View) aView = ViewerTest::CurrentView();
2352   Handle(NIS_View) V = Handle(NIS_View)::DownCast(aView);
2353   if (V.IsNull() == Standard_False) {
2354     V->FitAll3d();
2355   } else if (aView.IsNull() == Standard_False) {
2356     aView->FitAll();
2357   }
2358   return 0;
2359 }
2360
2361 //==============================================================================
2362 //function : VZFit
2363 //purpose  : ZFitall, no DRAW arguments
2364 //Draw arg : No args
2365 //==============================================================================
2366
2367 static int VZFit(Draw_Interpretor& , Standard_Integer , const char** )
2368 {
2369   Handle(V3d_View) V = ViewerTest::CurrentView();
2370   if ( !V.IsNull() ) V->ZFitAll(); return 0; }
2371
2372
2373 static int VRepaint(Draw_Interpretor& , Standard_Integer , const char** )
2374 {
2375   Handle(V3d_View) V = ViewerTest::CurrentView();
2376   if ( !V.IsNull() ) V->Redraw(); return 0;
2377 }
2378
2379
2380 //==============================================================================
2381 //function : VClear
2382 //purpose  : Remove all the object from the viewer
2383 //Draw arg : No args
2384 //==============================================================================
2385
2386 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2387 {
2388   Handle(V3d_View) V = ViewerTest::CurrentView();
2389   if(!V.IsNull())
2390     ViewerTest::Clear();
2391   return 0;
2392 }
2393
2394 //==============================================================================
2395 //function : VPick
2396 //purpose  :
2397 //==============================================================================
2398
2399 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2400 { if (ViewerTest::CurrentView().IsNull() ) return 1;
2401
2402 if ( argc < 4 ) {
2403   di << argv[0] << "Invalid number of arguments" << "\n";
2404   return 1;
2405 }
2406
2407 while (ViewerMainLoop( argc, argv)) {
2408 }
2409
2410 return 0;
2411 }
2412
2413 //==============================================================================
2414 //function : InitViewerTest
2415 //purpose  : initialisation de toutes les variables static de  ViewerTest (dp)
2416 //==============================================================================
2417
2418 void ViewerTest_InitViewerTest (const Handle(AIS_InteractiveContext)& theContext)
2419 {
2420   Handle(V3d_Viewer) aViewer = theContext->CurrentViewer();
2421   ViewerTest::SetAISContext(theContext);
2422   aViewer->InitActiveViews();
2423   Handle(V3d_View) aView = aViewer->ActiveView();
2424   if (aViewer->MoreActiveViews()) ViewerTest::CurrentView(aView);
2425   ViewerTest::ResetEventManager();
2426   Handle(Aspect_Window) aWindow = aView->Window();
2427 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2428   // X11
2429   VT_GetWindow() = Handle(Xw_Window)::DownCast(aWindow);
2430   OSWindowSetup();
2431   static int aFirst = 1;
2432   if ( aFirst ) {
2433 #if TCL_MAJOR_VERSION  < 8
2434     Tk_CreateFileHandler((void*)XConnectionNumber(GetDisplayConnection()->GetDisplay()),
2435       TK_READABLE, VProcessEvents, (ClientData) 0);
2436 #else
2437     Tk_CreateFileHandler(XConnectionNumber(GetDisplayConnection()->GetDisplay()),
2438       TK_READABLE, VProcessEvents, (ClientData) 0);
2439 #endif
2440     aFirst = 0;
2441   }
2442 #endif
2443 }
2444
2445 //==============================================================================
2446 //function : VSetBg
2447 //purpose  : Load image as background
2448 //==============================================================================
2449
2450 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2451 {
2452   if (argc < 2 || argc > 3)
2453   {
2454     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background" << "\n";
2455     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2456     return 1;
2457   }
2458
2459   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2460   if(AISContext.IsNull())
2461   {
2462     di << "use 'vinit' command before " << argv[0] << "\n";
2463     return 1;
2464   }
2465
2466   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
2467   if (argc == 3)
2468   {
2469     const char* szType = argv[2];
2470     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2471     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2472     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2473     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2474     else
2475     {
2476       di << "Wrong fill type : " << szType << "\n";
2477       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2478       return 1;
2479     }
2480   }
2481
2482   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2483   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
2484
2485   return 0;
2486 }
2487
2488 //==============================================================================
2489 //function : VSetBgMode
2490 //purpose  : Change background image fill type
2491 //==============================================================================
2492
2493 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2494 {
2495   if (argc != 2)
2496   {
2497     di << "Usage : " << argv[0] << " filltype : Change background image mode" << "\n";
2498     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2499     return 1;
2500   }
2501
2502   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2503   if(AISContext.IsNull())
2504   {
2505     di << "use 'vinit' command before " << argv[0] << "\n";
2506     return 1;
2507   }
2508   Aspect_FillMethod aFillType = Aspect_FM_NONE;
2509   const char* szType = argv[1];
2510   if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2511   else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2512   else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2513   else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2514   else
2515   {
2516     di << "Wrong fill type : " << szType << "\n";
2517     di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2518     return 1;
2519   }
2520   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2521   V3dView->SetBgImageStyle(aFillType, Standard_True);
2522   return 0;
2523 }
2524
2525 //==============================================================================
2526 //function : VSetGradientBg
2527 //purpose  : Mount gradient background
2528 //==============================================================================
2529 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2530 {
2531   if (argc != 8 )
2532   {
2533     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background" << "\n";
2534     di << "R1,G1,B1,R2,G2,B2 = [0..255]" << "\n";
2535     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2536     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2537     return 1;
2538   }
2539
2540   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2541   if(AISContext.IsNull())
2542   {
2543     di << "use 'vinit' command before " << argv[0] << "\n";
2544     return 1;
2545   }
2546   if (argc == 8)
2547   {
2548
2549     Standard_Real R1 = Draw::Atof(argv[1])/255.;
2550     Standard_Real G1 = Draw::Atof(argv[2])/255.;
2551     Standard_Real B1 = Draw::Atof(argv[3])/255.;
2552     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
2553
2554     Standard_Real R2 = Draw::Atof(argv[4])/255.;
2555     Standard_Real G2 = Draw::Atof(argv[5])/255.;
2556     Standard_Real B2 = Draw::Atof(argv[6])/255.;
2557
2558     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
2559     int aType = Draw::Atoi(argv[7]);
2560     if( aType < 0 || aType > 8 )
2561     {
2562       di << "Wrong fill type " << "\n";
2563       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2564       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2565       return 1;
2566     }
2567
2568     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2569
2570     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2571     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
2572   }
2573
2574   return 0;
2575 }
2576
2577 //==============================================================================
2578 //function : VSetGradientBgMode
2579 //purpose  : Change gradient background fill style
2580 //==============================================================================
2581 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2582 {
2583   if (argc != 2 )
2584   {
2585     di << "Usage : " << argv[0] << " Type : Change gradient background fill type" << "\n";
2586     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2587     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2588     return 1;
2589   }
2590
2591   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2592   if(AISContext.IsNull())
2593   {
2594     di << "use 'vinit' command before " << argv[0] << "\n";
2595     return 1;
2596   }
2597   if (argc == 2)
2598   {
2599     int aType = Draw::Atoi(argv[1]);
2600     if( aType < 0 || aType > 8 )
2601     {
2602       di << "Wrong fill type " << "\n";
2603       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2604       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2605       return 1;
2606     }
2607
2608     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2609
2610     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2611     V3dView->SetBgGradientStyle( aMethod, 1 );
2612   }
2613
2614   return 0;
2615 }
2616
2617 //==============================================================================
2618 //function : VSetColorBg
2619 //purpose  : Set color background
2620 //==============================================================================
2621 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2622 {
2623   if (argc != 4 )
2624   {
2625     di << "Usage : " << argv[0] << " R G B : Set color background" << "\n";
2626     di << "R,G,B = [0..255]" << "\n";
2627     return 1;
2628   }
2629
2630   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2631   if(AISContext.IsNull())
2632   {
2633     di << "use 'vinit' command before " << argv[0] << "\n";
2634     return 1;
2635   }
2636   if (argc == 4)
2637   {
2638
2639     Standard_Real R = Draw::Atof(argv[1])/255.;
2640     Standard_Real G = Draw::Atof(argv[2])/255.;
2641     Standard_Real B = Draw::Atof(argv[3])/255.;
2642     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
2643
2644     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2645     V3dView->SetBackgroundColor( aColor );
2646     V3dView->Update();
2647   }
2648
2649   return 0;
2650 }
2651
2652 //==============================================================================
2653 //function : VScale
2654 //purpose  : View Scaling
2655 //==============================================================================
2656
2657 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2658 {
2659   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2660   if ( V3dView.IsNull() ) return 1;
2661
2662   if ( argc != 4 ) {
2663     di << argv[0] << "Invalid number of arguments" << "\n";
2664     return 1;
2665   }
2666   V3dView->SetAxialScale( Draw::Atof(argv[1]),  Draw::Atof(argv[2]),  Draw::Atof(argv[3]) );
2667   return 0;
2668 }
2669 //==============================================================================
2670 //function : VTestZBuffTrihedron
2671 //purpose  : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron
2672 //==============================================================================
2673
2674 static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2675 {
2676   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2677   if ( V3dView.IsNull() ) return 1;
2678
2679   V3dView->ZBufferTriedronSetup();
2680
2681   if ( argc == 1 ) {
2682     // Set up default trihedron parameters
2683     V3dView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.1, V3d_ZBUFFER );
2684   } else
2685   if ( argc == 7 )
2686   {
2687     Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
2688     const char* aPosType = argv[1];
2689
2690     if ( strcmp(aPosType, "center") == 0 )
2691     {
2692       aPosition = Aspect_TOTP_CENTER;
2693     } else
2694     if (strcmp(aPosType, "left_lower") == 0)
2695     {
2696       aPosition = Aspect_TOTP_LEFT_LOWER;
2697     } else
2698     if (strcmp(aPosType, "left_upper") == 0)
2699     {
2700       aPosition = Aspect_TOTP_LEFT_UPPER;
2701     } else
2702     if (strcmp(aPosType, "right_lower") == 0)
2703     {
2704       aPosition = Aspect_TOTP_RIGHT_LOWER;
2705     } else
2706     if (strcmp(aPosType, "right_upper") == 0)
2707     {
2708       aPosition = Aspect_TOTP_RIGHT_UPPER;
2709     } else
2710     {
2711       di << argv[1] << " Invalid type of alignment"  << "\n";
2712       di << "Must be one of [ center, left_lower,"   << "\n";
2713       di << "left_upper, right_lower, right_upper ]" << "\n";
2714       return 1;
2715     }
2716
2717     Standard_Real R = Draw::Atof(argv[2])/255.;
2718     Standard_Real G = Draw::Atof(argv[3])/255.;
2719     Standard_Real B = Draw::Atof(argv[4])/255.;
2720     Quantity_Color aColor(R, G, B, Quantity_TOC_RGB);
2721
2722     Standard_Real aScale = Draw::Atof(argv[5]);
2723
2724     if( aScale <= 0.0 )
2725     {
2726       di << argv[5] << " Invalid value. Must be > 0" << "\n";
2727       return 1;
2728     }
2729
2730     V3d_TypeOfVisualization aPresentation = V3d_ZBUFFER;
2731     const char* aPresType = argv[6];
2732
2733     if ( strcmp(aPresType, "wireframe") == 0 )
2734     {
2735       aPresentation = V3d_WIREFRAME;
2736     } else
2737     if (strcmp(aPresType, "zbuffer") == 0)
2738     {
2739       aPresentation = V3d_ZBUFFER;
2740     } else
2741     {
2742       di << argv[6] << " Invalid type of visualization" << "\n";
2743       di << "Must be one of [ wireframe, zbuffer ]"     << "\n";
2744       return 1;
2745     }
2746
2747     V3dView->TriedronDisplay( aPosition, aColor.Name(), aScale, aPresentation );
2748
2749   } else
2750   {
2751     di << argv[0] << " Invalid number of arguments" << "\n";
2752     return 1;
2753   }
2754
2755   V3dView->ZFitAll();
2756
2757   return 0;
2758 }
2759
2760 //==============================================================================
2761 //function : VRotate
2762 //purpose  : Camera Rotating
2763 //==============================================================================
2764
2765 static int VRotate( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2766   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2767   if ( V3dView.IsNull() ) {
2768     return 1;
2769   }
2770
2771   if ( argc == 4 ) {
2772     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
2773     return 0;
2774   } else if ( argc == 7 ) {
2775     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]), Draw::Atof(argv[4]), Draw::Atof(argv[5]), Draw::Atof(argv[6]) );
2776     return 0;
2777   } else {
2778     di << argv[0] << " Invalid number of arguments" << "\n";
2779     return 1;
2780   }
2781 }
2782
2783 //==============================================================================
2784 //function : VZoom
2785 //purpose  : View zoom in / out (relative to current zoom)
2786 //==============================================================================
2787
2788 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2789   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2790   if ( V3dView.IsNull() ) {
2791     return 1;
2792   }
2793
2794   if ( argc == 2 ) {
2795     Standard_Real coef = Draw::Atof(argv[1]);
2796     if ( coef <= 0.0 ) {
2797       di << argv[1] << "Invalid value" << "\n";
2798       return 1;
2799     }
2800     V3dView->SetZoom( Draw::Atof(argv[1]) );
2801     return 0;
2802   } else {
2803     di << argv[0] << " Invalid number of arguments" << "\n";
2804     return 1;
2805   }
2806 }
2807
2808 //==============================================================================
2809 //function : VPan
2810 //purpose  : View panning (in pixels)
2811 //==============================================================================
2812
2813 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2814   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2815   if ( V3dView.IsNull() ) return 1;
2816
2817   if ( argc == 3 ) {
2818     V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
2819     return 0;
2820   } else {
2821     di << argv[0] << " Invalid number of arguments" << "\n";
2822     return 1;
2823   }
2824 }
2825
2826
2827 //==============================================================================
2828 //function : VExport
2829 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
2830 //==============================================================================
2831
2832 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2833 {
2834   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2835   if (V3dView.IsNull())
2836     return 1;
2837
2838   if (argc == 1)
2839   {
2840     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
2841     return 1;
2842   }
2843
2844   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
2845   TCollection_AsciiString aFormatStr;
2846
2847   TCollection_AsciiString aFileName (argv[1]);
2848   Standard_Integer aLen = aFileName.Length();
2849
2850   if (argc > 2)
2851   {
2852     aFormatStr = TCollection_AsciiString (argv[2]);
2853   }
2854   else if (aLen >= 4)
2855   {
2856     if (aFileName.Value (aLen - 2) == '.')
2857     {
2858       aFormatStr = aFileName.SubString (aLen - 1, aLen);
2859     }
2860     else if (aFileName.Value (aLen - 3) == '.')
2861     {
2862       aFormatStr = aFileName.SubString (aLen - 2, aLen);
2863     }
2864     else
2865     {
2866       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
2867       return 1;
2868     }
2869   }
2870   else
2871   {
2872     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
2873     return 1;
2874   }
2875
2876   aFormatStr.UpperCase();
2877   if (aFormatStr == "PS")
2878     anExpFormat = Graphic3d_EF_PostScript;
2879   else if (aFormatStr == "EPS")
2880     anExpFormat = Graphic3d_EF_EnhPostScript;
2881   else if (aFormatStr == "TEX")
2882     anExpFormat = Graphic3d_EF_TEX;
2883   else if (aFormatStr == "PDF")
2884     anExpFormat = Graphic3d_EF_PDF;
2885   else if (aFormatStr == "SVG")
2886     anExpFormat = Graphic3d_EF_SVG;
2887   else if (aFormatStr == "PGF")
2888     anExpFormat = Graphic3d_EF_PGF;
2889   else if (aFormatStr == "EMF")
2890     anExpFormat = Graphic3d_EF_EMF;
2891   else
2892   {
2893     std::cout << "Invalid export format '" << aFormatStr << "'\n";
2894     return 1;
2895   }
2896
2897   try {
2898     if (!V3dView->View()->Export (argv[1], anExpFormat))
2899     {
2900       di << "Error: export of image to " << aFormatStr << " failed!\n";
2901     }
2902   }
2903   catch (Standard_Failure)
2904   {
2905     di << "Error: export of image to " << aFormatStr << " failed";
2906     di << " (exception: " << Standard_Failure::Caught()->GetMessageString() << ")";
2907   }
2908   return 0;
2909 }
2910
2911 //==============================================================================
2912 //function : VColorScale
2913 //purpose  : representation color scale
2914 //==============================================================================
2915 #include <V3d_ColorScale.hxx>
2916
2917 static int VColorScale (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
2918 {
2919   if ( argc != 1 && argc != 4 && argc != 5 && argc != 6 && argc != 8 )
2920   {
2921     di << "Usage : " << argv[0] << " [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = Right X = 0 Y = 0]  " << "\n";
2922     return 1;
2923   }
2924
2925   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2926   if(aContext.IsNull()) {
2927     di << argv[0] << " ERROR : use 'vinit' command before " << "\n";
2928     return -1;
2929   }
2930
2931   Standard_Real minRange = 0. , maxRange = 100. ;
2932
2933   Standard_Integer numIntervals = 10 ;
2934   Standard_Integer textHeight = 16;
2935   Aspect_TypeOfColorScalePosition position = Aspect_TOCSP_RIGHT;
2936   Standard_Real X = 0., Y = 0. ;
2937
2938   if ( argc < 9 )
2939   {
2940      if( argc > 3 )
2941      {
2942        minRange = Draw::Atof( argv[1] );
2943        maxRange = Draw::Atof( argv[2] );
2944        numIntervals = Draw::Atoi( argv[3] );
2945      }
2946      if ( argc > 4 )
2947        textHeight = Draw::Atoi( argv[4] );
2948      if ( argc > 5 )
2949        position = (Aspect_TypeOfColorScalePosition)Draw::Atoi( argv[5] );
2950      if ( argc > 7 )
2951      {
2952        X = Draw::Atof( argv[6] );
2953        Y = Draw::Atof( argv[7] );
2954      }
2955   }
2956   Handle(V3d_View) curView = ViewerTest::CurrentView( );
2957   if ( curView.IsNull( ) )
2958     return 1;
2959   Handle(Aspect_ColorScale) aCSV = curView->ColorScale( );
2960   Handle(V3d_ColorScale) aCS = ( Handle( V3d_ColorScale )::DownCast( aCSV ) );
2961   if( ! aCS.IsNull( ) )
2962   {
2963     aCS->SetPosition( X , Y );
2964     aCS->SetHeight( 0.95) ;
2965     aCS->SetTextHeight( textHeight );
2966     aCS->SetRange( minRange , maxRange );
2967     aCS->SetNumberOfIntervals( numIntervals );
2968     aCS->SetLabelPosition( position );
2969     if( !curView->ColorScaleIsDisplayed() )
2970       curView->ColorScaleDisplay( );
2971   }
2972   return 0;
2973 }
2974
2975 //==============================================================================
2976 //function : VGraduatedTrihedron
2977 //purpose  : Displays a graduated trihedron
2978 //==============================================================================
2979
2980 static void AddMultibyteString (TCollection_ExtendedString &name, const char *arg)
2981 {
2982   const char *str = arg;
2983   while (*str)
2984   {
2985     unsigned short c1 = *str++;
2986     unsigned short c2 = *str++;
2987     if (!c1 || !c2) break;
2988     name += (Standard_ExtCharacter)((c1 << 8) | c2);
2989   }
2990 }
2991
2992 static int VGraduatedTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2993 {
2994   // Check arguments
2995   if (argc != 2 && argc < 5)
2996   {
2997     di<<"Error: "<<argv[0]<<" - invalid number of arguments\n";
2998     di<<"Usage: type help "<<argv[0]<<"\n";
2999     return 1; //TCL_ERROR
3000   }
3001
3002   Handle(V3d_View) aV3dView = ViewerTest::CurrentView();
3003
3004   // Create 3D view if it doesn't exist
3005   if ( aV3dView.IsNull() )
3006   {
3007     ViewerTest::ViewerInit();
3008     aV3dView = ViewerTest::CurrentView();
3009     if( aV3dView.IsNull() )
3010     {
3011       di << "Error: Cannot create a 3D view\n";
3012       return 1; //TCL_ERROR
3013     }
3014   }
3015
3016   // Erase (==0) or display (!=0)
3017   const int display = Draw::Atoi(argv[1]);
3018
3019   if (display)
3020   {
3021     // Text font
3022     TCollection_AsciiString font;
3023     if (argc < 6)
3024       font.AssignCat("Courier");
3025     else
3026       font.AssignCat(argv[5]);
3027
3028     // Text is multibyte
3029     const Standard_Boolean isMultibyte = (argc < 7)? Standard_False : (Draw::Atoi(argv[6]) != 0);
3030
3031     // Set axis names
3032     TCollection_ExtendedString xname, yname, zname;
3033     if (argc >= 5)
3034     {
3035       if (isMultibyte)
3036       {
3037         AddMultibyteString(xname, argv[2]);
3038         AddMultibyteString(yname, argv[3]);
3039         AddMultibyteString(zname, argv[4]);
3040       }
3041       else
3042       {
3043         xname += argv[2];
3044         yname += argv[3];
3045         zname += argv[4];
3046       }
3047     }
3048     else
3049     {
3050       xname += "X (mm)";
3051       yname += "Y (mm)";
3052       zname += "Z (mm)";
3053     }
3054
3055     aV3dView->GraduatedTrihedronDisplay(xname, yname, zname,
3056                                         Standard_True/*xdrawname*/, Standard_True/*ydrawname*/, Standard_True/*zdrawname*/,
3057                                         Standard_True/*xdrawvalues*/, Standard_True/*ydrawvalues*/, Standard_True/*zdrawvalues*/,
3058                                         Standard_True/*drawgrid*/,
3059                                         Standard_True/*drawaxes*/,
3060                                         5/*nbx*/, 5/*nby*/, 5/*nbz*/,
3061                                         10/*xoffset*/, 10/*yoffset*/, 10/*zoffset*/,
3062                                         30/*xaxisoffset*/, 30/*yaxisoffset*/, 30/*zaxisoffset*/,
3063                                         Standard_True/*xdrawtickmarks*/, Standard_True/*ydrawtickmarks*/, Standard_True/*zdrawtickmarks*/,
3064                                         10/*xtickmarklength*/, 10/*ytickmarklength*/, 10/*ztickmarklength*/,
3065                                         Quantity_NOC_WHITE/*gridcolor*/,
3066                                         Quantity_NOC_RED/*xnamecolor*/,Quantity_NOC_GREEN/*ynamecolor*/,Quantity_NOC_BLUE1/*znamecolor*/,
3067                                         Quantity_NOC_RED/*xcolor*/,Quantity_NOC_GREEN/*ycolor*/,Quantity_NOC_BLUE1/*zcolor*/,font);
3068   }
3069   else
3070     aV3dView->GraduatedTrihedronErase();
3071
3072   ViewerTest::GetAISContext()->UpdateCurrentViewer();
3073   aV3dView->Redraw();
3074
3075   return 0;
3076 }
3077
3078 //==============================================================================
3079 //function : VPrintView
3080 //purpose  : Test printing algorithm, print the view to image file with given
3081 //           width and height. Printing implemented only for WNT.
3082 //==============================================================================
3083 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
3084                        const char** argv)
3085 {
3086 #ifndef WNT
3087   di << "Printing implemented only for wnt!\n";
3088   return 1;
3089 #else
3090
3091   Handle(AIS_InteractiveContext) aContextAIS = NULL;
3092   Handle(V3d_View) aView = NULL;
3093   aContextAIS = ViewerTest::GetAISContext();
3094   if (!aContextAIS.IsNull())
3095   {
3096     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
3097     Vwr->InitActiveViews();
3098     if(Vwr->MoreActiveViews())
3099       aView = Vwr->ActiveView();
3100   }
3101
3102   // check for errors
3103   if (aView.IsNull())
3104   {
3105     di << "Call vinit before!\n";
3106     return 1;
3107   }
3108   else if (argc < 4)
3109   {
3110     di << "Use: " << argv[0];
3111     di << " width height filename [print algo=0]\n";
3112     di << "width, height of the intermediate buffer for operation\n";
3113     di << "algo : {0|1}\n";
3114     di << "        0 - stretch algorithm\n";
3115     di << "        1 - tile algorithm\n";
3116     di << "test printing algorithms into an intermediate buffer\n";
3117     di << "with saving output to an image file\n";
3118     return 1;
3119   }
3120
3121   // get the input params
3122   Standard_Integer aWidth  = Draw::Atoi (argv[1]);
3123   Standard_Integer aHeight = Draw::Atoi (argv[2]);
3124   Standard_Integer aMode   = 0;
3125   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
3126   if (argc==5)
3127     aMode = Draw::Atoi (argv[4]);
3128
3129   // check the input parameters
3130   if (aWidth <= 0 || aHeight <= 0)
3131   {
3132     di << "Width and height must be positive values!\n";
3133     return 1;
3134   }
3135   if (aMode != 0 && aMode != 1)
3136     aMode = 0;
3137
3138   // define compatible bitmap
3139   HDC anDC = CreateCompatibleDC(0);
3140   BITMAPINFO aBitmapData;
3141   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
3142   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
3143   aBitmapData.bmiHeader.biWidth         = aWidth ;
3144   aBitmapData.bmiHeader.biHeight        = aHeight;
3145   aBitmapData.bmiHeader.biPlanes        = 1;
3146   aBitmapData.bmiHeader.biBitCount      = 24;
3147   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
3148   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
3149   aBitmapData.bmiHeader.biClrUsed       = 0;
3150   aBitmapData.bmiHeader.biClrImportant  = 0;
3151   aBitmapData.bmiHeader.biCompression   = BI_RGB;
3152   aBitmapData.bmiHeader.biSizeImage     = 0;
3153
3154   // Create Device Independent Bitmap
3155   void* aBitsOut = NULL;
3156   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
3157                                             &aBitsOut, NULL, 0);
3158   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
3159
3160   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
3161   if (aBitsOut != NULL)
3162   {
3163     if (aMode == 0)
3164       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
3165     else
3166       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_TILE);
3167
3168     // succesfully printed into an intermediate buffer
3169     if (isPrinted)
3170     {
3171       Image_PixMap aWrapper;
3172       aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
3173       aWrapper.SetTopDown (false);
3174
3175       Image_AlienPixMap anImageBitmap;
3176       anImageBitmap.InitCopy (aWrapper);
3177       isSaved = anImageBitmap.Save (aFileName);
3178     }
3179     else
3180     {
3181       di << "Print operation failed due to printing errors or\n";
3182       di << "insufficient memory available\n";
3183       di << "Please, try to use smaller dimensions for this test\n";
3184       di << "command, as it allocates intermediate buffer for storing\n";
3185       di << "the result\n";
3186     }
3187   }
3188   else
3189   {
3190     di << "Can't allocate memory for intermediate buffer\n";
3191     di << "Please use smaller dimensions\n";
3192   }
3193
3194   if (aMemoryBitmap)
3195   {
3196     SelectObject (anDC, anOldBitmap);
3197     DeleteObject (aMemoryBitmap);
3198     DeleteDC(anDC);
3199   }
3200
3201   if (!isSaved)
3202   {
3203     di << "Save to file operation failed. This operation may fail\n";
3204     di << "if you don't have enough available memory, then you can\n";
3205     di << "use smaller dimensions for the output file\n";
3206     return 1;
3207   }
3208
3209   return 0;
3210
3211 #endif
3212 }
3213
3214 //==============================================================================
3215 //function : VZLayer
3216 //purpose  : Test z layer operations for v3d viewer
3217 //==============================================================================
3218 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3219 {
3220   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3221   if (aContextAIS.IsNull())
3222   {
3223     di << "Call vinit before!\n";
3224     return 1;
3225   }
3226   else if (argc < 2)
3227   {
3228     di << "Use: vzlayer " << argv[0];
3229     di << " add/del/get [id]\n";
3230     di << " add - add new z layer to viewer and print its id\n";
3231     di << " del - del z layer by its id\n";
3232     di << " get - print sequence of z layers in increasing order of their overlay level\n";
3233     di << "id - the layer identificator value defined when removing z layer\n";
3234     return 1;
3235   }
3236
3237   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
3238   if (aViewer.IsNull())
3239   {
3240     di << "No active viewer!\n";
3241     return 1;
3242   }
3243
3244   // perform operation
3245   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
3246   if (anOp == "add")
3247   {
3248     Standard_Integer aNewId;
3249     if (!aViewer->AddZLayer (aNewId))
3250     {
3251       di << "Impossible to add new z layer!\n";
3252       return 1;
3253     }
3254
3255     di << "New z layer added with index: " << aNewId << "\n";
3256   }
3257   else if (anOp == "del")
3258   {
3259     if (argc < 3)
3260     {
3261       di << "Please also provide as argument id of z layer to remove\n";
3262       return 1;
3263     }
3264
3265     Standard_Integer aDelId = Draw::Atoi (argv[2]);
3266     if (!aViewer->RemoveZLayer (aDelId))
3267     {
3268       di << "Impossible to remove the z layer or invalid id!\n";
3269       return 1;
3270     }
3271
3272     di << "Z layer " << aDelId << " has been removed\n";
3273   }
3274   else if (anOp == "get")
3275   {
3276     TColStd_SequenceOfInteger anIds;
3277     aViewer->GetAllZLayers (anIds);
3278     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
3279     {
3280       di << anIds.Value (aSeqIdx) << " ";
3281     }
3282
3283     di << "\n";
3284   }
3285   else
3286   {
3287     di << "Invalid operation, please use { add / del / get }\n";
3288     return 1;
3289   }
3290
3291   return 0;
3292 }
3293
3294 DEFINE_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
3295
3296 // this class provides a presentation of text item in v3d view under-/overlayer
3297 class V3d_TextItem : public Visual3d_LayerItem
3298 {
3299 public:
3300
3301   // CASCADE RTTI
3302   DEFINE_STANDARD_RTTI(V3d_TextItem)
3303
3304   // constructor
3305   Standard_EXPORT V3d_TextItem(const TCollection_AsciiString& theText,
3306                                const Standard_Real theX1,
3307                                const Standard_Real theY1,
3308                                const Standard_Real theHeight,
3309                                const TCollection_AsciiString& theFontName,
3310                                const Quantity_Color& theColor,
3311                                const Quantity_Color& theSubtitleColor,
3312                                const Aspect_TypeOfDisplayText& theTypeOfDisplay,
3313                                const Handle(Visual3d_Layer)& theLayer);
3314
3315   // redraw method
3316   Standard_EXPORT void RedrawLayerPrs();
3317
3318 private:
3319
3320   Standard_Real            myX1;
3321   Standard_Real            myY1;
3322   Standard_Real            myHeight;
3323   TCollection_AsciiString  myText;
3324   TCollection_AsciiString  myFontName;
3325   Quantity_Color           myColor;
3326   Quantity_Color           mySubtitleColor;
3327   Aspect_TypeOfDisplayText myType;
3328   Handle(Visual3d_Layer)   myLayer;
3329
3330 };
3331
3332 IMPLEMENT_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
3333 IMPLEMENT_STANDARD_RTTIEXT(V3d_TextItem, Visual3d_LayerItem)
3334
3335 // create and add to display the text item
3336 V3d_TextItem::V3d_TextItem (const TCollection_AsciiString& theText,
3337                             const Standard_Real theX1,
3338                             const Standard_Real theY1,
3339                             const Standard_Real theHeight,
3340                             const TCollection_AsciiString& theFontName,
3341                             const Quantity_Color& theColor,
3342                             const Quantity_Color& theSubtitleColor,
3343                             const Aspect_TypeOfDisplayText& theTypeOfDisplay,
3344                             const Handle(Visual3d_Layer)& theLayer)
3345  : myX1 (theX1), myY1 (theY1),
3346    myText (theText),
3347    myHeight (theHeight),
3348    myLayer (theLayer),
3349    myColor (theColor),
3350    mySubtitleColor (theSubtitleColor),
3351    myType (theTypeOfDisplay),
3352    myFontName (theFontName)
3353 {
3354   if (!myLayer.IsNull ())
3355     myLayer->AddLayerItem (this);
3356 }
3357
3358 // render item
3359 void V3d_TextItem::RedrawLayerPrs ()
3360 {
3361   if (myLayer.IsNull ())
3362     return;
3363
3364   myLayer->SetColor (myColor);
3365   myLayer->SetTextAttributes (myFontName.ToCString (), myType, mySubtitleColor);
3366   myLayer->DrawText (myText.ToCString (), myX1, myY1, myHeight);
3367 }
3368
3369 DEFINE_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
3370
3371 // The Visual3d_LayerItem line item for "vlayerline" command
3372 // it provides a presentation of line with user-defined
3373 // linewidth, linetype and transparency.
3374 class V3d_LineItem : public Visual3d_LayerItem
3375 {
3376 public:
3377   // CASCADE RTTI
3378   DEFINE_STANDARD_RTTI(V3d_LineItem)
3379
3380   // constructor
3381   Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
3382                                Standard_Real X2, Standard_Real Y2,
3383                                V3d_LayerMgrPointer theLayerMgr,
3384                                Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
3385                                Standard_Real theWidth    = 0.5,
3386                                Standard_Real theTransp   = 1.0);
3387
3388   // redraw method
3389   Standard_EXPORT   void RedrawLayerPrs();
3390
3391 private:
3392
3393   Standard_Real       myX1, myY1, myX2, myY2;
3394   Standard_Real       myWidth;
3395   Standard_Real       myTransparency;
3396   Aspect_TypeOfLine   myType;
3397   V3d_LayerMgrPointer myLayerMgr;
3398 };
3399
3400 IMPLEMENT_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
3401 IMPLEMENT_STANDARD_RTTIEXT(V3d_LineItem, Visual3d_LayerItem)
3402
3403 // default constructor for line item
3404 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
3405                            Standard_Real X2, Standard_Real Y2,
3406                            V3d_LayerMgrPointer theLayerMgr,
3407                            Aspect_TypeOfLine theType,
3408                            Standard_Real theWidth,
3409                            Standard_Real theTransp) :
3410   myX1(X1), myY1(Y1), myX2(X2), myY2(Y2), myLayerMgr(theLayerMgr),
3411   myType(theType), myWidth(theWidth), myTransparency(theTransp)
3412 {
3413   if (myLayerMgr && !myLayerMgr->Overlay().IsNull())
3414     myLayerMgr->Overlay()->AddLayerItem (this);
3415 }
3416
3417 // render line
3418 void V3d_LineItem::RedrawLayerPrs ()
3419 {
3420   Handle (Visual3d_Layer) aOverlay;
3421
3422   if (myLayerMgr)
3423     aOverlay = myLayerMgr->Overlay();
3424
3425   if (!aOverlay.IsNull())
3426   {
3427     Quantity_Color aColor(1.0, 0, 0, Quantity_TOC_RGB);
3428     aOverlay->SetColor(aColor);
3429     aOverlay->SetTransparency((Standard_ShortReal)myTransparency);
3430     aOverlay->SetLineAttributes((Aspect_TypeOfLine)myType, myWidth);
3431     aOverlay->BeginPolyline();
3432     aOverlay->AddVertex(myX1, myY1);
3433     aOverlay->AddVertex(myX2, myY2);
3434     aOverlay->ClosePrimitive();
3435   }
3436 }
3437
3438 //=============================================================================
3439 //function : VLayerLine
3440 //purpose  : Draws line in the v3d view layer with given attributes: linetype,
3441 //         : linewidth, transparency coefficient
3442 //============================================================================
3443 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3444 {
3445   // get the active view
3446   Handle(V3d_View) aView = ViewerTest::CurrentView();
3447   if (aView.IsNull())
3448   {
3449     di << "Call vinit before!\n";
3450     return 1;
3451   }
3452   else if (argc < 5)
3453   {
3454     di << "Use: " << argv[0];
3455     di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
3456     di << " linetype : { 0 | 1 | 2 | 3 } \n";
3457     di << "              0 - solid  \n";
3458     di << "              1 - dashed \n";
3459     di << "              2 - dot    \n";
3460     di << "              3 - dashdot\n";
3461     di << " transparency : { 0.0 - 1.0 } \n";
3462     di << "                  0.0 - transparent\n";
3463     di << "                  1.0 - visible    \n";
3464     return 1;
3465   }
3466
3467   // get the input params
3468   Standard_Real X1 = Draw::Atof(argv[1]);
3469   Standard_Real Y1 = Draw::Atof(argv[2]);
3470   Standard_Real X2 = Draw::Atof(argv[3]);
3471   Standard_Real Y2 = Draw::Atof(argv[4]);
3472
3473   Standard_Real    aWidth = 0.5;
3474   Standard_Integer aType  = 0;
3475   Standard_Real    aTransparency = 1.0;
3476
3477   // has width
3478   if (argc > 5)
3479     aWidth = Draw::Atof(argv[5]);
3480
3481   // has type
3482   if (argc > 6)
3483      aType = (Standard_Integer) Draw::Atoi(argv[6]);
3484
3485   // has transparency
3486   if (argc > 7)
3487   {
3488     aTransparency = Draw::Atof(argv[7]);
3489     if (aTransparency < 0 || aTransparency > 1.0)
3490       aTransparency = 1.0;
3491   }
3492
3493   // select appropriate line type
3494   Aspect_TypeOfLine aLineType;
3495   switch (aType)
3496   {
3497     case 1:
3498       aLineType = Aspect_TOL_DASH;
3499     break;
3500
3501     case 2:
3502       aLineType = Aspect_TOL_DOT;
3503     break;
3504
3505     case 3:
3506       aLineType = Aspect_TOL_DOTDASH;
3507     break;
3508
3509     default:
3510       aLineType = Aspect_TOL_SOLID;
3511   }
3512
3513   // replace layer manager
3514   Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr(aView);
3515   aView->SetLayerMgr(aMgr);
3516
3517   // add line item
3518   Handle (V3d_LineItem) anItem = new V3d_LineItem(X1, Y1, X2, Y2,
3519                                                   aMgr.operator->(),
3520                                                   aLineType, aWidth,
3521                                                   aTransparency);
3522
3523   // update view
3524   aView->MustBeResized();
3525   aView->Redraw();
3526
3527   return 0;
3528 }
3529
3530 //=======================================================================
3531 //function : VOverlayText
3532 //purpose  : Test text displaying in view overlay
3533 //=======================================================================
3534 static int VOverlayText (Draw_Interpretor& di, Standard_Integer argc, const char**argv)
3535 {
3536   // get the active view
3537   Handle(V3d_View) aView = ViewerTest::CurrentView();
3538   if (aView.IsNull())
3539   {
3540     di << "No active view. Please call vinit.\n";
3541     return 1;
3542   }
3543   else if (argc < 4 || argc > 13)
3544   {
3545     di << "Use: " << argv[0];
3546     di << " text x y [height] [font_name] [text_color: R G B] [displayType]\n";
3547     di << "[background_color: R G B]\n";
3548     di << "  height - pixel height of the text (default=10.0)\n";
3549     di << "  font_name - name of font (default=courier)\n";
3550     di << "  text_color - R G B values of text color (default=255.0 255.0 255.0)\n";
3551     di << "  display_type = {normal/subtitle/decal/blend}, (default=normal)\n";
3552     di << "  background_color- R G B values used for subtitle and decal text\n";
3553     di << "(default=255.0 255.0 255.0)\n";
3554     return 1;
3555   }
3556
3557   TCollection_AsciiString aText (argv[1]);
3558   Standard_Real aPosX = Draw::Atof(argv[2]);
3559   Standard_Real aPosY = Draw::Atof(argv[3]);
3560   Standard_Real aHeight = (argc >= 5) ? Draw::Atof (argv[4]) : 10.0;
3561
3562   // font name
3563   TCollection_AsciiString aFontName = "Courier";
3564   if (argc >= 6)
3565     aFontName = TCollection_AsciiString (argv[5]);
3566
3567   // text colors
3568   Quantity_Parameter aColorRed   = 1.0;
3569   Quantity_Parameter aColorGreen = 1.0;
3570   Quantity_Parameter aColorBlue  = 1.0;
3571   if (argc >= 9)
3572   {
3573     aColorRed   = Draw::Atof (argv[6])/255.;
3574     aColorGreen = Draw::Atof (argv[7])/255.;
3575     aColorBlue  = Draw::Atof (argv[8])/255.;
3576   }
3577
3578   // display type
3579   TCollection_AsciiString aDispStr;
3580   if (argc >= 10)
3581     aDispStr = TCollection_AsciiString (argv[9]);
3582
3583   Aspect_TypeOfDisplayText aTextType = Aspect_TODT_NORMAL;
3584   if (aDispStr.IsEqual ("subtitle"))
3585     aTextType = Aspect_TODT_SUBTITLE;
3586   else if (aDispStr.IsEqual ("decal"))
3587     aTextType = Aspect_TODT_DEKALE;
3588   else if (aDispStr.IsEqual ("blend"))
3589     aTextType = Aspect_TODT_BLEND;
3590
3591   // subtitle color
3592   Quantity_Parameter aSubRed   = 1.0;
3593   Quantity_Parameter aSubGreen = 1.0;
3594   Quantity_Parameter aSubBlue  = 1.0;
3595   if (argc == 13)
3596   {
3597     aSubRed   = Draw::Atof (argv[10])/255.;
3598     aSubGreen = Draw::Atof (argv[11])/255.;
3599     aSubBlue  = Draw::Atof (argv[12])/255.;
3600   }
3601
3602   // check fo current overlay
3603   Handle(Visual3d_Layer) anOverlay = aView->Viewer()->Viewer()->OverLayer ();
3604   if (anOverlay.IsNull ())
3605   {
3606     Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr (aView);
3607     anOverlay = aMgr->Overlay ();
3608     aView->SetLayerMgr (aMgr);
3609   }
3610
3611   Quantity_Color aTextColor (aColorRed, aColorGreen,
3612     aColorBlue, Quantity_TOC_RGB);
3613   Quantity_Color aSubtColor (aSubRed, aSubGreen,
3614     aSubBlue, Quantity_TOC_RGB);
3615
3616   // add text item
3617   Handle(V3d_TextItem) anItem = new V3d_TextItem (aText, aPosX, aPosY,
3618     aHeight, aFontName, aTextColor, aSubtColor, aTextType, anOverlay);
3619
3620   // update view
3621   aView->MustBeResized();
3622   aView->Redraw();
3623
3624   return 0;
3625 }
3626
3627 //==============================================================================
3628 //function : VGrid
3629 //purpose  :
3630 //==============================================================================
3631
3632 static int VGrid (Draw_Interpretor& /*theDI*/,
3633                   Standard_Integer  theArgNb,
3634                   const char**      theArgVec)
3635 {
3636   // get the active view
3637   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3638   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3639   if (aView.IsNull() || aViewer.IsNull())
3640   {
3641     std::cerr << "No active view. Please call vinit.\n";
3642     return 1;
3643   }
3644
3645   Aspect_GridType     aType = aViewer->GridType();
3646   Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
3647
3648   Standard_Integer anIter = 1;
3649   for (; anIter < theArgNb; ++anIter)
3650   {
3651     const char* aValue = theArgVec[anIter];
3652     if (*aValue == 'r')
3653     {
3654       aType = Aspect_GT_Rectangular;
3655     }
3656     else if (*aValue == 'c')
3657     {
3658       aType = Aspect_GT_Circular;
3659     }
3660     else if (*aValue == 'l')
3661     {
3662       aMode = Aspect_GDM_Lines;
3663     }
3664     else if (*aValue == 'p')
3665     {
3666       aMode = Aspect_GDM_Points;
3667     }
3668     else if (strcmp (aValue, "off" ) == 0)
3669     {
3670       aViewer->DeactivateGrid();
3671       return 0;
3672     }
3673     else
3674     {
3675       break;
3676     }
3677   }
3678
3679   Standard_Integer aTail = (theArgNb - anIter);
3680   if (aTail == 0)
3681   {
3682     aViewer->ActivateGrid (aType, aMode);
3683     return 0;
3684   }
3685   else if (aTail != 2 && aTail != 5)
3686   {
3687     std::cerr << "Incorrect arguments number! Usage:\n"
3688               << "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]\n";
3689     return 1;
3690   }
3691
3692   Quantity_Length anOriginX, anOriginY;
3693   Quantity_PlaneAngle aRotAngle;
3694   if (aType == Aspect_GT_Rectangular)
3695   {
3696     Quantity_Length aRStepX, aRStepY;
3697     aViewer->RectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
3698
3699     anOriginX = Draw::Atof (theArgVec[anIter++]);
3700     anOriginY = Draw::Atof (theArgVec[anIter++]);
3701     if (aTail == 5)
3702     {
3703       aRStepX   = Draw::Atof (theArgVec[anIter++]);
3704       aRStepY   = Draw::Atof (theArgVec[anIter++]);
3705       aRotAngle = Draw::Atof (theArgVec[anIter++]);
3706     }
3707     aViewer->SetRectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
3708     aViewer->ActivateGrid (aType, aMode);
3709   }
3710   else if (aType == Aspect_GT_Circular)
3711   {
3712     Quantity_Length aRadiusStep;
3713     Standard_Integer aDivisionNumber;
3714     aViewer->CircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
3715
3716     anOriginX = Draw::Atof (theArgVec[anIter++]);
3717     anOriginY = Draw::Atof (theArgVec[anIter++]);
3718     if (aTail == 5)
3719     {
3720       aRadiusStep     = Draw::Atof (theArgVec[anIter++]);
3721       aDivisionNumber = Draw::Atoi (theArgVec[anIter++]);
3722       aRotAngle       = Draw::Atof (theArgVec[anIter++]);
3723     }
3724
3725     aViewer->SetCircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
3726     aViewer->ActivateGrid (aType, aMode);
3727   }
3728
3729   return 0;
3730 }
3731
3732 //==============================================================================
3733 //function : VFps
3734 //purpose  :
3735 //==============================================================================
3736
3737 static int VFps (Draw_Interpretor& theDI,
3738                  Standard_Integer  theArgNb,
3739                  const char**      theArgVec)
3740 {
3741   // get the active view
3742   Handle(V3d_View) aView = ViewerTest::CurrentView();
3743   if (aView.IsNull())
3744   {
3745     std::cerr << "No active view. Please call vinit.\n";
3746     return 1;
3747   }
3748
3749   Standard_Integer aFramesNb = (theArgNb > 1) ? Draw::Atoi(theArgVec[1]) : 100;
3750   if (aFramesNb <= 0)
3751   {
3752     std::cerr << "Incorrect arguments!\n";
3753     return 1;
3754   }
3755
3756   // the time is meaningless for first call
3757   // due to async OpenGl rendering
3758   aView->Redraw();
3759
3760   // redraw view in loop to estimate average values
3761   OSD_Timer aTimer;
3762   aTimer.Start();
3763   for (Standard_Integer anInter = 0; anInter < aFramesNb; ++anInter)
3764   {
3765     aView->Redraw();
3766   }
3767   aTimer.Stop();
3768   Standard_Real aCpu;
3769   const Standard_Real aTime = aTimer.ElapsedTime();
3770   aTimer.OSD_Chronometer::Show (aCpu);
3771
3772   const Standard_Real aFpsAver = Standard_Real(aFramesNb) / aTime;
3773   const Standard_Real aCpuAver = aCpu / Standard_Real(aFramesNb);
3774
3775   // return statistics
3776   theDI << "FPS: " << aFpsAver << "\n"
3777         << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
3778
3779   return 0;
3780 }
3781
3782 //==============================================================================
3783 //function : VGlDebug
3784 //purpose  :
3785 //==============================================================================
3786
3787 static int VGlDebug (Draw_Interpretor& theDI,
3788                      Standard_Integer  theArgNb,
3789                      const char**      theArgVec)
3790 {
3791   if (theArgNb < 2)
3792   {
3793     Handle(V3d_View) aView = ViewerTest::CurrentView();
3794     if (aView.IsNull())
3795     {
3796       std::cerr << "No active view. Please call vinit.\n";
3797       return 0;
3798     }
3799
3800     Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS),
3801                                                                 "GL_ARB_debug_output");
3802     std::cout << "Active graphic driver: debug " << (isActive ? "ON" : "OFF") << "\n";
3803     theDI << (isActive ? "1" : "0");
3804     return 0;
3805   }
3806
3807   ViewerTest_myDefaultCaps.contextDebug = Draw::Atoi (theArgVec[1]) != 0;
3808   return 0;
3809 }
3810
3811 //==============================================================================
3812 //function : VVbo
3813 //purpose  :
3814 //==============================================================================
3815
3816 static int VVbo (Draw_Interpretor& theDI,
3817                  Standard_Integer  theArgNb,
3818                  const char**      theArgVec)
3819 {
3820   const Standard_Boolean toSet    = (theArgNb > 1);
3821   const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
3822   if (toSet)
3823   {
3824     ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
3825   }
3826
3827   // get the context
3828   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3829   if (aContextAIS.IsNull())
3830   {
3831     if (!toSet)
3832     {
3833       std::cerr << "No active view!\n";
3834     }
3835     return 1;
3836   }
3837   Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
3838   if (!aDriver.IsNull())
3839   {
3840     if (!toSet)
3841     {
3842       theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
3843     }
3844     else
3845     {
3846       aDriver->ChangeOptions().vboDisable = toUseVbo;
3847     }
3848   }
3849
3850   return 0;
3851 }
3852
3853 //==============================================================================
3854 //function : VCaps
3855 //purpose  :
3856 //==============================================================================
3857
3858 static int VCaps (Draw_Interpretor& theDI,
3859                   Standard_Integer  theArgNb,
3860                   const char**      theArgVec)
3861 {
3862   OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
3863   Handle(OpenGl_GraphicDriver)   aDriver;
3864   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3865   if (!aContextAIS.IsNull())
3866   {
3867     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
3868     aCaps   = &aDriver->ChangeOptions();
3869   }
3870
3871   if (theArgNb < 2)
3872   {
3873     theDI << "VBO:     " << (aCaps->vboDisable        ? "0" : "1") << "\n";
3874     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
3875     return 0;
3876   }
3877
3878   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3879   {
3880     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
3881     if (anArg.Search ("vbo=") > -1)
3882     {
3883       aCaps->vboDisable        = anArg.Token ("=", 2).IntegerValue() == 0;
3884     }
3885     else if (anArg.Search ("sprites=") > -1)
3886     {
3887       aCaps->pntSpritesDisable = anArg.Token ("=", 2).IntegerValue() == 0;
3888     }
3889     else
3890     {
3891       std::cerr << "Unknown argument: " << anArg << "\n";
3892     }
3893   }
3894   if (aCaps != &ViewerTest_myDefaultCaps)
3895   {
3896     ViewerTest_myDefaultCaps = *aCaps;
3897   }
3898   return 0;
3899 }
3900
3901 //==============================================================================
3902 //function : VMemGpu
3903 //purpose  :
3904 //==============================================================================
3905
3906 static int VMemGpu (Draw_Interpretor& theDI,
3907                     Standard_Integer  theArgNb,
3908                     const char**      theArgVec)
3909 {
3910   // get the context
3911   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3912   if (aContextAIS.IsNull())
3913   {
3914     std::cerr << "No active view. Please call vinit.\n";
3915     return 1;
3916   }
3917
3918   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
3919   if (aDriver.IsNull())
3920   {
3921     std::cerr << "Graphic driver not available.\n";
3922     return 1;
3923   }
3924
3925   Standard_Size aFreeBytes = 0;
3926   TCollection_AsciiString anInfo;
3927   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
3928   {
3929     std::cerr << "Information not available.\n";
3930     return 1;
3931   }
3932
3933   if (theArgNb > 1 && *theArgVec[1] == 'f')
3934   {
3935     theDI << Standard_Real (aFreeBytes);
3936   }
3937   else
3938   {
3939     theDI << anInfo;
3940   }
3941
3942   return 0;
3943 }
3944
3945 // ==============================================================================
3946 // function : VReadPixel
3947 // purpose  :
3948 // ==============================================================================
3949 static int VReadPixel (Draw_Interpretor& theDI,
3950                        Standard_Integer  theArgNb,
3951                        const char**      theArgVec)
3952 {
3953   // get the active view
3954   Handle(V3d_View) aView = ViewerTest::CurrentView();
3955   if (aView.IsNull())
3956   {
3957     std::cerr << "No active view. Please call vinit.\n";
3958     return 1;
3959   }
3960   else if (theArgNb < 3)
3961   {
3962     std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
3963     return 1;
3964   }
3965
3966   Image_PixMap::ImgFormat aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
3967   Graphic3d_BufferType    aBufferType = Graphic3d_BT_RGBA;
3968
3969   Standard_Integer aWidth, aHeight;
3970   aView->Window()->Size (aWidth, aHeight);
3971   const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
3972   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
3973   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
3974   {
3975     std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
3976     return 1;
3977   }
3978
3979   Standard_Boolean toShowName = Standard_False;
3980   Standard_Boolean toShowHls  = Standard_False;
3981   for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
3982   {
3983     const char* aParam = theArgVec[anIter];
3984     if ( strcasecmp( aParam, "rgb" ) == 0 )
3985     {
3986       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
3987       aBufferType = Graphic3d_BT_RGB;
3988     }
3989     else if ( strcasecmp( aParam, "hls" ) == 0 )
3990     {
3991       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
3992       aBufferType = Graphic3d_BT_RGB;
3993       toShowHls   = Standard_True;
3994     }
3995     else if ( strcasecmp( aParam, "rgbf" ) == 0 )
3996     {
3997       aFormat     = Image_PixMap::ImgRGBF;
3998       aBufferType = Graphic3d_BT_RGB;
3999     }
4000     else if ( strcasecmp( aParam, "rgba" ) == 0 )
4001     {
4002       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
4003       aBufferType = Graphic3d_BT_RGBA;
4004     }
4005     else if ( strcasecmp( aParam, "rgbaf" ) == 0 )
4006     {
4007       aFormat     = Image_PixMap::ImgRGBAF;
4008       aBufferType = Graphic3d_BT_RGBA;
4009     }
4010     else if ( strcasecmp( aParam, "depth" ) == 0 )
4011     {
4012       aFormat     = Image_PixMap::ImgGrayF;
4013       aBufferType = Graphic3d_BT_Depth;
4014     }
4015     else if ( strcasecmp( aParam, "name" ) == 0 )
4016     {
4017       toShowName = Standard_True;
4018     }
4019   }
4020
4021   Image_PixMap anImage;
4022   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
4023   {
4024     std::cerr << "Image allocation failed\n";
4025     return 1;
4026   }
4027   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
4028   {
4029     std::cerr << "Image dump failed\n";
4030     return 1;
4031   }
4032
4033   Quantity_Parameter anAlpha;
4034   Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
4035   if (toShowName)
4036   {
4037     if (aBufferType == Graphic3d_BT_RGBA)
4038     {
4039       theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha << "\n";
4040     }
4041     else
4042     {
4043       theDI << Quantity_Color::StringName (aColor.Name()) << "\n";
4044     }
4045   }
4046   else
4047   {
4048     switch (aBufferType)
4049     {
4050       default:
4051       case Graphic3d_BT_RGB:
4052       {
4053         if (toShowHls)
4054         {
4055           theDI << aColor.Hue() << " " << aColor.Light() << " " << aColor.Saturation() << "\n";
4056         }
4057         else
4058         {
4059           theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << "\n";
4060         }
4061         break;
4062       }
4063       case Graphic3d_BT_RGBA:
4064       {
4065         theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha << "\n";
4066         break;
4067       }
4068       case Graphic3d_BT_Depth:
4069       {
4070         theDI << aColor.Red() << "\n";
4071         break;
4072       }
4073     }
4074   }
4075
4076   return 0;
4077 }
4078
4079 //==============================================================================
4080 //function : VDiffImage
4081 //purpose  : The draw-command compares two images.
4082 //==============================================================================
4083
4084 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
4085 {
4086   if (theArgNb < 6)
4087   {
4088     theDI << "Not enough arguments.\n";
4089     return 1;
4090   }
4091
4092   // image file names
4093   const char* anImgPathRef = theArgVec[1];
4094   const char* anImgPathNew = theArgVec[2];
4095
4096   // get string tolerance and check its validity
4097   Standard_Real aTolColor = Draw::Atof (theArgVec[3]);
4098   if (aTolColor < 0.0)
4099     aTolColor = 0.0;
4100   if (aTolColor > 1.0)
4101     aTolColor = 1.0;
4102
4103   Standard_Boolean toBlackWhite     = (Draw::Atoi (theArgVec[4]) == 1);
4104   Standard_Boolean isBorderFilterOn = (Draw::Atoi (theArgVec[5]) == 1);
4105
4106   // image file of difference
4107   const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
4108
4109   // compare the images
4110   Image_Diff aComparer;
4111   if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
4112   {
4113     return 1;
4114   }
4115
4116   aComparer.SetColorTolerance (aTolColor);
4117   aComparer.SetBorderFilterOn (isBorderFilterOn);
4118   Standard_Integer aDiffColorsNb = aComparer.Compare();
4119   theDI << aDiffColorsNb << "\n";
4120
4121   // save image of difference
4122   if (aDiffImagePath != NULL)
4123   {
4124     aComparer.SaveDiffImage (aDiffImagePath);
4125   }
4126
4127   return 0;
4128 }
4129
4130 //=======================================================================
4131 //function : VSelect
4132 //purpose  : Emulates different types of selection by mouse:
4133 //           1) single click selection
4134 //           2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
4135 //           3) selection with polygon having corners at
4136 //           pixel positions (x1,y1),...,(xn,yn)
4137 //           4) any of these selections with shift button pressed
4138 //=======================================================================
4139 static Standard_Integer VSelect (Draw_Interpretor& di,
4140                                  Standard_Integer argc,
4141                                  const char ** argv)
4142 {
4143   if(argc < 3)
4144   {
4145     di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]" << "\n";
4146     return 1;
4147   }
4148
4149   Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
4150   if(myAIScontext.IsNull())
4151   {
4152     di << "use 'vinit' command before " << argv[0] << "\n";
4153     return 1;
4154   }
4155   const Standard_Boolean isShiftSelection = (argc>3 && !(argc%2) && (atoi(argv[argc-1])==1));
4156   Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
4157   aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
4158   if(argc <= 4)
4159   {
4160     if(isShiftSelection)
4161       aCurrentEventManager->ShiftSelect();
4162     else
4163       aCurrentEventManager->Select();
4164   }
4165   else if(argc <= 6)
4166   {
4167     if(isShiftSelection)
4168       aCurrentEventManager->ShiftSelect(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
4169     else
4170       aCurrentEventManager->Select(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
4171   }
4172   else
4173   {
4174     Standard_Integer anUpper = 0;
4175
4176     if(isShiftSelection)
4177       anUpper = (argc-1)/2;
4178     else
4179       anUpper = argc/2;
4180     TColgp_Array1OfPnt2d aPolyline(1,anUpper);
4181
4182     for(Standard_Integer i=1;i<=anUpper;++i)
4183       aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
4184
4185     if(isShiftSelection)
4186       aCurrentEventManager->ShiftSelect(aPolyline);
4187     else
4188       aCurrentEventManager->Select(aPolyline);
4189   }
4190   return 0;
4191 }
4192
4193 //=======================================================================
4194 //function : VMoveTo
4195 //purpose  : Emulates cursor movement to defined pixel position
4196 //=======================================================================
4197 static Standard_Integer VMoveTo (Draw_Interpretor& di,
4198                                 Standard_Integer argc,
4199                                 const char ** argv)
4200 {
4201   if(argc != 3)
4202   {
4203     di << "Usage : " << argv[0] << " x y" << "\n";
4204     return 1;
4205   }
4206
4207   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4208   if(aContext.IsNull())
4209   {
4210     di << "use 'vinit' command before " << argv[0] << "\n";
4211     return 1;
4212   }
4213   ViewerTest::CurrentEventManager()->MoveTo(atoi(argv[1]),atoi(argv[2]));
4214   return 0;
4215 }
4216
4217 //=======================================================================
4218 //function : VViewParams
4219 //purpose  : Gets or sets AIS View characteristics
4220 //=======================================================================
4221 static Standard_Integer VViewParams (Draw_Interpretor& di,
4222                                 Standard_Integer argc,
4223                                 const char ** argv)
4224 {
4225   if ( argc != 1 && argc != 13)
4226   {
4227     di << "Usage : " << argv[0] << "\n";
4228     return 1;
4229   }
4230   Handle (V3d_View) anAISView = ViewerTest::CurrentView ();
4231   if ( anAISView.IsNull () )
4232   {
4233     di << "use 'vinit' command before " << argv[0] << "\n";
4234     return 1;
4235   }
4236   if(argc==1){
4237     Quantity_Factor anAISViewScale = anAISView -> V3d_View::Scale ();
4238     Standard_Real anAISViewCenterCoordinateX = 0.0;
4239     Standard_Real anAISViewCenterCoordinateY = 0.0;
4240     anAISView -> V3d_View::Center (anAISViewCenterCoordinateX, anAISViewCenterCoordinateY);
4241     Standard_Real anAISViewProjX = 0.0;
4242     Standard_Real anAISViewProjY = 0.0;
4243     Standard_Real anAISViewProjZ = 0.0;
4244     anAISView -> V3d_View::Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
4245     Standard_Real anAISViewUpX = 0.0;
4246     Standard_Real anAISViewUpY = 0.0;
4247     Standard_Real anAISViewUpZ = 0.0;
4248     anAISView -> V3d_View::Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
4249     Standard_Real anAISViewAtX = 0.0;
4250     Standard_Real anAISViewAtY = 0.0;
4251     Standard_Real anAISViewAtZ = 0.0;
4252     anAISView -> V3d_View::At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
4253     di << "Scale of current view: " << anAISViewScale << "\n";
4254     di << "Center on X : "<< anAISViewCenterCoordinateX << "; on Y: " << anAISViewCenterCoordinateY << "\n";
4255     di << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
4256     di << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
4257     di << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
4258   }
4259   else
4260   {
4261     Quantity_Factor anAISViewScale = atof (argv [1]);
4262     Standard_Real anAISViewCenterCoordinateX = atof (argv [2]);
4263     Standard_Real anAISViewCenterCoordinateY = atof (argv [3]);
4264     Standard_Real anAISViewProjX = atof (argv [4]);
4265     Standard_Real anAISViewProjY = atof (argv [5]);
4266     Standard_Real anAISViewProjZ = atof (argv [6]);
4267     Standard_Real anAISViewUpX = atof (argv [7]);
4268     Standard_Real anAISViewUpY = atof (argv [8]);
4269     Standard_Real anAISViewUpZ = atof (argv [9]);
4270     Standard_Real anAISViewAtX = atof (argv [10]);
4271     Standard_Real anAISViewAtY = atof (argv [11]);
4272     Standard_Real anAISViewAtZ = atof (argv [12]);
4273     anAISView -> V3d_View::SetScale (anAISViewScale);
4274     anAISView -> V3d_View::SetCenter (anAISViewCenterCoordinateX, anAISViewCenterCoordinateY);
4275     anAISView -> V3d_View::SetAt (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
4276     anAISView -> V3d_View::SetProj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
4277     anAISView -> V3d_View::SetUp (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
4278   }
4279   return 0;
4280 }
4281
4282 //=======================================================================
4283 //function : VChangeSelected
4284 //purpose  : Adds the shape to selection or remove one from it
4285 //=======================================================================
4286 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
4287                                 Standard_Integer argc,
4288                                 const char ** argv)
4289 {
4290   if(argc != 2)
4291   {
4292     di<<"Usage : " << argv[0] << " shape \n";
4293     return 1;
4294   }
4295   //get AIS_Shape:
4296   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4297   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4298   TCollection_AsciiString aName(argv[1]);
4299   Handle(AIS_InteractiveObject) anAISObject;
4300
4301   if(!aMap.IsBound2(aName))
4302   {
4303     di<<"Use 'vdisplay' before";
4304     return 1;
4305   }
4306   else
4307   {
4308     anAISObject = Handle(AIS_InteractiveObject)::DownCast(aMap.Find2(aName));
4309     if(anAISObject.IsNull()){
4310       di<<"No interactive object \n";
4311       return 1;
4312     }
4313
4314     if(aContext->HasOpenedContext())
4315     {
4316       aContext->AddOrRemoveSelected(anAISObject);
4317     }
4318     else
4319     {
4320       aContext->AddOrRemoveCurrentObject(anAISObject);
4321     }
4322   }
4323   return 0;
4324 }
4325
4326 //=======================================================================
4327 //function : VZClipping
4328 //purpose  : Gets or sets ZClipping mode, width and depth
4329 //=======================================================================
4330 static Standard_Integer VZClipping (Draw_Interpretor& di,
4331                                 Standard_Integer argc,
4332                                 const char ** argv)
4333 {
4334   if(argc>4)
4335   {
4336     di << "Usage : " << argv[0] << " [mode] [depth  width]" << "\n"
4337       <<"mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4338     return -1;
4339   }
4340   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4341   if(aContext.IsNull())
4342   {
4343     di << "use 'vinit' command before " << argv[0] << "\n";
4344     return 1;
4345   }
4346   Handle(V3d_View) aView = ViewerTest::CurrentView();
4347   V3d_TypeOfZclipping aZClippingMode = V3d_OFF;
4348   if(argc==1)
4349   {
4350     TCollection_AsciiString aZClippingModeString;
4351     Quantity_Length aDepth, aWidth;
4352     aZClippingMode = aView->ZClipping(aDepth, aWidth);
4353     switch (aZClippingMode)
4354     {
4355     case V3d_OFF:
4356       aZClippingModeString.Copy("OFF");
4357       break;
4358     case V3d_BACK:
4359       aZClippingModeString.Copy("BACK");
4360       break;
4361     case V3d_FRONT:
4362       aZClippingModeString.Copy("FRONT");
4363       break;
4364     case V3d_SLICE:
4365       aZClippingModeString.Copy("SLICE");
4366       break;
4367     default:
4368       aZClippingModeString.Copy(TCollection_AsciiString(aZClippingMode));
4369       break;
4370     }
4371     di << "ZClippingMode = " << aZClippingModeString.ToCString() << "\n"
4372       << "ZClipping depth = " << aDepth << "\n"
4373       << "ZClipping width = " << aWidth << "\n";
4374   }
4375   else
4376   {
4377     if(argc !=3)
4378     {
4379       Standard_Integer aStatus = 0;
4380       if ( strcmp (argv [1], "OFF") == 0 ) {
4381         aStatus = 1;
4382         aZClippingMode = V3d_OFF;
4383       }
4384       if ( strcmp (argv [1], "BACK") == 0 ) {
4385         aStatus = 1;
4386         aZClippingMode = V3d_BACK;
4387       }
4388       if ( strcmp (argv [1], "FRONT") == 0 ) {
4389         aStatus = 1;
4390         aZClippingMode = V3d_FRONT;
4391       }
4392       if ( strcmp (argv [1], "SLICE") == 0 ) {
4393         aStatus = 1;
4394         aZClippingMode = V3d_SLICE;
4395       }
4396       if (aStatus != 1)
4397       {
4398         di << "Bad mode; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4399           << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4400         return 1;
4401       }
4402       aView->SetZClippingType(aZClippingMode);
4403     }
4404     if(argc >2)
4405     {
4406       Quantity_Length aDepth = 0., aWidth = 1.;
4407       if(argc == 3)
4408       {
4409         aDepth = atof(argv[1]);
4410         aWidth = atof(argv[2]);
4411       }
4412       else if(argc == 4)
4413       {
4414         aDepth = atof(argv[2]);
4415         aWidth = atof(argv[3]);
4416       }
4417
4418       if(aDepth<0. || aDepth>1.)
4419       {
4420         di << "Bad depth; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4421         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4422         return 1;
4423       }
4424       if(aWidth<0. || aWidth>1.)
4425       {
4426         di << "Bad width; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4427         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4428         return 1;
4429       }
4430
4431       aView->SetZClippingDepth(aDepth);
4432       aView->SetZClippingWidth(aWidth);
4433     }
4434     aView->Redraw();
4435   }
4436   return 0;
4437 }
4438
4439 //=======================================================================
4440 //function : VNbSelected
4441 //purpose  : Returns number of selected objects
4442 //=======================================================================
4443 static Standard_Integer VNbSelected (Draw_Interpretor& di,
4444                                 Standard_Integer argc,
4445                                 const char ** argv)
4446 {
4447   if(argc != 1)
4448   {
4449     di << "Usage : " << argv[0] << "\n";
4450     return 1;
4451   }
4452   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4453   if(aContext.IsNull())
4454   {
4455     di << "use 'vinit' command before " << argv[0] << "\n";
4456     return 1;
4457   }
4458   di << aContext->NbSelected() << "\n";
4459   return 0;
4460 }
4461
4462 //=======================================================================
4463 //function : VAntialiasing
4464 //purpose  : Switches altialiasing on or off
4465 //=======================================================================
4466 static Standard_Integer VAntialiasing (Draw_Interpretor& di,
4467                                 Standard_Integer argc,
4468                                 const char ** argv)
4469 {
4470   if(argc > 2)
4471   {
4472     di << "Usage : " << argv[0] << " [1|0]" << "\n";
4473     return 1;
4474   }
4475
4476   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4477   if(aContext.IsNull())
4478   {
4479     di << "use 'vinit' command before " << argv[0] << "\n";
4480     return 1;
4481   }
4482
4483   Handle(V3d_View) aView = ViewerTest::CurrentView();
4484
4485   if((argc == 2) && (atof(argv[1]) == 0))
4486     aView->SetAntialiasingOff();
4487   else
4488     aView->SetAntialiasingOn();
4489   aView->Update();
4490   return 0;
4491 }
4492
4493 //=======================================================================
4494 //function : VPurgeDisplay
4495 //purpose  : Switches altialiasing on or off
4496 //=======================================================================
4497 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
4498                                 Standard_Integer argc,
4499                                 const char ** argv)
4500 {
4501   if (argc > 2)
4502   {
4503     di << "Usage : " << argv[0] << " [CollectorToo = 0|1]" << "\n";
4504     return 1;
4505   }
4506   Standard_Boolean isCollectorToo = Standard_False;
4507   if (argc == 2)
4508   {
4509       isCollectorToo = (atoi(argv [1]) != 0);
4510   }
4511   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4512   if (aContext.IsNull())
4513   {
4514     di << "use 'vinit' command before " << argv[0] << "\n";
4515     return 1;
4516   }
4517   aContext->CloseAllContexts(Standard_False);
4518   di << aContext->PurgeDisplay(isCollectorToo) << "\n";
4519   return 0;
4520 }
4521
4522 //=======================================================================
4523 //function : VSetViewSize
4524 //purpose  :
4525 //=======================================================================
4526 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
4527                                 Standard_Integer argc,
4528                                 const char ** argv)
4529 {
4530   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4531   if(aContext.IsNull())
4532   {
4533     di << "use 'vinit' command before " << argv[0] << "\n";
4534     return 1;
4535   }
4536   if(argc != 2)
4537   {
4538     di<<"Usage : " << argv[0] << " Size\n";
4539     return 1;
4540   }
4541   Standard_Real aSize = atof(argv[1]);
4542   if (aSize <= 0.)
4543   {
4544     di<<"Bad Size value  : " << aSize << "\n";
4545     return 1;
4546   }
4547
4548   Handle(V3d_View) aView = ViewerTest::CurrentView();
4549   aView->SetSize(aSize);
4550   return 0;
4551 }
4552
4553 //=======================================================================
4554 //function : VMoveView
4555 //purpose  :
4556 //=======================================================================
4557 static Standard_Integer VMoveView (Draw_Interpretor& di,
4558                                 Standard_Integer argc,
4559                                 const char ** argv)
4560 {
4561   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4562   if(aContext.IsNull())
4563   {
4564     di << "use 'vinit' command before " << argv[0] << "\n";
4565     return 1;
4566   }
4567   if(argc < 4 || argc > 5)
4568   {
4569     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
4570     return 1;
4571   }
4572   Standard_Real Dx = atof(argv[1]);
4573   Standard_Real Dy = atof(argv[2]);
4574   Standard_Real Dz = atof(argv[3]);
4575   Standard_Boolean aStart = Standard_True;
4576   if (argc == 5)
4577   {
4578       aStart = (atoi(argv[4]) > 0);
4579   }
4580
4581   Handle(V3d_View) aView = ViewerTest::CurrentView();
4582   aView->Move(Dx,Dy,Dz,aStart);
4583   return 0;
4584 }
4585
4586 //=======================================================================
4587 //function : VTranslateView
4588 //purpose  :
4589 //=======================================================================
4590 static Standard_Integer VTranslateView (Draw_Interpretor& di,
4591                                 Standard_Integer argc,
4592                                 const char ** argv)
4593 {
4594   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4595   if(aContext.IsNull())
4596   {
4597     di << "use 'vinit' command before " << argv[0] << "\n";
4598     return 1;
4599   }
4600   if(argc < 4 || argc > 5)
4601   {
4602     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
4603     return 1;
4604   }
4605   Standard_Real Dx = atof(argv[1]);
4606   Standard_Real Dy = atof(argv[2]);
4607   Standard_Real Dz = atof(argv[3]);
4608   Standard_Boolean aStart = Standard_True;
4609   if (argc == 5)
4610   {
4611       aStart = (atoi(argv[4]) > 0);
4612   }
4613
4614   Handle(V3d_View) aView = ViewerTest::CurrentView();
4615   aView->Translate(Dx,Dy,Dz,aStart);
4616   return 0;
4617 }
4618
4619 //=======================================================================
4620 //function : VTurnView
4621 //purpose  :
4622 //=======================================================================
4623 static Standard_Integer VTurnView (Draw_Interpretor& di,
4624                                 Standard_Integer argc,
4625                                 const char ** argv)
4626 {
4627   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4628   if(aContext.IsNull()) {
4629     di << "use 'vinit' command before " << argv[0] << "\n";
4630     return 1;
4631   }
4632   if(argc < 4 || argc > 5){
4633     di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
4634     return 1;
4635   }
4636   Standard_Real Ax = atof(argv[1]);
4637   Standard_Real Ay = atof(argv[2]);
4638   Standard_Real Az = atof(argv[3]);
4639   Standard_Boolean aStart = Standard_True;
4640   if (argc == 5)
4641   {
4642       aStart = (atoi(argv[4]) > 0);
4643   }
4644
4645   Handle(V3d_View) aView = ViewerTest::CurrentView();
4646   aView->Turn(Ax,Ay,Az,aStart);
4647   return 0;
4648 }
4649
4650 //==============================================================================
4651 //function : VTextureEnv
4652 //purpose  : ENables or disables environment mapping
4653 //==============================================================================
4654 class OCC_TextureEnv : public Graphic3d_TextureEnv
4655 {
4656 public:
4657   OCC_TextureEnv(const Standard_CString FileName);
4658   OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
4659   void SetTextureParameters(const Standard_Boolean theRepeatFlag,
4660                             const Standard_Boolean theModulateFlag,
4661                             const Graphic3d_TypeOfTextureFilter theFilter,
4662                             const Standard_ShortReal theXScale,
4663                             const Standard_ShortReal theYScale,
4664                             const Standard_ShortReal theXShift,
4665                             const Standard_ShortReal theYShift,
4666                             const Standard_ShortReal theAngle);
4667   DEFINE_STANDARD_RTTI(OCC_TextureEnv);
4668 };
4669 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
4670 IMPLEMENT_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
4671 IMPLEMENT_STANDARD_RTTIEXT(OCC_TextureEnv, Graphic3d_TextureEnv);
4672
4673 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
4674   : Graphic3d_TextureEnv(theFileName)
4675 {
4676 }
4677
4678 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
4679   : Graphic3d_TextureEnv(theTexId)
4680 {
4681 }
4682
4683 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
4684                                           const Standard_Boolean theModulateFlag,
4685                                           const Graphic3d_TypeOfTextureFilter theFilter,
4686                                           const Standard_ShortReal theXScale,
4687                                           const Standard_ShortReal theYScale,
4688                                           const Standard_ShortReal theXShift,
4689                                           const Standard_ShortReal theYShift,
4690                                           const Standard_ShortReal theAngle)
4691 {
4692   myParams->SetRepeat     (theRepeatFlag);
4693   myParams->SetModulate   (theModulateFlag);
4694   myParams->SetFilter     (theFilter);
4695   myParams->SetScale      (Graphic3d_Vec2(theXScale, theYScale));
4696   myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
4697   myParams->SetRotation   (theAngle);
4698 }
4699
4700 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
4701 {
4702   // get the active view
4703   Handle(V3d_View) aView = ViewerTest::CurrentView();
4704   if (aView.IsNull())
4705   {
4706     std::cerr << "No active view. Please call vinit.\n";
4707     return 1;
4708   }
4709
4710   // Checking the input arguments
4711   Standard_Boolean anEnableFlag = Standard_False;
4712   Standard_Boolean isOk         = theArgNb >= 2;
4713   if (isOk)
4714   {
4715     TCollection_AsciiString anEnableOpt(theArgVec[1]);
4716     anEnableFlag = anEnableOpt.IsEqual("on");
4717     isOk         = anEnableFlag || anEnableOpt.IsEqual("off");
4718   }
4719   if (anEnableFlag)
4720   {
4721     isOk = (theArgNb == 3 || theArgNb == 11);
4722     if (isOk)
4723     {
4724       TCollection_AsciiString aTextureOpt(theArgVec[2]);
4725       isOk = (!aTextureOpt.IsIntegerValue() ||
4726              (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
4727
4728       if (isOk && theArgNb == 11)
4729       {
4730         TCollection_AsciiString aRepeatOpt  (theArgVec[3]),
4731                                 aModulateOpt(theArgVec[4]),
4732                                 aFilterOpt  (theArgVec[5]),
4733                                 aSScaleOpt  (theArgVec[6]),
4734                                 aTScaleOpt  (theArgVec[7]),
4735                                 aSTransOpt  (theArgVec[8]),
4736                                 aTTransOpt  (theArgVec[9]),
4737                                 anAngleOpt  (theArgVec[10]);
4738         isOk = ((aRepeatOpt.  IsEqual("repeat")   || aRepeatOpt.  IsEqual("clamp")) &&
4739                 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
4740                 (aFilterOpt.  IsEqual("nearest")  || aFilterOpt.  IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
4741                 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
4742                 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
4743                 anAngleOpt.IsRealValue());
4744       }
4745     }
4746   }
4747
4748   if (!isOk)
4749   {
4750     std::cerr << "Usage :" << std::endl;
4751     std::cerr << theArgVec[0] << " off" << std::endl;
4752     std::cerr << theArgVec[0] << " on {index_of_std_texture(0..7)|texture_file_name} [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} scale_s scale_t translation_s translation_t rotation_degrees]" << std::endl;
4753     return 1;
4754   }
4755
4756   if (anEnableFlag)
4757   {
4758     TCollection_AsciiString aTextureOpt(theArgVec[2]);
4759     Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
4760                                      new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
4761                                      new OCC_TextureEnv(theArgVec[2]);
4762
4763     if (theArgNb == 11)
4764     {
4765       TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
4766       aTexEnv->SetTextureParameters(
4767         aRepeatOpt.  IsEqual("repeat"),
4768         aModulateOpt.IsEqual("modulate"),
4769         aFilterOpt.  IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
4770                                           aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
4771                                                                            Graphic3d_TOTF_TRILINEAR,
4772         (Standard_ShortReal)Draw::Atof(theArgVec[6]),
4773         (Standard_ShortReal)Draw::Atof(theArgVec[7]),
4774         (Standard_ShortReal)Draw::Atof(theArgVec[8]),
4775         (Standard_ShortReal)Draw::Atof(theArgVec[9]),
4776         (Standard_ShortReal)Draw::Atof(theArgVec[10])
4777         );
4778     }
4779     aView->SetTextureEnv(aTexEnv);
4780     aView->SetSurfaceDetail(V3d_TEX_ENVIRONMENT);
4781   }
4782   else // Disabling environment mapping
4783   {
4784     aView->SetSurfaceDetail(V3d_TEX_NONE);
4785     Handle(Graphic3d_TextureEnv) aTexture;
4786     aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
4787   }
4788
4789   aView->Redraw();
4790   return 0;
4791 }
4792
4793 //=======================================================================
4794 //function : ViewerCommands
4795 //purpose  :
4796 //=======================================================================
4797
4798 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
4799 {
4800
4801   const char *group = "ZeViewer";
4802   theCommands.Add("vinit",
4803 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
4804     "[name=view_name] [display=display_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
4805 #else
4806     "[name=view_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
4807 #endif
4808     " - Creates new View window with specified name view_name.\n"
4809     "By default the new view is created in the viewer and in"
4810     " graphic driver shared with active view.\n"
4811     " - name = {driverName/viewerName/viewName | viewerName/viewName | viewName}.\n"
4812     "If driverName isn't specified the driver will be shared with active view.\n"
4813     "If viewerName isn't specified the viewer will be shared with active view.\n"
4814 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
4815     " - display = HostName.DisplayNumber[:ScreenNumber] : if specified"
4816     "is used in creation of graphic driver\n"
4817 #endif
4818     " - l, t: pixel position of left top corner of the window\n"
4819     " - w,h: width and heigth of window respectively.\n"
4820     "Additional commands for operations with views: vclose, vactivate, vviewlist.\n",
4821     __FILE__,VInit,group);
4822   theCommands.Add("vclose" ,
4823     "view_id [keep_context=0|1]\n"
4824     "or vclose ALL - to remove all created views\n"
4825     " - removes view(viewer window) defined by its view_id.\n"
4826     " - keep_context: by default 0; if 1 and the last view is deleted"
4827     " the current context is not removed.",
4828     __FILE__,VClose,group);
4829   theCommands.Add("vactivate" ,
4830     "view_id"
4831     " - activates view(viewer window) defined by its view_id",
4832     __FILE__,VActivate,group);
4833   theCommands.Add("vviewlist",
4834     "vviewlist [format={tree, long}]"
4835     " - prints current list of views per viewer and graphic_driver ID shared between viewers"
4836     " - format: format of result output, if tree the output is a tree view;"
4837     "otherwise it's a list of full view names. By default format = tree",
4838     __FILE__,VViewList,group);
4839   theCommands.Add("vhelp" ,
4840     "vhelp            : display help on the viewer commands",
4841     __FILE__,VHelp,group);
4842   theCommands.Add("vtop" ,
4843     "vtop or <T>      : Top view" ,
4844     __FILE__,VTop,group);
4845   theCommands.Add("vbottom" ,
4846     "vbottom          : Bottom view" ,
4847     __FILE__,VBottom,group);
4848   theCommands.Add("vleft" ,
4849     "vleft            : Left view" ,
4850     __FILE__,VLeft,group);
4851   theCommands.Add("vright" ,
4852     "vright           : Right view" ,
4853     __FILE__,VRight,group);
4854   theCommands.Add("vaxo" ,
4855     " vaxo or <A>     : Axonometric view ",
4856     __FILE__,VAxo,group);
4857   theCommands.Add("vfront" ,
4858     "vfront           : Front view" ,
4859     __FILE__,VFront,group);
4860   theCommands.Add("vback" ,
4861     "vback            : Back view" ,
4862     __FILE__,VBack,group);
4863   theCommands.Add("vpick" ,
4864     "vpick           : vpick X Y Z [shape subshape] ( all variables as string )",
4865     VPick,group);
4866   theCommands.Add("vfit"    ,
4867     "vfit or <F>         : vfit",
4868     __FILE__,VFit,group);
4869   theCommands.Add("vzfit"    ,
4870     "vzfit",
4871     __FILE__,VZFit,group);
4872   theCommands.Add("vrepaint",
4873     "vrepaint        : vrepaint, force redraw",
4874     __FILE__,VRepaint,group);
4875   theCommands.Add("vclear",
4876     "vclear          : vclear",
4877     __FILE__,VClear,group);
4878   theCommands.Add("vsetbg",
4879     "vsetbg          : vsetbg imagefile [filltype] : Load image as background",
4880     __FILE__,VSetBg,group);
4881   theCommands.Add("vsetbgmode",
4882     "vsetbgmode      : vsetbgmode filltype : Change background image fill type",
4883     __FILE__,VSetBgMode,group);
4884   theCommands.Add("vsetgradientbg",
4885     "vsetgradientbg  : vsetgradientbg r1 g1 b1 r2 g2 b2 filltype : Mount gradient background",
4886     __FILE__,VSetGradientBg,group);
4887   theCommands.Add("vsetgrbgmode",
4888     "vsetgrbgmode    : vsetgrbgmode filltype : Change gradient background fill type",
4889     __FILE__,VSetGradientBgMode,group);
4890   theCommands.Add("vsetcolorbg",
4891     "vsetcolorbg     : vsetcolorbg r g b : Set background color",
4892     __FILE__,VSetColorBg,group);
4893   theCommands.Add("vscale",
4894     "vscale          : vscale X Y Z",
4895     __FILE__,VScale,group);
4896   theCommands.Add("vzbufftrihedron",
4897     "vzbufftrihedron [center|left_lower|left_upper|right_lower|right_upper"
4898     " textR=255 textG=255 textB=255 scale=0.1 wireframe|zbuffer]"
4899     " : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron",
4900     __FILE__,VTestZBuffTrihedron,group);
4901   theCommands.Add("vrotate",
4902     "vrotate         : vrotate AX AY AZ [X Y Z]",
4903     __FILE__,VRotate,group);
4904   theCommands.Add("vzoom",
4905     "vzoom           : vzoom coef",
4906     __FILE__,VZoom,group);
4907   theCommands.Add("vpan",
4908     "vpan            : vpan dx dy",
4909     __FILE__,VPan,group);
4910   theCommands.Add("vexport",
4911     "vexport         : vexport full_file_path {PS | EPS | TEX | PDF | SVG | PGF | EMF }"
4912     " : exports the view to a vector file of a given format"
4913     " : notice that EMF format requires patched gl2ps",
4914     __FILE__,VExport,group);
4915   theCommands.Add("vcolorscale",
4916     "vcolorscale     : vcolorscale [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = 2 X = 0 Y = 0]: draw color scale",
4917     __FILE__,VColorScale,group);
4918   theCommands.Add("vgraduatedtrihedron",
4919     "vgraduatedtrihedron : 1/0 (display/erase) [Xname Yname Zname [Font [isMultibyte]]]",
4920     __FILE__,VGraduatedTrihedron,group);
4921   theCommands.Add("vprintview" ,
4922     "vprintview : width height filename [algo=0] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
4923     __FILE__,VPrintView,group);
4924   theCommands.Add("vzlayer",
4925     "vzlayer : add/del/get [id] : Z layer operations in v3d viewer: add new z layer, delete z layer, get z layer ids",
4926     __FILE__,VZLayer,group);
4927   theCommands.Add("voverlaytext",
4928     "voverlaytext : text x y [height] [font_name] [text_color: R G B] [display_type] [background_color: R G B]"
4929     " : height - pixel height of the text (default=10.0)"
4930     " : font_name - name of font (default=courier)"
4931     " : text_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0) "
4932     " : display_type = {normal/subtitle/decal/blend}, (default=normal) "
4933     " : background_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0), the parameter is defined for subtitle and decal display types ",
4934     __FILE__,VOverlayText,group);
4935   theCommands.Add("vlayerline",
4936     "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
4937     __FILE__,VLayerLine,group);
4938   theCommands.Add ("vgrid",
4939     "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]"
4940     " : Mode - rectangular or circular"
4941     " : Type - lines or points",
4942     __FILE__, VGrid, group);
4943   theCommands.Add ("vfps",
4944     "vfps [framesNb=100] : estimate average frame rate for active view",
4945     __FILE__, VFps, group);
4946   theCommands.Add ("vgldebug",
4947     "vgldebug [{0|1}] : request debug GL context, should be called before vinit\n"
4948     "                : this function is implemented only for Windows\n"
4949     "                : GL_ARB_debug_output extension should be exported by OpenGL driver!",
4950     __FILE__, VGlDebug, group);
4951   theCommands.Add ("vvbo",
4952     "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
4953     __FILE__, VVbo, group);
4954   theCommands.Add ("vcaps",
4955     "vcaps [vbo={0|1}] [sprites={0|1}] : modify particular graphic driver options",
4956     __FILE__, VCaps, group);
4957   theCommands.Add ("vmemgpu",
4958     "vmemgpu [f]: print system-dependent GPU memory information if available;"
4959     " with f option returns free memory in bytes",
4960     __FILE__, VMemGpu, group);
4961   theCommands.Add ("vreadpixel",
4962     "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
4963     " : Read pixel value for active view",
4964     __FILE__, VReadPixel, group);
4965   theCommands.Add("diffimage",
4966     "diffimage     : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
4967     __FILE__, VDiffImage, group);
4968   theCommands.Add ("vselect",
4969     "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [shift_selection = 0|1]\n"
4970     "- emulates different types of selection:\n"
4971     "- 1) single click selection\n"
4972     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
4973     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
4974     "- 4) any of these selections with shift button pressed",
4975     __FILE__, VSelect, group);
4976   theCommands.Add ("vmoveto",
4977     "vmoveto x y"
4978     "- emulates cursor movement to pixel postion (x,y)",
4979     __FILE__, VMoveTo, group);
4980   theCommands.Add("vviewparams",
4981     "vviewparams [scale center_X center_Y proj_X proj_Y proj_Z up_X up_Y up_Z at_X at_Y at_Z]"
4982     "- gets or sets current view characteristics",
4983     __FILE__,VViewParams, group);
4984   theCommands.Add("vchangeselected",
4985     "vchangeselected shape"
4986     "- adds to shape to selection or remove one from it",
4987                 __FILE__, VChangeSelected, group);
4988   theCommands.Add("vzclipping",
4989     "vzclipping [mode] [depth width]\n"
4990     "- mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]\n"
4991     "- gets or sets ZClipping mode, width and depth",
4992     __FILE__,VZClipping,group);
4993   theCommands.Add ("vnbselected",
4994     "vnbselected", __FILE__, VNbSelected, group);
4995   theCommands.Add("vantialiasing",
4996     "vantialiasing 1|0",
4997     __FILE__,VAntialiasing,group);
4998   theCommands.Add ("vpurgedisplay",
4999     "vpurgedisplay [CollectorToo = 0|1]"
5000     "- removes structures which don't belong to objects displayed in neutral point",
5001     __FILE__, VPurgeDisplay, group);
5002   theCommands.Add("vsetviewsize",
5003     "vsetviewsize size",
5004     __FILE__,VSetViewSize,group);
5005   theCommands.Add("vmoveview",
5006     "vmoveview Dx Dy Dz [Start = 1|0]",
5007     __FILE__,VMoveView,group);
5008   theCommands.Add("vtranslateview",
5009     "vtranslateview Dx Dy Dz [Start = 1|0)]",
5010     __FILE__,VTranslateView,group);
5011   theCommands.Add("vturnview",
5012     "vturnview Ax Ay Az [Start = 1|0]",
5013     __FILE__,VTurnView,group);
5014   theCommands.Add("vtextureenv",
5015     "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
5016     "or user-defined file and optionally applying texture mapping parameters\n"
5017     "                  Usage:\n"
5018     "                  vtextureenv off - disables environment mapping\n"
5019     "                  vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
5020     "                              std_texture = (0..7)\n"
5021     "                              rep         = {clamp|repeat}\n"
5022     "                              mod         = {decal|modulate}\n"
5023     "                              flt         = {nearest|bilinear|trilinear}\n"
5024     "                              ss, st      - scale factors for s and t texture coordinates\n"
5025     "                              ts, tt      - translation for s and t texture coordinates\n"
5026     "                              rot         - texture rotation angle in degrees",
5027     __FILE__, VTextureEnv, group);
5028   theCommands.Add("vhlr" ,
5029     "is_enabled={on|off}"
5030     " - Hidden line removal algorithm:"
5031     " - is_enabled: if is on HLR algorithm is applied\n",
5032     __FILE__,VHLR,group);
5033   theCommands.Add("vhlrtype" ,
5034     "algo_type={algo|polyalgo} [shape_1 ... shape_n]"
5035     " - Changes the type of HLR algorithm using for shapes."
5036     " - algo_type: if equals to algo, exact HLR algorithm is applied;\n"
5037     "   if equals to polyalgo, polygonal HLR algorithm is applied."
5038     "If shapes are not given HLR algoithm of given type is applied"
5039     " to all shapes in the view\n",
5040     __FILE__,VHLRType,group);
5041 }