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