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