0026272: Visualization - provide a possibility to activate selection modes without...
[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-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <OpenGl_GlCore20.hxx>
18 #include <AIS_Shape.hxx>
19 #include <AIS_InteractiveObject.hxx>
20 #include <AIS_ListOfInteractive.hxx>
21 #include <AIS_ListIteratorOfListOfInteractive.hxx>
22 #include <DBRep.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Graphic3d_ExportFormat.hxx>
25 #include <Graphic3d_NameOfTextureEnv.hxx>
26 #include <Graphic3d_GraduatedTrihedron.hxx>
27 #include <Graphic3d_TextureEnv.hxx>
28 #include <Graphic3d_TextureParams.hxx>
29 #include <Graphic3d_TypeOfTextureFilter.hxx>
30 #include <Graphic3d_AspectFillArea3d.hxx>
31 #include <ViewerTest.hxx>
32 #include <ViewerTest_AutoUpdater.hxx>
33 #include <ViewerTest_EventManager.hxx>
34 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
35 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
36 #include <Visual3d_View.hxx>
37 #include <Visual3d_ViewManager.hxx>
38 #include <V3d_AmbientLight.hxx>
39 #include <V3d_ColorScale.hxx>
40 #include <V3d_DirectionalLight.hxx>
41 #include <V3d_LayerMgr.hxx>
42 #include <V3d_LayerMgrPointer.hxx>
43 #include <V3d_PositionalLight.hxx>
44 #include <V3d_SpotLight.hxx>
45 #include <NCollection_DoubleMap.hxx>
46 #include <NCollection_List.hxx>
47 #include <NCollection_Vector.hxx>
48 #include <AIS_InteractiveContext.hxx>
49 #include <Draw_Interpretor.hxx>
50 #include <Draw.hxx>
51 #include <Draw_Appli.hxx>
52 #include <Aspect_PrintAlgo.hxx>
53 #include <Image_AlienPixMap.hxx>
54 #include <OpenGl_GraphicDriver.hxx>
55 #include <OSD_Timer.hxx>
56 #include <TColStd_HSequenceOfAsciiString.hxx>
57 #include <TColStd_SequenceOfInteger.hxx>
58 #include <TColStd_HSequenceOfReal.hxx>
59 #include <TColgp_Array1OfPnt2d.hxx>
60 #include <TColStd_MapOfAsciiString.hxx>
61 #include <Visual3d_LayerItem.hxx>
62 #include <Aspect_TypeOfLine.hxx>
63 #include <Image_Diff.hxx>
64 #include <Aspect_DisplayConnection.hxx>
65 #include <gp_Pnt.hxx>
66 #include <gp_Dir.hxx>
67 #include <gp_Pln.hxx>
68 #include <PrsMgr_PresentableObject.hxx>
69 #include <Graphic3d_ClipPlane.hxx>
70 #include <NCollection_DataMap.hxx>
71 #include <Graphic3d_Texture2Dmanual.hxx>
72 #include <Prs3d_ShadingAspect.hxx>
73 #include <Prs3d_Drawer.hxx>
74
75 #ifdef WNT
76 #undef DrawText
77 #endif
78
79 #include <Visual3d_Layer.hxx>
80 #include <cstdlib>
81
82 #if defined(_WIN32)
83   #include <WNT_WClass.hxx>
84   #include <WNT_Window.hxx>
85
86   #if defined(_MSC_VER)
87     #define _CRT_SECURE_NO_DEPRECATE
88     #pragma warning (disable:4996)
89   #endif
90 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
91   #include <Cocoa_Window.hxx>
92 #else
93   #include <Xw_Window.hxx>
94   #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
95   #include <X11/Xutil.h>
96   #include <tk.h>
97 #endif
98
99 inline Standard_Boolean parseOnOff (Standard_CString  theArg,
100                                     Standard_Boolean& theIsOn)
101 {
102   TCollection_AsciiString aFlag (theArg);
103   aFlag.LowerCase();
104   if (aFlag == "on"
105    || aFlag == "1")
106   {
107     theIsOn = Standard_True;
108     return Standard_True;
109   }
110   else if (aFlag == "off"
111         || aFlag == "0")
112   {
113     theIsOn = Standard_False;
114     return Standard_True;
115   }
116   return Standard_False;
117 }
118
119 // Auxiliary definitions
120 static const char THE_KEY_DELETE = 127;
121
122 //==============================================================================
123 //  VIEWER GLOBAL VARIABLES
124 //==============================================================================
125
126 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
127 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
128
129 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
130 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
131
132 extern int VErase (Draw_Interpretor& theDI,
133                    Standard_Integer  theArgNb,
134                    const char**      theArgVec);
135
136 #if defined(_WIN32)
137 static Handle(WNT_Window)& VT_GetWindow() {
138   static Handle(WNT_Window) WNTWin;
139   return WNTWin;
140 }
141 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
142 static Handle(Cocoa_Window)& VT_GetWindow()
143 {
144   static Handle(Cocoa_Window) aWindow;
145   return aWindow;
146 }
147 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
148 extern void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle);
149 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
150
151 #else
152 static Handle(Xw_Window)& VT_GetWindow(){
153   static Handle(Xw_Window) XWWin;
154   return XWWin;
155 }
156
157 static void VProcessEvents(ClientData,int);
158 #endif
159
160 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
161 {
162   static Handle(Aspect_DisplayConnection) aDisplayConnection;
163   return aDisplayConnection;
164 }
165
166 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
167 {
168   GetDisplayConnection() = theDisplayConnection;
169 }
170
171 #if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
172 Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow)
173 {
174   Aspect_Handle aWindowHandle = (Aspect_Handle)NULL;
175 #if defined(_WIN32)
176   const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow);
177   if (!aWindow.IsNull())
178     return aWindow->HWindow();
179 #elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
180   const Handle (Xw_Window) aWindow = Handle(Xw_Window)::DownCast (theWindow);
181   if (!aWindow.IsNull())
182   return aWindow->XWindow();
183 #endif
184   return aWindowHandle;
185 }
186 #endif
187
188 static Standard_Boolean MyHLRIsOn = Standard_False;
189
190 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
191 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>  ViewerTest_myContexts;
192 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
193 static OpenGl_Caps ViewerTest_myDefaultCaps;
194
195 #define ZCLIPWIDTH 1.
196
197 static void OSWindowSetup();
198
199 static struct
200 {
201   Quantity_Color FlatColor;
202   Quantity_Color GradientColor1;
203   Quantity_Color GradientColor2;
204   Aspect_GradientFillMethod FillMethod;
205 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
206
207 //==============================================================================
208 //  EVENT GLOBAL VARIABLES
209 //==============================================================================
210
211 static int Start_Rot = 0;
212 static int ZClipIsOn = 0;
213 int X_Motion = 0; // Current cursor position
214 int Y_Motion = 0;
215 int X_ButtonPress = 0; // Last ButtonPress position
216 int Y_ButtonPress = 0;
217 Standard_Boolean IsDragged = Standard_False;
218 Standard_Boolean DragFirst = Standard_False;
219
220 //==============================================================================
221
222 #ifdef WNT
223 static LRESULT WINAPI ViewerWindowProc(
224                                        HWND hwnd,
225                                        UINT uMsg,
226                                        WPARAM wParam,
227                                        LPARAM lParam );
228 static LRESULT WINAPI AdvViewerWindowProc(
229   HWND hwnd,
230   UINT uMsg,
231   WPARAM wParam,
232   LPARAM lParam );
233 #endif
234
235
236 //==============================================================================
237 //function : WClass
238 //purpose  :
239 //==============================================================================
240
241 const Handle(MMgt_TShared)& ViewerTest::WClass()
242 {
243   static Handle(MMgt_TShared) theWClass;
244 #if defined(_WIN32)
245   if (theWClass.IsNull())
246   {
247     theWClass = new WNT_WClass ("GW3D_Class", AdvViewerWindowProc,
248       CS_VREDRAW | CS_HREDRAW, 0, 0,
249       ::LoadCursor (NULL, IDC_ARROW));
250   }
251 #endif
252   return theWClass;
253 }
254
255 //==============================================================================
256 //function : CreateName
257 //purpose  : Create numerical name for new object in theMap
258 //==============================================================================
259 template <typename ObjectType>
260 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
261                                     const TCollection_AsciiString& theDefaultString)
262 {
263   if (theObjectMap.IsEmpty())
264     return theDefaultString + TCollection_AsciiString(1);
265
266   Standard_Integer aNextKey = 1;
267   Standard_Boolean isFound = Standard_False;
268   while (!isFound)
269   {
270     TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
271     // Look for objects with default names
272     if (theObjectMap.IsBound1(aStringKey))
273     {
274       aNextKey++;
275     }
276     else
277       isFound = Standard_True;
278   }
279
280   return theDefaultString + TCollection_AsciiString(aNextKey);
281 }
282
283 //==============================================================================
284 //structure : ViewerTest_Names
285 //purpose   : Allow to operate with full view name: driverName/viewerName/viewName
286 //==============================================================================
287 struct ViewerTest_Names
288 {
289 private:
290   TCollection_AsciiString myDriverName;
291   TCollection_AsciiString myViewerName;
292   TCollection_AsciiString myViewName;
293
294 public:
295
296   const TCollection_AsciiString& GetDriverName () const
297   {
298     return myDriverName;
299   }
300   void SetDriverName (const TCollection_AsciiString& theDriverName)
301   {
302     myDriverName = theDriverName;
303   }
304   const TCollection_AsciiString& GetViewerName () const
305   {
306     return myViewerName;
307   }
308   void SetViewerName (const TCollection_AsciiString& theViewerName)
309   {
310     myViewerName = theViewerName;
311   }
312   const TCollection_AsciiString& GetViewName () const
313   {
314     return myViewName;
315   }
316   void SetViewName (const TCollection_AsciiString& theViewName)
317   {
318     myViewName = theViewName;
319   }
320
321   //===========================================================================
322   //function : Constructor for ViewerTest_Names
323   //purpose  : Get view, viewer, driver names from custom string
324   //===========================================================================
325
326   ViewerTest_Names (const TCollection_AsciiString& theInputString)
327   {
328     TCollection_AsciiString aName(theInputString);
329     if (theInputString.IsEmpty())
330     {
331       // Get current configuration
332       if (ViewerTest_myDrivers.IsEmpty())
333         myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
334           (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
335       else
336         myDriverName = ViewerTest_myDrivers.Find2
337         (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
338
339       if(ViewerTest_myContexts.IsEmpty())
340       {
341         myViewerName = CreateName <Handle(AIS_InteractiveContext)>
342           (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
343       }
344       else
345         myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
346
347         myViewName = CreateName <Handle(V3d_View)>
348           (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
349     }
350     else
351     {
352       // There is at least view name
353       Standard_Integer aParserNumber = 0;
354       for (Standard_Integer i = 0; i < 3; ++i)
355       {
356         Standard_Integer aParserPos = aName.SearchFromEnd("/");
357         if(aParserPos != -1)
358         {
359           aParserNumber++;
360           aName.Split(aParserPos-1);
361         }
362         else
363           break;
364       }
365       if (aParserNumber == 0)
366       {
367         // Only view name
368         if (!ViewerTest::GetAISContext().IsNull())
369         {
370           myDriverName = ViewerTest_myDrivers.Find2
371           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
372           myViewerName = ViewerTest_myContexts.Find2
373           (ViewerTest::GetAISContext());
374         }
375         else
376         {
377           // There is no opened contexts here, need to create names for viewer and driver
378           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
379             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
380
381           myViewerName = CreateName <Handle(AIS_InteractiveContext)>
382             (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
383         }
384         myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
385       }
386       else if (aParserNumber == 1)
387       {
388         // Here is viewerName/viewName
389         if (!ViewerTest::GetAISContext().IsNull())
390           myDriverName = ViewerTest_myDrivers.Find2
391           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
392         else
393         {
394           // There is no opened contexts here, need to create name for driver
395           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
396             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
397         }
398         myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
399
400         myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
401       }
402       else
403       {
404         //Here is driverName/viewerName/viewName
405         myDriverName = TCollection_AsciiString(aName);
406
407         TCollection_AsciiString aViewerName(theInputString);
408         aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
409         myViewerName = TCollection_AsciiString(aViewerName);
410
411         myViewName = TCollection_AsciiString(theInputString);
412       }
413     }
414   }
415 };
416
417 //==============================================================================
418 //function : FindContextByView
419 //purpose  : Find AIS_InteractiveContext by View
420 //==============================================================================
421
422 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
423 {
424   Handle(AIS_InteractiveContext) anAISContext;
425
426   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
427        anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
428   {
429     if (anIter.Value()->CurrentViewer() == theView->Viewer())
430        return anIter.Key2();
431   }
432   return anAISContext;
433 }
434
435
436 //==============================================================================
437 //function : SetWindowTitle
438 //purpose  : Set window title
439 //==============================================================================
440
441 void SetWindowTitle (const Handle(Aspect_Window)& theWindow,
442                      Standard_CString theTitle)
443 {
444 #if defined(_WIN32)
445   SetWindowText ((HWND)Handle(WNT_Window)::DownCast(theWindow)->HWindow(),
446     theTitle);
447 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
448   SetCocoaWindowTitle (Handle(Cocoa_Window)::DownCast(theWindow), theTitle);
449 #else
450   if(GetDisplayConnection()->GetDisplay())
451   {
452     Window aWindow =
453       Handle(Xw_Window)::DownCast(theWindow)->XWindow();
454     XStoreName (GetDisplayConnection()->GetDisplay(), aWindow , theTitle);
455   }
456 #endif
457 }
458
459 //==============================================================================
460 //function : IsWindowOverlapped
461 //purpose  : Check if theWindow overlapp another view
462 //==============================================================================
463
464 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
465                                      const Standard_Integer thePxTop,
466                                      const Standard_Integer thePxRight,
467                                      const Standard_Integer thePxBottom,
468                                      TCollection_AsciiString& theViewId)
469 {
470   for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
471       anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
472   {
473     Standard_Integer aTop = 0,
474       aLeft = 0,
475       aRight = 0,
476       aBottom = 0;
477     anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
478     if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
479         (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
480         (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
481         (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
482     {
483       theViewId = anIter.Key1();
484       return Standard_True;
485     }
486   }
487   return Standard_False;
488 }
489
490 // Workaround: to create and delete non-orthographic views outside ViewerTest
491 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
492 {
493   ViewerTest_myViews.UnBind1 (theName);
494 }
495
496 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
497                                const Handle(V3d_View)& theView)
498 {
499   ViewerTest_myViews.Bind (theName, theView);
500 }
501
502 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
503 {
504   return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
505 }
506 //==============================================================================
507 //function : ViewerInit
508 //purpose  : Create the window viewer and initialize all the global variable
509 //==============================================================================
510
511 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
512                                                 const Standard_Integer thePxTop,
513                                                 const Standard_Integer thePxWidth,
514                                                 const Standard_Integer thePxHeight,
515                                                 Standard_CString theViewName,
516                                                 Standard_CString theDisplayName)
517 {
518   // Default position and dimension of the viewer window.
519   // Note that left top corner is set to be sufficiently small to have
520   // window fit in the small screens (actual for remote desktops, see #23003).
521   // The position corresponds to the window's client area, thus some
522   // gap is added for window frame to be visible.
523   Standard_Integer aPxLeft   = 20;
524   Standard_Integer aPxTop    = 40;
525   Standard_Integer aPxWidth  = 409;
526   Standard_Integer aPxHeight = 409;
527   Standard_Boolean toCreateViewer = Standard_False;
528
529   Handle(OpenGl_GraphicDriver) aGraphicDriver;
530   ViewerTest_Names aViewNames(theViewName);
531   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
532     aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
533
534   if (thePxLeft != 0)
535     aPxLeft = thePxLeft;
536   if (thePxTop != 0)
537     aPxTop = thePxTop;
538   if (thePxWidth != 0)
539     aPxWidth = thePxWidth;
540   if (thePxHeight != 0)
541     aPxHeight = thePxHeight;
542
543   // Get graphic driver (create it or get from another view)
544   if (!ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName()))
545   {
546     // Get connection string
547   #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
548     TCollection_AsciiString aDisplayName(theDisplayName);
549     if (!aDisplayName.IsEmpty())
550       SetDisplayConnection (new Aspect_DisplayConnection ());
551     else
552       SetDisplayConnection (new Aspect_DisplayConnection (aDisplayName));
553   #else
554     (void)theDisplayName; // avoid warning on unused argument
555     SetDisplayConnection (new Aspect_DisplayConnection ());
556   #endif
557     aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
558     aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
559     ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
560     toCreateViewer = Standard_True;
561   }
562   else
563   {
564     aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
565   }
566
567   //Dispose the window if input parameters are default
568   if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
569   {
570     Standard_Integer aTop = 0,
571                      aLeft = 0,
572                      aRight = 0,
573                      aBottom = 0,
574                      aScreenWidth = 0,
575                      aScreenHeight = 0;
576
577     // Get screen resolution
578 #if defined(_WIN32) || defined(__WIN32__)
579     RECT aWindowSize;
580     GetClientRect(GetDesktopWindow(), &aWindowSize);
581     aScreenHeight = aWindowSize.bottom;
582     aScreenWidth = aWindowSize.right;
583 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
584     GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
585 #else
586     Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
587     aScreenWidth = WidthOfScreen(aScreen);
588     aScreenHeight = HeightOfScreen(aScreen);
589 #endif
590
591     TCollection_AsciiString anOverlappedViewId("");
592
593     while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
594     {
595       ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
596
597       if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
598         && aRight + 2*aPxWidth + 40 > aScreenWidth)
599       {
600         if (aBottom + aPxHeight + 40 > aScreenHeight)
601         {
602           aPxLeft = 20;
603           aPxTop = 40;
604           break;
605         }
606         aPxLeft = 20;
607         aPxTop = aBottom + 40;
608       }
609       else
610         aPxLeft = aRight + 20;
611     }
612   }
613
614   // Get viewer name
615   TCollection_AsciiString aTitle("3D View - ");
616   aTitle = aTitle + aViewNames.GetViewName() + "(*)";
617
618   // Change name of current active window
619   if (!ViewerTest::CurrentView().IsNull())
620   {
621     TCollection_AsciiString aTitle("3D View - ");
622     aTitle = aTitle
623       + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
624     SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
625   }
626
627   // Create viewer
628   Handle(V3d_Viewer) a3DViewer;
629   // If it's the single view, we first look for empty context
630   if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
631   {
632     NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
633       anIter(ViewerTest_myContexts);
634     if (anIter.More())
635       ViewerTest::SetAISContext (anIter.Value());
636     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
637   }
638   else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
639   {
640     ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
641     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
642   }
643   else if (a3DViewer.IsNull())
644   {
645     toCreateViewer = Standard_True;
646     TCollection_ExtendedString NameOfWindow("Viewer3D");
647     a3DViewer = new V3d_Viewer(aGraphicDriver, NameOfWindow.ToExtString());
648     a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
649     a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
650                                            ViewerTest_DefaultBackground.GradientColor2,
651                                            ViewerTest_DefaultBackground.FillMethod);
652   }
653
654   // AIS context setup
655   if (ViewerTest::GetAISContext().IsNull() ||
656       !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
657   {
658     Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
659     ViewerTest::SetAISContext (aContext);
660     ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
661   }
662   else
663   {
664     ViewerTest::ResetEventManager();
665   }
666
667   // Create window
668 #if defined(_WIN32)
669   VT_GetWindow() = new WNT_Window (aTitle.ToCString(),
670                                     Handle(WNT_WClass)::DownCast (WClass()),
671                                     Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
672                                     aPxLeft, aPxTop,
673                                     aPxWidth, aPxHeight,
674                                     Quantity_NOC_BLACK);
675 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
676   VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
677                                      aPxLeft, aPxTop,
678                                      aPxWidth, aPxHeight);
679   ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
680 #else
681   VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
682                                   aTitle.ToCString(),
683                                   aPxLeft, aPxTop,
684                                   aPxWidth, aPxHeight);
685 #endif
686   VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
687
688   // View setup
689   Handle(V3d_View) aView = a3DViewer->CreateView();
690   aView->SetWindow (VT_GetWindow());
691   ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
692
693   ViewerTest::CurrentView(aView);
694   ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
695
696   // Setup for X11 or NT
697   OSWindowSetup();
698
699   // Set parameters for V3d_View and V3d_Viewer
700   const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
701   aV3dView->SetComputedMode(Standard_False);
702   MyHLRIsOn = aV3dView->ComputedMode();
703   aV3dView->SetZClippingDepth(0.5);
704   aV3dView->SetZClippingWidth(ZCLIPWIDTH/2.);
705
706   a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
707   if (toCreateViewer)
708   {
709     a3DViewer->SetDefaultLights();
710     a3DViewer->SetLightOn();
711   }
712
713   #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
714   #if TCL_MAJOR_VERSION  < 8
715   Tk_CreateFileHandler((void*)XConnectionNumber(GetDisplayConnection()->GetDisplay()),
716       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
717   #else
718   Tk_CreateFileHandler(XConnectionNumber(GetDisplayConnection()->GetDisplay()),
719       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
720   #endif
721   #endif
722
723   VT_GetWindow()->Map();
724
725   // Set the handle of created view in the event manager
726   ViewerTest::ResetEventManager();
727
728   ViewerTest::CurrentView()->Redraw();
729
730   aView.Nullify();
731   a3DViewer.Nullify();
732
733   return aViewNames.GetViewName();
734 }
735
736 //==============================================================================
737 //function : RedrawAllViews
738 //purpose  : Redraw all created views
739 //==============================================================================
740 void ViewerTest::RedrawAllViews()
741 {
742   NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
743   for (; aViewIt.More(); aViewIt.Next())
744   {
745     const Handle(V3d_View)& aView = aViewIt.Key2();
746     aView->Redraw();
747   }
748 }
749
750 //==============================================================================
751 //function : Vinit
752 //purpose  : Create the window viewer and initialize all the global variable
753 //    Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
754 //==============================================================================
755
756 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
757 {
758   if (theArgsNb > 9)
759   {
760     std::cerr << theArgVec[0] << ": incorrect number of command arguments.\n"
761               << "Type help for more information.\n";
762     return 1;
763   }
764
765   TCollection_AsciiString aViewName, aDisplayName;
766   Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
767   TCollection_AsciiString aName, aValue;
768   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
769   {
770     const TCollection_AsciiString anArg = theArgVec[anArgIt];
771     TCollection_AsciiString anArgCase = anArg;
772     anArgCase.UpperCase();
773     if (ViewerTest::SplitParameter (anArg, aName, aValue))
774     {
775       aName.UpperCase();
776       if (aName.IsEqual ("NAME"))
777       {
778         aViewName = aValue;
779       }
780       else if (aName.IsEqual ("L")
781             || aName.IsEqual ("LEFT"))
782       {
783         aPxLeft = aValue.IntegerValue();
784       }
785       else if (aName.IsEqual ("T")
786             || aName.IsEqual ("TOP"))
787       {
788         aPxTop = aValue.IntegerValue();
789       }
790     #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
791       else if (aName.IsEqual ("DISP")
792             || aName.IsEqual ("DISPLAY"))
793       {
794         aDisplayName = aValue;
795       }
796     #endif
797       else if (aName.IsEqual ("W")
798             || aName.IsEqual ("WIDTH"))
799       {
800         aPxWidth = aValue.IntegerValue();
801       }
802       else if (aName.IsEqual ("H")
803             || aName.IsEqual ("HEIGHT"))
804       {
805         aPxHeight = aValue.IntegerValue();
806       }
807       else
808       {
809         std::cerr << theArgVec[0] << ": Warning: unknown argument " << anArg << ".\n";
810       }
811     }
812     else if (aViewName.IsEmpty())
813     {
814       aViewName = anArg;
815     }
816     else
817     {
818       std::cerr << theArgVec[0] << ": Warning: unknown argument " << anArg << ".\n";
819     }
820   }
821
822   ViewerTest_Names aViewNames (aViewName);
823   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
824   {
825     TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
826     theDi.Eval (aCommand.ToCString());
827     return 0;
828   }
829
830   TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
831                                                             aViewName.ToCString(),
832                                                             aDisplayName.ToCString());
833   theDi << aViewId;
834   return 0;
835 }
836
837 //==============================================================================
838 //function : VHLR
839 //purpose  : hidden lines removal algorithm
840 //draw args: vhlr is_enabled={on|off} [show_hidden={1|0}]
841 //==============================================================================
842
843 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
844 {
845   if (ViewerTest::CurrentView().IsNull())
846   {
847     di << argv[0] << ": Call vinit before this command, please.\n";
848     return 1;
849   }
850
851   if (argc < 2)
852   {
853     di << argv[0] << ": Wrong number of command arguments.\n"
854       << "Type help " << argv[0] << " for more information.\n";
855     return 1;
856   }
857
858   // Enable or disable HLR mode.
859   Standard_Boolean isHLROn =
860     (!strcasecmp (argv[1], "on")) ? Standard_True : Standard_False;
861
862   if (isHLROn != MyHLRIsOn)
863   {
864     MyHLRIsOn = isHLROn;
865     ViewerTest::CurrentView()->SetComputedMode (MyHLRIsOn);
866   }
867
868   // Show or hide hidden lines in HLR mode.
869   Standard_Boolean isCurrentShowHidden
870     = ViewerTest::GetAISContext()->DefaultDrawer()->DrawHiddenLine();
871
872   Standard_Boolean isShowHidden =
873     (argc == 3) ? (atoi(argv[2]) == 1 ? Standard_True : Standard_False)
874                 : isCurrentShowHidden;
875
876
877   if (isShowHidden != isCurrentShowHidden)
878   {
879     if (isShowHidden)
880     {
881       ViewerTest::GetAISContext()->DefaultDrawer()->EnableDrawHiddenLine();
882     }
883     else
884     {
885       ViewerTest::GetAISContext()->DefaultDrawer()->DisableDrawHiddenLine();
886     }
887
888     // Redisplay shapes.
889     if (MyHLRIsOn)
890     {
891       AIS_ListOfInteractive aListOfShapes;
892       ViewerTest::GetAISContext()->DisplayedObjects (aListOfShapes);
893
894       for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
895       {
896         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (anIter.Value());
897         if (aShape.IsNull())
898         {
899           continue;
900         }
901         ViewerTest::GetAISContext()->Redisplay (aShape, Standard_False);
902       }
903     }
904   }
905
906   ViewerTest::CurrentView()->Update();
907   return 0;
908 }
909
910 //==============================================================================
911 //function : VHLRType
912 //purpose  : change type of using HLR algorithm
913 //==============================================================================
914
915 static int VHLRType (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
916 {
917   if (ViewerTest::CurrentView().IsNull())
918   {
919     di << argv[0] << ": Call vinit before this command, please.\n";
920     return 1;
921   }
922
923   if (argc < 2)
924   {
925     di << argv[0] << ": Wrong number of command arguments.\n"
926       << "Type help " << argv[0] << " for more information.\n";
927     return 1;
928   }
929
930   Prs3d_TypeOfHLR aTypeOfHLR =
931     (!strcasecmp (argv[1], "algo")) ? Prs3d_TOH_Algo : Prs3d_TOH_PolyAlgo;
932
933   if (argc == 2)
934   {
935     AIS_ListOfInteractive aListOfShapes;
936     ViewerTest::GetAISContext()->DisplayedObjects (aListOfShapes);
937     ViewerTest::GetAISContext()->DefaultDrawer()->SetTypeOfHLR(aTypeOfHLR);
938     for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
939       anIter.More(); anIter.Next())
940     {
941       Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
942       if (aShape.IsNull())
943         continue;
944       if (aShape->TypeOfHLR() != aTypeOfHLR)
945         aShape->SetTypeOfHLR (aTypeOfHLR);
946       if (MyHLRIsOn)
947         ViewerTest::GetAISContext()->Redisplay (aShape, Standard_False);
948     }
949     ViewerTest::CurrentView()->Update();
950     return 0;
951   }
952   else
953   {
954     for (Standard_Integer i = 2; i < argc; ++i)
955     {
956       ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
957       TCollection_AsciiString aName (argv[i]);
958
959       if (!aMap.IsBound2 (aName))
960       {
961         di << argv[0] << ":" << " Wrong shape name:" << aName.ToCString() << ".\n";
962         continue;
963       }
964       Handle(AIS_Shape) anAISObject =
965         Handle(AIS_Shape)::DownCast (aMap.Find2(aName));
966       if (anAISObject.IsNull())
967         continue;
968       anAISObject->SetTypeOfHLR (aTypeOfHLR);
969       if (MyHLRIsOn)
970         ViewerTest::GetAISContext()->Redisplay (anAISObject, Standard_False);
971     }
972     ViewerTest::CurrentView()->Update();
973   }
974
975   return 0;
976 }
977
978 //==============================================================================
979 //function : FindViewIdByWindowHandle
980 //purpose  : Find theView Id in the map of views by window handle
981 //==============================================================================
982 #if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
983 TCollection_AsciiString FindViewIdByWindowHandle(const Aspect_Handle theWindowHandle)
984 {
985   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
986        anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
987   {
988     Aspect_Handle aWindowHandle = GetWindowHandle(anIter.Value()->Window());
989     if (aWindowHandle == theWindowHandle)
990       return anIter.Key1();
991   }
992   return TCollection_AsciiString("");
993 }
994 #endif
995
996 //==============================================================================
997 //function : ActivateView
998 //purpose  : Make the view active
999 //==============================================================================
1000
1001 void ActivateView (const TCollection_AsciiString& theViewName)
1002 {
1003   const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1004   if (!aView.IsNull())
1005   {
1006     Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
1007     if (!anAISContext.IsNull())
1008     {
1009       if (!ViewerTest::CurrentView().IsNull())
1010       {
1011         TCollection_AsciiString aTitle("3D View - ");
1012         aTitle = aTitle + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
1013         SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1014       }
1015
1016       ViewerTest::CurrentView (aView);
1017       // Update degenerate mode
1018       MyHLRIsOn = ViewerTest::CurrentView()->ComputedMode();
1019       ViewerTest::SetAISContext (anAISContext);
1020       TCollection_AsciiString aTitle = TCollection_AsciiString("3D View - ");
1021       aTitle = aTitle + theViewName + "(*)";
1022       SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1023 #if defined(_WIN32) || defined(__WIN32__)
1024       VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
1025 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1026       VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
1027 #else
1028       VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
1029 #endif
1030       SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1031       ViewerTest::CurrentView()->Redraw();
1032     }
1033   }
1034 }
1035
1036 //==============================================================================
1037 //function : RemoveView
1038 //purpose  :
1039 //==============================================================================
1040 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
1041                              const Standard_Boolean  theToRemoveContext)
1042 {
1043   if (!ViewerTest_myViews.IsBound2 (theView))
1044   {
1045     return;
1046   }
1047
1048   const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
1049   RemoveView (aViewName, theToRemoveContext);
1050 }
1051
1052 //==============================================================================
1053 //function : RemoveView
1054 //purpose  : Close and remove view from display, clear maps if neccessary
1055 //==============================================================================
1056 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
1057 {
1058   if (!ViewerTest_myViews.IsBound1(theViewName))
1059   {
1060     cout << "Wrong view name\n";
1061     return;
1062   }
1063
1064   // Activate another view if it's active now
1065   if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
1066   {
1067     if (ViewerTest_myViews.Extent() > 1)
1068     {
1069       TCollection_AsciiString aNewViewName;
1070       for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> :: Iterator
1071            anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1072         if (anIter.Key1() != theViewName)
1073         {
1074           aNewViewName = anIter.Key1();
1075           break;
1076         }
1077         ActivateView (aNewViewName);
1078     }
1079     else
1080     {
1081       Handle(V3d_View) anEmptyView;
1082 #if defined(_WIN32) || defined(__WIN32__)
1083       Handle(WNT_Window) anEmptyWindow;
1084 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1085       Handle(Cocoa_Window) anEmptyWindow;
1086 #else
1087       Handle(Xw_Window) anEmptyWindow;
1088 #endif
1089       VT_GetWindow() = anEmptyWindow;
1090       ViewerTest::CurrentView (anEmptyView);
1091       if (isContextRemoved)
1092       {
1093         Handle(AIS_InteractiveContext) anEmptyContext;
1094         ViewerTest::SetAISContext(anEmptyContext);
1095       }
1096     }
1097   }
1098
1099   // Delete view
1100   Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1101   Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1102
1103   // Remove view resources
1104   ViewerTest_myViews.UnBind1(theViewName);
1105   aView->Remove();
1106
1107 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1108   XFlush (GetDisplayConnection()->GetDisplay());
1109 #endif
1110
1111   // Keep context opened only if the closed view is last to avoid
1112   // unused empty contexts
1113   if (!aCurrentContext.IsNull())
1114   {
1115     // Check if there are more difined views in the viewer
1116     aCurrentContext->CurrentViewer()->InitDefinedViews();
1117     if ((isContextRemoved || ViewerTest_myContexts.Size() != 1) && !aCurrentContext->CurrentViewer()->MoreDefinedViews())
1118     {
1119       // Remove driver if there is no viewers that use it
1120       Standard_Boolean isRemoveDriver = Standard_True;
1121       for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1122           anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1123       {
1124         if (aCurrentContext != anIter.Key2() &&
1125           aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
1126         {
1127           isRemoveDriver = Standard_False;
1128           break;
1129         }
1130       }
1131       if(isRemoveDriver)
1132       {
1133         ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1134       #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1135         #if TCL_MAJOR_VERSION  < 8
1136         Tk_DeleteFileHandler((void*)XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1137         #else
1138         Tk_DeleteFileHandler(XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1139         #endif
1140       #endif
1141       }
1142
1143       ViewerTest_myContexts.UnBind2(aCurrentContext);
1144     }
1145   }
1146   cout << "3D View - " << theViewName << " was deleted.\n";
1147
1148 }
1149
1150 //==============================================================================
1151 //function : VClose
1152 //purpose  : Remove the view defined by its name
1153 //==============================================================================
1154
1155 static int VClose (Draw_Interpretor& /*theDi*/,
1156                    Standard_Integer  theArgsNb,
1157                    const char**      theArgVec)
1158 {
1159   NCollection_List<TCollection_AsciiString> aViewList;
1160   if (theArgsNb > 1)
1161   {
1162     TCollection_AsciiString anArg (theArgVec[1]);
1163     anArg.UpperCase();
1164     if (anArg.IsEqual ("ALL")
1165      || anArg.IsEqual ("*"))
1166     {
1167       for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1168            anIter.More(); anIter.Next())
1169       {
1170         aViewList.Append (anIter.Key1());
1171       }
1172       if (aViewList.IsEmpty())
1173       {
1174         std::cout << "No view to close\n";
1175         return 0;
1176       }
1177     }
1178     else
1179     {
1180       ViewerTest_Names aViewName (theArgVec[1]);
1181       if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
1182       {
1183         std::cerr << "The view with name '" << theArgVec[1] << "' does not exist\n";
1184         return 1;
1185       }
1186       aViewList.Append (aViewName.GetViewName());
1187     }
1188   }
1189   else
1190   {
1191     // close active view
1192     if (ViewerTest::CurrentView().IsNull())
1193     {
1194       std::cerr << "No active view!\n";
1195       return 1;
1196     }
1197     aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1198   }
1199
1200   Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
1201   for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1202        anIter.More(); anIter.Next())
1203   {
1204     ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
1205   }
1206
1207   return 0;
1208 }
1209
1210 //==============================================================================
1211 //function : VActivate
1212 //purpose  : Activate the view defined by its ID
1213 //==============================================================================
1214
1215 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1216 {
1217   if (theArgsNb > 2)
1218   {
1219     theDi << theArgVec[0] << ": wrong number of command arguments.\n"
1220     << "Usage: " << theArgVec[0] << " ViewID\n";
1221     return 1;
1222   }
1223   if(theArgsNb == 1)
1224   {
1225     theDi.Eval("vviewlist");
1226     return 0;
1227   }
1228
1229   TCollection_AsciiString aNameString(theArgVec[1]);
1230   if ( strcasecmp( aNameString.ToCString(), "NONE" ) == 0 )
1231   {
1232     TCollection_AsciiString aTitle("3D View - ");
1233     aTitle = aTitle + ViewerTest_myViews.Find2(ViewerTest::CurrentView());
1234     SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1235     Handle(V3d_View) anEmptyView;
1236 #if defined(_WIN32) || defined(__WIN32__)
1237     Handle(WNT_Window) anEmptyWindow;
1238 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1239     Handle(Cocoa_Window) anEmptyWindow;
1240 #else
1241     Handle(Xw_Window) anEmptyWindow;
1242 #endif
1243     VT_GetWindow() = anEmptyWindow;
1244     ViewerTest::CurrentView (anEmptyView);
1245     ViewerTest::ResetEventManager();
1246     theDi << theArgVec[0] << ": all views are inactive\n";
1247     return 0;
1248   }
1249
1250   ViewerTest_Names aViewNames(aNameString);
1251
1252   // Check if this view exists in the viewer with the driver
1253   if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1254   {
1255     theDi << "Wrong view name\n";
1256     return 1;
1257   }
1258
1259   // Check if it is active already
1260   if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1261   {
1262     theDi << theArgVec[0] << ": the view is active already\n";
1263     return 0;
1264   }
1265
1266   ActivateView (aViewNames.GetViewName());
1267   return 0;
1268 }
1269
1270 //==============================================================================
1271 //function : VViewList
1272 //purpose  : Print current list of views per viewer and graphic driver ID
1273 //           shared between viewers
1274 //==============================================================================
1275
1276 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1277 {
1278   if (theArgsNb > 2)
1279   {
1280     theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1281           << "Usage: " << theArgVec[0] << " name";
1282     return 1;
1283   }
1284   if (ViewerTest_myContexts.Size() < 1)
1285     return 0;
1286
1287   Standard_Boolean isTreeView =
1288     (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1289
1290   if (isTreeView)
1291     theDi << theArgVec[0] <<":\n";
1292
1293     for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
1294       aDriverIter(ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
1295     {
1296       if (isTreeView)
1297         theDi << aDriverIter.Key1() << ":\n";
1298
1299       for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1300         aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1301       {
1302         if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1303         {
1304           if (isTreeView)
1305           {
1306             TCollection_AsciiString aContextName(aContextIter.Key1());
1307             theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":" << "\n";
1308           }
1309
1310           for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1311             aViewIter(ViewerTest_myViews); aViewIter.More(); aViewIter.Next())
1312           {
1313             if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1314             {
1315               TCollection_AsciiString aViewName(aViewIter.Key1());
1316               if (isTreeView)
1317               {
1318                 if (aViewIter.Value() == ViewerTest::CurrentView())
1319                   theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)" << "\n";
1320                 else
1321                   theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1322               }
1323               else
1324               {
1325                 theDi << aViewName << " ";
1326               }
1327             }
1328           }
1329         }
1330       }
1331     }
1332   return 0;
1333 }
1334
1335 //==============================================================================
1336 //function : VT_ProcessKeyPress
1337 //purpose  : Handle KeyPress event from a CString
1338 //==============================================================================
1339 void VT_ProcessKeyPress (const char* buf_ret)
1340 {
1341   //cout << "KeyPress" << endl;
1342   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1343   // Letter in alphabetic order
1344
1345   if (!strcasecmp (buf_ret, "A"))
1346   {
1347     // AXO
1348     aView->SetProj(V3d_XposYnegZpos);
1349   }
1350   else if (!strcasecmp (buf_ret, "D"))
1351   {
1352     // Reset
1353     aView->Reset();
1354   }
1355   else if (!strcasecmp (buf_ret, "F"))
1356   {
1357     if (ViewerTest::GetAISContext()->NbSelected() > 0)
1358     {
1359       ViewerTest::GetAISContext()->FitSelected (aView);
1360     }
1361     else
1362     {
1363       // FitAll
1364       aView->FitAll();
1365     }
1366   }
1367   else if (!strcasecmp (buf_ret, "H"))
1368   {
1369     // HLR
1370     cout << "HLR" << endl;
1371     aView->SetComputedMode (!aView->ComputedMode());
1372     MyHLRIsOn = aView->ComputedMode();
1373   }
1374   else if (!strcasecmp (buf_ret, "P"))
1375   {
1376     // Type of HLR
1377     Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1378     if (aContext->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo)
1379       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_PolyAlgo);
1380     else
1381       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_Algo);
1382     if (aContext->NbSelected()==0)
1383     {
1384       AIS_ListOfInteractive aListOfShapes;
1385       aContext->DisplayedObjects(aListOfShapes);
1386       for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
1387         anIter.More(); anIter.Next())
1388       {
1389         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1390         if (aShape.IsNull())
1391           continue;
1392         if (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1393           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1394         else
1395           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1396         aContext->Redisplay (aShape, Standard_False);
1397       }
1398     }
1399     else
1400     {
1401       for (aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected())
1402       {
1403         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aContext->SelectedInteractive());
1404         if (aShape.IsNull())
1405           continue;
1406         if(aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1407           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1408         else
1409           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1410         aContext->Redisplay (aShape, Standard_False);
1411       }
1412     }
1413
1414     aContext->UpdateCurrentViewer();
1415
1416   }
1417   else if (!strcasecmp (buf_ret, "S"))
1418   {
1419     std::cout << "setup Shaded display mode" << std::endl;
1420
1421     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1422     if(Ctx->NbSelected()==0)
1423       Ctx->SetDisplayMode(AIS_Shaded);
1424     else{
1425       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1426         Ctx->SetDisplayMode(Ctx->SelectedInteractive(),1,Standard_False);
1427       Ctx->UpdateCurrentViewer();
1428     }
1429   }
1430   else if (!strcasecmp (buf_ret, "U"))
1431   {
1432     // Unset display mode
1433     std::cout << "reset display mode to defaults" << std::endl;
1434
1435     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1436     if(Ctx->NbSelected()==0)
1437       Ctx->SetDisplayMode(AIS_WireFrame);
1438     else{
1439       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1440         Ctx->UnsetDisplayMode(Ctx->SelectedInteractive(),Standard_False);
1441       Ctx->UpdateCurrentViewer();
1442     }
1443
1444   }
1445   else if (!strcasecmp (buf_ret, "T"))
1446   {
1447     // Top
1448     aView->SetProj(V3d_Zpos);
1449   }
1450   else if (!strcasecmp (buf_ret, "B"))
1451   {
1452     // Bottom
1453     aView->SetProj(V3d_Zneg);
1454   }
1455   else if (!strcasecmp (buf_ret, "L"))
1456   {
1457     // Left
1458     aView->SetProj(V3d_Xneg);
1459   }
1460   else if (!strcasecmp (buf_ret, "R"))
1461   {
1462     // Right
1463     aView->SetProj(V3d_Xpos);
1464   }
1465   else if (!strcasecmp (buf_ret, "W"))
1466   {
1467     std::cout << "setup WireFrame display mode" << std::endl;
1468     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1469     if(Ctx->NbSelected()==0)
1470       Ctx->SetDisplayMode(AIS_WireFrame);
1471     else{
1472       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1473         Ctx->SetDisplayMode(Ctx->SelectedInteractive(),0,Standard_False);
1474       Ctx->UpdateCurrentViewer();
1475     }
1476   }
1477   else if (!strcasecmp (buf_ret, "Z"))
1478   {
1479     // ZCLIP
1480     if ( ZClipIsOn ) {
1481       cout << "ZClipping OFF" << endl;
1482       ZClipIsOn = 0;
1483
1484       aView->SetZClippingType(V3d_OFF);
1485       aView->Redraw();
1486     }
1487     else {
1488       cout << "ZClipping ON" << endl;
1489       ZClipIsOn = 1;
1490
1491       aView->SetZClippingType(V3d_FRONT);
1492       aView->Redraw();
1493     }
1494   }
1495   else if (!strcasecmp (buf_ret, ","))
1496   {
1497     ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
1498   }
1499   else if (!strcasecmp (buf_ret, "."))
1500   {
1501     ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
1502   }
1503   else if (!strcasecmp (buf_ret, "/"))
1504   {
1505     Handle(Graphic3d_Camera) aCamera = aView->Camera();
1506     if (aCamera->IsStereo())
1507     {
1508       aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
1509       aView->Redraw();
1510     }
1511   }
1512   else if (!strcasecmp (buf_ret, "*"))
1513   {
1514     Handle(Graphic3d_Camera) aCamera = aView->Camera();
1515     if (aCamera->IsStereo())
1516     {
1517       aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
1518       aView->Redraw();
1519     }
1520   }
1521   else if (*buf_ret == THE_KEY_DELETE)
1522   {
1523     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1524     if (!aCtx.IsNull()
1525      && aCtx->NbSelected() > 0)
1526     {
1527       Draw_Interprete ("verase");
1528     }
1529   }
1530   else
1531   {
1532     // Number
1533     Standard_Integer Num = Draw::Atoi(buf_ret);
1534     if(Num>=0 && Num<=7)
1535       ViewerTest::StandardModeActivation(Num);
1536   }
1537 }
1538
1539 //==============================================================================
1540 //function : VT_ProcessExpose
1541 //purpose  : Redraw the View on an Expose Event
1542 //==============================================================================
1543 void VT_ProcessExpose()
1544 {
1545   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1546   if (!aView3d.IsNull())
1547   {
1548     aView3d->Redraw();
1549   }
1550 }
1551
1552 //==============================================================================
1553 //function : VT_ProcessConfigure
1554 //purpose  : Resize the View on an Configure Event
1555 //==============================================================================
1556 void VT_ProcessConfigure()
1557 {
1558   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1559   if (aView3d.IsNull())
1560   {
1561     return;
1562   }
1563
1564   aView3d->MustBeResized();
1565   aView3d->Update();
1566   aView3d->Redraw();
1567 }
1568
1569 //==============================================================================
1570 //function : VT_ProcessButton1Press
1571 //purpose  : Picking
1572 //==============================================================================
1573 Standard_Boolean VT_ProcessButton1Press (Standard_Integer ,
1574                                          const char**     theArgVec,
1575                                          Standard_Boolean theToPick,
1576                                          Standard_Boolean theIsShift)
1577 {
1578   if (theToPick)
1579   {
1580     Standard_Real X, Y, Z;
1581     ViewerTest::CurrentView()->Convert (X_Motion, Y_Motion, X, Y, Z);
1582
1583     Draw::Set (theArgVec[1], X);
1584     Draw::Set (theArgVec[2], Y);
1585     Draw::Set (theArgVec[3], Z);
1586   }
1587
1588   if (theIsShift)
1589   {
1590     ViewerTest::CurrentEventManager()->ShiftSelect();
1591   }
1592   else
1593   {
1594     ViewerTest::CurrentEventManager()->Select();
1595   }
1596
1597   return Standard_False;
1598 }
1599
1600 //==============================================================================
1601 //function : VT_ProcessButton1Release
1602 //purpose  : End selecting
1603 //==============================================================================
1604 void VT_ProcessButton1Release (Standard_Boolean theIsShift)
1605 {
1606   if (IsDragged)
1607   {
1608     IsDragged = Standard_False;
1609     Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1610     if (theIsShift)
1611     {
1612       EM->ShiftSelect (X_ButtonPress, Y_ButtonPress,
1613                        X_Motion, Y_Motion);
1614     }
1615     else
1616     {
1617       EM->Select (X_ButtonPress, Y_ButtonPress,
1618                   X_Motion, Y_Motion);
1619     }
1620   }
1621 }
1622
1623 //==============================================================================
1624 //function : VT_ProcessButton3Press
1625 //purpose  : Start Rotation
1626 //==============================================================================
1627 void VT_ProcessButton3Press()
1628 {
1629   Start_Rot = 1;
1630   if (MyHLRIsOn)
1631   {
1632     ViewerTest::CurrentView()->SetComputedMode (Standard_False);
1633   }
1634   ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
1635 }
1636
1637 //==============================================================================
1638 //function : VT_ProcessButton3Release
1639 //purpose  : End rotation
1640 //==============================================================================
1641 void VT_ProcessButton3Release()
1642 {
1643   if (Start_Rot)
1644   {
1645     Start_Rot = 0;
1646     if (MyHLRIsOn)
1647     {
1648       ViewerTest::CurrentView()->SetComputedMode (Standard_True);
1649     }
1650   }
1651 }
1652
1653 //==============================================================================
1654 //function : ProcessZClipMotion
1655 //purpose  : Zoom
1656 //==============================================================================
1657
1658 void ProcessZClipMotion()
1659 {
1660   Handle(V3d_View)  a3DView = ViewerTest::CurrentView();
1661   if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
1662
1663     //Quantity_Length VDX, VDY;
1664     //a3DView->Size(VDX,VDY);
1665     //Standard_Real VDZ = a3DView->ZSize();
1666     //printf("View size (%lf,%lf,%lf)\n", VDX, VDY, VDZ);
1667
1668     Quantity_Length aDx = a3DView->Convert(X_Motion - X_ButtonPress);
1669
1670     // Front = Depth + width/2.
1671     Standard_Real aDepth = 0.5;
1672     Standard_Real aWidth = 0.1;
1673     a3DView->ZClipping(aDepth,aWidth);
1674
1675     aDepth += aDx;
1676
1677     //printf("dx %lf Depth %lf Width %lf\n", dx, D, W);
1678
1679     a3DView->SetZClippingDepth(aDepth);
1680
1681     a3DView->Redraw();
1682
1683     X_ButtonPress = X_Motion;
1684     Y_ButtonPress = Y_Motion;
1685   }
1686 }
1687
1688 //==============================================================================
1689 //function : ProcessControlButton1Motion
1690 //purpose  : Zoom
1691 //==============================================================================
1692
1693 #if defined(_WIN32) || ! defined(__APPLE__) || defined(MACOSX_USE_GLX)
1694 static void ProcessControlButton1Motion()
1695 {
1696   ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
1697
1698   X_ButtonPress = X_Motion;
1699   Y_ButtonPress = Y_Motion;
1700 }
1701 #endif
1702
1703 //==============================================================================
1704 //function : VT_ProcessControlButton2Motion
1705 //purpose  : Panning
1706 //==============================================================================
1707 void VT_ProcessControlButton2Motion()
1708 {
1709   Standard_Integer aDx = X_Motion - X_ButtonPress;
1710   Standard_Integer aDy = Y_Motion - Y_ButtonPress;
1711
1712   aDy = -aDy; // Xwindow Y axis is from top to Bottom
1713
1714   ViewerTest::CurrentView()->Pan (aDx, aDy);
1715
1716   X_ButtonPress = X_Motion;
1717   Y_ButtonPress = Y_Motion;
1718 }
1719
1720 //==============================================================================
1721 //function : VT_ProcessControlButton3Motion
1722 //purpose  : Rotation
1723 //==============================================================================
1724 void VT_ProcessControlButton3Motion()
1725 {
1726   if (Start_Rot)
1727   {
1728     ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
1729   }
1730 }
1731
1732 //==============================================================================
1733 //function : VT_ProcessMotion
1734 //purpose  :
1735 //==============================================================================
1736 void VT_ProcessMotion()
1737 {
1738   //pre-hilights detected objects at mouse position
1739
1740   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1741   EM->MoveTo(X_Motion, Y_Motion);
1742 }
1743
1744
1745 void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
1746 {
1747   Xpix = X_Motion;Ypix=Y_Motion;
1748 }
1749
1750 //==============================================================================
1751 //function : ViewProject: implements VAxo, VTop, VLeft, ...
1752 //purpose  : Switches to an axonometric, top, left and other views
1753 //==============================================================================
1754
1755 static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
1756 {
1757   if ( ViewerTest::CurrentView().IsNull() )
1758   {
1759     di<<"Call vinit before this command, please"<<"\n";
1760     return 1;
1761   }
1762
1763   ViewerTest::CurrentView()->SetProj(ori);
1764   return 0;
1765 }
1766
1767 //==============================================================================
1768 //function : VAxo
1769 //purpose  : Switch to an Axonometric view
1770 //Draw arg : No args
1771 //==============================================================================
1772
1773 static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
1774 {
1775   return ViewProject(di, V3d_XposYnegZpos);
1776 }
1777
1778 //==============================================================================
1779 //function : VTop
1780 //purpose  : Switch to a Top View
1781 //Draw arg : No args
1782 //==============================================================================
1783
1784 static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
1785 {
1786   return ViewProject(di, V3d_Zpos);
1787 }
1788
1789 //==============================================================================
1790 //function : VBottom
1791 //purpose  : Switch to a Bottom View
1792 //Draw arg : No args
1793 //==============================================================================
1794
1795 static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
1796 {
1797   return ViewProject(di, V3d_Zneg);
1798 }
1799
1800 //==============================================================================
1801 //function : VLeft
1802 //purpose  : Switch to a Left View
1803 //Draw arg : No args
1804 //==============================================================================
1805
1806 static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
1807 {
1808   return ViewProject(di, V3d_Ypos);
1809 }
1810
1811 //==============================================================================
1812 //function : VRight
1813 //purpose  : Switch to a Right View
1814 //Draw arg : No args
1815 //==============================================================================
1816
1817 static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
1818 {
1819   return ViewProject(di, V3d_Yneg);
1820 }
1821
1822 //==============================================================================
1823 //function : VFront
1824 //purpose  : Switch to a Front View
1825 //Draw arg : No args
1826 //==============================================================================
1827
1828 static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
1829 {
1830   return ViewProject(di, V3d_Xpos);
1831 }
1832
1833 //==============================================================================
1834 //function : VBack
1835 //purpose  : Switch to a Back View
1836 //Draw arg : No args
1837 //==============================================================================
1838
1839 static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
1840 {
1841   return ViewProject(di, V3d_Xneg);
1842 }
1843
1844 //==============================================================================
1845 //function : VHelp
1846 //purpose  : Dsiplay help on viewer Keyboead and mouse commands
1847 //Draw arg : No args
1848 //==============================================================================
1849
1850 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
1851 {
1852
1853   di << "Q : Quit the application" << "\n";
1854
1855   di << "========================="<<"\n";
1856   di << "F : FitAll" << "\n";
1857   di << "T : TopView" << "\n";
1858   di << "B : BottomView" << "\n";
1859   di << "R : RightView" << "\n";
1860   di << "L : LeftView" << "\n";
1861   di << "A : AxonometricView" << "\n";
1862   di << "D : ResetView" << "\n";
1863
1864   di << "========================="<<"\n";
1865   di << "S : Shading" << "\n";
1866   di << "W : Wireframe" << "\n";
1867   di << "H : HidelLineRemoval" << "\n";
1868   di << "U : Unset display mode" << "\n";
1869   di << "Delete : Remove selection from viewer" << "\n";
1870
1871   di << "========================="<<"\n";
1872   di << "Selection mode "<<"\n";
1873   di << "0 : Shape" <<"\n";
1874   di << "1 : Vertex" <<"\n";
1875   di << "2 : Edge" <<"\n";
1876   di << "3 : Wire" <<"\n";
1877   di << "4 : Face" <<"\n";
1878   di << "5 : Shell" <<"\n";
1879   di << "6 : Solid" <<"\n";
1880   di << "7 : Compound" <<"\n";
1881
1882   di << "========================="<<"\n";
1883   di << "Z : Switch Z clipping On/Off" << "\n";
1884   di << ", : Hilight next detected" << "\n";
1885   di << ". : Hilight previous detected" << "\n";
1886
1887   return 0;
1888 }
1889
1890 #ifdef WNT
1891
1892 static Standard_Boolean Ppick = 0;
1893 static Standard_Integer Pargc = 0;
1894 static const char**           Pargv = NULL;
1895
1896
1897 static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
1898                                           UINT Msg,
1899                                           WPARAM wParam,
1900                                           LPARAM lParam )
1901 {
1902   if (!ViewerTest_myViews.IsEmpty()) {
1903
1904     WPARAM fwKeys = wParam;
1905
1906     switch( Msg ) {
1907     case WM_CLOSE:
1908        {
1909          // Delete view from map of views
1910          ViewerTest::RemoveView(FindViewIdByWindowHandle(hwnd));
1911          return 0;
1912        }
1913        break;
1914     case WM_ACTIVATE:
1915       if(LOWORD(wParam) == WA_CLICKACTIVE || LOWORD(wParam) == WA_ACTIVE
1916         || ViewerTest::CurrentView().IsNull())
1917       {
1918         // Activate inactive window
1919         if(GetWindowHandle(VT_GetWindow()) != hwnd)
1920         {
1921           ActivateView (FindViewIdByWindowHandle(hwnd));
1922         }
1923       }
1924       break;
1925     case WM_LBUTTONUP:
1926       if (!DragFirst)
1927       {
1928         HDC hdc = GetDC( hwnd );
1929         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
1930         SetROP2( hdc, R2_NOT );
1931         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1932         ReleaseDC( hwnd, hdc );
1933         VT_ProcessButton1Release (fwKeys & MK_SHIFT);
1934       }
1935       IsDragged = Standard_False;
1936       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1937
1938     case WM_LBUTTONDOWN:
1939       if( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) )
1940       {
1941         IsDragged = Standard_True;
1942         DragFirst = Standard_True;
1943         X_ButtonPress = LOWORD(lParam);
1944         Y_ButtonPress = HIWORD(lParam);
1945       }
1946       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1947
1948       break;
1949
1950     case WM_MOUSEMOVE:
1951       if( IsDragged )
1952       {
1953         HDC hdc = GetDC( hwnd );
1954
1955         HGDIOBJ anObj = SelectObject( hdc, GetStockObject( WHITE_PEN ) );
1956         SelectObject( hdc, GetStockObject( HOLLOW_BRUSH ) );
1957         SetROP2( hdc, R2_NOT );
1958
1959         if( !DragFirst )
1960           Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1961
1962         DragFirst = Standard_False;
1963         X_Motion = LOWORD(lParam);
1964         Y_Motion = HIWORD(lParam);
1965
1966         Rectangle( hdc, X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion );
1967
1968         SelectObject( hdc, anObj );
1969
1970         ReleaseDC( hwnd, hdc );
1971       }
1972       else
1973         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1974       break;
1975
1976     default:
1977       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1978     }
1979     return 0;
1980   }
1981   return ViewerWindowProc( hwnd, Msg, wParam, lParam );
1982 }
1983
1984
1985 static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
1986                                        UINT Msg,
1987                                        WPARAM wParam,
1988                                        LPARAM lParam )
1989 {
1990   static int Up = 1;
1991   const Handle(V3d_View)& aView = ViewerTest::CurrentView();
1992   if (aView.IsNull())
1993   {
1994     return DefWindowProc( hwnd, Msg, wParam, lParam );
1995   }
1996
1997     PAINTSTRUCT    ps;
1998
1999     switch( Msg ) {
2000     case WM_PAINT:
2001       BeginPaint(hwnd, &ps);
2002       EndPaint(hwnd, &ps);
2003       VT_ProcessExpose();
2004       break;
2005
2006     case WM_SIZE:
2007       VT_ProcessConfigure();
2008       break;
2009     case WM_MOVE:
2010     case WM_MOVING:
2011     case WM_SIZING:
2012       switch (aView->RenderingParams().StereoMode)
2013       {
2014         case Graphic3d_StereoMode_RowInterlaced:
2015         case Graphic3d_StereoMode_ColumnInterlaced:
2016         case Graphic3d_StereoMode_ChessBoard:
2017           VT_ProcessConfigure(); // track window moves to reverse stereo pair
2018           break;
2019         default:
2020           break;
2021       }
2022       break;
2023
2024     case WM_KEYDOWN:
2025       if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
2026       {
2027         char c[2];
2028         c[0] = (char) wParam;
2029         c[1] = '\0';
2030         if (wParam == VK_DELETE)
2031         {
2032           c[0] = THE_KEY_DELETE;
2033         }
2034         // comma
2035         else if (wParam == VK_OEM_COMMA)
2036         {
2037           c[0] = ',';
2038         }
2039         // dot
2040         else if (wParam == VK_OEM_PERIOD)
2041         {
2042           c[0] = '.';
2043         }
2044         else if (wParam == VK_DIVIDE)
2045         {
2046           c[0] = '/';
2047         }
2048         // dot
2049         else if (wParam == VK_MULTIPLY)
2050         {
2051           c[0] = '*';
2052         }
2053         VT_ProcessKeyPress (c);
2054       }
2055       break;
2056
2057     case WM_LBUTTONUP:
2058     case WM_MBUTTONUP:
2059     case WM_RBUTTONUP:
2060       Up = 1;
2061       VT_ProcessButton3Release();
2062       break;
2063
2064     case WM_LBUTTONDOWN:
2065     case WM_MBUTTONDOWN:
2066     case WM_RBUTTONDOWN:
2067       {
2068         WPARAM fwKeys = wParam;
2069
2070         Up = 0;
2071
2072         X_ButtonPress = LOWORD(lParam);
2073         Y_ButtonPress = HIWORD(lParam);
2074
2075         if (Msg == WM_LBUTTONDOWN)
2076         {
2077           if (fwKeys & MK_CONTROL)
2078           {
2079             Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
2080           }
2081           else
2082           {
2083             VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
2084           }
2085         }
2086         else if (Msg == WM_RBUTTONDOWN)
2087         {
2088           // Start rotation
2089           VT_ProcessButton3Press();
2090         }
2091       }
2092       break;
2093
2094     case WM_MOUSEWHEEL:
2095     {
2096       int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
2097       if (wParam & MK_CONTROL)
2098       {
2099         if (aView->Camera()->IsStereo())
2100         {
2101           Standard_Real aFocus = aView->Camera()->ZFocus() + (aDelta > 0 ? 0.05 : -0.05);
2102           if (aFocus > 0.2
2103            && aFocus < 2.0)
2104           {
2105             aView->Camera()->SetZFocus (aView->Camera()->ZFocusType(), aFocus);
2106             aView->Redraw();
2107           }
2108         }
2109       }
2110       else
2111       {
2112         aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
2113       }
2114       break;
2115     }
2116
2117     case WM_MOUSEMOVE:
2118       {
2119         //cout << "\t WM_MOUSEMOVE" << endl;
2120         WPARAM fwKeys = wParam;
2121         X_Motion = LOWORD(lParam);
2122         Y_Motion = HIWORD(lParam);
2123
2124         if ( Up &&
2125           fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON ) ) {
2126             Up = 0;
2127             X_ButtonPress = LOWORD(lParam);
2128             Y_ButtonPress = HIWORD(lParam);
2129
2130             if ( fwKeys & MK_RBUTTON ) {
2131               // Start rotation
2132               VT_ProcessButton3Press();
2133             }
2134           }
2135
2136           if ( fwKeys & MK_CONTROL ) {
2137             if ( fwKeys & MK_LBUTTON ) {
2138               ProcessControlButton1Motion();
2139             }
2140             else if ( fwKeys & MK_MBUTTON ||
2141               ((fwKeys&MK_LBUTTON) &&
2142               (fwKeys&MK_RBUTTON) ) ){
2143                 VT_ProcessControlButton2Motion();
2144               }
2145             else if ( fwKeys & MK_RBUTTON ) {
2146               VT_ProcessControlButton3Motion();
2147             }
2148           }
2149 #ifdef BUG
2150           else if ( fwKeys & MK_SHIFT ) {
2151             if ( fwKeys & MK_MBUTTON ||
2152               ((fwKeys&MK_LBUTTON) &&
2153               (fwKeys&MK_RBUTTON) ) ) {
2154                 cout << "ProcessZClipMotion()" << endl;
2155                 ProcessZClipMotion();
2156               }
2157           }
2158 #endif
2159           else if (GetWindowHandle (VT_GetWindow()) == hwnd)
2160           {
2161             if ((fwKeys & MK_MBUTTON
2162             || ((fwKeys & MK_LBUTTON) && (fwKeys & MK_RBUTTON))))
2163             {
2164               ProcessZClipMotion();
2165             }
2166             else
2167             {
2168               VT_ProcessMotion();
2169             }
2170           }
2171       }
2172       break;
2173
2174     default:
2175       return( DefWindowProc( hwnd, Msg, wParam, lParam ));
2176     }
2177     return 0L;
2178 }
2179
2180
2181
2182
2183 //==============================================================================
2184 //function : ViewerMainLoop
2185 //purpose  : Get a Event on the view and dispatch it
2186 //==============================================================================
2187
2188
2189 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2190 {
2191   Ppick = (argc > 0)? 1 : 0;
2192   Pargc = argc;
2193   Pargv = argv;
2194
2195   if ( Ppick ) {
2196     MSG msg;
2197     msg.wParam = 1;
2198
2199     cout << "Start picking" << endl;
2200
2201     while ( Ppick == 1 ) {
2202       // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2203       if (GetMessage(&msg, NULL, 0, 0) ) {
2204         TranslateMessage(&msg);
2205         DispatchMessage(&msg);
2206       }
2207     }
2208
2209     cout << "Picking done" << endl;
2210   }
2211
2212   return Ppick;
2213 }
2214
2215 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
2216
2217 int min( int a, int b )
2218 {
2219   if( a<b )
2220     return a;
2221   else
2222     return b;
2223 }
2224
2225 int max( int a, int b )
2226 {
2227   if( a>b )
2228     return a;
2229   else
2230     return b;
2231 }
2232
2233 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2234
2235 {
2236   static XEvent aReport;
2237   Standard_Boolean pick = argc > 0;
2238   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2239   XNextEvent (aDisplay, &aReport);
2240
2241   // Handle event for the chosen display connection
2242   switch (aReport.type) {
2243       case ClientMessage:
2244         {
2245           if((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2246           {
2247             // Close the window
2248             ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2249           }
2250         }
2251         return 0;
2252      case FocusIn:
2253       {
2254          // Activate inactive view
2255          Window aWindow = GetWindowHandle(VT_GetWindow());
2256          if(aWindow != aReport.xfocus.window)
2257          {
2258            ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2259          }
2260       }
2261       break;
2262       case Expose:
2263         {
2264           VT_ProcessExpose();
2265         }
2266         break;
2267       case ConfigureNotify:
2268         {
2269           VT_ProcessConfigure();
2270         }
2271         break;
2272       case KeyPress:
2273         {
2274
2275           KeySym ks_ret ;
2276           char buf_ret[11] ;
2277           int ret_len ;
2278           XComposeStatus status_in_out;
2279
2280           ret_len = XLookupString( ( XKeyEvent *)&aReport ,
2281             (char *) buf_ret , 10 ,
2282             &ks_ret , &status_in_out ) ;
2283
2284
2285           buf_ret[ret_len] = '\0' ;
2286
2287           if (ret_len)
2288           {
2289             VT_ProcessKeyPress (buf_ret);
2290           }
2291         }
2292         break;
2293       case ButtonPress:
2294         {
2295           X_ButtonPress = aReport.xbutton.x;
2296           Y_ButtonPress = aReport.xbutton.y;
2297
2298           if (aReport.xbutton.button == Button1)
2299           {
2300             if (aReport.xbutton.state & ControlMask)
2301             {
2302               pick = VT_ProcessButton1Press (argc, argv, pick, (aReport.xbutton.state & ShiftMask));
2303             }
2304             else
2305             {
2306               IsDragged = Standard_True;
2307               DragFirst = Standard_True;
2308             }
2309           }
2310           else if (aReport.xbutton.button == Button3)
2311           {
2312             // Start rotation
2313             VT_ProcessButton3Press();
2314           }
2315         }
2316         break;
2317       case ButtonRelease:
2318         {
2319           if( IsDragged )
2320           {
2321             if( !DragFirst )
2322             {
2323               Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2324               GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2325               XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2326             }
2327
2328             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
2329             if( aContext.IsNull() )
2330             {
2331               cout << "The context is null. Please use vinit before createmesh" << endl;
2332               return 0;
2333             }
2334
2335             Standard_Boolean ShiftPressed = ( aReport.xbutton.state & ShiftMask );
2336             if( aReport.xbutton.button==1 )
2337               if( DragFirst )
2338                 if( ShiftPressed )
2339                 {
2340                   aContext->ShiftSelect();
2341                 }
2342                 else
2343                 {
2344                   aContext->Select();
2345                 }
2346               else
2347                 if( ShiftPressed )
2348                 {
2349                   aContext->ShiftSelect( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2350                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2351                     ViewerTest::CurrentView());
2352                 }
2353                 else
2354                 {
2355                   aContext->Select( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2356                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2357                     ViewerTest::CurrentView() );
2358                 }
2359             else
2360               VT_ProcessButton3Release();
2361
2362             IsDragged = Standard_False;
2363           }
2364           else
2365             VT_ProcessButton3Release();
2366         }
2367         break;
2368       case MotionNotify:
2369         {
2370           if (GetWindowHandle (VT_GetWindow()) != aReport.xmotion.window)
2371           {
2372             break;
2373           }
2374           if( IsDragged )
2375           {
2376             Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2377             GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2378             XSetFunction( aDisplay, gc, GXinvert );
2379
2380             if( !DragFirst )
2381               XDrawRectangle(aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2382
2383             X_Motion = aReport.xmotion.x;
2384             Y_Motion = aReport.xmotion.y;
2385             DragFirst = Standard_False;
2386
2387             XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2388           }
2389           else
2390           {
2391             X_Motion = aReport.xmotion.x;
2392             Y_Motion = aReport.xmotion.y;
2393
2394             // remove all the ButtonMotionMaskr
2395             while( XCheckMaskEvent( aDisplay, ButtonMotionMask, &aReport) ) ;
2396
2397             if ( ZClipIsOn && aReport.xmotion.state & ShiftMask ) {
2398               if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
2399
2400                 Quantity_Length VDX, VDY;
2401
2402                 ViewerTest::CurrentView()->Size(VDX,VDY);
2403                 Standard_Real VDZ =0 ;
2404                 VDZ = ViewerTest::CurrentView()->ZSize();
2405
2406                 printf("%f,%f,%f\n", VDX, VDY, VDZ);
2407
2408                 Quantity_Length dx = 0 ;
2409                 dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
2410
2411                 cout << dx << endl;
2412
2413                 dx = dx / VDX * VDZ;
2414
2415                 cout << dx << endl;
2416
2417                 ViewerTest::CurrentView()->Redraw();
2418               }
2419             }
2420
2421             if ( aReport.xmotion.state & ControlMask ) {
2422               if ( aReport.xmotion.state & Button1Mask ) {
2423                 ProcessControlButton1Motion();
2424               }
2425               else if ( aReport.xmotion.state & Button2Mask ) {
2426                 VT_ProcessControlButton2Motion();
2427               }
2428               else if ( aReport.xmotion.state & Button3Mask ) {
2429                 VT_ProcessControlButton3Motion();
2430               }
2431             }
2432             else
2433             {
2434               VT_ProcessMotion();
2435             }
2436           }
2437         }
2438         break;
2439 }
2440 return pick;
2441 }
2442
2443 //==============================================================================
2444 //function : VProcessEvents
2445 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
2446 //       event in the Viewer window
2447 //==============================================================================
2448
2449 static void VProcessEvents(ClientData,int)
2450 {
2451   NCollection_Vector<int> anEventNumbers;
2452   // Get number of messages from every display
2453   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2454        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next())
2455   {
2456     anEventNumbers.Append(XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()));
2457   }
2458     // Handle events for every display
2459   int anEventIter = 0;
2460   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2461        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next(), anEventIter++)
2462   {
2463     for (int i = 0; i < anEventNumbers.Value(anEventIter) &&
2464          XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()) > 0; ++i)
2465     {
2466       SetDisplayConnection (anIter.Key2()->GetDisplayConnection());
2467       int anEventResult = ViewerMainLoop( 0, NULL);
2468       // If window is closed or context was not found finish current event processing loop
2469       if (!anEventResult)
2470         return;
2471     }
2472   }
2473
2474   SetDisplayConnection (ViewerTest::GetAISContext()->CurrentViewer()->Driver()->GetDisplayConnection());
2475
2476 }
2477 #endif
2478
2479 //==============================================================================
2480 //function : OSWindowSetup
2481 //purpose  : Setup for the X11 window to be able to cath the event
2482 //==============================================================================
2483
2484
2485 static void OSWindowSetup()
2486 {
2487 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2488   // X11
2489
2490   Window  window   = VT_GetWindow()->XWindow();
2491   SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2492   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2493   XSynchronize(aDisplay, 1);
2494
2495   // X11 : For keyboard on SUN
2496   XWMHints wmhints;
2497   wmhints.flags = InputHint;
2498   wmhints.input = 1;
2499
2500   XSetWMHints( aDisplay, window, &wmhints);
2501
2502   XSelectInput( aDisplay, window,  ExposureMask | KeyPressMask |
2503     ButtonPressMask | ButtonReleaseMask |
2504     StructureNotifyMask |
2505     PointerMotionMask |
2506     Button1MotionMask | Button2MotionMask |
2507     Button3MotionMask | FocusChangeMask
2508     );
2509   Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
2510   XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
2511
2512   XSynchronize(aDisplay, 0);
2513
2514 #else
2515   // WNT
2516 #endif
2517
2518 }
2519
2520 //==============================================================================
2521 //function : VFit
2522
2523 //purpose  : Fitall, no DRAW arguments
2524 //Draw arg : No args
2525 //==============================================================================
2526
2527 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgc, const char** theArgv)
2528 {
2529   if (theArgc > 2)
2530   {
2531     std::cout << "Wrong number of arguments! Use: vfit [-selected]" << std::endl;
2532   }
2533
2534   const Handle(V3d_View) aView = ViewerTest::CurrentView();
2535
2536   if (theArgc == 2)
2537   {
2538     TCollection_AsciiString anArg (theArgv[1]);
2539     anArg.LowerCase();
2540     if (anArg == "-selected")
2541     {
2542       ViewerTest::GetAISContext()->FitSelected (aView);
2543       return 0;
2544     }
2545   }
2546   if (aView.IsNull() == Standard_False) {
2547
2548     aView->FitAll();
2549   }
2550   return 0;
2551 }
2552
2553 //=======================================================================
2554 //function : VFitArea
2555 //purpose  : Fit view to show area located between two points
2556 //         : given in world 2D or 3D coordinates.
2557 //=======================================================================
2558 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer  theArgNb, const char** theArgVec)
2559 {
2560   Handle(V3d_View) aView = ViewerTest::CurrentView();
2561   if (aView.IsNull())
2562   {
2563     std::cerr << theArgVec[0] << "Error: No active view.\n";
2564     return 1;
2565   }
2566
2567   // Parse arguments.
2568   gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
2569   gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
2570
2571   if (theArgNb == 5)
2572   {
2573     aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2574     aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2575     aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
2576     aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
2577   }
2578   else if (theArgNb == 7)
2579   {
2580     aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2581     aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2582     aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
2583     aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
2584     aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
2585     aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
2586   }
2587   else
2588   {
2589     std::cerr << theArgVec[0] << "Error: Invalid number of arguments.\n";
2590     theDI.PrintHelp(theArgVec[0]);
2591     return 1;
2592   }
2593
2594   // Convert model coordinates to view space
2595   Handle(Graphic3d_Camera) aCamera = aView->Camera();
2596   gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
2597   gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
2598
2599   // Determine fit area
2600   gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
2601   gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
2602
2603   Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
2604
2605   if (aDiagonal < Precision::Confusion())
2606   {
2607     std::cerr << theArgVec[0] << "Error: view area is too small.\n";
2608     return 1;
2609   }
2610
2611   aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
2612   return 0;
2613 }
2614
2615 //==============================================================================
2616 //function : VZFit
2617 //purpose  : ZFitall, no DRAW arguments
2618 //Draw arg : No args
2619 //==============================================================================
2620 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2621 {
2622   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2623
2624   if (aCurrentView.IsNull())
2625   {
2626     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
2627     return 1;
2628   }
2629
2630   if (theArgsNb == 1)
2631   {
2632     aCurrentView->View()->ZFitAll();
2633     aCurrentView->Redraw();
2634     return 0;
2635   }
2636
2637   Standard_Real aScale = 1.0;
2638
2639   if (theArgsNb >= 2)
2640   {
2641     aScale = Draw::Atoi (theArgVec[1]);
2642   }
2643
2644   aCurrentView->View()->ZFitAll (aScale);
2645   aCurrentView->Redraw();
2646
2647   return 0;
2648 }
2649
2650 //==============================================================================
2651 //function : VRepaint
2652 //purpose  :
2653 //==============================================================================
2654 static int VRepaint (Draw_Interpretor& , Standard_Integer , const char** )
2655 {
2656   Handle(V3d_View) V = ViewerTest::CurrentView();
2657   if ( !V.IsNull() ) V->Redraw(); return 0;
2658 }
2659
2660 //==============================================================================
2661 //function : VClear
2662 //purpose  : Remove all the object from the viewer
2663 //Draw arg : No args
2664 //==============================================================================
2665
2666 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2667 {
2668   Handle(V3d_View) V = ViewerTest::CurrentView();
2669   if(!V.IsNull())
2670     ViewerTest::Clear();
2671   return 0;
2672 }
2673
2674 //==============================================================================
2675 //function : VPick
2676 //purpose  :
2677 //==============================================================================
2678
2679 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2680 { if (ViewerTest::CurrentView().IsNull() ) return 1;
2681
2682 if ( argc < 4 ) {
2683   di << argv[0] << "Invalid number of arguments" << "\n";
2684   return 1;
2685 }
2686
2687 while (ViewerMainLoop( argc, argv)) {
2688 }
2689
2690 return 0;
2691 }
2692
2693 //==============================================================================
2694 //function : VSetBg
2695 //purpose  : Load image as background
2696 //==============================================================================
2697
2698 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2699 {
2700   if (argc < 2 || argc > 3)
2701   {
2702     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background" << "\n";
2703     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2704     return 1;
2705   }
2706
2707   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2708   if(AISContext.IsNull())
2709   {
2710     di << "use 'vinit' command before " << argv[0] << "\n";
2711     return 1;
2712   }
2713
2714   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
2715   if (argc == 3)
2716   {
2717     const char* szType = argv[2];
2718     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2719     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2720     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2721     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2722     else
2723     {
2724       di << "Wrong fill type : " << szType << "\n";
2725       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2726       return 1;
2727     }
2728   }
2729
2730   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2731   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
2732
2733   return 0;
2734 }
2735
2736 //==============================================================================
2737 //function : VSetBgMode
2738 //purpose  : Change background image fill type
2739 //==============================================================================
2740
2741 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2742 {
2743   if (argc != 2)
2744   {
2745     di << "Usage : " << argv[0] << " filltype : Change background image mode" << "\n";
2746     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2747     return 1;
2748   }
2749
2750   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2751   if(AISContext.IsNull())
2752   {
2753     di << "use 'vinit' command before " << argv[0] << "\n";
2754     return 1;
2755   }
2756   Aspect_FillMethod aFillType = Aspect_FM_NONE;
2757   const char* szType = argv[1];
2758   if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2759   else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2760   else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2761   else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2762   else
2763   {
2764     di << "Wrong fill type : " << szType << "\n";
2765     di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2766     return 1;
2767   }
2768   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2769   V3dView->SetBgImageStyle(aFillType, Standard_True);
2770   return 0;
2771 }
2772
2773 //==============================================================================
2774 //function : VSetGradientBg
2775 //purpose  : Mount gradient background
2776 //==============================================================================
2777 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2778 {
2779   if (argc != 8 )
2780   {
2781     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background" << "\n";
2782     di << "R1,G1,B1,R2,G2,B2 = [0..255]" << "\n";
2783     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2784     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2785     return 1;
2786   }
2787
2788   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2789   if(AISContext.IsNull())
2790   {
2791     di << "use 'vinit' command before " << argv[0] << "\n";
2792     return 1;
2793   }
2794   if (argc == 8)
2795   {
2796
2797     Standard_Real R1 = Draw::Atof(argv[1])/255.;
2798     Standard_Real G1 = Draw::Atof(argv[2])/255.;
2799     Standard_Real B1 = Draw::Atof(argv[3])/255.;
2800     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
2801
2802     Standard_Real R2 = Draw::Atof(argv[4])/255.;
2803     Standard_Real G2 = Draw::Atof(argv[5])/255.;
2804     Standard_Real B2 = Draw::Atof(argv[6])/255.;
2805
2806     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
2807     int aType = Draw::Atoi(argv[7]);
2808     if( aType < 0 || aType > 8 )
2809     {
2810       di << "Wrong fill type " << "\n";
2811       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2812       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2813       return 1;
2814     }
2815
2816     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2817
2818     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2819     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
2820   }
2821
2822   return 0;
2823 }
2824
2825 //==============================================================================
2826 //function : VSetGradientBgMode
2827 //purpose  : Change gradient background fill style
2828 //==============================================================================
2829 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2830 {
2831   if (argc != 2 )
2832   {
2833     di << "Usage : " << argv[0] << " Type : Change gradient background fill type" << "\n";
2834     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2835     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2836     return 1;
2837   }
2838
2839   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2840   if(AISContext.IsNull())
2841   {
2842     di << "use 'vinit' command before " << argv[0] << "\n";
2843     return 1;
2844   }
2845   if (argc == 2)
2846   {
2847     int aType = Draw::Atoi(argv[1]);
2848     if( aType < 0 || aType > 8 )
2849     {
2850       di << "Wrong fill type " << "\n";
2851       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2852       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2853       return 1;
2854     }
2855
2856     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2857
2858     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2859     V3dView->SetBgGradientStyle( aMethod, 1 );
2860   }
2861
2862   return 0;
2863 }
2864
2865 //==============================================================================
2866 //function : VSetColorBg
2867 //purpose  : Set color background
2868 //==============================================================================
2869 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2870 {
2871   if (argc != 4 )
2872   {
2873     di << "Usage : " << argv[0] << " R G B : Set color background" << "\n";
2874     di << "R,G,B = [0..255]" << "\n";
2875     return 1;
2876   }
2877
2878   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2879   if(AISContext.IsNull())
2880   {
2881     di << "use 'vinit' command before " << argv[0] << "\n";
2882     return 1;
2883   }
2884   if (argc == 4)
2885   {
2886
2887     Standard_Real R = Draw::Atof(argv[1])/255.;
2888     Standard_Real G = Draw::Atof(argv[2])/255.;
2889     Standard_Real B = Draw::Atof(argv[3])/255.;
2890     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
2891
2892     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2893     V3dView->SetBackgroundColor( aColor );
2894     V3dView->Update();
2895   }
2896
2897   return 0;
2898 }
2899
2900 //==============================================================================
2901 //function : VSetDefaultBg
2902 //purpose  : Set default viewer background fill color
2903 //==============================================================================
2904 static int VSetDefaultBg (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
2905 {
2906   if (theArgNb != 4
2907    && theArgNb != 8)
2908   {
2909     std::cout << "Error: wrong syntax! See usage:\n";
2910     theDI.PrintHelp (theArgVec[0]);
2911     return 1;
2912   }
2913
2914   ViewerTest_DefaultBackground.FillMethod =
2915     theArgNb == 4 ? Aspect_GFM_NONE
2916                   : (Aspect_GradientFillMethod) Draw::Atoi (theArgVec[7]);
2917
2918   if (theArgNb == 4)
2919   {
2920     Standard_Real R = Draw::Atof (theArgVec[1]) / 255.;
2921     Standard_Real G = Draw::Atof (theArgVec[2]) / 255.;
2922     Standard_Real B = Draw::Atof (theArgVec[3]) / 255.;
2923     ViewerTest_DefaultBackground.FlatColor.SetValues (R, G, B, Quantity_TOC_RGB);
2924   }
2925   else
2926   {
2927     Standard_Real R1 = Draw::Atof (theArgVec[1]) / 255.;
2928     Standard_Real G1 = Draw::Atof (theArgVec[2]) / 255.;
2929     Standard_Real B1 = Draw::Atof (theArgVec[3]) / 255.;
2930     ViewerTest_DefaultBackground.GradientColor1.SetValues (R1, G1, B1, Quantity_TOC_RGB);
2931
2932     Standard_Real R2 = Draw::Atof (theArgVec[4]) / 255.;
2933     Standard_Real G2 = Draw::Atof (theArgVec[5]) / 255.;
2934     Standard_Real B2 = Draw::Atof (theArgVec[6]) / 255.;
2935     ViewerTest_DefaultBackground.GradientColor2.SetValues (R2, G2, B2, Quantity_TOC_RGB);
2936   }
2937
2938   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2939        anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
2940   {
2941     const Handle(V3d_Viewer)& aViewer = anIter.Value()->CurrentViewer();
2942     aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
2943     aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
2944                                          ViewerTest_DefaultBackground.GradientColor2,
2945                                          ViewerTest_DefaultBackground.FillMethod);
2946   }
2947
2948   return 0;
2949 }
2950
2951 //==============================================================================
2952 //function : VScale
2953 //purpose  : View Scaling
2954 //==============================================================================
2955
2956 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2957 {
2958   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2959   if ( V3dView.IsNull() ) return 1;
2960
2961   if ( argc != 4 ) {
2962     di << argv[0] << "Invalid number of arguments" << "\n";
2963     return 1;
2964   }
2965   V3dView->SetAxialScale( Draw::Atof(argv[1]),  Draw::Atof(argv[2]),  Draw::Atof(argv[3]) );
2966   return 0;
2967 }
2968 //==============================================================================
2969 //function : VZBuffTrihedron
2970 //purpose  :
2971 //==============================================================================
2972
2973 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
2974                             Standard_Integer  theArgNb,
2975                             const char**      theArgVec)
2976 {
2977   Handle(V3d_View) aView = ViewerTest::CurrentView();
2978   if (aView.IsNull())
2979   {
2980     std::cout << "Error: no active viewer!\n";
2981     return 1;
2982   }
2983
2984   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
2985
2986   Aspect_TypeOfTriedronPosition aPosition     = Aspect_TOTP_LEFT_LOWER;
2987   V3d_TypeOfVisualization       aVisType      = V3d_ZBUFFER;
2988   Quantity_Color                aLabelsColor  = Quantity_NOC_WHITE;
2989   Quantity_Color                anArrowColorX = Quantity_NOC_RED;
2990   Quantity_Color                anArrowColorY = Quantity_NOC_GREEN;
2991   Quantity_Color                anArrowColorZ = Quantity_NOC_BLUE1;
2992   Standard_Real                 aScale        = 0.1;
2993   Standard_Real                 aSizeRatio    = 0.8;
2994   Standard_Real                 anArrowDiam   = 0.05;
2995   Standard_Integer              aNbFacets     = 12;
2996   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2997   {
2998     Standard_CString        anArg = theArgVec[anArgIter];
2999     TCollection_AsciiString aFlag (anArg);
3000     aFlag.LowerCase();
3001     if (anUpdateTool.parseRedrawMode (aFlag))
3002     {
3003       continue;
3004     }
3005     else if (aFlag == "-on")
3006     {
3007       continue;
3008     }
3009     else if (aFlag == "-off")
3010     {
3011       aView->TriedronErase();
3012       return 0;
3013     }
3014     else if (aFlag == "-pos"
3015           || aFlag == "-position"
3016           || aFlag == "-corner")
3017     {
3018       if (++anArgIter >= theArgNb)
3019       {
3020         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3021         return 1;
3022       }
3023
3024       TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3025       aPosName.LowerCase();
3026       if (aPosName == "center")
3027       {
3028         aPosition = Aspect_TOTP_CENTER;
3029       }
3030       else if (aPosName == "left_lower"
3031             || aPosName == "lower_left"
3032             || aPosName == "leftlower"
3033             || aPosName == "lowerleft")
3034       {
3035         aPosition = Aspect_TOTP_LEFT_LOWER;
3036       }
3037       else if (aPosName == "left_upper"
3038             || aPosName == "upper_left"
3039             || aPosName == "leftupper"
3040             || aPosName == "upperleft")
3041       {
3042         aPosition = Aspect_TOTP_LEFT_UPPER;
3043       }
3044       else if (aPosName == "right_lower"
3045             || aPosName == "lower_right"
3046             || aPosName == "rightlower"
3047             || aPosName == "lowerright")
3048       {
3049         aPosition = Aspect_TOTP_RIGHT_LOWER;
3050       }
3051       else if (aPosName == "right_upper"
3052             || aPosName == "upper_right"
3053             || aPosName == "rightupper"
3054             || aPosName == "upperright")
3055       {
3056         aPosition = Aspect_TOTP_RIGHT_UPPER;
3057       }
3058       else
3059       {
3060         std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'\n";
3061         return 1;
3062       }
3063     }
3064     else if (aFlag == "-type")
3065     {
3066       if (++anArgIter >= theArgNb)
3067       {
3068         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3069         return 1;
3070       }
3071
3072       TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3073       aTypeName.LowerCase();
3074       if (aTypeName == "wireframe"
3075        || aTypeName == "wire")
3076       {
3077         aVisType = V3d_WIREFRAME;
3078       }
3079       else if (aTypeName == "zbuffer"
3080             || aTypeName == "shaded")
3081       {
3082         aVisType = V3d_ZBUFFER;
3083       }
3084       else
3085       {
3086         std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'\n";
3087       }
3088     }
3089     else if (aFlag == "-scale")
3090     {
3091       if (++anArgIter >= theArgNb)
3092       {
3093         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3094         return 1;
3095       }
3096
3097       aScale = Draw::Atof (theArgVec[anArgIter]);
3098     }
3099     else if (aFlag == "-size"
3100           || aFlag == "-sizeratio")
3101     {
3102       if (++anArgIter >= theArgNb)
3103       {
3104         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3105         return 1;
3106       }
3107
3108       aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3109     }
3110     else if (aFlag == "-arrowdiam"
3111           || aFlag == "-arrowdiameter")
3112     {
3113       if (++anArgIter >= theArgNb)
3114       {
3115         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3116         return 1;
3117       }
3118
3119       anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3120     }
3121     else if (aFlag == "-nbfacets")
3122     {
3123       if (++anArgIter >= theArgNb)
3124       {
3125         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3126         return 1;
3127       }
3128
3129       aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3130     }
3131     else if (aFlag == "-colorlabel"
3132           || aFlag == "-colorlabels")
3133     {
3134       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3135                                                            theArgVec + anArgIter + 1,
3136                                                            aLabelsColor);
3137       if (aNbParsed == 0)
3138       {
3139         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3140         return 1;
3141       }
3142       anArgIter += aNbParsed;
3143     }
3144     else if (aFlag == "-colorarrowx")
3145     {
3146       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3147                                                            theArgVec + anArgIter + 1,
3148                                                            anArrowColorX);
3149       if (aNbParsed == 0)
3150       {
3151         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3152         return 1;
3153       }
3154       anArgIter += aNbParsed;
3155     }
3156     else if (aFlag == "-colorarrowy")
3157     {
3158       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3159                                                            theArgVec + anArgIter + 1,
3160                                                            anArrowColorY);
3161       if (aNbParsed == 0)
3162       {
3163         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3164         return 1;
3165       }
3166       anArgIter += aNbParsed;
3167     }
3168     else if (aFlag == "-colorarrowz")
3169     {
3170       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3171                                                            theArgVec + anArgIter + 1,
3172                                                            anArrowColorZ);
3173       if (aNbParsed == 0)
3174       {
3175         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3176         return 1;
3177       }
3178       anArgIter += aNbParsed;
3179     }
3180     else
3181     {
3182       std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3183       return 1;
3184     }
3185   }
3186
3187   aView->ZBufferTriedronSetup (anArrowColorX.Name(), anArrowColorY.Name(), anArrowColorZ.Name(),
3188                                aSizeRatio, anArrowDiam, aNbFacets);
3189   aView->TriedronDisplay (aPosition, aLabelsColor.Name(), aScale, aVisType);
3190   aView->View()->ZFitAll();
3191   return 0;
3192 }
3193
3194 //==============================================================================
3195 //function : VRotate
3196 //purpose  : Camera Rotating
3197 //==============================================================================
3198
3199 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
3200 {
3201   Handle(V3d_View) aView = ViewerTest::CurrentView();
3202   if (aView.IsNull())
3203   {
3204     std::cout << "No active view!\n";
3205     return 1;
3206   }
3207
3208   Standard_Boolean hasFlags = Standard_False;
3209   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3210   {
3211     Standard_CString        anArg (theArgVec[anArgIter]);
3212     TCollection_AsciiString aFlag (anArg);
3213     aFlag.LowerCase();
3214     if (aFlag == "-mousestart"
3215      || aFlag == "-mousefrom")
3216     {
3217       hasFlags = Standard_True;
3218       if (anArgIter + 2 >= theArgNb)
3219       {
3220         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
3221         return 1;
3222       }
3223
3224       Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3225       Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3226       aView->StartRotation (anX, anY);
3227     }
3228     else if (aFlag == "-mousemove")
3229     {
3230       hasFlags = Standard_True;
3231       if (anArgIter + 2 >= theArgNb)
3232       {
3233         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
3234         return 1;
3235       }
3236
3237       Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3238       Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3239       aView->Rotation (anX, anY);
3240     }
3241     else if (theArgNb != 4
3242           && theArgNb != 7)
3243     {
3244       std::cout << "Error: wrong syntax at '" << anArg << "'\n";
3245       return 1;
3246     }
3247   }
3248
3249   if (hasFlags)
3250   {
3251     return 0;
3252   }
3253   else if (theArgNb == 4)
3254   {
3255     Standard_Real anAX = Draw::Atof (theArgVec[1]);
3256     Standard_Real anAY = Draw::Atof (theArgVec[2]);
3257     Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3258     aView->Rotate (anAX, anAY, anAZ);
3259     return 0;
3260   }
3261   else if (theArgNb == 7)
3262   {
3263     Standard_Real anAX = Draw::Atof (theArgVec[1]);
3264     Standard_Real anAY = Draw::Atof (theArgVec[2]);
3265     Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3266
3267     Standard_Real anX = Draw::Atof (theArgVec[4]);
3268     Standard_Real anY = Draw::Atof (theArgVec[5]);
3269     Standard_Real anZ = Draw::Atof (theArgVec[6]);
3270
3271     aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
3272     return 0;
3273   }
3274
3275   std::cout << "Error: Invalid number of arguments\n";
3276   return 1;
3277 }
3278
3279 //==============================================================================
3280 //function : VZoom
3281 //purpose  : View zoom in / out (relative to current zoom)
3282 //==============================================================================
3283
3284 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3285   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3286   if ( V3dView.IsNull() ) {
3287     return 1;
3288   }
3289
3290   if ( argc == 2 ) {
3291     Standard_Real coef = Draw::Atof(argv[1]);
3292     if ( coef <= 0.0 ) {
3293       di << argv[1] << "Invalid value" << "\n";
3294       return 1;
3295     }
3296     V3dView->SetZoom( Draw::Atof(argv[1]) );
3297     return 0;
3298   } else {
3299     di << argv[0] << " Invalid number of arguments" << "\n";
3300     return 1;
3301   }
3302 }
3303
3304 //==============================================================================
3305 //function : VPan
3306 //purpose  : View panning (in pixels)
3307 //==============================================================================
3308
3309 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3310   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3311   if ( V3dView.IsNull() ) return 1;
3312
3313   if ( argc == 3 ) {
3314     V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
3315     return 0;
3316   } else {
3317     di << argv[0] << " Invalid number of arguments" << "\n";
3318     return 1;
3319   }
3320 }
3321
3322 //==============================================================================
3323 //function : VPlace
3324 //purpose  : Place the point (in pixels) at the center of the window
3325 //==============================================================================
3326 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
3327 {
3328   Handle(V3d_View) aView = ViewerTest::CurrentView();
3329   if (aView.IsNull())
3330   {
3331     std::cerr << theArgs[0] << "Error: no active view." << std::endl;
3332     return 1;
3333   }
3334
3335   if (theArgNb != 3)
3336   {
3337     std::cerr << theArgs[0] << "Error: invalid number of arguments." << std::endl;
3338     return 1;
3339   }
3340
3341   aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
3342
3343   return 0;
3344 }
3345
3346 //==============================================================================
3347 //function : VExport
3348 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
3349 //==============================================================================
3350
3351 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3352 {
3353   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3354   if (V3dView.IsNull())
3355     return 1;
3356
3357   if (argc == 1)
3358   {
3359     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
3360     return 1;
3361   }
3362
3363   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
3364   TCollection_AsciiString aFormatStr;
3365
3366   TCollection_AsciiString aFileName (argv[1]);
3367   Standard_Integer aLen = aFileName.Length();
3368
3369   if (argc > 2)
3370   {
3371     aFormatStr = TCollection_AsciiString (argv[2]);
3372   }
3373   else if (aLen >= 4)
3374   {
3375     if (aFileName.Value (aLen - 2) == '.')
3376     {
3377       aFormatStr = aFileName.ToCString() + aLen - 2;
3378     }
3379     else if (aFileName.Value (aLen - 3) == '.')
3380     {
3381       aFormatStr = aFileName.ToCString() + aLen - 3;
3382     }
3383     else
3384     {
3385       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
3386       return 1;
3387     }
3388   }
3389   else
3390   {
3391     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
3392     return 1;
3393   }
3394
3395   aFormatStr.UpperCase();
3396   if (aFormatStr == "PS")
3397     anExpFormat = Graphic3d_EF_PostScript;
3398   else if (aFormatStr == "EPS")
3399     anExpFormat = Graphic3d_EF_EnhPostScript;
3400   else if (aFormatStr == "TEX")
3401     anExpFormat = Graphic3d_EF_TEX;
3402   else if (aFormatStr == "PDF")
3403     anExpFormat = Graphic3d_EF_PDF;
3404   else if (aFormatStr == "SVG")
3405     anExpFormat = Graphic3d_EF_SVG;
3406   else if (aFormatStr == "PGF")
3407     anExpFormat = Graphic3d_EF_PGF;
3408   else if (aFormatStr == "EMF")
3409     anExpFormat = Graphic3d_EF_EMF;
3410   else
3411   {
3412     std::cout << "Invalid export format '" << aFormatStr << "'\n";
3413     return 1;
3414   }
3415
3416   try {
3417     if (!V3dView->View()->Export (argv[1], anExpFormat))
3418     {
3419       di << "Error: export of image to " << aFormatStr << " failed!\n";
3420     }
3421   }
3422   catch (Standard_Failure)
3423   {
3424     di << "Error: export of image to " << aFormatStr << " failed";
3425     di << " (exception: " << Standard_Failure::Caught()->GetMessageString() << ")";
3426   }
3427   return 0;
3428 }
3429
3430 //==============================================================================
3431 //function : VColorScale
3432 //purpose  : representation color scale
3433 //==============================================================================
3434
3435 static Standard_Boolean checkColor (const TCollection_AsciiString& theRed,
3436                                     const TCollection_AsciiString& theGreen,
3437                                     const TCollection_AsciiString& theBlue,
3438                                                     Standard_Real& theRedValue,
3439                                                     Standard_Real& theGreenValue,
3440                                                     Standard_Real& theBlueValue)
3441 {
3442   if (!theRed.IsRealValue()
3443    || !theGreen.IsRealValue()
3444    || !theBlue.IsRealValue())
3445   {
3446     std::cout << "Error: RGB color values should be real!\n";
3447     return Standard_True;
3448   }
3449   theRedValue = theRed    .RealValue();
3450   theGreenValue = theGreen.RealValue();
3451   theBlueValue = theBlue  .RealValue();
3452   if (theRedValue < 0.0 || theRedValue > 1.0
3453    || theGreenValue < 0.0 || theGreenValue > 1.0
3454    || theBlueValue < 0.0 || theBlueValue > 1.0)
3455   {
3456     std::cout << "Error: RGB color values should be within range 0..1!\n";
3457     return Standard_True;
3458   }
3459   return Standard_False;
3460 }
3461
3462 static int VColorScale (Draw_Interpretor& theDI,
3463                         Standard_Integer  theArgNb,
3464                         const char**      theArgVec)
3465 {
3466   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3467   Handle(V3d_View)               aView    = ViewerTest::CurrentView();
3468   if (aContext.IsNull())
3469   {
3470     std::cout << "Error: no active view!\n";
3471     return 1;
3472   }
3473
3474   Handle(V3d_ColorScale) aCS = Handle(V3d_ColorScale)::DownCast (aView->ColorScale());
3475   if (aCS.IsNull())
3476   {
3477     std::cout << "Error: color scale is undefined!\n";
3478     return 1;
3479   }
3480
3481   Standard_Real                   aMinRange    = aCS->GetMin();
3482   Standard_Real                   aMaxRange    = aCS->GetMax();
3483   Standard_Integer                aNbIntervals = aCS->GetNumberOfIntervals();
3484   Standard_Integer                aTextHeight  = aCS->GetTextHeight();
3485   Aspect_TypeOfColorScalePosition aLabPosition = aCS->GetLabelPosition();
3486   gp_XY                           aPos (aCS->GetXPosition(), aCS->GetYPosition());
3487
3488   ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
3489
3490   if (theArgNb <= 1)
3491   {
3492     theDI << "Current color scale parameters:\n"
3493           << "Min range: " << aMinRange << "\n"
3494           << "Max range: " << aMaxRange << "\n"
3495           << "Number of intervals: " << aNbIntervals << "\n"
3496           << "Text height: " << aTextHeight << "\n"
3497           << "Color scale position: " << aPos.X() <<" "<< aPos.Y()<< "\n"
3498           << "Color scale title: " << aCS->GetTitle() << "\n"
3499           << "Label position: ";
3500     switch (aLabPosition)
3501     {
3502       case Aspect_TOCSP_NONE:
3503         theDI << "None\n";
3504         break;
3505       case Aspect_TOCSP_LEFT:
3506         theDI << "Left\n";
3507         break;
3508       case Aspect_TOCSP_RIGHT:
3509         theDI << "Right\n";
3510         break;
3511       case Aspect_TOCSP_CENTER:
3512         theDI << "Center\n";
3513         break;
3514     }
3515     return 0;
3516   }
3517   Standard_CString        aFirstArg = theArgVec[1];
3518   TCollection_AsciiString aFlag (aFirstArg);
3519   aFlag.LowerCase();
3520   if (aFlag == "-hide" ||
3521       aFlag == "-erase")
3522   {
3523     if (theArgNb > 2)
3524     {
3525       std::cout << "Error: wrong syntax at argument '" << theArgVec[1] << "'!\n";
3526       return 1;
3527     }
3528     if (!aView->ColorScaleIsDisplayed())
3529     {
3530       std::cout << "Error: color scale is not displayed!\n";
3531       return 1;
3532    }
3533     else
3534     {
3535       aView->ColorScaleErase();
3536       return 0;
3537     }
3538   }
3539   else if (aFlag == "-show" ||
3540            aFlag == "-display")
3541   {
3542     if (theArgNb > 2)
3543     {
3544       std::cout << "Error: wrong syntax at argument '" << theArgVec[1] << "'!\n";
3545       return 1;
3546     }
3547     aView->ColorScaleDisplay();
3548     return 0;
3549   }
3550
3551   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3552   {
3553     Standard_CString        anArg = theArgVec[anArgIter];
3554     TCollection_AsciiString aFlag (anArg);
3555     aFlag.LowerCase();
3556     if (anUpdateTool.parseRedrawMode (aFlag))
3557     {
3558       continue;
3559     }
3560     else if (aFlag == "-range")
3561     {
3562       if (anArgIter + 3 >= theArgNb)
3563       {
3564         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3565         return 1;
3566       }
3567
3568       TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
3569       TCollection_AsciiString anArg2 (theArgVec[++anArgIter]);
3570       TCollection_AsciiString anArg3 (theArgVec[++anArgIter]);
3571       if (!anArg1.IsRealValue())
3572       {
3573         std::cout << "Error: the minRange value should be real!\n";
3574         return 1;
3575       }
3576       else if (!anArg2.IsRealValue())
3577       {
3578         std::cout << "Error: the maxRange value should be real!\n";
3579         return 1;
3580       }
3581       else if (!anArg3.IsIntegerValue())
3582       {
3583         std::cout << "Error: the number of intervals should be integer!\n";
3584         return 1;
3585       }
3586
3587       aMinRange    = anArg1.RealValue();
3588       aMaxRange    = anArg2.RealValue();
3589       aNbIntervals = anArg3.IntegerValue();
3590     }
3591     else if (aFlag == "-font")
3592     {
3593       if (anArgIter + 1 >= theArgNb)
3594       {
3595         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3596         return 1;
3597       }
3598       TCollection_AsciiString anArg (theArgVec[anArgIter + 1]);
3599       if (!anArg.IsIntegerValue())
3600       {
3601         std::cout << "Error: HeightFont value should be integer!\n";
3602         return 1;
3603       }
3604
3605       aTextHeight = anArg.IntegerValue();
3606       anArgIter += 1;
3607     }
3608     else if (aFlag == "-textpos")
3609     {
3610       if (anArgIter + 1 >= theArgNb)
3611       {
3612         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3613         return 1;
3614       }
3615       TCollection_AsciiString anArg (theArgVec[++anArgIter]);
3616       anArg.LowerCase();
3617       if (anArg == "none")
3618       {
3619         aLabPosition = Aspect_TOCSP_NONE;
3620       }
3621       else if (anArg == "left")
3622       {
3623         aLabPosition = Aspect_TOCSP_LEFT;
3624       }
3625       else if (anArg == "right")
3626       {
3627         aLabPosition = Aspect_TOCSP_RIGHT;
3628       }
3629       else if (anArg == "center")
3630       {
3631         aLabPosition = Aspect_TOCSP_CENTER;
3632       }
3633       else
3634       {
3635         std::cout << "Error: unknown position '" << anArg << "'!\n";
3636         return 1;
3637       }
3638     }
3639     else if (aFlag == "-xy")
3640     {
3641       if (anArgIter + 2 >= theArgNb)
3642       {
3643         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3644         return 1;
3645       }
3646
3647       TCollection_AsciiString aX (theArgVec[++anArgIter]);
3648       TCollection_AsciiString aY (theArgVec[++anArgIter]);
3649       if (!aX.IsRealValue()
3650        || !aY.IsRealValue())
3651       {
3652         std::cout << "Error: coordinates should be real values!\n";
3653         return 1;
3654       }
3655
3656       aPos.SetCoord (aX.RealValue(), aY.RealValue());
3657     }
3658     else if (aFlag == "-color")
3659     {
3660       if (aCS->GetColorType() != Aspect_TOCSD_USER)
3661       {
3662         std::cout << "Error: wrong color type! Call -colors before to set user-specified colors!\n";
3663         return 1;
3664       }
3665
3666       Quantity_NameOfColor aColorName;
3667       if (anArgIter + 4 >= theArgNb)
3668       {
3669         if (anArgIter + 2 >= theArgNb)
3670         {
3671           std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3672           return 1;
3673         }
3674         else if (!Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName))
3675         {
3676           std::cout << "Error: wrong color name: '" << theArgVec[anArgIter + 2] << "' !\n";
3677           return 1;
3678         }
3679       }
3680
3681       TCollection_AsciiString anInd (theArgVec[anArgIter + 1]);
3682       if (!anInd.IsIntegerValue())
3683       {
3684         std::cout << "Error: Index value should be integer!\n";
3685         return 1;
3686       }
3687
3688       Standard_Integer anIndex = anInd.IntegerValue();
3689       if (anIndex < 0
3690        || anIndex > aNbIntervals - 1)
3691       {
3692         std::cout << "Error: Index value should be within range 0..." << (aNbIntervals - 1) <<"!\n";
3693         return 1;
3694       }
3695
3696       if (Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName))
3697       {
3698         aCS->SetColor    (Quantity_Color (aColorName), anIndex);
3699         aCS->SetColorType(Aspect_TOCSD_USER);
3700         anArgIter += 2;
3701         continue;
3702       }
3703
3704       TCollection_AsciiString aRed   (theArgVec[anArgIter + 2]);
3705       TCollection_AsciiString aGreen (theArgVec[anArgIter + 3]);
3706       TCollection_AsciiString aBlue  (theArgVec[anArgIter + 4]);
3707       Standard_Real aRedValue,aGreenValue, aBlueValue;
3708       if(checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue))
3709       {
3710         return 1;
3711       }
3712       aCS->SetColor     (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB), anIndex);
3713       aCS->SetColorType (Aspect_TOCSD_USER);
3714       anArgIter += 4;
3715     }
3716     else if (aFlag == "-label")
3717     {
3718       if (aCS->GetColorType() != Aspect_TOCSD_USER)
3719       {
3720         std::cout << "Error: wrong label type! Call -labels before to set user-specified labels!\n";
3721         return 1;
3722       }
3723       else if (anArgIter + 2 >= theArgNb)
3724       {
3725         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3726         return 1;
3727       }
3728
3729       Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
3730       if (anIndex < 0
3731        || anIndex > aNbIntervals)
3732       {
3733         std::cout << "Error: Index value should be within range 0..." << aNbIntervals <<"!\n";
3734         return 1;
3735       }
3736
3737       TCollection_ExtendedString aText (theArgVec[anArgIter + 2]);
3738       aCS->SetLabel     (aText, anIndex);
3739       aCS->SetLabelType (Aspect_TOCSD_USER);
3740       anArgIter += 2;
3741     }
3742     else if (aFlag == "-colors")
3743     {
3744       Aspect_SequenceOfColor aSeq;
3745       if (anArgIter + aNbIntervals + 1 > theArgNb)
3746       {
3747         std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
3748                   << aNbIntervals << " intervals\n";
3749         return 1;
3750       }
3751
3752       Standard_Integer aColorIter = anArgIter + 1;
3753       while (aColorIter < theArgNb)
3754       {
3755         if (theArgVec[aColorIter][0] == '-')
3756         {
3757           break;
3758         }
3759
3760         else if (theArgVec[aColorIter][0] >= 97
3761               && theArgVec[aColorIter][0] <= 122)
3762         {
3763           Quantity_NameOfColor aColorName;
3764           if (!Quantity_Color::ColorFromName (theArgVec[aColorIter], aColorName))
3765           {
3766             std::cout << "Error: wrong color name: " << theArgVec[aColorIter] << " !\n";
3767             return 1;
3768           }
3769           aSeq.Append (Quantity_Color (aColorName));
3770           aColorIter++;
3771           anArgIter++;
3772         }
3773         else
3774         {
3775           TCollection_AsciiString aRed   (theArgVec[aColorIter]);
3776           TCollection_AsciiString aGreen (theArgVec[aColorIter + 1]);
3777           TCollection_AsciiString aBlue  (theArgVec[aColorIter + 2]);
3778           Standard_Real aRedValue,aGreenValue, aBlueValue;
3779           if (checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue))
3780           {
3781             return 1;
3782           }
3783           aSeq.Append (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB));
3784           aColorIter += 3;
3785           anArgIter += 3;
3786         }
3787       }
3788       if (aSeq.Length() < aNbIntervals)
3789       {
3790         std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
3791                   << aNbIntervals << " intervals\n";
3792         return 1;
3793       }
3794
3795       aCS->SetColors    (aSeq);
3796       aCS->SetColorType (Aspect_TOCSD_USER);
3797     }
3798     else if (aFlag == "-labels")
3799     {
3800       if (anArgIter + aNbIntervals + 1 >= theArgNb)
3801       {
3802         std::cout << "Error: not enough arguments! You should provide " << (aNbIntervals + 1)
3803                   << " text labels for " << aNbIntervals << " intervals.\n";
3804         return 1;
3805       }
3806
3807       TColStd_SequenceOfExtendedString aSeq;
3808       for (int aLabelIter = anArgIter + 1; aLabelIter <= anArgIter + aNbIntervals + 1; aLabelIter += 1)
3809       {
3810         aSeq.Append (TCollection_ExtendedString (theArgVec[aLabelIter]));
3811       }
3812       aCS->SetLabels (aSeq);
3813       aCS->SetLabelType (Aspect_TOCSD_USER);
3814       anArgIter += aSeq.Length();
3815     }
3816     else if (aFlag == "-title")
3817     {
3818       if (anArgIter + 1 >= theArgNb)
3819       {
3820         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3821         return 1;
3822       }
3823
3824       Standard_Boolean isTwoArgs = Standard_False;
3825       if (anArgIter + 2 < theArgNb)
3826       {
3827         TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
3828         aSecondArg.LowerCase();
3829         if (aSecondArg == "none")
3830         {
3831           aCS->SetTitlePosition (Aspect_TOCSP_NONE);
3832           isTwoArgs = Standard_True;
3833         }
3834         else if (aSecondArg == "left")
3835         {
3836           aCS->SetTitlePosition (Aspect_TOCSP_LEFT);
3837           isTwoArgs = Standard_True;
3838         }
3839         else if (aSecondArg == "right")
3840         {
3841           aCS->SetTitlePosition (Aspect_TOCSP_RIGHT);
3842           isTwoArgs = Standard_True;
3843         }
3844         else if (aSecondArg == "center")
3845         {
3846           aCS->SetTitlePosition (Aspect_TOCSP_CENTER);
3847           isTwoArgs = Standard_True;
3848         }
3849       }
3850
3851       aCS->SetTitle (theArgVec[anArgIter + 1]);
3852       if (isTwoArgs)
3853       {
3854         anArgIter += 1;
3855       }
3856       anArgIter += 1;
3857     }
3858     else if (aFlag == "-demoversion"
3859           || aFlag == "-demo")
3860     {
3861       aPos.SetCoord (0.0, 0.0);
3862       aTextHeight  = 16;
3863       aMinRange    = 0.0;
3864       aMaxRange    = 100;
3865       aNbIntervals = 10;
3866       aLabPosition = Aspect_TOCSP_RIGHT;
3867       aCS->SetColorType(Aspect_TOCSD_AUTO);
3868       aCS->SetLabelType(Aspect_TOCSD_AUTO);
3869     }
3870     else
3871     {
3872       std::cout << "Error: wrong syntax at " << anArg << " - unknown argument!\n";
3873       return 1;
3874     }
3875   }
3876
3877   aCS->SetPosition          (aPos.X(), aPos.Y());
3878   aCS->SetHeight            (0.95);
3879   aCS->SetTextHeight        (aTextHeight);
3880   aCS->SetRange             (aMinRange, aMaxRange);
3881   aCS->SetNumberOfIntervals (aNbIntervals);
3882   aCS->SetLabelPosition     (aLabPosition);
3883
3884   if (!aView->ColorScaleIsDisplayed())
3885   {
3886     aView->ColorScaleDisplay();
3887   }
3888
3889   return 0;
3890 }
3891
3892 //==============================================================================
3893 //function : VGraduatedTrihedron
3894 //purpose  : Displays or hides a graduated trihedron
3895 //==============================================================================
3896 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
3897                                   Quantity_Color& theColor)
3898 {
3899   Quantity_NameOfColor aColorName;
3900   TCollection_AsciiString aVal = theValue;
3901   aVal.UpperCase();
3902   if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
3903   {
3904     return Standard_False;
3905   }
3906   theColor = Quantity_Color (aColorName);
3907   return Standard_True;
3908 }
3909
3910 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
3911 {
3912   if (theArgNum < 2)
3913   {
3914     std::cout << theArgs[0] << " error: wrong number of parameters. Type 'help"
3915               << theArgs[0] <<"' for more information.\n";
3916     return 1;  //TCL_ERROR
3917   }
3918
3919   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
3920   TCollection_AsciiString aParseKey;
3921   for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
3922   {
3923     TCollection_AsciiString anArg (theArgs [anArgIt]);
3924
3925     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
3926     {
3927       aParseKey = anArg;
3928       aParseKey.Remove (1);
3929       aParseKey.LowerCase();
3930       aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
3931       continue;
3932     }
3933
3934     if (aParseKey.IsEmpty())
3935     {
3936       continue;
3937     }
3938
3939     aMapOfArgs(aParseKey)->Append (anArg);
3940   }
3941
3942   // Check parameters
3943   for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
3944        aMapIt.More(); aMapIt.Next())
3945   {
3946     const TCollection_AsciiString& aKey = aMapIt.Key();
3947     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
3948
3949     // Bool key, without arguments
3950     if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
3951         && anArgs->IsEmpty())
3952     {
3953       continue;
3954     }
3955
3956     // One argument
3957     if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
3958           && anArgs->Length() == 1)
3959     {
3960       continue;
3961     }
3962
3963     // On/off arguments
3964     if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
3965         || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
3966         || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
3967         || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
3968         && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
3969     {
3970       continue;
3971     }
3972
3973     // One string argument
3974     if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
3975           || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
3976           && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
3977     {
3978       continue;
3979     }
3980
3981     // One integer argument
3982     if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
3983           || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
3984           || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
3985           || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
3986          && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
3987     {
3988       continue;
3989     }
3990
3991     // One real argument
3992     if ( aKey.IsEqual ("arrowlength")
3993          && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue()))
3994     {
3995       continue;
3996     }
3997
3998     // Two string arguments
3999     if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
4000          && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
4001     {
4002       continue;
4003     }
4004
4005     TCollection_AsciiString aLowerKey;
4006     aLowerKey  = "-";
4007     aLowerKey += aKey;
4008     aLowerKey.LowerCase();
4009     std::cout << theArgs[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
4010     std::cout << "Type help for more information.\n";
4011     return 1;
4012   }
4013
4014   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4015   if (anAISContext.IsNull())
4016   {
4017     std::cout << theArgs[0] << ": " << " please use 'vinit' command to initialize view.\n";
4018     return 1;
4019   }
4020
4021   Standard_Boolean toDisplay = Standard_True;
4022   Quantity_Color aColor;
4023   Graphic3d_GraduatedTrihedron aTrihedronData;
4024   // Process parameters
4025   Handle(TColStd_HSequenceOfAsciiString) aValues;
4026   if (aMapOfArgs.Find ("off", aValues))
4027   {
4028     toDisplay = Standard_False;
4029   }
4030
4031   // AXES NAMES
4032   if (aMapOfArgs.Find ("xname", aValues))
4033   {
4034     aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4035   }
4036   if (aMapOfArgs.Find ("yname", aValues))
4037   {
4038     aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4039   }
4040   if (aMapOfArgs.Find ("zname", aValues))
4041   {
4042     aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4043   }
4044   if (aMapOfArgs.Find ("xdrawname", aValues))
4045   {
4046     aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4047   }
4048   if (aMapOfArgs.Find ("ydrawname", aValues))
4049   {
4050     aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4051   }
4052   if (aMapOfArgs.Find ("zdrawname", aValues))
4053   {
4054     aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4055   }
4056   if (aMapOfArgs.Find ("xnameoffset", aValues))
4057   {
4058     aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4059   }
4060   if (aMapOfArgs.Find ("ynameoffset", aValues))
4061   {
4062     aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4063   }
4064   if (aMapOfArgs.Find ("znameoffset", aValues))
4065   {
4066     aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4067   }
4068
4069   // COLORS
4070   if (aMapOfArgs.Find ("xnamecolor", aValues))
4071   {
4072     if (!GetColor (aValues->Value(1), aColor))
4073     {
4074       std::cout << theArgs[0] << "error: -xnamecolor wrong color name.\n";
4075       return 1;
4076     }
4077     aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4078   }
4079   if (aMapOfArgs.Find ("ynamecolor", aValues))
4080   {
4081     if (!GetColor (aValues->Value(1), aColor))
4082     {
4083       std::cout << theArgs[0] << "error: -ynamecolor wrong color name.\n";
4084       return 1;
4085     }
4086     aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4087   }
4088   if (aMapOfArgs.Find ("znamecolor", aValues))
4089   {
4090     if (!GetColor (aValues->Value(1), aColor))
4091     {
4092       std::cout << theArgs[0] << "error: -znamecolor wrong color name.\n";
4093       return 1;
4094     }
4095     aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4096   }
4097   if (aMapOfArgs.Find ("xcolor", aValues))
4098   {
4099     if (!GetColor (aValues->Value(1), aColor))
4100     {
4101       std::cout << theArgs[0] << "error: -xcolor wrong color name.\n";
4102       return 1;
4103     }
4104     aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4105   }
4106   if (aMapOfArgs.Find ("ycolor", aValues))
4107   {
4108     if (!GetColor (aValues->Value(1), aColor))
4109     {
4110       std::cout << theArgs[0] << "error: -ycolor wrong color name.\n";
4111       return 1;
4112     }
4113     aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4114   }
4115   if (aMapOfArgs.Find ("zcolor", aValues))
4116   {
4117     if (!GetColor (aValues->Value(1), aColor))
4118     {
4119       std::cout << theArgs[0] << "error: -zcolor wrong color name.\n";
4120       return 1;
4121     }
4122     aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4123   }
4124
4125   // TICKMARKS
4126   if (aMapOfArgs.Find ("xticks", aValues))
4127   {
4128     aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4129   }
4130   if (aMapOfArgs.Find ("yticks", aValues))
4131   {
4132     aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4133   }
4134   if (aMapOfArgs.Find ("zticks", aValues))
4135   {
4136     aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4137   }
4138   if (aMapOfArgs.Find ("xticklength", aValues))
4139   {
4140     aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4141   }
4142   if (aMapOfArgs.Find ("yticklength", aValues))
4143   {
4144     aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4145   }
4146   if (aMapOfArgs.Find ("zticklength", aValues))
4147   {
4148     aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4149   }
4150   if (aMapOfArgs.Find ("xdrawticks", aValues))
4151   {
4152     aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4153   }
4154   if (aMapOfArgs.Find ("ydrawticks", aValues))
4155   {
4156     aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4157   }
4158   if (aMapOfArgs.Find ("zdrawticks", aValues))
4159   {
4160     aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4161   }
4162
4163   // VALUES
4164   if (aMapOfArgs.Find ("xdrawvalues", aValues))
4165   {
4166     aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4167   }
4168   if (aMapOfArgs.Find ("ydrawvalues", aValues))
4169   {
4170     aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4171   }
4172   if (aMapOfArgs.Find ("zdrawvalues", aValues))
4173   {
4174     aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4175   }
4176   if (aMapOfArgs.Find ("xvaluesoffset", aValues))
4177   {
4178     aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4179   }
4180   if (aMapOfArgs.Find ("yvaluesoffset", aValues))
4181   {
4182     aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4183   }
4184   if (aMapOfArgs.Find ("zvaluesoffset", aValues))
4185   {
4186     aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4187   }
4188
4189   // ARROWS
4190   if (aMapOfArgs.Find ("arrowlength", aValues))
4191   {
4192     aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
4193   }
4194
4195   // FONTS
4196   if (aMapOfArgs.Find ("namefont", aValues))
4197   {
4198     aTrihedronData.SetNamesFont (aValues->Value(1));
4199   }
4200   if (aMapOfArgs.Find ("valuesfont", aValues))
4201   {
4202     aTrihedronData.SetValuesFont (aValues->Value(1));
4203   }
4204
4205   if (aMapOfArgs.Find ("drawgrid", aValues))
4206   {
4207     aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
4208   }
4209   if (aMapOfArgs.Find ("drawaxes", aValues))
4210   {
4211     aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
4212   }
4213
4214   // The final step: display of erase trihedron
4215   if (toDisplay)
4216   {
4217     ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
4218   }
4219   else
4220   {
4221     ViewerTest::CurrentView()->GraduatedTrihedronErase();
4222   }
4223
4224   ViewerTest::GetAISContext()->UpdateCurrentViewer();
4225   ViewerTest::CurrentView()->Redraw();
4226
4227   return 0;
4228 }
4229
4230 //==============================================================================
4231 //function : VPrintView
4232 //purpose  : Test printing algorithm, print the view to image file with given
4233 //           width and height. Printing implemented only for WNT.
4234 //==============================================================================
4235 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
4236                        const char** argv)
4237 {
4238 #ifndef WNT
4239   di << "Printing implemented only for wnt!\n";
4240   return 0;
4241 #else
4242
4243   Handle(AIS_InteractiveContext) aContextAIS = NULL;
4244   Handle(V3d_View) aView = NULL;
4245   aContextAIS = ViewerTest::GetAISContext();
4246   if (!aContextAIS.IsNull())
4247   {
4248     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
4249     Vwr->InitActiveViews();
4250     if(Vwr->MoreActiveViews())
4251       aView = Vwr->ActiveView();
4252   }
4253
4254   // check for errors
4255   if (aView.IsNull())
4256   {
4257     di << "Call vinit before!\n";
4258     return 1;
4259   }
4260   else if (argc < 4)
4261   {
4262     di << "Use: " << argv[0];
4263     di << " width height filename [print algo=0] [tile_width tile_height]\n";
4264     di << "width, height of the intermediate buffer for operation\n";
4265     di << "algo : {0|1}\n";
4266     di << "        0 - stretch algorithm\n";
4267     di << "        1 - tile algorithm\n";
4268     di << "test printing algorithms into an intermediate buffer\n";
4269     di << "using specific tile size if provided\n";
4270     di << "with saving output to an image file\n";
4271     return 1;
4272   }
4273
4274   // get the input params
4275   Standard_Integer aWidth  = Draw::Atoi (argv[1]);
4276   Standard_Integer aHeight = Draw::Atoi (argv[2]);
4277   Standard_Integer aMode   = 0;
4278   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
4279   if (argc >= 5)
4280     aMode = Draw::Atoi (argv[4]);
4281
4282   Standard_Integer aTileWidth  = 0;
4283   Standard_Integer aTileHeight = 0;
4284   Standard_Boolean isTileSizeProvided = Standard_False;
4285   if (argc == 7)
4286   {
4287     isTileSizeProvided = Standard_True;
4288     aTileWidth  = Draw::Atoi (argv[5]);
4289     aTileHeight = Draw::Atoi (argv[6]);
4290   }
4291
4292   // check the input parameters
4293   if (aWidth <= 0 || aHeight <= 0)
4294   {
4295     di << "Width and height must be positive values!\n";
4296     return 1;
4297   }
4298   if (aMode != 0 && aMode != 1)
4299     aMode = 0;
4300
4301   // define compatible bitmap
4302   HDC anDC = CreateCompatibleDC(0);
4303   BITMAPINFO aBitmapData;
4304   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
4305   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
4306   aBitmapData.bmiHeader.biWidth         = aWidth ;
4307   aBitmapData.bmiHeader.biHeight        = aHeight;
4308   aBitmapData.bmiHeader.biPlanes        = 1;
4309   aBitmapData.bmiHeader.biBitCount      = 24;
4310   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
4311   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
4312   aBitmapData.bmiHeader.biClrUsed       = 0;
4313   aBitmapData.bmiHeader.biClrImportant  = 0;
4314   aBitmapData.bmiHeader.biCompression   = BI_RGB;
4315   aBitmapData.bmiHeader.biSizeImage     = 0;
4316
4317   // Create Device Independent Bitmap
4318   void* aBitsOut = NULL;
4319   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
4320                                             &aBitsOut, NULL, 0);
4321   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
4322
4323   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
4324   if (aBitsOut != NULL)
4325   {
4326     if (aMode == 0)
4327       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
4328     else
4329     {
4330       if (isTileSizeProvided)
4331       {
4332         Graphic3d_CView* aCView = static_cast<Graphic3d_CView*> (ViewerTest::CurrentView()->View()->CView());
4333         Graphic3d_PtrFrameBuffer anOldBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
4334         aCView->ptrFBO = aView->View()->FBOCreate (aTileWidth, aTileHeight);
4335
4336         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
4337
4338         Graphic3d_PtrFrameBuffer aNewBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
4339         aView->View()->FBORelease (aNewBuffer);
4340         aCView->ptrFBO = anOldBuffer;
4341       }
4342       else
4343       {
4344         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
4345       }
4346     }
4347
4348     // succesfully printed into an intermediate buffer
4349     if (isPrinted)
4350     {
4351       Image_PixMap aWrapper;
4352       aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
4353       aWrapper.SetTopDown (false);
4354
4355       Image_AlienPixMap anImageBitmap;
4356       anImageBitmap.InitCopy (aWrapper);
4357       isSaved = anImageBitmap.Save (aFileName);
4358     }
4359     else
4360     {
4361       di << "Print operation failed due to printing errors or\n";
4362       di << "insufficient memory available\n";
4363       di << "Please, try to use smaller dimensions for this test\n";
4364       di << "command, as it allocates intermediate buffer for storing\n";
4365       di << "the result\n";
4366     }
4367   }
4368   else
4369   {
4370     di << "Can't allocate memory for intermediate buffer\n";
4371     di << "Please use smaller dimensions\n";
4372   }
4373
4374   if (aMemoryBitmap)
4375   {
4376     SelectObject (anDC, anOldBitmap);
4377     DeleteObject (aMemoryBitmap);
4378     DeleteDC(anDC);
4379   }
4380
4381   if (!isSaved)
4382   {
4383     di << "Save to file operation failed. This operation may fail\n";
4384     di << "if you don't have enough available memory, then you can\n";
4385     di << "use smaller dimensions for the output file\n";
4386     return 1;
4387   }
4388
4389   return 0;
4390
4391 #endif
4392 }
4393
4394 //==============================================================================
4395 //function : VZLayer
4396 //purpose  : Test z layer operations for v3d viewer
4397 //==============================================================================
4398 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4399 {
4400   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
4401   if (aContextAIS.IsNull())
4402   {
4403     di << "Call vinit before!\n";
4404     return 1;
4405   }
4406   else if (argc < 2)
4407   {
4408     di << "Use: vzlayer ";
4409     di << " add/del/get/settings/enable/disable [id]\n";
4410     di << " add - add new z layer to viewer and print its id\n";
4411     di << " del - del z layer by its id\n";
4412     di << " get - print sequence of z layers in increasing order of their overlay level\n";
4413     di << " settings - print status of z layer settings\n";
4414     di << " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n";
4415     di << " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n";
4416     di << " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n";
4417     di << "\nWhere id is the layer identificator\n";
4418     di << "\nExamples:\n";
4419     di << "   vzlayer add\n";
4420     di << "   vzlayer enable poffset 1\n";
4421     di << "   vzlayer disable depthtest 1\n";
4422     di << "   vzlayer del 1\n";
4423     return 1;
4424   }
4425
4426   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
4427   if (aViewer.IsNull())
4428   {
4429     di << "No active viewer!\n";
4430     return 1;
4431   }
4432
4433   // perform operation
4434   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
4435   if (anOp == "add")
4436   {
4437     Standard_Integer aNewId;
4438     if (!aViewer->AddZLayer (aNewId))
4439     {
4440       di << "Impossible to add new z layer!\n";
4441       return 1;
4442     }
4443
4444     di << "New z layer added with index: " << aNewId << "\n";
4445   }
4446   else if (anOp == "del")
4447   {
4448     if (argc < 3)
4449     {
4450       di << "Please also provide as argument id of z layer to remove\n";
4451       return 1;
4452     }
4453
4454     Standard_Integer aDelId = Draw::Atoi (argv[2]);
4455     if (!aViewer->RemoveZLayer (aDelId))
4456     {
4457       di << "Impossible to remove the z layer or invalid id!\n";
4458       return 1;
4459     }
4460
4461     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4462          anObjIter.More(); anObjIter.Next())
4463     {
4464       Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anObjIter.Key1());
4465       if (aPrs.IsNull()
4466        || aPrs->ZLayer() != aDelId)
4467       {
4468         continue;
4469       }
4470       aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
4471     }
4472
4473     di << "Z layer " << aDelId << " has been removed\n";
4474   }
4475   else if (anOp == "get")
4476   {
4477     TColStd_SequenceOfInteger anIds;
4478     aViewer->GetAllZLayers (anIds);
4479     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
4480     {
4481       di << anIds.Value (aSeqIdx) << " ";
4482     }
4483
4484     di << "\n";
4485   }
4486   else if (anOp == "settings")
4487   {
4488     if (argc < 3)
4489     {
4490       di << "Please also provide an id\n";
4491       return 1;
4492     }
4493
4494     Standard_Integer anId = Draw::Atoi (argv[2]);
4495     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4496
4497     di << "Depth test - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthTest) ? "enabled" : "disabled") << "\n";
4498     di << "Depth write - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite) ? "enabled" : "disabled") << "\n";
4499     di << "Depth buffer clearing - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear) ? "enabled" : "disabled") << "\n";
4500     di << "Depth offset - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthOffset) ? "enabled" : "disabled") << "\n";
4501
4502   }
4503   else if (anOp == "enable")
4504   {
4505     if (argc < 3)
4506     {
4507       di << "Please also provide an option to enable\n";
4508       return 1;
4509     }
4510
4511     if (argc < 4)
4512     {
4513       di << "Please also provide a layer id\n";
4514       return 1;
4515     }
4516
4517     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
4518     Standard_Integer anId = Draw::Atoi (argv[3]);
4519     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4520
4521     if (aSubOp == "depthtest" || aSubOp == "test")
4522     {
4523       aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
4524     }
4525     else if (aSubOp == "depthwrite" || aSubOp == "write")
4526     {
4527       aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
4528     }
4529     else if (aSubOp == "depthclear" || aSubOp == "clear")
4530     {
4531       aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
4532     }
4533     else if (aSubOp == "depthoffset" || aSubOp == "offset")
4534     {
4535       if (argc < 6)
4536       {
4537         di << "Please also provide a factor and units values for depth offset\n";
4538         di << "Format is: vzlayer enable offset [factor] [units] [layerId]\n";
4539         return 1;
4540       }
4541
4542       Standard_ShortReal aFactor = static_cast<Standard_ShortReal> (Draw::Atof (argv[3]));
4543       Standard_ShortReal aUnits  = static_cast<Standard_ShortReal> (Draw::Atof (argv[4]));
4544       anId = Draw::Atoi (argv[5]);
4545       aSettings = aViewer->ZLayerSettings (anId);
4546
4547       aSettings.DepthOffsetFactor = aFactor;
4548       aSettings.DepthOffsetUnits  = aUnits;
4549
4550       aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
4551     }
4552     else if (aSubOp == "positiveoffset" || aSubOp == "poffset")
4553     {
4554       aSettings.SetDepthOffsetPositive();
4555     }
4556     else if (aSubOp == "negativeoffset" || aSubOp == "noffset")
4557     {
4558       aSettings.SetDepthOffsetNegative();
4559     }
4560
4561     aViewer->SetZLayerSettings (anId, aSettings);
4562   }
4563   else if (anOp == "disable")
4564   {
4565     if (argc < 3)
4566     {
4567       di << "Please also provide an option to disable\n";
4568       return 1;
4569     }
4570
4571     if (argc < 4)
4572     {
4573       di << "Please also provide a layer id\n";
4574       return 1;
4575     }
4576
4577     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
4578     Standard_Integer anId = Draw::Atoi (argv[3]);
4579     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4580
4581     if (aSubOp == "depthtest" || aSubOp == "test")
4582     {
4583       aSettings.DisableSetting (Graphic3d_ZLayerDepthTest);
4584     }
4585     else if (aSubOp == "depthwrite" || aSubOp == "write")
4586     {
4587       aSettings.DisableSetting (Graphic3d_ZLayerDepthWrite);
4588     }
4589     else if (aSubOp == "depthclear" || aSubOp == "clear")
4590     {
4591       aSettings.DisableSetting (Graphic3d_ZLayerDepthClear);
4592     }
4593     else if (aSubOp == "depthoffset" || aSubOp == "offset")
4594     {
4595       aSettings.DisableSetting (Graphic3d_ZLayerDepthOffset);
4596     }
4597
4598     aViewer->SetZLayerSettings (anId, aSettings);
4599   }
4600   else
4601   {
4602     di << "Invalid operation, please use { add / del / get / settings / enable / disable}\n";
4603     return 1;
4604   }
4605
4606   return 0;
4607 }
4608
4609 // this class provides a presentation of text item in v3d view under-/overlayer
4610 class V3d_TextItem : public Visual3d_LayerItem
4611 {
4612 public:
4613
4614   // CASCADE RTTI
4615   DEFINE_STANDARD_RTTI(V3d_TextItem, Visual3d_LayerItem)
4616
4617   // constructor
4618   Standard_EXPORT V3d_TextItem(const TCollection_AsciiString& theText,
4619                                const Standard_Real theX1,
4620                                const Standard_Real theY1,
4621                                const Standard_Real theHeight,
4622                                const TCollection_AsciiString& theFontName,
4623                                const Quantity_Color& theColor,
4624                                const Quantity_Color& theSubtitleColor,
4625                                const Aspect_TypeOfDisplayText& theTypeOfDisplay,
4626                                const Handle(Visual3d_Layer)& theLayer);
4627
4628   // redraw method
4629   Standard_EXPORT void RedrawLayerPrs();
4630
4631 private:
4632
4633   Standard_Real            myX1;
4634   Standard_Real            myY1;
4635   TCollection_AsciiString  myText;
4636   Standard_Real            myHeight;
4637   Handle(Visual3d_Layer)   myLayer;
4638   Quantity_Color           myColor;
4639   Quantity_Color           mySubtitleColor;
4640   Aspect_TypeOfDisplayText myType;
4641   TCollection_AsciiString  myFontName;
4642 };
4643
4644
4645 // create and add to display the text item
4646 V3d_TextItem::V3d_TextItem (const TCollection_AsciiString& theText,
4647                             const Standard_Real theX1,
4648                             const Standard_Real theY1,
4649                             const Standard_Real theHeight,
4650                             const TCollection_AsciiString& theFontName,
4651                             const Quantity_Color& theColor,
4652                             const Quantity_Color& theSubtitleColor,
4653                             const Aspect_TypeOfDisplayText& theTypeOfDisplay,
4654                             const Handle(Visual3d_Layer)& theLayer)
4655  : myX1 (theX1), myY1 (theY1),
4656    myText (theText),
4657    myHeight (theHeight),
4658    myLayer (theLayer),
4659    myColor (theColor),
4660    mySubtitleColor (theSubtitleColor),
4661    myType (theTypeOfDisplay),
4662    myFontName (theFontName)
4663 {
4664   if (!myLayer.IsNull ())
4665     myLayer->AddLayerItem (this);
4666 }
4667
4668 // render item
4669 void V3d_TextItem::RedrawLayerPrs ()
4670 {
4671   if (myLayer.IsNull ())
4672     return;
4673
4674   myLayer->SetColor (myColor);
4675   myLayer->SetTextAttributes (myFontName.ToCString (), myType, mySubtitleColor);
4676   myLayer->DrawText (myText.ToCString (), myX1, myY1, myHeight);
4677 }
4678
4679 // The Visual3d_LayerItem line item for "vlayerline" command
4680 // it provides a presentation of line with user-defined
4681 // linewidth, linetype and transparency.
4682 class V3d_LineItem : public Visual3d_LayerItem
4683 {
4684 public:
4685   // CASCADE RTTI
4686   DEFINE_STANDARD_RTTI(V3d_LineItem, Visual3d_LayerItem)
4687
4688   // constructor
4689   Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4690                                Standard_Real X2, Standard_Real Y2,
4691                                V3d_LayerMgrPointer theLayerMgr,
4692                                Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
4693                                Standard_Real theWidth    = 0.5,
4694                                Standard_Real theTransp   = 1.0);
4695
4696   // redraw method
4697   Standard_EXPORT   void RedrawLayerPrs();
4698
4699 private:
4700
4701   Standard_Real       myX1, myY1, myX2, myY2;
4702   V3d_LayerMgrPointer myLayerMgr;
4703   Aspect_TypeOfLine   myType;
4704   Standard_Real       myWidth;
4705   Standard_Real       myTransparency;
4706 };
4707
4708
4709 // default constructor for line item
4710 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4711                            Standard_Real X2, Standard_Real Y2,
4712                            V3d_LayerMgrPointer theLayerMgr,
4713                            Aspect_TypeOfLine theType,
4714                            Standard_Real theWidth,
4715                            Standard_Real theTransp) :
4716   myX1(X1), myY1(Y1), myX2(X2), myY2(Y2), myLayerMgr(theLayerMgr),
4717   myType(theType), myWidth(theWidth), myTransparency(theTransp)
4718 {
4719   if (myLayerMgr && !myLayerMgr->Overlay().IsNull())
4720     myLayerMgr->Overlay()->AddLayerItem (this);
4721 }
4722
4723 // render line
4724 void V3d_LineItem::RedrawLayerPrs ()
4725 {
4726   Handle (Visual3d_Layer) aOverlay;
4727
4728   if (myLayerMgr)
4729     aOverlay = myLayerMgr->Overlay();
4730
4731   if (!aOverlay.IsNull())
4732   {
4733     Quantity_Color aColor(1.0, 0, 0, Quantity_TOC_RGB);
4734     aOverlay->SetColor(aColor);
4735     aOverlay->SetTransparency((Standard_ShortReal)myTransparency);
4736     aOverlay->SetLineAttributes((Aspect_TypeOfLine)myType, myWidth);
4737     aOverlay->BeginPolyline();
4738     aOverlay->AddVertex(myX1, myY1);
4739     aOverlay->AddVertex(myX2, myY2);
4740     aOverlay->ClosePrimitive();
4741   }
4742 }
4743
4744 //=============================================================================
4745 //function : VLayerLine
4746 //purpose  : Draws line in the v3d view layer with given attributes: linetype,
4747 //         : linewidth, transparency coefficient
4748 //============================================================================
4749 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4750 {
4751   // get the active view
4752   Handle(V3d_View) aView = ViewerTest::CurrentView();
4753   if (aView.IsNull())
4754   {
4755     di << "Call vinit before!\n";
4756     return 1;
4757   }
4758   else if (argc < 5)
4759   {
4760     di << "Use: " << argv[0];
4761     di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
4762     di << " linetype : { 0 | 1 | 2 | 3 } \n";
4763     di << "              0 - solid  \n";
4764     di << "              1 - dashed \n";
4765     di << "              2 - dot    \n";
4766     di << "              3 - dashdot\n";
4767     di << " transparency : { 0.0 - 1.0 } \n";
4768     di << "                  0.0 - transparent\n";
4769     di << "                  1.0 - visible    \n";
4770     return 1;
4771   }
4772
4773   // get the input params
4774   Standard_Real X1 = Draw::Atof(argv[1]);
4775   Standard_Real Y1 = Draw::Atof(argv[2]);
4776   Standard_Real X2 = Draw::Atof(argv[3]);
4777   Standard_Real Y2 = Draw::Atof(argv[4]);
4778
4779   Standard_Real    aWidth = 0.5;
4780   Standard_Integer aType  = 0;
4781   Standard_Real    aTransparency = 1.0;
4782
4783   // has width
4784   if (argc > 5)
4785     aWidth = Draw::Atof(argv[5]);
4786
4787   // has type
4788   if (argc > 6)
4789      aType = (Standard_Integer) Draw::Atoi(argv[6]);
4790
4791   // has transparency
4792   if (argc > 7)
4793   {
4794     aTransparency = Draw::Atof(argv[7]);
4795     if (aTransparency < 0 || aTransparency > 1.0)
4796       aTransparency = 1.0;
4797   }
4798
4799   // select appropriate line type
4800   Aspect_TypeOfLine aLineType;
4801   switch (aType)
4802   {
4803     case 1:
4804       aLineType = Aspect_TOL_DASH;
4805     break;
4806
4807     case 2:
4808       aLineType = Aspect_TOL_DOT;
4809     break;
4810
4811     case 3:
4812       aLineType = Aspect_TOL_DOTDASH;
4813     break;
4814
4815     default:
4816       aLineType = Aspect_TOL_SOLID;
4817   }
4818
4819   // replace layer manager
4820   Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr(aView);
4821   aView->SetLayerMgr(aMgr);
4822
4823   // add line item
4824   Handle (V3d_LineItem) anItem = new V3d_LineItem(X1, Y1, X2, Y2,
4825                                                   aMgr.operator->(),
4826                                                   aLineType, aWidth,
4827                                                   aTransparency);
4828
4829   // update view
4830   aView->MustBeResized();
4831   aView->Redraw();
4832
4833   return 0;
4834 }
4835
4836 //=======================================================================
4837 //function : VOverlayText
4838 //purpose  : Test text displaying in view overlay
4839 //=======================================================================
4840 static int VOverlayText (Draw_Interpretor& di, Standard_Integer argc, const char**argv)
4841 {
4842   // get the active view
4843   Handle(V3d_View) aView = ViewerTest::CurrentView();
4844   if (aView.IsNull())
4845   {
4846     di << "No active view. Please call vinit.\n";
4847     return 1;
4848   }
4849   else if (argc < 4 || argc > 13)
4850   {
4851     di << "Use: " << argv[0];
4852     di << " text x y [height] [font_name] [text_color: R G B] [displayType]\n";
4853     di << "[background_color: R G B]\n";
4854     di << "  height - pixel height of the text (default=10.0)\n";
4855     di << "  font_name - name of font (default=courier)\n";
4856     di << "  text_color - R G B values of text color (default=255.0 255.0 255.0)\n";
4857     di << "  display_type = {normal/subtitle/decal/blend/dimension}, (default=normal)\n";
4858     di << "  background_color- R G B values used for subtitle and decal text\n";
4859     di << "(default=255.0 255.0 255.0)\n";
4860     return 1;
4861   }
4862
4863   TCollection_AsciiString aText (argv[1]);
4864   Standard_Real aPosX = Draw::Atof(argv[2]);
4865   Standard_Real aPosY = Draw::Atof(argv[3]);
4866   Standard_Real aHeight = (argc >= 5) ? Draw::Atof (argv[4]) : 10.0;
4867
4868   // font name
4869   TCollection_AsciiString aFontName = "Courier";
4870   if (argc >= 6)
4871     aFontName = TCollection_AsciiString (argv[5]);
4872
4873   // text colors
4874   Quantity_Parameter aColorRed   = 1.0;
4875   Quantity_Parameter aColorGreen = 1.0;
4876   Quantity_Parameter aColorBlue  = 1.0;
4877   if (argc >= 9)
4878   {
4879     aColorRed   = Draw::Atof (argv[6])/255.;
4880     aColorGreen = Draw::Atof (argv[7])/255.;
4881     aColorBlue  = Draw::Atof (argv[8])/255.;
4882   }
4883
4884   // display type
4885   TCollection_AsciiString aDispStr;
4886   if (argc >= 10)
4887     aDispStr = TCollection_AsciiString (argv[9]);
4888
4889   Aspect_TypeOfDisplayText aTextType = Aspect_TODT_NORMAL;
4890   if (aDispStr.IsEqual ("subtitle"))
4891     aTextType = Aspect_TODT_SUBTITLE;
4892   else if (aDispStr.IsEqual ("decal"))
4893     aTextType = Aspect_TODT_DEKALE;
4894   else if (aDispStr.IsEqual ("blend"))
4895     aTextType = Aspect_TODT_BLEND;
4896   else if (aDispStr.IsEqual ("dimension"))
4897     aTextType = Aspect_TODT_DIMENSION;
4898
4899   // subtitle color
4900   Quantity_Parameter aSubRed   = 1.0;
4901   Quantity_Parameter aSubGreen = 1.0;
4902   Quantity_Parameter aSubBlue  = 1.0;
4903   if (argc == 13)
4904   {
4905     aSubRed   = Draw::Atof (argv[10])/255.;
4906     aSubGreen = Draw::Atof (argv[11])/255.;
4907     aSubBlue  = Draw::Atof (argv[12])/255.;
4908   }
4909
4910   // check fo current overlay
4911   Handle(Visual3d_Layer) anOverlay = aView->Viewer()->Viewer()->OverLayer ();
4912   if (anOverlay.IsNull ())
4913   {
4914     Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr (aView);
4915     anOverlay = aMgr->Overlay ();
4916     aView->SetLayerMgr (aMgr);
4917   }
4918
4919   Quantity_Color aTextColor (aColorRed, aColorGreen,
4920     aColorBlue, Quantity_TOC_RGB);
4921   Quantity_Color aSubtColor (aSubRed, aSubGreen,
4922     aSubBlue, Quantity_TOC_RGB);
4923
4924   // add text item
4925   Handle(V3d_TextItem) anItem = new V3d_TextItem (aText, aPosX, aPosY,
4926     aHeight, aFontName, aTextColor, aSubtColor, aTextType, anOverlay);
4927
4928   // update view
4929   aView->MustBeResized();
4930   aView->Redraw();
4931
4932   return 0;
4933 }
4934
4935 //==============================================================================
4936 //function : VGrid
4937 //purpose  :
4938 //==============================================================================
4939
4940 static int VGrid (Draw_Interpretor& /*theDI*/,
4941                   Standard_Integer  theArgNb,
4942                   const char**      theArgVec)
4943 {
4944   // get the active view
4945   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
4946   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
4947   if (aView.IsNull() || aViewer.IsNull())
4948   {
4949     std::cerr << "No active view. Please call vinit.\n";
4950     return 1;
4951   }
4952
4953   Aspect_GridType     aType = aViewer->GridType();
4954   Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
4955
4956   Standard_Integer anIter = 1;
4957   for (; anIter < theArgNb; ++anIter)
4958   {
4959     const char* aValue = theArgVec[anIter];
4960     if (*aValue == 'r')
4961     {
4962       aType = Aspect_GT_Rectangular;
4963     }
4964     else if (*aValue == 'c')
4965     {
4966       aType = Aspect_GT_Circular;
4967     }
4968     else if (*aValue == 'l')
4969     {
4970       aMode = Aspect_GDM_Lines;
4971     }
4972     else if (*aValue == 'p')
4973     {
4974       aMode = Aspect_GDM_Points;
4975     }
4976     else if (strcmp (aValue, "off" ) == 0)
4977     {
4978       aViewer->DeactivateGrid();
4979       return 0;
4980     }
4981     else
4982     {
4983       break;
4984     }
4985   }
4986
4987   Standard_Integer aTail = (theArgNb - anIter);
4988   if (aTail == 0)
4989   {
4990     aViewer->ActivateGrid (aType, aMode);
4991     return 0;
4992   }
4993   else if (aTail != 2 && aTail != 5)
4994   {
4995     std::cerr << "Incorrect arguments number! Usage:\n"
4996               << "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]\n";
4997     return 1;
4998   }
4999
5000   Quantity_Length anOriginX, anOriginY;
5001   Quantity_PlaneAngle aRotAngle;
5002   if (aType == Aspect_GT_Rectangular)
5003   {
5004     Quantity_Length aRStepX, aRStepY;
5005     aViewer->RectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
5006
5007     anOriginX = Draw::Atof (theArgVec[anIter++]);
5008     anOriginY = Draw::Atof (theArgVec[anIter++]);
5009     if (aTail == 5)
5010     {
5011       aRStepX   = Draw::Atof (theArgVec[anIter++]);
5012       aRStepY   = Draw::Atof (theArgVec[anIter++]);
5013       aRotAngle = Draw::Atof (theArgVec[anIter++]);
5014     }
5015     aViewer->SetRectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
5016     aViewer->ActivateGrid (aType, aMode);
5017   }
5018   else if (aType == Aspect_GT_Circular)
5019   {
5020     Quantity_Length aRadiusStep;
5021     Standard_Integer aDivisionNumber;
5022     aViewer->CircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
5023
5024     anOriginX = Draw::Atof (theArgVec[anIter++]);
5025     anOriginY = Draw::Atof (theArgVec[anIter++]);
5026     if (aTail == 5)
5027     {
5028       aRadiusStep     = Draw::Atof (theArgVec[anIter++]);
5029       aDivisionNumber = Draw::Atoi (theArgVec[anIter++]);
5030       aRotAngle       = Draw::Atof (theArgVec[anIter++]);
5031     }
5032
5033     aViewer->SetCircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
5034     aViewer->ActivateGrid (aType, aMode);
5035   }
5036
5037   return 0;
5038 }
5039
5040 //==============================================================================
5041 //function : VPriviledgedPlane
5042 //purpose  :
5043 //==============================================================================
5044
5045 static int VPriviledgedPlane (Draw_Interpretor& theDI,
5046                               Standard_Integer  theArgNb,
5047                               const char**      theArgVec)
5048 {
5049   if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
5050   {
5051     std::cerr << "Error: wrong number of arguments! See usage:\n";
5052     theDI.PrintHelp (theArgVec[0]);
5053     return 1;
5054   }
5055
5056   // get the active viewer
5057   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5058   if (aViewer.IsNull())
5059   {
5060     std::cerr << "Error: no active viewer. Please call vinit.\n";
5061     return 1;
5062   }
5063
5064   if (theArgNb == 1)
5065   {
5066     gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
5067     const gp_Pnt& anOrig = aPriviledgedPlane.Location();
5068     const gp_Dir& aNorm = aPriviledgedPlane.Direction();
5069     const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
5070     theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
5071           << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
5072           << "X-dir: "  << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
5073     return 0;
5074   }
5075
5076   Standard_Integer anArgIdx = 1;
5077   Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
5078   Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
5079   Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
5080   Standard_Real aNormX  = Draw::Atof (theArgVec[anArgIdx++]);
5081   Standard_Real aNormY  = Draw::Atof (theArgVec[anArgIdx++]);
5082   Standard_Real aNormZ  = Draw::Atof (theArgVec[anArgIdx++]);
5083
5084   gp_Ax3 aPriviledgedPlane;
5085   gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
5086   gp_Dir aNorm (aNormX, aNormY, aNormZ);
5087   if (theArgNb > 7)
5088   {
5089     Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
5090     Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
5091     Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
5092     gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
5093     aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
5094   }
5095   else
5096   {
5097     aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
5098   }
5099
5100   aViewer->SetPrivilegedPlane (aPriviledgedPlane);
5101
5102   return 0;
5103 }
5104
5105 //==============================================================================
5106 //function : VConvert
5107 //purpose  :
5108 //==============================================================================
5109
5110 static int VConvert (Draw_Interpretor& theDI,
5111                      Standard_Integer  theArgNb,
5112                      const char**      theArgVec)
5113 {
5114   // get the active view
5115   Handle(V3d_View) aView = ViewerTest::CurrentView();
5116   if (aView.IsNull())
5117   {
5118     std::cerr << "Error: no active view. Please call vinit.\n";
5119     return 1;
5120   }
5121
5122   enum { Model, Ray, View, Window, Grid } aMode = Model;
5123
5124   // access coordinate arguments
5125   TColStd_SequenceOfReal aCoord;
5126   Standard_Integer anArgIdx = 1;
5127   for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
5128   {
5129     TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5130     if (!anArg.IsRealValue())
5131     {
5132       break;
5133     }
5134     aCoord.Append (anArg.RealValue());
5135   }
5136
5137   // non-numeric argument too early
5138   if (aCoord.IsEmpty())
5139   {
5140     std::cerr << "Error: wrong number of arguments! See usage:\n";
5141     theDI.PrintHelp (theArgVec[0]);
5142     return 1;
5143   }
5144
5145   // collect all other arguments and options
5146   for (; anArgIdx < theArgNb; ++anArgIdx)
5147   {
5148     TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5149     anArg.LowerCase();
5150     if      (anArg == "window") aMode = Window;
5151     else if (anArg == "view")   aMode = View;
5152     else if (anArg == "grid")   aMode = Grid;
5153     else if (anArg == "ray")    aMode = Ray;
5154     else
5155     {
5156       std::cerr << "Error: wrong argument " << anArg << "! See usage:\n";
5157       theDI.PrintHelp (theArgVec[0]);
5158       return 1;
5159     }
5160   }
5161
5162   // complete input checks
5163   if ((aCoord.Length() == 1 && theArgNb > 3) ||
5164       (aCoord.Length() == 2 && theArgNb > 4) ||
5165       (aCoord.Length() == 3 && theArgNb > 5))
5166   {
5167     std::cerr << "Error: wrong number of arguments! See usage:\n";
5168     theDI.PrintHelp (theArgVec[0]);
5169     return 1;
5170   }
5171
5172   Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
5173   Standard_Integer aXYp[2] = {0, 0};
5174
5175   // convert one-dimensional coordinate
5176   if (aCoord.Length() == 1)
5177   {
5178     switch (aMode)
5179     {
5180       case View   : theDI << "View Vv: "   << aView->Convert ((Standard_Integer) aCoord (1)); return 0;
5181       case Window : theDI << "Window Vp: " << aView->Convert ((Quantity_Length) aCoord (1));  return 0;
5182       default:
5183         std::cerr << "Error: wrong arguments! See usage:\n";
5184         theDI.PrintHelp (theArgVec[0]);
5185         return 1;
5186     }
5187   }
5188
5189   // convert 2D coordinates from projection or view reference space
5190   if (aCoord.Length() == 2)
5191   {
5192     switch (aMode)
5193     {
5194       case Model :
5195         aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5196         theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5197         return 0;
5198
5199       case View :
5200         aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
5201         theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
5202         return 0;
5203
5204       case Window :
5205         aView->Convert ((V3d_Coordinate) aCoord (1), (V3d_Coordinate) aCoord (2), aXYp[0], aXYp[1]);
5206         theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5207         return 0;
5208
5209       case Grid :
5210         aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5211         aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
5212         theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5213         return 0;
5214
5215       case Ray :
5216         aView->ConvertWithProj ((Standard_Integer) aCoord (1),
5217                                 (Standard_Integer) aCoord (2),
5218                                 aXYZ[0], aXYZ[1], aXYZ[2],
5219                                 aXYZ[3], aXYZ[4], aXYZ[5]);
5220         theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5221         return 0;
5222
5223       default:
5224         std::cerr << "Error: wrong arguments! See usage:\n";
5225         theDI.PrintHelp (theArgVec[0]);
5226         return 1;
5227     }
5228   }
5229
5230   // convert 3D coordinates from view reference space
5231   else if (aCoord.Length() == 3)
5232   {
5233     switch (aMode)
5234     {
5235       case Window :
5236         aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
5237         theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5238         return 0;
5239
5240       case Grid :
5241         aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
5242         theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5243         return 0;
5244
5245       default:
5246         std::cerr << "Error: wrong arguments! See usage:\n";
5247         theDI.PrintHelp (theArgVec[0]);
5248         return 1;
5249     }
5250   }
5251
5252   return 0;
5253 }
5254
5255 //==============================================================================
5256 //function : VFps
5257 //purpose  :
5258 //==============================================================================
5259
5260 static int VFps (Draw_Interpretor& theDI,
5261                  Standard_Integer  theArgNb,
5262                  const char**      theArgVec)
5263 {
5264   // get the active view
5265   Handle(V3d_View) aView = ViewerTest::CurrentView();
5266   if (aView.IsNull())
5267   {
5268     std::cerr << "No active view. Please call vinit.\n";
5269     return 1;
5270   }
5271
5272   Standard_Integer aFramesNb = (theArgNb > 1) ? Draw::Atoi(theArgVec[1]) : 100;
5273   if (aFramesNb <= 0)
5274   {
5275     std::cerr << "Incorrect arguments!\n";
5276     return 1;
5277   }
5278
5279   // the time is meaningless for first call
5280   // due to async OpenGl rendering
5281   aView->Redraw();
5282
5283   // redraw view in loop to estimate average values
5284   OSD_Timer aTimer;
5285   aTimer.Start();
5286   for (Standard_Integer anInter = 0; anInter < aFramesNb; ++anInter)
5287   {
5288     aView->Redraw();
5289   }
5290   aTimer.Stop();
5291   Standard_Real aCpu;
5292   const Standard_Real aTime = aTimer.ElapsedTime();
5293   aTimer.OSD_Chronometer::Show (aCpu);
5294
5295   const Standard_Real aFpsAver = Standard_Real(aFramesNb) / aTime;
5296   const Standard_Real aCpuAver = aCpu / Standard_Real(aFramesNb);
5297
5298   // return statistics
5299   theDI << "FPS: " << aFpsAver << "\n"
5300         << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
5301
5302   // compute additional statistics in ray-tracing mode
5303   Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
5304
5305   if (aParams.Method == Graphic3d_RM_RAYTRACING)
5306   {
5307     Standard_Integer aSizeX;
5308     Standard_Integer aSizeY;
5309
5310     aView->Window()->Size (aSizeX, aSizeY);
5311
5312     // 1 shadow ray and 1 secondary ray pew each bounce
5313     const Standard_Real aMRays = aSizeX * aSizeY * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
5314
5315     theDI << "MRays/sec (upper bound): " << aMRays << "\n";
5316   }
5317
5318   return 0;
5319 }
5320
5321 //==============================================================================
5322 //function : VGlDebug
5323 //purpose  :
5324 //==============================================================================
5325
5326 static int VGlDebug (Draw_Interpretor& theDI,
5327                      Standard_Integer  theArgNb,
5328                      const char**      theArgVec)
5329 {
5330   Handle(OpenGl_GraphicDriver) aDriver;
5331   Handle(V3d_View) aView = ViewerTest::CurrentView();
5332   if (!aView.IsNull())
5333   {
5334     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
5335   }
5336   OpenGl_Caps* aDefCaps = &ViewerTest_myDefaultCaps;
5337   OpenGl_Caps* aCaps    = !aDriver.IsNull() ? &aDriver->ChangeOptions() : NULL;
5338
5339   if (theArgNb < 2)
5340   {
5341     TCollection_AsciiString aDebActive, aSyncActive;
5342     if (aCaps == NULL)
5343     {
5344       aCaps = aDefCaps;
5345     }
5346     else
5347     {
5348       Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )::glGetString (GL_EXTENSIONS),
5349                                                                   "GL_ARB_debug_output");
5350       aDebActive = isActive ? " (active)" : " (inactive)";
5351       if (isActive)
5352       {
5353         // GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
5354         aSyncActive = ::glIsEnabled (0x8242) == GL_TRUE ? " (active)" : " (inactive)";
5355       }
5356     }
5357
5358     theDI << "debug:   " << (aCaps->contextDebug      ? "1" : "0") << aDebActive  << "\n"
5359           << "sync:    " << (aCaps->contextSyncDebug  ? "1" : "0") << aSyncActive << "\n"
5360           << "glslWarn:" << (aCaps->glslWarnings      ? "1" : "0") << "\n"
5361           << "extraMsg:" << (aCaps->suppressExtraMsg  ? "0" : "1") << "\n";
5362     return 0;
5363   }
5364
5365   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5366   {
5367     Standard_CString        anArg     = theArgVec[anArgIter];
5368     TCollection_AsciiString anArgCase (anArg);
5369     anArgCase.LowerCase();
5370     Standard_Boolean toEnableDebug = Standard_True;
5371     if (anArgCase == "-glsl"
5372      || anArgCase == "-glslwarn"
5373      || anArgCase == "-glslwarns"
5374      || anArgCase == "-glslwarnings")
5375     {
5376       Standard_Boolean toShowWarns = Standard_True;
5377       if (++anArgIter < theArgNb
5378       && !parseOnOff (theArgVec[anArgIter], toShowWarns))
5379       {
5380         --anArgIter;
5381       }
5382       aDefCaps->glslWarnings = toShowWarns;
5383       if (aCaps != NULL)
5384       {
5385         aCaps->glslWarnings = toShowWarns;
5386       }
5387     }
5388     else if (anArgCase == "-extra"
5389           || anArgCase == "-extramsg"
5390           || anArgCase == "-extramessages")
5391     {
5392       Standard_Boolean toShow = Standard_True;
5393       if (++anArgIter < theArgNb
5394       && !parseOnOff (theArgVec[anArgIter], toShow))
5395       {
5396         --anArgIter;
5397       }
5398       aDefCaps->suppressExtraMsg = !toShow;
5399       if (aCaps != NULL)
5400       {
5401         aCaps->suppressExtraMsg = !toShow;
5402       }
5403     }
5404     else if (anArgCase == "-noextra"
5405           || anArgCase == "-noextramsg"
5406           || anArgCase == "-noextramessages")
5407     {
5408       Standard_Boolean toSuppress = Standard_True;
5409       if (++anArgIter < theArgNb
5410       && !parseOnOff (theArgVec[anArgIter], toSuppress))
5411       {
5412         --anArgIter;
5413       }
5414       aDefCaps->suppressExtraMsg = toSuppress;
5415       if (aCaps != NULL)
5416       {
5417         aCaps->suppressExtraMsg = toSuppress;
5418       }
5419     }
5420     else if (anArgCase == "-sync")
5421     {
5422       Standard_Boolean toSync = Standard_True;
5423       if (++anArgIter < theArgNb
5424       && !parseOnOff (theArgVec[anArgIter], toSync))
5425       {
5426         --anArgIter;
5427       }
5428       aDefCaps->contextSyncDebug = toSync;
5429       if (toSync)
5430       {
5431         aDefCaps->contextDebug = Standard_True;
5432       }
5433     }
5434     else if (anArgCase == "-debug")
5435     {
5436       if (++anArgIter < theArgNb
5437       && !parseOnOff (theArgVec[anArgIter], toEnableDebug))
5438       {
5439         --anArgIter;
5440       }
5441       aDefCaps->contextDebug = toEnableDebug;
5442     }
5443     else if (parseOnOff (anArg, toEnableDebug)
5444           && (anArgIter + 1 == theArgNb))
5445     {
5446       // simple alias to turn on almost everything
5447       aDefCaps->contextDebug     = toEnableDebug;
5448       aDefCaps->contextSyncDebug = toEnableDebug;
5449       aDefCaps->glslWarnings     = toEnableDebug;
5450     }
5451     else
5452     {
5453       std::cout << "Error: wrong syntax at '" << anArg << "'\n";
5454       return 1;
5455     }
5456   }
5457
5458   return 0;
5459 }
5460
5461 //==============================================================================
5462 //function : VVbo
5463 //purpose  :
5464 //==============================================================================
5465
5466 static int VVbo (Draw_Interpretor& theDI,
5467                  Standard_Integer  theArgNb,
5468                  const char**      theArgVec)
5469 {
5470   const Standard_Boolean toSet    = (theArgNb > 1);
5471   const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
5472   if (toSet)
5473   {
5474     ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
5475   }
5476
5477   // get the context
5478   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5479   if (aContextAIS.IsNull())
5480   {
5481     if (!toSet)
5482     {
5483       std::cerr << "No active view!\n";
5484     }
5485     return 1;
5486   }
5487   Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
5488   if (!aDriver.IsNull())
5489   {
5490     if (!toSet)
5491     {
5492       theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
5493     }
5494     else
5495     {
5496       aDriver->ChangeOptions().vboDisable = toUseVbo;
5497     }
5498   }
5499
5500   return 0;
5501 }
5502
5503 //==============================================================================
5504 //function : VCaps
5505 //purpose  :
5506 //==============================================================================
5507
5508 static int VCaps (Draw_Interpretor& theDI,
5509                   Standard_Integer  theArgNb,
5510                   const char**      theArgVec)
5511 {
5512   OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
5513   Handle(OpenGl_GraphicDriver)   aDriver;
5514   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5515   if (!aContext.IsNull())
5516   {
5517     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
5518     aCaps   = &aDriver->ChangeOptions();
5519   }
5520
5521   if (theArgNb < 2)
5522   {
5523     theDI << "VBO:     " << (aCaps->vboDisable        ? "0" : "1") << "\n";
5524     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
5525     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
5526     theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
5527     theDI << "VSync:   " <<  aCaps->swapInterval                   << "\n";
5528     theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
5529     theDI << "Stereo:  " << (aCaps->contextStereo ? "1" : "0") << "\n";
5530     return 0;
5531   }
5532
5533   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
5534   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5535   {
5536     Standard_CString        anArg     = theArgVec[anArgIter];
5537     TCollection_AsciiString anArgCase (anArg);
5538     anArgCase.LowerCase();
5539     if (anUpdateTool.parseRedrawMode (anArg))
5540     {
5541       continue;
5542     }
5543     else if (anArgCase == "-vsync"
5544           || anArgCase == "-swapinterval")
5545     {
5546       Standard_Boolean toEnable = Standard_True;
5547       if (++anArgIter < theArgNb
5548       && !parseOnOff (theArgVec[anArgIter], toEnable))
5549       {
5550         --anArgIter;
5551       }
5552       aCaps->swapInterval = toEnable;
5553     }
5554     else if (anArgCase == "-ffp")
5555     {
5556       Standard_Boolean toEnable = Standard_True;
5557       if (++anArgIter < theArgNb
5558       && !parseOnOff (theArgVec[anArgIter], toEnable))
5559       {
5560         --anArgIter;
5561       }
5562       aCaps->ffpEnable = toEnable;
5563     }
5564     else if (anArgCase == "-vbo")
5565     {
5566       Standard_Boolean toEnable = Standard_True;
5567       if (++anArgIter < theArgNb
5568       && !parseOnOff (theArgVec[anArgIter], toEnable))
5569       {
5570         --anArgIter;
5571       }
5572       aCaps->vboDisable = !toEnable;
5573     }
5574     else if (anArgCase == "-sprite"
5575           || anArgCase == "-sprites")
5576     {
5577       Standard_Boolean toEnable = Standard_True;
5578       if (++anArgIter < theArgNb
5579       && !parseOnOff (theArgVec[anArgIter], toEnable))
5580       {
5581         --anArgIter;
5582       }
5583       aCaps->pntSpritesDisable = !toEnable;
5584     }
5585     else if (anArgCase == "-softmode")
5586     {
5587       Standard_Boolean toEnable = Standard_True;
5588       if (++anArgIter < theArgNb
5589       && !parseOnOff (theArgVec[anArgIter], toEnable))
5590       {
5591         --anArgIter;
5592       }
5593       aCaps->contextNoAccel = toEnable;
5594     }
5595     else if (anArgCase == "-accel"
5596           || anArgCase == "-acceleration")
5597     {
5598       Standard_Boolean toEnable = Standard_True;
5599       if (++anArgIter < theArgNb
5600       && !parseOnOff (theArgVec[anArgIter], toEnable))
5601       {
5602         --anArgIter;
5603       }
5604       aCaps->contextNoAccel = !toEnable;
5605     }
5606     else if (anArgCase == "-compat"
5607           || anArgCase == "-compatprofile"
5608           || anArgCase == "-compatible"
5609           || anArgCase == "-compatibleprofile")
5610     {
5611       Standard_Boolean toEnable = Standard_True;
5612       if (++anArgIter < theArgNb
5613       && !parseOnOff (theArgVec[anArgIter], toEnable))
5614       {
5615         --anArgIter;
5616       }
5617       aCaps->contextCompatible = toEnable;
5618       if (!aCaps->contextCompatible)
5619       {
5620         aCaps->ffpEnable = Standard_False;
5621       }
5622     }
5623     else if (anArgCase == "-core"
5624           || anArgCase == "-coreprofile")
5625     {
5626       Standard_Boolean toEnable = Standard_True;
5627       if (++anArgIter < theArgNb
5628       && !parseOnOff (theArgVec[anArgIter], toEnable))
5629       {
5630         --anArgIter;
5631       }
5632       aCaps->contextCompatible = !toEnable;
5633       if (!aCaps->contextCompatible)
5634       {
5635         aCaps->ffpEnable = Standard_False;
5636       }
5637     }
5638     else if (anArgCase == "-stereo"
5639           || anArgCase == "-quadbuffer")
5640     {
5641       Standard_Boolean toEnable = Standard_True;
5642       if (++anArgIter < theArgNb
5643       && !parseOnOff (theArgVec[anArgIter], toEnable))
5644       {
5645         --anArgIter;
5646       }
5647       aCaps->contextStereo = toEnable;
5648     }
5649     else
5650     {
5651       std::cout << "Error: unknown argument '" << anArg << "'\n";
5652       return 1;
5653     }
5654   }
5655   if (aCaps != &ViewerTest_myDefaultCaps)
5656   {
5657     ViewerTest_myDefaultCaps = *aCaps;
5658   }
5659   return 0;
5660 }
5661
5662 //==============================================================================
5663 //function : VMemGpu
5664 //purpose  :
5665 //==============================================================================
5666
5667 static int VMemGpu (Draw_Interpretor& theDI,
5668                     Standard_Integer  theArgNb,
5669                     const char**      theArgVec)
5670 {
5671   // get the context
5672   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5673   if (aContextAIS.IsNull())
5674   {
5675     std::cerr << "No active view. Please call vinit.\n";
5676     return 1;
5677   }
5678
5679   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
5680   if (aDriver.IsNull())
5681   {
5682     std::cerr << "Graphic driver not available.\n";
5683     return 1;
5684   }
5685
5686   Standard_Size aFreeBytes = 0;
5687   TCollection_AsciiString anInfo;
5688   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
5689   {
5690     std::cerr << "Information not available.\n";
5691     return 1;
5692   }
5693
5694   if (theArgNb > 1 && *theArgVec[1] == 'f')
5695   {
5696     theDI << Standard_Real (aFreeBytes);
5697   }
5698   else
5699   {
5700     theDI << anInfo;
5701   }
5702
5703   return 0;
5704 }
5705
5706 // ==============================================================================
5707 // function : VReadPixel
5708 // purpose  :
5709 // ==============================================================================
5710 static int VReadPixel (Draw_Interpretor& theDI,
5711                        Standard_Integer  theArgNb,
5712                        const char**      theArgVec)
5713 {
5714   // get the active view
5715   Handle(V3d_View) aView = ViewerTest::CurrentView();
5716   if (aView.IsNull())
5717   {
5718     std::cerr << "No active view. Please call vinit.\n";
5719     return 1;
5720   }
5721   else if (theArgNb < 3)
5722   {
5723     std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
5724     return 1;
5725   }
5726
5727   Image_PixMap::ImgFormat aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
5728   Graphic3d_BufferType    aBufferType = Graphic3d_BT_RGBA;
5729
5730   Standard_Integer aWidth, aHeight;
5731   aView->Window()->Size (aWidth, aHeight);
5732   const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
5733   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
5734   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
5735   {
5736     std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
5737     return 1;
5738   }
5739
5740   Standard_Boolean toShowName = Standard_False;
5741   Standard_Boolean toShowHls  = Standard_False;
5742   for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
5743   {
5744     const char* aParam = theArgVec[anIter];
5745     if ( strcasecmp( aParam, "rgb" ) == 0 )
5746     {
5747       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
5748       aBufferType = Graphic3d_BT_RGB;
5749     }
5750     else if ( strcasecmp( aParam, "hls" ) == 0 )
5751     {
5752       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
5753       aBufferType = Graphic3d_BT_RGB;
5754       toShowHls   = Standard_True;
5755     }
5756     else if ( strcasecmp( aParam, "rgbf" ) == 0 )
5757     {
5758       aFormat     = Image_PixMap::ImgRGBF;
5759       aBufferType = Graphic3d_BT_RGB;
5760     }
5761     else if ( strcasecmp( aParam, "rgba" ) == 0 )
5762     {
5763       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
5764       aBufferType = Graphic3d_BT_RGBA;
5765     }
5766     else if ( strcasecmp( aParam, "rgbaf" ) == 0 )
5767     {
5768       aFormat     = Image_PixMap::ImgRGBAF;
5769       aBufferType = Graphic3d_BT_RGBA;
5770     }
5771     else if ( strcasecmp( aParam, "depth" ) == 0 )
5772     {
5773       aFormat     = Image_PixMap::ImgGrayF;
5774       aBufferType = Graphic3d_BT_Depth;
5775     }
5776     else if ( strcasecmp( aParam, "name" ) == 0 )
5777     {
5778       toShowName = Standard_True;
5779     }
5780   }
5781
5782   Image_PixMap anImage;
5783   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
5784   {
5785     std::cerr << "Image allocation failed\n";
5786     return 1;
5787   }
5788   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
5789   {
5790     std::cerr << "Image dump failed\n";
5791     return 1;
5792   }
5793
5794   Quantity_Parameter anAlpha;
5795   Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
5796   if (toShowName)
5797   {
5798     if (aBufferType == Graphic3d_BT_RGBA)
5799     {
5800       theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha;
5801     }
5802     else
5803     {
5804       theDI << Quantity_Color::StringName (aColor.Name());
5805     }
5806   }
5807   else
5808   {
5809     switch (aBufferType)
5810     {
5811       default:
5812       case Graphic3d_BT_RGB:
5813       {
5814         if (toShowHls)
5815         {
5816           theDI << aColor.Hue() << " " << aColor.Light() << " " << aColor.Saturation();
5817         }
5818         else
5819         {
5820           theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue();
5821         }
5822         break;
5823       }
5824       case Graphic3d_BT_RGBA:
5825       {
5826         theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha;
5827         break;
5828       }
5829       case Graphic3d_BT_Depth:
5830       {
5831         theDI << aColor.Red();
5832         break;
5833       }
5834     }
5835   }
5836
5837   return 0;
5838 }
5839
5840 //==============================================================================
5841 //function : VDiffImage
5842 //purpose  : The draw-command compares two images.
5843 //==============================================================================
5844
5845 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
5846 {
5847   if (theArgNb < 6)
5848   {
5849     theDI << "Not enough arguments.\n";
5850     return 1;
5851   }
5852
5853   // image file names
5854   const char* anImgPathRef = theArgVec[1];
5855   const char* anImgPathNew = theArgVec[2];
5856
5857   // get string tolerance and check its validity
5858   Standard_Real aTolColor = Draw::Atof (theArgVec[3]);
5859   if (aTolColor < 0.0)
5860     aTolColor = 0.0;
5861   if (aTolColor > 1.0)
5862     aTolColor = 1.0;
5863
5864   Standard_Boolean toBlackWhite     = (Draw::Atoi (theArgVec[4]) == 1);
5865   Standard_Boolean isBorderFilterOn = (Draw::Atoi (theArgVec[5]) == 1);
5866
5867   // image file of difference
5868   const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
5869
5870   // compare the images
5871   Image_Diff aComparer;
5872   if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
5873   {
5874     return 1;
5875   }
5876
5877   aComparer.SetColorTolerance (aTolColor);
5878   aComparer.SetBorderFilterOn (isBorderFilterOn);
5879   Standard_Integer aDiffColorsNb = aComparer.Compare();
5880   theDI << aDiffColorsNb << "\n";
5881
5882   // save image of difference
5883   if (aDiffColorsNb >0 && aDiffImagePath != NULL)
5884   {
5885     aComparer.SaveDiffImage (aDiffImagePath);
5886   }
5887
5888   return 0;
5889 }
5890
5891 //=======================================================================
5892 //function : VSelect
5893 //purpose  : Emulates different types of selection by mouse:
5894 //           1) single click selection
5895 //           2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
5896 //           3) selection with polygon having corners at
5897 //           pixel positions (x1,y1),...,(xn,yn)
5898 //           4) any of these selections with shift button pressed
5899 //=======================================================================
5900 static Standard_Integer VSelect (Draw_Interpretor& di,
5901                                  Standard_Integer argc,
5902                                  const char ** argv)
5903 {
5904   if(argc < 3)
5905   {
5906     di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]" << "\n";
5907     return 1;
5908   }
5909
5910   Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
5911   if(myAIScontext.IsNull())
5912   {
5913     di << "use 'vinit' command before " << argv[0] << "\n";
5914     return 1;
5915   }
5916
5917   const Standard_Boolean isShiftSelection = (argc > 3 && !(argc % 2) && (atoi (argv[argc - 1]) == 1));
5918   Standard_Integer aCoordsNb = isShiftSelection ? argc - 2 : argc - 1;
5919   TCollection_AsciiString anArg;
5920   anArg = isShiftSelection ? argv[argc - 3] : argv[argc - 2];
5921   anArg.LowerCase();
5922   if (anArg == "-allowoverlap")
5923   {
5924     Standard_Boolean isValidated = isShiftSelection ? argc == 8
5925       : argc == 7;
5926     if (!isValidated)
5927     {
5928       di << "Wrong number of arguments! -allowoverlap key is applied only for rectangle selection";
5929       return 1;
5930     }
5931
5932     Standard_Integer isToAllow = isShiftSelection ? Draw::Atoi(argv[argc - 2]) : Draw::Atoi(argv[argc - 1]);
5933     myAIScontext->MainSelector()->AllowOverlapDetection((Standard_Boolean)isToAllow);
5934     aCoordsNb -= 2;
5935   }
5936
5937   Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
5938   aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
5939   if(aCoordsNb == 2)
5940   {
5941     if(isShiftSelection)
5942       aCurrentEventManager->ShiftSelect();
5943     else
5944       aCurrentEventManager->Select();
5945   }
5946   else if(aCoordsNb == 4)
5947   {
5948     if(isShiftSelection)
5949       aCurrentEventManager->ShiftSelect (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
5950     else
5951       aCurrentEventManager->Select (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
5952   }
5953   else
5954   {
5955     TColgp_Array1OfPnt2d aPolyline (1,aCoordsNb / 2);
5956
5957     for(Standard_Integer i=1;i<=aCoordsNb / 2;++i)
5958       aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
5959
5960     if(isShiftSelection)
5961       aCurrentEventManager->ShiftSelect(aPolyline);
5962     else
5963       aCurrentEventManager->Select(aPolyline);
5964   }
5965   return 0;
5966 }
5967
5968 //=======================================================================
5969 //function : VMoveTo
5970 //purpose  : Emulates cursor movement to defined pixel position
5971 //=======================================================================
5972 static Standard_Integer VMoveTo (Draw_Interpretor& di,
5973                                 Standard_Integer argc,
5974                                 const char ** argv)
5975 {
5976   if(argc != 3)
5977   {
5978     di << "Usage : " << argv[0] << " x y" << "\n";
5979     return 1;
5980   }
5981
5982   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5983   if(aContext.IsNull())
5984   {
5985     di << "use 'vinit' command before " << argv[0] << "\n";
5986     return 1;
5987   }
5988   ViewerTest::CurrentEventManager()->MoveTo(atoi(argv[1]),atoi(argv[2]));
5989   return 0;
5990 }
5991
5992 //=================================================================================================
5993 //function : VViewParams
5994 //purpose  : Gets or sets AIS View characteristics
5995 //=================================================================================================
5996 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5997 {
5998   Handle(V3d_View) anAISView = ViewerTest::CurrentView();
5999   if (anAISView.IsNull())
6000   {
6001     std::cout << theArgVec[0] << ": please initialize or activate view.\n";
6002     return 1;
6003   }
6004
6005   if (theArgsNb == 1)
6006   {
6007     // print all of the available view parameters
6008     Quantity_Factor anAISViewScale = anAISView->Scale();
6009
6010     Standard_Real anAISViewProjX = 0.0;
6011     Standard_Real anAISViewProjY = 0.0;
6012     Standard_Real anAISViewProjZ = 0.0;
6013     anAISView->Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
6014
6015     Standard_Real anAISViewUpX = 0.0;
6016     Standard_Real anAISViewUpY = 0.0;
6017     Standard_Real anAISViewUpZ = 0.0;
6018     anAISView->Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
6019
6020     Standard_Real anAISViewAtX = 0.0;
6021     Standard_Real anAISViewAtY = 0.0;
6022     Standard_Real anAISViewAtZ = 0.0;
6023     anAISView->At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
6024
6025     Standard_Real anAISViewEyeX = 0.0;
6026     Standard_Real anAISViewEyeY = 0.0;
6027     Standard_Real anAISViewEyeZ = 0.0;
6028     anAISView->Eye (anAISViewEyeX, anAISViewEyeY, anAISViewEyeZ);
6029
6030     theDi << "Scale of current view: " << anAISViewScale << "\n";
6031     theDi << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
6032     theDi << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
6033     theDi << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
6034     theDi << "Eye on X : " << anAISViewEyeX << "; on Y: " << anAISViewEyeY << "; on Z: " << anAISViewEyeZ << "\n";
6035     return 0;
6036   }
6037
6038   // -------------------------
6039   //  Parse options and values
6040   // -------------------------
6041
6042   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfKeysByValues;
6043   TCollection_AsciiString aParseKey;
6044   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
6045   {
6046     TCollection_AsciiString anArg (theArgVec [anArgIt]);
6047
6048     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
6049     {
6050       aParseKey = anArg;
6051       aParseKey.Remove (1);
6052       aParseKey.UpperCase();
6053       aMapOfKeysByValues.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
6054       continue;
6055     }
6056
6057     if (aParseKey.IsEmpty())
6058     {
6059       std::cout << theArgVec[0] << ": values should be passed with key.\n";
6060       std::cout << "Type help for more information.\n";
6061       return 1;
6062     }
6063
6064     aMapOfKeysByValues(aParseKey)->Append (anArg);
6065   }
6066
6067   // ---------------------------------------------
6068   //  Change or print parameters, order plays role
6069   // ---------------------------------------------
6070
6071   // Check arguments for validity
6072   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfKeysByValues);
6073   for (; aMapIt.More(); aMapIt.Next())
6074   {
6075     const TCollection_AsciiString& aKey = aMapIt.Key();
6076     const Handle(TColStd_HSequenceOfAsciiString)& aValues = aMapIt.Value();
6077
6078     if (!(aKey.IsEqual ("SCALE")  && (aValues->Length() == 1 || aValues->IsEmpty()))
6079      && !(aKey.IsEqual ("SIZE")   && (aValues->Length() == 1 || aValues->IsEmpty()))
6080      && !(aKey.IsEqual ("EYE")    && (aValues->Length() == 3 || aValues->IsEmpty()))
6081      && !(aKey.IsEqual ("AT")     && (aValues->Length() == 3 || aValues->IsEmpty()))
6082      && !(aKey.IsEqual ("UP")     && (aValues->Length() == 3 || aValues->IsEmpty()))
6083      && !(aKey.IsEqual ("PROJ")   && (aValues->Length() == 3 || aValues->IsEmpty()))
6084      && !(aKey.IsEqual ("CENTER") &&  aValues->Length() == 2))
6085     {
6086       TCollection_AsciiString aLowerKey;
6087       aLowerKey  = "-";
6088       aLowerKey += aKey;
6089       aLowerKey.LowerCase();
6090       std::cout << theArgVec[0] << ": " << aLowerKey << " is unknown option, or number of arguments is invalid.\n";
6091       std::cout << "Type help for more information.\n";
6092       return 1;
6093     }
6094   }
6095
6096   Handle(TColStd_HSequenceOfAsciiString) aValues;
6097
6098   // Change view parameters in proper order
6099   if (aMapOfKeysByValues.Find ("SCALE", aValues))
6100   {
6101     if (aValues->IsEmpty())
6102     {
6103       theDi << "Scale: " << anAISView->Scale() << "\n";
6104     }
6105     else
6106     {
6107       anAISView->SetScale (aValues->Value(1).RealValue());
6108     }
6109   }
6110   if (aMapOfKeysByValues.Find ("SIZE", aValues))
6111   {
6112     if (aValues->IsEmpty())
6113     {
6114       Standard_Real aSizeX = 0.0;
6115       Standard_Real aSizeY = 0.0;
6116       anAISView->Size (aSizeX, aSizeY);
6117       theDi << "Size X: " << aSizeX << " Y: " << aSizeY << "\n";
6118     }
6119     else
6120     {
6121       anAISView->SetSize (aValues->Value(1).RealValue());
6122     }
6123   }
6124   if (aMapOfKeysByValues.Find ("EYE", aValues))
6125   {
6126     if (aValues->IsEmpty())
6127     {
6128       Standard_Real anEyeX = 0.0;
6129       Standard_Real anEyeY = 0.0;
6130       Standard_Real anEyeZ = 0.0;
6131       anAISView->Eye (anEyeX, anEyeY, anEyeZ);
6132       theDi << "Eye X: " << anEyeX << " Y: " << anEyeY << " Z: " << anEyeZ << "\n";
6133     }
6134     else
6135     {
6136       anAISView->SetEye (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
6137     }
6138   }
6139   if (aMapOfKeysByValues.Find ("AT", aValues))
6140   {
6141     if (aValues->IsEmpty())
6142     {
6143       Standard_Real anAtX = 0.0;
6144       Standard_Real anAtY = 0.0;
6145       Standard_Real anAtZ = 0.0;
6146       anAISView->At (anAtX, anAtY, anAtZ);
6147       theDi << "At X: " << anAtX << " Y: " << anAtY << " Z: " << anAtZ << "\n";
6148     }
6149     else
6150     {
6151       anAISView->SetAt (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
6152     }
6153   }
6154   if (aMapOfKeysByValues.Find ("PROJ", aValues))
6155   {
6156     if (aValues->IsEmpty())
6157     {
6158       Standard_Real aProjX = 0.0;
6159       Standard_Real aProjY = 0.0;
6160       Standard_Real aProjZ = 0.0;
6161       anAISView->Proj (aProjX, aProjY, aProjZ);
6162       theDi << "Proj X: " << aProjX << " Y: " << aProjY << " Z: " << aProjZ << "\n";
6163     }
6164     else
6165     {
6166       anAISView->SetProj (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
6167     }
6168   }
6169   if (aMapOfKeysByValues.Find ("UP", aValues))
6170   {
6171     if (aValues->IsEmpty())
6172     {
6173       Standard_Real anUpX = 0.0;
6174       Standard_Real anUpY = 0.0;
6175       Standard_Real anUpZ = 0.0;
6176       anAISView->Up (anUpX, anUpY, anUpZ);
6177       theDi << "Up X: " << anUpX << " Y: " << anUpY << " Z: " << anUpZ << "\n";
6178     }
6179     else
6180     {
6181       anAISView->SetUp (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
6182     }
6183   }
6184   if (aMapOfKeysByValues.Find ("CENTER", aValues))
6185   {
6186     anAISView->SetCenter (aValues->Value(1).IntegerValue(), aValues->Value(2).IntegerValue());
6187   }
6188
6189   return 0;
6190 }
6191
6192 //=======================================================================
6193 //function : VChangeSelected
6194 //purpose  : Adds the shape to selection or remove one from it
6195 //=======================================================================
6196 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
6197                                 Standard_Integer argc,
6198                                 const char ** argv)
6199 {
6200   if(argc != 2)
6201   {
6202     di<<"Usage : " << argv[0] << " shape \n";
6203     return 1;
6204   }
6205   //get AIS_Shape:
6206   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6207   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
6208   TCollection_AsciiString aName(argv[1]);
6209   Handle(AIS_InteractiveObject) anAISObject;
6210
6211   if(!aMap.IsBound2(aName))
6212   {
6213     di<<"Use 'vdisplay' before";
6214     return 1;
6215   }
6216   else
6217   {
6218     anAISObject = Handle(AIS_InteractiveObject)::DownCast(aMap.Find2(aName));
6219     if(anAISObject.IsNull()){
6220       di<<"No interactive object \n";
6221       return 1;
6222     }
6223
6224     aContext->AddOrRemoveSelected(anAISObject);
6225   }
6226   return 0;
6227 }
6228
6229 //=======================================================================
6230 //function : VZClipping
6231 //purpose  : Gets or sets ZClipping mode, width and depth
6232 //=======================================================================
6233 static Standard_Integer VZClipping (Draw_Interpretor& di,
6234                                 Standard_Integer argc,
6235                                 const char ** argv)
6236 {
6237   if(argc>4)
6238   {
6239     di << "Usage : " << argv[0] << " [mode] [depth  width]" << "\n"
6240       <<"mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
6241     return -1;
6242   }
6243   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6244   if(aContext.IsNull())
6245   {
6246     di << "use 'vinit' command before " << argv[0] << "\n";
6247     return 1;
6248   }
6249   Handle(V3d_View) aView = ViewerTest::CurrentView();
6250   V3d_TypeOfZclipping aZClippingMode = V3d_OFF;
6251   if(argc==1)
6252   {
6253     TCollection_AsciiString aZClippingModeString;
6254     Quantity_Length aDepth, aWidth;
6255     aZClippingMode = aView->ZClipping(aDepth, aWidth);
6256     switch (aZClippingMode)
6257     {
6258     case V3d_OFF:
6259       aZClippingModeString.Copy("OFF");
6260       break;
6261     case V3d_BACK:
6262       aZClippingModeString.Copy("BACK");
6263       break;
6264     case V3d_FRONT:
6265       aZClippingModeString.Copy("FRONT");
6266       break;
6267     case V3d_SLICE:
6268       aZClippingModeString.Copy("SLICE");
6269       break;
6270     default:
6271       aZClippingModeString.Copy(TCollection_AsciiString(aZClippingMode));
6272       break;
6273     }
6274     di << "ZClippingMode = " << aZClippingModeString.ToCString() << "\n"
6275       << "ZClipping depth = " << aDepth << "\n"
6276       << "ZClipping width = " << aWidth << "\n";
6277   }
6278   else
6279   {
6280     if(argc !=3)
6281     {
6282       Standard_Integer aStatus = 0;
6283       if ( strcmp (argv [1], "OFF") == 0 ) {
6284         aStatus = 1;
6285         aZClippingMode = V3d_OFF;
6286       }
6287       if ( strcmp (argv [1], "BACK") == 0 ) {
6288         aStatus = 1;
6289         aZClippingMode = V3d_BACK;
6290       }
6291       if ( strcmp (argv [1], "FRONT") == 0 ) {
6292         aStatus = 1;
6293         aZClippingMode = V3d_FRONT;
6294       }
6295       if ( strcmp (argv [1], "SLICE") == 0 ) {
6296         aStatus = 1;
6297         aZClippingMode = V3d_SLICE;
6298       }
6299       if (aStatus != 1)
6300       {
6301         di << "Bad mode; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
6302           << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
6303         return 1;
6304       }
6305       aView->SetZClippingType(aZClippingMode);
6306     }
6307     if(argc >2)
6308     {
6309       Quantity_Length aDepth = 0., aWidth = 1.;
6310       if(argc == 3)
6311       {
6312         aDepth = Draw::Atof (argv[1]);
6313         aWidth = Draw::Atof (argv[2]);
6314       }
6315       else if(argc == 4)
6316       {
6317         aDepth = Draw::Atof (argv[2]);
6318         aWidth = Draw::Atof (argv[3]);
6319       }
6320
6321       if(aDepth<0. || aDepth>1.)
6322       {
6323         di << "Bad depth; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
6324         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
6325         return 1;
6326       }
6327       if(aWidth<0. || aWidth>1.)
6328       {
6329         di << "Bad width; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
6330         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
6331         return 1;
6332       }
6333
6334       aView->SetZClippingDepth(aDepth);
6335       aView->SetZClippingWidth(aWidth);
6336     }
6337     aView->Redraw();
6338   }
6339   return 0;
6340 }
6341
6342 //=======================================================================
6343 //function : VNbSelected
6344 //purpose  : Returns number of selected objects
6345 //=======================================================================
6346 static Standard_Integer VNbSelected (Draw_Interpretor& di,
6347                                 Standard_Integer argc,
6348                                 const char ** argv)
6349 {
6350   if(argc != 1)
6351   {
6352     di << "Usage : " << argv[0] << "\n";
6353     return 1;
6354   }
6355   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6356   if(aContext.IsNull())
6357   {
6358     di << "use 'vinit' command before " << argv[0] << "\n";
6359     return 1;
6360   }
6361   di << aContext->NbSelected() << "\n";
6362   return 0;
6363 }
6364
6365 //=======================================================================
6366 //function : VAntialiasing
6367 //purpose  : Switches altialiasing on or off
6368 //=======================================================================
6369 static Standard_Integer VAntialiasing (Draw_Interpretor& di,
6370                                 Standard_Integer argc,
6371                                 const char ** argv)
6372 {
6373   if(argc > 2)
6374   {
6375     di << "Usage : " << argv[0] << " [1|0]" << "\n";
6376     return 1;
6377   }
6378
6379   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6380   if(aContext.IsNull())
6381   {
6382     di << "use 'vinit' command before " << argv[0] << "\n";
6383     return 1;
6384   }
6385
6386   Handle(V3d_View) aView = ViewerTest::CurrentView();
6387
6388   if((argc == 2) && (atof(argv[1]) == 0))
6389     aView->SetAntialiasingOff();
6390   else
6391     aView->SetAntialiasingOn();
6392   aView->Update();
6393   return 0;
6394 }
6395
6396 //=======================================================================
6397 //function : VPurgeDisplay
6398 //purpose  : Switches altialiasing on or off
6399 //=======================================================================
6400 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
6401                                 Standard_Integer argc,
6402                                 const char ** argv)
6403 {
6404   if (argc > 1)
6405   {
6406     di << "Usage : " << argv[0] << "\n";
6407     return 1;
6408   }
6409   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6410   if (aContext.IsNull())
6411   {
6412     di << "use 'vinit' command before " << argv[0] << "\n";
6413     return 1;
6414   }
6415   aContext->CloseAllContexts(Standard_False);
6416   di << aContext->PurgeDisplay() << "\n";
6417   return 0;
6418 }
6419
6420 //=======================================================================
6421 //function : VSetViewSize
6422 //purpose  :
6423 //=======================================================================
6424 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
6425                                 Standard_Integer argc,
6426                                 const char ** argv)
6427 {
6428   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6429   if(aContext.IsNull())
6430   {
6431     di << "use 'vinit' command before " << argv[0] << "\n";
6432     return 1;
6433   }
6434   if(argc != 2)
6435   {
6436     di<<"Usage : " << argv[0] << " Size\n";
6437     return 1;
6438   }
6439   Standard_Real aSize = Draw::Atof (argv[1]);
6440   if (aSize <= 0.)
6441   {
6442     di<<"Bad Size value  : " << aSize << "\n";
6443     return 1;
6444   }
6445
6446   Handle(V3d_View) aView = ViewerTest::CurrentView();
6447   aView->SetSize(aSize);
6448   return 0;
6449 }
6450
6451 //=======================================================================
6452 //function : VMoveView
6453 //purpose  :
6454 //=======================================================================
6455 static Standard_Integer VMoveView (Draw_Interpretor& di,
6456                                 Standard_Integer argc,
6457                                 const char ** argv)
6458 {
6459   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6460   if(aContext.IsNull())
6461   {
6462     di << "use 'vinit' command before " << argv[0] << "\n";
6463     return 1;
6464   }
6465   if(argc < 4 || argc > 5)
6466   {
6467     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
6468     return 1;
6469   }
6470   Standard_Real Dx = Draw::Atof (argv[1]);
6471   Standard_Real Dy = Draw::Atof (argv[2]);
6472   Standard_Real Dz = Draw::Atof (argv[3]);
6473   Standard_Boolean aStart = Standard_True;
6474   if (argc == 5)
6475   {
6476       aStart = (Draw::Atoi (argv[4]) > 0);
6477   }
6478
6479   Handle(V3d_View) aView = ViewerTest::CurrentView();
6480   aView->Move(Dx,Dy,Dz,aStart);
6481   return 0;
6482 }
6483
6484 //=======================================================================
6485 //function : VTranslateView
6486 //purpose  :
6487 //=======================================================================
6488 static Standard_Integer VTranslateView (Draw_Interpretor& di,
6489                                 Standard_Integer argc,
6490                                 const char ** argv)
6491 {
6492   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6493   if(aContext.IsNull())
6494   {
6495     di << "use 'vinit' command before " << argv[0] << "\n";
6496     return 1;
6497   }
6498   if(argc < 4 || argc > 5)
6499   {
6500     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
6501     return 1;
6502   }
6503   Standard_Real Dx = Draw::Atof (argv[1]);
6504   Standard_Real Dy = Draw::Atof (argv[2]);
6505   Standard_Real Dz = Draw::Atof (argv[3]);
6506   Standard_Boolean aStart = Standard_True;
6507   if (argc == 5)
6508   {
6509       aStart = (Draw::Atoi (argv[4]) > 0);
6510   }
6511
6512   Handle(V3d_View) aView = ViewerTest::CurrentView();
6513   aView->Translate(Dx,Dy,Dz,aStart);
6514   return 0;
6515 }
6516
6517 //=======================================================================
6518 //function : VTurnView
6519 //purpose  :
6520 //=======================================================================
6521 static Standard_Integer VTurnView (Draw_Interpretor& di,
6522                                 Standard_Integer argc,
6523                                 const char ** argv)
6524 {
6525   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6526   if(aContext.IsNull()) {
6527     di << "use 'vinit' command before " << argv[0] << "\n";
6528     return 1;
6529   }
6530   if(argc < 4 || argc > 5){
6531     di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
6532     return 1;
6533   }
6534   Standard_Real Ax = Draw::Atof (argv[1]);
6535   Standard_Real Ay = Draw::Atof (argv[2]);
6536   Standard_Real Az = Draw::Atof (argv[3]);
6537   Standard_Boolean aStart = Standard_True;
6538   if (argc == 5)
6539   {
6540       aStart = (Draw::Atoi (argv[4]) > 0);
6541   }
6542
6543   Handle(V3d_View) aView = ViewerTest::CurrentView();
6544   aView->Turn(Ax,Ay,Az,aStart);
6545   return 0;
6546 }
6547
6548 //==============================================================================
6549 //function : VTextureEnv
6550 //purpose  : ENables or disables environment mapping
6551 //==============================================================================
6552 class OCC_TextureEnv : public Graphic3d_TextureEnv
6553 {
6554 public:
6555   OCC_TextureEnv(const Standard_CString FileName);
6556   OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
6557   void SetTextureParameters(const Standard_Boolean theRepeatFlag,
6558                             const Standard_Boolean theModulateFlag,
6559                             const Graphic3d_TypeOfTextureFilter theFilter,
6560                             const Standard_ShortReal theXScale,
6561                             const Standard_ShortReal theYScale,
6562                             const Standard_ShortReal theXShift,
6563                             const Standard_ShortReal theYShift,
6564                             const Standard_ShortReal theAngle);
6565   DEFINE_STANDARD_RTTI(OCC_TextureEnv, Graphic3d_TextureEnv);
6566 };
6567 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
6568
6569
6570
6571
6572 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
6573   : Graphic3d_TextureEnv(theFileName)
6574 {
6575 }
6576
6577 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
6578   : Graphic3d_TextureEnv(theTexId)
6579 {
6580 }
6581
6582 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
6583                                           const Standard_Boolean theModulateFlag,
6584                                           const Graphic3d_TypeOfTextureFilter theFilter,
6585                                           const Standard_ShortReal theXScale,
6586                                           const Standard_ShortReal theYScale,
6587                                           const Standard_ShortReal theXShift,
6588                                           const Standard_ShortReal theYShift,
6589                                           const Standard_ShortReal theAngle)
6590 {
6591   myParams->SetRepeat     (theRepeatFlag);
6592   myParams->SetModulate   (theModulateFlag);
6593   myParams->SetFilter     (theFilter);
6594   myParams->SetScale      (Graphic3d_Vec2(theXScale, theYScale));
6595   myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
6596   myParams->SetRotation   (theAngle);
6597 }
6598
6599 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
6600 {
6601   // get the active view
6602   Handle(V3d_View) aView = ViewerTest::CurrentView();
6603   if (aView.IsNull())
6604   {
6605     std::cerr << "No active view. Please call vinit.\n";
6606     return 1;
6607   }
6608
6609   // Checking the input arguments
6610   Standard_Boolean anEnableFlag = Standard_False;
6611   Standard_Boolean isOk         = theArgNb >= 2;
6612   if (isOk)
6613   {
6614     TCollection_AsciiString anEnableOpt(theArgVec[1]);
6615     anEnableFlag = anEnableOpt.IsEqual("on");
6616     isOk         = anEnableFlag || anEnableOpt.IsEqual("off");
6617   }
6618   if (anEnableFlag)
6619   {
6620     isOk = (theArgNb == 3 || theArgNb == 11);
6621     if (isOk)
6622     {
6623       TCollection_AsciiString aTextureOpt(theArgVec[2]);
6624       isOk = (!aTextureOpt.IsIntegerValue() ||
6625              (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
6626
6627       if (isOk && theArgNb == 11)
6628       {
6629         TCollection_AsciiString aRepeatOpt  (theArgVec[3]),
6630                                 aModulateOpt(theArgVec[4]),
6631                                 aFilterOpt  (theArgVec[5]),
6632                                 aSScaleOpt  (theArgVec[6]),
6633                                 aTScaleOpt  (theArgVec[7]),
6634                                 aSTransOpt  (theArgVec[8]),
6635                                 aTTransOpt  (theArgVec[9]),
6636                                 anAngleOpt  (theArgVec[10]);
6637         isOk = ((aRepeatOpt.  IsEqual("repeat")   || aRepeatOpt.  IsEqual("clamp")) &&
6638                 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
6639                 (aFilterOpt.  IsEqual("nearest")  || aFilterOpt.  IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
6640                 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
6641                 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
6642                 anAngleOpt.IsRealValue());
6643       }
6644     }
6645   }
6646
6647   if (!isOk)
6648   {
6649     std::cerr << "Usage :" << std::endl;
6650     std::cerr << theArgVec[0] << " off" << std::endl;
6651     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;
6652     return 1;
6653   }
6654
6655   if (anEnableFlag)
6656   {
6657     TCollection_AsciiString aTextureOpt(theArgVec[2]);
6658     Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
6659                                      new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
6660                                      new OCC_TextureEnv(theArgVec[2]);
6661
6662     if (theArgNb == 11)
6663     {
6664       TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
6665       aTexEnv->SetTextureParameters(
6666         aRepeatOpt.  IsEqual("repeat"),
6667         aModulateOpt.IsEqual("modulate"),
6668         aFilterOpt.  IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
6669                                           aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
6670                                                                            Graphic3d_TOTF_TRILINEAR,
6671         (Standard_ShortReal)Draw::Atof(theArgVec[6]),
6672         (Standard_ShortReal)Draw::Atof(theArgVec[7]),
6673         (Standard_ShortReal)Draw::Atof(theArgVec[8]),
6674         (Standard_ShortReal)Draw::Atof(theArgVec[9]),
6675         (Standard_ShortReal)Draw::Atof(theArgVec[10])
6676         );
6677     }
6678     aView->SetTextureEnv(aTexEnv);
6679     aView->SetSurfaceDetail(V3d_TEX_ENVIRONMENT);
6680   }
6681   else // Disabling environment mapping
6682   {
6683     aView->SetSurfaceDetail(V3d_TEX_NONE);
6684     Handle(Graphic3d_TextureEnv) aTexture;
6685     aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
6686   }
6687
6688   aView->Redraw();
6689   return 0;
6690 }
6691
6692 //===============================================================================================
6693 //function : VClipPlane
6694 //purpose  :
6695 //===============================================================================================
6696 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6697 {
6698   // use short-cut for created clip planes map of created (or "registered by name") clip planes
6699   typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
6700   static MapOfPlanes aRegPlanes;
6701
6702   if (theArgsNb < 2)
6703   {
6704     theDi << theArgVec[0] << ": command argument is required. Type help for more information.\n";
6705     return 1;
6706   }
6707
6708   TCollection_AsciiString aCommand (theArgVec[1]);
6709
6710   // print maximum number of planes for current viewer
6711   if (aCommand == "maxplanes")
6712   {
6713     if (theArgsNb < 3)
6714     {
6715       theDi << theArgVec[0] << ": view name is required. Type help for more information.\n";
6716       return 1;
6717     }
6718
6719     TCollection_AsciiString aViewName (theArgVec[2]);
6720
6721     if (!ViewerTest_myViews.IsBound1 (aViewName))
6722     {
6723       theDi << theArgVec[0] << ": view is not found.\n";
6724       return 1;
6725     }
6726
6727     const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
6728
6729     theDi << theArgVec[0] << ": "
6730                           << aView->Viewer()->Driver()->InquirePlaneLimit()
6731                           << " plane slots provided by driver."
6732                           << " Note that 2 more planes might be used (reserved for z-clipping).\n";
6733
6734     return 0;
6735   }
6736
6737   // create / delete plane instance
6738   if (aCommand == "create" || aCommand == "delete" || aCommand == "clone")
6739   {
6740     if (theArgsNb < 3)
6741     {
6742       theDi << theArgVec[0] << ": plane name is required. Type help for more information.\n";
6743       return 1;
6744     }
6745
6746     Standard_Boolean toCreate = (aCommand == "create");
6747     Standard_Boolean toClone  = (aCommand == "clone");
6748     TCollection_AsciiString aPlane (theArgVec[2]);
6749
6750     if (toCreate)
6751     {
6752       if (aRegPlanes.IsBound (aPlane))
6753       {
6754         theDi << theArgVec[0] << ": plane name is in use.\n";
6755         return 1;
6756       }
6757
6758       aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
6759     }
6760     else if (toClone) // toClone
6761     {
6762       if (!aRegPlanes.IsBound (aPlane))
6763       {
6764         theDi << theArgVec[0] << ": no such plane.\n";
6765         return 1;
6766       }
6767
6768       if (theArgsNb < 4)
6769       {
6770         theDi << theArgVec[0] << ": enter name for new plane. Type help for more information.\n";
6771         return 1;
6772       }
6773
6774       TCollection_AsciiString aClone (theArgVec[3]);
6775       if (aRegPlanes.IsBound (aClone))
6776       {
6777         theDi << theArgVec[0] << ": plane name is in use.\n";
6778         return 1;
6779       }
6780
6781       const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6782
6783       aRegPlanes.Bind (aClone, aClipPlane->Clone());
6784     }
6785     else// toDelete
6786     {
6787       if (!aRegPlanes.IsBound (aPlane))
6788       {
6789         theDi << theArgVec[0] << ": no such plane.\n";
6790         return 1;
6791       }
6792
6793       Handle(Graphic3d_ClipPlane) aClipPlane = aRegPlanes.Find (aPlane);
6794       aRegPlanes.UnBind (aPlane);
6795
6796       ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
6797       for (; anIObjIt.More(); anIObjIt.Next())
6798       {
6799         Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1());
6800         aPrs->RemoveClipPlane(aClipPlane);
6801       }
6802
6803       NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
6804       for (; aViewIt.More(); aViewIt.Next())
6805       {
6806         const Handle(V3d_View)& aView = aViewIt.Key2();
6807         aView->RemoveClipPlane(aClipPlane);
6808       }
6809
6810       ViewerTest::RedrawAllViews();
6811     }
6812
6813     return 0;
6814   }
6815
6816   // set / unset plane command
6817   if (aCommand == "set" || aCommand == "unset")
6818   {
6819     if (theArgsNb < 4)
6820     {
6821       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6822       return 1;
6823     }
6824
6825     Standard_Boolean toSet = (aCommand == "set");
6826     TCollection_AsciiString aPlane (theArgVec [2]);
6827     if (!aRegPlanes.IsBound (aPlane))
6828     {
6829       theDi << theArgVec[0] << ": no such plane.\n";
6830       return 1;
6831     }
6832
6833     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6834
6835     TCollection_AsciiString aTarget (theArgVec [3]);
6836     if (aTarget != "object" && aTarget != "view")
6837     {
6838       theDi << theArgVec[0] << ": invalid target.\n";
6839       return 1;
6840     }
6841
6842     if (aTarget == "object" || aTarget == "view")
6843     {
6844       if (theArgsNb < 5)
6845       {
6846         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6847         return 1;
6848       }
6849
6850       Standard_Boolean isObject = (aTarget == "object");
6851
6852       for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
6853       {
6854         TCollection_AsciiString anEntityName (theArgVec[anIt]);
6855         if (isObject) // to object
6856         {
6857           if (!GetMapOfAIS().IsBound2 (anEntityName))
6858           {
6859             theDi << theArgVec[0] << ": can not find IO with name " << anEntityName << ".\n";
6860             continue;
6861           }
6862
6863           Handle(AIS_InteractiveObject) aIObj =
6864             Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName));
6865
6866           if (toSet)
6867             aIObj->AddClipPlane (aClipPlane);
6868           else
6869             aIObj->RemoveClipPlane (aClipPlane);
6870         }
6871         else // to view
6872         {
6873           if (!ViewerTest_myViews.IsBound1 (anEntityName))
6874           {
6875             theDi << theArgVec[0] << ": can not find View with name " << anEntityName << ".\n";
6876             continue;
6877           }
6878
6879           Handle(V3d_View) aView = ViewerTest_myViews.Find1(anEntityName);
6880           if (toSet)
6881             aView->AddClipPlane (aClipPlane);
6882           else
6883             aView->RemoveClipPlane (aClipPlane);
6884         }
6885       }
6886
6887       ViewerTest::RedrawAllViews();
6888     }
6889
6890     return 0;
6891   }
6892
6893   // change plane command
6894   if (aCommand == "change")
6895   {
6896     if (theArgsNb < 4)
6897     {
6898       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6899       return 1;
6900     }
6901
6902     TCollection_AsciiString aPlane (theArgVec [2]);
6903     if (!aRegPlanes.IsBound (aPlane))
6904     {
6905       theDi << theArgVec[0] << ": no such plane.\n";
6906       return 1;
6907     }
6908
6909     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6910
6911     TCollection_AsciiString aChangeArg (theArgVec [3]);
6912     if (aChangeArg != "on" && aChangeArg != "off" && aChangeArg != "capping" && aChangeArg != "equation")
6913     {
6914       theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
6915       return 1;
6916     }
6917
6918     if (aChangeArg == "on" || aChangeArg == "off") // on / off
6919     {
6920       aClipPlane->SetOn (aChangeArg == "on");
6921     }
6922     else if (aChangeArg == "equation") // change equation
6923     {
6924       if (theArgsNb < 8)
6925       {
6926         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6927         return 1;
6928       }
6929
6930       Standard_Real aCoeffA = Draw::Atof (theArgVec [4]);
6931       Standard_Real aCoeffB = Draw::Atof (theArgVec [5]);
6932       Standard_Real aCoeffC = Draw::Atof (theArgVec [6]);
6933       Standard_Real aCoeffD = Draw::Atof (theArgVec [7]);
6934       aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
6935     }
6936     else if (aChangeArg == "capping") // change capping aspects
6937     {
6938       if (theArgsNb < 5)
6939       {
6940         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6941         return 1;
6942       }
6943
6944       TCollection_AsciiString aCappingArg (theArgVec [4]);
6945       if (aCappingArg != "on" && aCappingArg != "off" &&
6946           aCappingArg != "color" && aCappingArg != "texname" &&
6947           aCappingArg != "texscale" && aCappingArg != "texorigin" &&
6948           aCappingArg != "texrotate" && aCappingArg != "hatch")
6949       {
6950         theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
6951         return 1;
6952       }
6953
6954       if (aCappingArg == "on" || aCappingArg == "off") // on / off capping
6955       {
6956         aClipPlane->SetCapping (aCappingArg == "on");
6957       }
6958       else if (aCappingArg == "color") // color aspect for capping
6959       {
6960         if (theArgsNb < 8)
6961         {
6962           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6963           return 1;
6964         }
6965
6966         Standard_Real aRed = Draw::Atof (theArgVec [5]);
6967         Standard_Real aGrn = Draw::Atof (theArgVec [6]);
6968         Standard_Real aBlu = Draw::Atof (theArgVec [7]);
6969
6970         Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
6971         Quantity_Color aColor (aRed, aGrn, aBlu, Quantity_TOC_RGB);
6972         aMat.SetAmbientColor (aColor);
6973         aMat.SetDiffuseColor (aColor);
6974         aClipPlane->SetCappingMaterial (aMat);
6975       }
6976       else if (aCappingArg == "texname") // texture name
6977       {
6978         if (theArgsNb < 6)
6979         {
6980           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6981           return 1;
6982         }
6983
6984         TCollection_AsciiString aTextureName (theArgVec [5]);
6985
6986         Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
6987         if (!aTexture->IsDone ())
6988         {
6989           aClipPlane->SetCappingTexture (NULL);
6990         }
6991         else
6992         {
6993           aTexture->EnableModulate();
6994           aTexture->EnableRepeat();
6995           aClipPlane->SetCappingTexture (aTexture);
6996         }
6997       }
6998       else if (aCappingArg == "texscale") // texture scale
6999       {
7000         if (aClipPlane->CappingTexture().IsNull())
7001         {
7002           theDi << theArgVec[0] << ": no texture is set.\n";
7003           return 1;
7004         }
7005
7006         if (theArgsNb < 7)
7007         {
7008           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
7009           return 1;
7010         }
7011
7012         Standard_ShortReal aSx = (Standard_ShortReal)atof (theArgVec [5]);
7013         Standard_ShortReal aSy = (Standard_ShortReal)atof (theArgVec [6]);
7014
7015         aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
7016       }
7017       else if (aCappingArg == "texorigin") // texture origin
7018       {
7019         if (aClipPlane->CappingTexture().IsNull())
7020         {
7021           theDi << theArgVec[0] << ": no texture is set.\n";
7022           return 1;
7023         }
7024
7025         if (theArgsNb < 7)
7026         {
7027           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
7028           return 1;
7029         }
7030
7031         Standard_ShortReal aTx = (Standard_ShortReal)atof (theArgVec [5]);
7032         Standard_ShortReal aTy = (Standard_ShortReal)atof (theArgVec [6]);
7033
7034         aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
7035       }
7036       else if (aCappingArg == "texrotate") // texture rotation
7037       {
7038         if (aClipPlane->CappingTexture().IsNull())
7039         {
7040           theDi << theArgVec[0] << ": no texture is set.\n";
7041           return 1;
7042         }
7043
7044         if (theArgsNb < 6)
7045         {
7046           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
7047           return 1;
7048         }
7049
7050         Standard_ShortReal aRot = (Standard_ShortReal)atof (theArgVec[5]);
7051
7052         aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
7053       }
7054       else if (aCappingArg == "hatch") // hatch style
7055       {
7056         if (theArgsNb < 6)
7057         {
7058           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
7059           return 1;
7060         }
7061
7062         TCollection_AsciiString aHatchStr (theArgVec [5]);
7063         if (aHatchStr == "on")
7064         {
7065           aClipPlane->SetCappingHatchOn();
7066         }
7067         else if (aHatchStr == "off")
7068         {
7069           aClipPlane->SetCappingHatchOff();
7070         }
7071         else
7072         {
7073           aClipPlane->SetCappingHatch ((Aspect_HatchStyle)atoi (theArgVec[5]));
7074         }
7075       }
7076     }
7077
7078     ViewerTest::RedrawAllViews();
7079
7080     return 0;
7081   }
7082
7083   theDi << theArgVec[0] << ": invalid command. Type help for more information.\n";
7084   return 1;
7085 }
7086
7087 //===============================================================================================
7088 //function : VSetTextureMode
7089 //purpose  :
7090 //===============================================================================================
7091 static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7092 {
7093   if (theArgsNb < 3)
7094   {
7095     theDi << theArgVec[0] << ": insufficient command arguments. Type help for more information.\n";
7096     return 1;
7097   }
7098
7099   TCollection_AsciiString aViewName (theArgVec[1]);
7100   if (!ViewerTest_myViews.IsBound1 (aViewName))
7101   {
7102     theDi << theArgVec[0] << ": view is not found.\n";
7103     return 1;
7104   }
7105
7106   const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
7107   switch (atoi (theArgVec[2]))
7108   {
7109     case 0: aView->SetSurfaceDetail (V3d_TEX_NONE); break;
7110     case 1: aView->SetSurfaceDetail (V3d_TEX_ENVIRONMENT); break;
7111     case 2: aView->SetSurfaceDetail (V3d_TEX_ALL); break;
7112     default:
7113       theDi << theArgVec[0] << ": invalid mode.\n";
7114       return 1;
7115   }
7116
7117   aView->Redraw();
7118   return 0;
7119 }
7120
7121 //===============================================================================================
7122 //function : VZRange
7123 //purpose  :
7124 //===============================================================================================
7125 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7126 {
7127   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
7128
7129   if (aCurrentView.IsNull())
7130   {
7131     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
7132     return 1;
7133   }
7134
7135   Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
7136
7137   if (theArgsNb < 2)
7138   {
7139     theDi << "ZNear: " << aCamera->ZNear() << "\n";
7140     theDi << "ZFar: " << aCamera->ZFar() << "\n";
7141     return 0;
7142   }
7143
7144   if (theArgsNb == 3)
7145   {
7146     Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
7147     Standard_Real aNewZFar  = Draw::Atof (theArgVec[2]);
7148
7149     if (aNewZNear >= aNewZFar)
7150     {
7151       std::cout << theArgVec[0] << ": invalid arguments: znear should be less than zfar.\n";
7152       return 1;
7153     }
7154
7155     if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
7156     {
7157       std::cout << theArgVec[0] << ": invalid arguments: ";
7158       std::cout << "znear, zfar should be positive for perspective camera.\n";
7159       return 1;
7160     }
7161
7162     aCamera->SetZRange (aNewZNear, aNewZFar);
7163   }
7164   else
7165   {
7166     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
7167     return 1;
7168   }
7169
7170   aCurrentView->Redraw();
7171
7172   return 0;
7173 }
7174
7175 //===============================================================================================
7176 //function : VAutoZFit
7177 //purpose  :
7178 //===============================================================================================
7179 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7180 {
7181   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
7182
7183   if (aCurrentView.IsNull())
7184   {
7185     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
7186     return 1;
7187   }
7188
7189   Standard_Real aScale = aCurrentView->View()->AutoZFitScaleFactor();
7190
7191   if (theArgsNb > 3)
7192   {
7193     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
7194     return 1;
7195   }
7196
7197   if (theArgsNb < 2)
7198   {
7199     theDi << "Auto z-fit mode: " << "\n"
7200           << "On: " << (aCurrentView->View()->AutoZFitMode() ? "enabled" : "disabled") << "\n"
7201           << "Scale: " << aScale << "\n";
7202     return 0;
7203   }
7204
7205   Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
7206
7207   if (theArgsNb >= 3)
7208   {
7209     aScale = Draw::Atoi (theArgVec[2]);
7210   }
7211
7212   aCurrentView->View()->SetAutoZFitMode (isOn, aScale);
7213   aCurrentView->View()->AutoZFit();
7214   aCurrentView->Redraw();
7215
7216   return 0;
7217 }
7218
7219 //! Auxiliary function to print projection type
7220 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
7221 {
7222   switch (theProjType)
7223   {
7224     case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
7225     case Graphic3d_Camera::Projection_Perspective:  return "perspective";
7226     case Graphic3d_Camera::Projection_Stereo:       return "stereoscopic";
7227     case Graphic3d_Camera::Projection_MonoLeftEye:  return "monoLeftEye";
7228     case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
7229   }
7230   return "UNKNOWN";
7231 }
7232
7233 //===============================================================================================
7234 //function : VCamera
7235 //purpose  :
7236 //===============================================================================================
7237 static int VCamera (Draw_Interpretor& theDI,
7238                     Standard_Integer  theArgsNb,
7239                     const char**      theArgVec)
7240 {
7241   Handle(V3d_View) aView = ViewerTest::CurrentView();
7242   if (aView.IsNull())
7243   {
7244     std::cout << "Error: no active view.\n";
7245     return 1;
7246   }
7247
7248   Handle(Graphic3d_Camera) aCamera = aView->Camera();
7249   if (theArgsNb < 2)
7250   {
7251     theDI << "ProjType:   " << projTypeName (aCamera->ProjectionType()) << "\n";
7252     theDI << "FOVy:       " << aCamera->FOVy() << "\n";
7253     theDI << "Distance:   " << aCamera->Distance() << "\n";
7254     theDI << "IOD:        " << aCamera->IOD() << "\n";
7255     theDI << "IODType:    " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute   ? "absolute" : "relative") << "\n";
7256     theDI << "ZFocus:     " << aCamera->ZFocus() << "\n";
7257     theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
7258     return 0;
7259   }
7260
7261   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
7262   {
7263     Standard_CString        anArg = theArgVec[anArgIter];
7264     TCollection_AsciiString anArgCase (anArg);
7265     anArgCase.LowerCase();
7266     if (anArgCase == "-proj"
7267      || anArgCase == "-projection"
7268      || anArgCase == "-projtype"
7269      || anArgCase == "-projectiontype")
7270     {
7271       theDI << projTypeName (aCamera->ProjectionType()) << " ";
7272     }
7273     else if (anArgCase == "-ortho"
7274           || anArgCase == "-orthographic")
7275     {
7276       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
7277     }
7278     else if (anArgCase == "-persp"
7279           || anArgCase == "-perspective"
7280           || anArgCase == "-perspmono"
7281           || anArgCase == "-perspectivemono"
7282           || anArgCase == "-mono")
7283     {
7284       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
7285     }
7286     else if (anArgCase == "-stereo"
7287           || anArgCase == "-stereoscopic"
7288           || anArgCase == "-perspstereo"
7289           || anArgCase == "-perspectivestereo")
7290     {
7291       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
7292     }
7293     else if (anArgCase == "-left"
7294           || anArgCase == "-lefteye"
7295           || anArgCase == "-monoleft"
7296           || anArgCase == "-monolefteye"
7297           || anArgCase == "-perpsleft"
7298           || anArgCase == "-perpslefteye")
7299     {
7300       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
7301     }
7302     else if (anArgCase == "-right"
7303           || anArgCase == "-righteye"
7304           || anArgCase == "-monoright"
7305           || anArgCase == "-monorighteye"
7306           || anArgCase == "-perpsright")
7307     {
7308       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
7309     }
7310     else if (anArgCase == "-dist"
7311           || anArgCase == "-distance")
7312     {
7313       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
7314       if (anArgValue != NULL
7315       && *anArgValue != '-')
7316       {
7317         ++anArgIter;
7318         aCamera->SetDistance (Draw::Atof (anArgValue));
7319         continue;
7320       }
7321       theDI << aCamera->Distance() << " ";
7322     }
7323     else if (anArgCase == "-iod")
7324     {
7325       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
7326       if (anArgValue != NULL
7327       && *anArgValue != '-')
7328       {
7329         ++anArgIter;
7330         aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
7331         continue;
7332       }
7333       theDI << aCamera->IOD() << " ";
7334     }
7335     else if (anArgCase == "-iodtype")
7336     {
7337       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
7338       TCollection_AsciiString anValueCase (anArgValue);
7339       anValueCase.LowerCase();
7340       if (anValueCase == "abs"
7341        || anValueCase == "absolute")
7342       {
7343         ++anArgIter;
7344         aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
7345         continue;
7346       }
7347       else if (anValueCase == "rel"
7348             || anValueCase == "relative")
7349       {
7350         ++anArgIter;
7351         aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
7352         continue;
7353       }
7354       else if (*anArgValue != '-')
7355       {
7356         std::cout << "Error: unknown IOD type '" << anArgValue << "'\n";
7357         return 1;
7358       }
7359       switch (aCamera->GetIODType())
7360       {
7361         case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
7362         case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
7363       }
7364     }
7365     else if (anArgCase == "-zfocus")
7366     {
7367       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
7368       if (anArgValue != NULL
7369       && *anArgValue != '-')
7370       {
7371         ++anArgIter;
7372         aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
7373         continue;
7374       }
7375       theDI << aCamera->ZFocus() << " ";
7376     }
7377     else if (anArgCase == "-zfocustype")
7378     {
7379       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
7380       TCollection_AsciiString anValueCase (anArgValue);
7381       anValueCase.LowerCase();
7382       if (anValueCase == "abs"
7383        || anValueCase == "absolute")
7384       {
7385         ++anArgIter;
7386         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
7387         continue;
7388       }
7389       else if (anValueCase == "rel"
7390             || anValueCase == "relative")
7391       {
7392         ++anArgIter;
7393         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
7394         continue;
7395       }
7396       else if (*anArgValue != '-')
7397       {
7398         std::cout << "Error: unknown ZFocus type '" << anArgValue << "'\n";
7399         return 1;
7400       }
7401       switch (aCamera->ZFocusType())
7402       {
7403         case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
7404         case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
7405       }
7406     }
7407     else if (anArgCase == "-fov"
7408           || anArgCase == "-fovy")
7409     {
7410       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
7411       if (anArgValue != NULL
7412       && *anArgValue != '-')
7413       {
7414         ++anArgIter;
7415         aCamera->SetFOVy (Draw::Atof (anArgValue));
7416         continue;
7417       }
7418       theDI << aCamera->FOVy() << " ";
7419     }
7420     else
7421     {
7422       std::cout << "Error: unknown argument '" << anArg << "'\n";
7423       return 1;
7424     }
7425   }
7426
7427   aView->View()->AutoZFit();
7428   aView->Redraw();
7429
7430   return 0;
7431 }
7432
7433 //! Parse stereo output mode
7434 inline Standard_Boolean parseStereoMode (Standard_CString      theArg,
7435                                          Graphic3d_StereoMode& theMode)
7436 {
7437   TCollection_AsciiString aFlag (theArg);
7438   aFlag.LowerCase();
7439   if (aFlag == "quadbuffer")
7440   {
7441     theMode = Graphic3d_StereoMode_QuadBuffer;
7442   }
7443   else if (aFlag == "anaglyph")
7444   {
7445     theMode = Graphic3d_StereoMode_Anaglyph;
7446   }
7447   else if (aFlag == "row"
7448         || aFlag == "rowinterlaced")
7449   {
7450     theMode = Graphic3d_StereoMode_RowInterlaced;
7451   }
7452   else if (aFlag == "col"
7453         || aFlag == "colinterlaced"
7454         || aFlag == "columninterlaced")
7455   {
7456     theMode = Graphic3d_StereoMode_ColumnInterlaced;
7457   }
7458   else if (aFlag == "chess"
7459         || aFlag == "chessboard")
7460   {
7461     theMode = Graphic3d_StereoMode_ChessBoard;
7462   }
7463   else if (aFlag == "sbs"
7464         || aFlag == "sidebyside")
7465   {
7466     theMode = Graphic3d_StereoMode_SideBySide;
7467   }
7468   else if (aFlag == "ou"
7469         || aFlag == "overunder")
7470   {
7471     theMode = Graphic3d_StereoMode_OverUnder;
7472   }
7473   else if (aFlag == "pageflip"
7474         || aFlag == "softpageflip")
7475   {
7476     theMode = Graphic3d_StereoMode_SoftPageFlip;
7477   }
7478   else
7479   {
7480     return Standard_False;
7481   }
7482   return Standard_True;
7483 }
7484
7485 //! Parse anaglyph filter
7486 inline Standard_Boolean parseAnaglyphFilter (Standard_CString                     theArg,
7487                                              Graphic3d_RenderingParams::Anaglyph& theFilter)
7488 {
7489   TCollection_AsciiString aFlag (theArg);
7490   aFlag.LowerCase();
7491   if (aFlag == "redcyansimple")
7492   {
7493     theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
7494   }
7495   else if (aFlag == "redcyan"
7496         || aFlag == "redcyanoptimized")
7497   {
7498     theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
7499   }
7500   else if (aFlag == "yellowbluesimple")
7501   {
7502     theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
7503   }
7504   else if (aFlag == "yellowblue"
7505         || aFlag == "yellowblueoptimized")
7506   {
7507     theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
7508   }
7509   else if (aFlag == "greenmagenta"
7510         || aFlag == "greenmagentasimple")
7511   {
7512     theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
7513   }
7514   else
7515   {
7516     return Standard_False;
7517   }
7518   return Standard_True;
7519 }
7520
7521 //==============================================================================
7522 //function : VStereo
7523 //purpose  :
7524 //==============================================================================
7525
7526 static int VStereo (Draw_Interpretor& theDI,
7527                     Standard_Integer  theArgNb,
7528                     const char**      theArgVec)
7529 {
7530   Handle(V3d_View) aView = ViewerTest::CurrentView();
7531   if (theArgNb < 2)
7532   {
7533     if (aView.IsNull())
7534     {
7535       std::cout << "Error: no active viewer!\n";
7536       return 0;
7537     }
7538
7539     Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
7540     theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
7541     return 0;
7542   }
7543
7544   Handle(Graphic3d_Camera) aCamera;
7545   Graphic3d_RenderingParams*   aParams   = NULL;
7546   Graphic3d_StereoMode         aMode     = Graphic3d_StereoMode_QuadBuffer;
7547   if (!aView.IsNull())
7548   {
7549     aParams   = &aView->ChangeRenderingParams();
7550     aMode     = aParams->StereoMode;
7551     aCamera   = aView->Camera();
7552   }
7553
7554   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7555   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7556   {
7557     Standard_CString        anArg = theArgVec[anArgIter];
7558     TCollection_AsciiString aFlag (anArg);
7559     aFlag.LowerCase();
7560     if (anUpdateTool.parseRedrawMode (aFlag))
7561     {
7562       continue;
7563     }
7564     else if (aFlag == "0"
7565           || aFlag == "off")
7566     {
7567       if (++anArgIter < theArgNb)
7568       {
7569         std::cout << "Error: wrong number of arguments!\n";
7570         return 1;
7571       }
7572
7573       if (!aCamera.IsNull()
7574        &&  aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
7575       {
7576         aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
7577       }
7578       ViewerTest_myDefaultCaps.contextStereo = Standard_False;
7579       return 0;
7580     }
7581     else if (aFlag == "1"
7582           || aFlag == "on")
7583     {
7584       if (++anArgIter < theArgNb)
7585       {
7586         std::cout << "Error: wrong number of arguments!\n";
7587         return 1;
7588       }
7589
7590       if (!aCamera.IsNull())
7591       {
7592         aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
7593       }
7594       ViewerTest_myDefaultCaps.contextStereo = Standard_True;
7595       return 0;
7596     }
7597     else if (aFlag == "-reverse"
7598           || aFlag == "-reversed"
7599           || aFlag == "-swap")
7600     {
7601       Standard_Boolean toEnable = Standard_True;
7602       if (++anArgIter < theArgNb
7603       && !parseOnOff (theArgVec[anArgIter], toEnable))
7604       {
7605         --anArgIter;
7606       }
7607       aParams->ToReverseStereo = toEnable;
7608     }
7609     else if (aFlag == "-noreverse"
7610           || aFlag == "-noswap")
7611     {
7612       Standard_Boolean toDisable = Standard_True;
7613       if (++anArgIter < theArgNb
7614       && !parseOnOff (theArgVec[anArgIter], toDisable))
7615       {
7616         --anArgIter;
7617       }
7618       aParams->ToReverseStereo = !toDisable;
7619     }
7620     else if (aFlag == "-mode"
7621           || aFlag == "-stereomode")
7622     {
7623       if (++anArgIter >= theArgNb
7624       || !parseStereoMode (theArgVec[anArgIter], aMode))
7625       {
7626         std::cout << "Error: syntax error at '" << anArg << "'\n";
7627         return 1;
7628       }
7629
7630       if (aMode == Graphic3d_StereoMode_QuadBuffer)
7631       {
7632         ViewerTest_myDefaultCaps.contextStereo = Standard_True;
7633       }
7634     }
7635     else if (aFlag == "-anaglyph"
7636           || aFlag == "-anaglyphfilter")
7637     {
7638       Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
7639       if (++anArgIter >= theArgNb
7640       || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
7641       {
7642         std::cout << "Error: syntax error at '" << anArg << "'\n";
7643         return 1;
7644       }
7645
7646       aMode = Graphic3d_StereoMode_Anaglyph;
7647       aParams->AnaglyphFilter = aFilter;
7648     }
7649     else if (parseStereoMode (anArg, aMode)) // short syntax
7650     {
7651       if (aMode == Graphic3d_StereoMode_QuadBuffer)
7652       {
7653         ViewerTest_myDefaultCaps.contextStereo = Standard_True;
7654       }
7655     }
7656     else
7657     {
7658       std::cout << "Error: syntax error at '" << anArg << "'\n";
7659       return 1;
7660     }
7661   }
7662
7663   if (!aView.IsNull())
7664   {
7665     aParams->StereoMode = aMode;
7666     aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
7667   }
7668   return 0;
7669 }
7670
7671 //===============================================================================================
7672 //function : VDefaults
7673 //purpose  :
7674 //===============================================================================================
7675 static int VDefaults (Draw_Interpretor& theDi,
7676                       Standard_Integer  theArgsNb,
7677                       const char**      theArgVec)
7678 {
7679   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
7680   if (aCtx.IsNull())
7681   {
7682     std::cerr << "No active viewer!\n";
7683     return 1;
7684   }
7685
7686   Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
7687   if (theArgsNb < 2)
7688   {
7689     if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
7690     {
7691       theDi << "DeflType:           relative\n"
7692             << "DeviationCoeff:     " << aDefParams->DeviationCoefficient() << "\n";
7693     }
7694     else
7695     {
7696       theDi << "DeflType:           absolute\n"
7697             << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
7698     }
7699     theDi << "AngularDeflection:  " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
7700     theDi << "AutoTriangulation:  " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
7701     return 0;
7702   }
7703
7704   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
7705   {
7706     TCollection_AsciiString anArg (theArgVec[anArgIter]);
7707     anArg.UpperCase();
7708     if (anArg == "-ABSDEFL"
7709      || anArg == "-ABSOLUTEDEFLECTION"
7710      || anArg == "-DEFL"
7711      || anArg == "-DEFLECTION")
7712     {
7713       if (++anArgIter >= theArgsNb)
7714       {
7715         std::cout << "Error: wrong syntax at " << anArg << "\n";
7716         return 1;
7717       }
7718       aDefParams->SetTypeOfDeflection         (Aspect_TOD_ABSOLUTE);
7719       aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
7720     }
7721     else if (anArg == "-RELDEFL"
7722           || anArg == "-RELATIVEDEFLECTION"
7723           || anArg == "-DEVCOEFF"
7724           || anArg == "-DEVIATIONCOEFF"
7725           || anArg == "-DEVIATIONCOEFFICIENT")
7726     {
7727       if (++anArgIter >= theArgsNb)
7728       {
7729         std::cout << "Error: wrong syntax at " << anArg << "\n";
7730         return 1;
7731       }
7732       aDefParams->SetTypeOfDeflection     (Aspect_TOD_RELATIVE);
7733       aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
7734     }
7735     else if (anArg == "-ANGDEFL"
7736           || anArg == "-ANGULARDEFL"
7737           || anArg == "-ANGULARDEFLECTION")
7738     {
7739       if (++anArgIter >= theArgsNb)
7740       {
7741         std::cout << "Error: wrong syntax at " << anArg << "\n";
7742         return 1;
7743       }
7744       // currently HLRDeviationAngle is used instead of DeviationAngle in most places
7745       aDefParams->SetHLRAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
7746     }
7747     else if (anArg == "-AUTOTR"
7748           || anArg == "-AUTOTRIANG"
7749           || anArg == "-AUTOTRIANGULATION")
7750     {
7751       if (++anArgIter >= theArgsNb)
7752       {
7753         std::cout << "Error: wrong syntax at " << anArg << "\n";
7754         return 1;
7755       }
7756       TCollection_AsciiString aValue (theArgVec[anArgIter]);
7757       aValue.LowerCase();
7758       if (aValue == "on"
7759        || aValue == "1")
7760       {
7761         aDefParams->SetAutoTriangulation (Standard_True);
7762       }
7763       else if (aValue == "off"
7764             || aValue == "0")
7765       {
7766         aDefParams->SetAutoTriangulation (Standard_False);
7767       }
7768     }
7769     else
7770     {
7771       std::cerr << "Warning, unknown argument '" << anArg.ToCString() << "'\n";
7772     }
7773   }
7774
7775   return 0;
7776 }
7777
7778 //! Auxiliary method
7779 inline void addLight (const Handle(V3d_Light)& theLightNew,
7780                       const Standard_Boolean   theIsGlobal)
7781 {
7782   if (theLightNew.IsNull())
7783   {
7784     return;
7785   }
7786
7787   if (theIsGlobal)
7788   {
7789     ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew);
7790   }
7791   else
7792   {
7793     ViewerTest::CurrentView()->SetLightOn (theLightNew);
7794   }
7795 }
7796
7797 //! Auxiliary method
7798 inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
7799 {
7800   TCollection_AsciiString anArgNextCase (theArgNext);
7801   anArgNextCase.UpperCase();
7802   if (anArgNextCase.Length() > 5
7803    && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
7804   {
7805     return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
7806   }
7807   else
7808   {
7809     return theArgNext.IntegerValue();
7810   }
7811 }
7812
7813 //===============================================================================================
7814 //function : VLight
7815 //purpose  :
7816 //===============================================================================================
7817 static int VLight (Draw_Interpretor& theDi,
7818                    Standard_Integer  theArgsNb,
7819                    const char**      theArgVec)
7820 {
7821   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
7822   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
7823   if (aView.IsNull()
7824    || aViewer.IsNull())
7825   {
7826     std::cerr << "No active viewer!\n";
7827     return 1;
7828   }
7829
7830   Standard_Real        anXYZ[3];
7831   Quantity_Coefficient anAtten[2];
7832   if (theArgsNb < 2)
7833   {
7834     // print lights info
7835     Standard_Integer aLightId = 0;
7836     for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightId)
7837     {
7838       Handle(V3d_Light) aLight = aView->ActiveLight();
7839       const Quantity_Color aColor = aLight->Color();
7840       theDi << "Light" << aLightId << "\n";
7841       switch (aLight->Type())
7842       {
7843         case V3d_AMBIENT:
7844         {
7845           theDi << "  Type:       Ambient\n";
7846           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
7847           break;
7848         }
7849         case V3d_DIRECTIONAL:
7850         {
7851           Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
7852           theDi << "  Type:       Directional\n";
7853           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
7854           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7855           theDi << "  Smoothness: " << aLight->Smoothness() << "\n";
7856           if (!aLightDir.IsNull())
7857           {
7858             aLightDir->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7859             theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7860             aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
7861             theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7862           }
7863           break;
7864         }
7865         case V3d_POSITIONAL:
7866         {
7867           Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
7868           theDi << "  Type:       Positional\n";
7869           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
7870           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7871           theDi << "  Smoothness: " << aLight->Smoothness() << "\n";
7872           if (!aLightPos.IsNull())
7873           {
7874             aLightPos->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7875             theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7876             aLightPos->Attenuation (anAtten[0], anAtten[1]);
7877             theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
7878           }
7879           break;
7880         }
7881         case V3d_SPOT:
7882         {
7883           Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
7884           theDi << "  Type:       Spot\n";
7885           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
7886           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7887           if (!aLightSpot.IsNull())
7888           {
7889             aLightSpot->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7890             theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7891             aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
7892             theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7893             aLightSpot->Attenuation (anAtten[0], anAtten[1]);
7894             theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
7895             theDi << "  Angle:      " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
7896             theDi << "  Exponent:   " << aLightSpot->Concentration() << "\n";
7897           }
7898           break;
7899         }
7900         default:
7901         {
7902           theDi << "  Type:       UNKNOWN\n";
7903           break;
7904         }
7905       }
7906       theDi << "  Color:     " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n";
7907     }
7908   }
7909
7910   Handle(V3d_Light) aLightNew;
7911   Handle(V3d_Light) aLightOld;
7912   Standard_Boolean  isGlobal = Standard_True;
7913   Standard_Boolean  toCreate = Standard_False;
7914   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7915   {
7916     Handle(V3d_Light)            aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
7917     Handle(V3d_AmbientLight)     aLightAmb  = Handle(V3d_AmbientLight)    ::DownCast (aLightCurr);
7918     Handle(V3d_DirectionalLight) aLightDir  = Handle(V3d_DirectionalLight)::DownCast (aLightCurr);
7919     Handle(V3d_PositionalLight)  aLightPos  = Handle(V3d_PositionalLight) ::DownCast (aLightCurr);
7920     Handle(V3d_SpotLight)        aLightSpot = Handle(V3d_SpotLight)       ::DownCast (aLightCurr);
7921
7922     TCollection_AsciiString aName, aValue;
7923     const TCollection_AsciiString anArg (theArgVec[anArgIt]);
7924     TCollection_AsciiString anArgCase (anArg);
7925     anArgCase.UpperCase();
7926     if (anArgCase.IsEqual ("NEW")
7927      || anArgCase.IsEqual ("ADD")
7928      || anArgCase.IsEqual ("CREATE"))
7929     {
7930       toCreate = Standard_True;
7931     }
7932     else if (anArgCase.IsEqual ("GLOB")
7933           || anArgCase.IsEqual ("GLOBAL"))
7934     {
7935       isGlobal = Standard_True;
7936     }
7937     else if (anArgCase.IsEqual ("LOC")
7938           || anArgCase.IsEqual ("LOCAL"))
7939     {
7940       isGlobal = Standard_False;
7941     }
7942     else if (anArgCase.IsEqual ("DEF")
7943           || anArgCase.IsEqual ("DEFAULTS"))
7944     {
7945       toCreate = Standard_False;
7946       aViewer->SetDefaultLights();
7947     }
7948     else if (anArgCase.IsEqual ("CLR")
7949           || anArgCase.IsEqual ("CLEAR"))
7950     {
7951       toCreate = Standard_False;
7952       aView->InitActiveLights();
7953       while (aView->MoreActiveLights())
7954       {
7955         aViewer->DelLight (aView->ActiveLight());
7956         aView->InitActiveLights();
7957       }
7958     }
7959     else if (anArgCase.IsEqual ("AMB")
7960           || anArgCase.IsEqual ("AMBIENT")
7961           || anArgCase.IsEqual ("AMBLIGHT"))
7962     {
7963       addLight (aLightNew, isGlobal);
7964       if (!toCreate)
7965       {
7966         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7967         return 1;
7968       }
7969       toCreate  = Standard_False;
7970       aLightNew = new V3d_AmbientLight (aViewer);
7971     }
7972     else if (anArgCase.IsEqual ("DIRECTIONAL")
7973           || anArgCase.IsEqual ("DIRLIGHT"))
7974     {
7975       addLight (aLightNew, isGlobal);
7976       if (!toCreate)
7977       {
7978         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7979         return 1;
7980       }
7981       toCreate  = Standard_False;
7982       aLightNew = new V3d_DirectionalLight (aViewer);
7983     }
7984     else if (anArgCase.IsEqual ("SPOT")
7985           || anArgCase.IsEqual ("SPOTLIGHT"))
7986     {
7987       addLight (aLightNew, isGlobal);
7988       if (!toCreate)
7989       {
7990         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7991         return 1;
7992       }
7993       toCreate  = Standard_False;
7994       aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0);
7995     }
7996     else if (anArgCase.IsEqual ("POSLIGHT")
7997           || anArgCase.IsEqual ("POSITIONAL"))
7998     {
7999       addLight (aLightNew, isGlobal);
8000       if (!toCreate)
8001       {
8002         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8003         return 1;
8004       }
8005       toCreate  = Standard_False;
8006       aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0);
8007     }
8008     else if (anArgCase.IsEqual ("CHANGE"))
8009     {
8010       addLight (aLightNew, isGlobal);
8011       aLightNew.Nullify();
8012       if (++anArgIt >= theArgsNb)
8013       {
8014         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8015         return 1;
8016       }
8017
8018       const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
8019       Standard_Integer aLightIt = 0;
8020       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
8021       {
8022         if (aLightIt == aLightId)
8023         {
8024           aLightOld = aView->ActiveLight();
8025           break;
8026         }
8027       }
8028
8029       if (aLightOld.IsNull())
8030       {
8031         std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n";
8032         return 1;
8033       }
8034     }
8035     else if (anArgCase.IsEqual ("DEL")
8036           || anArgCase.IsEqual ("DELETE"))
8037     {
8038       Handle(V3d_Light) aLightDel;
8039       if (++anArgIt >= theArgsNb)
8040       {
8041         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8042         return 1;
8043       }
8044
8045       const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
8046       const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
8047       Standard_Integer aLightIt = 0;
8048       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
8049       {
8050         aLightDel = aView->ActiveLight();
8051         if (aLightIt == aLightDelId)
8052         {
8053           break;
8054         }
8055       }
8056       if (!aLightDel.IsNull())
8057       {
8058         aViewer->DelLight (aLightDel);
8059       }
8060     }
8061     else if (anArgCase.IsEqual ("COLOR")
8062           || anArgCase.IsEqual ("COLOUR"))
8063     {
8064       if (++anArgIt >= theArgsNb)
8065       {
8066         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8067         return 1;
8068       }
8069
8070       TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
8071       anArgNext.UpperCase();
8072       const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
8073       if (!aLightCurr.IsNull())
8074       {
8075         aLightCurr->SetColor (aColor);
8076       }
8077     }
8078     else if (anArgCase.IsEqual ("POS")
8079           || anArgCase.IsEqual ("POSITION"))
8080     {
8081       if ((anArgIt + 3) >= theArgsNb)
8082       {
8083         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8084         return 1;
8085       }
8086
8087       anXYZ[0] = Atof (theArgVec[++anArgIt]);
8088       anXYZ[1] = Atof (theArgVec[++anArgIt]);
8089       anXYZ[2] = Atof (theArgVec[++anArgIt]);
8090       if (!aLightDir.IsNull())
8091       {
8092         aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
8093       }
8094       else if (!aLightPos.IsNull())
8095       {
8096         aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
8097       }
8098       else if (!aLightSpot.IsNull())
8099       {
8100         aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
8101       }
8102       else
8103       {
8104         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8105         return 1;
8106       }
8107     }
8108     else if (anArgCase.IsEqual ("DIR")
8109           || anArgCase.IsEqual ("DIRECTION"))
8110     {
8111       if ((anArgIt + 3) >= theArgsNb)
8112       {
8113         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8114         return 1;
8115       }
8116
8117       anXYZ[0] = Atof (theArgVec[++anArgIt]);
8118       anXYZ[1] = Atof (theArgVec[++anArgIt]);
8119       anXYZ[2] = Atof (theArgVec[++anArgIt]);
8120       if (!aLightDir.IsNull())
8121       {
8122         aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
8123       }
8124       else if (!aLightSpot.IsNull())
8125       {
8126         aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
8127       }
8128       else
8129       {
8130         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8131         return 1;
8132       }
8133     }
8134     else if (anArgCase.IsEqual ("SM")
8135           || anArgCase.IsEqual ("SMOOTHNESS"))
8136     {
8137       if (++anArgIt >= theArgsNb)
8138       {
8139         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8140         return 1;
8141       }
8142
8143       Standard_Real aSmoothness = Atof (theArgVec[anArgIt]);
8144
8145       if (fabs (aSmoothness) < Precision::Confusion())
8146       {
8147         aLightCurr->SetIntensity (1.f);
8148       }
8149       else if (fabs (aLightCurr->Smoothness()) < Precision::Confusion())
8150       {
8151         aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
8152       }
8153       else
8154       {
8155         Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
8156         aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
8157       }
8158
8159       if (!aLightPos.IsNull())
8160       {
8161         aLightPos->SetSmoothRadius (aSmoothness);
8162       }
8163       else if (!aLightDir.IsNull())
8164       {
8165         aLightDir->SetSmoothAngle (aSmoothness);
8166       }
8167     }
8168     else if (anArgCase.IsEqual ("INT")
8169           || anArgCase.IsEqual ("INTENSITY"))
8170     {
8171       if (++anArgIt >= theArgsNb)
8172       {
8173         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8174         return 1;
8175       }
8176
8177       Standard_Real aIntensity = Atof (theArgVec[anArgIt]);
8178
8179       if (!aLightCurr.IsNull())
8180       {
8181         aLightCurr->SetIntensity (aIntensity);
8182       }
8183     }
8184     else if (anArgCase.IsEqual ("ANG")
8185           || anArgCase.IsEqual ("ANGLE"))
8186     {
8187       if (++anArgIt >= theArgsNb)
8188       {
8189         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8190         return 1;
8191       }
8192
8193       Standard_Real anAngle = Atof (theArgVec[anArgIt]);
8194
8195       if (!aLightSpot.IsNull())
8196       {
8197         aLightSpot->SetAngle (anAngle / 180.0 * M_PI);
8198       }
8199     }
8200     else if (anArgCase.IsEqual ("CONSTATTEN")
8201           || anArgCase.IsEqual ("CONSTATTENUATION"))
8202     {
8203       if (++anArgIt >= theArgsNb)
8204       {
8205         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8206         return 1;
8207       }
8208
8209       if (!aLightPos.IsNull())
8210       {
8211         aLightPos->Attenuation (anAtten[0], anAtten[1]);
8212         anAtten[0] = Atof (theArgVec[anArgIt]);
8213         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
8214       }
8215       else if (!aLightSpot.IsNull())
8216       {
8217         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
8218         anAtten[0] = Atof (theArgVec[anArgIt]);
8219         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
8220       }
8221       else
8222       {
8223         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8224         return 1;
8225       }
8226     }
8227     else if (anArgCase.IsEqual ("LINATTEN")
8228           || anArgCase.IsEqual ("LINEARATTEN")
8229           || anArgCase.IsEqual ("LINEARATTENUATION"))
8230     {
8231       if (++anArgIt >= theArgsNb)
8232       {
8233         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8234         return 1;
8235       }
8236
8237       if (!aLightPos.IsNull())
8238       {
8239         aLightPos->Attenuation (anAtten[0], anAtten[1]);
8240         anAtten[1] = Atof (theArgVec[anArgIt]);
8241         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
8242       }
8243       else if (!aLightSpot.IsNull())
8244       {
8245         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
8246         anAtten[1] = Atof (theArgVec[anArgIt]);
8247         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
8248       }
8249       else
8250       {
8251         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8252         return 1;
8253       }
8254     }
8255     else if (anArgCase.IsEqual ("EXP")
8256           || anArgCase.IsEqual ("EXPONENT")
8257           || anArgCase.IsEqual ("SPOTEXP")
8258           || anArgCase.IsEqual ("SPOTEXPONENT"))
8259     {
8260       if (++anArgIt >= theArgsNb)
8261       {
8262         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8263         return 1;
8264       }
8265
8266       if (!aLightSpot.IsNull())
8267       {
8268         aLightSpot->SetConcentration (Atof (theArgVec[anArgIt]));
8269       }
8270       else
8271       {
8272         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8273         return 1;
8274       }
8275     }
8276     else if (anArgCase.IsEqual ("HEAD")
8277           || anArgCase.IsEqual ("HEADLIGHT"))
8278     {
8279       if (++anArgIt >= theArgsNb)
8280       {
8281         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8282         return 1;
8283       }
8284
8285       if (aLightAmb.IsNull()
8286        && !aLightCurr.IsNull())
8287       {
8288         aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0);
8289       }
8290       else
8291       {
8292         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
8293         return 1;
8294       }
8295     }
8296     else
8297     {
8298       std::cerr << "Warning: unknown argument '" << anArg << "'\n";
8299     }
8300   }
8301
8302   addLight (aLightNew, isGlobal);
8303   aViewer->UpdateLights();
8304
8305   return 0;
8306 }
8307
8308 //=======================================================================
8309 //function : VRenderParams
8310 //purpose  : Enables/disables rendering features
8311 //=======================================================================
8312
8313 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
8314                                        Standard_Integer  theArgNb,
8315                                        const char**      theArgVec)
8316 {
8317   Handle(V3d_View) aView = ViewerTest::CurrentView();
8318   if (aView.IsNull())
8319   {
8320     std::cerr << "Error: no active viewer!\n";
8321     return 1;
8322   }
8323
8324   Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
8325   TCollection_AsciiString aCmdName (theArgVec[0]);
8326   aCmdName.LowerCase();
8327   if (aCmdName == "vraytrace")
8328   {
8329     if (theArgNb == 1)
8330     {
8331       theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
8332       return 0;
8333     }
8334     else if (theArgNb == 2)
8335     {
8336       TCollection_AsciiString aValue (theArgVec[1]);
8337       aValue.LowerCase();
8338       if (aValue == "on"
8339        || aValue == "1")
8340       {
8341         aParams.Method = Graphic3d_RM_RAYTRACING;
8342         aView->Redraw();
8343         return 0;
8344       }
8345       else if (aValue == "off"
8346             || aValue == "0")
8347       {
8348         aParams.Method = Graphic3d_RM_RASTERIZATION;
8349         aView->Redraw();
8350         return 0;
8351       }
8352       else
8353       {
8354         std::cout << "Error: unknown argument '" << theArgVec[1] << "'\n";
8355         return 1;
8356       }
8357     }
8358     else
8359     {
8360       std::cout << "Error: wrong number of arguments\n";
8361       return 1;
8362     }
8363   }
8364
8365   if (theArgNb < 2)
8366   {
8367     theDI << "renderMode:  ";
8368     switch (aParams.Method)
8369     {
8370       case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
8371       case Graphic3d_RM_RAYTRACING:    theDI << "raytrace ";      break;
8372     }
8373     theDI << "\n";
8374     theDI << "fsaa:         " << (aParams.IsAntialiasingEnabled       ? "on" : "off") << "\n";
8375     theDI << "shadows:      " << (aParams.IsShadowEnabled             ? "on" : "off") << "\n";
8376     theDI << "reflections:  " << (aParams.IsReflectionEnabled         ? "on" : "off") << "\n";
8377     theDI << "rayDepth:     " <<  aParams.RaytracingDepth                             << "\n";
8378     theDI << "gleam:        " << (aParams.IsTransparentShadowEnabled  ? "on" : "off") << "\n";
8379     theDI << "GI:           " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
8380     theDI << "blocked RNG:  " << (aParams.CoherentPathTracingMode     ? "on" : "off") << "\n";
8381     theDI << "shadingModel: ";
8382     switch (aView->ShadingModel())
8383     {
8384       case V3d_COLOR:   theDI << "color";   break;
8385       case V3d_FLAT:    theDI << "flat";    break;
8386       case V3d_GOURAUD: theDI << "gouraud"; break;
8387       case V3d_PHONG:   theDI << "phong";   break;
8388     }
8389     theDI << "\n";
8390     return 0;
8391   }
8392
8393   Standard_Boolean toPrint = Standard_False;
8394   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
8395   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
8396   {
8397     Standard_CString        anArg (theArgVec[anArgIter]);
8398     TCollection_AsciiString aFlag (anArg);
8399     aFlag.LowerCase();
8400     if (anUpdateTool.parseRedrawMode (aFlag))
8401     {
8402       continue;
8403     }
8404     else if (aFlag == "-echo"
8405           || aFlag == "-print")
8406     {
8407       toPrint = Standard_True;
8408       anUpdateTool.Invalidate();
8409     }
8410     else if (aFlag == "-mode"
8411           || aFlag == "-rendermode"
8412           || aFlag == "-render_mode")
8413     {
8414       if (toPrint)
8415       {
8416         switch (aParams.Method)
8417         {
8418           case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
8419           case Graphic3d_RM_RAYTRACING:    theDI << "ray-tracing ";   break;
8420         }
8421         continue;
8422       }
8423       else
8424       {
8425         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
8426         return 1;
8427       }
8428     }
8429     else if (aFlag == "-ray"
8430           || aFlag == "-raytrace")
8431     {
8432       if (toPrint)
8433       {
8434         theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
8435         continue;
8436       }
8437
8438       aParams.Method = Graphic3d_RM_RAYTRACING;
8439     }
8440     else if (aFlag == "-rast"
8441           || aFlag == "-raster"
8442           || aFlag == "-rasterization")
8443     {
8444       if (toPrint)
8445       {
8446         theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
8447         continue;
8448       }
8449
8450       aParams.Method = Graphic3d_RM_RASTERIZATION;
8451     }
8452     else if (aFlag == "-raydepth"
8453           || aFlag == "-ray_depth")
8454     {
8455       if (toPrint)
8456       {
8457         theDI << aParams.RaytracingDepth << " ";
8458         continue;
8459       }
8460       else if (++anArgIter >= theArgNb)
8461       {
8462         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
8463         return 1;
8464       }
8465
8466       const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
8467
8468       // We allow RaytracingDepth be more than 10 in case of GI enabled
8469       if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
8470       {
8471         std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
8472         return 1;
8473       }
8474       else
8475       {
8476         aParams.RaytracingDepth = aDepth;
8477       }
8478     }
8479     else if (aFlag == "-shad"
8480           || aFlag == "-shadows")
8481     {
8482       if (toPrint)
8483       {
8484         theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
8485         continue;
8486       }
8487
8488       Standard_Boolean toEnable = Standard_True;
8489       if (++anArgIter < theArgNb
8490       && !parseOnOff (theArgVec[anArgIter], toEnable))
8491       {
8492         --anArgIter;
8493       }
8494       aParams.IsShadowEnabled = toEnable;
8495     }
8496     else if (aFlag == "-refl"
8497           || aFlag == "-reflections")
8498     {
8499       if (toPrint)
8500       {
8501         theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
8502         continue;
8503       }
8504
8505       Standard_Boolean toEnable = Standard_True;
8506       if (++anArgIter < theArgNb
8507       && !parseOnOff (theArgVec[anArgIter], toEnable))
8508       {
8509         --anArgIter;
8510       }
8511       aParams.IsReflectionEnabled = toEnable;
8512     }
8513     else if (aFlag == "-fsaa")
8514     {
8515       if (toPrint)
8516       {
8517         theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
8518         continue;
8519       }
8520
8521       Standard_Boolean toEnable = Standard_True;
8522       if (++anArgIter < theArgNb
8523       && !parseOnOff (theArgVec[anArgIter], toEnable))
8524       {
8525         --anArgIter;
8526       }
8527       aParams.IsAntialiasingEnabled = toEnable;
8528     }
8529     else if (aFlag == "-gleam")
8530     {
8531       if (toPrint)
8532       {
8533         theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
8534         continue;
8535       }
8536
8537       Standard_Boolean toEnable = Standard_True;
8538       if (++anArgIter < theArgNb
8539       && !parseOnOff (theArgVec[anArgIter], toEnable))
8540       {
8541         --anArgIter;
8542       }
8543       aParams.IsTransparentShadowEnabled = toEnable;
8544     }
8545     else if (aFlag == "-gi")
8546     {
8547       if (toPrint)
8548       {
8549         theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
8550         continue;
8551       }
8552
8553       Standard_Boolean toEnable = Standard_True;
8554       if (++anArgIter < theArgNb
8555       && !parseOnOff (theArgVec[anArgIter], toEnable))
8556       {
8557         --anArgIter;
8558       }
8559       aParams.IsGlobalIlluminationEnabled = toEnable;
8560       if (!toEnable)
8561       {
8562         aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
8563       }
8564     }
8565     else if (aFlag == "-blockedrng"
8566           || aFlag == "-brng")
8567     {
8568       if (toPrint)
8569       {
8570         theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
8571         continue;
8572       }
8573
8574       Standard_Boolean toEnable = Standard_True;
8575       if (++anArgIter < theArgNb
8576         && !parseOnOff (theArgVec[anArgIter], toEnable))
8577       {
8578         --anArgIter;
8579       }
8580       aParams.CoherentPathTracingMode = toEnable;
8581     }
8582     else if (aFlag == "-env")
8583     {
8584       if (toPrint)
8585       {
8586         theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
8587         continue;
8588       }
8589
8590       Standard_Boolean toEnable = Standard_True;
8591       if (++anArgIter < theArgNb
8592         && !parseOnOff (theArgVec[anArgIter], toEnable))
8593       {
8594         --anArgIter;
8595       }
8596       aParams.UseEnvironmentMapBackground = toEnable;
8597     }
8598     else if (aFlag == "-shademodel"
8599           || aFlag == "-shadingmodel"
8600           || aFlag == "-shading")
8601     {
8602       if (toPrint)
8603       {
8604         switch (aView->ShadingModel())
8605         {
8606           case V3d_COLOR:   theDI << "color ";   break;
8607           case V3d_FLAT:    theDI << "flat ";    break;
8608           case V3d_GOURAUD: theDI << "gouraud "; break;
8609           case V3d_PHONG:   theDI << "phong ";   break;
8610         }
8611         continue;
8612       }
8613
8614       if (++anArgIter >= theArgNb)
8615       {
8616         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
8617       }
8618
8619       TCollection_AsciiString aMode (theArgVec[anArgIter]);
8620       aMode.LowerCase();
8621       if (aMode == "color"
8622        || aMode == "none")
8623       {
8624         aView->SetShadingModel (V3d_COLOR);
8625       }
8626       else if (aMode == "flat"
8627             || aMode == "facet")
8628       {
8629         aView->SetShadingModel (V3d_FLAT);
8630       }
8631       else if (aMode == "gouraud"
8632             || aMode == "vertex"
8633             || aMode == "vert")
8634       {
8635         aView->SetShadingModel (V3d_GOURAUD);
8636       }
8637       else if (aMode == "phong"
8638             || aMode == "fragment"
8639             || aMode == "frag"
8640             || aMode == "pixel")
8641       {
8642         aView->SetShadingModel (V3d_PHONG);
8643       }
8644       else
8645       {
8646         std::cout << "Error: unknown shading model '" << aMode << "'\n";
8647         return 1;
8648       }
8649     }
8650     else
8651     {
8652       std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
8653       return 1;
8654     }
8655   }
8656
8657   return 0;
8658 }
8659
8660 //=======================================================================
8661 //function : VProgressiveMode
8662 //purpose  :
8663 //=======================================================================
8664 #if defined(_WIN32)
8665 static Standard_Integer VProgressiveMode (Draw_Interpretor& /*theDI*/,
8666                                           Standard_Integer  /*theNbArgs*/,
8667                                           const char**      /*theArgs*/)
8668 {
8669   Handle(V3d_View) aView = ViewerTest::CurrentView();
8670   if (aView.IsNull())
8671   {
8672     std::cerr << "Error: no active viewer!\n";
8673     return 1;
8674   }
8675
8676   std::cout << "Press Enter or Escape key to exit progressive rendering mode" << std::endl;
8677
8678   for (;;)
8679   {
8680     aView->Redraw();
8681
8682     Standard_Boolean toExit = Standard_False;
8683
8684     MSG aMsg;
8685     while (PeekMessage (&aMsg, NULL, NULL, NULL, PM_REMOVE))
8686     {
8687       if (aMsg.message == WM_KEYDOWN && (aMsg.wParam == 0x0d || aMsg.wParam == 0x1b))
8688       {
8689         toExit = Standard_True;
8690       }
8691
8692       TranslateMessage (&aMsg);
8693       DispatchMessage  (&aMsg);
8694     }
8695
8696     if (toExit)
8697     {
8698       break;
8699     }
8700   }
8701
8702   return 0;
8703 }
8704 #endif
8705
8706 //=======================================================================
8707 //function : VFrustumCulling
8708 //purpose  : enables/disables view volume's culling.
8709 //=======================================================================
8710 static int VFrustumCulling (Draw_Interpretor& theDI,
8711                             Standard_Integer  theArgNb,
8712                             const char**      theArgVec)
8713 {
8714   Handle(V3d_View) aView = ViewerTest::CurrentView();
8715   if (aView.IsNull())
8716   {
8717     std::cout << theArgVec[0] << " Error: Use 'vinit' command before\n";
8718     return 1;
8719   }
8720
8721   if (theArgNb < 2)
8722   {
8723     theDI << (aView->IsCullingEnabled() ? "on" : "off");
8724     return 0;
8725   }
8726   else if (theArgNb != 2)
8727   {
8728     std::cout << theArgVec[0] << " Syntax error: Specify the mode\n";
8729     return 1;
8730   }
8731
8732   TCollection_AsciiString aModeStr (theArgVec[1]);
8733   aModeStr.LowerCase();
8734   Standard_Boolean toEnable = 0;
8735   if (aModeStr == "on")
8736   {
8737     toEnable = 1;
8738   }
8739   else if (aModeStr == "off")
8740   {
8741     toEnable = 0;
8742   }
8743   else
8744   {
8745     toEnable = Draw::Atoi (theArgVec[1]) != 0;
8746   }
8747
8748   aView->SetFrustumCulling (toEnable);
8749   aView->Redraw();
8750   return 0;
8751 }
8752
8753 //=======================================================================
8754 //function : VHighlightSelected
8755 //purpose  : 
8756 //=======================================================================
8757 static int VHighlightSelected (Draw_Interpretor& theDI,
8758                                Standard_Integer  theArgNb,
8759                                const char**      theArgVec)
8760 {
8761   if (ViewerTest::GetAISContext().IsNull())
8762   {
8763     std::cout << theArgVec[0] << " error : Context is not created. Please call vinit before.\n";
8764     return 1;
8765   }
8766
8767   const Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8768
8769   if (theArgNb < 2)
8770   {
8771     theDI << (aContext->ToHilightSelected() ? "on" : "off");
8772     return 0;
8773   }
8774
8775   if (theArgNb != 2)
8776   {
8777     std::cout  << theArgVec[0] << " error : wrong number of parameters."
8778           << "Type 'help" << theArgVec[0] << "' for more information.";
8779     return 1;
8780   }
8781
8782   // Parse parameter
8783   TCollection_AsciiString aMode (theArgVec[1]);
8784   aMode.LowerCase();
8785   Standard_Boolean toEnable = Standard_False;
8786   if (aMode.IsEqual ("on"))
8787   {
8788     toEnable = Standard_True;
8789   }
8790   else if (aMode.IsEqual ("off"))
8791   {
8792     toEnable = Standard_False;
8793   }
8794   else
8795   {
8796     toEnable = Draw::Atoi (theArgVec[1]) != 0;
8797   }
8798
8799   if (toEnable != aContext->ToHilightSelected())
8800   {
8801     aContext->SetToHilightSelected (toEnable);
8802
8803     // Move cursor to null position and  back to process updating of detection
8804     // and highlighting of selected object immediatly.
8805     Standard_Integer aPixX = 0;
8806     Standard_Integer aPixY = 0;
8807     const Handle(ViewerTest_EventManager)& anEventManager =  ViewerTest::CurrentEventManager();
8808
8809     anEventManager->GetCurrentPosition (aPixX, aPixY);
8810     anEventManager->MoveTo (0, 0);
8811     anEventManager->MoveTo (aPixX, aPixY);
8812   }
8813
8814   return 0;
8815 }
8816
8817 //=======================================================================
8818 //function : VXRotate
8819 //purpose  :
8820 //=======================================================================
8821 static Standard_Integer VXRotate (Draw_Interpretor& di,
8822                                    Standard_Integer argc,
8823                                    const char ** argv)
8824 {
8825   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8826   if (aContext.IsNull())
8827   {
8828     di << argv[0] << "ERROR : use 'vinit' command before " << "\n";
8829     return 1;
8830   }
8831   
8832   if (argc != 3)
8833   {
8834     di << "ERROR : Usage : " << argv[0] << " name angle" << "\n";
8835     return 1;
8836   }
8837
8838   TCollection_AsciiString aName (argv[1]);
8839   Standard_Real anAngle = Draw::Atof (argv[2]);
8840
8841   // find object
8842   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
8843   Handle(AIS_InteractiveObject) anIObj;
8844   if (!aMap.IsBound2 (aName) )
8845   {
8846     di << "Use 'vdisplay' before" << "\n";
8847     return 1;
8848   }
8849   else
8850   {
8851     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
8852
8853     gp_Trsf aTransform;
8854     aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
8855     aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
8856
8857     aContext->SetLocation (anIObj, aTransform);
8858     aContext->UpdateCurrentViewer();
8859   }
8860
8861   return 0;
8862 }
8863
8864 //=======================================================================
8865 //function : ViewerCommands
8866 //purpose  :
8867 //=======================================================================
8868
8869 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
8870 {
8871
8872   const char *group = "ZeViewer";
8873   theCommands.Add("vinit",
8874 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8875     "[name=view_name] [display=display_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
8876 #else
8877     "[name=view_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
8878 #endif
8879     " - Creates new View window with specified name view_name.\n"
8880     "By default the new view is created in the viewer and in"
8881     " graphic driver shared with active view.\n"
8882     " - name = {driverName/viewerName/viewName | viewerName/viewName | viewName}.\n"
8883     "If driverName isn't specified the driver will be shared with active view.\n"
8884     "If viewerName isn't specified the viewer will be shared with active view.\n"
8885 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8886     " - display = HostName.DisplayNumber[:ScreenNumber] : if specified"
8887     "is used in creation of graphic driver\n"
8888 #endif
8889     " - l, t: pixel position of left top corner of the window\n"
8890     " - w,h: width and heigth of window respectively.\n"
8891     "Additional commands for operations with views: vclose, vactivate, vviewlist.\n",
8892     __FILE__,VInit,group);
8893   theCommands.Add("vclose" ,
8894     "[view_id [keep_context=0|1]]\n"
8895     "or vclose ALL - to remove all created views\n"
8896     " - removes view(viewer window) defined by its view_id.\n"
8897     " - keep_context: by default 0; if 1 and the last view is deleted"
8898     " the current context is not removed.",
8899     __FILE__,VClose,group);
8900   theCommands.Add("vactivate" ,
8901     "view_id"
8902     " - activates view(viewer window) defined by its view_id",
8903     __FILE__,VActivate,group);
8904   theCommands.Add("vviewlist",
8905     "vviewlist [format={tree, long}]"
8906     " - prints current list of views per viewer and graphic_driver ID shared between viewers"
8907     " - format: format of result output, if tree the output is a tree view;"
8908     "otherwise it's a list of full view names. By default format = tree",
8909     __FILE__,VViewList,group);
8910   theCommands.Add("vhelp" ,
8911     "vhelp            : display help on the viewer commands",
8912     __FILE__,VHelp,group);
8913   theCommands.Add("vtop" ,
8914     "vtop or <T>      : Top view" ,
8915     __FILE__,VTop,group);
8916   theCommands.Add("vbottom" ,
8917     "vbottom          : Bottom view" ,
8918     __FILE__,VBottom,group);
8919   theCommands.Add("vleft" ,
8920     "vleft            : Left view" ,
8921     __FILE__,VLeft,group);
8922   theCommands.Add("vright" ,
8923     "vright           : Right view" ,
8924     __FILE__,VRight,group);
8925   theCommands.Add("vaxo" ,
8926     " vaxo or <A>     : Axonometric view ",
8927     __FILE__,VAxo,group);
8928   theCommands.Add("vfront" ,
8929     "vfront           : Front view" ,
8930     __FILE__,VFront,group);
8931   theCommands.Add("vback" ,
8932     "vback            : Back view" ,
8933     __FILE__,VBack,group);
8934   theCommands.Add("vpick" ,
8935     "vpick           : vpick X Y Z [shape subshape] ( all variables as string )",
8936     VPick,group);
8937   theCommands.Add("vfit"    ,
8938     "vfit or <F> [-selected]"
8939     "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
8940     __FILE__,VFit,group);
8941   theCommands.Add ("vfitarea",
8942     "vfitarea x1 y1 x2 y2"
8943     "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
8944     "\n\t\t: Fit view to show area located between two points"
8945     "\n\t\t: given in world 2D or 3D corrdinates.",
8946     __FILE__, VFitArea, group);
8947   theCommands.Add ("vzfit", "vzfit [scale]\n"
8948     "   Matches Z near, Z far view volume planes to the displayed objects.\n"
8949     "   \"scale\" - specifies factor to scale computed z range.\n",
8950     __FILE__, VZFit, group);
8951   theCommands.Add("vrepaint",
8952     "vrepaint        : vrepaint, force redraw",
8953     __FILE__,VRepaint,group);
8954   theCommands.Add("vclear",
8955     "vclear          : vclear",
8956     __FILE__,VClear,group);
8957   theCommands.Add("vsetbg",
8958     "vsetbg          : vsetbg imagefile [filltype] : Load image as background",
8959     __FILE__,VSetBg,group);
8960   theCommands.Add("vsetbgmode",
8961     "vsetbgmode      : vsetbgmode filltype : Change background image fill type",
8962     __FILE__,VSetBgMode,group);
8963   theCommands.Add("vsetgradientbg",
8964     "vsetgradientbg  : vsetgradientbg r1 g1 b1 r2 g2 b2 filltype : Mount gradient background",
8965     __FILE__,VSetGradientBg,group);
8966   theCommands.Add("vsetgrbgmode",
8967     "vsetgrbgmode    : vsetgrbgmode filltype : Change gradient background fill type",
8968     __FILE__,VSetGradientBgMode,group);
8969   theCommands.Add("vsetcolorbg",
8970     "vsetcolorbg     : vsetcolorbg r g b : Set background color",
8971     __FILE__,VSetColorBg,group);
8972   theCommands.Add("vsetdefaultbg",
8973     "vsetdefaultbg r g b\n"
8974     "\n\t\t: vsetdefaultbg r1 g1 b1 r2 g2 b2 fillmode"
8975     "\n\t\t: Set default viewer background fill color (flat/gradient).",
8976     __FILE__,VSetDefaultBg,group);
8977   theCommands.Add("vscale",
8978     "vscale          : vscale X Y Z",
8979     __FILE__,VScale,group);
8980   theCommands.Add("vzbufftrihedron",
8981             "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
8982     "\n\t\t:       [-position center|left_lower|left_upper|right_lower|right_upper]"
8983     "\n\t\t:       [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
8984     "\n\t\t:       [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
8985     "\n\t\t:       [-nbfacets value=12] [-colorLabels color=WHITE]"
8986     "\n\t\t: Displays a trihedron",
8987     __FILE__,VZBuffTrihedron,group);
8988   theCommands.Add("vrotate",
8989     "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
8990     "\n                : Option -mouseStart starts rotation according to the mouse position"
8991     "\n                : Option -mouseMove continues rotation with angle computed"
8992     "\n                : from last and new mouse position."
8993     "\n                : vrotate AX AY AZ [X Y Z]",
8994     __FILE__,VRotate,group);
8995   theCommands.Add("vzoom",
8996     "vzoom           : vzoom coef",
8997     __FILE__,VZoom,group);
8998   theCommands.Add("vpan",
8999     "vpan            : vpan dx dy",
9000     __FILE__,VPan,group);
9001   theCommands.Add("vexport",
9002     "vexport         : vexport full_file_path {PS | EPS | TEX | PDF | SVG | PGF | EMF }"
9003     " : exports the view to a vector file of a given format"
9004     " : notice that EMF format requires patched gl2ps",
9005     __FILE__,VExport,group);
9006   theCommands.Add("vcolorscale",
9007     "vcolorscale     : vcolorscale [-range RangeMin = 0 RangeMax = 100 Intervals = 10 -font HeightFont = 16  -textpos "
9008     "Position = left -xy X = 0 Y = 0] [-noupdate|-update]: draw color scale\n"
9009     "-demo/-demoversion draw a demoversion of color scale.\n"
9010     "-show/display display color scale.\n"
9011     "-hide/erase erase color scale.\n"
9012     "Please note that -show/-hide option must be the first argument!\n"
9013     "-color Index R G B: set color for indexed interval\n"
9014     "-color Index ColorName: set color for indexed interval\n"
9015     "-colors R G B R G B ...: set colors for all intervals\n"
9016     "-colors ColorName1 ColorName2 ...: set colors for all intervals\n"
9017     "-colors supports both color names and rgb values in one call\n"
9018     "-label Index Text: set label for indexed interval\n"
9019     "-labels Text Text Text ...: set labels for all intervals\n"
9020     "-title Title [Position]: set the title for color scale with certain position. Default position = center;\n"
9021     "Available text positions: left, right, center, none;\n",
9022     __FILE__,VColorScale,group);
9023   theCommands.Add("vgraduatedtrihedron",
9024     "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
9025     "\t[-namefont Name] [-valuesfont Name]\n"
9026     "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
9027     "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
9028     "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
9029     "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
9030     "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
9031     "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
9032     "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
9033     "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
9034     "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
9035     "\t[-drawgrid on/off] [-drawaxes on/off]\n"
9036     " - Displays or erases graduated trihedron"
9037     " - xname, yname, zname - names of axes, default: X, Y, Z\n"
9038     " - namefont - font of axes names. Default: Arial\n"
9039     " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
9040     " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
9041     " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
9042     " - valuesfont - font of axes values. Default: Arial\n"
9043     " - xcolor, ycolor, zcolor - color of axis and values\n"
9044     " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
9045     " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
9046     __FILE__,VGraduatedTrihedron,group);
9047   theCommands.Add("vprintview" ,
9048     "vprintview : width height filename [algo=0] [tile_width tile_height] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
9049     __FILE__,VPrintView,group);
9050   theCommands.Add("vzlayer",
9051     "vzlayer add/del/get/settings/enable/disable [id]\n"
9052     " add - add new z layer to viewer and print its id\n"
9053     " del - del z layer by its id\n"
9054     " get - print sequence of z layers in increasing order of their overlay level\n"
9055     " settings - print status of z layer settings\n"
9056     " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n"
9057     " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n"
9058     " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n"
9059     "\nWhere id is the layer identificator\n"
9060     "\nExamples:\n"
9061     "   vzlayer add\n"
9062     "   vzlayer enable poffset 1\n"
9063     "   vzlayer disable depthtest 1\n"
9064     "   vzlayer del 1\n",
9065     __FILE__,VZLayer,group);
9066   theCommands.Add("voverlaytext",
9067     "voverlaytext : text x y [height] [font_name] [text_color: R G B] [display_type] [background_color: R G B]"
9068     " : height - pixel height of the text (default=10.0)"
9069     " : font_name - name of font (default=courier)"
9070     " : text_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0) "
9071     " : display_type = {normal/subtitle/decal/blend}, (default=normal) "
9072     " : background_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0), the parameter is defined for subtitle and decal display types ",
9073     __FILE__,VOverlayText,group);
9074   theCommands.Add("vlayerline",
9075     "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
9076     __FILE__,VLayerLine,group);
9077   theCommands.Add ("vgrid",
9078     "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]"
9079     " : Mode - rectangular or circular"
9080     " : Type - lines or points",
9081     __FILE__, VGrid, group);
9082   theCommands.Add ("vpriviledgedplane",
9083     "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
9084     "\n\t\t:   Ox, Oy, Oz - plane origin"
9085     "\n\t\t:   Nx, Ny, Nz - plane normal direction"
9086     "\n\t\t:   Xx, Xy, Xz - plane x-reference axis direction"
9087     "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
9088     __FILE__, VPriviledgedPlane, group);
9089   theCommands.Add ("vconvert",
9090     "vconvert v [Mode={window|view}]"
9091     "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
9092     "\n\t\t: vconvert x y z [Mode={window|grid}]"
9093     "\n\t\t:   window - convert to window coordinates, pixels"
9094     "\n\t\t:   view   - convert to view projection plane"
9095     "\n\t\t:   grid   - convert to model coordinates, given on grid"
9096     "\n\t\t:   ray    - convert projection ray to model coordiantes"
9097     "\n\t\t: - vconvert v window : convert view to window;"
9098     "\n\t\t: - vconvert v view   : convert window to view;"
9099     "\n\t\t: - vconvert x y window : convert view to window;"
9100     "\n\t\t: - vconvert x y view : convert window to view;"
9101     "\n\t\t: - vconvert x y : convert window to model;"
9102     "\n\t\t: - vconvert x y grid : convert window to model using grid;"
9103     "\n\t\t: - vconvert x y ray : convert window projection line to model;"
9104     "\n\t\t: - vconvert x y z window : convert model to window;"
9105     "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
9106     "\n\t\t: Converts the given coordinates to window/view/model space.",
9107     __FILE__, VConvert, group);
9108   theCommands.Add ("vfps",
9109     "vfps [framesNb=100] : estimate average frame rate for active view",
9110     __FILE__, VFps, group);
9111   theCommands.Add ("vgldebug",
9112             "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
9113     "\n\t\t:          [-extraMsg {0|1}] [{0|1}]"
9114     "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
9115     "\n\t\t: Debug context can be requested only on Windows"
9116     "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
9117     "\n\t\t:  -sync     - request synchronized debug GL context"
9118     "\n\t\t:  -glslWarn - log GLSL compiler/linker warnings,"
9119     "\n\t\t:              which are suppressed by default,"
9120     "\n\t\t:  -extraMsg - log extra diagnostic messages from GL context,"
9121     "\n\t\t:              which are suppressed by default",
9122     __FILE__, VGlDebug, group);
9123   theCommands.Add ("vvbo",
9124     "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
9125     __FILE__, VVbo, group);
9126   theCommands.Add ("vstereo",
9127             "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
9128     "\n\t\t:         [-anaglyph Filter]"
9129     "\n\t\t: Control stereo output mode. Available modes for -mode:"
9130     "\n\t\t:  quadBuffer        - OpenGL QuadBuffer stereo,"
9131     "\n\t\t:                     requires driver support."
9132     "\n\t\t:                     Should be called BEFORE vinit!"
9133     "\n\t\t:  anaglyph         - Anaglyph glasses"
9134     "\n\t\t:  rowInterlaced    - row-interlaced display"
9135     "\n\t\t:  columnInterlaced - column-interlaced display"
9136     "\n\t\t:  chessBoard       - chess-board output"
9137     "\n\t\t:  sideBySide       - horizontal pair"
9138     "\n\t\t:  overUnder        - vertical   pair"
9139     "\n\t\t: Available Anaglyph filters for -anaglyph:"
9140     "\n\t\t:  redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
9141     "\n\t\t:  greenMagentaSimple",
9142     __FILE__, VStereo, group);
9143   theCommands.Add ("vcaps",
9144             "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
9145     "\n\t\t:       [-compatibleContext {0|1}]"
9146     "\n\t\t:       [-vsync {0|1}]"
9147     "\n\t\t:       [-quadBuffer {0|1}] [-stereo {0|1}]"
9148     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
9149     "\n\t\t: Modify particular graphic driver options:"
9150     "\n\t\t:  FFP      - use fixed-function pipeline instead of"
9151     "\n\t\t:             built-in GLSL programs"
9152     "\n\t\t:            (requires compatible profile)"
9153     "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
9154     "\n\t\t:             arrays to GPU memory)"
9155     "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
9156     "\n\t\t:  vsync    - switch VSync on or off"
9157     "\n\t\t: Context creation options:"
9158     "\n\t\t:  softMode          - software OpenGL implementation"
9159     "\n\t\t:  compatibleProfile - backward-compatible profile"
9160     "\n\t\t:  quadbuffer        - QuadBuffer"
9161     "\n\t\t: Unlike vrenderparams, these parameters control alternative"
9162     "\n\t\t: rendering paths producing the same visual result when"
9163     "\n\t\t: possible."
9164     "\n\t\t: Command is intended for testing old hardware compatibility.",
9165     __FILE__, VCaps, group);
9166   theCommands.Add ("vmemgpu",
9167     "vmemgpu [f]: print system-dependent GPU memory information if available;"
9168     " with f option returns free memory in bytes",
9169     __FILE__, VMemGpu, group);
9170   theCommands.Add ("vreadpixel",
9171     "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
9172     " : Read pixel value for active view",
9173     __FILE__, VReadPixel, group);
9174   theCommands.Add("diffimage",
9175     "diffimage     : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
9176     __FILE__, VDiffImage, group);
9177   theCommands.Add ("vselect",
9178     "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [shift_selection = 0|1]\n"
9179     "- emulates different types of selection:\n"
9180     "- 1) single click selection\n"
9181     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
9182     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
9183     "- 4) -allowoverlap determines will partially included objects be selected in rectangular selection"
9184     " (partial inclusion - overlap - is not allowed by default)\n"
9185     "- 5) any of these selections with shift button pressed",
9186     __FILE__, VSelect, group);
9187   theCommands.Add ("vmoveto",
9188     "vmoveto x y"
9189     "- emulates cursor movement to pixel postion (x,y)",
9190     __FILE__, VMoveTo, group);
9191   theCommands.Add ("vviewparams", "vviewparams usage:\n"
9192     "- vviewparams\n"
9193     "- vviewparams [-scale [s]] [-eye [x y z]] [-at [x y z]] [-up [x y z]]\n"
9194     "              [-proj [x y z]] [-center x y] [-size sx]\n"
9195     "-   Gets or sets current view parameters.\n"
9196     "-   If called without arguments, all view parameters are printed.\n"
9197     "-   The options are:\n"
9198     "      -scale [s]    : prints or sets viewport relative scale.\n"
9199     "      -eye [x y z]  : prints or sets eye location.\n"
9200     "      -at [x y z]   : prints or sets center of look.\n"
9201     "      -up [x y z]   : prints or sets direction of up vector.\n"
9202     "      -proj [x y z] : prints or sets direction of look.\n"
9203     "      -center x y   : sets location of center of the screen in pixels.\n"
9204     "      -size [sx]    : prints viewport projection width and height sizes\n"
9205     "                    : or changes the size of its maximum dimension.\n",
9206     __FILE__, VViewParams, group);
9207   theCommands.Add("vchangeselected",
9208     "vchangeselected shape"
9209     "- adds to shape to selection or remove one from it",
9210                 __FILE__, VChangeSelected, group);
9211   theCommands.Add("vzclipping",
9212     "vzclipping [mode] [depth width]\n"
9213     "- mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]\n"
9214     "- gets or sets ZClipping mode, width and depth",
9215     __FILE__,VZClipping,group);
9216   theCommands.Add ("vnbselected",
9217     "vnbselected", __FILE__, VNbSelected, group);
9218   theCommands.Add ("vcamera",
9219               "vcamera [-ortho] [-projtype]"
9220       "\n\t\t:         [-persp]"
9221       "\n\t\t:         [-fovy   [Angle]] [-distance [Distance]]"
9222       "\n\t\t:         [-stereo] [-leftEye] [-rightEye]"
9223       "\n\t\t:         [-iod [Distance]] [-iodType    [absolute|relative]]"
9224       "\n\t\t:         [-zfocus [Value]] [-zfocusType [absolute|relative]]"
9225       "\n\t\t: Manage camera parameters."
9226       "\n\t\t: Prints current value when option called without argument."
9227       "\n\t\t: Orthographic camera:"
9228       "\n\t\t:   -ortho      activate orthographic projection"
9229       "\n\t\t: Perspective camera:"
9230       "\n\t\t:   -persp      activate perspective  projection (mono)"
9231       "\n\t\t:   -fovy       field of view in y axis, in degrees"
9232       "\n\t\t:   -distance   distance of eye from camera center"
9233       "\n\t\t: Stereoscopic camera:"
9234       "\n\t\t:   -stereo     perspective  projection (stereo)"
9235       "\n\t\t:   -leftEye    perspective  projection (left  eye)"
9236       "\n\t\t:   -rightEye   perspective  projection (right eye)"
9237       "\n\t\t:   -iod        intraocular distance value"
9238       "\n\t\t:   -iodType    distance type, absolute or relative"
9239       "\n\t\t:   -zfocus     stereographic focus value"
9240       "\n\t\t:   -zfocusType focus type, absolute or relative",
9241     __FILE__, VCamera, group);
9242   theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
9243     "- vautozfit [on={1|0}] [scale]\n"
9244     "    Prints or changes parameters of automatic z-fit mode:\n"
9245     "   \"on\" - turns automatic z-fit on or off\n"
9246     "   \"scale\" - specifies factor to scale computed z range.\n",
9247     __FILE__, VAutoZFit, group);
9248   theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
9249     "   vzrange                - without parameters shows current values\n"
9250     "   vzrange [znear] [zfar] - applies provided values to view",
9251     __FILE__,VZRange, group);
9252   theCommands.Add("vantialiasing",
9253     "vantialiasing 1|0",
9254     __FILE__,VAntialiasing,group);
9255   theCommands.Add ("vpurgedisplay",
9256     "vpurgedisplay"
9257     "- removes structures which don't belong to objects displayed in neutral point",
9258     __FILE__, VPurgeDisplay, group);
9259   theCommands.Add("vsetviewsize",
9260     "vsetviewsize size",
9261     __FILE__,VSetViewSize,group);
9262   theCommands.Add("vmoveview",
9263     "vmoveview Dx Dy Dz [Start = 1|0]",
9264     __FILE__,VMoveView,group);
9265   theCommands.Add("vtranslateview",
9266     "vtranslateview Dx Dy Dz [Start = 1|0)]",
9267     __FILE__,VTranslateView,group);
9268   theCommands.Add("vturnview",
9269     "vturnview Ax Ay Az [Start = 1|0]",
9270     __FILE__,VTurnView,group);
9271   theCommands.Add("vtextureenv",
9272     "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
9273     "or user-defined file and optionally applying texture mapping parameters\n"
9274     "                  Usage:\n"
9275     "                  vtextureenv off - disables environment mapping\n"
9276     "                  vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
9277     "                              std_texture = (0..7)\n"
9278     "                              rep         = {clamp|repeat}\n"
9279     "                              mod         = {decal|modulate}\n"
9280     "                              flt         = {nearest|bilinear|trilinear}\n"
9281     "                              ss, st      - scale factors for s and t texture coordinates\n"
9282     "                              ts, tt      - translation for s and t texture coordinates\n"
9283     "                              rot         - texture rotation angle in degrees",
9284     __FILE__, VTextureEnv, group);
9285   theCommands.Add("vhlr" ,
9286     "is_enabled={on|off} [show_hidden={1|0}]"
9287     " - Hidden line removal algorithm:"
9288     " - is_enabled: if is on HLR algorithm is applied\n"
9289     " - show_hidden: if equals to 1, hidden lines are drawn as dotted ones.\n",
9290     __FILE__,VHLR,group);
9291   theCommands.Add("vhlrtype" ,
9292     "algo_type={algo|polyalgo} [shape_1 ... shape_n]"
9293     " - Changes the type of HLR algorithm using for shapes."
9294     " - algo_type: if equals to algo, exact HLR algorithm is applied;\n"
9295     "   if equals to polyalgo, polygonal HLR algorithm is applied."
9296     "If shapes are not given HLR algoithm of given type is applied"
9297     " to all shapes in the view\n",
9298     __FILE__,VHLRType,group);
9299   theCommands.Add("vclipplane", "vclipplane usage: \n"
9300     "  maxplanes <view_name> - get plane limit for view.\n"
9301     "  create <plane_name> - create new plane.\n"
9302     "  delete <plane_name> - delete plane.\n"
9303     "  clone <source_plane> <plane_name> - clone the plane definition.\n"
9304     "  set/unset <plane_name> object <object list> - set/unset plane for IO.\n"
9305     "  set/unset <plane_name> view <view list> - set/unset plane for view.\n"
9306     "  change <plane_name> on/off - turn clipping on/off.\n"
9307     "  change <plane_name> equation <a> <b> <c> <d> - change plane equation.\n"
9308     "  change <plane_name> capping on/off - turn capping on/off.\n"
9309     "  change <plane_name> capping color <r> <g> <b> - set color.\n"
9310     "  change <plane name> capping texname <texture> - set texture.\n"
9311     "  change <plane_name> capping texscale <sx> <sy> - set tex scale.\n"
9312     "  change <plane_name> capping texorigin <tx> <ty> - set tex origin.\n"
9313     "  change <plane_name> capping texrotate <angle> - set tex rotation.\n"
9314     "  change <plane_name> capping hatch on/off/<id> - set hatching mask.\n"
9315     "  please use VSetTextureMode command to enable texture rendering in view.\n"
9316     , __FILE__, VClipPlane, group);
9317   theCommands.Add("vsettexturemode", "vsettexturemode view_name mode \n"
9318     "  mode can be:\n"
9319     "  0 - no textures enabled in view.\n"
9320     "  1 - only environment textures enabled.\n"
9321     "  2 - all textures enabled.\n"
9322     "  this command sets texture details mode for the specified view.\n"
9323     , __FILE__, VSetTextureMode, group);
9324   theCommands.Add("vdefaults",
9325                "vdefaults [-absDefl value]"
9326        "\n\t\t:           [-devCoeff value]"
9327        "\n\t\t:           [-angDefl value]"
9328        "\n\t\t:           [-autoTriang {off/on | 0/1}]"
9329     , __FILE__, VDefaults, group);
9330   theCommands.Add("vlight",
9331     "tool to manage light sources, without arguments shows list of lights."
9332     "\n    Main commands: "
9333     "\n      'clear' to clear lights"
9334     "\n      '{def}aults' to load deafault lights"
9335     "\n      'add' (or 'new') <type> to add any light source"
9336     "\n          where <type> is one of {amb}ient|directional|{spot}light|positional"
9337     "\n      'change' <lightId> to edit light source with specified lightId"
9338     "\n\n      In addition to 'add' and 'change' commands you can use light parameters:"
9339     "\n        {pos}ition X Y Z"
9340     "\n        {dir}ection X Y Z (for directional light or for spotlight)"
9341     "\n        color colorName"
9342     "\n        {head}light 0|1"
9343     "\n        {sm}oothness value"
9344     "\n        {int}ensity value"
9345     "\n        {constAtten}uation value"
9346     "\n        {linearAtten}uation value"
9347     "\n        angle angleDeg"
9348     "\n        {spotexp}onent value"
9349     "\n        local|global"
9350     "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
9351     "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
9352     __FILE__, VLight, group);
9353   theCommands.Add("vraytrace",
9354             "vraytrace [0|1]"
9355     "\n\t\t: Turns on/off ray-tracing renderer."
9356     "\n\t\t:   'vraytrace 0' alias for 'vrenderparams -raster'."
9357     "\n\t\t:   'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
9358     __FILE__, VRenderParams, group);
9359   theCommands.Add("vrenderparams",
9360     "\n    Manages rendering parameters: "
9361     "\n      '-rayTrace'             Enables  GPU ray-tracing"
9362     "\n      '-raster'               Disables GPU ray-tracing"
9363     "\n      '-rayDepth     0..10'   Defines maximum ray-tracing depth"
9364     "\n      '-shadows      on|off'  Enables/disables shadows rendering"
9365     "\n      '-reflections  on|off'  Enables/disables specular reflections"
9366     "\n      '-fsaa         on|off'  Enables/disables adaptive anti-aliasing"
9367     "\n      '-gleam        on|off'  Enables/disables transparency shadow effects"
9368     "\n      '-gi           on|off'  Enables/disables global illumination effects"
9369     "\n      '-brng         on|off'  Enables/disables blocked RNG (fast coherent PT)"
9370     "\n      '-env          on|off'  Enables/disables environment map background"
9371     "\n      '-shadingModel model'   Controls shading model from enumeration"
9372     "\n                              color, flat, gouraud, phong"
9373     "\n    Unlike vcaps, these parameters dramatically change visual properties."
9374     "\n    Command is intended to control presentation quality depending on"
9375     "\n    hardware capabilities and performance.",
9376     __FILE__, VRenderParams, group);
9377   theCommands.Add("vfrustumculling",
9378     "vfrustumculling [toEnable]: enables/disables objects clipping",
9379     __FILE__,VFrustumCulling,group);
9380   theCommands.Add("vhighlightselected",
9381     "vhighlightselected [0|1] or vhighlightselected [on|off]: enables/disables highlighting of selected objects.\n"
9382     "Without arguments it shows if highlighting of selected objects is enabled now.",
9383     __FILE__,VHighlightSelected,group);
9384   theCommands.Add ("vplace",
9385             "vplace dx dy"
9386     "\n\t\t: Places the point (in pixels) at the center of the window",
9387     __FILE__, VPlace, group);
9388   theCommands.Add("vxrotate",
9389     "vxrotate",
9390     __FILE__,VXRotate,group);
9391
9392 #if defined(_WIN32)
9393   theCommands.Add("vprogressive",
9394     "vprogressive",
9395     __FILE__, VProgressiveMode, group);
9396 #endif
9397 }