0021802: Not all names are transferred from STEP to IGES via XDE
[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         VT_ProcessKeyPress (c);
2017       }
2018       break;
2019
2020     case WM_LBUTTONUP:
2021     case WM_MBUTTONUP:
2022     case WM_RBUTTONUP:
2023       Up = 1;
2024       VT_ProcessButton3Release();
2025       break;
2026
2027     case WM_LBUTTONDOWN:
2028     case WM_MBUTTONDOWN:
2029     case WM_RBUTTONDOWN:
2030       {
2031         WPARAM fwKeys = wParam;
2032
2033         Up = 0;
2034
2035         X_ButtonPress = LOWORD(lParam);
2036         Y_ButtonPress = HIWORD(lParam);
2037
2038         if (Msg == WM_LBUTTONDOWN)
2039         {
2040           if (fwKeys & MK_CONTROL)
2041           {
2042             Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
2043           }
2044           else
2045           {
2046             VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT));
2047           }
2048         }
2049         else if (Msg == WM_RBUTTONDOWN)
2050         {
2051           // Start rotation
2052           VT_ProcessButton3Press();
2053         }
2054       }
2055       break;
2056
2057     case WM_MOUSEMOVE:
2058       {
2059         //cout << "\t WM_MOUSEMOVE" << endl;
2060         WPARAM fwKeys = wParam;
2061         X_Motion = LOWORD(lParam);
2062         Y_Motion = HIWORD(lParam);
2063
2064         if ( Up &&
2065           fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON ) ) {
2066             Up = 0;
2067             X_ButtonPress = LOWORD(lParam);
2068             Y_ButtonPress = HIWORD(lParam);
2069
2070             if ( fwKeys & MK_RBUTTON ) {
2071               // Start rotation
2072               VT_ProcessButton3Press();
2073             }
2074           }
2075
2076           if ( fwKeys & MK_CONTROL ) {
2077             if ( fwKeys & MK_LBUTTON ) {
2078               ProcessControlButton1Motion();
2079             }
2080             else if ( fwKeys & MK_MBUTTON ||
2081               ((fwKeys&MK_LBUTTON) &&
2082               (fwKeys&MK_RBUTTON) ) ){
2083                 VT_ProcessControlButton2Motion();
2084               }
2085             else if ( fwKeys & MK_RBUTTON ) {
2086               VT_ProcessControlButton3Motion();
2087             }
2088           }
2089 #ifdef BUG
2090           else if ( fwKeys & MK_SHIFT ) {
2091             if ( fwKeys & MK_MBUTTON ||
2092               ((fwKeys&MK_LBUTTON) &&
2093               (fwKeys&MK_RBUTTON) ) ) {
2094                 cout << "ProcessZClipMotion()" << endl;
2095                 ProcessZClipMotion();
2096               }
2097           }
2098 #endif
2099           else if (GetWindowHandle (VT_GetWindow()) == hwnd)
2100           {
2101             if ((fwKeys & MK_MBUTTON
2102             || ((fwKeys & MK_LBUTTON) && (fwKeys & MK_RBUTTON))))
2103             {
2104               ProcessZClipMotion();
2105             }
2106             else
2107             {
2108               VT_ProcessMotion();
2109             }
2110           }
2111       }
2112       break;
2113
2114     default:
2115       return( DefWindowProc( hwnd, Msg, wParam, lParam ));
2116     }
2117     return 0L;
2118   }
2119
2120   return DefWindowProc( hwnd, Msg, wParam, lParam );
2121 }
2122
2123
2124
2125
2126 //==============================================================================
2127 //function : ViewerMainLoop
2128 //purpose  : Get a Event on the view and dispatch it
2129 //==============================================================================
2130
2131
2132 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2133 {
2134   Ppick = (argc > 0)? 1 : 0;
2135   Pargc = argc;
2136   Pargv = argv;
2137
2138   if ( Ppick ) {
2139     MSG msg;
2140     msg.wParam = 1;
2141
2142     cout << "Start picking" << endl;
2143
2144     while ( Ppick == 1 ) {
2145       // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2146       if (GetMessage(&msg, NULL, 0, 0) ) {
2147         TranslateMessage(&msg);
2148         DispatchMessage(&msg);
2149       }
2150     }
2151
2152     cout << "Picking done" << endl;
2153   }
2154
2155   return Ppick;
2156 }
2157
2158 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
2159
2160 int min( int a, int b )
2161 {
2162   if( a<b )
2163     return a;
2164   else
2165     return b;
2166 }
2167
2168 int max( int a, int b )
2169 {
2170   if( a>b )
2171     return a;
2172   else
2173     return b;
2174 }
2175
2176 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2177
2178 {
2179   static XEvent aReport;
2180   Standard_Boolean pick = argc > 0;
2181   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2182   XNextEvent (aDisplay, &aReport);
2183
2184   // Handle event for the chosen display connection
2185   switch (aReport.type) {
2186       case ClientMessage:
2187         {
2188           if((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2189           {
2190             // Close the window
2191             ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2192           }
2193         }
2194         return 0;
2195      case FocusIn:
2196       {
2197          // Activate inactive view
2198          Window aWindow = GetWindowHandle(VT_GetWindow());
2199          if(aWindow != aReport.xfocus.window)
2200          {
2201            ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2202          }
2203       }
2204       break;
2205       case Expose:
2206         {
2207           VT_ProcessExpose();
2208         }
2209         break;
2210       case ConfigureNotify:
2211         {
2212           VT_ProcessConfigure();
2213         }
2214         break;
2215       case KeyPress:
2216         {
2217
2218           KeySym ks_ret ;
2219           char buf_ret[11] ;
2220           int ret_len ;
2221           XComposeStatus status_in_out;
2222
2223           ret_len = XLookupString( ( XKeyEvent *)&aReport ,
2224             (char *) buf_ret , 10 ,
2225             &ks_ret , &status_in_out ) ;
2226
2227
2228           buf_ret[ret_len] = '\0' ;
2229
2230           if (ret_len)
2231           {
2232             VT_ProcessKeyPress (buf_ret);
2233           }
2234         }
2235         break;
2236       case ButtonPress:
2237         {
2238           X_ButtonPress = aReport.xbutton.x;
2239           Y_ButtonPress = aReport.xbutton.y;
2240
2241           if (aReport.xbutton.button == Button1)
2242           {
2243             if (aReport.xbutton.state & ControlMask)
2244             {
2245               pick = VT_ProcessButton1Press (argc, argv, pick, (aReport.xbutton.state & ShiftMask));
2246             }
2247             else
2248             {
2249               IsDragged = Standard_True;
2250               DragFirst = Standard_True;
2251             }
2252           }
2253           else if (aReport.xbutton.button == Button3)
2254           {
2255             // Start rotation
2256             VT_ProcessButton3Press();
2257           }
2258         }
2259         break;
2260       case ButtonRelease:
2261         {
2262           if( IsDragged )
2263           {
2264             if( !DragFirst )
2265             {
2266               Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2267               GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2268               XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2269             }
2270
2271             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
2272             if( aContext.IsNull() )
2273             {
2274               cout << "The context is null. Please use vinit before createmesh" << endl;
2275               return 0;
2276             }
2277
2278             Standard_Boolean ShiftPressed = ( aReport.xbutton.state & ShiftMask );
2279             if( aReport.xbutton.button==1 )
2280               if( DragFirst )
2281                 if( ShiftPressed )
2282                 {
2283                   aContext->ShiftSelect();
2284                 }
2285                 else
2286                 {
2287                   aContext->Select();
2288                 }
2289               else
2290                 if( ShiftPressed )
2291                 {
2292                   aContext->ShiftSelect( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2293                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2294                     ViewerTest::CurrentView());
2295                 }
2296                 else
2297                 {
2298                   aContext->Select( min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ),
2299                     max( X_ButtonPress, X_Motion ), max( Y_ButtonPress, Y_Motion ),
2300                     ViewerTest::CurrentView() );
2301                 }
2302             else
2303               VT_ProcessButton3Release();
2304
2305             IsDragged = Standard_False;
2306           }
2307           else
2308             VT_ProcessButton3Release();
2309         }
2310         break;
2311       case MotionNotify:
2312         {
2313           if (GetWindowHandle (VT_GetWindow()) != aReport.xmotion.window)
2314           {
2315             break;
2316           }
2317           if( IsDragged )
2318           {
2319             Aspect_Handle aWindow = VT_GetWindow()->XWindow();
2320             GC gc = XCreateGC( aDisplay, aWindow, 0, 0 );
2321             XSetFunction( aDisplay, gc, GXinvert );
2322
2323             if( !DragFirst )
2324               XDrawRectangle(aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2325
2326             X_Motion = aReport.xmotion.x;
2327             Y_Motion = aReport.xmotion.y;
2328             DragFirst = Standard_False;
2329
2330             XDrawRectangle( aDisplay, aWindow, gc, min( X_ButtonPress, X_Motion ), min( Y_ButtonPress, Y_Motion ), abs( X_Motion-X_ButtonPress ), abs( Y_Motion-Y_ButtonPress ) );
2331           }
2332           else
2333           {
2334             X_Motion = aReport.xmotion.x;
2335             Y_Motion = aReport.xmotion.y;
2336
2337             // remove all the ButtonMotionMaskr
2338             while( XCheckMaskEvent( aDisplay, ButtonMotionMask, &aReport) ) ;
2339
2340             if ( ZClipIsOn && aReport.xmotion.state & ShiftMask ) {
2341               if ( Abs(X_Motion - X_ButtonPress) > 2 ) {
2342
2343                 Quantity_Length VDX, VDY;
2344
2345                 ViewerTest::CurrentView()->Size(VDX,VDY);
2346                 Standard_Real VDZ =0 ;
2347                 VDZ = ViewerTest::CurrentView()->ZSize();
2348
2349                 printf("%f,%f,%f\n", VDX, VDY, VDZ);
2350
2351                 Quantity_Length dx = 0 ;
2352                 dx = ViewerTest::CurrentView()->Convert(X_Motion - X_ButtonPress);
2353
2354                 cout << dx << endl;
2355
2356                 dx = dx / VDX * VDZ;
2357
2358                 cout << dx << endl;
2359
2360                 ViewerTest::CurrentView()->Redraw();
2361               }
2362             }
2363
2364             if ( aReport.xmotion.state & ControlMask ) {
2365               if ( aReport.xmotion.state & Button1Mask ) {
2366                 ProcessControlButton1Motion();
2367               }
2368               else if ( aReport.xmotion.state & Button2Mask ) {
2369                 VT_ProcessControlButton2Motion();
2370               }
2371               else if ( aReport.xmotion.state & Button3Mask ) {
2372                 VT_ProcessControlButton3Motion();
2373               }
2374             }
2375             else
2376             {
2377               VT_ProcessMotion();
2378             }
2379           }
2380         }
2381         break;
2382 }
2383 return pick;
2384 }
2385
2386 //==============================================================================
2387 //function : VProcessEvents
2388 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
2389 //       event in the Viewer window
2390 //==============================================================================
2391
2392 static void VProcessEvents(ClientData,int)
2393 {
2394   NCollection_Vector<int> anEventNumbers;
2395   // Get number of messages from every display
2396   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2397        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next())
2398   {
2399     anEventNumbers.Append(XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()));
2400   }
2401     // Handle events for every display
2402   int anEventIter = 0;
2403   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2404        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next(), anEventIter++)
2405   {
2406     for (int i = 0; i < anEventNumbers.Value(anEventIter) &&
2407          XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()) > 0; ++i)
2408     {
2409       SetDisplayConnection (anIter.Key2()->GetDisplayConnection());
2410       int anEventResult = ViewerMainLoop( 0, NULL);
2411       // If window is closed or context was not found finish current event processing loop
2412       if (!anEventResult)
2413         return;
2414     }
2415   }
2416
2417   SetDisplayConnection (ViewerTest::GetAISContext()->CurrentViewer()->Driver()->GetDisplayConnection());
2418
2419 }
2420 #endif
2421
2422 //==============================================================================
2423 //function : OSWindowSetup
2424 //purpose  : Setup for the X11 window to be able to cath the event
2425 //==============================================================================
2426
2427
2428 static void OSWindowSetup()
2429 {
2430 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2431   // X11
2432
2433   Window  window   = VT_GetWindow()->XWindow();
2434   SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2435   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2436   XSynchronize(aDisplay, 1);
2437
2438   // X11 : For keyboard on SUN
2439   XWMHints wmhints;
2440   wmhints.flags = InputHint;
2441   wmhints.input = 1;
2442
2443   XSetWMHints( aDisplay, window, &wmhints);
2444
2445   XSelectInput( aDisplay, window,  ExposureMask | KeyPressMask |
2446     ButtonPressMask | ButtonReleaseMask |
2447     StructureNotifyMask |
2448     PointerMotionMask |
2449     Button1MotionMask | Button2MotionMask |
2450     Button3MotionMask | FocusChangeMask
2451     );
2452   Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
2453   XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
2454
2455   XSynchronize(aDisplay, 0);
2456
2457 #else
2458   // WNT
2459 #endif
2460
2461 }
2462
2463
2464 //==============================================================================
2465 //function : VFit
2466
2467 //purpose  : Fitall, no DRAW arguments
2468 //Draw arg : No args
2469 //==============================================================================
2470
2471 static int VFit(Draw_Interpretor& , Standard_Integer , const char** )
2472 {
2473   const Handle(V3d_View) aView = ViewerTest::CurrentView();
2474   Handle(NIS_View) V = Handle(NIS_View)::DownCast(aView);
2475   if (V.IsNull() == Standard_False) {
2476     V->FitAll3d();
2477   } else if (aView.IsNull() == Standard_False) {
2478     aView->FitAll();
2479   }
2480   return 0;
2481 }
2482
2483 //==============================================================================
2484 //function : VZFit
2485 //purpose  : ZFitall, no DRAW arguments
2486 //Draw arg : No args
2487 //==============================================================================
2488 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2489 {
2490   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2491
2492   if (aCurrentView.IsNull())
2493   {
2494     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
2495     return 1;
2496   }
2497
2498   if (theArgsNb == 1)
2499   {
2500     aCurrentView->View()->ZFitAll();
2501     aCurrentView->Redraw();
2502     return 0;
2503   }
2504
2505   Standard_Real aScale = 1.0;
2506
2507   if (theArgsNb >= 2)
2508   {
2509     aScale = Draw::Atoi (theArgVec[1]);
2510   }
2511
2512   aCurrentView->View()->ZFitAll (aScale);
2513   aCurrentView->Redraw();
2514
2515   return 0;
2516 }
2517
2518 //==============================================================================
2519 //function : VRepaint
2520 //purpose  :
2521 //==============================================================================
2522 static int VRepaint (Draw_Interpretor& , Standard_Integer , const char** )
2523 {
2524   Handle(V3d_View) V = ViewerTest::CurrentView();
2525   if ( !V.IsNull() ) V->Redraw(); return 0;
2526 }
2527
2528 //==============================================================================
2529 //function : VClear
2530 //purpose  : Remove all the object from the viewer
2531 //Draw arg : No args
2532 //==============================================================================
2533
2534 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2535 {
2536   Handle(V3d_View) V = ViewerTest::CurrentView();
2537   if(!V.IsNull())
2538     ViewerTest::Clear();
2539   return 0;
2540 }
2541
2542 //==============================================================================
2543 //function : VPick
2544 //purpose  :
2545 //==============================================================================
2546
2547 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2548 { if (ViewerTest::CurrentView().IsNull() ) return 1;
2549
2550 if ( argc < 4 ) {
2551   di << argv[0] << "Invalid number of arguments" << "\n";
2552   return 1;
2553 }
2554
2555 while (ViewerMainLoop( argc, argv)) {
2556 }
2557
2558 return 0;
2559 }
2560
2561 //==============================================================================
2562 //function : VSetBg
2563 //purpose  : Load image as background
2564 //==============================================================================
2565
2566 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2567 {
2568   if (argc < 2 || argc > 3)
2569   {
2570     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background" << "\n";
2571     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2572     return 1;
2573   }
2574
2575   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2576   if(AISContext.IsNull())
2577   {
2578     di << "use 'vinit' command before " << argv[0] << "\n";
2579     return 1;
2580   }
2581
2582   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
2583   if (argc == 3)
2584   {
2585     const char* szType = argv[2];
2586     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2587     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2588     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2589     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2590     else
2591     {
2592       di << "Wrong fill type : " << szType << "\n";
2593       di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2594       return 1;
2595     }
2596   }
2597
2598   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2599   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
2600
2601   return 0;
2602 }
2603
2604 //==============================================================================
2605 //function : VSetBgMode
2606 //purpose  : Change background image fill type
2607 //==============================================================================
2608
2609 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2610 {
2611   if (argc != 2)
2612   {
2613     di << "Usage : " << argv[0] << " filltype : Change background image mode" << "\n";
2614     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2615     return 1;
2616   }
2617
2618   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2619   if(AISContext.IsNull())
2620   {
2621     di << "use 'vinit' command before " << argv[0] << "\n";
2622     return 1;
2623   }
2624   Aspect_FillMethod aFillType = Aspect_FM_NONE;
2625   const char* szType = argv[1];
2626   if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
2627   else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
2628   else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
2629   else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
2630   else
2631   {
2632     di << "Wrong fill type : " << szType << "\n";
2633     di << "Must be one of CENTERED, TILED, STRETCH, NONE" << "\n";
2634     return 1;
2635   }
2636   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2637   V3dView->SetBgImageStyle(aFillType, Standard_True);
2638   return 0;
2639 }
2640
2641 //==============================================================================
2642 //function : VSetGradientBg
2643 //purpose  : Mount gradient background
2644 //==============================================================================
2645 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2646 {
2647   if (argc != 8 )
2648   {
2649     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background" << "\n";
2650     di << "R1,G1,B1,R2,G2,B2 = [0..255]" << "\n";
2651     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2652     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2653     return 1;
2654   }
2655
2656   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2657   if(AISContext.IsNull())
2658   {
2659     di << "use 'vinit' command before " << argv[0] << "\n";
2660     return 1;
2661   }
2662   if (argc == 8)
2663   {
2664
2665     Standard_Real R1 = Draw::Atof(argv[1])/255.;
2666     Standard_Real G1 = Draw::Atof(argv[2])/255.;
2667     Standard_Real B1 = Draw::Atof(argv[3])/255.;
2668     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
2669
2670     Standard_Real R2 = Draw::Atof(argv[4])/255.;
2671     Standard_Real G2 = Draw::Atof(argv[5])/255.;
2672     Standard_Real B2 = Draw::Atof(argv[6])/255.;
2673
2674     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
2675     int aType = Draw::Atoi(argv[7]);
2676     if( aType < 0 || aType > 8 )
2677     {
2678       di << "Wrong fill type " << "\n";
2679       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2680       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2681       return 1;
2682     }
2683
2684     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2685
2686     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2687     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
2688   }
2689
2690   return 0;
2691 }
2692
2693 //==============================================================================
2694 //function : VSetGradientBgMode
2695 //purpose  : Change gradient background fill style
2696 //==============================================================================
2697 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2698 {
2699   if (argc != 2 )
2700   {
2701     di << "Usage : " << argv[0] << " Type : Change gradient background fill type" << "\n";
2702     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2703     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2704     return 1;
2705   }
2706
2707   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2708   if(AISContext.IsNull())
2709   {
2710     di << "use 'vinit' command before " << argv[0] << "\n";
2711     return 1;
2712   }
2713   if (argc == 2)
2714   {
2715     int aType = Draw::Atoi(argv[1]);
2716     if( aType < 0 || aType > 8 )
2717     {
2718       di << "Wrong fill type " << "\n";
2719       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2" << "\n";
2720       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4" << "\n";
2721       return 1;
2722     }
2723
2724     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
2725
2726     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2727     V3dView->SetBgGradientStyle( aMethod, 1 );
2728   }
2729
2730   return 0;
2731 }
2732
2733 //==============================================================================
2734 //function : VSetColorBg
2735 //purpose  : Set color background
2736 //==============================================================================
2737 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2738 {
2739   if (argc != 4 )
2740   {
2741     di << "Usage : " << argv[0] << " R G B : Set color background" << "\n";
2742     di << "R,G,B = [0..255]" << "\n";
2743     return 1;
2744   }
2745
2746   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
2747   if(AISContext.IsNull())
2748   {
2749     di << "use 'vinit' command before " << argv[0] << "\n";
2750     return 1;
2751   }
2752   if (argc == 4)
2753   {
2754
2755     Standard_Real R = Draw::Atof(argv[1])/255.;
2756     Standard_Real G = Draw::Atof(argv[2])/255.;
2757     Standard_Real B = Draw::Atof(argv[3])/255.;
2758     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
2759
2760     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2761     V3dView->SetBackgroundColor( aColor );
2762     V3dView->Update();
2763   }
2764
2765   return 0;
2766 }
2767
2768 //==============================================================================
2769 //function : VScale
2770 //purpose  : View Scaling
2771 //==============================================================================
2772
2773 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2774 {
2775   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2776   if ( V3dView.IsNull() ) return 1;
2777
2778   if ( argc != 4 ) {
2779     di << argv[0] << "Invalid number of arguments" << "\n";
2780     return 1;
2781   }
2782   V3dView->SetAxialScale( Draw::Atof(argv[1]),  Draw::Atof(argv[2]),  Draw::Atof(argv[3]) );
2783   return 0;
2784 }
2785 //==============================================================================
2786 //function : VTestZBuffTrihedron
2787 //purpose  : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron
2788 //==============================================================================
2789
2790 static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2791 {
2792   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2793   if ( V3dView.IsNull() ) return 1;
2794
2795   V3dView->ZBufferTriedronSetup();
2796
2797   if ( argc == 1 ) {
2798     // Set up default trihedron parameters
2799     V3dView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.1, V3d_ZBUFFER );
2800   } else
2801   if ( argc == 7 )
2802   {
2803     Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
2804     const char* aPosType = argv[1];
2805
2806     if ( strcmp(aPosType, "center") == 0 )
2807     {
2808       aPosition = Aspect_TOTP_CENTER;
2809     } else
2810     if (strcmp(aPosType, "left_lower") == 0)
2811     {
2812       aPosition = Aspect_TOTP_LEFT_LOWER;
2813     } else
2814     if (strcmp(aPosType, "left_upper") == 0)
2815     {
2816       aPosition = Aspect_TOTP_LEFT_UPPER;
2817     } else
2818     if (strcmp(aPosType, "right_lower") == 0)
2819     {
2820       aPosition = Aspect_TOTP_RIGHT_LOWER;
2821     } else
2822     if (strcmp(aPosType, "right_upper") == 0)
2823     {
2824       aPosition = Aspect_TOTP_RIGHT_UPPER;
2825     } else
2826     {
2827       di << argv[1] << " Invalid type of alignment"  << "\n";
2828       di << "Must be one of [ center, left_lower,"   << "\n";
2829       di << "left_upper, right_lower, right_upper ]" << "\n";
2830       return 1;
2831     }
2832
2833     Standard_Real R = Draw::Atof(argv[2])/255.;
2834     Standard_Real G = Draw::Atof(argv[3])/255.;
2835     Standard_Real B = Draw::Atof(argv[4])/255.;
2836     Quantity_Color aColor(R, G, B, Quantity_TOC_RGB);
2837
2838     Standard_Real aScale = Draw::Atof(argv[5]);
2839
2840     if( aScale <= 0.0 )
2841     {
2842       di << argv[5] << " Invalid value. Must be > 0" << "\n";
2843       return 1;
2844     }
2845
2846     V3d_TypeOfVisualization aPresentation = V3d_ZBUFFER;
2847     const char* aPresType = argv[6];
2848
2849     if ( strcmp(aPresType, "wireframe") == 0 )
2850     {
2851       aPresentation = V3d_WIREFRAME;
2852     } else
2853     if (strcmp(aPresType, "zbuffer") == 0)
2854     {
2855       aPresentation = V3d_ZBUFFER;
2856     } else
2857     {
2858       di << argv[6] << " Invalid type of visualization" << "\n";
2859       di << "Must be one of [ wireframe, zbuffer ]"     << "\n";
2860       return 1;
2861     }
2862
2863     V3dView->TriedronDisplay( aPosition, aColor.Name(), aScale, aPresentation );
2864
2865   } else
2866   {
2867     di << argv[0] << " Invalid number of arguments" << "\n";
2868     return 1;
2869   }
2870
2871   V3dView->View()->ZFitAll();
2872
2873   return 0;
2874 }
2875
2876 //==============================================================================
2877 //function : VRotate
2878 //purpose  : Camera Rotating
2879 //==============================================================================
2880
2881 static int VRotate( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2882   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2883   if ( V3dView.IsNull() ) {
2884     return 1;
2885   }
2886
2887   if ( argc == 4 ) {
2888     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
2889     return 0;
2890   } else if ( argc == 7 ) {
2891     V3dView->Rotate( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]), Draw::Atof(argv[4]), Draw::Atof(argv[5]), Draw::Atof(argv[6]) );
2892     return 0;
2893   } else {
2894     di << argv[0] << " Invalid number of arguments" << "\n";
2895     return 1;
2896   }
2897 }
2898
2899 //==============================================================================
2900 //function : VZoom
2901 //purpose  : View zoom in / out (relative to current zoom)
2902 //==============================================================================
2903
2904 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2905   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2906   if ( V3dView.IsNull() ) {
2907     return 1;
2908   }
2909
2910   if ( argc == 2 ) {
2911     Standard_Real coef = Draw::Atof(argv[1]);
2912     if ( coef <= 0.0 ) {
2913       di << argv[1] << "Invalid value" << "\n";
2914       return 1;
2915     }
2916     V3dView->SetZoom( Draw::Atof(argv[1]) );
2917     return 0;
2918   } else {
2919     di << argv[0] << " Invalid number of arguments" << "\n";
2920     return 1;
2921   }
2922 }
2923
2924 //==============================================================================
2925 //function : VPan
2926 //purpose  : View panning (in pixels)
2927 //==============================================================================
2928
2929 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
2930   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2931   if ( V3dView.IsNull() ) return 1;
2932
2933   if ( argc == 3 ) {
2934     V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
2935     return 0;
2936   } else {
2937     di << argv[0] << " Invalid number of arguments" << "\n";
2938     return 1;
2939   }
2940 }
2941
2942
2943 //==============================================================================
2944 //function : VExport
2945 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
2946 //==============================================================================
2947
2948 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2949 {
2950   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2951   if (V3dView.IsNull())
2952     return 1;
2953
2954   if (argc == 1)
2955   {
2956     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
2957     return 1;
2958   }
2959
2960   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
2961   TCollection_AsciiString aFormatStr;
2962
2963   TCollection_AsciiString aFileName (argv[1]);
2964   Standard_Integer aLen = aFileName.Length();
2965
2966   if (argc > 2)
2967   {
2968     aFormatStr = TCollection_AsciiString (argv[2]);
2969   }
2970   else if (aLen >= 4)
2971   {
2972     if (aFileName.Value (aLen - 2) == '.')
2973     {
2974       aFormatStr = aFileName.SubString (aLen - 1, aLen);
2975     }
2976     else if (aFileName.Value (aLen - 3) == '.')
2977     {
2978       aFormatStr = aFileName.SubString (aLen - 2, aLen);
2979     }
2980     else
2981     {
2982       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
2983       return 1;
2984     }
2985   }
2986   else
2987   {
2988     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
2989     return 1;
2990   }
2991
2992   aFormatStr.UpperCase();
2993   if (aFormatStr == "PS")
2994     anExpFormat = Graphic3d_EF_PostScript;
2995   else if (aFormatStr == "EPS")
2996     anExpFormat = Graphic3d_EF_EnhPostScript;
2997   else if (aFormatStr == "TEX")
2998     anExpFormat = Graphic3d_EF_TEX;
2999   else if (aFormatStr == "PDF")
3000     anExpFormat = Graphic3d_EF_PDF;
3001   else if (aFormatStr == "SVG")
3002     anExpFormat = Graphic3d_EF_SVG;
3003   else if (aFormatStr == "PGF")
3004     anExpFormat = Graphic3d_EF_PGF;
3005   else if (aFormatStr == "EMF")
3006     anExpFormat = Graphic3d_EF_EMF;
3007   else
3008   {
3009     std::cout << "Invalid export format '" << aFormatStr << "'\n";
3010     return 1;
3011   }
3012
3013   try {
3014     if (!V3dView->View()->Export (argv[1], anExpFormat))
3015     {
3016       di << "Error: export of image to " << aFormatStr << " failed!\n";
3017     }
3018   }
3019   catch (Standard_Failure)
3020   {
3021     di << "Error: export of image to " << aFormatStr << " failed";
3022     di << " (exception: " << Standard_Failure::Caught()->GetMessageString() << ")";
3023   }
3024   return 0;
3025 }
3026
3027 //==============================================================================
3028 //function : VColorScale
3029 //purpose  : representation color scale
3030 //==============================================================================
3031 #include <V3d_ColorScale.hxx>
3032
3033 static int VColorScale (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
3034 {
3035   if ( argc != 1 && argc != 4 && argc != 5 && argc != 6 && argc != 8 )
3036   {
3037     di << "Usage : " << argv[0] << " [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = Right X = 0 Y = 0]  " << "\n";
3038     return 1;
3039   }
3040
3041   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3042   if(aContext.IsNull()) {
3043     di << argv[0] << " ERROR : use 'vinit' command before " << "\n";
3044     return -1;
3045   }
3046
3047   Standard_Real minRange = 0. , maxRange = 100. ;
3048
3049   Standard_Integer numIntervals = 10 ;
3050   Standard_Integer textHeight = 16;
3051   Aspect_TypeOfColorScalePosition position = Aspect_TOCSP_RIGHT;
3052   Standard_Real X = 0., Y = 0. ;
3053
3054   if ( argc < 9 )
3055   {
3056      if( argc > 3 )
3057      {
3058        minRange = Draw::Atof( argv[1] );
3059        maxRange = Draw::Atof( argv[2] );
3060        numIntervals = Draw::Atoi( argv[3] );
3061      }
3062      if ( argc > 4 )
3063        textHeight = Draw::Atoi( argv[4] );
3064      if ( argc > 5 )
3065        position = (Aspect_TypeOfColorScalePosition)Draw::Atoi( argv[5] );
3066      if ( argc > 7 )
3067      {
3068        X = Draw::Atof( argv[6] );
3069        Y = Draw::Atof( argv[7] );
3070      }
3071   }
3072   Handle(V3d_View) curView = ViewerTest::CurrentView( );
3073   if ( curView.IsNull( ) )
3074     return 1;
3075   Handle(Aspect_ColorScale) aCSV = curView->ColorScale( );
3076   Handle(V3d_ColorScale) aCS = ( Handle( V3d_ColorScale )::DownCast( aCSV ) );
3077   if( ! aCS.IsNull( ) )
3078   {
3079     aCS->SetPosition( X , Y );
3080     aCS->SetHeight( 0.95) ;
3081     aCS->SetTextHeight( textHeight );
3082     aCS->SetRange( minRange , maxRange );
3083     aCS->SetNumberOfIntervals( numIntervals );
3084     aCS->SetLabelPosition( position );
3085     if( !curView->ColorScaleIsDisplayed() )
3086       curView->ColorScaleDisplay( );
3087   }
3088   return 0;
3089 }
3090
3091 //==============================================================================
3092 //function : VGraduatedTrihedron
3093 //purpose  : Displays a graduated trihedron
3094 //==============================================================================
3095
3096 static void AddMultibyteString (TCollection_ExtendedString &name, const char *arg)
3097 {
3098   const char *str = arg;
3099   while (*str)
3100   {
3101     unsigned short c1 = *str++;
3102     unsigned short c2 = *str++;
3103     if (!c1 || !c2) break;
3104     name += (Standard_ExtCharacter)((c1 << 8) | c2);
3105   }
3106 }
3107
3108 static int VGraduatedTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3109 {
3110   // Check arguments
3111   if (argc != 2 && argc < 5)
3112   {
3113     di<<"Error: "<<argv[0]<<" - invalid number of arguments\n";
3114     di<<"Usage: type help "<<argv[0]<<"\n";
3115     return 1; //TCL_ERROR
3116   }
3117
3118   Handle(V3d_View) aV3dView = ViewerTest::CurrentView();
3119
3120   // Create 3D view if it doesn't exist
3121   if ( aV3dView.IsNull() )
3122   {
3123     ViewerTest::ViewerInit();
3124     aV3dView = ViewerTest::CurrentView();
3125     if( aV3dView.IsNull() )
3126     {
3127       di << "Error: Cannot create a 3D view\n";
3128       return 1; //TCL_ERROR
3129     }
3130   }
3131
3132   // Erase (==0) or display (!=0)
3133   const int display = Draw::Atoi(argv[1]);
3134
3135   if (display)
3136   {
3137     // Text font
3138     TCollection_AsciiString font;
3139     if (argc < 6)
3140       font.AssignCat("Courier");
3141     else
3142       font.AssignCat(argv[5]);
3143
3144     // Text is multibyte
3145     const Standard_Boolean isMultibyte = (argc < 7)? Standard_False : (Draw::Atoi(argv[6]) != 0);
3146
3147     // Set axis names
3148     TCollection_ExtendedString xname, yname, zname;
3149     if (argc >= 5)
3150     {
3151       if (isMultibyte)
3152       {
3153         AddMultibyteString(xname, argv[2]);
3154         AddMultibyteString(yname, argv[3]);
3155         AddMultibyteString(zname, argv[4]);
3156       }
3157       else
3158       {
3159         xname += argv[2];
3160         yname += argv[3];
3161         zname += argv[4];
3162       }
3163     }
3164     else
3165     {
3166       xname += "X (mm)";
3167       yname += "Y (mm)";
3168       zname += "Z (mm)";
3169     }
3170
3171     aV3dView->GraduatedTrihedronDisplay(xname, yname, zname,
3172                                         Standard_True/*xdrawname*/, Standard_True/*ydrawname*/, Standard_True/*zdrawname*/,
3173                                         Standard_True/*xdrawvalues*/, Standard_True/*ydrawvalues*/, Standard_True/*zdrawvalues*/,
3174                                         Standard_True/*drawgrid*/,
3175                                         Standard_True/*drawaxes*/,
3176                                         5/*nbx*/, 5/*nby*/, 5/*nbz*/,
3177                                         10/*xoffset*/, 10/*yoffset*/, 10/*zoffset*/,
3178                                         30/*xaxisoffset*/, 30/*yaxisoffset*/, 30/*zaxisoffset*/,
3179                                         Standard_True/*xdrawtickmarks*/, Standard_True/*ydrawtickmarks*/, Standard_True/*zdrawtickmarks*/,
3180                                         10/*xtickmarklength*/, 10/*ytickmarklength*/, 10/*ztickmarklength*/,
3181                                         Quantity_NOC_WHITE/*gridcolor*/,
3182                                         Quantity_NOC_RED/*xnamecolor*/,Quantity_NOC_GREEN/*ynamecolor*/,Quantity_NOC_BLUE1/*znamecolor*/,
3183                                         Quantity_NOC_RED/*xcolor*/,Quantity_NOC_GREEN/*ycolor*/,Quantity_NOC_BLUE1/*zcolor*/,font);
3184   }
3185   else
3186     aV3dView->GraduatedTrihedronErase();
3187
3188   ViewerTest::GetAISContext()->UpdateCurrentViewer();
3189   aV3dView->Redraw();
3190
3191   return 0;
3192 }
3193
3194 //==============================================================================
3195 //function : VPrintView
3196 //purpose  : Test printing algorithm, print the view to image file with given
3197 //           width and height. Printing implemented only for WNT.
3198 //==============================================================================
3199 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
3200                        const char** argv)
3201 {
3202 #ifndef WNT
3203   di << "Printing implemented only for wnt!\n";
3204   return 0;
3205 #else
3206
3207   Handle(AIS_InteractiveContext) aContextAIS = NULL;
3208   Handle(V3d_View) aView = NULL;
3209   aContextAIS = ViewerTest::GetAISContext();
3210   if (!aContextAIS.IsNull())
3211   {
3212     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
3213     Vwr->InitActiveViews();
3214     if(Vwr->MoreActiveViews())
3215       aView = Vwr->ActiveView();
3216   }
3217
3218   // check for errors
3219   if (aView.IsNull())
3220   {
3221     di << "Call vinit before!\n";
3222     return 1;
3223   }
3224   else if (argc < 4)
3225   {
3226     di << "Use: " << argv[0];
3227     di << " width height filename [print algo=0] [tile_width tile_height]\n";
3228     di << "width, height of the intermediate buffer for operation\n";
3229     di << "algo : {0|1}\n";
3230     di << "        0 - stretch algorithm\n";
3231     di << "        1 - tile algorithm\n";
3232     di << "test printing algorithms into an intermediate buffer\n";
3233     di << "using specific tile size if provided\n";
3234     di << "with saving output to an image file\n";
3235     return 1;
3236   }
3237
3238   // get the input params
3239   Standard_Integer aWidth  = Draw::Atoi (argv[1]);
3240   Standard_Integer aHeight = Draw::Atoi (argv[2]);
3241   Standard_Integer aMode   = 0;
3242   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
3243   if (argc >= 5)
3244     aMode = Draw::Atoi (argv[4]);
3245
3246   Standard_Integer aTileWidth  = 0;
3247   Standard_Integer aTileHeight = 0;
3248   Standard_Boolean isTileSizeProvided = Standard_False;
3249   if (argc == 7)
3250   {
3251     isTileSizeProvided = Standard_True;
3252     aTileWidth  = Draw::Atoi (argv[5]);
3253     aTileHeight = Draw::Atoi (argv[6]);
3254   }
3255
3256   // check the input parameters
3257   if (aWidth <= 0 || aHeight <= 0)
3258   {
3259     di << "Width and height must be positive values!\n";
3260     return 1;
3261   }
3262   if (aMode != 0 && aMode != 1)
3263     aMode = 0;
3264
3265   // define compatible bitmap
3266   HDC anDC = CreateCompatibleDC(0);
3267   BITMAPINFO aBitmapData;
3268   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
3269   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
3270   aBitmapData.bmiHeader.biWidth         = aWidth ;
3271   aBitmapData.bmiHeader.biHeight        = aHeight;
3272   aBitmapData.bmiHeader.biPlanes        = 1;
3273   aBitmapData.bmiHeader.biBitCount      = 24;
3274   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
3275   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
3276   aBitmapData.bmiHeader.biClrUsed       = 0;
3277   aBitmapData.bmiHeader.biClrImportant  = 0;
3278   aBitmapData.bmiHeader.biCompression   = BI_RGB;
3279   aBitmapData.bmiHeader.biSizeImage     = 0;
3280
3281   // Create Device Independent Bitmap
3282   void* aBitsOut = NULL;
3283   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
3284                                             &aBitsOut, NULL, 0);
3285   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
3286
3287   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
3288   if (aBitsOut != NULL)
3289   {
3290     if (aMode == 0)
3291       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
3292     else
3293     {
3294       if (isTileSizeProvided)
3295       {
3296         Graphic3d_CView* aCView = static_cast<Graphic3d_CView*> (ViewerTest::CurrentView()->View()->CView());
3297         Graphic3d_PtrFrameBuffer anOldBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
3298         aCView->ptrFBO = aView->View()->FBOCreate (aTileWidth, aTileHeight);
3299
3300         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
3301
3302         Graphic3d_PtrFrameBuffer aNewBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
3303         aView->View()->FBORelease (aNewBuffer);
3304         aCView->ptrFBO = anOldBuffer;
3305       }
3306       else
3307       {
3308         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
3309       }
3310     }
3311
3312     // succesfully printed into an intermediate buffer
3313     if (isPrinted)
3314     {
3315       Image_PixMap aWrapper;
3316       aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
3317       aWrapper.SetTopDown (false);
3318
3319       Image_AlienPixMap anImageBitmap;
3320       anImageBitmap.InitCopy (aWrapper);
3321       isSaved = anImageBitmap.Save (aFileName);
3322     }
3323     else
3324     {
3325       di << "Print operation failed due to printing errors or\n";
3326       di << "insufficient memory available\n";
3327       di << "Please, try to use smaller dimensions for this test\n";
3328       di << "command, as it allocates intermediate buffer for storing\n";
3329       di << "the result\n";
3330     }
3331   }
3332   else
3333   {
3334     di << "Can't allocate memory for intermediate buffer\n";
3335     di << "Please use smaller dimensions\n";
3336   }
3337
3338   if (aMemoryBitmap)
3339   {
3340     SelectObject (anDC, anOldBitmap);
3341     DeleteObject (aMemoryBitmap);
3342     DeleteDC(anDC);
3343   }
3344
3345   if (!isSaved)
3346   {
3347     di << "Save to file operation failed. This operation may fail\n";
3348     di << "if you don't have enough available memory, then you can\n";
3349     di << "use smaller dimensions for the output file\n";
3350     return 1;
3351   }
3352
3353   return 0;
3354
3355 #endif
3356 }
3357
3358 //==============================================================================
3359 //function : VZLayer
3360 //purpose  : Test z layer operations for v3d viewer
3361 //==============================================================================
3362 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3363 {
3364   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3365   if (aContextAIS.IsNull())
3366   {
3367     di << "Call vinit before!\n";
3368     return 1;
3369   }
3370   else if (argc < 2)
3371   {
3372     di << "Use: vzlayer ";
3373     di << " add/del/get/settings/enable/disable [id]\n";
3374     di << " add - add new z layer to viewer and print its id\n";
3375     di << " del - del z layer by its id\n";
3376     di << " get - print sequence of z layers in increasing order of their overlay level\n";
3377     di << " settings - print status of z layer settings\n";
3378     di << " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n";
3379     di << " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n";
3380     di << " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n";
3381     di << "\nWhere id is the layer identificator\n";
3382     di << "\nExamples:\n";
3383     di << "   vzlayer add\n";
3384     di << "   vzlayer enable poffset 1\n";
3385     di << "   vzlayer disable depthtest 1\n";
3386     di << "   vzlayer del 1\n";
3387     return 1;
3388   }
3389
3390   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
3391   if (aViewer.IsNull())
3392   {
3393     di << "No active viewer!\n";
3394     return 1;
3395   }
3396
3397   // perform operation
3398   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
3399   if (anOp == "add")
3400   {
3401     Standard_Integer aNewId;
3402     if (!aViewer->AddZLayer (aNewId))
3403     {
3404       di << "Impossible to add new z layer!\n";
3405       return 1;
3406     }
3407
3408     di << "New z layer added with index: " << aNewId << "\n";
3409   }
3410   else if (anOp == "del")
3411   {
3412     if (argc < 3)
3413     {
3414       di << "Please also provide as argument id of z layer to remove\n";
3415       return 1;
3416     }
3417
3418     Standard_Integer aDelId = Draw::Atoi (argv[2]);
3419     if (!aViewer->RemoveZLayer (aDelId))
3420     {
3421       di << "Impossible to remove the z layer or invalid id!\n";
3422       return 1;
3423     }
3424
3425     di << "Z layer " << aDelId << " has been removed\n";
3426   }
3427   else if (anOp == "get")
3428   {
3429     TColStd_SequenceOfInteger anIds;
3430     aViewer->GetAllZLayers (anIds);
3431     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
3432     {
3433       di << anIds.Value (aSeqIdx) << " ";
3434     }
3435
3436     di << "\n";
3437   }
3438   else if (anOp == "settings")
3439   {
3440     if (argc < 3)
3441     {
3442       di << "Please also provide an id\n";
3443       return 1;
3444     }
3445
3446     Standard_Integer anId = Draw::Atoi (argv[2]);
3447     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
3448
3449     di << "Depth test - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthTest) ? "enabled" : "disabled") << "\n";
3450     di << "Depth write - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite) ? "enabled" : "disabled") << "\n";
3451     di << "Depth buffer clearing - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear) ? "enabled" : "disabled") << "\n";
3452     di << "Depth offset - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthOffset) ? "enabled" : "disabled") << "\n";
3453
3454   }
3455   else if (anOp == "enable")
3456   {
3457     if (argc < 3)
3458     {
3459       di << "Please also provide an option to enable\n";
3460       return 1;
3461     }
3462
3463     if (argc < 4)
3464     {
3465       di << "Please also provide a layer id\n";
3466       return 1;
3467     }
3468
3469     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
3470     Standard_Integer anId = Draw::Atoi (argv[3]);
3471     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
3472
3473     if (aSubOp == "depthtest" || aSubOp == "test")
3474     {
3475       aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
3476     }
3477     else if (aSubOp == "depthwrite" || aSubOp == "write")
3478     {
3479       aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
3480     }
3481     else if (aSubOp == "depthclear" || aSubOp == "clear")
3482     {
3483       aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
3484     }
3485     else if (aSubOp == "depthoffset" || aSubOp == "offset")
3486     {
3487       if (argc < 6)
3488       {
3489         di << "Please also provide a factor and units values for depth offset\n";
3490         di << "Format is: vzlayer enable offset [factor] [units] [layerId]\n";
3491         return 1;
3492       }
3493
3494       Standard_ShortReal aFactor = static_cast<Standard_ShortReal> (Draw::Atof (argv[3]));
3495       Standard_ShortReal aUnits  = static_cast<Standard_ShortReal> (Draw::Atof (argv[4]));
3496       anId = Draw::Atoi (argv[5]);
3497       aSettings = aViewer->ZLayerSettings (anId);
3498
3499       aSettings.DepthOffsetFactor = aFactor;
3500       aSettings.DepthOffsetUnits  = aUnits;
3501
3502       aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
3503     }
3504     else if (aSubOp == "positiveoffset" || aSubOp == "poffset")
3505     {
3506       aSettings.SetDepthOffsetPositive();
3507     }
3508     else if (aSubOp == "negativeoffset" || aSubOp == "noffset")
3509     {
3510       aSettings.SetDepthOffsetNegative();
3511     }
3512
3513     aViewer->SetZLayerSettings (anId, aSettings);
3514   }
3515   else if (anOp == "disable")
3516   {
3517     if (argc < 3)
3518     {
3519       di << "Please also provide an option to disable\n";
3520       return 1;
3521     }
3522
3523     if (argc < 4)
3524     {
3525       di << "Please also provide a layer id\n";
3526       return 1;
3527     }
3528
3529     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
3530     Standard_Integer anId = Draw::Atoi (argv[3]);
3531     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
3532
3533     if (aSubOp == "depthtest" || aSubOp == "test")
3534     {
3535       aSettings.DisableSetting (Graphic3d_ZLayerDepthTest);
3536     }
3537     else if (aSubOp == "depthwrite" || aSubOp == "write")
3538     {
3539       aSettings.DisableSetting (Graphic3d_ZLayerDepthWrite);
3540     }
3541     else if (aSubOp == "depthclear" || aSubOp == "clear")
3542     {
3543       aSettings.DisableSetting (Graphic3d_ZLayerDepthClear);
3544     }
3545     else if (aSubOp == "depthoffset" || aSubOp == "offset")
3546     {
3547       aSettings.DisableSetting (Graphic3d_ZLayerDepthOffset);
3548     }
3549
3550     aViewer->SetZLayerSettings (anId, aSettings);
3551   }
3552   else
3553   {
3554     di << "Invalid operation, please use { add / del / get / settings / enable / disable}\n";
3555     return 1;
3556   }
3557
3558   return 0;
3559 }
3560
3561 DEFINE_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
3562
3563 // this class provides a presentation of text item in v3d view under-/overlayer
3564 class V3d_TextItem : public Visual3d_LayerItem
3565 {
3566 public:
3567
3568   // CASCADE RTTI
3569   DEFINE_STANDARD_RTTI(V3d_TextItem)
3570
3571   // constructor
3572   Standard_EXPORT V3d_TextItem(const TCollection_AsciiString& theText,
3573                                const Standard_Real theX1,
3574                                const Standard_Real theY1,
3575                                const Standard_Real theHeight,
3576                                const TCollection_AsciiString& theFontName,
3577                                const Quantity_Color& theColor,
3578                                const Quantity_Color& theSubtitleColor,
3579                                const Aspect_TypeOfDisplayText& theTypeOfDisplay,
3580                                const Handle(Visual3d_Layer)& theLayer);
3581
3582   // redraw method
3583   Standard_EXPORT void RedrawLayerPrs();
3584
3585 private:
3586
3587   Standard_Real            myX1;
3588   Standard_Real            myY1;
3589   TCollection_AsciiString  myText;
3590   Standard_Real            myHeight;
3591   Handle(Visual3d_Layer)   myLayer;
3592   Quantity_Color           myColor;
3593   Quantity_Color           mySubtitleColor;
3594   Aspect_TypeOfDisplayText myType;
3595   TCollection_AsciiString  myFontName;
3596 };
3597
3598 IMPLEMENT_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
3599 IMPLEMENT_STANDARD_RTTIEXT(V3d_TextItem, Visual3d_LayerItem)
3600
3601 // create and add to display the text item
3602 V3d_TextItem::V3d_TextItem (const TCollection_AsciiString& theText,
3603                             const Standard_Real theX1,
3604                             const Standard_Real theY1,
3605                             const Standard_Real theHeight,
3606                             const TCollection_AsciiString& theFontName,
3607                             const Quantity_Color& theColor,
3608                             const Quantity_Color& theSubtitleColor,
3609                             const Aspect_TypeOfDisplayText& theTypeOfDisplay,
3610                             const Handle(Visual3d_Layer)& theLayer)
3611  : myX1 (theX1), myY1 (theY1),
3612    myText (theText),
3613    myHeight (theHeight),
3614    myLayer (theLayer),
3615    myColor (theColor),
3616    mySubtitleColor (theSubtitleColor),
3617    myType (theTypeOfDisplay),
3618    myFontName (theFontName)
3619 {
3620   if (!myLayer.IsNull ())
3621     myLayer->AddLayerItem (this);
3622 }
3623
3624 // render item
3625 void V3d_TextItem::RedrawLayerPrs ()
3626 {
3627   if (myLayer.IsNull ())
3628     return;
3629
3630   myLayer->SetColor (myColor);
3631   myLayer->SetTextAttributes (myFontName.ToCString (), myType, mySubtitleColor);
3632   myLayer->DrawText (myText.ToCString (), myX1, myY1, myHeight);
3633 }
3634
3635 DEFINE_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
3636
3637 // The Visual3d_LayerItem line item for "vlayerline" command
3638 // it provides a presentation of line with user-defined
3639 // linewidth, linetype and transparency.
3640 class V3d_LineItem : public Visual3d_LayerItem
3641 {
3642 public:
3643   // CASCADE RTTI
3644   DEFINE_STANDARD_RTTI(V3d_LineItem)
3645
3646   // constructor
3647   Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
3648                                Standard_Real X2, Standard_Real Y2,
3649                                V3d_LayerMgrPointer theLayerMgr,
3650                                Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
3651                                Standard_Real theWidth    = 0.5,
3652                                Standard_Real theTransp   = 1.0);
3653
3654   // redraw method
3655   Standard_EXPORT   void RedrawLayerPrs();
3656
3657 private:
3658
3659   Standard_Real       myX1, myY1, myX2, myY2;
3660   V3d_LayerMgrPointer myLayerMgr;
3661   Aspect_TypeOfLine   myType;
3662   Standard_Real       myWidth;
3663   Standard_Real       myTransparency;
3664 };
3665
3666 IMPLEMENT_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
3667 IMPLEMENT_STANDARD_RTTIEXT(V3d_LineItem, Visual3d_LayerItem)
3668
3669 // default constructor for line item
3670 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
3671                            Standard_Real X2, Standard_Real Y2,
3672                            V3d_LayerMgrPointer theLayerMgr,
3673                            Aspect_TypeOfLine theType,
3674                            Standard_Real theWidth,
3675                            Standard_Real theTransp) :
3676   myX1(X1), myY1(Y1), myX2(X2), myY2(Y2), myLayerMgr(theLayerMgr),
3677   myType(theType), myWidth(theWidth), myTransparency(theTransp)
3678 {
3679   if (myLayerMgr && !myLayerMgr->Overlay().IsNull())
3680     myLayerMgr->Overlay()->AddLayerItem (this);
3681 }
3682
3683 // render line
3684 void V3d_LineItem::RedrawLayerPrs ()
3685 {
3686   Handle (Visual3d_Layer) aOverlay;
3687
3688   if (myLayerMgr)
3689     aOverlay = myLayerMgr->Overlay();
3690
3691   if (!aOverlay.IsNull())
3692   {
3693     Quantity_Color aColor(1.0, 0, 0, Quantity_TOC_RGB);
3694     aOverlay->SetColor(aColor);
3695     aOverlay->SetTransparency((Standard_ShortReal)myTransparency);
3696     aOverlay->SetLineAttributes((Aspect_TypeOfLine)myType, myWidth);
3697     aOverlay->BeginPolyline();
3698     aOverlay->AddVertex(myX1, myY1);
3699     aOverlay->AddVertex(myX2, myY2);
3700     aOverlay->ClosePrimitive();
3701   }
3702 }
3703
3704 //=============================================================================
3705 //function : VLayerLine
3706 //purpose  : Draws line in the v3d view layer with given attributes: linetype,
3707 //         : linewidth, transparency coefficient
3708 //============================================================================
3709 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3710 {
3711   // get the active view
3712   Handle(V3d_View) aView = ViewerTest::CurrentView();
3713   if (aView.IsNull())
3714   {
3715     di << "Call vinit before!\n";
3716     return 1;
3717   }
3718   else if (argc < 5)
3719   {
3720     di << "Use: " << argv[0];
3721     di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
3722     di << " linetype : { 0 | 1 | 2 | 3 } \n";
3723     di << "              0 - solid  \n";
3724     di << "              1 - dashed \n";
3725     di << "              2 - dot    \n";
3726     di << "              3 - dashdot\n";
3727     di << " transparency : { 0.0 - 1.0 } \n";
3728     di << "                  0.0 - transparent\n";
3729     di << "                  1.0 - visible    \n";
3730     return 1;
3731   }
3732
3733   // get the input params
3734   Standard_Real X1 = Draw::Atof(argv[1]);
3735   Standard_Real Y1 = Draw::Atof(argv[2]);
3736   Standard_Real X2 = Draw::Atof(argv[3]);
3737   Standard_Real Y2 = Draw::Atof(argv[4]);
3738
3739   Standard_Real    aWidth = 0.5;
3740   Standard_Integer aType  = 0;
3741   Standard_Real    aTransparency = 1.0;
3742
3743   // has width
3744   if (argc > 5)
3745     aWidth = Draw::Atof(argv[5]);
3746
3747   // has type
3748   if (argc > 6)
3749      aType = (Standard_Integer) Draw::Atoi(argv[6]);
3750
3751   // has transparency
3752   if (argc > 7)
3753   {
3754     aTransparency = Draw::Atof(argv[7]);
3755     if (aTransparency < 0 || aTransparency > 1.0)
3756       aTransparency = 1.0;
3757   }
3758
3759   // select appropriate line type
3760   Aspect_TypeOfLine aLineType;
3761   switch (aType)
3762   {
3763     case 1:
3764       aLineType = Aspect_TOL_DASH;
3765     break;
3766
3767     case 2:
3768       aLineType = Aspect_TOL_DOT;
3769     break;
3770
3771     case 3:
3772       aLineType = Aspect_TOL_DOTDASH;
3773     break;
3774
3775     default:
3776       aLineType = Aspect_TOL_SOLID;
3777   }
3778
3779   // replace layer manager
3780   Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr(aView);
3781   aView->SetLayerMgr(aMgr);
3782
3783   // add line item
3784   Handle (V3d_LineItem) anItem = new V3d_LineItem(X1, Y1, X2, Y2,
3785                                                   aMgr.operator->(),
3786                                                   aLineType, aWidth,
3787                                                   aTransparency);
3788
3789   // update view
3790   aView->MustBeResized();
3791   aView->Redraw();
3792
3793   return 0;
3794 }
3795
3796 //=======================================================================
3797 //function : VOverlayText
3798 //purpose  : Test text displaying in view overlay
3799 //=======================================================================
3800 static int VOverlayText (Draw_Interpretor& di, Standard_Integer argc, const char**argv)
3801 {
3802   // get the active view
3803   Handle(V3d_View) aView = ViewerTest::CurrentView();
3804   if (aView.IsNull())
3805   {
3806     di << "No active view. Please call vinit.\n";
3807     return 1;
3808   }
3809   else if (argc < 4 || argc > 13)
3810   {
3811     di << "Use: " << argv[0];
3812     di << " text x y [height] [font_name] [text_color: R G B] [displayType]\n";
3813     di << "[background_color: R G B]\n";
3814     di << "  height - pixel height of the text (default=10.0)\n";
3815     di << "  font_name - name of font (default=courier)\n";
3816     di << "  text_color - R G B values of text color (default=255.0 255.0 255.0)\n";
3817     di << "  display_type = {normal/subtitle/decal/blend/dimension}, (default=normal)\n";
3818     di << "  background_color- R G B values used for subtitle and decal text\n";
3819     di << "(default=255.0 255.0 255.0)\n";
3820     return 1;
3821   }
3822
3823   TCollection_AsciiString aText (argv[1]);
3824   Standard_Real aPosX = Draw::Atof(argv[2]);
3825   Standard_Real aPosY = Draw::Atof(argv[3]);
3826   Standard_Real aHeight = (argc >= 5) ? Draw::Atof (argv[4]) : 10.0;
3827
3828   // font name
3829   TCollection_AsciiString aFontName = "Courier";
3830   if (argc >= 6)
3831     aFontName = TCollection_AsciiString (argv[5]);
3832
3833   // text colors
3834   Quantity_Parameter aColorRed   = 1.0;
3835   Quantity_Parameter aColorGreen = 1.0;
3836   Quantity_Parameter aColorBlue  = 1.0;
3837   if (argc >= 9)
3838   {
3839     aColorRed   = Draw::Atof (argv[6])/255.;
3840     aColorGreen = Draw::Atof (argv[7])/255.;
3841     aColorBlue  = Draw::Atof (argv[8])/255.;
3842   }
3843
3844   // display type
3845   TCollection_AsciiString aDispStr;
3846   if (argc >= 10)
3847     aDispStr = TCollection_AsciiString (argv[9]);
3848
3849   Aspect_TypeOfDisplayText aTextType = Aspect_TODT_NORMAL;
3850   if (aDispStr.IsEqual ("subtitle"))
3851     aTextType = Aspect_TODT_SUBTITLE;
3852   else if (aDispStr.IsEqual ("decal"))
3853     aTextType = Aspect_TODT_DEKALE;
3854   else if (aDispStr.IsEqual ("blend"))
3855     aTextType = Aspect_TODT_BLEND;
3856   else if (aDispStr.IsEqual ("dimension"))
3857     aTextType = Aspect_TODT_DIMENSION;
3858
3859   // subtitle color
3860   Quantity_Parameter aSubRed   = 1.0;
3861   Quantity_Parameter aSubGreen = 1.0;
3862   Quantity_Parameter aSubBlue  = 1.0;
3863   if (argc == 13)
3864   {
3865     aSubRed   = Draw::Atof (argv[10])/255.;
3866     aSubGreen = Draw::Atof (argv[11])/255.;
3867     aSubBlue  = Draw::Atof (argv[12])/255.;
3868   }
3869
3870   // check fo current overlay
3871   Handle(Visual3d_Layer) anOverlay = aView->Viewer()->Viewer()->OverLayer ();
3872   if (anOverlay.IsNull ())
3873   {
3874     Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr (aView);
3875     anOverlay = aMgr->Overlay ();
3876     aView->SetLayerMgr (aMgr);
3877   }
3878
3879   Quantity_Color aTextColor (aColorRed, aColorGreen,
3880     aColorBlue, Quantity_TOC_RGB);
3881   Quantity_Color aSubtColor (aSubRed, aSubGreen,
3882     aSubBlue, Quantity_TOC_RGB);
3883
3884   // add text item
3885   Handle(V3d_TextItem) anItem = new V3d_TextItem (aText, aPosX, aPosY,
3886     aHeight, aFontName, aTextColor, aSubtColor, aTextType, anOverlay);
3887
3888   // update view
3889   aView->MustBeResized();
3890   aView->Redraw();
3891
3892   return 0;
3893 }
3894
3895 //==============================================================================
3896 //function : VGrid
3897 //purpose  :
3898 //==============================================================================
3899
3900 static int VGrid (Draw_Interpretor& /*theDI*/,
3901                   Standard_Integer  theArgNb,
3902                   const char**      theArgVec)
3903 {
3904   // get the active view
3905   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3906   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3907   if (aView.IsNull() || aViewer.IsNull())
3908   {
3909     std::cerr << "No active view. Please call vinit.\n";
3910     return 1;
3911   }
3912
3913   Aspect_GridType     aType = aViewer->GridType();
3914   Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
3915
3916   Standard_Integer anIter = 1;
3917   for (; anIter < theArgNb; ++anIter)
3918   {
3919     const char* aValue = theArgVec[anIter];
3920     if (*aValue == 'r')
3921     {
3922       aType = Aspect_GT_Rectangular;
3923     }
3924     else if (*aValue == 'c')
3925     {
3926       aType = Aspect_GT_Circular;
3927     }
3928     else if (*aValue == 'l')
3929     {
3930       aMode = Aspect_GDM_Lines;
3931     }
3932     else if (*aValue == 'p')
3933     {
3934       aMode = Aspect_GDM_Points;
3935     }
3936     else if (strcmp (aValue, "off" ) == 0)
3937     {
3938       aViewer->DeactivateGrid();
3939       return 0;
3940     }
3941     else
3942     {
3943       break;
3944     }
3945   }
3946
3947   Standard_Integer aTail = (theArgNb - anIter);
3948   if (aTail == 0)
3949   {
3950     aViewer->ActivateGrid (aType, aMode);
3951     return 0;
3952   }
3953   else if (aTail != 2 && aTail != 5)
3954   {
3955     std::cerr << "Incorrect arguments number! Usage:\n"
3956               << "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]\n";
3957     return 1;
3958   }
3959
3960   Quantity_Length anOriginX, anOriginY;
3961   Quantity_PlaneAngle aRotAngle;
3962   if (aType == Aspect_GT_Rectangular)
3963   {
3964     Quantity_Length aRStepX, aRStepY;
3965     aViewer->RectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
3966
3967     anOriginX = Draw::Atof (theArgVec[anIter++]);
3968     anOriginY = Draw::Atof (theArgVec[anIter++]);
3969     if (aTail == 5)
3970     {
3971       aRStepX   = Draw::Atof (theArgVec[anIter++]);
3972       aRStepY   = Draw::Atof (theArgVec[anIter++]);
3973       aRotAngle = Draw::Atof (theArgVec[anIter++]);
3974     }
3975     aViewer->SetRectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
3976     aViewer->ActivateGrid (aType, aMode);
3977   }
3978   else if (aType == Aspect_GT_Circular)
3979   {
3980     Quantity_Length aRadiusStep;
3981     Standard_Integer aDivisionNumber;
3982     aViewer->CircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
3983
3984     anOriginX = Draw::Atof (theArgVec[anIter++]);
3985     anOriginY = Draw::Atof (theArgVec[anIter++]);
3986     if (aTail == 5)
3987     {
3988       aRadiusStep     = Draw::Atof (theArgVec[anIter++]);
3989       aDivisionNumber = Draw::Atoi (theArgVec[anIter++]);
3990       aRotAngle       = Draw::Atof (theArgVec[anIter++]);
3991     }
3992
3993     aViewer->SetCircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
3994     aViewer->ActivateGrid (aType, aMode);
3995   }
3996
3997   return 0;
3998 }
3999
4000 //==============================================================================
4001 //function : VFps
4002 //purpose  :
4003 //==============================================================================
4004
4005 static int VFps (Draw_Interpretor& theDI,
4006                  Standard_Integer  theArgNb,
4007                  const char**      theArgVec)
4008 {
4009   // get the active view
4010   Handle(V3d_View) aView = ViewerTest::CurrentView();
4011   if (aView.IsNull())
4012   {
4013     std::cerr << "No active view. Please call vinit.\n";
4014     return 1;
4015   }
4016
4017   Standard_Integer aFramesNb = (theArgNb > 1) ? Draw::Atoi(theArgVec[1]) : 100;
4018   if (aFramesNb <= 0)
4019   {
4020     std::cerr << "Incorrect arguments!\n";
4021     return 1;
4022   }
4023
4024   // the time is meaningless for first call
4025   // due to async OpenGl rendering
4026   aView->Redraw();
4027
4028   // redraw view in loop to estimate average values
4029   OSD_Timer aTimer;
4030   aTimer.Start();
4031   for (Standard_Integer anInter = 0; anInter < aFramesNb; ++anInter)
4032   {
4033     aView->Redraw();
4034   }
4035   aTimer.Stop();
4036   Standard_Real aCpu;
4037   const Standard_Real aTime = aTimer.ElapsedTime();
4038   aTimer.OSD_Chronometer::Show (aCpu);
4039
4040   const Standard_Real aFpsAver = Standard_Real(aFramesNb) / aTime;
4041   const Standard_Real aCpuAver = aCpu / Standard_Real(aFramesNb);
4042
4043   // return statistics
4044   theDI << "FPS: " << aFpsAver << "\n"
4045         << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
4046
4047   return 0;
4048 }
4049
4050 //==============================================================================
4051 //function : VGlDebug
4052 //purpose  :
4053 //==============================================================================
4054
4055 static int VGlDebug (Draw_Interpretor& theDI,
4056                      Standard_Integer  theArgNb,
4057                      const char**      theArgVec)
4058 {
4059   Handle(OpenGl_GraphicDriver) aDriver;
4060   Handle(V3d_View) aView = ViewerTest::CurrentView();
4061   if (!aView.IsNull())
4062   {
4063     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
4064   }
4065   if (theArgNb < 2)
4066   {
4067     if (aDriver.IsNull())
4068     {
4069       std::cerr << "No active view. Please call vinit.\n";
4070       return 0;
4071     }
4072
4073     Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS),
4074                                                                 "GL_ARB_debug_output");
4075     std::cout << "Active graphic driver: debug " << (isActive ? "ON" : "OFF") << "\n";
4076     theDI << (isActive ? "1" : "0");
4077     return 0;
4078   }
4079
4080   const Standard_Boolean toEnableDebug = Draw::Atoi (theArgVec[1]) != 0;
4081   ViewerTest_myDefaultCaps.contextDebug = toEnableDebug;
4082   ViewerTest_myDefaultCaps.glslWarnings = toEnableDebug;
4083   if (aDriver.IsNull())
4084   {
4085     return 0;
4086   }
4087
4088   aDriver->ChangeOptions().glslWarnings = toEnableDebug;
4089   return 0;
4090 }
4091
4092 //==============================================================================
4093 //function : VVbo
4094 //purpose  :
4095 //==============================================================================
4096
4097 static int VVbo (Draw_Interpretor& theDI,
4098                  Standard_Integer  theArgNb,
4099                  const char**      theArgVec)
4100 {
4101   const Standard_Boolean toSet    = (theArgNb > 1);
4102   const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
4103   if (toSet)
4104   {
4105     ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
4106   }
4107
4108   // get the context
4109   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4110   if (aContextAIS.IsNull())
4111   {
4112     if (!toSet)
4113     {
4114       std::cerr << "No active view!\n";
4115     }
4116     return 1;
4117   }
4118   Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
4119   if (!aDriver.IsNull())
4120   {
4121     if (!toSet)
4122     {
4123       theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
4124     }
4125     else
4126     {
4127       aDriver->ChangeOptions().vboDisable = toUseVbo;
4128     }
4129   }
4130
4131   return 0;
4132 }
4133
4134 //==============================================================================
4135 //function : VCaps
4136 //purpose  :
4137 //==============================================================================
4138
4139 static int VCaps (Draw_Interpretor& theDI,
4140                   Standard_Integer  theArgNb,
4141                   const char**      theArgVec)
4142 {
4143   OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
4144   Handle(OpenGl_GraphicDriver)   aDriver;
4145   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4146   if (!aContext.IsNull())
4147   {
4148     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
4149     aCaps   = &aDriver->ChangeOptions();
4150   }
4151
4152   if (theArgNb < 2)
4153   {
4154     theDI << "VBO:     " << (aCaps->vboDisable        ? "0" : "1") << "\n";
4155     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
4156     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
4157     theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
4158     return 0;
4159   }
4160
4161   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
4162   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4163   {
4164     Standard_CString        anArg     = theArgVec[anArgIter];
4165     TCollection_AsciiString anArgCase (anArg);
4166     anArgCase.LowerCase();
4167     if (anUpdateTool.parseRedrawMode (anArg))
4168     {
4169       continue;
4170     }
4171     else if (anArgCase == "-ffp")
4172     {
4173       Standard_Boolean toEnable = Standard_True;
4174       if (++anArgIter < theArgNb
4175       && !parseOnOff (theArgVec[anArgIter], toEnable))
4176       {
4177         --anArgIter;
4178       }
4179       aCaps->ffpEnable = toEnable;
4180     }
4181     else if (anArgCase == "-vbo")
4182     {
4183       Standard_Boolean toEnable = Standard_True;
4184       if (++anArgIter < theArgNb
4185       && !parseOnOff (theArgVec[anArgIter], toEnable))
4186       {
4187         --anArgIter;
4188       }
4189       aCaps->vboDisable = !toEnable;
4190     }
4191     else if (anArgCase == "-sprite"
4192           || anArgCase == "-sprites")
4193     {
4194       Standard_Boolean toEnable = Standard_True;
4195       if (++anArgIter < theArgNb
4196       && !parseOnOff (theArgVec[anArgIter], toEnable))
4197       {
4198         --anArgIter;
4199       }
4200       aCaps->pntSpritesDisable = !toEnable;
4201     }
4202     else if (anArgCase == "-softmode")
4203     {
4204       Standard_Boolean toEnable = Standard_True;
4205       if (++anArgIter < theArgNb
4206       && !parseOnOff (theArgVec[anArgIter], toEnable))
4207       {
4208         --anArgIter;
4209       }
4210       aCaps->contextNoAccel = toEnable;
4211     }
4212     else if (anArgCase == "-accel"
4213           || anArgCase == "-acceleration")
4214     {
4215       Standard_Boolean toEnable = Standard_True;
4216       if (++anArgIter < theArgNb
4217       && !parseOnOff (theArgVec[anArgIter], toEnable))
4218       {
4219         --anArgIter;
4220       }
4221       aCaps->contextNoAccel = !toEnable;
4222     }
4223     else
4224     {
4225       std::cout << "Error: unknown argument '" << anArg << "'\n";
4226       return 1;
4227     }
4228   }
4229   if (aCaps != &ViewerTest_myDefaultCaps)
4230   {
4231     ViewerTest_myDefaultCaps = *aCaps;
4232   }
4233   return 0;
4234 }
4235
4236 //==============================================================================
4237 //function : VMemGpu
4238 //purpose  :
4239 //==============================================================================
4240
4241 static int VMemGpu (Draw_Interpretor& theDI,
4242                     Standard_Integer  theArgNb,
4243                     const char**      theArgVec)
4244 {
4245   // get the context
4246   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4247   if (aContextAIS.IsNull())
4248   {
4249     std::cerr << "No active view. Please call vinit.\n";
4250     return 1;
4251   }
4252
4253   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
4254   if (aDriver.IsNull())
4255   {
4256     std::cerr << "Graphic driver not available.\n";
4257     return 1;
4258   }
4259
4260   Standard_Size aFreeBytes = 0;
4261   TCollection_AsciiString anInfo;
4262   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
4263   {
4264     std::cerr << "Information not available.\n";
4265     return 1;
4266   }
4267
4268   if (theArgNb > 1 && *theArgVec[1] == 'f')
4269   {
4270     theDI << Standard_Real (aFreeBytes);
4271   }
4272   else
4273   {
4274     theDI << anInfo;
4275   }
4276
4277   return 0;
4278 }
4279
4280 // ==============================================================================
4281 // function : VReadPixel
4282 // purpose  :
4283 // ==============================================================================
4284 static int VReadPixel (Draw_Interpretor& theDI,
4285                        Standard_Integer  theArgNb,
4286                        const char**      theArgVec)
4287 {
4288   // get the active view
4289   Handle(V3d_View) aView = ViewerTest::CurrentView();
4290   if (aView.IsNull())
4291   {
4292     std::cerr << "No active view. Please call vinit.\n";
4293     return 1;
4294   }
4295   else if (theArgNb < 3)
4296   {
4297     std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
4298     return 1;
4299   }
4300
4301   Image_PixMap::ImgFormat aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
4302   Graphic3d_BufferType    aBufferType = Graphic3d_BT_RGBA;
4303
4304   Standard_Integer aWidth, aHeight;
4305   aView->Window()->Size (aWidth, aHeight);
4306   const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
4307   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
4308   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
4309   {
4310     std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
4311     return 1;
4312   }
4313
4314   Standard_Boolean toShowName = Standard_False;
4315   Standard_Boolean toShowHls  = Standard_False;
4316   for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
4317   {
4318     const char* aParam = theArgVec[anIter];
4319     if ( strcasecmp( aParam, "rgb" ) == 0 )
4320     {
4321       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
4322       aBufferType = Graphic3d_BT_RGB;
4323     }
4324     else if ( strcasecmp( aParam, "hls" ) == 0 )
4325     {
4326       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
4327       aBufferType = Graphic3d_BT_RGB;
4328       toShowHls   = Standard_True;
4329     }
4330     else if ( strcasecmp( aParam, "rgbf" ) == 0 )
4331     {
4332       aFormat     = Image_PixMap::ImgRGBF;
4333       aBufferType = Graphic3d_BT_RGB;
4334     }
4335     else if ( strcasecmp( aParam, "rgba" ) == 0 )
4336     {
4337       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
4338       aBufferType = Graphic3d_BT_RGBA;
4339     }
4340     else if ( strcasecmp( aParam, "rgbaf" ) == 0 )
4341     {
4342       aFormat     = Image_PixMap::ImgRGBAF;
4343       aBufferType = Graphic3d_BT_RGBA;
4344     }
4345     else if ( strcasecmp( aParam, "depth" ) == 0 )
4346     {
4347       aFormat     = Image_PixMap::ImgGrayF;
4348       aBufferType = Graphic3d_BT_Depth;
4349     }
4350     else if ( strcasecmp( aParam, "name" ) == 0 )
4351     {
4352       toShowName = Standard_True;
4353     }
4354   }
4355
4356   Image_PixMap anImage;
4357   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
4358   {
4359     std::cerr << "Image allocation failed\n";
4360     return 1;
4361   }
4362   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
4363   {
4364     std::cerr << "Image dump failed\n";
4365     return 1;
4366   }
4367
4368   Quantity_Parameter anAlpha;
4369   Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
4370   if (toShowName)
4371   {
4372     if (aBufferType == Graphic3d_BT_RGBA)
4373     {
4374       theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha;
4375     }
4376     else
4377     {
4378       theDI << Quantity_Color::StringName (aColor.Name());
4379     }
4380   }
4381   else
4382   {
4383     switch (aBufferType)
4384     {
4385       default:
4386       case Graphic3d_BT_RGB:
4387       {
4388         if (toShowHls)
4389         {
4390           theDI << aColor.Hue() << " " << aColor.Light() << " " << aColor.Saturation();
4391         }
4392         else
4393         {
4394           theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue();
4395         }
4396         break;
4397       }
4398       case Graphic3d_BT_RGBA:
4399       {
4400         theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha;
4401         break;
4402       }
4403       case Graphic3d_BT_Depth:
4404       {
4405         theDI << aColor.Red();
4406         break;
4407       }
4408     }
4409   }
4410
4411   return 0;
4412 }
4413
4414 //==============================================================================
4415 //function : VDiffImage
4416 //purpose  : The draw-command compares two images.
4417 //==============================================================================
4418
4419 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
4420 {
4421   if (theArgNb < 6)
4422   {
4423     theDI << "Not enough arguments.\n";
4424     return 1;
4425   }
4426
4427   // image file names
4428   const char* anImgPathRef = theArgVec[1];
4429   const char* anImgPathNew = theArgVec[2];
4430
4431   // get string tolerance and check its validity
4432   Standard_Real aTolColor = Draw::Atof (theArgVec[3]);
4433   if (aTolColor < 0.0)
4434     aTolColor = 0.0;
4435   if (aTolColor > 1.0)
4436     aTolColor = 1.0;
4437
4438   Standard_Boolean toBlackWhite     = (Draw::Atoi (theArgVec[4]) == 1);
4439   Standard_Boolean isBorderFilterOn = (Draw::Atoi (theArgVec[5]) == 1);
4440
4441   // image file of difference
4442   const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
4443
4444   // compare the images
4445   Image_Diff aComparer;
4446   if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
4447   {
4448     return 1;
4449   }
4450
4451   aComparer.SetColorTolerance (aTolColor);
4452   aComparer.SetBorderFilterOn (isBorderFilterOn);
4453   Standard_Integer aDiffColorsNb = aComparer.Compare();
4454   theDI << aDiffColorsNb << "\n";
4455
4456   // save image of difference
4457   if (aDiffImagePath != NULL)
4458   {
4459     aComparer.SaveDiffImage (aDiffImagePath);
4460   }
4461
4462   return 0;
4463 }
4464
4465 //=======================================================================
4466 //function : VSelect
4467 //purpose  : Emulates different types of selection by mouse:
4468 //           1) single click selection
4469 //           2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
4470 //           3) selection with polygon having corners at
4471 //           pixel positions (x1,y1),...,(xn,yn)
4472 //           4) any of these selections with shift button pressed
4473 //=======================================================================
4474 static Standard_Integer VSelect (Draw_Interpretor& di,
4475                                  Standard_Integer argc,
4476                                  const char ** argv)
4477 {
4478   if(argc < 3)
4479   {
4480     di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]" << "\n";
4481     return 1;
4482   }
4483
4484   Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
4485   if(myAIScontext.IsNull())
4486   {
4487     di << "use 'vinit' command before " << argv[0] << "\n";
4488     return 1;
4489   }
4490   const Standard_Boolean isShiftSelection = (argc>3 && !(argc%2) && (atoi(argv[argc-1])==1));
4491   Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
4492   aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
4493   if(argc <= 4)
4494   {
4495     if(isShiftSelection)
4496       aCurrentEventManager->ShiftSelect();
4497     else
4498       aCurrentEventManager->Select();
4499   }
4500   else if(argc <= 6)
4501   {
4502     if(isShiftSelection)
4503       aCurrentEventManager->ShiftSelect(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
4504     else
4505       aCurrentEventManager->Select(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
4506   }
4507   else
4508   {
4509     Standard_Integer anUpper = 0;
4510
4511     if(isShiftSelection)
4512       anUpper = (argc-1)/2;
4513     else
4514       anUpper = argc/2;
4515     TColgp_Array1OfPnt2d aPolyline(1,anUpper);
4516
4517     for(Standard_Integer i=1;i<=anUpper;++i)
4518       aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
4519
4520     if(isShiftSelection)
4521       aCurrentEventManager->ShiftSelect(aPolyline);
4522     else
4523       aCurrentEventManager->Select(aPolyline);
4524   }
4525   return 0;
4526 }
4527
4528 //=======================================================================
4529 //function : VMoveTo
4530 //purpose  : Emulates cursor movement to defined pixel position
4531 //=======================================================================
4532 static Standard_Integer VMoveTo (Draw_Interpretor& di,
4533                                 Standard_Integer argc,
4534                                 const char ** argv)
4535 {
4536   if(argc != 3)
4537   {
4538     di << "Usage : " << argv[0] << " x y" << "\n";
4539     return 1;
4540   }
4541
4542   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4543   if(aContext.IsNull())
4544   {
4545     di << "use 'vinit' command before " << argv[0] << "\n";
4546     return 1;
4547   }
4548   ViewerTest::CurrentEventManager()->MoveTo(atoi(argv[1]),atoi(argv[2]));
4549   return 0;
4550 }
4551
4552 //=================================================================================================
4553 //function : VViewParams
4554 //purpose  : Gets or sets AIS View characteristics
4555 //=================================================================================================
4556 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4557 {
4558   Handle(V3d_View) anAISView = ViewerTest::CurrentView();
4559   if (anAISView.IsNull())
4560   {
4561     std::cout << theArgVec[0] << ": please initialize or activate view.\n";
4562     return 1;
4563   }
4564
4565   if (theArgsNb == 1)
4566   {
4567     // print all of the available view parameters
4568     Quantity_Factor anAISViewScale = anAISView->Scale();
4569
4570     Standard_Real anAISViewProjX = 0.0;
4571     Standard_Real anAISViewProjY = 0.0;
4572     Standard_Real anAISViewProjZ = 0.0;
4573     anAISView->Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
4574
4575     Standard_Real anAISViewUpX = 0.0;
4576     Standard_Real anAISViewUpY = 0.0;
4577     Standard_Real anAISViewUpZ = 0.0;
4578     anAISView->Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
4579
4580     Standard_Real anAISViewAtX = 0.0;
4581     Standard_Real anAISViewAtY = 0.0;
4582     Standard_Real anAISViewAtZ = 0.0;
4583     anAISView->At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
4584
4585     Standard_Real anAISViewEyeX = 0.0;
4586     Standard_Real anAISViewEyeY = 0.0;
4587     Standard_Real anAISViewEyeZ = 0.0;
4588     anAISView->Eye (anAISViewEyeX, anAISViewEyeY, anAISViewEyeZ);
4589
4590     theDi << "Scale of current view: " << anAISViewScale << "\n";
4591     theDi << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
4592     theDi << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
4593     theDi << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
4594     theDi << "Eye on X : " << anAISViewEyeX << "; on Y: " << anAISViewEyeY << "; on Z: " << anAISViewEyeZ << "\n";
4595     return 0;
4596   }
4597
4598   // -------------------------
4599   //  Parse options and values
4600   // -------------------------
4601
4602   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfKeysByValues;
4603   TCollection_AsciiString aParseKey;
4604   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
4605   {
4606     TCollection_AsciiString anArg (theArgVec [anArgIt]);
4607
4608     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
4609     {
4610       aParseKey = anArg;
4611       aParseKey.Remove (1);
4612       aParseKey.UpperCase();
4613       aMapOfKeysByValues.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4614       continue;
4615     }
4616
4617     if (aParseKey.IsEmpty())
4618     {
4619       std::cout << theArgVec[0] << ": values should be passed with key.\n";
4620       std::cout << "Type help for more information.\n";
4621       return 1;
4622     }
4623
4624     aMapOfKeysByValues(aParseKey)->Append (anArg);
4625   }
4626
4627   // ---------------------------------------------
4628   //  Change or print parameters, order plays role
4629   // ---------------------------------------------
4630
4631   // Check arguments for validity
4632   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfKeysByValues);
4633   for (; aMapIt.More(); aMapIt.Next())
4634   {
4635     const TCollection_AsciiString& aKey = aMapIt.Key();
4636     const Handle(TColStd_HSequenceOfAsciiString)& aValues = aMapIt.Value();
4637
4638     if (!(aKey.IsEqual ("SCALE")  && (aValues->Length() == 1 || aValues->IsEmpty()))
4639      && !(aKey.IsEqual ("SIZE")   && (aValues->Length() == 1 || aValues->IsEmpty()))
4640      && !(aKey.IsEqual ("EYE")    && (aValues->Length() == 3 || aValues->IsEmpty()))
4641      && !(aKey.IsEqual ("AT")     && (aValues->Length() == 3 || aValues->IsEmpty()))
4642      && !(aKey.IsEqual ("UP")     && (aValues->Length() == 3 || aValues->IsEmpty()))
4643      && !(aKey.IsEqual ("PROJ")   && (aValues->Length() == 3 || aValues->IsEmpty()))
4644      && !(aKey.IsEqual ("CENTER") &&  aValues->Length() == 2))
4645     {
4646       TCollection_AsciiString aLowerKey;
4647       aLowerKey  = "-";
4648       aLowerKey += aKey;
4649       aLowerKey.LowerCase();
4650       std::cout << theArgVec[0] << ": " << aLowerKey << " is unknown option, or number of arguments is invalid.\n";
4651       std::cout << "Type help for more information.\n";
4652       return 1;
4653     }
4654   }
4655
4656   Handle(TColStd_HSequenceOfAsciiString) aValues;
4657
4658   // Change view parameters in proper order
4659   if (aMapOfKeysByValues.Find ("SCALE", aValues))
4660   {
4661     if (aValues->IsEmpty())
4662     {
4663       theDi << "Scale: " << anAISView->Scale() << "\n";
4664     }
4665     else
4666     {
4667       anAISView->SetScale (aValues->Value(1).RealValue());
4668     }
4669   }
4670   if (aMapOfKeysByValues.Find ("SIZE", aValues))
4671   {
4672     if (aValues->IsEmpty())
4673     {
4674       Standard_Real aSizeX = 0.0;
4675       Standard_Real aSizeY = 0.0;
4676       anAISView->Size (aSizeX, aSizeY);
4677       theDi << "Size X: " << aSizeX << " Y: " << aSizeY << "\n";
4678     }
4679     else
4680     {
4681       anAISView->SetSize (aValues->Value(1).RealValue());
4682     }
4683   }
4684   if (aMapOfKeysByValues.Find ("EYE", aValues))
4685   {
4686     if (aValues->IsEmpty())
4687     {
4688       Standard_Real anEyeX = 0.0;
4689       Standard_Real anEyeY = 0.0;
4690       Standard_Real anEyeZ = 0.0;
4691       anAISView->Eye (anEyeX, anEyeY, anEyeZ);
4692       theDi << "Eye X: " << anEyeX << " Y: " << anEyeY << " Z: " << anEyeZ << "\n";
4693     }
4694     else
4695     {
4696       anAISView->SetEye (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
4697     }
4698   }
4699   if (aMapOfKeysByValues.Find ("AT", aValues))
4700   {
4701     if (aValues->IsEmpty())
4702     {
4703       Standard_Real anAtX = 0.0;
4704       Standard_Real anAtY = 0.0;
4705       Standard_Real anAtZ = 0.0;
4706       anAISView->At (anAtX, anAtY, anAtZ);
4707       theDi << "At X: " << anAtX << " Y: " << anAtY << " Z: " << anAtZ << "\n";
4708     }
4709     else
4710     {
4711       anAISView->SetAt (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
4712     }
4713   }
4714   if (aMapOfKeysByValues.Find ("PROJ", aValues))
4715   {
4716     if (aValues->IsEmpty())
4717     {
4718       Standard_Real aProjX = 0.0;
4719       Standard_Real aProjY = 0.0;
4720       Standard_Real aProjZ = 0.0;
4721       anAISView->Proj (aProjX, aProjY, aProjZ);
4722       theDi << "Proj X: " << aProjX << " Y: " << aProjY << " Z: " << aProjZ << "\n";
4723     }
4724     else
4725     {
4726       anAISView->SetProj (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
4727     }
4728   }
4729   if (aMapOfKeysByValues.Find ("UP", aValues))
4730   {
4731     if (aValues->IsEmpty())
4732     {
4733       Standard_Real anUpX = 0.0;
4734       Standard_Real anUpY = 0.0;
4735       Standard_Real anUpZ = 0.0;
4736       anAISView->Up (anUpX, anUpY, anUpZ);
4737       theDi << "Up X: " << anUpX << " Y: " << anUpY << " Z: " << anUpZ << "\n";
4738     }
4739     else
4740     {
4741       anAISView->SetUp (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
4742     }
4743   }
4744   if (aMapOfKeysByValues.Find ("CENTER", aValues))
4745   {
4746     anAISView->SetCenter (aValues->Value(1).IntegerValue(), aValues->Value(2).IntegerValue());
4747   }
4748
4749   return 0;
4750 }
4751
4752 //=======================================================================
4753 //function : VChangeSelected
4754 //purpose  : Adds the shape to selection or remove one from it
4755 //=======================================================================
4756 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
4757                                 Standard_Integer argc,
4758                                 const char ** argv)
4759 {
4760   if(argc != 2)
4761   {
4762     di<<"Usage : " << argv[0] << " shape \n";
4763     return 1;
4764   }
4765   //get AIS_Shape:
4766   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4767   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4768   TCollection_AsciiString aName(argv[1]);
4769   Handle(AIS_InteractiveObject) anAISObject;
4770
4771   if(!aMap.IsBound2(aName))
4772   {
4773     di<<"Use 'vdisplay' before";
4774     return 1;
4775   }
4776   else
4777   {
4778     anAISObject = Handle(AIS_InteractiveObject)::DownCast(aMap.Find2(aName));
4779     if(anAISObject.IsNull()){
4780       di<<"No interactive object \n";
4781       return 1;
4782     }
4783
4784     if(aContext->HasOpenedContext())
4785     {
4786       aContext->AddOrRemoveSelected(anAISObject);
4787     }
4788     else
4789     {
4790       aContext->AddOrRemoveCurrentObject(anAISObject);
4791     }
4792   }
4793   return 0;
4794 }
4795
4796 //=======================================================================
4797 //function : VZClipping
4798 //purpose  : Gets or sets ZClipping mode, width and depth
4799 //=======================================================================
4800 static Standard_Integer VZClipping (Draw_Interpretor& di,
4801                                 Standard_Integer argc,
4802                                 const char ** argv)
4803 {
4804   if(argc>4)
4805   {
4806     di << "Usage : " << argv[0] << " [mode] [depth  width]" << "\n"
4807       <<"mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4808     return -1;
4809   }
4810   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4811   if(aContext.IsNull())
4812   {
4813     di << "use 'vinit' command before " << argv[0] << "\n";
4814     return 1;
4815   }
4816   Handle(V3d_View) aView = ViewerTest::CurrentView();
4817   V3d_TypeOfZclipping aZClippingMode = V3d_OFF;
4818   if(argc==1)
4819   {
4820     TCollection_AsciiString aZClippingModeString;
4821     Quantity_Length aDepth, aWidth;
4822     aZClippingMode = aView->ZClipping(aDepth, aWidth);
4823     switch (aZClippingMode)
4824     {
4825     case V3d_OFF:
4826       aZClippingModeString.Copy("OFF");
4827       break;
4828     case V3d_BACK:
4829       aZClippingModeString.Copy("BACK");
4830       break;
4831     case V3d_FRONT:
4832       aZClippingModeString.Copy("FRONT");
4833       break;
4834     case V3d_SLICE:
4835       aZClippingModeString.Copy("SLICE");
4836       break;
4837     default:
4838       aZClippingModeString.Copy(TCollection_AsciiString(aZClippingMode));
4839       break;
4840     }
4841     di << "ZClippingMode = " << aZClippingModeString.ToCString() << "\n"
4842       << "ZClipping depth = " << aDepth << "\n"
4843       << "ZClipping width = " << aWidth << "\n";
4844   }
4845   else
4846   {
4847     if(argc !=3)
4848     {
4849       Standard_Integer aStatus = 0;
4850       if ( strcmp (argv [1], "OFF") == 0 ) {
4851         aStatus = 1;
4852         aZClippingMode = V3d_OFF;
4853       }
4854       if ( strcmp (argv [1], "BACK") == 0 ) {
4855         aStatus = 1;
4856         aZClippingMode = V3d_BACK;
4857       }
4858       if ( strcmp (argv [1], "FRONT") == 0 ) {
4859         aStatus = 1;
4860         aZClippingMode = V3d_FRONT;
4861       }
4862       if ( strcmp (argv [1], "SLICE") == 0 ) {
4863         aStatus = 1;
4864         aZClippingMode = V3d_SLICE;
4865       }
4866       if (aStatus != 1)
4867       {
4868         di << "Bad mode; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4869           << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4870         return 1;
4871       }
4872       aView->SetZClippingType(aZClippingMode);
4873     }
4874     if(argc >2)
4875     {
4876       Quantity_Length aDepth = 0., aWidth = 1.;
4877       if(argc == 3)
4878       {
4879         aDepth = Draw::Atof (argv[1]);
4880         aWidth = Draw::Atof (argv[2]);
4881       }
4882       else if(argc == 4)
4883       {
4884         aDepth = Draw::Atof (argv[2]);
4885         aWidth = Draw::Atof (argv[3]);
4886       }
4887
4888       if(aDepth<0. || aDepth>1.)
4889       {
4890         di << "Bad depth; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4891         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4892         return 1;
4893       }
4894       if(aWidth<0. || aWidth>1.)
4895       {
4896         di << "Bad width; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
4897         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
4898         return 1;
4899       }
4900
4901       aView->SetZClippingDepth(aDepth);
4902       aView->SetZClippingWidth(aWidth);
4903     }
4904     aView->Redraw();
4905   }
4906   return 0;
4907 }
4908
4909 //=======================================================================
4910 //function : VNbSelected
4911 //purpose  : Returns number of selected objects
4912 //=======================================================================
4913 static Standard_Integer VNbSelected (Draw_Interpretor& di,
4914                                 Standard_Integer argc,
4915                                 const char ** argv)
4916 {
4917   if(argc != 1)
4918   {
4919     di << "Usage : " << argv[0] << "\n";
4920     return 1;
4921   }
4922   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4923   if(aContext.IsNull())
4924   {
4925     di << "use 'vinit' command before " << argv[0] << "\n";
4926     return 1;
4927   }
4928   di << aContext->NbSelected() << "\n";
4929   return 0;
4930 }
4931
4932 //=======================================================================
4933 //function : VAntialiasing
4934 //purpose  : Switches altialiasing on or off
4935 //=======================================================================
4936 static Standard_Integer VAntialiasing (Draw_Interpretor& di,
4937                                 Standard_Integer argc,
4938                                 const char ** argv)
4939 {
4940   if(argc > 2)
4941   {
4942     di << "Usage : " << argv[0] << " [1|0]" << "\n";
4943     return 1;
4944   }
4945
4946   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4947   if(aContext.IsNull())
4948   {
4949     di << "use 'vinit' command before " << argv[0] << "\n";
4950     return 1;
4951   }
4952
4953   Handle(V3d_View) aView = ViewerTest::CurrentView();
4954
4955   if((argc == 2) && (atof(argv[1]) == 0))
4956     aView->SetAntialiasingOff();
4957   else
4958     aView->SetAntialiasingOn();
4959   aView->Update();
4960   return 0;
4961 }
4962
4963 //=======================================================================
4964 //function : VPurgeDisplay
4965 //purpose  : Switches altialiasing on or off
4966 //=======================================================================
4967 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
4968                                 Standard_Integer argc,
4969                                 const char ** argv)
4970 {
4971   if (argc > 1)
4972   {
4973     di << "Usage : " << argv[0] << "\n";
4974     return 1;
4975   }
4976   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4977   if (aContext.IsNull())
4978   {
4979     di << "use 'vinit' command before " << argv[0] << "\n";
4980     return 1;
4981   }
4982   aContext->CloseAllContexts(Standard_False);
4983   di << aContext->PurgeDisplay() << "\n";
4984   return 0;
4985 }
4986
4987 //=======================================================================
4988 //function : VSetViewSize
4989 //purpose  :
4990 //=======================================================================
4991 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
4992                                 Standard_Integer argc,
4993                                 const char ** argv)
4994 {
4995   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4996   if(aContext.IsNull())
4997   {
4998     di << "use 'vinit' command before " << argv[0] << "\n";
4999     return 1;
5000   }
5001   if(argc != 2)
5002   {
5003     di<<"Usage : " << argv[0] << " Size\n";
5004     return 1;
5005   }
5006   Standard_Real aSize = Draw::Atof (argv[1]);
5007   if (aSize <= 0.)
5008   {
5009     di<<"Bad Size value  : " << aSize << "\n";
5010     return 1;
5011   }
5012
5013   Handle(V3d_View) aView = ViewerTest::CurrentView();
5014   aView->SetSize(aSize);
5015   return 0;
5016 }
5017
5018 //=======================================================================
5019 //function : VMoveView
5020 //purpose  :
5021 //=======================================================================
5022 static Standard_Integer VMoveView (Draw_Interpretor& di,
5023                                 Standard_Integer argc,
5024                                 const char ** argv)
5025 {
5026   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5027   if(aContext.IsNull())
5028   {
5029     di << "use 'vinit' command before " << argv[0] << "\n";
5030     return 1;
5031   }
5032   if(argc < 4 || argc > 5)
5033   {
5034     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
5035     return 1;
5036   }
5037   Standard_Real Dx = Draw::Atof (argv[1]);
5038   Standard_Real Dy = Draw::Atof (argv[2]);
5039   Standard_Real Dz = Draw::Atof (argv[3]);
5040   Standard_Boolean aStart = Standard_True;
5041   if (argc == 5)
5042   {
5043       aStart = (Draw::Atoi (argv[4]) > 0);
5044   }
5045
5046   Handle(V3d_View) aView = ViewerTest::CurrentView();
5047   aView->Move(Dx,Dy,Dz,aStart);
5048   return 0;
5049 }
5050
5051 //=======================================================================
5052 //function : VTranslateView
5053 //purpose  :
5054 //=======================================================================
5055 static Standard_Integer VTranslateView (Draw_Interpretor& di,
5056                                 Standard_Integer argc,
5057                                 const char ** argv)
5058 {
5059   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5060   if(aContext.IsNull())
5061   {
5062     di << "use 'vinit' command before " << argv[0] << "\n";
5063     return 1;
5064   }
5065   if(argc < 4 || argc > 5)
5066   {
5067     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
5068     return 1;
5069   }
5070   Standard_Real Dx = Draw::Atof (argv[1]);
5071   Standard_Real Dy = Draw::Atof (argv[2]);
5072   Standard_Real Dz = Draw::Atof (argv[3]);
5073   Standard_Boolean aStart = Standard_True;
5074   if (argc == 5)
5075   {
5076       aStart = (Draw::Atoi (argv[4]) > 0);
5077   }
5078
5079   Handle(V3d_View) aView = ViewerTest::CurrentView();
5080   aView->Translate(Dx,Dy,Dz,aStart);
5081   return 0;
5082 }
5083
5084 //=======================================================================
5085 //function : VTurnView
5086 //purpose  :
5087 //=======================================================================
5088 static Standard_Integer VTurnView (Draw_Interpretor& di,
5089                                 Standard_Integer argc,
5090                                 const char ** argv)
5091 {
5092   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5093   if(aContext.IsNull()) {
5094     di << "use 'vinit' command before " << argv[0] << "\n";
5095     return 1;
5096   }
5097   if(argc < 4 || argc > 5){
5098     di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
5099     return 1;
5100   }
5101   Standard_Real Ax = Draw::Atof (argv[1]);
5102   Standard_Real Ay = Draw::Atof (argv[2]);
5103   Standard_Real Az = Draw::Atof (argv[3]);
5104   Standard_Boolean aStart = Standard_True;
5105   if (argc == 5)
5106   {
5107       aStart = (Draw::Atoi (argv[4]) > 0);
5108   }
5109
5110   Handle(V3d_View) aView = ViewerTest::CurrentView();
5111   aView->Turn(Ax,Ay,Az,aStart);
5112   return 0;
5113 }
5114
5115 //==============================================================================
5116 //function : VTextureEnv
5117 //purpose  : ENables or disables environment mapping
5118 //==============================================================================
5119 class OCC_TextureEnv : public Graphic3d_TextureEnv
5120 {
5121 public:
5122   OCC_TextureEnv(const Standard_CString FileName);
5123   OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
5124   void SetTextureParameters(const Standard_Boolean theRepeatFlag,
5125                             const Standard_Boolean theModulateFlag,
5126                             const Graphic3d_TypeOfTextureFilter theFilter,
5127                             const Standard_ShortReal theXScale,
5128                             const Standard_ShortReal theYScale,
5129                             const Standard_ShortReal theXShift,
5130                             const Standard_ShortReal theYShift,
5131                             const Standard_ShortReal theAngle);
5132   DEFINE_STANDARD_RTTI(OCC_TextureEnv);
5133 };
5134 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
5135 IMPLEMENT_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
5136 IMPLEMENT_STANDARD_RTTIEXT(OCC_TextureEnv, Graphic3d_TextureEnv);
5137
5138 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
5139   : Graphic3d_TextureEnv(theFileName)
5140 {
5141 }
5142
5143 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
5144   : Graphic3d_TextureEnv(theTexId)
5145 {
5146 }
5147
5148 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
5149                                           const Standard_Boolean theModulateFlag,
5150                                           const Graphic3d_TypeOfTextureFilter theFilter,
5151                                           const Standard_ShortReal theXScale,
5152                                           const Standard_ShortReal theYScale,
5153                                           const Standard_ShortReal theXShift,
5154                                           const Standard_ShortReal theYShift,
5155                                           const Standard_ShortReal theAngle)
5156 {
5157   myParams->SetRepeat     (theRepeatFlag);
5158   myParams->SetModulate   (theModulateFlag);
5159   myParams->SetFilter     (theFilter);
5160   myParams->SetScale      (Graphic3d_Vec2(theXScale, theYScale));
5161   myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
5162   myParams->SetRotation   (theAngle);
5163 }
5164
5165 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
5166 {
5167   // get the active view
5168   Handle(V3d_View) aView = ViewerTest::CurrentView();
5169   if (aView.IsNull())
5170   {
5171     std::cerr << "No active view. Please call vinit.\n";
5172     return 1;
5173   }
5174
5175   // Checking the input arguments
5176   Standard_Boolean anEnableFlag = Standard_False;
5177   Standard_Boolean isOk         = theArgNb >= 2;
5178   if (isOk)
5179   {
5180     TCollection_AsciiString anEnableOpt(theArgVec[1]);
5181     anEnableFlag = anEnableOpt.IsEqual("on");
5182     isOk         = anEnableFlag || anEnableOpt.IsEqual("off");
5183   }
5184   if (anEnableFlag)
5185   {
5186     isOk = (theArgNb == 3 || theArgNb == 11);
5187     if (isOk)
5188     {
5189       TCollection_AsciiString aTextureOpt(theArgVec[2]);
5190       isOk = (!aTextureOpt.IsIntegerValue() ||
5191              (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
5192
5193       if (isOk && theArgNb == 11)
5194       {
5195         TCollection_AsciiString aRepeatOpt  (theArgVec[3]),
5196                                 aModulateOpt(theArgVec[4]),
5197                                 aFilterOpt  (theArgVec[5]),
5198                                 aSScaleOpt  (theArgVec[6]),
5199                                 aTScaleOpt  (theArgVec[7]),
5200                                 aSTransOpt  (theArgVec[8]),
5201                                 aTTransOpt  (theArgVec[9]),
5202                                 anAngleOpt  (theArgVec[10]);
5203         isOk = ((aRepeatOpt.  IsEqual("repeat")   || aRepeatOpt.  IsEqual("clamp")) &&
5204                 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
5205                 (aFilterOpt.  IsEqual("nearest")  || aFilterOpt.  IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
5206                 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
5207                 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
5208                 anAngleOpt.IsRealValue());
5209       }
5210     }
5211   }
5212
5213   if (!isOk)
5214   {
5215     std::cerr << "Usage :" << std::endl;
5216     std::cerr << theArgVec[0] << " off" << std::endl;
5217     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;
5218     return 1;
5219   }
5220
5221   if (anEnableFlag)
5222   {
5223     TCollection_AsciiString aTextureOpt(theArgVec[2]);
5224     Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
5225                                      new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
5226                                      new OCC_TextureEnv(theArgVec[2]);
5227
5228     if (theArgNb == 11)
5229     {
5230       TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
5231       aTexEnv->SetTextureParameters(
5232         aRepeatOpt.  IsEqual("repeat"),
5233         aModulateOpt.IsEqual("modulate"),
5234         aFilterOpt.  IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
5235                                           aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
5236                                                                            Graphic3d_TOTF_TRILINEAR,
5237         (Standard_ShortReal)Draw::Atof(theArgVec[6]),
5238         (Standard_ShortReal)Draw::Atof(theArgVec[7]),
5239         (Standard_ShortReal)Draw::Atof(theArgVec[8]),
5240         (Standard_ShortReal)Draw::Atof(theArgVec[9]),
5241         (Standard_ShortReal)Draw::Atof(theArgVec[10])
5242         );
5243     }
5244     aView->SetTextureEnv(aTexEnv);
5245     aView->SetSurfaceDetail(V3d_TEX_ENVIRONMENT);
5246   }
5247   else // Disabling environment mapping
5248   {
5249     aView->SetSurfaceDetail(V3d_TEX_NONE);
5250     Handle(Graphic3d_TextureEnv) aTexture;
5251     aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
5252   }
5253
5254   aView->Redraw();
5255   return 0;
5256 }
5257
5258 //===============================================================================================
5259 //function : VClipPlane
5260 //purpose  :
5261 //===============================================================================================
5262 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5263 {
5264   // use short-cut for created clip planes map of created (or "registered by name") clip planes
5265   typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
5266   static MapOfPlanes aRegPlanes;
5267
5268   if (theArgsNb < 2)
5269   {
5270     theDi << theArgVec[0] << ": command argument is required. Type help for more information.\n";
5271     return 1;
5272   }
5273
5274   TCollection_AsciiString aCommand (theArgVec[1]);
5275
5276   // print maximum number of planes for current viewer
5277   if (aCommand == "maxplanes")
5278   {
5279     if (theArgsNb < 3)
5280     {
5281       theDi << theArgVec[0] << ": view name is required. Type help for more information.\n";
5282       return 1;
5283     }
5284
5285     TCollection_AsciiString aViewName (theArgVec[2]);
5286
5287     if (!ViewerTest_myViews.IsBound1 (aViewName))
5288     {
5289       theDi << theArgVec[0] << ": view is not found.\n";
5290       return 1;
5291     }
5292
5293     const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
5294
5295     theDi << theArgVec[0] << ": "
5296                           << aView->Viewer()->Driver()->InquirePlaneLimit()
5297                           << " plane slots provided by driver."
5298                           << " Note that 2 more planes might be used (reserved for z-clipping).\n";
5299
5300     return 0;
5301   }
5302
5303   // create / delete plane instance
5304   if (aCommand == "create" || aCommand == "delete" || aCommand == "clone")
5305   {
5306     if (theArgsNb < 3)
5307     {
5308       theDi << theArgVec[0] << ": plane name is required. Type help for more information.\n";
5309       return 1;
5310     }
5311
5312     Standard_Boolean toCreate = (aCommand == "create");
5313     Standard_Boolean toClone  = (aCommand == "clone");
5314     TCollection_AsciiString aPlane (theArgVec[2]);
5315
5316     if (toCreate)
5317     {
5318       if (aRegPlanes.IsBound (aPlane))
5319       {
5320         theDi << theArgVec[0] << ": plane name is in use.\n";
5321         return 1;
5322       }
5323
5324       aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
5325     }
5326     else if (toClone) // toClone
5327     {
5328       if (!aRegPlanes.IsBound (aPlane))
5329       {
5330         theDi << theArgVec[0] << ": no such plane.\n";
5331         return 1;
5332       }
5333
5334       if (theArgsNb < 4)
5335       {
5336         theDi << theArgVec[0] << ": enter name for new plane. Type help for more information.\n";
5337         return 1;
5338       }
5339
5340       TCollection_AsciiString aClone (theArgVec[3]);
5341       if (aRegPlanes.IsBound (aClone))
5342       {
5343         theDi << theArgVec[0] << ": plane name is in use.\n";
5344         return 1;
5345       }
5346
5347       const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
5348
5349       aRegPlanes.Bind (aClone, aClipPlane->Clone());
5350     }
5351     else// toDelete
5352     {
5353       if (!aRegPlanes.IsBound (aPlane))
5354       {
5355         theDi << theArgVec[0] << ": no such plane.\n";
5356         return 1;
5357       }
5358
5359       Handle(Graphic3d_ClipPlane) aClipPlane = aRegPlanes.Find (aPlane);
5360       aRegPlanes.UnBind (aPlane);
5361
5362       ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
5363       for (; anIObjIt.More(); anIObjIt.Next())
5364       {
5365         Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1());
5366         aPrs->RemoveClipPlane(aClipPlane);
5367       }
5368
5369       NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
5370       for (; aViewIt.More(); aViewIt.Next())
5371       {
5372         const Handle(V3d_View)& aView = aViewIt.Key2();
5373         aView->RemoveClipPlane(aClipPlane);
5374       }
5375
5376       ViewerTest::RedrawAllViews();
5377     }
5378
5379     return 0;
5380   }
5381
5382   // set / unset plane command
5383   if (aCommand == "set" || aCommand == "unset")
5384   {
5385     if (theArgsNb < 4)
5386     {
5387       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5388       return 1;
5389     }
5390
5391     Standard_Boolean toSet = (aCommand == "set");
5392     TCollection_AsciiString aPlane (theArgVec [2]);
5393     if (!aRegPlanes.IsBound (aPlane))
5394     {
5395       theDi << theArgVec[0] << ": no such plane.\n";
5396       return 1;
5397     }
5398
5399     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
5400
5401     TCollection_AsciiString aTarget (theArgVec [3]);
5402     if (aTarget != "object" && aTarget != "view")
5403     {
5404       theDi << theArgVec[0] << ": invalid target.\n";
5405       return 1;
5406     }
5407
5408     if (aTarget == "object" || aTarget == "view")
5409     {
5410       if (theArgsNb < 5)
5411       {
5412         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5413         return 1;
5414       }
5415
5416       Standard_Boolean isObject = (aTarget == "object");
5417
5418       for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
5419       {
5420         TCollection_AsciiString anEntityName (theArgVec[anIt]);
5421         if (isObject) // to object
5422         {
5423           if (!GetMapOfAIS().IsBound2 (anEntityName))
5424           {
5425             theDi << theArgVec[0] << ": can not find IO with name " << anEntityName << ".\n";
5426             continue;
5427           }
5428
5429           Handle(AIS_InteractiveObject) aIObj =
5430             Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName));
5431
5432           if (toSet)
5433             aIObj->AddClipPlane (aClipPlane);
5434           else
5435             aIObj->RemoveClipPlane (aClipPlane);
5436         }
5437         else // to view
5438         {
5439           if (!ViewerTest_myViews.IsBound1 (anEntityName))
5440           {
5441             theDi << theArgVec[0] << ": can not find View with name " << anEntityName << ".\n";
5442             continue;
5443           }
5444
5445           Handle(V3d_View) aView = ViewerTest_myViews.Find1(anEntityName);
5446           if (toSet)
5447             aView->AddClipPlane (aClipPlane);
5448           else
5449             aView->RemoveClipPlane (aClipPlane);
5450         }
5451       }
5452
5453       ViewerTest::RedrawAllViews();
5454     }
5455
5456     return 0;
5457   }
5458
5459   // change plane command
5460   if (aCommand == "change")
5461   {
5462     if (theArgsNb < 4)
5463     {
5464       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5465       return 1;
5466     }
5467
5468     TCollection_AsciiString aPlane (theArgVec [2]);
5469     if (!aRegPlanes.IsBound (aPlane))
5470     {
5471       theDi << theArgVec[0] << ": no such plane.\n";
5472       return 1;
5473     }
5474
5475     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
5476
5477     TCollection_AsciiString aChangeArg (theArgVec [3]);
5478     if (aChangeArg != "on" && aChangeArg != "off" && aChangeArg != "capping" && aChangeArg != "equation")
5479     {
5480       theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
5481       return 1;
5482     }
5483
5484     if (aChangeArg == "on" || aChangeArg == "off") // on / off
5485     {
5486       aClipPlane->SetOn (aChangeArg == "on");
5487     }
5488     else if (aChangeArg == "equation") // change equation
5489     {
5490       if (theArgsNb < 8)
5491       {
5492         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5493         return 1;
5494       }
5495
5496       Standard_Real aCoeffA = Draw::Atof (theArgVec [4]);
5497       Standard_Real aCoeffB = Draw::Atof (theArgVec [5]);
5498       Standard_Real aCoeffC = Draw::Atof (theArgVec [6]);
5499       Standard_Real aCoeffD = Draw::Atof (theArgVec [7]);
5500       aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
5501     }
5502     else if (aChangeArg == "capping") // change capping aspects
5503     {
5504       if (theArgsNb < 5)
5505       {
5506         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5507         return 1;
5508       }
5509
5510       TCollection_AsciiString aCappingArg (theArgVec [4]);
5511       if (aCappingArg != "on" && aCappingArg != "off" &&
5512           aCappingArg != "color" && aCappingArg != "texname" &&
5513           aCappingArg != "texscale" && aCappingArg != "texorigin" &&
5514           aCappingArg != "texrotate" && aCappingArg != "hatch")
5515       {
5516         theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
5517         return 1;
5518       }
5519
5520       if (aCappingArg == "on" || aCappingArg == "off") // on / off capping
5521       {
5522         aClipPlane->SetCapping (aCappingArg == "on");
5523       }
5524       else if (aCappingArg == "color") // color aspect for capping
5525       {
5526         if (theArgsNb < 8)
5527         {
5528           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5529           return 1;
5530         }
5531
5532         Standard_Real aRed = Draw::Atof (theArgVec [5]);
5533         Standard_Real aGrn = Draw::Atof (theArgVec [6]);
5534         Standard_Real aBlu = Draw::Atof (theArgVec [7]);
5535
5536         Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
5537         Quantity_Color aColor (aRed, aGrn, aBlu, Quantity_TOC_RGB);
5538         aMat.SetAmbientColor (aColor);
5539         aMat.SetDiffuseColor (aColor);
5540         aClipPlane->SetCappingMaterial (aMat);
5541       }
5542       else if (aCappingArg == "texname") // texture name
5543       {
5544         if (theArgsNb < 6)
5545         {
5546           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5547           return 1;
5548         }
5549
5550         TCollection_AsciiString aTextureName (theArgVec [5]);
5551
5552         Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
5553         if (!aTexture->IsDone ())
5554         {
5555           aClipPlane->SetCappingTexture (NULL);
5556         }
5557         else
5558         {
5559           aTexture->EnableModulate();
5560           aTexture->EnableRepeat();
5561           aClipPlane->SetCappingTexture (aTexture);
5562         }
5563       }
5564       else if (aCappingArg == "texscale") // texture scale
5565       {
5566         if (aClipPlane->CappingTexture().IsNull())
5567         {
5568           theDi << theArgVec[0] << ": no texture is set.\n";
5569           return 1;
5570         }
5571
5572         if (theArgsNb < 7)
5573         {
5574           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5575           return 1;
5576         }
5577
5578         Standard_ShortReal aSx = (Standard_ShortReal)atof (theArgVec [5]);
5579         Standard_ShortReal aSy = (Standard_ShortReal)atof (theArgVec [6]);
5580
5581         aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
5582       }
5583       else if (aCappingArg == "texorigin") // texture origin
5584       {
5585         if (aClipPlane->CappingTexture().IsNull())
5586         {
5587           theDi << theArgVec[0] << ": no texture is set.\n";
5588           return 1;
5589         }
5590
5591         if (theArgsNb < 7)
5592         {
5593           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5594           return 1;
5595         }
5596
5597         Standard_ShortReal aTx = (Standard_ShortReal)atof (theArgVec [5]);
5598         Standard_ShortReal aTy = (Standard_ShortReal)atof (theArgVec [6]);
5599
5600         aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
5601       }
5602       else if (aCappingArg == "texrotate") // texture rotation
5603       {
5604         if (aClipPlane->CappingTexture().IsNull())
5605         {
5606           theDi << theArgVec[0] << ": no texture is set.\n";
5607           return 1;
5608         }
5609
5610         if (theArgsNb < 6)
5611         {
5612           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5613           return 1;
5614         }
5615
5616         Standard_ShortReal aRot = (Standard_ShortReal)atof (theArgVec[5]);
5617
5618         aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
5619       }
5620       else if (aCappingArg == "hatch") // hatch style
5621       {
5622         if (theArgsNb < 6)
5623         {
5624           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
5625           return 1;
5626         }
5627
5628         TCollection_AsciiString aHatchStr (theArgVec [5]);
5629         if (aHatchStr == "on")
5630         {
5631           aClipPlane->SetCappingHatchOn();
5632         }
5633         else if (aHatchStr == "off")
5634         {
5635           aClipPlane->SetCappingHatchOff();
5636         }
5637         else
5638         {
5639           aClipPlane->SetCappingHatch ((Aspect_HatchStyle)atoi (theArgVec[5]));
5640         }
5641       }
5642     }
5643
5644     ViewerTest::RedrawAllViews();
5645
5646     return 0;
5647   }
5648
5649   theDi << theArgVec[0] << ": invalid command. Type help for more information.\n";
5650   return 1;
5651 }
5652
5653 //===============================================================================================
5654 //function : VSetTextureMode
5655 //purpose  :
5656 //===============================================================================================
5657 static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5658 {
5659   if (theArgsNb < 3)
5660   {
5661     theDi << theArgVec[0] << ": insufficient command arguments. Type help for more information.\n";
5662     return 1;
5663   }
5664
5665   TCollection_AsciiString aViewName (theArgVec[1]);
5666   if (!ViewerTest_myViews.IsBound1 (aViewName))
5667   {
5668     theDi << theArgVec[0] << ": view is not found.\n";
5669     return 1;
5670   }
5671
5672   const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
5673   switch (atoi (theArgVec[2]))
5674   {
5675     case 0: aView->SetSurfaceDetail (V3d_TEX_NONE); break;
5676     case 1: aView->SetSurfaceDetail (V3d_TEX_ENVIRONMENT); break;
5677     case 2: aView->SetSurfaceDetail (V3d_TEX_ALL); break;
5678     default:
5679       theDi << theArgVec[0] << ": invalid mode.\n";
5680       return 1;
5681   }
5682
5683   aView->Redraw();
5684   return 0;
5685 }
5686
5687 //===============================================================================================
5688 //function : VZRange
5689 //purpose  :
5690 //===============================================================================================
5691 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5692 {
5693   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
5694
5695   if (aCurrentView.IsNull())
5696   {
5697     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
5698     return 1;
5699   }
5700
5701   Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
5702
5703   if (theArgsNb < 2)
5704   {
5705     theDi << "ZNear: " << aCamera->ZNear() << "\n";
5706     theDi << "ZFar: " << aCamera->ZFar() << "\n";
5707     return 0;
5708   }
5709
5710   if (theArgsNb == 3)
5711   {
5712     Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
5713     Standard_Real aNewZFar  = Draw::Atof (theArgVec[2]);
5714
5715     if (aNewZNear >= aNewZFar)
5716     {
5717       std::cout << theArgVec[0] << ": invalid arguments: znear should be less than zfar.\n";
5718       return 1;
5719     }
5720
5721     if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
5722     {
5723       std::cout << theArgVec[0] << ": invalid arguments: ";
5724       std::cout << "znear, zfar should be positive for perspective camera.\n";
5725       return 1;
5726     }
5727
5728     aCamera->SetZRange (aNewZNear, aNewZFar);
5729   }
5730   else
5731   {
5732     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
5733     return 1;
5734   }
5735
5736   aCurrentView->Redraw();
5737
5738   return 0;
5739 }
5740
5741 //===============================================================================================
5742 //function : VAutoZFit
5743 //purpose  :
5744 //===============================================================================================
5745 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5746 {
5747   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
5748
5749   if (aCurrentView.IsNull())
5750   {
5751     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
5752     return 1;
5753   }
5754
5755   Standard_Real aScale = aCurrentView->View()->AutoZFitScaleFactor();
5756
5757   if (theArgsNb > 3)
5758   {
5759     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
5760     return 1;
5761   }
5762
5763   if (theArgsNb < 2)
5764   {
5765     theDi << "Auto z-fit mode: " << "\n"
5766           << "On: " << (aCurrentView->View()->AutoZFitMode() ? "enabled" : "disabled") << "\n"
5767           << "Scale: " << aScale << "\n";
5768     return 0;
5769   }
5770
5771   Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
5772
5773   if (theArgsNb >= 3)
5774   {
5775     aScale = Draw::Atoi (theArgVec[2]);
5776   }
5777
5778   aCurrentView->View()->SetAutoZFitMode (isOn, aScale);
5779   aCurrentView->View()->AutoZFit();
5780   aCurrentView->Redraw();
5781
5782   return 0;
5783 }
5784
5785 //! Auxiliary function to print projection type
5786 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
5787 {
5788   switch (theProjType)
5789   {
5790     case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
5791     case Graphic3d_Camera::Projection_Perspective:  return "perspective";
5792     case Graphic3d_Camera::Projection_Stereo:       return "stereoscopic";
5793     case Graphic3d_Camera::Projection_MonoLeftEye:  return "monoLeftEye";
5794     case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
5795   }
5796   return "UNKNOWN";
5797 }
5798
5799 //===============================================================================================
5800 //function : VCamera
5801 //purpose  :
5802 //===============================================================================================
5803 static int VCamera (Draw_Interpretor& theDI,
5804                     Standard_Integer  theArgsNb,
5805                     const char**      theArgVec)
5806 {
5807   Handle(V3d_View) aView = ViewerTest::CurrentView();
5808   if (aView.IsNull())
5809   {
5810     std::cout << "Error: no active view.\n";
5811     return 1;
5812   }
5813
5814   Handle(Graphic3d_Camera) aCamera = aView->Camera();
5815   if (theArgsNb < 2)
5816   {
5817     theDI << "ProjType:   " << projTypeName (aCamera->ProjectionType()) << "\n";
5818     theDI << "FOVy:       " << aCamera->FOVy() << "\n";
5819     theDI << "Distance:   " << aCamera->Distance() << "\n";
5820     theDI << "IOD:        " << aCamera->IOD() << "\n";
5821     theDI << "IODType:    " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute   ? "absolute" : "relative") << "\n";
5822     theDI << "ZFocus:     " << aCamera->ZFocus() << "\n";
5823     theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
5824     return 0;
5825   }
5826
5827   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
5828   {
5829     Standard_CString        anArg = theArgVec[anArgIter];
5830     TCollection_AsciiString anArgCase (anArg);
5831     anArgCase.LowerCase();
5832     if (anArgCase == "-proj"
5833      || anArgCase == "-projection"
5834      || anArgCase == "-projtype"
5835      || anArgCase == "-projectiontype")
5836     {
5837       theDI << projTypeName (aCamera->ProjectionType()) << " ";
5838     }
5839     else if (anArgCase == "-ortho"
5840           || anArgCase == "-orthographic")
5841     {
5842       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
5843     }
5844     else if (anArgCase == "-persp"
5845           || anArgCase == "-perspective"
5846           || anArgCase == "-perspmono"
5847           || anArgCase == "-perspectivemono"
5848           || anArgCase == "-mono")
5849     {
5850       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
5851     }
5852     else if (anArgCase == "-stereo"
5853           || anArgCase == "-stereoscopic"
5854           || anArgCase == "-perspstereo"
5855           || anArgCase == "-perspectivestereo")
5856     {
5857       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
5858     }
5859     else if (anArgCase == "-left"
5860           || anArgCase == "-lefteye"
5861           || anArgCase == "-monoleft"
5862           || anArgCase == "-monolefteye"
5863           || anArgCase == "-perpsleft"
5864           || anArgCase == "-perpslefteye")
5865     {
5866       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
5867     }
5868     else if (anArgCase == "-right"
5869           || anArgCase == "-righteye"
5870           || anArgCase == "-monoright"
5871           || anArgCase == "-monorighteye"
5872           || anArgCase == "-perpsright")
5873     {
5874       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
5875     }
5876     else if (anArgCase == "-dist"
5877           || anArgCase == "-distance")
5878     {
5879       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
5880       if (anArgValue != NULL
5881       && *anArgValue != '-')
5882       {
5883         ++anArgIter;
5884         aCamera->SetDistance (Draw::Atof (anArgValue));
5885         continue;
5886       }
5887       theDI << aCamera->Distance() << " ";
5888     }
5889     else if (anArgCase == "-iod")
5890     {
5891       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
5892       if (anArgValue != NULL
5893       && *anArgValue != '-')
5894       {
5895         ++anArgIter;
5896         aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
5897         continue;
5898       }
5899       theDI << aCamera->IOD() << " ";
5900     }
5901     else if (anArgCase == "-iodtype")
5902     {
5903       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
5904       TCollection_AsciiString anValueCase (anArgValue);
5905       anValueCase.LowerCase();
5906       if (anValueCase == "abs"
5907        || anValueCase == "absolute")
5908       {
5909         ++anArgIter;
5910         aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
5911         continue;
5912       }
5913       else if (anValueCase == "rel"
5914             || anValueCase == "relative")
5915       {
5916         ++anArgIter;
5917         aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
5918         continue;
5919       }
5920       else if (*anArgValue != '-')
5921       {
5922         std::cout << "Error: unknown IOD type '" << anArgValue << "'\n";
5923         return 1;
5924       }
5925       switch (aCamera->GetIODType())
5926       {
5927         case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
5928         case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
5929       }
5930     }
5931     else if (anArgCase == "-zfocus")
5932     {
5933       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
5934       if (anArgValue != NULL
5935       && *anArgValue != '-')
5936       {
5937         ++anArgIter;
5938         aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
5939         continue;
5940       }
5941       theDI << aCamera->ZFocus() << " ";
5942     }
5943     else if (anArgCase == "-zfocustype")
5944     {
5945       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
5946       TCollection_AsciiString anValueCase (anArgValue);
5947       anValueCase.LowerCase();
5948       if (anValueCase == "abs"
5949        || anValueCase == "absolute")
5950       {
5951         ++anArgIter;
5952         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
5953         continue;
5954       }
5955       else if (anValueCase == "rel"
5956             || anValueCase == "relative")
5957       {
5958         ++anArgIter;
5959         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
5960         continue;
5961       }
5962       else if (*anArgValue != '-')
5963       {
5964         std::cout << "Error: unknown ZFocus type '" << anArgValue << "'\n";
5965         return 1;
5966       }
5967       switch (aCamera->ZFocusType())
5968       {
5969         case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
5970         case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
5971       }
5972     }
5973     else if (anArgCase == "-fov"
5974           || anArgCase == "-fovy")
5975     {
5976       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
5977       if (anArgValue != NULL
5978       && *anArgValue != '-')
5979       {
5980         ++anArgIter;
5981         aCamera->SetFOVy (Draw::Atof (anArgValue));
5982         continue;
5983       }
5984       theDI << aCamera->FOVy() << " ";
5985     }
5986     else
5987     {
5988       std::cout << "Error: unknown argument '" << anArg << "'\n";
5989       return 1;
5990     }
5991   }
5992
5993   aView->View()->AutoZFit();
5994   aView->Redraw();
5995
5996   return 0;
5997 }
5998
5999 //==============================================================================
6000 //function : VStereo
6001 //purpose  :
6002 //==============================================================================
6003
6004 static int VStereo (Draw_Interpretor& theDI,
6005                     Standard_Integer  theArgNb,
6006                     const char**      theArgVec)
6007 {
6008   if (theArgNb < 2)
6009   {
6010     Handle(V3d_View) aView = ViewerTest::CurrentView();
6011     if (aView.IsNull())
6012     {
6013       std::cerr << "No active view. Please call vinit.\n";
6014       return 0;
6015     }
6016
6017     Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
6018     theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
6019     return 0;
6020   }
6021
6022   ViewerTest_myDefaultCaps.contextStereo = Draw::Atoi (theArgVec[1]) != 0;
6023   return 0;
6024 }
6025
6026 //===============================================================================================
6027 //function : VDefaults
6028 //purpose  :
6029 //===============================================================================================
6030 static int VDefaults (Draw_Interpretor& theDi,
6031                       Standard_Integer  theArgsNb,
6032                       const char**      theArgVec)
6033 {
6034   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6035   if (aCtx.IsNull())
6036   {
6037     std::cerr << "No active viewer!\n";
6038     return 1;
6039   }
6040
6041   Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
6042   if (theArgsNb < 2)
6043   {
6044     if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
6045     {
6046       theDi << "DeflType:           relative\n"
6047             << "DeviationCoeff:     " << aDefParams->DeviationCoefficient() << "\n";
6048     }
6049     else
6050     {
6051       theDi << "DeflType:           absolute\n"
6052             << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
6053     }
6054     theDi << "AngularDeflection:  " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
6055     return 0;
6056   }
6057
6058   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6059   {
6060     TCollection_AsciiString anArg (theArgVec[anArgIter]);
6061     TCollection_AsciiString aKey, aValue;
6062     if (!ViewerTest::SplitParameter (anArg, aKey, aValue)
6063      || aValue.IsEmpty())
6064     {
6065       std::cerr << "Error, wrong syntax at: '" << anArg.ToCString() << "'!\n";
6066       return 1;
6067     }
6068
6069     aKey.UpperCase();
6070     if (aKey == "ABSDEFL"
6071      || aKey == "ABSOLUTEDEFLECTION"
6072      || aKey == "DEFL"
6073      || aKey == "DEFLECTION")
6074     {
6075       aDefParams->SetTypeOfDeflection         (Aspect_TOD_ABSOLUTE);
6076       aDefParams->SetMaximalChordialDeviation (aValue.RealValue());
6077     }
6078     else if (aKey == "RELDEFL"
6079           || aKey == "RELATIVEDEFLECTION"
6080           || aKey == "DEVCOEFF"
6081           || aKey == "DEVIATIONCOEFF"
6082           || aKey == "DEVIATIONCOEFFICIENT")
6083     {
6084       aDefParams->SetTypeOfDeflection     (Aspect_TOD_RELATIVE);
6085       aDefParams->SetDeviationCoefficient (aValue.RealValue());
6086     }
6087     else if (aKey == "ANGDEFL"
6088           || aKey == "ANGULARDEFL"
6089           || aKey == "ANGULARDEFLECTION")
6090     {
6091       // currently HLRDeviationAngle is used instead of DeviationAngle in most places
6092       aDefParams->SetHLRAngle (M_PI * aValue.RealValue() / 180.0);
6093     }
6094     else
6095     {
6096       std::cerr << "Warning, unknown argument '" << anArg.ToCString() << "'\n";
6097     }
6098   }
6099
6100   return 0;
6101 }
6102
6103 //! Auxiliary method
6104 inline void addLight (const Handle(V3d_Light)& theLightNew,
6105                       const Standard_Boolean   theIsGlobal)
6106 {
6107   if (theLightNew.IsNull())
6108   {
6109     return;
6110   }
6111
6112   if (theIsGlobal)
6113   {
6114     ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew);
6115   }
6116   else
6117   {
6118     ViewerTest::CurrentView()->SetLightOn (theLightNew);
6119   }
6120 }
6121
6122 //! Auxiliary method
6123 inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
6124 {
6125   TCollection_AsciiString anArgNextCase (theArgNext);
6126   anArgNextCase.UpperCase();
6127   if (anArgNextCase.Length() > 5
6128    && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
6129   {
6130     return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
6131   }
6132   else
6133   {
6134     return theArgNext.IntegerValue();
6135   }
6136 }
6137
6138 //===============================================================================================
6139 //function : VLight
6140 //purpose  :
6141 //===============================================================================================
6142 static int VLight (Draw_Interpretor& theDi,
6143                    Standard_Integer  theArgsNb,
6144                    const char**      theArgVec)
6145 {
6146   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
6147   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6148   if (aView.IsNull()
6149    || aViewer.IsNull())
6150   {
6151     std::cerr << "No active viewer!\n";
6152     return 1;
6153   }
6154
6155   Standard_Real        anXYZ[3];
6156   Quantity_Coefficient anAtten[2];
6157   if (theArgsNb < 2)
6158   {
6159     // print lights info
6160     Standard_Integer aLightId = 0;
6161     for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightId)
6162     {
6163       Handle(V3d_Light) aLight = aView->ActiveLight();
6164       const Quantity_Color aColor = aLight->Color();
6165       theDi << "Light" << aLightId << "\n";
6166       switch (aLight->Type())
6167       {
6168         case V3d_AMBIENT:
6169         {
6170           theDi << "  Type:      Ambient\n";
6171           break;
6172         }
6173         case V3d_DIRECTIONAL:
6174         {
6175           Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
6176           theDi << "  Type:      Directional\n";
6177           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
6178           if (!aLightDir.IsNull())
6179           {
6180             aLightDir->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
6181             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
6182             aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
6183             theDi << "  Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
6184           }
6185           break;
6186         }
6187         case V3d_POSITIONAL:
6188         {
6189           Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
6190           theDi << "  Type:      Positional\n";
6191           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
6192           if (!aLightPos.IsNull())
6193           {
6194             aLightPos->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
6195             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
6196             aLightPos->Attenuation (anAtten[0], anAtten[1]);
6197             theDi << "  Atten.:    " << anAtten[0] << " " << anAtten[1] << "\n";
6198           }
6199           break;
6200         }
6201         case V3d_SPOT:
6202         {
6203           Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
6204           theDi << "  Type:      Spot\n";
6205           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
6206           if (!aLightSpot.IsNull())
6207           {
6208             aLightSpot->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
6209             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
6210             aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
6211             theDi << "  Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
6212             aLightSpot->Attenuation (anAtten[0], anAtten[1]);
6213             theDi << "  Atten.:    " << anAtten[0] << " " << anAtten[1] << "\n";
6214             theDi << "  Angle:     " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
6215             theDi << "  Exponent:  " << aLightSpot->Concentration() << "\n";
6216           }
6217           break;
6218         }
6219         default:
6220         {
6221           theDi << "  Type:      UNKNOWN\n";
6222           break;
6223         }
6224       }
6225       theDi << "  Color:     " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n";
6226     }
6227   }
6228
6229   Handle(V3d_Light) aLightNew;
6230   Handle(V3d_Light) aLightOld;
6231   Standard_Boolean  isGlobal = Standard_True;
6232   Standard_Boolean  toCreate = Standard_False;
6233   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
6234   {
6235     Handle(V3d_Light)            aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
6236     Handle(V3d_AmbientLight)     aLightAmb  = Handle(V3d_AmbientLight)    ::DownCast (aLightCurr);
6237     Handle(V3d_DirectionalLight) aLightDir  = Handle(V3d_DirectionalLight)::DownCast (aLightCurr);
6238     Handle(V3d_PositionalLight)  aLightPos  = Handle(V3d_PositionalLight) ::DownCast (aLightCurr);
6239     Handle(V3d_SpotLight)        aLightSpot = Handle(V3d_SpotLight)       ::DownCast (aLightCurr);
6240
6241     TCollection_AsciiString aName, aValue;
6242     const TCollection_AsciiString anArg (theArgVec[anArgIt]);
6243     TCollection_AsciiString anArgCase (anArg);
6244     anArgCase.UpperCase();
6245     if (anArgCase.IsEqual ("NEW")
6246      || anArgCase.IsEqual ("ADD")
6247      || anArgCase.IsEqual ("CREATE"))
6248     {
6249       toCreate = Standard_True;
6250     }
6251     else if (anArgCase.IsEqual ("GLOB")
6252           || anArgCase.IsEqual ("GLOBAL"))
6253     {
6254       isGlobal = Standard_True;
6255     }
6256     else if (anArgCase.IsEqual ("LOC")
6257           || anArgCase.IsEqual ("LOCAL"))
6258     {
6259       isGlobal = Standard_False;
6260     }
6261     else if (anArgCase.IsEqual ("DEF")
6262           || anArgCase.IsEqual ("DEFAULTS"))
6263     {
6264       toCreate = Standard_False;
6265       aViewer->SetDefaultLights();
6266     }
6267     else if (anArgCase.IsEqual ("CLR")
6268           || anArgCase.IsEqual ("CLEAR"))
6269     {
6270       toCreate = Standard_False;
6271       aView->InitActiveLights();
6272       while (aView->MoreActiveLights())
6273       {
6274         aViewer->DelLight (aView->ActiveLight());
6275         aView->InitActiveLights();
6276       }
6277     }
6278     else if (anArgCase.IsEqual ("AMB")
6279           || anArgCase.IsEqual ("AMBIENT")
6280           || anArgCase.IsEqual ("AMBLIGHT"))
6281     {
6282       addLight (aLightNew, isGlobal);
6283       if (!toCreate)
6284       {
6285         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6286         return 1;
6287       }
6288       toCreate  = Standard_False;
6289       aLightNew = new V3d_AmbientLight (aViewer);
6290     }
6291     else if (anArgCase.IsEqual ("DIRECTIONAL")
6292           || anArgCase.IsEqual ("DIRLIGHT"))
6293     {
6294       addLight (aLightNew, isGlobal);
6295       if (!toCreate)
6296       {
6297         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6298         return 1;
6299       }
6300       toCreate  = Standard_False;
6301       aLightNew = new V3d_DirectionalLight (aViewer);
6302     }
6303     else if (anArgCase.IsEqual ("SPOT")
6304           || anArgCase.IsEqual ("SPOTLIGHT"))
6305     {
6306       addLight (aLightNew, isGlobal);
6307       if (!toCreate)
6308       {
6309         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6310         return 1;
6311       }
6312       toCreate  = Standard_False;
6313       aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0);
6314     }
6315     else if (anArgCase.IsEqual ("POSLIGHT")
6316           || anArgCase.IsEqual ("POSITIONAL"))
6317     {
6318       addLight (aLightNew, isGlobal);
6319       if (!toCreate)
6320       {
6321         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6322         return 1;
6323       }
6324       toCreate  = Standard_False;
6325       aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0);
6326     }
6327     else if (anArgCase.IsEqual ("CHANGE"))
6328     {
6329       addLight (aLightNew, isGlobal);
6330       aLightNew.Nullify();
6331       if (++anArgIt >= theArgsNb)
6332       {
6333         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6334         return 1;
6335       }
6336
6337       const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
6338       Standard_Integer aLightIt = 0;
6339       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
6340       {
6341         if (aLightIt == aLightId)
6342         {
6343           aLightOld = aView->ActiveLight();
6344           break;
6345         }
6346       }
6347
6348       if (aLightOld.IsNull())
6349       {
6350         std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n";
6351         return 1;
6352       }
6353     }
6354     else if (anArgCase.IsEqual ("DEL")
6355           || anArgCase.IsEqual ("DELETE"))
6356     {
6357       Handle(V3d_Light) aLightDel;
6358       if (++anArgIt >= theArgsNb)
6359       {
6360         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6361         return 1;
6362       }
6363
6364       const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
6365       const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
6366       Standard_Integer aLightIt = 0;
6367       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
6368       {
6369         aLightDel = aView->ActiveLight();
6370         if (aLightIt == aLightDelId)
6371         {
6372           break;
6373         }
6374       }
6375       if (!aLightDel.IsNull())
6376       {
6377         aViewer->DelLight (aLightDel);
6378       }
6379     }
6380     else if (anArgCase.IsEqual ("COLOR")
6381           || anArgCase.IsEqual ("COLOUR"))
6382     {
6383       if (++anArgIt >= theArgsNb)
6384       {
6385         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6386         return 1;
6387       }
6388
6389       TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
6390       anArgNext.UpperCase();
6391       const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
6392       if (!aLightCurr.IsNull())
6393       {
6394         aLightCurr->SetColor (aColor);
6395       }
6396     }
6397     else if (anArgCase.IsEqual ("POS")
6398           || anArgCase.IsEqual ("POSITION"))
6399     {
6400       if ((anArgIt + 3) >= theArgsNb)
6401       {
6402         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6403         return 1;
6404       }
6405
6406       anXYZ[0] = Atof (theArgVec[++anArgIt]);
6407       anXYZ[1] = Atof (theArgVec[++anArgIt]);
6408       anXYZ[2] = Atof (theArgVec[++anArgIt]);
6409       if (!aLightDir.IsNull())
6410       {
6411         aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
6412       }
6413       else if (!aLightPos.IsNull())
6414       {
6415         aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
6416       }
6417       else if (!aLightSpot.IsNull())
6418       {
6419         aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
6420       }
6421       else
6422       {
6423         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6424         return 1;
6425       }
6426     }
6427     else if (anArgCase.IsEqual ("DIR")
6428           || anArgCase.IsEqual ("DIRECTION"))
6429     {
6430       if ((anArgIt + 3) >= theArgsNb)
6431       {
6432         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6433         return 1;
6434       }
6435
6436       anXYZ[0] = Atof (theArgVec[++anArgIt]);
6437       anXYZ[1] = Atof (theArgVec[++anArgIt]);
6438       anXYZ[2] = Atof (theArgVec[++anArgIt]);
6439       if (!aLightDir.IsNull())
6440       {
6441         aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
6442       }
6443       else if (!aLightSpot.IsNull())
6444       {
6445         aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
6446       }
6447       else
6448       {
6449         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6450         return 1;
6451       }
6452     }
6453     else if (anArgCase.IsEqual ("ANG")
6454           || anArgCase.IsEqual ("ANGLE"))
6455     {
6456       if (++anArgIt >= theArgsNb)
6457       {
6458         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6459         return 1;
6460       }
6461
6462       Standard_Real anAngle = Atof (theArgVec[anArgIt]);
6463
6464       if (!aLightSpot.IsNull())
6465       {
6466         aLightSpot->SetAngle (anAngle / 180.0 * M_PI);
6467       }
6468     }
6469     else if (anArgCase.IsEqual ("CONSTATTEN")
6470           || anArgCase.IsEqual ("CONSTATTENUATION"))
6471     {
6472       if (++anArgIt >= theArgsNb)
6473       {
6474         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6475         return 1;
6476       }
6477
6478       if (!aLightPos.IsNull())
6479       {
6480         aLightPos->Attenuation (anAtten[0], anAtten[1]);
6481         anAtten[0] = Atof (theArgVec[anArgIt]);
6482         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
6483       }
6484       else if (!aLightSpot.IsNull())
6485       {
6486         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
6487         anAtten[0] = Atof (theArgVec[anArgIt]);
6488         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
6489       }
6490       else
6491       {
6492         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6493         return 1;
6494       }
6495     }
6496     else if (anArgCase.IsEqual ("LINATTEN")
6497           || anArgCase.IsEqual ("LINEARATTEN")
6498           || anArgCase.IsEqual ("LINEARATTENUATION"))
6499     {
6500       if (++anArgIt >= theArgsNb)
6501       {
6502         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6503         return 1;
6504       }
6505
6506       if (!aLightPos.IsNull())
6507       {
6508         aLightPos->Attenuation (anAtten[0], anAtten[1]);
6509         anAtten[1] = Atof (theArgVec[anArgIt]);
6510         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
6511       }
6512       else if (!aLightSpot.IsNull())
6513       {
6514         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
6515         anAtten[1] = Atof (theArgVec[anArgIt]);
6516         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
6517       }
6518       else
6519       {
6520         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6521         return 1;
6522       }
6523     }
6524     else if (anArgCase.IsEqual ("EXP")
6525           || anArgCase.IsEqual ("EXPONENT")
6526           || anArgCase.IsEqual ("SPOTEXP")
6527           || anArgCase.IsEqual ("SPOTEXPONENT"))
6528     {
6529       if (++anArgIt >= theArgsNb)
6530       {
6531         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6532         return 1;
6533       }
6534
6535       if (!aLightSpot.IsNull())
6536       {
6537         aLightSpot->SetConcentration (Atof (theArgVec[anArgIt]));
6538       }
6539       else
6540       {
6541         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6542         return 1;
6543       }
6544     }
6545     else if (anArgCase.IsEqual ("HEAD")
6546           || anArgCase.IsEqual ("HEADLIGHT"))
6547     {
6548       if (++anArgIt >= theArgsNb)
6549       {
6550         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6551         return 1;
6552       }
6553
6554       if (aLightAmb.IsNull()
6555        && !aLightCurr.IsNull())
6556       {
6557         aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0);
6558       }
6559       else
6560       {
6561         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
6562         return 1;
6563       }
6564     }
6565     else
6566     {
6567       std::cerr << "Warning: unknown argument '" << anArg << "'\n";
6568     }
6569   }
6570
6571   addLight (aLightNew, isGlobal);
6572   aViewer->UpdateLights();
6573
6574   return 0;
6575 }
6576
6577 //=======================================================================
6578 //function : VRenderParams
6579 //purpose  : Enables/disables rendering features
6580 //=======================================================================
6581
6582 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
6583                                        Standard_Integer  theArgNb,
6584                                        const char**      theArgVec)
6585 {
6586   Handle(V3d_View) aView = ViewerTest::CurrentView();
6587   if (aView.IsNull())
6588   {
6589     std::cerr << "Error: no active viewer!\n";
6590     return 1;
6591   }
6592
6593   Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6594   TCollection_AsciiString aCmdName (theArgVec[0]);
6595   aCmdName.LowerCase();
6596   if (aCmdName == "vraytrace")
6597   {
6598     if (theArgNb == 1)
6599     {
6600       theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
6601       return 0;
6602     }
6603     else if (theArgNb == 2)
6604     {
6605       TCollection_AsciiString aValue (theArgVec[1]);
6606       aValue.LowerCase();
6607       if (aValue == "on"
6608        || aValue == "1")
6609       {
6610         aParams.Method = Graphic3d_RM_RAYTRACING;
6611         aView->Redraw();
6612         return 0;
6613       }
6614       else if (aValue == "off"
6615             || aValue == "0")
6616       {
6617         aParams.Method = Graphic3d_RM_RASTERIZATION;
6618         aView->Redraw();
6619         return 0;
6620       }
6621       else
6622       {
6623         std::cout << "Error: unknown argument '" << theArgVec[1] << "'\n";
6624         return 1;
6625       }
6626     }
6627     else
6628     {
6629       std::cout << "Error: wrong number of arguments\n";
6630       return 1;
6631     }
6632   }
6633
6634   if (theArgNb < 2)
6635   {
6636     theDI << "renderMode:  ";
6637     switch (aParams.Method)
6638     {
6639       case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
6640       case Graphic3d_RM_RAYTRACING:    theDI << "raytrace ";      break;
6641     }
6642     theDI << "\n";
6643     theDI << "fsaa:         " << (aParams.IsAntialiasingEnabled      ? "on" : "off") << "\n";
6644     theDI << "shadows:      " << (aParams.IsShadowEnabled            ? "on" : "off") << "\n";
6645     theDI << "reflections:  " << (aParams.IsReflectionEnabled        ? "on" : "off") << "\n";
6646     theDI << "rayDepth:     " <<  aParams.RaytracingDepth                            << "\n";
6647     theDI << "gleam:        " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
6648     theDI << "shadingModel: ";
6649     switch (aView->ShadingModel())
6650     {
6651       case V3d_COLOR:   theDI << "color";   break;
6652       case V3d_FLAT:    theDI << "flat";    break;
6653       case V3d_GOURAUD: theDI << "gouraud"; break;
6654       case V3d_PHONG:   theDI << "phong";   break;
6655     }
6656     theDI << "\n";
6657     return 0;
6658   }
6659
6660   Standard_Boolean toPrint = Standard_False;
6661   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
6662   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6663   {
6664     Standard_CString        anArg (theArgVec[anArgIter]);
6665     TCollection_AsciiString aFlag (anArg);
6666     aFlag.LowerCase();
6667     if (anUpdateTool.parseRedrawMode (aFlag))
6668     {
6669       continue;
6670     }
6671     else if (aFlag == "-echo"
6672           || aFlag == "-print")
6673     {
6674       toPrint = Standard_True;
6675       anUpdateTool.Invalidate();
6676     }
6677     else if (aFlag == "-mode"
6678           || aFlag == "-rendermode"
6679           || aFlag == "-render_mode")
6680     {
6681       if (toPrint)
6682       {
6683         switch (aParams.Method)
6684         {
6685           case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
6686           case Graphic3d_RM_RAYTRACING:    theDI << "ray-tracing ";   break;
6687         }
6688         continue;
6689       }
6690       else
6691       {
6692         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
6693         return 1;
6694       }
6695     }
6696     else if (aFlag == "-ray"
6697           || aFlag == "-raytrace")
6698     {
6699       if (toPrint)
6700       {
6701         theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
6702         continue;
6703       }
6704
6705       aParams.Method = Graphic3d_RM_RAYTRACING;
6706     }
6707     else if (aFlag == "-rast"
6708           || aFlag == "-raster"
6709           || aFlag == "-rasterization")
6710     {
6711       if (toPrint)
6712       {
6713         theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
6714         continue;
6715       }
6716
6717       aParams.Method = Graphic3d_RM_RASTERIZATION;
6718     }
6719     else if (aFlag == "-raydepth"
6720           || aFlag == "-ray_depth")
6721     {
6722       if (toPrint)
6723       {
6724         theDI << aParams.RaytracingDepth << " ";
6725         continue;
6726       }
6727       else if (++anArgIter >= theArgNb)
6728       {
6729         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
6730         return 1;
6731       }
6732
6733       const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
6734       if (aDepth < 1 || aDepth > 10)
6735       {
6736         std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
6737         return 1;
6738       }
6739       else
6740       {
6741         aParams.RaytracingDepth = aDepth;
6742       }
6743     }
6744     else if (aFlag == "-shad"
6745           || aFlag == "-shadows")
6746     {
6747       if (toPrint)
6748       {
6749         theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
6750         continue;
6751       }
6752
6753       Standard_Boolean toEnable = Standard_True;
6754       if (++anArgIter < theArgNb
6755       && !parseOnOff (theArgVec[anArgIter], toEnable))
6756       {
6757         --anArgIter;
6758       }
6759       aParams.IsShadowEnabled = toEnable;
6760     }
6761     else if (aFlag == "-refl"
6762           || aFlag == "-reflections")
6763     {
6764       if (toPrint)
6765       {
6766         theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
6767         continue;
6768       }
6769
6770       Standard_Boolean toEnable = Standard_True;
6771       if (++anArgIter < theArgNb
6772       && !parseOnOff (theArgVec[anArgIter], toEnable))
6773       {
6774         --anArgIter;
6775       }
6776       aParams.IsReflectionEnabled = toEnable;
6777     }
6778     else if (aFlag == "-fsaa")
6779     {
6780       if (toPrint)
6781       {
6782         theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
6783         continue;
6784       }
6785
6786       Standard_Boolean toEnable = Standard_True;
6787       if (++anArgIter < theArgNb
6788       && !parseOnOff (theArgVec[anArgIter], toEnable))
6789       {
6790         --anArgIter;
6791       }
6792       aParams.IsAntialiasingEnabled = toEnable;
6793     }
6794     else if (aFlag == "-gleam")
6795     {
6796       if (toPrint)
6797       {
6798         theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
6799         continue;
6800       }
6801
6802       Standard_Boolean toEnable = Standard_True;
6803       if (++anArgIter < theArgNb
6804       && !parseOnOff (theArgVec[anArgIter], toEnable))
6805       {
6806         --anArgIter;
6807       }
6808       aParams.IsTransparentShadowEnabled = toEnable;
6809     }
6810     else if (aFlag == "-shademodel"
6811           || aFlag == "-shadingmodel"
6812           || aFlag == "-shading")
6813     {
6814       if (toPrint)
6815       {
6816         switch (aView->ShadingModel())
6817         {
6818           case V3d_COLOR:   theDI << "color ";   break;
6819           case V3d_FLAT:    theDI << "flat ";    break;
6820           case V3d_GOURAUD: theDI << "gouraud "; break;
6821           case V3d_PHONG:   theDI << "phong ";   break;
6822         }
6823         continue;
6824       }
6825
6826       if (++anArgIter >= theArgNb)
6827       {
6828         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
6829       }
6830
6831       TCollection_AsciiString aMode (theArgVec[anArgIter]);
6832       aMode.LowerCase();
6833       if (aMode == "color"
6834        || aMode == "none")
6835       {
6836         aView->SetShadingModel (V3d_COLOR);
6837       }
6838       else if (aMode == "flat"
6839             || aMode == "facet")
6840       {
6841         aView->SetShadingModel (V3d_FLAT);
6842       }
6843       else if (aMode == "gouraud"
6844             || aMode == "vertex"
6845             || aMode == "vert")
6846       {
6847         aView->SetShadingModel (V3d_GOURAUD);
6848       }
6849       else if (aMode == "phong"
6850             || aMode == "fragment"
6851             || aMode == "frag"
6852             || aMode == "pixel")
6853       {
6854         aView->SetShadingModel (V3d_PHONG);
6855       }
6856       else
6857       {
6858         std::cout << "Error: unknown shading model '" << aMode << "'\n";
6859         return 1;
6860       }
6861     }
6862     else
6863     {
6864       std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
6865       return 1;
6866     }
6867   }
6868   return 0;
6869 }
6870
6871 //=======================================================================
6872 //function : VFrustumCulling
6873 //purpose  : enables/disables view volume's culling.
6874 //=======================================================================
6875 static int VFrustumCulling (Draw_Interpretor& theDI,
6876                             Standard_Integer  theArgNb,
6877                             const char**      theArgVec)
6878 {
6879   Handle(V3d_View) aView = ViewerTest::CurrentView();
6880   if (aView.IsNull())
6881   {
6882     std::cout << theArgVec[0] << " Error: Use 'vinit' command before\n";
6883     return 1;
6884   }
6885
6886   if (theArgNb < 2)
6887   {
6888     theDI << (aView->IsCullingEnabled() ? "on" : "off");
6889     return 0;
6890   }
6891   else if (theArgNb != 2)
6892   {
6893     std::cout << theArgVec[0] << " Syntax error: Specify the mode\n";
6894     return 1;
6895   }
6896
6897   TCollection_AsciiString aModeStr (theArgVec[1]);
6898   aModeStr.LowerCase();
6899   Standard_Boolean toEnable = 0;
6900   if (aModeStr == "on")
6901   {
6902     toEnable = 1;
6903   }
6904   else if (aModeStr == "off")
6905   {
6906     toEnable = 0;
6907   }
6908   else
6909   {
6910     toEnable = Draw::Atoi (theArgVec[1]) != 0;
6911   }
6912
6913   aView->SetFrustumCulling (toEnable);
6914   aView->Redraw();
6915   return 0;
6916 }
6917
6918 //=======================================================================
6919 //function : VHighlightSelected
6920 //purpose  : 
6921 //=======================================================================
6922 static int VHighlightSelected (Draw_Interpretor& theDI,
6923                                Standard_Integer  theArgNb,
6924                                const char**      theArgVec)
6925 {
6926   if (ViewerTest::GetAISContext().IsNull())
6927   {
6928     std::cout << theArgVec[0] << " error : Context is not created. Please call vinit before.\n";
6929     return 1;
6930   }
6931
6932   const Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6933
6934   if (theArgNb < 2)
6935   {
6936     theDI << (aContext->ToHilightSelected() ? "on" : "off");
6937     return 0;
6938   }
6939
6940   if (theArgNb != 2)
6941   {
6942     std::cout  << theArgVec[0] << " error : wrong number of parameters."
6943           << "Type 'help" << theArgVec[0] << "' for more information.";
6944     return 1;
6945   }
6946
6947   // Parse parameter
6948   TCollection_AsciiString aMode (theArgVec[1]);
6949   aMode.LowerCase();
6950   Standard_Boolean toEnable = Standard_False;
6951   if (aMode.IsEqual ("on"))
6952   {
6953     toEnable = Standard_True;
6954   }
6955   else if (aMode.IsEqual ("off"))
6956   {
6957     toEnable = Standard_False;
6958   }
6959   else
6960   {
6961     toEnable = Draw::Atoi (theArgVec[1]) != 0;
6962   }
6963
6964   if (toEnable != aContext->ToHilightSelected())
6965   {
6966     aContext->SetToHilightSelected (toEnable);
6967
6968     // Move cursor to null position and  back to process updating of detection
6969     // and highlighting of selected object immediatly.
6970     Standard_Integer aPixX = 0;
6971     Standard_Integer aPixY = 0;
6972     const Handle(ViewerTest_EventManager)& anEventManager =  ViewerTest::CurrentEventManager();
6973
6974     anEventManager->GetCurrentPosition (aPixX, aPixY);
6975     anEventManager->MoveTo (0, 0);
6976     anEventManager->MoveTo (aPixX, aPixY);
6977   }
6978
6979   return 0;
6980 }
6981
6982 //=======================================================================
6983 //function : VXRotate
6984 //purpose  :
6985 //=======================================================================
6986 static Standard_Integer VXRotate (Draw_Interpretor& di,
6987                                    Standard_Integer argc,
6988                                    const char ** argv)
6989 {
6990   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6991   if (aContext.IsNull())
6992   {
6993     di << argv[0] << "ERROR : use 'vinit' command before " << "\n";
6994     return 1;
6995   }
6996   
6997   if (argc != 3)
6998   {
6999     di << "ERROR : Usage : " << argv[0] << " name angle" << "\n";
7000     return 1;
7001   }
7002
7003   TCollection_AsciiString aName (argv[1]);
7004   Standard_Real anAngle = Draw::Atof (argv[2]);
7005
7006   // find object
7007   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
7008   Handle(AIS_InteractiveObject) anIObj;
7009   if (!aMap.IsBound2 (aName) )
7010   {
7011     di << "Use 'vdisplay' before" << "\n";
7012     return 1;
7013   }
7014   else
7015   {
7016     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
7017
7018     gp_Trsf aTransform;
7019     aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
7020     aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
7021
7022     aContext->SetLocation (anIObj, aTransform);
7023     aContext->UpdateCurrentViewer();
7024   }
7025
7026   return 0;
7027 }
7028
7029 //=======================================================================
7030 //function : ViewerCommands
7031 //purpose  :
7032 //=======================================================================
7033
7034 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
7035 {
7036
7037   const char *group = "ZeViewer";
7038   theCommands.Add("vinit",
7039 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7040     "[name=view_name] [display=display_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
7041 #else
7042     "[name=view_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
7043 #endif
7044     " - Creates new View window with specified name view_name.\n"
7045     "By default the new view is created in the viewer and in"
7046     " graphic driver shared with active view.\n"
7047     " - name = {driverName/viewerName/viewName | viewerName/viewName | viewName}.\n"
7048     "If driverName isn't specified the driver will be shared with active view.\n"
7049     "If viewerName isn't specified the viewer will be shared with active view.\n"
7050 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7051     " - display = HostName.DisplayNumber[:ScreenNumber] : if specified"
7052     "is used in creation of graphic driver\n"
7053 #endif
7054     " - l, t: pixel position of left top corner of the window\n"
7055     " - w,h: width and heigth of window respectively.\n"
7056     "Additional commands for operations with views: vclose, vactivate, vviewlist.\n",
7057     __FILE__,VInit,group);
7058   theCommands.Add("vclose" ,
7059     "[view_id [keep_context=0|1]]\n"
7060     "or vclose ALL - to remove all created views\n"
7061     " - removes view(viewer window) defined by its view_id.\n"
7062     " - keep_context: by default 0; if 1 and the last view is deleted"
7063     " the current context is not removed.",
7064     __FILE__,VClose,group);
7065   theCommands.Add("vactivate" ,
7066     "view_id"
7067     " - activates view(viewer window) defined by its view_id",
7068     __FILE__,VActivate,group);
7069   theCommands.Add("vviewlist",
7070     "vviewlist [format={tree, long}]"
7071     " - prints current list of views per viewer and graphic_driver ID shared between viewers"
7072     " - format: format of result output, if tree the output is a tree view;"
7073     "otherwise it's a list of full view names. By default format = tree",
7074     __FILE__,VViewList,group);
7075   theCommands.Add("vhelp" ,
7076     "vhelp            : display help on the viewer commands",
7077     __FILE__,VHelp,group);
7078   theCommands.Add("vtop" ,
7079     "vtop or <T>      : Top view" ,
7080     __FILE__,VTop,group);
7081   theCommands.Add("vbottom" ,
7082     "vbottom          : Bottom view" ,
7083     __FILE__,VBottom,group);
7084   theCommands.Add("vleft" ,
7085     "vleft            : Left view" ,
7086     __FILE__,VLeft,group);
7087   theCommands.Add("vright" ,
7088     "vright           : Right view" ,
7089     __FILE__,VRight,group);
7090   theCommands.Add("vaxo" ,
7091     " vaxo or <A>     : Axonometric view ",
7092     __FILE__,VAxo,group);
7093   theCommands.Add("vfront" ,
7094     "vfront           : Front view" ,
7095     __FILE__,VFront,group);
7096   theCommands.Add("vback" ,
7097     "vback            : Back view" ,
7098     __FILE__,VBack,group);
7099   theCommands.Add("vpick" ,
7100     "vpick           : vpick X Y Z [shape subshape] ( all variables as string )",
7101     VPick,group);
7102   theCommands.Add("vfit"    ,
7103     "vfit or <F>         : vfit",
7104     __FILE__,VFit,group);
7105   theCommands.Add ("vzfit", "vzfit [scale]\n"
7106     "   Matches Z near, Z far view volume planes to the displayed objects.\n"
7107     "   \"scale\" - specifies factor to scale computed z range.\n",
7108     __FILE__, VZFit, group);
7109   theCommands.Add("vrepaint",
7110     "vrepaint        : vrepaint, force redraw",
7111     __FILE__,VRepaint,group);
7112   theCommands.Add("vclear",
7113     "vclear          : vclear",
7114     __FILE__,VClear,group);
7115   theCommands.Add("vsetbg",
7116     "vsetbg          : vsetbg imagefile [filltype] : Load image as background",
7117     __FILE__,VSetBg,group);
7118   theCommands.Add("vsetbgmode",
7119     "vsetbgmode      : vsetbgmode filltype : Change background image fill type",
7120     __FILE__,VSetBgMode,group);
7121   theCommands.Add("vsetgradientbg",
7122     "vsetgradientbg  : vsetgradientbg r1 g1 b1 r2 g2 b2 filltype : Mount gradient background",
7123     __FILE__,VSetGradientBg,group);
7124   theCommands.Add("vsetgrbgmode",
7125     "vsetgrbgmode    : vsetgrbgmode filltype : Change gradient background fill type",
7126     __FILE__,VSetGradientBgMode,group);
7127   theCommands.Add("vsetcolorbg",
7128     "vsetcolorbg     : vsetcolorbg r g b : Set background color",
7129     __FILE__,VSetColorBg,group);
7130   theCommands.Add("vscale",
7131     "vscale          : vscale X Y Z",
7132     __FILE__,VScale,group);
7133   theCommands.Add("vzbufftrihedron",
7134     "vzbufftrihedron [center|left_lower|left_upper|right_lower|right_upper"
7135     " textR=255 textG=255 textB=255 scale=0.1 wireframe|zbuffer]"
7136     " : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron",
7137     __FILE__,VTestZBuffTrihedron,group);
7138   theCommands.Add("vrotate",
7139     "vrotate         : vrotate AX AY AZ [X Y Z]",
7140     __FILE__,VRotate,group);
7141   theCommands.Add("vzoom",
7142     "vzoom           : vzoom coef",
7143     __FILE__,VZoom,group);
7144   theCommands.Add("vpan",
7145     "vpan            : vpan dx dy",
7146     __FILE__,VPan,group);
7147   theCommands.Add("vexport",
7148     "vexport         : vexport full_file_path {PS | EPS | TEX | PDF | SVG | PGF | EMF }"
7149     " : exports the view to a vector file of a given format"
7150     " : notice that EMF format requires patched gl2ps",
7151     __FILE__,VExport,group);
7152   theCommands.Add("vcolorscale",
7153     "vcolorscale     : vcolorscale [RangeMin = 0 RangeMax = 100 Intervals = 10 HeightFont = 16 Position = 2 X = 0 Y = 0]: draw color scale",
7154     __FILE__,VColorScale,group);
7155   theCommands.Add("vgraduatedtrihedron",
7156     "vgraduatedtrihedron : 1/0 (display/erase) [Xname Yname Zname [Font [isMultibyte]]]",
7157     __FILE__,VGraduatedTrihedron,group);
7158   theCommands.Add("vprintview" ,
7159     "vprintview : width height filename [algo=0] [tile_width tile_height] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
7160     __FILE__,VPrintView,group);
7161   theCommands.Add("vzlayer",
7162     "vzlayer add/del/get/settings/enable/disable [id]\n"
7163     " add - add new z layer to viewer and print its id\n"
7164     " del - del z layer by its id\n"
7165     " get - print sequence of z layers in increasing order of their overlay level\n"
7166     " settings - print status of z layer settings\n"
7167     " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n"
7168     " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n"
7169     " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n"
7170     "\nWhere id is the layer identificator\n"
7171     "\nExamples:\n"
7172     "   vzlayer add\n"
7173     "   vzlayer enable poffset 1\n"
7174     "   vzlayer disable depthtest 1\n"
7175     "   vzlayer del 1\n",
7176     __FILE__,VZLayer,group);
7177   theCommands.Add("voverlaytext",
7178     "voverlaytext : text x y [height] [font_name] [text_color: R G B] [display_type] [background_color: R G B]"
7179     " : height - pixel height of the text (default=10.0)"
7180     " : font_name - name of font (default=courier)"
7181     " : text_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0) "
7182     " : display_type = {normal/subtitle/decal/blend}, (default=normal) "
7183     " : background_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0), the parameter is defined for subtitle and decal display types ",
7184     __FILE__,VOverlayText,group);
7185   theCommands.Add("vlayerline",
7186     "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
7187     __FILE__,VLayerLine,group);
7188   theCommands.Add ("vgrid",
7189     "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]"
7190     " : Mode - rectangular or circular"
7191     " : Type - lines or points",
7192     __FILE__, VGrid, group);
7193   theCommands.Add ("vfps",
7194     "vfps [framesNb=100] : estimate average frame rate for active view",
7195     __FILE__, VFps, group);
7196   theCommands.Add ("vgldebug",
7197     "vgldebug [{0|1}] : request debug GL context, should be called before vinit\n"
7198     "                : this function is implemented only for Windows\n"
7199     "                : GL_ARB_debug_output extension should be exported by OpenGL driver!",
7200     __FILE__, VGlDebug, group);
7201   theCommands.Add ("vvbo",
7202     "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
7203     __FILE__, VVbo, group);
7204   theCommands.Add ("vstereo",
7205     "\nvstereo [{0|1}] : turn stereo usage On/Off; affects only newly displayed objects",
7206     __FILE__, VStereo, group);
7207   theCommands.Add ("vcaps",
7208             "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
7209     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
7210     "\n\t\t: Modify particular graphic driver options:"
7211     "\n\t\t:  FFP      - use fixed-function pipeline instead of"
7212     "\n\t\t:             built-in GLSL programs"
7213     "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
7214     "\n\t\t:             arrays to GPU memory)"
7215     "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
7216     "\n\t\t:  softMode - use software OpenGL implementation,"
7217     "\n\t\t:             should be set BEFORE viewer creation"
7218     "\n\t\t: Unlike vrenderparams, these parameters control alternative"
7219     "\n\t\t: rendering paths producing the same visual result when"
7220     "\n\t\t: possible."
7221     "\n\t\t: Command is intended for testing old hardware compatibility.",
7222     __FILE__, VCaps, group);
7223   theCommands.Add ("vmemgpu",
7224     "vmemgpu [f]: print system-dependent GPU memory information if available;"
7225     " with f option returns free memory in bytes",
7226     __FILE__, VMemGpu, group);
7227   theCommands.Add ("vreadpixel",
7228     "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
7229     " : Read pixel value for active view",
7230     __FILE__, VReadPixel, group);
7231   theCommands.Add("diffimage",
7232     "diffimage     : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
7233     __FILE__, VDiffImage, group);
7234   theCommands.Add ("vselect",
7235     "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [shift_selection = 0|1]\n"
7236     "- emulates different types of selection:\n"
7237     "- 1) single click selection\n"
7238     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
7239     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
7240     "- 4) any of these selections with shift button pressed",
7241     __FILE__, VSelect, group);
7242   theCommands.Add ("vmoveto",
7243     "vmoveto x y"
7244     "- emulates cursor movement to pixel postion (x,y)",
7245     __FILE__, VMoveTo, group);
7246   theCommands.Add ("vviewparams", "vviewparams usage:\n"
7247     "- vviewparams\n"
7248     "- vviewparams [-scale [s]] [-eye [x y z]] [-at [x y z]] [-up [x y z]]\n"
7249     "              [-proj [x y z]] [-center x y] [-size sx]\n"
7250     "-   Gets or sets current view parameters.\n"
7251     "-   If called without arguments, all view parameters are printed.\n"
7252     "-   The options are:\n"
7253     "      -scale [s]    : prints or sets viewport relative scale.\n"
7254     "      -eye [x y z]  : prints or sets eye location.\n"
7255     "      -at [x y z]   : prints or sets center of look.\n"
7256     "      -up [x y z]   : prints or sets direction of up vector.\n"
7257     "      -proj [x y z] : prints or sets direction of look.\n"
7258     "      -center x y   : sets location of center of the screen in pixels.\n"
7259     "      -size [sx]    : prints viewport projection width and height sizes\n"
7260     "                    : or changes the size of its maximum dimension.\n",
7261     __FILE__, VViewParams, group);
7262   theCommands.Add("vchangeselected",
7263     "vchangeselected shape"
7264     "- adds to shape to selection or remove one from it",
7265                 __FILE__, VChangeSelected, group);
7266   theCommands.Add("vzclipping",
7267     "vzclipping [mode] [depth width]\n"
7268     "- mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]\n"
7269     "- gets or sets ZClipping mode, width and depth",
7270     __FILE__,VZClipping,group);
7271   theCommands.Add ("vnbselected",
7272     "vnbselected", __FILE__, VNbSelected, group);
7273   theCommands.Add ("vcamera",
7274               "vcamera [-ortho] [-projtype]"
7275       "\n\t\t:         [-persp]"
7276       "\n\t\t:         [-fovy   [Angle]] [-distance [Distance]]"
7277       "\n\t\t:         [-stereo] [-leftEye] [-rightEye]"
7278       "\n\t\t:         [-iod [Distance]] [-iodType    [absolute|relative]]"
7279       "\n\t\t:         [-zfocus [Value]] [-zfocusType [absolute|relative]]"
7280       "\n\t\t: Manage camera parameters."
7281       "\n\t\t: Prints current value when option called without argument."
7282       "\n\t\t: Orthographic camera:"
7283       "\n\t\t:   -ortho      activate orthographic projection"
7284       "\n\t\t: Perspective camera:"
7285       "\n\t\t:   -persp      activate perspective  projection (mono)"
7286       "\n\t\t:   -fovy       field of view in y axis, in degrees"
7287       "\n\t\t:   -distance   distance of eye from camera center"
7288       "\n\t\t: Stereoscopic camera:"
7289       "\n\t\t:   -stereo     perspective  projection (stereo)"
7290       "\n\t\t:   -leftEye    perspective  projection (left  eye)"
7291       "\n\t\t:   -rightEye   perspective  projection (right eye)"
7292       "\n\t\t:   -iod        intraocular distance value"
7293       "\n\t\t:   -iodType    distance type, absolute or relative"
7294       "\n\t\t:   -zfocus     stereographic focus value"
7295       "\n\t\t:   -zfocusType focus type, absolute or relative",
7296     __FILE__, VCamera, group);
7297   theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
7298     "- vautozfit [on={1|0}] [scale]\n"
7299     "    Prints or changes parameters of automatic z-fit mode:\n"
7300     "   \"on\" - turns automatic z-fit on or off\n"
7301     "   \"scale\" - specifies factor to scale computed z range.\n",
7302     __FILE__, VAutoZFit, group);
7303   theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
7304     "   vzrange                - without parameters shows current values\n"
7305     "   vzrange [znear] [zfar] - applies provided values to view",
7306     __FILE__,VZRange, group);
7307   theCommands.Add("vantialiasing",
7308     "vantialiasing 1|0",
7309     __FILE__,VAntialiasing,group);
7310   theCommands.Add ("vpurgedisplay",
7311     "vpurgedisplay"
7312     "- removes structures which don't belong to objects displayed in neutral point",
7313     __FILE__, VPurgeDisplay, group);
7314   theCommands.Add("vsetviewsize",
7315     "vsetviewsize size",
7316     __FILE__,VSetViewSize,group);
7317   theCommands.Add("vmoveview",
7318     "vmoveview Dx Dy Dz [Start = 1|0]",
7319     __FILE__,VMoveView,group);
7320   theCommands.Add("vtranslateview",
7321     "vtranslateview Dx Dy Dz [Start = 1|0)]",
7322     __FILE__,VTranslateView,group);
7323   theCommands.Add("vturnview",
7324     "vturnview Ax Ay Az [Start = 1|0]",
7325     __FILE__,VTurnView,group);
7326   theCommands.Add("vtextureenv",
7327     "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
7328     "or user-defined file and optionally applying texture mapping parameters\n"
7329     "                  Usage:\n"
7330     "                  vtextureenv off - disables environment mapping\n"
7331     "                  vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
7332     "                              std_texture = (0..7)\n"
7333     "                              rep         = {clamp|repeat}\n"
7334     "                              mod         = {decal|modulate}\n"
7335     "                              flt         = {nearest|bilinear|trilinear}\n"
7336     "                              ss, st      - scale factors for s and t texture coordinates\n"
7337     "                              ts, tt      - translation for s and t texture coordinates\n"
7338     "                              rot         - texture rotation angle in degrees",
7339     __FILE__, VTextureEnv, group);
7340   theCommands.Add("vhlr" ,
7341     "is_enabled={on|off} [show_hidden={1|0}]"
7342     " - Hidden line removal algorithm:"
7343     " - is_enabled: if is on HLR algorithm is applied\n"
7344     " - show_hidden: if equals to 1, hidden lines are drawn as dotted ones.\n",
7345     __FILE__,VHLR,group);
7346   theCommands.Add("vhlrtype" ,
7347     "algo_type={algo|polyalgo} [shape_1 ... shape_n]"
7348     " - Changes the type of HLR algorithm using for shapes."
7349     " - algo_type: if equals to algo, exact HLR algorithm is applied;\n"
7350     "   if equals to polyalgo, polygonal HLR algorithm is applied."
7351     "If shapes are not given HLR algoithm of given type is applied"
7352     " to all shapes in the view\n",
7353     __FILE__,VHLRType,group);
7354   theCommands.Add("vclipplane", "vclipplane usage: \n"
7355     "  maxplanes <view_name> - get plane limit for view.\n"
7356     "  create <plane_name> - create new plane.\n"
7357     "  delete <plane_name> - delete plane.\n"
7358     "  clone <source_plane> <plane_name> - clone the plane definition.\n"
7359     "  set/unset <plane_name> object <object list> - set/unset plane for IO.\n"
7360     "  set/unset <plane_name> view <view list> - set/unset plane for view.\n"
7361     "  change <plane_name> on/off - turn clipping on/off.\n"
7362     "  change <plane_name> equation <a> <b> <c> <d> - change plane equation.\n"
7363     "  change <plane_name> capping on/off - turn capping on/off.\n"
7364     "  change <plane_name> capping color <r> <g> <b> - set color.\n"
7365     "  change <plane name> capping texname <texture> - set texture.\n"
7366     "  change <plane_name> capping texscale <sx> <sy> - set tex scale.\n"
7367     "  change <plane_name> capping texorigin <tx> <ty> - set tex origin.\n"
7368     "  change <plane_name> capping texrotate <angle> - set tex rotation.\n"
7369     "  change <plane_name> capping hatch on/off/<id> - set hatching mask.\n"
7370     "  please use VSetTextureMode command to enable texture rendering in view.\n"
7371     , __FILE__, VClipPlane, group);
7372   theCommands.Add("vsettexturemode", "vsettexturemode view_name mode \n"
7373     "  mode can be:\n"
7374     "  0 - no textures enabled in view.\n"
7375     "  1 - only environment textures enabled.\n"
7376     "  2 - all textures enabled.\n"
7377     "  this command sets texture details mode for the specified view.\n"
7378     , __FILE__, VSetTextureMode, group);
7379   theCommands.Add("vdefaults",
7380     "vdefaults [absDefl=value] [devCoeff=value] [angDefl=value]",
7381     __FILE__, VDefaults, group);
7382   theCommands.Add("vlight",
7383     "tool to manage light sources, without arguments shows list of lights."
7384     "\n    Main commands: "
7385     "\n      'clear' to clear lights"
7386     "\n      '{def}aults' to load deafault lights"
7387     "\n      'add' (or 'new') <type> to add any light source"
7388     "\n          where <type> is one of {amb}ient|directional|{spot}light|positional"
7389     "\n      'change' <lightId> to edit light source with specified lightId"
7390     "\n\n      In addition to 'add' and 'change' commands you can use light parameters:"
7391     "\n        {pos}ition X Y Z"
7392     "\n        {dir}ection X Y Z (for directional light or for spotlight)"
7393     "\n        color colorName"
7394     "\n        {head}light 0|1"
7395     "\n        {constAtten}uation value"
7396     "\n        {linearAtten}uation value"
7397     "\n        angle angleDeg"
7398     "\n        {spotexp}onent value"
7399     "\n        local|global"
7400     "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
7401     "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
7402     __FILE__, VLight, group);
7403   theCommands.Add("vraytrace",
7404             "vraytrace [0|1]"
7405     "\n\t\t: Turn on/off raytracing renderer."
7406     "\n\t\t:   'vraytrace 0' alias for 'vrenderparams -raster'."
7407     "\n\t\t:   'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
7408     __FILE__, VRenderParams, group);
7409   theCommands.Add("vrenderparams",
7410     "\n    Manages rendering parameters: "
7411     "\n      '-rayTrace'             Enables  GPU ray-tracing"
7412     "\n      '-raster'               Disables GPU ray-tracing"
7413     "\n      '-rayDepth     0..10'   Defines maximum ray-tracing depth"
7414     "\n      '-shadows      on|off'  Enables/disables shadows rendering"
7415     "\n      '-reflections  on|off'  Enables/disables specular reflections"
7416     "\n      '-fsaa         on|off'  Enables/disables adaptive anti-aliasing"
7417     "\n      '-gleam        on|off'  Enables/disables transparency shadow effects"
7418     "\n      '-shadingModel model'   Controls shading model from enumeration"
7419     "\n                              color, flat, gouraud, phong"
7420     "\n    Unlike vcaps, these parameters dramatically change visual properties."
7421     "\n    Command is intended to control presentation quality depending on"
7422     "\n    hardware capabilities and performance.",
7423     __FILE__, VRenderParams, group);
7424   theCommands.Add("vfrustumculling",
7425     "vfrustumculling [toEnable]: enables/disables objects clipping",
7426     __FILE__,VFrustumCulling,group);
7427   theCommands.Add("vhighlightselected",
7428     "vhighlightselected [0|1] or vhighlightselected [on|off]: enables/disables highlighting of selected objects.\n"
7429     "Without arguments it shows if highlighting of selected objects is enabled now.",
7430     __FILE__,VHighlightSelected,group);
7431
7432
7433   theCommands.Add("vxrotate",
7434     "vxrotate",
7435     __FILE__,VXRotate,group);
7436
7437 }