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