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