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