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