d32f2f5078d9cfc13bc5295a9752b8c06be4f7ec
[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 : VTestZBuffTrihedron
2861 //purpose  : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron
2862 //==============================================================================
2863
2864 static int VTestZBuffTrihedron(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2865 {
2866   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
2867   if ( V3dView.IsNull() ) return 1;
2868
2869   V3dView->ZBufferTriedronSetup();
2870
2871   if ( argc == 1 ) {
2872     // Set up default trihedron parameters
2873     V3dView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.1, V3d_ZBUFFER );
2874   } else
2875   if ( argc == 7 )
2876   {
2877     Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
2878     const char* aPosType = argv[1];
2879
2880     if ( strcmp(aPosType, "center") == 0 )
2881     {
2882       aPosition = Aspect_TOTP_CENTER;
2883     } else
2884     if (strcmp(aPosType, "left_lower") == 0)
2885     {
2886       aPosition = Aspect_TOTP_LEFT_LOWER;
2887     } else
2888     if (strcmp(aPosType, "left_upper") == 0)
2889     {
2890       aPosition = Aspect_TOTP_LEFT_UPPER;
2891     } else
2892     if (strcmp(aPosType, "right_lower") == 0)
2893     {
2894       aPosition = Aspect_TOTP_RIGHT_LOWER;
2895     } else
2896     if (strcmp(aPosType, "right_upper") == 0)
2897     {
2898       aPosition = Aspect_TOTP_RIGHT_UPPER;
2899     } else
2900     {
2901       di << argv[1] << " Invalid type of alignment"  << "\n";
2902       di << "Must be one of [ center, left_lower,"   << "\n";
2903       di << "left_upper, right_lower, right_upper ]" << "\n";
2904       return 1;
2905     }
2906
2907     Standard_Real R = Draw::Atof(argv[2])/255.;
2908     Standard_Real G = Draw::Atof(argv[3])/255.;
2909     Standard_Real B = Draw::Atof(argv[4])/255.;
2910     Quantity_Color aColor(R, G, B, Quantity_TOC_RGB);
2911
2912     Standard_Real aScale = Draw::Atof(argv[5]);
2913
2914     if( aScale <= 0.0 )
2915     {
2916       di << argv[5] << " Invalid value. Must be > 0" << "\n";
2917       return 1;
2918     }
2919
2920     V3d_TypeOfVisualization aPresentation = V3d_ZBUFFER;
2921     const char* aPresType = argv[6];
2922
2923     if ( strcmp(aPresType, "wireframe") == 0 )
2924     {
2925       aPresentation = V3d_WIREFRAME;
2926     } else
2927     if (strcmp(aPresType, "zbuffer") == 0)
2928     {
2929       aPresentation = V3d_ZBUFFER;
2930     } else
2931     {
2932       di << argv[6] << " Invalid type of visualization" << "\n";
2933       di << "Must be one of [ wireframe, zbuffer ]"     << "\n";
2934       return 1;
2935     }
2936
2937     V3dView->TriedronDisplay( aPosition, aColor.Name(), aScale, aPresentation );
2938
2939   } else
2940   {
2941     di << argv[0] << " Invalid number of arguments" << "\n";
2942     return 1;
2943   }
2944
2945   V3dView->View()->ZFitAll();
2946   V3dView->Redraw();
2947
2948   return 0;
2949 }
2950
2951 //==============================================================================
2952 //function : VRotate
2953 //purpose  : Camera Rotating
2954 //==============================================================================
2955
2956 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
2957 {
2958   Handle(V3d_View) aView = ViewerTest::CurrentView();
2959   if (aView.IsNull())
2960   {
2961     std::cout << "No active view!\n";
2962     return 1;
2963   }
2964
2965   Standard_Boolean hasFlags = Standard_False;
2966   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2967   {
2968     Standard_CString        anArg (theArgVec[anArgIter]);
2969     TCollection_AsciiString aFlag (anArg);
2970     aFlag.LowerCase();
2971     if (aFlag == "-mousestart"
2972      || aFlag == "-mousefrom")
2973     {
2974       hasFlags = Standard_True;
2975       if (anArgIter + 2 >= theArgNb)
2976       {
2977         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
2978         return 1;
2979       }
2980
2981       Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
2982       Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
2983       aView->StartRotation (anX, anY);
2984     }
2985     else if (aFlag == "-mousemove")
2986     {
2987       hasFlags = Standard_True;
2988       if (anArgIter + 2 >= theArgNb)
2989       {
2990         std::cout << "Error: wrong syntax at '" << anArg << "'\n";
2991         return 1;
2992       }
2993
2994       Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
2995       Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
2996       aView->Rotation (anX, anY);
2997     }
2998     else if (theArgNb != 4
2999           && theArgNb != 7)
3000     {
3001       std::cout << "Error: wrong syntax at '" << anArg << "'\n";
3002       return 1;
3003     }
3004   }
3005
3006   if (hasFlags)
3007   {
3008     return 0;
3009   }
3010   else if (theArgNb == 4)
3011   {
3012     Standard_Real anAX = Draw::Atof (theArgVec[1]);
3013     Standard_Real anAY = Draw::Atof (theArgVec[2]);
3014     Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3015     aView->Rotate (anAX, anAY, anAZ);
3016     return 0;
3017   }
3018   else if (theArgNb == 7)
3019   {
3020     Standard_Real anAX = Draw::Atof (theArgVec[1]);
3021     Standard_Real anAY = Draw::Atof (theArgVec[2]);
3022     Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3023
3024     Standard_Real anX = Draw::Atof (theArgVec[4]);
3025     Standard_Real anY = Draw::Atof (theArgVec[5]);
3026     Standard_Real anZ = Draw::Atof (theArgVec[6]);
3027
3028     aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
3029     return 0;
3030   }
3031
3032   std::cout << "Error: Invalid number of arguments\n";
3033   return 1;
3034 }
3035
3036 //==============================================================================
3037 //function : VZoom
3038 //purpose  : View zoom in / out (relative to current zoom)
3039 //==============================================================================
3040
3041 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3042   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3043   if ( V3dView.IsNull() ) {
3044     return 1;
3045   }
3046
3047   if ( argc == 2 ) {
3048     Standard_Real coef = Draw::Atof(argv[1]);
3049     if ( coef <= 0.0 ) {
3050       di << argv[1] << "Invalid value" << "\n";
3051       return 1;
3052     }
3053     V3dView->SetZoom( Draw::Atof(argv[1]) );
3054     return 0;
3055   } else {
3056     di << argv[0] << " Invalid number of arguments" << "\n";
3057     return 1;
3058   }
3059 }
3060
3061 //==============================================================================
3062 //function : VPan
3063 //purpose  : View panning (in pixels)
3064 //==============================================================================
3065
3066 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3067   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3068   if ( V3dView.IsNull() ) return 1;
3069
3070   if ( argc == 3 ) {
3071     V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
3072     return 0;
3073   } else {
3074     di << argv[0] << " Invalid number of arguments" << "\n";
3075     return 1;
3076   }
3077 }
3078
3079 //==============================================================================
3080 //function : VPlace
3081 //purpose  : Place the point (in pixels) at the center of the window
3082 //==============================================================================
3083 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
3084 {
3085   Handle(V3d_View) aView = ViewerTest::CurrentView();
3086   if (aView.IsNull())
3087   {
3088     std::cerr << theArgs[0] << "Error: no active view." << std::endl;
3089     return 1;
3090   }
3091
3092   if (theArgNb != 3)
3093   {
3094     std::cerr << theArgs[0] << "Error: invalid number of arguments." << std::endl;
3095     return 1;
3096   }
3097
3098   aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
3099
3100   return 0;
3101 }
3102
3103 //==============================================================================
3104 //function : VExport
3105 //purpose  : Export the view to a vector graphic format (PS, EMF, PDF)
3106 //==============================================================================
3107
3108 static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3109 {
3110   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3111   if (V3dView.IsNull())
3112     return 1;
3113
3114   if (argc == 1)
3115   {
3116     std::cout << "Usage: " << argv[0] << " Filename [Format]\n";
3117     return 1;
3118   }
3119
3120   Graphic3d_ExportFormat anExpFormat = Graphic3d_EF_PDF;
3121   TCollection_AsciiString aFormatStr;
3122
3123   TCollection_AsciiString aFileName (argv[1]);
3124   Standard_Integer aLen = aFileName.Length();
3125
3126   if (argc > 2)
3127   {
3128     aFormatStr = TCollection_AsciiString (argv[2]);
3129   }
3130   else if (aLen >= 4)
3131   {
3132     if (aFileName.Value (aLen - 2) == '.')
3133     {
3134       aFormatStr = aFileName.SubString (aLen - 1, aLen);
3135     }
3136     else if (aFileName.Value (aLen - 3) == '.')
3137     {
3138       aFormatStr = aFileName.SubString (aLen - 2, aLen);
3139     }
3140     else
3141     {
3142       std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
3143       return 1;
3144     }
3145   }
3146   else
3147   {
3148     std::cout << "Export format couln't be detected from filename '" << argv[1] << "'\n";
3149     return 1;
3150   }
3151
3152   aFormatStr.UpperCase();
3153   if (aFormatStr == "PS")
3154     anExpFormat = Graphic3d_EF_PostScript;
3155   else if (aFormatStr == "EPS")
3156     anExpFormat = Graphic3d_EF_EnhPostScript;
3157   else if (aFormatStr == "TEX")
3158     anExpFormat = Graphic3d_EF_TEX;
3159   else if (aFormatStr == "PDF")
3160     anExpFormat = Graphic3d_EF_PDF;
3161   else if (aFormatStr == "SVG")
3162     anExpFormat = Graphic3d_EF_SVG;
3163   else if (aFormatStr == "PGF")
3164     anExpFormat = Graphic3d_EF_PGF;
3165   else if (aFormatStr == "EMF")
3166     anExpFormat = Graphic3d_EF_EMF;
3167   else
3168   {
3169     std::cout << "Invalid export format '" << aFormatStr << "'\n";
3170     return 1;
3171   }
3172
3173   try {
3174     if (!V3dView->View()->Export (argv[1], anExpFormat))
3175     {
3176       di << "Error: export of image to " << aFormatStr << " failed!\n";
3177     }
3178   }
3179   catch (Standard_Failure)
3180   {
3181     di << "Error: export of image to " << aFormatStr << " failed";
3182     di << " (exception: " << Standard_Failure::Caught()->GetMessageString() << ")";
3183   }
3184   return 0;
3185 }
3186
3187 //==============================================================================
3188 //function : VColorScale
3189 //purpose  : representation color scale
3190 //==============================================================================
3191
3192 static Standard_Boolean checkColor (const TCollection_AsciiString& theRed,
3193                                     const TCollection_AsciiString& theGreen,
3194                                     const TCollection_AsciiString& theBlue,
3195                                                     Standard_Real& theRedValue,
3196                                                     Standard_Real& theGreenValue,
3197                                                     Standard_Real& theBlueValue)
3198 {
3199   if (!theRed.IsRealValue()
3200    || !theGreen.IsRealValue()
3201    || !theBlue.IsRealValue())
3202   {
3203     std::cout << "Error: RGB color values should be real!\n";
3204     return Standard_True;
3205   }
3206   theRedValue = theRed    .RealValue();
3207   theGreenValue = theGreen.RealValue();
3208   theBlueValue = theBlue  .RealValue();
3209   if (theRedValue < 0.0 || theRedValue > 1.0
3210    || theGreenValue < 0.0 || theGreenValue > 1.0
3211    || theBlueValue < 0.0 || theBlueValue > 1.0)
3212   {
3213     std::cout << "Error: RGB color values should be within range 0..1!\n";
3214     return Standard_True;
3215   }
3216   return Standard_False;
3217 }
3218
3219 static int VColorScale (Draw_Interpretor& theDI,
3220                         Standard_Integer  theArgNb,
3221                         const char**      theArgVec)
3222 {
3223   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3224   Handle(V3d_View)               aView    = ViewerTest::CurrentView();
3225   if (aContext.IsNull())
3226   {
3227     std::cout << "Error: no active view!\n";
3228     return 1;
3229   }
3230
3231   Handle(V3d_ColorScale) aCS = Handle(V3d_ColorScale)::DownCast (aView->ColorScale());
3232   if (aCS.IsNull())
3233   {
3234     std::cout << "Error: color scale is undefined!\n";
3235     return 1;
3236   }
3237
3238   Standard_Real                   aMinRange    = aCS->GetMin();
3239   Standard_Real                   aMaxRange    = aCS->GetMax();
3240   Standard_Integer                aNbIntervals = aCS->GetNumberOfIntervals();
3241   Standard_Integer                aTextHeight  = aCS->GetTextHeight();
3242   Aspect_TypeOfColorScalePosition aLabPosition = aCS->GetLabelPosition();
3243   gp_XY                           aPos (aCS->GetXPosition(), aCS->GetYPosition());
3244
3245   ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
3246
3247   if (theArgNb <= 1)
3248   {
3249     theDI << "Current color scale parameters:\n"
3250           << "Min range: " << aMinRange << "\n"
3251           << "Max range: " << aMaxRange << "\n"
3252           << "Number of intervals: " << aNbIntervals << "\n"
3253           << "Text height: " << aTextHeight << "\n"
3254           << "Color scale position: " << aPos.X() <<" "<< aPos.Y()<< "\n"
3255           << "Color scale title: " << aCS->GetTitle() << "\n"
3256           << "Label position: ";
3257     switch (aLabPosition)
3258     {
3259       case Aspect_TOCSP_NONE:
3260         theDI << "None\n";
3261         break;
3262       case Aspect_TOCSP_LEFT:
3263         theDI << "Left\n";
3264         break;
3265       case Aspect_TOCSP_RIGHT:
3266         theDI << "Right\n";
3267         break;
3268       case Aspect_TOCSP_CENTER:
3269         theDI << "Center\n";
3270         break;
3271     }
3272     return 0;
3273   }
3274   Standard_CString        aFirstArg = theArgVec[1];
3275   TCollection_AsciiString aFlag (aFirstArg);
3276   aFlag.LowerCase();
3277   if (aFlag == "-hide" ||
3278       aFlag == "-erase")
3279   {
3280     if (theArgNb > 2)
3281     {
3282       std::cout << "Error: wrong syntax at argument '" << theArgVec[1] << "'!\n";
3283       return 1;
3284     }
3285     if (!aView->ColorScaleIsDisplayed())
3286     {
3287       std::cout << "Error: color scale is not displayed!\n";
3288       return 1;
3289    }
3290     else
3291     {
3292       aView->ColorScaleErase();
3293       return 0;
3294     }
3295   }
3296   else if (aFlag == "-show" ||
3297            aFlag == "-display")
3298   {
3299     if (theArgNb > 2)
3300     {
3301       std::cout << "Error: wrong syntax at argument '" << theArgVec[1] << "'!\n";
3302       return 1;
3303     }
3304     aView->ColorScaleDisplay();
3305     return 0;
3306   }
3307
3308   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3309   {
3310     Standard_CString        anArg = theArgVec[anArgIter];
3311     TCollection_AsciiString aFlag (anArg);
3312     aFlag.LowerCase();
3313     if (anUpdateTool.parseRedrawMode (aFlag))
3314     {
3315       continue;
3316     }
3317     else if (aFlag == "-range")
3318     {
3319       if (anArgIter + 3 >= theArgNb)
3320       {
3321         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3322         return 1;
3323       }
3324
3325       TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
3326       TCollection_AsciiString anArg2 (theArgVec[++anArgIter]);
3327       TCollection_AsciiString anArg3 (theArgVec[++anArgIter]);
3328       if (!anArg1.IsRealValue())
3329       {
3330         std::cout << "Error: the minRange value should be real!\n";
3331         return 1;
3332       }
3333       else if (!anArg2.IsRealValue())
3334       {
3335         std::cout << "Error: the maxRange value should be real!\n";
3336         return 1;
3337       }
3338       else if (!anArg3.IsIntegerValue())
3339       {
3340         std::cout << "Error: the number of intervals should be integer!\n";
3341         return 1;
3342       }
3343
3344       aMinRange    = anArg1.RealValue();
3345       aMaxRange    = anArg2.RealValue();
3346       aNbIntervals = anArg3.IntegerValue();
3347     }
3348     else if (aFlag == "-font")
3349     {
3350       if (anArgIter + 1 >= theArgNb)
3351       {
3352         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3353         return 1;
3354       }
3355       TCollection_AsciiString anArg (theArgVec[anArgIter + 1]);
3356       if (!anArg.IsIntegerValue())
3357       {
3358         std::cout << "Error: HeightFont value should be integer!\n";
3359         return 1;
3360       }
3361
3362       aTextHeight = anArg.IntegerValue();
3363       anArgIter += 1;
3364     }
3365     else if (aFlag == "-textpos")
3366     {
3367       if (anArgIter + 1 >= theArgNb)
3368       {
3369         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3370         return 1;
3371       }
3372       TCollection_AsciiString anArg (theArgVec[++anArgIter]);
3373       anArg.LowerCase();
3374       if (anArg == "none")
3375       {
3376         aLabPosition = Aspect_TOCSP_NONE;
3377       }
3378       else if (anArg == "left")
3379       {
3380         aLabPosition = Aspect_TOCSP_LEFT;
3381       }
3382       else if (anArg == "right")
3383       {
3384         aLabPosition = Aspect_TOCSP_RIGHT;
3385       }
3386       else if (anArg == "center")
3387       {
3388         aLabPosition = Aspect_TOCSP_CENTER;
3389       }
3390       else
3391       {
3392         std::cout << "Error: unknown position '" << anArg << "'!\n";
3393         return 1;
3394       }
3395     }
3396     else if (aFlag == "-xy")
3397     {
3398       if (anArgIter + 2 >= theArgNb)
3399       {
3400         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3401         return 1;
3402       }
3403
3404       TCollection_AsciiString aX (theArgVec[++anArgIter]);
3405       TCollection_AsciiString aY (theArgVec[++anArgIter]);
3406       if (!aX.IsRealValue()
3407        || !aY.IsRealValue())
3408       {
3409         std::cout << "Error: coordinates should be real values!\n";
3410         return 1;
3411       }
3412
3413       aPos.SetCoord (aX.RealValue(), aY.RealValue());
3414     }
3415     else if (aFlag == "-color")
3416     {
3417       if (aCS->GetColorType() != Aspect_TOCSD_USER)
3418       {
3419         std::cout << "Error: wrong color type! Call -colors before to set user-specified colors!\n";
3420         return 1;
3421       }
3422
3423       Quantity_NameOfColor aColorName;
3424       if (anArgIter + 4 >= theArgNb)
3425       {
3426         if (anArgIter + 2 >= theArgNb)
3427         {
3428           std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3429           return 1;
3430         }
3431         else if (!Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName))
3432         {
3433           std::cout << "Error: wrong color name: '" << theArgVec[anArgIter + 2] << "' !\n";
3434           return 1;
3435         }
3436       }
3437
3438       TCollection_AsciiString anInd (theArgVec[anArgIter + 1]);
3439       if (!anInd.IsIntegerValue())
3440       {
3441         std::cout << "Error: Index value should be integer!\n";
3442         return 1;
3443       }
3444
3445       Standard_Integer anIndex = anInd.IntegerValue();
3446       if (anIndex < 0
3447        || anIndex > aNbIntervals - 1)
3448       {
3449         std::cout << "Error: Index value should be within range 0..." << (aNbIntervals - 1) <<"!\n";
3450         return 1;
3451       }
3452
3453       if (Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName))
3454       {
3455         aCS->SetColor    (Quantity_Color (aColorName), anIndex);
3456         aCS->SetColorType(Aspect_TOCSD_USER);
3457         anArgIter += 2;
3458         continue;
3459       }
3460
3461       TCollection_AsciiString aRed   (theArgVec[anArgIter + 2]);
3462       TCollection_AsciiString aGreen (theArgVec[anArgIter + 3]);
3463       TCollection_AsciiString aBlue  (theArgVec[anArgIter + 4]);
3464       Standard_Real aRedValue,aGreenValue, aBlueValue;
3465       if(checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue))
3466       {
3467         return 1;
3468       }
3469       aCS->SetColor     (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB), anIndex);
3470       aCS->SetColorType (Aspect_TOCSD_USER);
3471       anArgIter += 4;
3472     }
3473     else if (aFlag == "-label")
3474     {
3475       if (aCS->GetColorType() != Aspect_TOCSD_USER)
3476       {
3477         std::cout << "Error: wrong label type! Call -labels before to set user-specified labels!\n";
3478         return 1;
3479       }
3480       else if (anArgIter + 2 >= theArgNb)
3481       {
3482         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3483         return 1;
3484       }
3485
3486       Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
3487       if (anIndex < 0
3488        || anIndex > aNbIntervals)
3489       {
3490         std::cout << "Error: Index value should be within range 0..." << aNbIntervals <<"!\n";
3491         return 1;
3492       }
3493
3494       TCollection_ExtendedString aText (theArgVec[anArgIter + 2]);
3495       aCS->SetLabel     (aText, anIndex);
3496       aCS->SetLabelType (Aspect_TOCSD_USER);
3497       anArgIter += 2;
3498     }
3499     else if (aFlag == "-colors")
3500     {
3501       Aspect_SequenceOfColor aSeq;
3502       if (anArgIter + aNbIntervals + 1 > theArgNb)
3503       {
3504         std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
3505                   << aNbIntervals << " intervals\n";
3506         return 1;
3507       }
3508
3509       Standard_Integer aColorIter = anArgIter + 1;
3510       while (aColorIter < theArgNb)
3511       {
3512         if (theArgVec[aColorIter][0] == '-')
3513         {
3514           break;
3515         }
3516
3517         else if (theArgVec[aColorIter][0] >= 97
3518               && theArgVec[aColorIter][0] <= 122)
3519         {
3520           Quantity_NameOfColor aColorName;
3521           if (!Quantity_Color::ColorFromName (theArgVec[aColorIter], aColorName))
3522           {
3523             std::cout << "Error: wrong color name: " << theArgVec[aColorIter] << " !\n";
3524             return 1;
3525           }
3526           aSeq.Append (Quantity_Color (aColorName));
3527           aColorIter++;
3528           anArgIter++;
3529         }
3530         else
3531         {
3532           TCollection_AsciiString aRed   (theArgVec[aColorIter]);
3533           TCollection_AsciiString aGreen (theArgVec[aColorIter + 1]);
3534           TCollection_AsciiString aBlue  (theArgVec[aColorIter + 2]);
3535           Standard_Real aRedValue,aGreenValue, aBlueValue;
3536           if (checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue))
3537           {
3538             return 1;
3539           }
3540           aSeq.Append (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB));
3541           aColorIter += 3;
3542           anArgIter += 3;
3543         }
3544       }
3545       if (aSeq.Length() < aNbIntervals)
3546       {
3547         std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
3548                   << aNbIntervals << " intervals\n";
3549         return 1;
3550       }
3551
3552       aCS->SetColors    (aSeq);
3553       aCS->SetColorType (Aspect_TOCSD_USER);
3554     }
3555     else if (aFlag == "-labels")
3556     {
3557       if (anArgIter + aNbIntervals + 1 >= theArgNb)
3558       {
3559         std::cout << "Error: not enough arguments! You should provide " << (aNbIntervals + 1)
3560                   << " text labels for " << aNbIntervals << " intervals.\n";
3561         return 1;
3562       }
3563
3564       TColStd_SequenceOfExtendedString aSeq;
3565       for (int aLabelIter = anArgIter + 1; aLabelIter <= anArgIter + aNbIntervals + 1; aLabelIter += 1)
3566       {
3567         aSeq.Append (TCollection_ExtendedString (theArgVec[aLabelIter]));
3568       }
3569       aCS->SetLabels (aSeq);
3570       aCS->SetLabelType (Aspect_TOCSD_USER);
3571       anArgIter += aSeq.Length();
3572     }
3573     else if (aFlag == "-title")
3574     {
3575       if (anArgIter + 1 >= theArgNb)
3576       {
3577         std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
3578         return 1;
3579       }
3580
3581       Standard_Boolean isTwoArgs = Standard_False;
3582       if (anArgIter + 2 < theArgNb)
3583       {
3584         TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
3585         aSecondArg.LowerCase();
3586         if (aSecondArg == "none")
3587         {
3588           aCS->SetTitlePosition (Aspect_TOCSP_NONE);
3589           isTwoArgs = Standard_True;
3590         }
3591         else if (aSecondArg == "left")
3592         {
3593           aCS->SetTitlePosition (Aspect_TOCSP_LEFT);
3594           isTwoArgs = Standard_True;
3595         }
3596         else if (aSecondArg == "right")
3597         {
3598           aCS->SetTitlePosition (Aspect_TOCSP_RIGHT);
3599           isTwoArgs = Standard_True;
3600         }
3601         else if (aSecondArg == "center")
3602         {
3603           aCS->SetTitlePosition (Aspect_TOCSP_CENTER);
3604           isTwoArgs = Standard_True;
3605         }
3606       }
3607
3608       aCS->SetTitle (theArgVec[anArgIter + 1]);
3609       if (isTwoArgs)
3610       {
3611         anArgIter += 1;
3612       }
3613       anArgIter += 1;
3614     }
3615     else if (aFlag == "-demoversion"
3616           || aFlag == "-demo")
3617     {
3618       aPos.SetCoord (0.0, 0.0);
3619       aTextHeight  = 16;
3620       aMinRange    = 0.0;
3621       aMaxRange    = 100;
3622       aNbIntervals = 10;
3623       aLabPosition = Aspect_TOCSP_RIGHT;
3624       aCS->SetColorType(Aspect_TOCSD_AUTO);
3625       aCS->SetLabelType(Aspect_TOCSD_AUTO);
3626     }
3627     else
3628     {
3629       std::cout << "Error: wrong syntax at " << anArg << " - unknown argument!\n";
3630       return 1;
3631     }
3632   }
3633
3634   aCS->SetPosition          (aPos.X(), aPos.Y());
3635   aCS->SetHeight            (0.95);
3636   aCS->SetTextHeight        (aTextHeight);
3637   aCS->SetRange             (aMinRange, aMaxRange);
3638   aCS->SetNumberOfIntervals (aNbIntervals);
3639   aCS->SetLabelPosition     (aLabPosition);
3640
3641   if (!aView->ColorScaleIsDisplayed())
3642   {
3643     aView->ColorScaleDisplay();
3644   }
3645
3646   return 0;
3647 }
3648
3649 //==============================================================================
3650 //function : VGraduatedTrihedron
3651 //purpose  : Displays or hides a graduated trihedron
3652 //==============================================================================
3653 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
3654                                   Quantity_Color& theColor)
3655 {
3656   Quantity_NameOfColor aColorName;
3657   TCollection_AsciiString aVal = theValue;
3658   aVal.UpperCase();
3659   if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
3660   {
3661     return Standard_False;
3662   }
3663   theColor = Quantity_Color (aColorName);
3664   return Standard_True;
3665 }
3666
3667 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
3668 {
3669   if (theArgNum < 2)
3670   {
3671     std::cout << theArgs[0] << " error: wrong number of parameters. Type 'help"
3672               << theArgs[0] <<"' for more information.\n";
3673     return 1;  //TCL_ERROR
3674   }
3675
3676   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
3677   TCollection_AsciiString aParseKey;
3678   for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
3679   {
3680     TCollection_AsciiString anArg (theArgs [anArgIt]);
3681
3682     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
3683     {
3684       aParseKey = anArg;
3685       aParseKey.Remove (1);
3686       aParseKey.LowerCase();
3687       aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
3688       continue;
3689     }
3690
3691     if (aParseKey.IsEmpty())
3692     {
3693       continue;
3694     }
3695
3696     aMapOfArgs(aParseKey)->Append (anArg);
3697   }
3698
3699   // Check parameters
3700   for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
3701        aMapIt.More(); aMapIt.Next())
3702   {
3703     const TCollection_AsciiString& aKey = aMapIt.Key();
3704     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
3705
3706     // Bool key, without arguments
3707     if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
3708         && anArgs->IsEmpty())
3709     {
3710       continue;
3711     }
3712
3713     // One argument
3714     if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
3715           && anArgs->Length() == 1)
3716     {
3717       continue;
3718     }
3719
3720     // On/off arguments
3721     if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
3722         || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
3723         || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues"))
3724         && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
3725     {
3726       continue;
3727     }
3728
3729     // One string argument
3730     if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
3731           || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
3732           && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
3733     {
3734       continue;
3735     }
3736
3737     // One integer argument
3738     if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
3739           || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
3740           || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
3741           || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
3742          && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
3743     {
3744       continue;
3745     }
3746
3747     // One real argument
3748     if ( aKey.IsEqual ("arrowlength")
3749          && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue()))
3750     {
3751       continue;
3752     }
3753
3754     // Two string arguments
3755     if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
3756          && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
3757     {
3758       continue;
3759     }
3760
3761     TCollection_AsciiString aLowerKey;
3762     aLowerKey  = "-";
3763     aLowerKey += aKey;
3764     aLowerKey.LowerCase();
3765     std::cout << theArgs[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
3766     std::cout << "Type help for more information.\n";
3767     return 1;
3768   }
3769
3770   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3771   if (anAISContext.IsNull())
3772   {
3773     std::cout << theArgs[0] << ": " << " please use 'vinit' command to initialize view.\n";
3774     return 1;
3775   }
3776
3777   Standard_Boolean toDisplay = Standard_True;
3778   Quantity_Color aColor;
3779   Graphic3d_GraduatedTrihedron aTrihedronData;
3780   // Process parameters
3781   Handle(TColStd_HSequenceOfAsciiString) aValues;
3782   if (aMapOfArgs.Find ("off", aValues))
3783   {
3784     toDisplay = Standard_False;
3785   }
3786
3787   // AXES NAMES
3788   if (aMapOfArgs.Find ("xname", aValues))
3789   {
3790     aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
3791   }
3792   if (aMapOfArgs.Find ("yname", aValues))
3793   {
3794     aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
3795   }
3796   if (aMapOfArgs.Find ("zname", aValues))
3797   {
3798     aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
3799   }
3800   if (aMapOfArgs.Find ("xdrawname", aValues))
3801   {
3802     aTrihedronData.ChangeXAxisAspect().SetToDrawName (aValues->Value(1).IsEqual ("on"));
3803   }
3804   if (aMapOfArgs.Find ("ydrawname", aValues))
3805   {
3806     aTrihedronData.ChangeYAxisAspect().SetToDrawName (aValues->Value(1).IsEqual ("on"));
3807   }
3808   if (aMapOfArgs.Find ("zdrawname", aValues))
3809   {
3810     aTrihedronData.ChangeZAxisAspect().SetToDrawName (aValues->Value(1).IsEqual ("on"));
3811   }
3812   if (aMapOfArgs.Find ("xnameoffset", aValues))
3813   {
3814     aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
3815   }
3816   if (aMapOfArgs.Find ("ynameoffset", aValues))
3817   {
3818     aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
3819   }
3820   if (aMapOfArgs.Find ("znameoffset", aValues))
3821   {
3822     aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
3823   }
3824
3825   // COLORS
3826   if (aMapOfArgs.Find ("xnamecolor", aValues))
3827   {
3828     if (!GetColor (aValues->Value(1), aColor))
3829     {
3830       std::cout << theArgs[0] << "error: -xnamecolor wrong color name.\n";
3831       return 1;
3832     }
3833     aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
3834   }
3835   if (aMapOfArgs.Find ("ynamecolor", aValues))
3836   {
3837     if (!GetColor (aValues->Value(1), aColor))
3838     {
3839       std::cout << theArgs[0] << "error: -ynamecolor wrong color name.\n";
3840       return 1;
3841     }
3842     aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
3843   }
3844   if (aMapOfArgs.Find ("znamecolor", aValues))
3845   {
3846     if (!GetColor (aValues->Value(1), aColor))
3847     {
3848       std::cout << theArgs[0] << "error: -znamecolor wrong color name.\n";
3849       return 1;
3850     }
3851     aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
3852   }
3853   if (aMapOfArgs.Find ("xcolor", aValues))
3854   {
3855     if (!GetColor (aValues->Value(1), aColor))
3856     {
3857       std::cout << theArgs[0] << "error: -xcolor wrong color name.\n";
3858       return 1;
3859     }
3860     aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
3861   }
3862   if (aMapOfArgs.Find ("ycolor", aValues))
3863   {
3864     if (!GetColor (aValues->Value(1), aColor))
3865     {
3866       std::cout << theArgs[0] << "error: -ycolor wrong color name.\n";
3867       return 1;
3868     }
3869     aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
3870   }
3871   if (aMapOfArgs.Find ("zcolor", aValues))
3872   {
3873     if (!GetColor (aValues->Value(1), aColor))
3874     {
3875       std::cout << theArgs[0] << "error: -zcolor wrong color name.\n";
3876       return 1;
3877     }
3878     aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
3879   }
3880
3881   // TICKMARKS
3882   if (aMapOfArgs.Find ("xticks", aValues))
3883   {
3884     aTrihedronData.ChangeXAxisAspect().SetTickmarkNumber (aValues->Value(1).IntegerValue());
3885   }
3886   if (aMapOfArgs.Find ("yticks", aValues))
3887   {
3888     aTrihedronData.ChangeYAxisAspect().SetTickmarkNumber (aValues->Value(1).IntegerValue());
3889   }
3890   if (aMapOfArgs.Find ("zticks", aValues))
3891   {
3892     aTrihedronData.ChangeZAxisAspect().SetTickmarkNumber (aValues->Value(1).IntegerValue());
3893   }
3894   if (aMapOfArgs.Find ("xticklength", aValues))
3895   {
3896     aTrihedronData.ChangeXAxisAspect().SetTickmarkLength (aValues->Value(1).IntegerValue());
3897   }
3898   if (aMapOfArgs.Find ("yticklength", aValues))
3899   {
3900     aTrihedronData.ChangeYAxisAspect().SetTickmarkLength (aValues->Value(1).IntegerValue());
3901   }
3902   if (aMapOfArgs.Find ("zticklength", aValues))
3903   {
3904     aTrihedronData.ChangeZAxisAspect().SetTickmarkLength (aValues->Value(1).IntegerValue());
3905   }
3906   if (aMapOfArgs.Find ("xdrawticks", aValues))
3907   {
3908     aTrihedronData.ChangeXAxisAspect().SetToDrawTickmarks (aValues->Value(1).IsEqual ("on"));
3909   }
3910   if (aMapOfArgs.Find ("ydrawticks", aValues))
3911   {
3912     aTrihedronData.ChangeYAxisAspect().SetToDrawTickmarks (aValues->Value(1).IsEqual ("on"));
3913   }
3914   if (aMapOfArgs.Find ("zdrawticks", aValues))
3915   {
3916     aTrihedronData.ChangeZAxisAspect().SetToDrawTickmarks (aValues->Value(1).IsEqual ("on"));
3917   }
3918
3919   // VALUES
3920   if (aMapOfArgs.Find ("xdrawvalues", aValues))
3921   {
3922     aTrihedronData.ChangeXAxisAspect().SetToDrawValues (aValues->Value(1).IsEqual ("on"));
3923   }
3924   if (aMapOfArgs.Find ("ydrawvalues", aValues))
3925   {
3926     aTrihedronData.ChangeYAxisAspect().SetToDrawValues (aValues->Value(1).IsEqual ("on"));
3927   }
3928   if (aMapOfArgs.Find ("zdrawvalues", aValues))
3929   {
3930     aTrihedronData.ChangeZAxisAspect().SetToDrawValues (aValues->Value(1).IsEqual ("on"));
3931   }
3932   if (aMapOfArgs.Find ("xvaluesoffset", aValues))
3933   {
3934     aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
3935   }
3936   if (aMapOfArgs.Find ("yvaluesoffset", aValues))
3937   {
3938     aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
3939   }
3940   if (aMapOfArgs.Find ("zvaluesoffset", aValues))
3941   {
3942     aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
3943   }
3944
3945   // ARROWS
3946   if (aMapOfArgs.Find ("arrowlength", aValues))
3947   {
3948     aTrihedronData.SetArrowLength ((Standard_ShortReal) aValues->Value(1).RealValue());
3949   }
3950
3951   // FONTS
3952   if (aMapOfArgs.Find ("namefont", aValues))
3953   {
3954     aTrihedronData.SetNamesFont (aValues->Value(1));
3955   }
3956   if (aMapOfArgs.Find ("valuesfont", aValues))
3957   {
3958     aTrihedronData.SetValuesFont (aValues->Value(1));
3959   }
3960
3961   // The final step: display of erase trihedron
3962   if (toDisplay)
3963   {
3964     ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
3965   }
3966   else
3967   {
3968     ViewerTest::CurrentView()->GraduatedTrihedronErase();
3969   }
3970
3971   ViewerTest::GetAISContext()->UpdateCurrentViewer();
3972   ViewerTest::CurrentView()->Redraw();
3973
3974   return 0;
3975 }
3976
3977 //==============================================================================
3978 //function : VPrintView
3979 //purpose  : Test printing algorithm, print the view to image file with given
3980 //           width and height. Printing implemented only for WNT.
3981 //==============================================================================
3982 static int VPrintView (Draw_Interpretor& di, Standard_Integer argc,
3983                        const char** argv)
3984 {
3985 #ifndef WNT
3986   di << "Printing implemented only for wnt!\n";
3987   return 0;
3988 #else
3989
3990   Handle(AIS_InteractiveContext) aContextAIS = NULL;
3991   Handle(V3d_View) aView = NULL;
3992   aContextAIS = ViewerTest::GetAISContext();
3993   if (!aContextAIS.IsNull())
3994   {
3995     const Handle(V3d_Viewer)& Vwr = aContextAIS->CurrentViewer();
3996     Vwr->InitActiveViews();
3997     if(Vwr->MoreActiveViews())
3998       aView = Vwr->ActiveView();
3999   }
4000
4001   // check for errors
4002   if (aView.IsNull())
4003   {
4004     di << "Call vinit before!\n";
4005     return 1;
4006   }
4007   else if (argc < 4)
4008   {
4009     di << "Use: " << argv[0];
4010     di << " width height filename [print algo=0] [tile_width tile_height]\n";
4011     di << "width, height of the intermediate buffer for operation\n";
4012     di << "algo : {0|1}\n";
4013     di << "        0 - stretch algorithm\n";
4014     di << "        1 - tile algorithm\n";
4015     di << "test printing algorithms into an intermediate buffer\n";
4016     di << "using specific tile size if provided\n";
4017     di << "with saving output to an image file\n";
4018     return 1;
4019   }
4020
4021   // get the input params
4022   Standard_Integer aWidth  = Draw::Atoi (argv[1]);
4023   Standard_Integer aHeight = Draw::Atoi (argv[2]);
4024   Standard_Integer aMode   = 0;
4025   TCollection_AsciiString aFileName = TCollection_AsciiString (argv[3]);
4026   if (argc >= 5)
4027     aMode = Draw::Atoi (argv[4]);
4028
4029   Standard_Integer aTileWidth  = 0;
4030   Standard_Integer aTileHeight = 0;
4031   Standard_Boolean isTileSizeProvided = Standard_False;
4032   if (argc == 7)
4033   {
4034     isTileSizeProvided = Standard_True;
4035     aTileWidth  = Draw::Atoi (argv[5]);
4036     aTileHeight = Draw::Atoi (argv[6]);
4037   }
4038
4039   // check the input parameters
4040   if (aWidth <= 0 || aHeight <= 0)
4041   {
4042     di << "Width and height must be positive values!\n";
4043     return 1;
4044   }
4045   if (aMode != 0 && aMode != 1)
4046     aMode = 0;
4047
4048   // define compatible bitmap
4049   HDC anDC = CreateCompatibleDC(0);
4050   BITMAPINFO aBitmapData;
4051   memset (&aBitmapData, 0, sizeof (BITMAPINFOHEADER));
4052   aBitmapData.bmiHeader.biSize          = sizeof (BITMAPINFOHEADER);
4053   aBitmapData.bmiHeader.biWidth         = aWidth ;
4054   aBitmapData.bmiHeader.biHeight        = aHeight;
4055   aBitmapData.bmiHeader.biPlanes        = 1;
4056   aBitmapData.bmiHeader.biBitCount      = 24;
4057   aBitmapData.bmiHeader.biXPelsPerMeter = 0;
4058   aBitmapData.bmiHeader.biYPelsPerMeter = 0;
4059   aBitmapData.bmiHeader.biClrUsed       = 0;
4060   aBitmapData.bmiHeader.biClrImportant  = 0;
4061   aBitmapData.bmiHeader.biCompression   = BI_RGB;
4062   aBitmapData.bmiHeader.biSizeImage     = 0;
4063
4064   // Create Device Independent Bitmap
4065   void* aBitsOut = NULL;
4066   HBITMAP aMemoryBitmap = CreateDIBSection (anDC, &aBitmapData, DIB_RGB_COLORS,
4067                                             &aBitsOut, NULL, 0);
4068   HGDIOBJ anOldBitmap   = SelectObject(anDC, aMemoryBitmap);
4069
4070   Standard_Boolean isSaved = Standard_False, isPrinted = Standard_False;
4071   if (aBitsOut != NULL)
4072   {
4073     if (aMode == 0)
4074       isPrinted = aView->Print(anDC,1,1,0,Aspect_PA_STRETCH);
4075     else
4076     {
4077       if (isTileSizeProvided)
4078       {
4079         Graphic3d_CView* aCView = static_cast<Graphic3d_CView*> (ViewerTest::CurrentView()->View()->CView());
4080         Graphic3d_PtrFrameBuffer anOldBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
4081         aCView->ptrFBO = aView->View()->FBOCreate (aTileWidth, aTileHeight);
4082
4083         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
4084
4085         Graphic3d_PtrFrameBuffer aNewBuffer = static_cast<Graphic3d_PtrFrameBuffer> (aCView->ptrFBO);
4086         aView->View()->FBORelease (aNewBuffer);
4087         aCView->ptrFBO = anOldBuffer;
4088       }
4089       else
4090       {
4091         isPrinted = aView->Print (anDC, 1, 1, 0, Aspect_PA_TILE);
4092       }
4093     }
4094
4095     // succesfully printed into an intermediate buffer
4096     if (isPrinted)
4097     {
4098       Image_PixMap aWrapper;
4099       aWrapper.InitWrapper (Image_PixMap::ImgBGR, (Standard_Byte* )aBitsOut, aWidth, aHeight, aWidth * 3 + aWidth % 4);
4100       aWrapper.SetTopDown (false);
4101
4102       Image_AlienPixMap anImageBitmap;
4103       anImageBitmap.InitCopy (aWrapper);
4104       isSaved = anImageBitmap.Save (aFileName);
4105     }
4106     else
4107     {
4108       di << "Print operation failed due to printing errors or\n";
4109       di << "insufficient memory available\n";
4110       di << "Please, try to use smaller dimensions for this test\n";
4111       di << "command, as it allocates intermediate buffer for storing\n";
4112       di << "the result\n";
4113     }
4114   }
4115   else
4116   {
4117     di << "Can't allocate memory for intermediate buffer\n";
4118     di << "Please use smaller dimensions\n";
4119   }
4120
4121   if (aMemoryBitmap)
4122   {
4123     SelectObject (anDC, anOldBitmap);
4124     DeleteObject (aMemoryBitmap);
4125     DeleteDC(anDC);
4126   }
4127
4128   if (!isSaved)
4129   {
4130     di << "Save to file operation failed. This operation may fail\n";
4131     di << "if you don't have enough available memory, then you can\n";
4132     di << "use smaller dimensions for the output file\n";
4133     return 1;
4134   }
4135
4136   return 0;
4137
4138 #endif
4139 }
4140
4141 //==============================================================================
4142 //function : VZLayer
4143 //purpose  : Test z layer operations for v3d viewer
4144 //==============================================================================
4145 static int VZLayer (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4146 {
4147   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
4148   if (aContextAIS.IsNull())
4149   {
4150     di << "Call vinit before!\n";
4151     return 1;
4152   }
4153   else if (argc < 2)
4154   {
4155     di << "Use: vzlayer ";
4156     di << " add/del/get/settings/enable/disable [id]\n";
4157     di << " add - add new z layer to viewer and print its id\n";
4158     di << " del - del z layer by its id\n";
4159     di << " get - print sequence of z layers in increasing order of their overlay level\n";
4160     di << " settings - print status of z layer settings\n";
4161     di << " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n";
4162     di << " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n";
4163     di << " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n";
4164     di << "\nWhere id is the layer identificator\n";
4165     di << "\nExamples:\n";
4166     di << "   vzlayer add\n";
4167     di << "   vzlayer enable poffset 1\n";
4168     di << "   vzlayer disable depthtest 1\n";
4169     di << "   vzlayer del 1\n";
4170     return 1;
4171   }
4172
4173   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
4174   if (aViewer.IsNull())
4175   {
4176     di << "No active viewer!\n";
4177     return 1;
4178   }
4179
4180   // perform operation
4181   TCollection_AsciiString anOp = TCollection_AsciiString (argv[1]);
4182   if (anOp == "add")
4183   {
4184     Standard_Integer aNewId;
4185     if (!aViewer->AddZLayer (aNewId))
4186     {
4187       di << "Impossible to add new z layer!\n";
4188       return 1;
4189     }
4190
4191     di << "New z layer added with index: " << aNewId << "\n";
4192   }
4193   else if (anOp == "del")
4194   {
4195     if (argc < 3)
4196     {
4197       di << "Please also provide as argument id of z layer to remove\n";
4198       return 1;
4199     }
4200
4201     Standard_Integer aDelId = Draw::Atoi (argv[2]);
4202     if (!aViewer->RemoveZLayer (aDelId))
4203     {
4204       di << "Impossible to remove the z layer or invalid id!\n";
4205       return 1;
4206     }
4207
4208     for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4209          anObjIter.More(); anObjIter.Next())
4210     {
4211       Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anObjIter.Key1());
4212       if (aPrs.IsNull()
4213        || aPrs->ZLayer() != aDelId)
4214       {
4215         continue;
4216       }
4217       aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
4218     }
4219
4220     di << "Z layer " << aDelId << " has been removed\n";
4221   }
4222   else if (anOp == "get")
4223   {
4224     TColStd_SequenceOfInteger anIds;
4225     aViewer->GetAllZLayers (anIds);
4226     for (Standard_Integer aSeqIdx = 1; aSeqIdx <= anIds.Length(); aSeqIdx++)
4227     {
4228       di << anIds.Value (aSeqIdx) << " ";
4229     }
4230
4231     di << "\n";
4232   }
4233   else if (anOp == "settings")
4234   {
4235     if (argc < 3)
4236     {
4237       di << "Please also provide an id\n";
4238       return 1;
4239     }
4240
4241     Standard_Integer anId = Draw::Atoi (argv[2]);
4242     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4243
4244     di << "Depth test - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthTest) ? "enabled" : "disabled") << "\n";
4245     di << "Depth write - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthWrite) ? "enabled" : "disabled") << "\n";
4246     di << "Depth buffer clearing - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthClear) ? "enabled" : "disabled") << "\n";
4247     di << "Depth offset - " << (aSettings.IsSettingEnabled (Graphic3d_ZLayerDepthOffset) ? "enabled" : "disabled") << "\n";
4248
4249   }
4250   else if (anOp == "enable")
4251   {
4252     if (argc < 3)
4253     {
4254       di << "Please also provide an option to enable\n";
4255       return 1;
4256     }
4257
4258     if (argc < 4)
4259     {
4260       di << "Please also provide a layer id\n";
4261       return 1;
4262     }
4263
4264     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
4265     Standard_Integer anId = Draw::Atoi (argv[3]);
4266     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4267
4268     if (aSubOp == "depthtest" || aSubOp == "test")
4269     {
4270       aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
4271     }
4272     else if (aSubOp == "depthwrite" || aSubOp == "write")
4273     {
4274       aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
4275     }
4276     else if (aSubOp == "depthclear" || aSubOp == "clear")
4277     {
4278       aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
4279     }
4280     else if (aSubOp == "depthoffset" || aSubOp == "offset")
4281     {
4282       if (argc < 6)
4283       {
4284         di << "Please also provide a factor and units values for depth offset\n";
4285         di << "Format is: vzlayer enable offset [factor] [units] [layerId]\n";
4286         return 1;
4287       }
4288
4289       Standard_ShortReal aFactor = static_cast<Standard_ShortReal> (Draw::Atof (argv[3]));
4290       Standard_ShortReal aUnits  = static_cast<Standard_ShortReal> (Draw::Atof (argv[4]));
4291       anId = Draw::Atoi (argv[5]);
4292       aSettings = aViewer->ZLayerSettings (anId);
4293
4294       aSettings.DepthOffsetFactor = aFactor;
4295       aSettings.DepthOffsetUnits  = aUnits;
4296
4297       aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
4298     }
4299     else if (aSubOp == "positiveoffset" || aSubOp == "poffset")
4300     {
4301       aSettings.SetDepthOffsetPositive();
4302     }
4303     else if (aSubOp == "negativeoffset" || aSubOp == "noffset")
4304     {
4305       aSettings.SetDepthOffsetNegative();
4306     }
4307
4308     aViewer->SetZLayerSettings (anId, aSettings);
4309   }
4310   else if (anOp == "disable")
4311   {
4312     if (argc < 3)
4313     {
4314       di << "Please also provide an option to disable\n";
4315       return 1;
4316     }
4317
4318     if (argc < 4)
4319     {
4320       di << "Please also provide a layer id\n";
4321       return 1;
4322     }
4323
4324     TCollection_AsciiString aSubOp = TCollection_AsciiString (argv[2]);
4325     Standard_Integer anId = Draw::Atoi (argv[3]);
4326     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
4327
4328     if (aSubOp == "depthtest" || aSubOp == "test")
4329     {
4330       aSettings.DisableSetting (Graphic3d_ZLayerDepthTest);
4331     }
4332     else if (aSubOp == "depthwrite" || aSubOp == "write")
4333     {
4334       aSettings.DisableSetting (Graphic3d_ZLayerDepthWrite);
4335     }
4336     else if (aSubOp == "depthclear" || aSubOp == "clear")
4337     {
4338       aSettings.DisableSetting (Graphic3d_ZLayerDepthClear);
4339     }
4340     else if (aSubOp == "depthoffset" || aSubOp == "offset")
4341     {
4342       aSettings.DisableSetting (Graphic3d_ZLayerDepthOffset);
4343     }
4344
4345     aViewer->SetZLayerSettings (anId, aSettings);
4346   }
4347   else
4348   {
4349     di << "Invalid operation, please use { add / del / get / settings / enable / disable}\n";
4350     return 1;
4351   }
4352
4353   return 0;
4354 }
4355
4356 DEFINE_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
4357
4358 // this class provides a presentation of text item in v3d view under-/overlayer
4359 class V3d_TextItem : public Visual3d_LayerItem
4360 {
4361 public:
4362
4363   // CASCADE RTTI
4364   DEFINE_STANDARD_RTTI(V3d_TextItem)
4365
4366   // constructor
4367   Standard_EXPORT V3d_TextItem(const TCollection_AsciiString& theText,
4368                                const Standard_Real theX1,
4369                                const Standard_Real theY1,
4370                                const Standard_Real theHeight,
4371                                const TCollection_AsciiString& theFontName,
4372                                const Quantity_Color& theColor,
4373                                const Quantity_Color& theSubtitleColor,
4374                                const Aspect_TypeOfDisplayText& theTypeOfDisplay,
4375                                const Handle(Visual3d_Layer)& theLayer);
4376
4377   // redraw method
4378   Standard_EXPORT void RedrawLayerPrs();
4379
4380 private:
4381
4382   Standard_Real            myX1;
4383   Standard_Real            myY1;
4384   TCollection_AsciiString  myText;
4385   Standard_Real            myHeight;
4386   Handle(Visual3d_Layer)   myLayer;
4387   Quantity_Color           myColor;
4388   Quantity_Color           mySubtitleColor;
4389   Aspect_TypeOfDisplayText myType;
4390   TCollection_AsciiString  myFontName;
4391 };
4392
4393 IMPLEMENT_STANDARD_HANDLE(V3d_TextItem, Visual3d_LayerItem)
4394 IMPLEMENT_STANDARD_RTTIEXT(V3d_TextItem, Visual3d_LayerItem)
4395
4396 // create and add to display the text item
4397 V3d_TextItem::V3d_TextItem (const TCollection_AsciiString& theText,
4398                             const Standard_Real theX1,
4399                             const Standard_Real theY1,
4400                             const Standard_Real theHeight,
4401                             const TCollection_AsciiString& theFontName,
4402                             const Quantity_Color& theColor,
4403                             const Quantity_Color& theSubtitleColor,
4404                             const Aspect_TypeOfDisplayText& theTypeOfDisplay,
4405                             const Handle(Visual3d_Layer)& theLayer)
4406  : myX1 (theX1), myY1 (theY1),
4407    myText (theText),
4408    myHeight (theHeight),
4409    myLayer (theLayer),
4410    myColor (theColor),
4411    mySubtitleColor (theSubtitleColor),
4412    myType (theTypeOfDisplay),
4413    myFontName (theFontName)
4414 {
4415   if (!myLayer.IsNull ())
4416     myLayer->AddLayerItem (this);
4417 }
4418
4419 // render item
4420 void V3d_TextItem::RedrawLayerPrs ()
4421 {
4422   if (myLayer.IsNull ())
4423     return;
4424
4425   myLayer->SetColor (myColor);
4426   myLayer->SetTextAttributes (myFontName.ToCString (), myType, mySubtitleColor);
4427   myLayer->DrawText (myText.ToCString (), myX1, myY1, myHeight);
4428 }
4429
4430 DEFINE_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
4431
4432 // The Visual3d_LayerItem line item for "vlayerline" command
4433 // it provides a presentation of line with user-defined
4434 // linewidth, linetype and transparency.
4435 class V3d_LineItem : public Visual3d_LayerItem
4436 {
4437 public:
4438   // CASCADE RTTI
4439   DEFINE_STANDARD_RTTI(V3d_LineItem)
4440
4441   // constructor
4442   Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4443                                Standard_Real X2, Standard_Real Y2,
4444                                V3d_LayerMgrPointer theLayerMgr,
4445                                Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
4446                                Standard_Real theWidth    = 0.5,
4447                                Standard_Real theTransp   = 1.0);
4448
4449   // redraw method
4450   Standard_EXPORT   void RedrawLayerPrs();
4451
4452 private:
4453
4454   Standard_Real       myX1, myY1, myX2, myY2;
4455   V3d_LayerMgrPointer myLayerMgr;
4456   Aspect_TypeOfLine   myType;
4457   Standard_Real       myWidth;
4458   Standard_Real       myTransparency;
4459 };
4460
4461 IMPLEMENT_STANDARD_HANDLE(V3d_LineItem, Visual3d_LayerItem)
4462 IMPLEMENT_STANDARD_RTTIEXT(V3d_LineItem, Visual3d_LayerItem)
4463
4464 // default constructor for line item
4465 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4466                            Standard_Real X2, Standard_Real Y2,
4467                            V3d_LayerMgrPointer theLayerMgr,
4468                            Aspect_TypeOfLine theType,
4469                            Standard_Real theWidth,
4470                            Standard_Real theTransp) :
4471   myX1(X1), myY1(Y1), myX2(X2), myY2(Y2), myLayerMgr(theLayerMgr),
4472   myType(theType), myWidth(theWidth), myTransparency(theTransp)
4473 {
4474   if (myLayerMgr && !myLayerMgr->Overlay().IsNull())
4475     myLayerMgr->Overlay()->AddLayerItem (this);
4476 }
4477
4478 // render line
4479 void V3d_LineItem::RedrawLayerPrs ()
4480 {
4481   Handle (Visual3d_Layer) aOverlay;
4482
4483   if (myLayerMgr)
4484     aOverlay = myLayerMgr->Overlay();
4485
4486   if (!aOverlay.IsNull())
4487   {
4488     Quantity_Color aColor(1.0, 0, 0, Quantity_TOC_RGB);
4489     aOverlay->SetColor(aColor);
4490     aOverlay->SetTransparency((Standard_ShortReal)myTransparency);
4491     aOverlay->SetLineAttributes((Aspect_TypeOfLine)myType, myWidth);
4492     aOverlay->BeginPolyline();
4493     aOverlay->AddVertex(myX1, myY1);
4494     aOverlay->AddVertex(myX2, myY2);
4495     aOverlay->ClosePrimitive();
4496   }
4497 }
4498
4499 //=============================================================================
4500 //function : VLayerLine
4501 //purpose  : Draws line in the v3d view layer with given attributes: linetype,
4502 //         : linewidth, transparency coefficient
4503 //============================================================================
4504 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4505 {
4506   // get the active view
4507   Handle(V3d_View) aView = ViewerTest::CurrentView();
4508   if (aView.IsNull())
4509   {
4510     di << "Call vinit before!\n";
4511     return 1;
4512   }
4513   else if (argc < 5)
4514   {
4515     di << "Use: " << argv[0];
4516     di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
4517     di << " linetype : { 0 | 1 | 2 | 3 } \n";
4518     di << "              0 - solid  \n";
4519     di << "              1 - dashed \n";
4520     di << "              2 - dot    \n";
4521     di << "              3 - dashdot\n";
4522     di << " transparency : { 0.0 - 1.0 } \n";
4523     di << "                  0.0 - transparent\n";
4524     di << "                  1.0 - visible    \n";
4525     return 1;
4526   }
4527
4528   // get the input params
4529   Standard_Real X1 = Draw::Atof(argv[1]);
4530   Standard_Real Y1 = Draw::Atof(argv[2]);
4531   Standard_Real X2 = Draw::Atof(argv[3]);
4532   Standard_Real Y2 = Draw::Atof(argv[4]);
4533
4534   Standard_Real    aWidth = 0.5;
4535   Standard_Integer aType  = 0;
4536   Standard_Real    aTransparency = 1.0;
4537
4538   // has width
4539   if (argc > 5)
4540     aWidth = Draw::Atof(argv[5]);
4541
4542   // has type
4543   if (argc > 6)
4544      aType = (Standard_Integer) Draw::Atoi(argv[6]);
4545
4546   // has transparency
4547   if (argc > 7)
4548   {
4549     aTransparency = Draw::Atof(argv[7]);
4550     if (aTransparency < 0 || aTransparency > 1.0)
4551       aTransparency = 1.0;
4552   }
4553
4554   // select appropriate line type
4555   Aspect_TypeOfLine aLineType;
4556   switch (aType)
4557   {
4558     case 1:
4559       aLineType = Aspect_TOL_DASH;
4560     break;
4561
4562     case 2:
4563       aLineType = Aspect_TOL_DOT;
4564     break;
4565
4566     case 3:
4567       aLineType = Aspect_TOL_DOTDASH;
4568     break;
4569
4570     default:
4571       aLineType = Aspect_TOL_SOLID;
4572   }
4573
4574   // replace layer manager
4575   Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr(aView);
4576   aView->SetLayerMgr(aMgr);
4577
4578   // add line item
4579   Handle (V3d_LineItem) anItem = new V3d_LineItem(X1, Y1, X2, Y2,
4580                                                   aMgr.operator->(),
4581                                                   aLineType, aWidth,
4582                                                   aTransparency);
4583
4584   // update view
4585   aView->MustBeResized();
4586   aView->Redraw();
4587
4588   return 0;
4589 }
4590
4591 //=======================================================================
4592 //function : VOverlayText
4593 //purpose  : Test text displaying in view overlay
4594 //=======================================================================
4595 static int VOverlayText (Draw_Interpretor& di, Standard_Integer argc, const char**argv)
4596 {
4597   // get the active view
4598   Handle(V3d_View) aView = ViewerTest::CurrentView();
4599   if (aView.IsNull())
4600   {
4601     di << "No active view. Please call vinit.\n";
4602     return 1;
4603   }
4604   else if (argc < 4 || argc > 13)
4605   {
4606     di << "Use: " << argv[0];
4607     di << " text x y [height] [font_name] [text_color: R G B] [displayType]\n";
4608     di << "[background_color: R G B]\n";
4609     di << "  height - pixel height of the text (default=10.0)\n";
4610     di << "  font_name - name of font (default=courier)\n";
4611     di << "  text_color - R G B values of text color (default=255.0 255.0 255.0)\n";
4612     di << "  display_type = {normal/subtitle/decal/blend/dimension}, (default=normal)\n";
4613     di << "  background_color- R G B values used for subtitle and decal text\n";
4614     di << "(default=255.0 255.0 255.0)\n";
4615     return 1;
4616   }
4617
4618   TCollection_AsciiString aText (argv[1]);
4619   Standard_Real aPosX = Draw::Atof(argv[2]);
4620   Standard_Real aPosY = Draw::Atof(argv[3]);
4621   Standard_Real aHeight = (argc >= 5) ? Draw::Atof (argv[4]) : 10.0;
4622
4623   // font name
4624   TCollection_AsciiString aFontName = "Courier";
4625   if (argc >= 6)
4626     aFontName = TCollection_AsciiString (argv[5]);
4627
4628   // text colors
4629   Quantity_Parameter aColorRed   = 1.0;
4630   Quantity_Parameter aColorGreen = 1.0;
4631   Quantity_Parameter aColorBlue  = 1.0;
4632   if (argc >= 9)
4633   {
4634     aColorRed   = Draw::Atof (argv[6])/255.;
4635     aColorGreen = Draw::Atof (argv[7])/255.;
4636     aColorBlue  = Draw::Atof (argv[8])/255.;
4637   }
4638
4639   // display type
4640   TCollection_AsciiString aDispStr;
4641   if (argc >= 10)
4642     aDispStr = TCollection_AsciiString (argv[9]);
4643
4644   Aspect_TypeOfDisplayText aTextType = Aspect_TODT_NORMAL;
4645   if (aDispStr.IsEqual ("subtitle"))
4646     aTextType = Aspect_TODT_SUBTITLE;
4647   else if (aDispStr.IsEqual ("decal"))
4648     aTextType = Aspect_TODT_DEKALE;
4649   else if (aDispStr.IsEqual ("blend"))
4650     aTextType = Aspect_TODT_BLEND;
4651   else if (aDispStr.IsEqual ("dimension"))
4652     aTextType = Aspect_TODT_DIMENSION;
4653
4654   // subtitle color
4655   Quantity_Parameter aSubRed   = 1.0;
4656   Quantity_Parameter aSubGreen = 1.0;
4657   Quantity_Parameter aSubBlue  = 1.0;
4658   if (argc == 13)
4659   {
4660     aSubRed   = Draw::Atof (argv[10])/255.;
4661     aSubGreen = Draw::Atof (argv[11])/255.;
4662     aSubBlue  = Draw::Atof (argv[12])/255.;
4663   }
4664
4665   // check fo current overlay
4666   Handle(Visual3d_Layer) anOverlay = aView->Viewer()->Viewer()->OverLayer ();
4667   if (anOverlay.IsNull ())
4668   {
4669     Handle(V3d_LayerMgr) aMgr = new V3d_LayerMgr (aView);
4670     anOverlay = aMgr->Overlay ();
4671     aView->SetLayerMgr (aMgr);
4672   }
4673
4674   Quantity_Color aTextColor (aColorRed, aColorGreen,
4675     aColorBlue, Quantity_TOC_RGB);
4676   Quantity_Color aSubtColor (aSubRed, aSubGreen,
4677     aSubBlue, Quantity_TOC_RGB);
4678
4679   // add text item
4680   Handle(V3d_TextItem) anItem = new V3d_TextItem (aText, aPosX, aPosY,
4681     aHeight, aFontName, aTextColor, aSubtColor, aTextType, anOverlay);
4682
4683   // update view
4684   aView->MustBeResized();
4685   aView->Redraw();
4686
4687   return 0;
4688 }
4689
4690 //==============================================================================
4691 //function : VGrid
4692 //purpose  :
4693 //==============================================================================
4694
4695 static int VGrid (Draw_Interpretor& /*theDI*/,
4696                   Standard_Integer  theArgNb,
4697                   const char**      theArgVec)
4698 {
4699   // get the active view
4700   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
4701   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
4702   if (aView.IsNull() || aViewer.IsNull())
4703   {
4704     std::cerr << "No active view. Please call vinit.\n";
4705     return 1;
4706   }
4707
4708   Aspect_GridType     aType = aViewer->GridType();
4709   Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
4710
4711   Standard_Integer anIter = 1;
4712   for (; anIter < theArgNb; ++anIter)
4713   {
4714     const char* aValue = theArgVec[anIter];
4715     if (*aValue == 'r')
4716     {
4717       aType = Aspect_GT_Rectangular;
4718     }
4719     else if (*aValue == 'c')
4720     {
4721       aType = Aspect_GT_Circular;
4722     }
4723     else if (*aValue == 'l')
4724     {
4725       aMode = Aspect_GDM_Lines;
4726     }
4727     else if (*aValue == 'p')
4728     {
4729       aMode = Aspect_GDM_Points;
4730     }
4731     else if (strcmp (aValue, "off" ) == 0)
4732     {
4733       aViewer->DeactivateGrid();
4734       return 0;
4735     }
4736     else
4737     {
4738       break;
4739     }
4740   }
4741
4742   Standard_Integer aTail = (theArgNb - anIter);
4743   if (aTail == 0)
4744   {
4745     aViewer->ActivateGrid (aType, aMode);
4746     return 0;
4747   }
4748   else if (aTail != 2 && aTail != 5)
4749   {
4750     std::cerr << "Incorrect arguments number! Usage:\n"
4751               << "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]\n";
4752     return 1;
4753   }
4754
4755   Quantity_Length anOriginX, anOriginY;
4756   Quantity_PlaneAngle aRotAngle;
4757   if (aType == Aspect_GT_Rectangular)
4758   {
4759     Quantity_Length aRStepX, aRStepY;
4760     aViewer->RectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
4761
4762     anOriginX = Draw::Atof (theArgVec[anIter++]);
4763     anOriginY = Draw::Atof (theArgVec[anIter++]);
4764     if (aTail == 5)
4765     {
4766       aRStepX   = Draw::Atof (theArgVec[anIter++]);
4767       aRStepY   = Draw::Atof (theArgVec[anIter++]);
4768       aRotAngle = Draw::Atof (theArgVec[anIter++]);
4769     }
4770     aViewer->SetRectangularGridValues (anOriginX, anOriginY, aRStepX, aRStepY, aRotAngle);
4771     aViewer->ActivateGrid (aType, aMode);
4772   }
4773   else if (aType == Aspect_GT_Circular)
4774   {
4775     Quantity_Length aRadiusStep;
4776     Standard_Integer aDivisionNumber;
4777     aViewer->CircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
4778
4779     anOriginX = Draw::Atof (theArgVec[anIter++]);
4780     anOriginY = Draw::Atof (theArgVec[anIter++]);
4781     if (aTail == 5)
4782     {
4783       aRadiusStep     = Draw::Atof (theArgVec[anIter++]);
4784       aDivisionNumber = Draw::Atoi (theArgVec[anIter++]);
4785       aRotAngle       = Draw::Atof (theArgVec[anIter++]);
4786     }
4787
4788     aViewer->SetCircularGridValues (anOriginX, anOriginY, aRadiusStep, aDivisionNumber, aRotAngle);
4789     aViewer->ActivateGrid (aType, aMode);
4790   }
4791
4792   return 0;
4793 }
4794
4795 //==============================================================================
4796 //function : VFps
4797 //purpose  :
4798 //==============================================================================
4799
4800 static int VFps (Draw_Interpretor& theDI,
4801                  Standard_Integer  theArgNb,
4802                  const char**      theArgVec)
4803 {
4804   // get the active view
4805   Handle(V3d_View) aView = ViewerTest::CurrentView();
4806   if (aView.IsNull())
4807   {
4808     std::cerr << "No active view. Please call vinit.\n";
4809     return 1;
4810   }
4811
4812   Standard_Integer aFramesNb = (theArgNb > 1) ? Draw::Atoi(theArgVec[1]) : 100;
4813   if (aFramesNb <= 0)
4814   {
4815     std::cerr << "Incorrect arguments!\n";
4816     return 1;
4817   }
4818
4819   // the time is meaningless for first call
4820   // due to async OpenGl rendering
4821   aView->Redraw();
4822
4823   // redraw view in loop to estimate average values
4824   OSD_Timer aTimer;
4825   aTimer.Start();
4826   for (Standard_Integer anInter = 0; anInter < aFramesNb; ++anInter)
4827   {
4828     aView->Redraw();
4829   }
4830   aTimer.Stop();
4831   Standard_Real aCpu;
4832   const Standard_Real aTime = aTimer.ElapsedTime();
4833   aTimer.OSD_Chronometer::Show (aCpu);
4834
4835   const Standard_Real aFpsAver = Standard_Real(aFramesNb) / aTime;
4836   const Standard_Real aCpuAver = aCpu / Standard_Real(aFramesNb);
4837
4838   // return statistics
4839   theDI << "FPS: " << aFpsAver << "\n"
4840         << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
4841
4842   return 0;
4843 }
4844
4845 //==============================================================================
4846 //function : VGlDebug
4847 //purpose  :
4848 //==============================================================================
4849
4850 static int VGlDebug (Draw_Interpretor& theDI,
4851                      Standard_Integer  theArgNb,
4852                      const char**      theArgVec)
4853 {
4854   Handle(OpenGl_GraphicDriver) aDriver;
4855   Handle(V3d_View) aView = ViewerTest::CurrentView();
4856   if (!aView.IsNull())
4857   {
4858     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
4859   }
4860   if (theArgNb < 2)
4861   {
4862     if (aDriver.IsNull())
4863     {
4864       std::cerr << "No active view. Please call vinit.\n";
4865       return 0;
4866     }
4867
4868     Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )glGetString (GL_EXTENSIONS),
4869                                                                 "GL_ARB_debug_output");
4870     std::cout << "Active graphic driver: debug " << (isActive ? "ON" : "OFF") << "\n";
4871     theDI << (isActive ? "1" : "0");
4872     return 0;
4873   }
4874
4875   const Standard_Boolean toEnableDebug = Draw::Atoi (theArgVec[1]) != 0;
4876   ViewerTest_myDefaultCaps.contextDebug = toEnableDebug;
4877   ViewerTest_myDefaultCaps.glslWarnings = toEnableDebug;
4878   if (aDriver.IsNull())
4879   {
4880     return 0;
4881   }
4882
4883   aDriver->ChangeOptions().glslWarnings = toEnableDebug;
4884   return 0;
4885 }
4886
4887 //==============================================================================
4888 //function : VVbo
4889 //purpose  :
4890 //==============================================================================
4891
4892 static int VVbo (Draw_Interpretor& theDI,
4893                  Standard_Integer  theArgNb,
4894                  const char**      theArgVec)
4895 {
4896   const Standard_Boolean toSet    = (theArgNb > 1);
4897   const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
4898   if (toSet)
4899   {
4900     ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
4901   }
4902
4903   // get the context
4904   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4905   if (aContextAIS.IsNull())
4906   {
4907     if (!toSet)
4908     {
4909       std::cerr << "No active view!\n";
4910     }
4911     return 1;
4912   }
4913   Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
4914   if (!aDriver.IsNull())
4915   {
4916     if (!toSet)
4917     {
4918       theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
4919     }
4920     else
4921     {
4922       aDriver->ChangeOptions().vboDisable = toUseVbo;
4923     }
4924   }
4925
4926   return 0;
4927 }
4928
4929 //==============================================================================
4930 //function : VCaps
4931 //purpose  :
4932 //==============================================================================
4933
4934 static int VCaps (Draw_Interpretor& theDI,
4935                   Standard_Integer  theArgNb,
4936                   const char**      theArgVec)
4937 {
4938   OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
4939   Handle(OpenGl_GraphicDriver)   aDriver;
4940   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4941   if (!aContext.IsNull())
4942   {
4943     aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
4944     aCaps   = &aDriver->ChangeOptions();
4945   }
4946
4947   if (theArgNb < 2)
4948   {
4949     theDI << "VBO:     " << (aCaps->vboDisable        ? "0" : "1") << "\n";
4950     theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
4951     theDI << "SoftMode:" << (aCaps->contextNoAccel    ? "1" : "0") << "\n";
4952     theDI << "FFP:     " << (aCaps->ffpEnable         ? "1" : "0") << "\n";
4953     theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
4954     return 0;
4955   }
4956
4957   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
4958   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4959   {
4960     Standard_CString        anArg     = theArgVec[anArgIter];
4961     TCollection_AsciiString anArgCase (anArg);
4962     anArgCase.LowerCase();
4963     if (anUpdateTool.parseRedrawMode (anArg))
4964     {
4965       continue;
4966     }
4967     else if (anArgCase == "-ffp")
4968     {
4969       Standard_Boolean toEnable = Standard_True;
4970       if (++anArgIter < theArgNb
4971       && !parseOnOff (theArgVec[anArgIter], toEnable))
4972       {
4973         --anArgIter;
4974       }
4975       aCaps->ffpEnable = toEnable;
4976     }
4977     else if (anArgCase == "-vbo")
4978     {
4979       Standard_Boolean toEnable = Standard_True;
4980       if (++anArgIter < theArgNb
4981       && !parseOnOff (theArgVec[anArgIter], toEnable))
4982       {
4983         --anArgIter;
4984       }
4985       aCaps->vboDisable = !toEnable;
4986     }
4987     else if (anArgCase == "-sprite"
4988           || anArgCase == "-sprites")
4989     {
4990       Standard_Boolean toEnable = Standard_True;
4991       if (++anArgIter < theArgNb
4992       && !parseOnOff (theArgVec[anArgIter], toEnable))
4993       {
4994         --anArgIter;
4995       }
4996       aCaps->pntSpritesDisable = !toEnable;
4997     }
4998     else if (anArgCase == "-softmode")
4999     {
5000       Standard_Boolean toEnable = Standard_True;
5001       if (++anArgIter < theArgNb
5002       && !parseOnOff (theArgVec[anArgIter], toEnable))
5003       {
5004         --anArgIter;
5005       }
5006       aCaps->contextNoAccel = toEnable;
5007     }
5008     else if (anArgCase == "-accel"
5009           || anArgCase == "-acceleration")
5010     {
5011       Standard_Boolean toEnable = Standard_True;
5012       if (++anArgIter < theArgNb
5013       && !parseOnOff (theArgVec[anArgIter], toEnable))
5014       {
5015         --anArgIter;
5016       }
5017       aCaps->contextNoAccel = !toEnable;
5018     }
5019     else if (anArgCase == "-compat"
5020           || anArgCase == "-compatprofile"
5021           || anArgCase == "-compatible"
5022           || anArgCase == "-compatibleprofile")
5023     {
5024       Standard_Boolean toEnable = Standard_True;
5025       if (++anArgIter < theArgNb
5026       && !parseOnOff (theArgVec[anArgIter], toEnable))
5027       {
5028         --anArgIter;
5029       }
5030       aCaps->contextCompatible = toEnable;
5031       if (!aCaps->contextCompatible)
5032       {
5033         aCaps->ffpEnable = Standard_False;
5034       }
5035     }
5036     else if (anArgCase == "-core"
5037           || anArgCase == "-coreprofile")
5038     {
5039       Standard_Boolean toEnable = Standard_True;
5040       if (++anArgIter < theArgNb
5041       && !parseOnOff (theArgVec[anArgIter], toEnable))
5042       {
5043         --anArgIter;
5044       }
5045       aCaps->contextCompatible = !toEnable;
5046       if (!aCaps->contextCompatible)
5047       {
5048         aCaps->ffpEnable = Standard_False;
5049       }
5050     }
5051     else
5052     {
5053       std::cout << "Error: unknown argument '" << anArg << "'\n";
5054       return 1;
5055     }
5056   }
5057   if (aCaps != &ViewerTest_myDefaultCaps)
5058   {
5059     ViewerTest_myDefaultCaps = *aCaps;
5060   }
5061   return 0;
5062 }
5063
5064 //==============================================================================
5065 //function : VMemGpu
5066 //purpose  :
5067 //==============================================================================
5068
5069 static int VMemGpu (Draw_Interpretor& theDI,
5070                     Standard_Integer  theArgNb,
5071                     const char**      theArgVec)
5072 {
5073   // get the context
5074   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5075   if (aContextAIS.IsNull())
5076   {
5077     std::cerr << "No active view. Please call vinit.\n";
5078     return 1;
5079   }
5080
5081   Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
5082   if (aDriver.IsNull())
5083   {
5084     std::cerr << "Graphic driver not available.\n";
5085     return 1;
5086   }
5087
5088   Standard_Size aFreeBytes = 0;
5089   TCollection_AsciiString anInfo;
5090   if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
5091   {
5092     std::cerr << "Information not available.\n";
5093     return 1;
5094   }
5095
5096   if (theArgNb > 1 && *theArgVec[1] == 'f')
5097   {
5098     theDI << Standard_Real (aFreeBytes);
5099   }
5100   else
5101   {
5102     theDI << anInfo;
5103   }
5104
5105   return 0;
5106 }
5107
5108 // ==============================================================================
5109 // function : VReadPixel
5110 // purpose  :
5111 // ==============================================================================
5112 static int VReadPixel (Draw_Interpretor& theDI,
5113                        Standard_Integer  theArgNb,
5114                        const char**      theArgVec)
5115 {
5116   // get the active view
5117   Handle(V3d_View) aView = ViewerTest::CurrentView();
5118   if (aView.IsNull())
5119   {
5120     std::cerr << "No active view. Please call vinit.\n";
5121     return 1;
5122   }
5123   else if (theArgNb < 3)
5124   {
5125     std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
5126     return 1;
5127   }
5128
5129   Image_PixMap::ImgFormat aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
5130   Graphic3d_BufferType    aBufferType = Graphic3d_BT_RGBA;
5131
5132   Standard_Integer aWidth, aHeight;
5133   aView->Window()->Size (aWidth, aHeight);
5134   const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
5135   const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
5136   if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
5137   {
5138     std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
5139     return 1;
5140   }
5141
5142   Standard_Boolean toShowName = Standard_False;
5143   Standard_Boolean toShowHls  = Standard_False;
5144   for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
5145   {
5146     const char* aParam = theArgVec[anIter];
5147     if ( strcasecmp( aParam, "rgb" ) == 0 )
5148     {
5149       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
5150       aBufferType = Graphic3d_BT_RGB;
5151     }
5152     else if ( strcasecmp( aParam, "hls" ) == 0 )
5153     {
5154       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
5155       aBufferType = Graphic3d_BT_RGB;
5156       toShowHls   = Standard_True;
5157     }
5158     else if ( strcasecmp( aParam, "rgbf" ) == 0 )
5159     {
5160       aFormat     = Image_PixMap::ImgRGBF;
5161       aBufferType = Graphic3d_BT_RGB;
5162     }
5163     else if ( strcasecmp( aParam, "rgba" ) == 0 )
5164     {
5165       aFormat     = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
5166       aBufferType = Graphic3d_BT_RGBA;
5167     }
5168     else if ( strcasecmp( aParam, "rgbaf" ) == 0 )
5169     {
5170       aFormat     = Image_PixMap::ImgRGBAF;
5171       aBufferType = Graphic3d_BT_RGBA;
5172     }
5173     else if ( strcasecmp( aParam, "depth" ) == 0 )
5174     {
5175       aFormat     = Image_PixMap::ImgGrayF;
5176       aBufferType = Graphic3d_BT_Depth;
5177     }
5178     else if ( strcasecmp( aParam, "name" ) == 0 )
5179     {
5180       toShowName = Standard_True;
5181     }
5182   }
5183
5184   Image_PixMap anImage;
5185   if (!anImage.InitTrash (aFormat, aWidth, aHeight))
5186   {
5187     std::cerr << "Image allocation failed\n";
5188     return 1;
5189   }
5190   else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
5191   {
5192     std::cerr << "Image dump failed\n";
5193     return 1;
5194   }
5195
5196   Quantity_Parameter anAlpha;
5197   Quantity_Color aColor = anImage.PixelColor (anX, anY, anAlpha);
5198   if (toShowName)
5199   {
5200     if (aBufferType == Graphic3d_BT_RGBA)
5201     {
5202       theDI << Quantity_Color::StringName (aColor.Name()) << " " << anAlpha;
5203     }
5204     else
5205     {
5206       theDI << Quantity_Color::StringName (aColor.Name());
5207     }
5208   }
5209   else
5210   {
5211     switch (aBufferType)
5212     {
5213       default:
5214       case Graphic3d_BT_RGB:
5215       {
5216         if (toShowHls)
5217         {
5218           theDI << aColor.Hue() << " " << aColor.Light() << " " << aColor.Saturation();
5219         }
5220         else
5221         {
5222           theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue();
5223         }
5224         break;
5225       }
5226       case Graphic3d_BT_RGBA:
5227       {
5228         theDI << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " " << anAlpha;
5229         break;
5230       }
5231       case Graphic3d_BT_Depth:
5232       {
5233         theDI << aColor.Red();
5234         break;
5235       }
5236     }
5237   }
5238
5239   return 0;
5240 }
5241
5242 //==============================================================================
5243 //function : VDiffImage
5244 //purpose  : The draw-command compares two images.
5245 //==============================================================================
5246
5247 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
5248 {
5249   if (theArgNb < 6)
5250   {
5251     theDI << "Not enough arguments.\n";
5252     return 1;
5253   }
5254
5255   // image file names
5256   const char* anImgPathRef = theArgVec[1];
5257   const char* anImgPathNew = theArgVec[2];
5258
5259   // get string tolerance and check its validity
5260   Standard_Real aTolColor = Draw::Atof (theArgVec[3]);
5261   if (aTolColor < 0.0)
5262     aTolColor = 0.0;
5263   if (aTolColor > 1.0)
5264     aTolColor = 1.0;
5265
5266   Standard_Boolean toBlackWhite     = (Draw::Atoi (theArgVec[4]) == 1);
5267   Standard_Boolean isBorderFilterOn = (Draw::Atoi (theArgVec[5]) == 1);
5268
5269   // image file of difference
5270   const char* aDiffImagePath = (theArgNb >= 7) ? theArgVec[6] : NULL;
5271
5272   // compare the images
5273   Image_Diff aComparer;
5274   if (!aComparer.Init (anImgPathRef, anImgPathNew, toBlackWhite))
5275   {
5276     return 1;
5277   }
5278
5279   aComparer.SetColorTolerance (aTolColor);
5280   aComparer.SetBorderFilterOn (isBorderFilterOn);
5281   Standard_Integer aDiffColorsNb = aComparer.Compare();
5282   theDI << aDiffColorsNb << "\n";
5283
5284   // save image of difference
5285   if (aDiffColorsNb >0 && aDiffImagePath != NULL)
5286   {
5287     aComparer.SaveDiffImage (aDiffImagePath);
5288   }
5289
5290   return 0;
5291 }
5292
5293 //=======================================================================
5294 //function : VSelect
5295 //purpose  : Emulates different types of selection by mouse:
5296 //           1) single click selection
5297 //           2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
5298 //           3) selection with polygon having corners at
5299 //           pixel positions (x1,y1),...,(xn,yn)
5300 //           4) any of these selections with shift button pressed
5301 //=======================================================================
5302 static Standard_Integer VSelect (Draw_Interpretor& di,
5303                                  Standard_Integer argc,
5304                                  const char ** argv)
5305 {
5306   if(argc < 3)
5307   {
5308     di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]" << "\n";
5309     return 1;
5310   }
5311
5312   Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
5313   if(myAIScontext.IsNull())
5314   {
5315     di << "use 'vinit' command before " << argv[0] << "\n";
5316     return 1;
5317   }
5318   const Standard_Boolean isShiftSelection = (argc>3 && !(argc%2) && (atoi(argv[argc-1])==1));
5319   Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
5320   aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
5321   if(argc <= 4)
5322   {
5323     if(isShiftSelection)
5324       aCurrentEventManager->ShiftSelect();
5325     else
5326       aCurrentEventManager->Select();
5327   }
5328   else if(argc <= 6)
5329   {
5330     if(isShiftSelection)
5331       aCurrentEventManager->ShiftSelect(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
5332     else
5333       aCurrentEventManager->Select(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
5334   }
5335   else
5336   {
5337     Standard_Integer anUpper = 0;
5338
5339     if(isShiftSelection)
5340       anUpper = (argc-1)/2;
5341     else
5342       anUpper = argc/2;
5343     TColgp_Array1OfPnt2d aPolyline(1,anUpper);
5344
5345     for(Standard_Integer i=1;i<=anUpper;++i)
5346       aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
5347
5348     if(isShiftSelection)
5349       aCurrentEventManager->ShiftSelect(aPolyline);
5350     else
5351       aCurrentEventManager->Select(aPolyline);
5352   }
5353   return 0;
5354 }
5355
5356 //=======================================================================
5357 //function : VMoveTo
5358 //purpose  : Emulates cursor movement to defined pixel position
5359 //=======================================================================
5360 static Standard_Integer VMoveTo (Draw_Interpretor& di,
5361                                 Standard_Integer argc,
5362                                 const char ** argv)
5363 {
5364   if(argc != 3)
5365   {
5366     di << "Usage : " << argv[0] << " x y" << "\n";
5367     return 1;
5368   }
5369
5370   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5371   if(aContext.IsNull())
5372   {
5373     di << "use 'vinit' command before " << argv[0] << "\n";
5374     return 1;
5375   }
5376   ViewerTest::CurrentEventManager()->MoveTo(atoi(argv[1]),atoi(argv[2]));
5377   return 0;
5378 }
5379
5380 //=================================================================================================
5381 //function : VViewParams
5382 //purpose  : Gets or sets AIS View characteristics
5383 //=================================================================================================
5384 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
5385 {
5386   Handle(V3d_View) anAISView = ViewerTest::CurrentView();
5387   if (anAISView.IsNull())
5388   {
5389     std::cout << theArgVec[0] << ": please initialize or activate view.\n";
5390     return 1;
5391   }
5392
5393   if (theArgsNb == 1)
5394   {
5395     // print all of the available view parameters
5396     Quantity_Factor anAISViewScale = anAISView->Scale();
5397
5398     Standard_Real anAISViewProjX = 0.0;
5399     Standard_Real anAISViewProjY = 0.0;
5400     Standard_Real anAISViewProjZ = 0.0;
5401     anAISView->Proj (anAISViewProjX, anAISViewProjY, anAISViewProjZ);
5402
5403     Standard_Real anAISViewUpX = 0.0;
5404     Standard_Real anAISViewUpY = 0.0;
5405     Standard_Real anAISViewUpZ = 0.0;
5406     anAISView->Up (anAISViewUpX, anAISViewUpY, anAISViewUpZ);
5407
5408     Standard_Real anAISViewAtX = 0.0;
5409     Standard_Real anAISViewAtY = 0.0;
5410     Standard_Real anAISViewAtZ = 0.0;
5411     anAISView->At (anAISViewAtX, anAISViewAtY, anAISViewAtZ);
5412
5413     Standard_Real anAISViewEyeX = 0.0;
5414     Standard_Real anAISViewEyeY = 0.0;
5415     Standard_Real anAISViewEyeZ = 0.0;
5416     anAISView->Eye (anAISViewEyeX, anAISViewEyeY, anAISViewEyeZ);
5417
5418     theDi << "Scale of current view: " << anAISViewScale << "\n";
5419     theDi << "Proj on X : " << anAISViewProjX << "; on Y: " << anAISViewProjY << "; on Z: " << anAISViewProjZ << "\n";
5420     theDi << "Up on X : " << anAISViewUpX << "; on Y: " << anAISViewUpY << "; on Z: " << anAISViewUpZ << "\n";
5421     theDi << "At on X : " << anAISViewAtX << "; on Y: " << anAISViewAtY << "; on Z: " << anAISViewAtZ << "\n";
5422     theDi << "Eye on X : " << anAISViewEyeX << "; on Y: " << anAISViewEyeY << "; on Z: " << anAISViewEyeZ << "\n";
5423     return 0;
5424   }
5425
5426   // -------------------------
5427   //  Parse options and values
5428   // -------------------------
5429
5430   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfKeysByValues;
5431   TCollection_AsciiString aParseKey;
5432   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
5433   {
5434     TCollection_AsciiString anArg (theArgVec [anArgIt]);
5435
5436     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
5437     {
5438       aParseKey = anArg;
5439       aParseKey.Remove (1);
5440       aParseKey.UpperCase();
5441       aMapOfKeysByValues.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
5442       continue;
5443     }
5444
5445     if (aParseKey.IsEmpty())
5446     {
5447       std::cout << theArgVec[0] << ": values should be passed with key.\n";
5448       std::cout << "Type help for more information.\n";
5449       return 1;
5450     }
5451
5452     aMapOfKeysByValues(aParseKey)->Append (anArg);
5453   }
5454
5455   // ---------------------------------------------
5456   //  Change or print parameters, order plays role
5457   // ---------------------------------------------
5458
5459   // Check arguments for validity
5460   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfKeysByValues);
5461   for (; aMapIt.More(); aMapIt.Next())
5462   {
5463     const TCollection_AsciiString& aKey = aMapIt.Key();
5464     const Handle(TColStd_HSequenceOfAsciiString)& aValues = aMapIt.Value();
5465
5466     if (!(aKey.IsEqual ("SCALE")  && (aValues->Length() == 1 || aValues->IsEmpty()))
5467      && !(aKey.IsEqual ("SIZE")   && (aValues->Length() == 1 || aValues->IsEmpty()))
5468      && !(aKey.IsEqual ("EYE")    && (aValues->Length() == 3 || aValues->IsEmpty()))
5469      && !(aKey.IsEqual ("AT")     && (aValues->Length() == 3 || aValues->IsEmpty()))
5470      && !(aKey.IsEqual ("UP")     && (aValues->Length() == 3 || aValues->IsEmpty()))
5471      && !(aKey.IsEqual ("PROJ")   && (aValues->Length() == 3 || aValues->IsEmpty()))
5472      && !(aKey.IsEqual ("CENTER") &&  aValues->Length() == 2))
5473     {
5474       TCollection_AsciiString aLowerKey;
5475       aLowerKey  = "-";
5476       aLowerKey += aKey;
5477       aLowerKey.LowerCase();
5478       std::cout << theArgVec[0] << ": " << aLowerKey << " is unknown option, or number of arguments is invalid.\n";
5479       std::cout << "Type help for more information.\n";
5480       return 1;
5481     }
5482   }
5483
5484   Handle(TColStd_HSequenceOfAsciiString) aValues;
5485
5486   // Change view parameters in proper order
5487   if (aMapOfKeysByValues.Find ("SCALE", aValues))
5488   {
5489     if (aValues->IsEmpty())
5490     {
5491       theDi << "Scale: " << anAISView->Scale() << "\n";
5492     }
5493     else
5494     {
5495       anAISView->SetScale (aValues->Value(1).RealValue());
5496     }
5497   }
5498   if (aMapOfKeysByValues.Find ("SIZE", aValues))
5499   {
5500     if (aValues->IsEmpty())
5501     {
5502       Standard_Real aSizeX = 0.0;
5503       Standard_Real aSizeY = 0.0;
5504       anAISView->Size (aSizeX, aSizeY);
5505       theDi << "Size X: " << aSizeX << " Y: " << aSizeY << "\n";
5506     }
5507     else
5508     {
5509       anAISView->SetSize (aValues->Value(1).RealValue());
5510     }
5511   }
5512   if (aMapOfKeysByValues.Find ("EYE", aValues))
5513   {
5514     if (aValues->IsEmpty())
5515     {
5516       Standard_Real anEyeX = 0.0;
5517       Standard_Real anEyeY = 0.0;
5518       Standard_Real anEyeZ = 0.0;
5519       anAISView->Eye (anEyeX, anEyeY, anEyeZ);
5520       theDi << "Eye X: " << anEyeX << " Y: " << anEyeY << " Z: " << anEyeZ << "\n";
5521     }
5522     else
5523     {
5524       anAISView->SetEye (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
5525     }
5526   }
5527   if (aMapOfKeysByValues.Find ("AT", aValues))
5528   {
5529     if (aValues->IsEmpty())
5530     {
5531       Standard_Real anAtX = 0.0;
5532       Standard_Real anAtY = 0.0;
5533       Standard_Real anAtZ = 0.0;
5534       anAISView->At (anAtX, anAtY, anAtZ);
5535       theDi << "At X: " << anAtX << " Y: " << anAtY << " Z: " << anAtZ << "\n";
5536     }
5537     else
5538     {
5539       anAISView->SetAt (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
5540     }
5541   }
5542   if (aMapOfKeysByValues.Find ("PROJ", aValues))
5543   {
5544     if (aValues->IsEmpty())
5545     {
5546       Standard_Real aProjX = 0.0;
5547       Standard_Real aProjY = 0.0;
5548       Standard_Real aProjZ = 0.0;
5549       anAISView->Proj (aProjX, aProjY, aProjZ);
5550       theDi << "Proj X: " << aProjX << " Y: " << aProjY << " Z: " << aProjZ << "\n";
5551     }
5552     else
5553     {
5554       anAISView->SetProj (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
5555     }
5556   }
5557   if (aMapOfKeysByValues.Find ("UP", aValues))
5558   {
5559     if (aValues->IsEmpty())
5560     {
5561       Standard_Real anUpX = 0.0;
5562       Standard_Real anUpY = 0.0;
5563       Standard_Real anUpZ = 0.0;
5564       anAISView->Up (anUpX, anUpY, anUpZ);
5565       theDi << "Up X: " << anUpX << " Y: " << anUpY << " Z: " << anUpZ << "\n";
5566     }
5567     else
5568     {
5569       anAISView->SetUp (aValues->Value(1).RealValue(), aValues->Value(2).RealValue(), aValues->Value(3).RealValue());
5570     }
5571   }
5572   if (aMapOfKeysByValues.Find ("CENTER", aValues))
5573   {
5574     anAISView->SetCenter (aValues->Value(1).IntegerValue(), aValues->Value(2).IntegerValue());
5575   }
5576
5577   return 0;
5578 }
5579
5580 //=======================================================================
5581 //function : VChangeSelected
5582 //purpose  : Adds the shape to selection or remove one from it
5583 //=======================================================================
5584 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
5585                                 Standard_Integer argc,
5586                                 const char ** argv)
5587 {
5588   if(argc != 2)
5589   {
5590     di<<"Usage : " << argv[0] << " shape \n";
5591     return 1;
5592   }
5593   //get AIS_Shape:
5594   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5595   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
5596   TCollection_AsciiString aName(argv[1]);
5597   Handle(AIS_InteractiveObject) anAISObject;
5598
5599   if(!aMap.IsBound2(aName))
5600   {
5601     di<<"Use 'vdisplay' before";
5602     return 1;
5603   }
5604   else
5605   {
5606     anAISObject = Handle(AIS_InteractiveObject)::DownCast(aMap.Find2(aName));
5607     if(anAISObject.IsNull()){
5608       di<<"No interactive object \n";
5609       return 1;
5610     }
5611
5612     if(aContext->HasOpenedContext())
5613     {
5614       aContext->AddOrRemoveSelected(anAISObject);
5615     }
5616     else
5617     {
5618       aContext->AddOrRemoveCurrentObject(anAISObject);
5619     }
5620   }
5621   return 0;
5622 }
5623
5624 //=======================================================================
5625 //function : VZClipping
5626 //purpose  : Gets or sets ZClipping mode, width and depth
5627 //=======================================================================
5628 static Standard_Integer VZClipping (Draw_Interpretor& di,
5629                                 Standard_Integer argc,
5630                                 const char ** argv)
5631 {
5632   if(argc>4)
5633   {
5634     di << "Usage : " << argv[0] << " [mode] [depth  width]" << "\n"
5635       <<"mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
5636     return -1;
5637   }
5638   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5639   if(aContext.IsNull())
5640   {
5641     di << "use 'vinit' command before " << argv[0] << "\n";
5642     return 1;
5643   }
5644   Handle(V3d_View) aView = ViewerTest::CurrentView();
5645   V3d_TypeOfZclipping aZClippingMode = V3d_OFF;
5646   if(argc==1)
5647   {
5648     TCollection_AsciiString aZClippingModeString;
5649     Quantity_Length aDepth, aWidth;
5650     aZClippingMode = aView->ZClipping(aDepth, aWidth);
5651     switch (aZClippingMode)
5652     {
5653     case V3d_OFF:
5654       aZClippingModeString.Copy("OFF");
5655       break;
5656     case V3d_BACK:
5657       aZClippingModeString.Copy("BACK");
5658       break;
5659     case V3d_FRONT:
5660       aZClippingModeString.Copy("FRONT");
5661       break;
5662     case V3d_SLICE:
5663       aZClippingModeString.Copy("SLICE");
5664       break;
5665     default:
5666       aZClippingModeString.Copy(TCollection_AsciiString(aZClippingMode));
5667       break;
5668     }
5669     di << "ZClippingMode = " << aZClippingModeString.ToCString() << "\n"
5670       << "ZClipping depth = " << aDepth << "\n"
5671       << "ZClipping width = " << aWidth << "\n";
5672   }
5673   else
5674   {
5675     if(argc !=3)
5676     {
5677       Standard_Integer aStatus = 0;
5678       if ( strcmp (argv [1], "OFF") == 0 ) {
5679         aStatus = 1;
5680         aZClippingMode = V3d_OFF;
5681       }
5682       if ( strcmp (argv [1], "BACK") == 0 ) {
5683         aStatus = 1;
5684         aZClippingMode = V3d_BACK;
5685       }
5686       if ( strcmp (argv [1], "FRONT") == 0 ) {
5687         aStatus = 1;
5688         aZClippingMode = V3d_FRONT;
5689       }
5690       if ( strcmp (argv [1], "SLICE") == 0 ) {
5691         aStatus = 1;
5692         aZClippingMode = V3d_SLICE;
5693       }
5694       if (aStatus != 1)
5695       {
5696         di << "Bad mode; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
5697           << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
5698         return 1;
5699       }
5700       aView->SetZClippingType(aZClippingMode);
5701     }
5702     if(argc >2)
5703     {
5704       Quantity_Length aDepth = 0., aWidth = 1.;
5705       if(argc == 3)
5706       {
5707         aDepth = Draw::Atof (argv[1]);
5708         aWidth = Draw::Atof (argv[2]);
5709       }
5710       else if(argc == 4)
5711       {
5712         aDepth = Draw::Atof (argv[2]);
5713         aWidth = Draw::Atof (argv[3]);
5714       }
5715
5716       if(aDepth<0. || aDepth>1.)
5717       {
5718         di << "Bad depth; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
5719         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
5720         return 1;
5721       }
5722       if(aWidth<0. || aWidth>1.)
5723       {
5724         di << "Bad width; Usage : " << argv[0] << " [mode] [depth width]" << "\n"
5725         << "mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]" << "\n";
5726         return 1;
5727       }
5728
5729       aView->SetZClippingDepth(aDepth);
5730       aView->SetZClippingWidth(aWidth);
5731     }
5732     aView->Redraw();
5733   }
5734   return 0;
5735 }
5736
5737 //=======================================================================
5738 //function : VNbSelected
5739 //purpose  : Returns number of selected objects
5740 //=======================================================================
5741 static Standard_Integer VNbSelected (Draw_Interpretor& di,
5742                                 Standard_Integer argc,
5743                                 const char ** argv)
5744 {
5745   if(argc != 1)
5746   {
5747     di << "Usage : " << argv[0] << "\n";
5748     return 1;
5749   }
5750   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5751   if(aContext.IsNull())
5752   {
5753     di << "use 'vinit' command before " << argv[0] << "\n";
5754     return 1;
5755   }
5756   di << aContext->NbSelected() << "\n";
5757   return 0;
5758 }
5759
5760 //=======================================================================
5761 //function : VAntialiasing
5762 //purpose  : Switches altialiasing on or off
5763 //=======================================================================
5764 static Standard_Integer VAntialiasing (Draw_Interpretor& di,
5765                                 Standard_Integer argc,
5766                                 const char ** argv)
5767 {
5768   if(argc > 2)
5769   {
5770     di << "Usage : " << argv[0] << " [1|0]" << "\n";
5771     return 1;
5772   }
5773
5774   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5775   if(aContext.IsNull())
5776   {
5777     di << "use 'vinit' command before " << argv[0] << "\n";
5778     return 1;
5779   }
5780
5781   Handle(V3d_View) aView = ViewerTest::CurrentView();
5782
5783   if((argc == 2) && (atof(argv[1]) == 0))
5784     aView->SetAntialiasingOff();
5785   else
5786     aView->SetAntialiasingOn();
5787   aView->Update();
5788   return 0;
5789 }
5790
5791 //=======================================================================
5792 //function : VPurgeDisplay
5793 //purpose  : Switches altialiasing on or off
5794 //=======================================================================
5795 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
5796                                 Standard_Integer argc,
5797                                 const char ** argv)
5798 {
5799   if (argc > 1)
5800   {
5801     di << "Usage : " << argv[0] << "\n";
5802     return 1;
5803   }
5804   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5805   if (aContext.IsNull())
5806   {
5807     di << "use 'vinit' command before " << argv[0] << "\n";
5808     return 1;
5809   }
5810   aContext->CloseAllContexts(Standard_False);
5811   di << aContext->PurgeDisplay() << "\n";
5812   return 0;
5813 }
5814
5815 //=======================================================================
5816 //function : VSetViewSize
5817 //purpose  :
5818 //=======================================================================
5819 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
5820                                 Standard_Integer argc,
5821                                 const char ** argv)
5822 {
5823   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5824   if(aContext.IsNull())
5825   {
5826     di << "use 'vinit' command before " << argv[0] << "\n";
5827     return 1;
5828   }
5829   if(argc != 2)
5830   {
5831     di<<"Usage : " << argv[0] << " Size\n";
5832     return 1;
5833   }
5834   Standard_Real aSize = Draw::Atof (argv[1]);
5835   if (aSize <= 0.)
5836   {
5837     di<<"Bad Size value  : " << aSize << "\n";
5838     return 1;
5839   }
5840
5841   Handle(V3d_View) aView = ViewerTest::CurrentView();
5842   aView->SetSize(aSize);
5843   return 0;
5844 }
5845
5846 //=======================================================================
5847 //function : VMoveView
5848 //purpose  :
5849 //=======================================================================
5850 static Standard_Integer VMoveView (Draw_Interpretor& di,
5851                                 Standard_Integer argc,
5852                                 const char ** argv)
5853 {
5854   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5855   if(aContext.IsNull())
5856   {
5857     di << "use 'vinit' command before " << argv[0] << "\n";
5858     return 1;
5859   }
5860   if(argc < 4 || argc > 5)
5861   {
5862     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
5863     return 1;
5864   }
5865   Standard_Real Dx = Draw::Atof (argv[1]);
5866   Standard_Real Dy = Draw::Atof (argv[2]);
5867   Standard_Real Dz = Draw::Atof (argv[3]);
5868   Standard_Boolean aStart = Standard_True;
5869   if (argc == 5)
5870   {
5871       aStart = (Draw::Atoi (argv[4]) > 0);
5872   }
5873
5874   Handle(V3d_View) aView = ViewerTest::CurrentView();
5875   aView->Move(Dx,Dy,Dz,aStart);
5876   return 0;
5877 }
5878
5879 //=======================================================================
5880 //function : VTranslateView
5881 //purpose  :
5882 //=======================================================================
5883 static Standard_Integer VTranslateView (Draw_Interpretor& di,
5884                                 Standard_Integer argc,
5885                                 const char ** argv)
5886 {
5887   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5888   if(aContext.IsNull())
5889   {
5890     di << "use 'vinit' command before " << argv[0] << "\n";
5891     return 1;
5892   }
5893   if(argc < 4 || argc > 5)
5894   {
5895     di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
5896     return 1;
5897   }
5898   Standard_Real Dx = Draw::Atof (argv[1]);
5899   Standard_Real Dy = Draw::Atof (argv[2]);
5900   Standard_Real Dz = Draw::Atof (argv[3]);
5901   Standard_Boolean aStart = Standard_True;
5902   if (argc == 5)
5903   {
5904       aStart = (Draw::Atoi (argv[4]) > 0);
5905   }
5906
5907   Handle(V3d_View) aView = ViewerTest::CurrentView();
5908   aView->Translate(Dx,Dy,Dz,aStart);
5909   return 0;
5910 }
5911
5912 //=======================================================================
5913 //function : VTurnView
5914 //purpose  :
5915 //=======================================================================
5916 static Standard_Integer VTurnView (Draw_Interpretor& di,
5917                                 Standard_Integer argc,
5918                                 const char ** argv)
5919 {
5920   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5921   if(aContext.IsNull()) {
5922     di << "use 'vinit' command before " << argv[0] << "\n";
5923     return 1;
5924   }
5925   if(argc < 4 || argc > 5){
5926     di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
5927     return 1;
5928   }
5929   Standard_Real Ax = Draw::Atof (argv[1]);
5930   Standard_Real Ay = Draw::Atof (argv[2]);
5931   Standard_Real Az = Draw::Atof (argv[3]);
5932   Standard_Boolean aStart = Standard_True;
5933   if (argc == 5)
5934   {
5935       aStart = (Draw::Atoi (argv[4]) > 0);
5936   }
5937
5938   Handle(V3d_View) aView = ViewerTest::CurrentView();
5939   aView->Turn(Ax,Ay,Az,aStart);
5940   return 0;
5941 }
5942
5943 //==============================================================================
5944 //function : VTextureEnv
5945 //purpose  : ENables or disables environment mapping
5946 //==============================================================================
5947 class OCC_TextureEnv : public Graphic3d_TextureEnv
5948 {
5949 public:
5950   OCC_TextureEnv(const Standard_CString FileName);
5951   OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
5952   void SetTextureParameters(const Standard_Boolean theRepeatFlag,
5953                             const Standard_Boolean theModulateFlag,
5954                             const Graphic3d_TypeOfTextureFilter theFilter,
5955                             const Standard_ShortReal theXScale,
5956                             const Standard_ShortReal theYScale,
5957                             const Standard_ShortReal theXShift,
5958                             const Standard_ShortReal theYShift,
5959                             const Standard_ShortReal theAngle);
5960   DEFINE_STANDARD_RTTI(OCC_TextureEnv);
5961 };
5962 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
5963 IMPLEMENT_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv);
5964 IMPLEMENT_STANDARD_RTTIEXT(OCC_TextureEnv, Graphic3d_TextureEnv);
5965
5966 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
5967   : Graphic3d_TextureEnv(theFileName)
5968 {
5969 }
5970
5971 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
5972   : Graphic3d_TextureEnv(theTexId)
5973 {
5974 }
5975
5976 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
5977                                           const Standard_Boolean theModulateFlag,
5978                                           const Graphic3d_TypeOfTextureFilter theFilter,
5979                                           const Standard_ShortReal theXScale,
5980                                           const Standard_ShortReal theYScale,
5981                                           const Standard_ShortReal theXShift,
5982                                           const Standard_ShortReal theYShift,
5983                                           const Standard_ShortReal theAngle)
5984 {
5985   myParams->SetRepeat     (theRepeatFlag);
5986   myParams->SetModulate   (theModulateFlag);
5987   myParams->SetFilter     (theFilter);
5988   myParams->SetScale      (Graphic3d_Vec2(theXScale, theYScale));
5989   myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
5990   myParams->SetRotation   (theAngle);
5991 }
5992
5993 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
5994 {
5995   // get the active view
5996   Handle(V3d_View) aView = ViewerTest::CurrentView();
5997   if (aView.IsNull())
5998   {
5999     std::cerr << "No active view. Please call vinit.\n";
6000     return 1;
6001   }
6002
6003   // Checking the input arguments
6004   Standard_Boolean anEnableFlag = Standard_False;
6005   Standard_Boolean isOk         = theArgNb >= 2;
6006   if (isOk)
6007   {
6008     TCollection_AsciiString anEnableOpt(theArgVec[1]);
6009     anEnableFlag = anEnableOpt.IsEqual("on");
6010     isOk         = anEnableFlag || anEnableOpt.IsEqual("off");
6011   }
6012   if (anEnableFlag)
6013   {
6014     isOk = (theArgNb == 3 || theArgNb == 11);
6015     if (isOk)
6016     {
6017       TCollection_AsciiString aTextureOpt(theArgVec[2]);
6018       isOk = (!aTextureOpt.IsIntegerValue() ||
6019              (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
6020
6021       if (isOk && theArgNb == 11)
6022       {
6023         TCollection_AsciiString aRepeatOpt  (theArgVec[3]),
6024                                 aModulateOpt(theArgVec[4]),
6025                                 aFilterOpt  (theArgVec[5]),
6026                                 aSScaleOpt  (theArgVec[6]),
6027                                 aTScaleOpt  (theArgVec[7]),
6028                                 aSTransOpt  (theArgVec[8]),
6029                                 aTTransOpt  (theArgVec[9]),
6030                                 anAngleOpt  (theArgVec[10]);
6031         isOk = ((aRepeatOpt.  IsEqual("repeat")   || aRepeatOpt.  IsEqual("clamp")) &&
6032                 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
6033                 (aFilterOpt.  IsEqual("nearest")  || aFilterOpt.  IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
6034                 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
6035                 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
6036                 anAngleOpt.IsRealValue());
6037       }
6038     }
6039   }
6040
6041   if (!isOk)
6042   {
6043     std::cerr << "Usage :" << std::endl;
6044     std::cerr << theArgVec[0] << " off" << std::endl;
6045     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;
6046     return 1;
6047   }
6048
6049   if (anEnableFlag)
6050   {
6051     TCollection_AsciiString aTextureOpt(theArgVec[2]);
6052     Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
6053                                      new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
6054                                      new OCC_TextureEnv(theArgVec[2]);
6055
6056     if (theArgNb == 11)
6057     {
6058       TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
6059       aTexEnv->SetTextureParameters(
6060         aRepeatOpt.  IsEqual("repeat"),
6061         aModulateOpt.IsEqual("modulate"),
6062         aFilterOpt.  IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
6063                                           aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
6064                                                                            Graphic3d_TOTF_TRILINEAR,
6065         (Standard_ShortReal)Draw::Atof(theArgVec[6]),
6066         (Standard_ShortReal)Draw::Atof(theArgVec[7]),
6067         (Standard_ShortReal)Draw::Atof(theArgVec[8]),
6068         (Standard_ShortReal)Draw::Atof(theArgVec[9]),
6069         (Standard_ShortReal)Draw::Atof(theArgVec[10])
6070         );
6071     }
6072     aView->SetTextureEnv(aTexEnv);
6073     aView->SetSurfaceDetail(V3d_TEX_ENVIRONMENT);
6074   }
6075   else // Disabling environment mapping
6076   {
6077     aView->SetSurfaceDetail(V3d_TEX_NONE);
6078     Handle(Graphic3d_TextureEnv) aTexture;
6079     aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
6080   }
6081
6082   aView->Redraw();
6083   return 0;
6084 }
6085
6086 //===============================================================================================
6087 //function : VClipPlane
6088 //purpose  :
6089 //===============================================================================================
6090 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6091 {
6092   // use short-cut for created clip planes map of created (or "registered by name") clip planes
6093   typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
6094   static MapOfPlanes aRegPlanes;
6095
6096   if (theArgsNb < 2)
6097   {
6098     theDi << theArgVec[0] << ": command argument is required. Type help for more information.\n";
6099     return 1;
6100   }
6101
6102   TCollection_AsciiString aCommand (theArgVec[1]);
6103
6104   // print maximum number of planes for current viewer
6105   if (aCommand == "maxplanes")
6106   {
6107     if (theArgsNb < 3)
6108     {
6109       theDi << theArgVec[0] << ": view name is required. Type help for more information.\n";
6110       return 1;
6111     }
6112
6113     TCollection_AsciiString aViewName (theArgVec[2]);
6114
6115     if (!ViewerTest_myViews.IsBound1 (aViewName))
6116     {
6117       theDi << theArgVec[0] << ": view is not found.\n";
6118       return 1;
6119     }
6120
6121     const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
6122
6123     theDi << theArgVec[0] << ": "
6124                           << aView->Viewer()->Driver()->InquirePlaneLimit()
6125                           << " plane slots provided by driver."
6126                           << " Note that 2 more planes might be used (reserved for z-clipping).\n";
6127
6128     return 0;
6129   }
6130
6131   // create / delete plane instance
6132   if (aCommand == "create" || aCommand == "delete" || aCommand == "clone")
6133   {
6134     if (theArgsNb < 3)
6135     {
6136       theDi << theArgVec[0] << ": plane name is required. Type help for more information.\n";
6137       return 1;
6138     }
6139
6140     Standard_Boolean toCreate = (aCommand == "create");
6141     Standard_Boolean toClone  = (aCommand == "clone");
6142     TCollection_AsciiString aPlane (theArgVec[2]);
6143
6144     if (toCreate)
6145     {
6146       if (aRegPlanes.IsBound (aPlane))
6147       {
6148         theDi << theArgVec[0] << ": plane name is in use.\n";
6149         return 1;
6150       }
6151
6152       aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
6153     }
6154     else if (toClone) // toClone
6155     {
6156       if (!aRegPlanes.IsBound (aPlane))
6157       {
6158         theDi << theArgVec[0] << ": no such plane.\n";
6159         return 1;
6160       }
6161
6162       if (theArgsNb < 4)
6163       {
6164         theDi << theArgVec[0] << ": enter name for new plane. Type help for more information.\n";
6165         return 1;
6166       }
6167
6168       TCollection_AsciiString aClone (theArgVec[3]);
6169       if (aRegPlanes.IsBound (aClone))
6170       {
6171         theDi << theArgVec[0] << ": plane name is in use.\n";
6172         return 1;
6173       }
6174
6175       const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6176
6177       aRegPlanes.Bind (aClone, aClipPlane->Clone());
6178     }
6179     else// toDelete
6180     {
6181       if (!aRegPlanes.IsBound (aPlane))
6182       {
6183         theDi << theArgVec[0] << ": no such plane.\n";
6184         return 1;
6185       }
6186
6187       Handle(Graphic3d_ClipPlane) aClipPlane = aRegPlanes.Find (aPlane);
6188       aRegPlanes.UnBind (aPlane);
6189
6190       ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
6191       for (; anIObjIt.More(); anIObjIt.Next())
6192       {
6193         Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1());
6194         aPrs->RemoveClipPlane(aClipPlane);
6195       }
6196
6197       NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
6198       for (; aViewIt.More(); aViewIt.Next())
6199       {
6200         const Handle(V3d_View)& aView = aViewIt.Key2();
6201         aView->RemoveClipPlane(aClipPlane);
6202       }
6203
6204       ViewerTest::RedrawAllViews();
6205     }
6206
6207     return 0;
6208   }
6209
6210   // set / unset plane command
6211   if (aCommand == "set" || aCommand == "unset")
6212   {
6213     if (theArgsNb < 4)
6214     {
6215       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6216       return 1;
6217     }
6218
6219     Standard_Boolean toSet = (aCommand == "set");
6220     TCollection_AsciiString aPlane (theArgVec [2]);
6221     if (!aRegPlanes.IsBound (aPlane))
6222     {
6223       theDi << theArgVec[0] << ": no such plane.\n";
6224       return 1;
6225     }
6226
6227     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6228
6229     TCollection_AsciiString aTarget (theArgVec [3]);
6230     if (aTarget != "object" && aTarget != "view")
6231     {
6232       theDi << theArgVec[0] << ": invalid target.\n";
6233       return 1;
6234     }
6235
6236     if (aTarget == "object" || aTarget == "view")
6237     {
6238       if (theArgsNb < 5)
6239       {
6240         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6241         return 1;
6242       }
6243
6244       Standard_Boolean isObject = (aTarget == "object");
6245
6246       for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
6247       {
6248         TCollection_AsciiString anEntityName (theArgVec[anIt]);
6249         if (isObject) // to object
6250         {
6251           if (!GetMapOfAIS().IsBound2 (anEntityName))
6252           {
6253             theDi << theArgVec[0] << ": can not find IO with name " << anEntityName << ".\n";
6254             continue;
6255           }
6256
6257           Handle(AIS_InteractiveObject) aIObj =
6258             Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName));
6259
6260           if (toSet)
6261             aIObj->AddClipPlane (aClipPlane);
6262           else
6263             aIObj->RemoveClipPlane (aClipPlane);
6264         }
6265         else // to view
6266         {
6267           if (!ViewerTest_myViews.IsBound1 (anEntityName))
6268           {
6269             theDi << theArgVec[0] << ": can not find View with name " << anEntityName << ".\n";
6270             continue;
6271           }
6272
6273           Handle(V3d_View) aView = ViewerTest_myViews.Find1(anEntityName);
6274           if (toSet)
6275             aView->AddClipPlane (aClipPlane);
6276           else
6277             aView->RemoveClipPlane (aClipPlane);
6278         }
6279       }
6280
6281       ViewerTest::RedrawAllViews();
6282     }
6283
6284     return 0;
6285   }
6286
6287   // change plane command
6288   if (aCommand == "change")
6289   {
6290     if (theArgsNb < 4)
6291     {
6292       theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6293       return 1;
6294     }
6295
6296     TCollection_AsciiString aPlane (theArgVec [2]);
6297     if (!aRegPlanes.IsBound (aPlane))
6298     {
6299       theDi << theArgVec[0] << ": no such plane.\n";
6300       return 1;
6301     }
6302
6303     const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
6304
6305     TCollection_AsciiString aChangeArg (theArgVec [3]);
6306     if (aChangeArg != "on" && aChangeArg != "off" && aChangeArg != "capping" && aChangeArg != "equation")
6307     {
6308       theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
6309       return 1;
6310     }
6311
6312     if (aChangeArg == "on" || aChangeArg == "off") // on / off
6313     {
6314       aClipPlane->SetOn (aChangeArg == "on");
6315     }
6316     else if (aChangeArg == "equation") // change equation
6317     {
6318       if (theArgsNb < 8)
6319       {
6320         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6321         return 1;
6322       }
6323
6324       Standard_Real aCoeffA = Draw::Atof (theArgVec [4]);
6325       Standard_Real aCoeffB = Draw::Atof (theArgVec [5]);
6326       Standard_Real aCoeffC = Draw::Atof (theArgVec [6]);
6327       Standard_Real aCoeffD = Draw::Atof (theArgVec [7]);
6328       aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
6329     }
6330     else if (aChangeArg == "capping") // change capping aspects
6331     {
6332       if (theArgsNb < 5)
6333       {
6334         theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6335         return 1;
6336       }
6337
6338       TCollection_AsciiString aCappingArg (theArgVec [4]);
6339       if (aCappingArg != "on" && aCappingArg != "off" &&
6340           aCappingArg != "color" && aCappingArg != "texname" &&
6341           aCappingArg != "texscale" && aCappingArg != "texorigin" &&
6342           aCappingArg != "texrotate" && aCappingArg != "hatch")
6343       {
6344         theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n";
6345         return 1;
6346       }
6347
6348       if (aCappingArg == "on" || aCappingArg == "off") // on / off capping
6349       {
6350         aClipPlane->SetCapping (aCappingArg == "on");
6351       }
6352       else if (aCappingArg == "color") // color aspect for capping
6353       {
6354         if (theArgsNb < 8)
6355         {
6356           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6357           return 1;
6358         }
6359
6360         Standard_Real aRed = Draw::Atof (theArgVec [5]);
6361         Standard_Real aGrn = Draw::Atof (theArgVec [6]);
6362         Standard_Real aBlu = Draw::Atof (theArgVec [7]);
6363
6364         Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
6365         Quantity_Color aColor (aRed, aGrn, aBlu, Quantity_TOC_RGB);
6366         aMat.SetAmbientColor (aColor);
6367         aMat.SetDiffuseColor (aColor);
6368         aClipPlane->SetCappingMaterial (aMat);
6369       }
6370       else if (aCappingArg == "texname") // texture name
6371       {
6372         if (theArgsNb < 6)
6373         {
6374           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6375           return 1;
6376         }
6377
6378         TCollection_AsciiString aTextureName (theArgVec [5]);
6379
6380         Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
6381         if (!aTexture->IsDone ())
6382         {
6383           aClipPlane->SetCappingTexture (NULL);
6384         }
6385         else
6386         {
6387           aTexture->EnableModulate();
6388           aTexture->EnableRepeat();
6389           aClipPlane->SetCappingTexture (aTexture);
6390         }
6391       }
6392       else if (aCappingArg == "texscale") // texture scale
6393       {
6394         if (aClipPlane->CappingTexture().IsNull())
6395         {
6396           theDi << theArgVec[0] << ": no texture is set.\n";
6397           return 1;
6398         }
6399
6400         if (theArgsNb < 7)
6401         {
6402           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6403           return 1;
6404         }
6405
6406         Standard_ShortReal aSx = (Standard_ShortReal)atof (theArgVec [5]);
6407         Standard_ShortReal aSy = (Standard_ShortReal)atof (theArgVec [6]);
6408
6409         aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
6410       }
6411       else if (aCappingArg == "texorigin") // texture origin
6412       {
6413         if (aClipPlane->CappingTexture().IsNull())
6414         {
6415           theDi << theArgVec[0] << ": no texture is set.\n";
6416           return 1;
6417         }
6418
6419         if (theArgsNb < 7)
6420         {
6421           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6422           return 1;
6423         }
6424
6425         Standard_ShortReal aTx = (Standard_ShortReal)atof (theArgVec [5]);
6426         Standard_ShortReal aTy = (Standard_ShortReal)atof (theArgVec [6]);
6427
6428         aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
6429       }
6430       else if (aCappingArg == "texrotate") // texture rotation
6431       {
6432         if (aClipPlane->CappingTexture().IsNull())
6433         {
6434           theDi << theArgVec[0] << ": no texture is set.\n";
6435           return 1;
6436         }
6437
6438         if (theArgsNb < 6)
6439         {
6440           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6441           return 1;
6442         }
6443
6444         Standard_ShortReal aRot = (Standard_ShortReal)atof (theArgVec[5]);
6445
6446         aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
6447       }
6448       else if (aCappingArg == "hatch") // hatch style
6449       {
6450         if (theArgsNb < 6)
6451         {
6452           theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n";
6453           return 1;
6454         }
6455
6456         TCollection_AsciiString aHatchStr (theArgVec [5]);
6457         if (aHatchStr == "on")
6458         {
6459           aClipPlane->SetCappingHatchOn();
6460         }
6461         else if (aHatchStr == "off")
6462         {
6463           aClipPlane->SetCappingHatchOff();
6464         }
6465         else
6466         {
6467           aClipPlane->SetCappingHatch ((Aspect_HatchStyle)atoi (theArgVec[5]));
6468         }
6469       }
6470     }
6471
6472     ViewerTest::RedrawAllViews();
6473
6474     return 0;
6475   }
6476
6477   theDi << theArgVec[0] << ": invalid command. Type help for more information.\n";
6478   return 1;
6479 }
6480
6481 //===============================================================================================
6482 //function : VSetTextureMode
6483 //purpose  :
6484 //===============================================================================================
6485 static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6486 {
6487   if (theArgsNb < 3)
6488   {
6489     theDi << theArgVec[0] << ": insufficient command arguments. Type help for more information.\n";
6490     return 1;
6491   }
6492
6493   TCollection_AsciiString aViewName (theArgVec[1]);
6494   if (!ViewerTest_myViews.IsBound1 (aViewName))
6495   {
6496     theDi << theArgVec[0] << ": view is not found.\n";
6497     return 1;
6498   }
6499
6500   const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName);
6501   switch (atoi (theArgVec[2]))
6502   {
6503     case 0: aView->SetSurfaceDetail (V3d_TEX_NONE); break;
6504     case 1: aView->SetSurfaceDetail (V3d_TEX_ENVIRONMENT); break;
6505     case 2: aView->SetSurfaceDetail (V3d_TEX_ALL); break;
6506     default:
6507       theDi << theArgVec[0] << ": invalid mode.\n";
6508       return 1;
6509   }
6510
6511   aView->Redraw();
6512   return 0;
6513 }
6514
6515 //===============================================================================================
6516 //function : VZRange
6517 //purpose  :
6518 //===============================================================================================
6519 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6520 {
6521   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
6522
6523   if (aCurrentView.IsNull())
6524   {
6525     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
6526     return 1;
6527   }
6528
6529   Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
6530
6531   if (theArgsNb < 2)
6532   {
6533     theDi << "ZNear: " << aCamera->ZNear() << "\n";
6534     theDi << "ZFar: " << aCamera->ZFar() << "\n";
6535     return 0;
6536   }
6537
6538   if (theArgsNb == 3)
6539   {
6540     Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
6541     Standard_Real aNewZFar  = Draw::Atof (theArgVec[2]);
6542
6543     if (aNewZNear >= aNewZFar)
6544     {
6545       std::cout << theArgVec[0] << ": invalid arguments: znear should be less than zfar.\n";
6546       return 1;
6547     }
6548
6549     if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
6550     {
6551       std::cout << theArgVec[0] << ": invalid arguments: ";
6552       std::cout << "znear, zfar should be positive for perspective camera.\n";
6553       return 1;
6554     }
6555
6556     aCamera->SetZRange (aNewZNear, aNewZFar);
6557   }
6558   else
6559   {
6560     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
6561     return 1;
6562   }
6563
6564   aCurrentView->Redraw();
6565
6566   return 0;
6567 }
6568
6569 //===============================================================================================
6570 //function : VAutoZFit
6571 //purpose  :
6572 //===============================================================================================
6573 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6574 {
6575   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
6576
6577   if (aCurrentView.IsNull())
6578   {
6579     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
6580     return 1;
6581   }
6582
6583   Standard_Real aScale = aCurrentView->View()->AutoZFitScaleFactor();
6584
6585   if (theArgsNb > 3)
6586   {
6587     std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
6588     return 1;
6589   }
6590
6591   if (theArgsNb < 2)
6592   {
6593     theDi << "Auto z-fit mode: " << "\n"
6594           << "On: " << (aCurrentView->View()->AutoZFitMode() ? "enabled" : "disabled") << "\n"
6595           << "Scale: " << aScale << "\n";
6596     return 0;
6597   }
6598
6599   Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
6600
6601   if (theArgsNb >= 3)
6602   {
6603     aScale = Draw::Atoi (theArgVec[2]);
6604   }
6605
6606   aCurrentView->View()->SetAutoZFitMode (isOn, aScale);
6607   aCurrentView->View()->AutoZFit();
6608   aCurrentView->Redraw();
6609
6610   return 0;
6611 }
6612
6613 //! Auxiliary function to print projection type
6614 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
6615 {
6616   switch (theProjType)
6617   {
6618     case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
6619     case Graphic3d_Camera::Projection_Perspective:  return "perspective";
6620     case Graphic3d_Camera::Projection_Stereo:       return "stereoscopic";
6621     case Graphic3d_Camera::Projection_MonoLeftEye:  return "monoLeftEye";
6622     case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
6623   }
6624   return "UNKNOWN";
6625 }
6626
6627 //===============================================================================================
6628 //function : VCamera
6629 //purpose  :
6630 //===============================================================================================
6631 static int VCamera (Draw_Interpretor& theDI,
6632                     Standard_Integer  theArgsNb,
6633                     const char**      theArgVec)
6634 {
6635   Handle(V3d_View) aView = ViewerTest::CurrentView();
6636   if (aView.IsNull())
6637   {
6638     std::cout << "Error: no active view.\n";
6639     return 1;
6640   }
6641
6642   Handle(Graphic3d_Camera) aCamera = aView->Camera();
6643   if (theArgsNb < 2)
6644   {
6645     theDI << "ProjType:   " << projTypeName (aCamera->ProjectionType()) << "\n";
6646     theDI << "FOVy:       " << aCamera->FOVy() << "\n";
6647     theDI << "Distance:   " << aCamera->Distance() << "\n";
6648     theDI << "IOD:        " << aCamera->IOD() << "\n";
6649     theDI << "IODType:    " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute   ? "absolute" : "relative") << "\n";
6650     theDI << "ZFocus:     " << aCamera->ZFocus() << "\n";
6651     theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
6652     return 0;
6653   }
6654
6655   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6656   {
6657     Standard_CString        anArg = theArgVec[anArgIter];
6658     TCollection_AsciiString anArgCase (anArg);
6659     anArgCase.LowerCase();
6660     if (anArgCase == "-proj"
6661      || anArgCase == "-projection"
6662      || anArgCase == "-projtype"
6663      || anArgCase == "-projectiontype")
6664     {
6665       theDI << projTypeName (aCamera->ProjectionType()) << " ";
6666     }
6667     else if (anArgCase == "-ortho"
6668           || anArgCase == "-orthographic")
6669     {
6670       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6671     }
6672     else if (anArgCase == "-persp"
6673           || anArgCase == "-perspective"
6674           || anArgCase == "-perspmono"
6675           || anArgCase == "-perspectivemono"
6676           || anArgCase == "-mono")
6677     {
6678       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
6679     }
6680     else if (anArgCase == "-stereo"
6681           || anArgCase == "-stereoscopic"
6682           || anArgCase == "-perspstereo"
6683           || anArgCase == "-perspectivestereo")
6684     {
6685       aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
6686     }
6687     else if (anArgCase == "-left"
6688           || anArgCase == "-lefteye"
6689           || anArgCase == "-monoleft"
6690           || anArgCase == "-monolefteye"
6691           || anArgCase == "-perpsleft"
6692           || anArgCase == "-perpslefteye")
6693     {
6694       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
6695     }
6696     else if (anArgCase == "-right"
6697           || anArgCase == "-righteye"
6698           || anArgCase == "-monoright"
6699           || anArgCase == "-monorighteye"
6700           || anArgCase == "-perpsright")
6701     {
6702       aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
6703     }
6704     else if (anArgCase == "-dist"
6705           || anArgCase == "-distance")
6706     {
6707       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
6708       if (anArgValue != NULL
6709       && *anArgValue != '-')
6710       {
6711         ++anArgIter;
6712         aCamera->SetDistance (Draw::Atof (anArgValue));
6713         continue;
6714       }
6715       theDI << aCamera->Distance() << " ";
6716     }
6717     else if (anArgCase == "-iod")
6718     {
6719       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
6720       if (anArgValue != NULL
6721       && *anArgValue != '-')
6722       {
6723         ++anArgIter;
6724         aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
6725         continue;
6726       }
6727       theDI << aCamera->IOD() << " ";
6728     }
6729     else if (anArgCase == "-iodtype")
6730     {
6731       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
6732       TCollection_AsciiString anValueCase (anArgValue);
6733       anValueCase.LowerCase();
6734       if (anValueCase == "abs"
6735        || anValueCase == "absolute")
6736       {
6737         ++anArgIter;
6738         aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
6739         continue;
6740       }
6741       else if (anValueCase == "rel"
6742             || anValueCase == "relative")
6743       {
6744         ++anArgIter;
6745         aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
6746         continue;
6747       }
6748       else if (*anArgValue != '-')
6749       {
6750         std::cout << "Error: unknown IOD type '" << anArgValue << "'\n";
6751         return 1;
6752       }
6753       switch (aCamera->GetIODType())
6754       {
6755         case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
6756         case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
6757       }
6758     }
6759     else if (anArgCase == "-zfocus")
6760     {
6761       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
6762       if (anArgValue != NULL
6763       && *anArgValue != '-')
6764       {
6765         ++anArgIter;
6766         aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
6767         continue;
6768       }
6769       theDI << aCamera->ZFocus() << " ";
6770     }
6771     else if (anArgCase == "-zfocustype")
6772     {
6773       Standard_CString        anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
6774       TCollection_AsciiString anValueCase (anArgValue);
6775       anValueCase.LowerCase();
6776       if (anValueCase == "abs"
6777        || anValueCase == "absolute")
6778       {
6779         ++anArgIter;
6780         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
6781         continue;
6782       }
6783       else if (anValueCase == "rel"
6784             || anValueCase == "relative")
6785       {
6786         ++anArgIter;
6787         aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
6788         continue;
6789       }
6790       else if (*anArgValue != '-')
6791       {
6792         std::cout << "Error: unknown ZFocus type '" << anArgValue << "'\n";
6793         return 1;
6794       }
6795       switch (aCamera->ZFocusType())
6796       {
6797         case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
6798         case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
6799       }
6800     }
6801     else if (anArgCase == "-fov"
6802           || anArgCase == "-fovy")
6803     {
6804       Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
6805       if (anArgValue != NULL
6806       && *anArgValue != '-')
6807       {
6808         ++anArgIter;
6809         aCamera->SetFOVy (Draw::Atof (anArgValue));
6810         continue;
6811       }
6812       theDI << aCamera->FOVy() << " ";
6813     }
6814     else
6815     {
6816       std::cout << "Error: unknown argument '" << anArg << "'\n";
6817       return 1;
6818     }
6819   }
6820
6821   aView->View()->AutoZFit();
6822   aView->Redraw();
6823
6824   return 0;
6825 }
6826
6827 //==============================================================================
6828 //function : VStereo
6829 //purpose  :
6830 //==============================================================================
6831
6832 static int VStereo (Draw_Interpretor& theDI,
6833                     Standard_Integer  theArgNb,
6834                     const char**      theArgVec)
6835 {
6836   if (theArgNb < 2)
6837   {
6838     Handle(V3d_View) aView = ViewerTest::CurrentView();
6839     if (aView.IsNull())
6840     {
6841       std::cerr << "No active view. Please call vinit.\n";
6842       return 0;
6843     }
6844
6845     Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
6846     theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
6847     return 0;
6848   }
6849
6850   ViewerTest_myDefaultCaps.contextStereo = Draw::Atoi (theArgVec[1]) != 0;
6851   return 0;
6852 }
6853
6854 //===============================================================================================
6855 //function : VDefaults
6856 //purpose  :
6857 //===============================================================================================
6858 static int VDefaults (Draw_Interpretor& theDi,
6859                       Standard_Integer  theArgsNb,
6860                       const char**      theArgVec)
6861 {
6862   const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6863   if (aCtx.IsNull())
6864   {
6865     std::cerr << "No active viewer!\n";
6866     return 1;
6867   }
6868
6869   Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
6870   if (theArgsNb < 2)
6871   {
6872     if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
6873     {
6874       theDi << "DeflType:           relative\n"
6875             << "DeviationCoeff:     " << aDefParams->DeviationCoefficient() << "\n";
6876     }
6877     else
6878     {
6879       theDi << "DeflType:           absolute\n"
6880             << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
6881     }
6882     theDi << "AngularDeflection:  " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
6883     theDi << "AutoTriangulation:  " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
6884     return 0;
6885   }
6886
6887   for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6888   {
6889     TCollection_AsciiString anArg (theArgVec[anArgIter]);
6890     anArg.UpperCase();
6891     if (anArg == "-ABSDEFL"
6892      || anArg == "-ABSOLUTEDEFLECTION"
6893      || anArg == "-DEFL"
6894      || anArg == "-DEFLECTION")
6895     {
6896       if (++anArgIter >= theArgsNb)
6897       {
6898         std::cout << "Error: wrong syntax at " << anArg << "\n";
6899         return 1;
6900       }
6901       aDefParams->SetTypeOfDeflection         (Aspect_TOD_ABSOLUTE);
6902       aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
6903     }
6904     else if (anArg == "-RELDEFL"
6905           || anArg == "-RELATIVEDEFLECTION"
6906           || anArg == "-DEVCOEFF"
6907           || anArg == "-DEVIATIONCOEFF"
6908           || anArg == "-DEVIATIONCOEFFICIENT")
6909     {
6910       if (++anArgIter >= theArgsNb)
6911       {
6912         std::cout << "Error: wrong syntax at " << anArg << "\n";
6913         return 1;
6914       }
6915       aDefParams->SetTypeOfDeflection     (Aspect_TOD_RELATIVE);
6916       aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
6917     }
6918     else if (anArg == "-ANGDEFL"
6919           || anArg == "-ANGULARDEFL"
6920           || anArg == "-ANGULARDEFLECTION")
6921     {
6922       if (++anArgIter >= theArgsNb)
6923       {
6924         std::cout << "Error: wrong syntax at " << anArg << "\n";
6925         return 1;
6926       }
6927       // currently HLRDeviationAngle is used instead of DeviationAngle in most places
6928       aDefParams->SetHLRAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
6929     }
6930     if (anArg == "-AUTOTR"
6931      || anArg == "-AUTOTRIANG"
6932      || anArg == "-AUTOTRIANGULATION")
6933     {
6934       if (++anArgIter >= theArgsNb)
6935       {
6936         std::cout << "Error: wrong syntax at " << anArg << "\n";
6937         return 1;
6938       }
6939       TCollection_AsciiString aValue (theArgVec[anArgIter]);
6940       aValue.LowerCase();
6941       if (aValue == "on"
6942        || aValue == "1")
6943       {
6944         aDefParams->SetAutoTriangulation (Standard_True);
6945       }
6946       else if (aValue == "off"
6947             || aValue == "0")
6948       {
6949         aDefParams->SetAutoTriangulation (Standard_False);
6950       }
6951     }
6952     else
6953     {
6954       std::cerr << "Warning, unknown argument '" << anArg.ToCString() << "'\n";
6955     }
6956   }
6957
6958   return 0;
6959 }
6960
6961 //! Auxiliary method
6962 inline void addLight (const Handle(V3d_Light)& theLightNew,
6963                       const Standard_Boolean   theIsGlobal)
6964 {
6965   if (theLightNew.IsNull())
6966   {
6967     return;
6968   }
6969
6970   if (theIsGlobal)
6971   {
6972     ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew);
6973   }
6974   else
6975   {
6976     ViewerTest::CurrentView()->SetLightOn (theLightNew);
6977   }
6978 }
6979
6980 //! Auxiliary method
6981 inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
6982 {
6983   TCollection_AsciiString anArgNextCase (theArgNext);
6984   anArgNextCase.UpperCase();
6985   if (anArgNextCase.Length() > 5
6986    && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
6987   {
6988     return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
6989   }
6990   else
6991   {
6992     return theArgNext.IntegerValue();
6993   }
6994 }
6995
6996 //===============================================================================================
6997 //function : VLight
6998 //purpose  :
6999 //===============================================================================================
7000 static int VLight (Draw_Interpretor& theDi,
7001                    Standard_Integer  theArgsNb,
7002                    const char**      theArgVec)
7003 {
7004   Handle(V3d_View)   aView   = ViewerTest::CurrentView();
7005   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
7006   if (aView.IsNull()
7007    || aViewer.IsNull())
7008   {
7009     std::cerr << "No active viewer!\n";
7010     return 1;
7011   }
7012
7013   Standard_Real        anXYZ[3];
7014   Quantity_Coefficient anAtten[2];
7015   if (theArgsNb < 2)
7016   {
7017     // print lights info
7018     Standard_Integer aLightId = 0;
7019     for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightId)
7020     {
7021       Handle(V3d_Light) aLight = aView->ActiveLight();
7022       const Quantity_Color aColor = aLight->Color();
7023       theDi << "Light" << aLightId << "\n";
7024       switch (aLight->Type())
7025       {
7026         case V3d_AMBIENT:
7027         {
7028           theDi << "  Type:      Ambient\n";
7029           break;
7030         }
7031         case V3d_DIRECTIONAL:
7032         {
7033           Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
7034           theDi << "  Type:      Directional\n";
7035           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7036           if (!aLightDir.IsNull())
7037           {
7038             aLightDir->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7039             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7040             aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
7041             theDi << "  Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7042           }
7043           break;
7044         }
7045         case V3d_POSITIONAL:
7046         {
7047           Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
7048           theDi << "  Type:      Positional\n";
7049           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7050           if (!aLightPos.IsNull())
7051           {
7052             aLightPos->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7053             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7054             aLightPos->Attenuation (anAtten[0], anAtten[1]);
7055             theDi << "  Atten.:    " << anAtten[0] << " " << anAtten[1] << "\n";
7056           }
7057           break;
7058         }
7059         case V3d_SPOT:
7060         {
7061           Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
7062           theDi << "  Type:      Spot\n";
7063           theDi << "  Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
7064           if (!aLightSpot.IsNull())
7065           {
7066             aLightSpot->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
7067             theDi << "  Position:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7068             aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
7069             theDi << "  Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
7070             aLightSpot->Attenuation (anAtten[0], anAtten[1]);
7071             theDi << "  Atten.:    " << anAtten[0] << " " << anAtten[1] << "\n";
7072             theDi << "  Angle:     " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
7073             theDi << "  Exponent:  " << aLightSpot->Concentration() << "\n";
7074           }
7075           break;
7076         }
7077         default:
7078         {
7079           theDi << "  Type:      UNKNOWN\n";
7080           break;
7081         }
7082       }
7083       theDi << "  Color:     " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n";
7084     }
7085   }
7086
7087   Handle(V3d_Light) aLightNew;
7088   Handle(V3d_Light) aLightOld;
7089   Standard_Boolean  isGlobal = Standard_True;
7090   Standard_Boolean  toCreate = Standard_False;
7091   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7092   {
7093     Handle(V3d_Light)            aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
7094     Handle(V3d_AmbientLight)     aLightAmb  = Handle(V3d_AmbientLight)    ::DownCast (aLightCurr);
7095     Handle(V3d_DirectionalLight) aLightDir  = Handle(V3d_DirectionalLight)::DownCast (aLightCurr);
7096     Handle(V3d_PositionalLight)  aLightPos  = Handle(V3d_PositionalLight) ::DownCast (aLightCurr);
7097     Handle(V3d_SpotLight)        aLightSpot = Handle(V3d_SpotLight)       ::DownCast (aLightCurr);
7098
7099     TCollection_AsciiString aName, aValue;
7100     const TCollection_AsciiString anArg (theArgVec[anArgIt]);
7101     TCollection_AsciiString anArgCase (anArg);
7102     anArgCase.UpperCase();
7103     if (anArgCase.IsEqual ("NEW")
7104      || anArgCase.IsEqual ("ADD")
7105      || anArgCase.IsEqual ("CREATE"))
7106     {
7107       toCreate = Standard_True;
7108     }
7109     else if (anArgCase.IsEqual ("GLOB")
7110           || anArgCase.IsEqual ("GLOBAL"))
7111     {
7112       isGlobal = Standard_True;
7113     }
7114     else if (anArgCase.IsEqual ("LOC")
7115           || anArgCase.IsEqual ("LOCAL"))
7116     {
7117       isGlobal = Standard_False;
7118     }
7119     else if (anArgCase.IsEqual ("DEF")
7120           || anArgCase.IsEqual ("DEFAULTS"))
7121     {
7122       toCreate = Standard_False;
7123       aViewer->SetDefaultLights();
7124     }
7125     else if (anArgCase.IsEqual ("CLR")
7126           || anArgCase.IsEqual ("CLEAR"))
7127     {
7128       toCreate = Standard_False;
7129       aView->InitActiveLights();
7130       while (aView->MoreActiveLights())
7131       {
7132         aViewer->DelLight (aView->ActiveLight());
7133         aView->InitActiveLights();
7134       }
7135     }
7136     else if (anArgCase.IsEqual ("AMB")
7137           || anArgCase.IsEqual ("AMBIENT")
7138           || anArgCase.IsEqual ("AMBLIGHT"))
7139     {
7140       addLight (aLightNew, isGlobal);
7141       if (!toCreate)
7142       {
7143         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7144         return 1;
7145       }
7146       toCreate  = Standard_False;
7147       aLightNew = new V3d_AmbientLight (aViewer);
7148     }
7149     else if (anArgCase.IsEqual ("DIRECTIONAL")
7150           || anArgCase.IsEqual ("DIRLIGHT"))
7151     {
7152       addLight (aLightNew, isGlobal);
7153       if (!toCreate)
7154       {
7155         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7156         return 1;
7157       }
7158       toCreate  = Standard_False;
7159       aLightNew = new V3d_DirectionalLight (aViewer);
7160     }
7161     else if (anArgCase.IsEqual ("SPOT")
7162           || anArgCase.IsEqual ("SPOTLIGHT"))
7163     {
7164       addLight (aLightNew, isGlobal);
7165       if (!toCreate)
7166       {
7167         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7168         return 1;
7169       }
7170       toCreate  = Standard_False;
7171       aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0);
7172     }
7173     else if (anArgCase.IsEqual ("POSLIGHT")
7174           || anArgCase.IsEqual ("POSITIONAL"))
7175     {
7176       addLight (aLightNew, isGlobal);
7177       if (!toCreate)
7178       {
7179         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7180         return 1;
7181       }
7182       toCreate  = Standard_False;
7183       aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0);
7184     }
7185     else if (anArgCase.IsEqual ("CHANGE"))
7186     {
7187       addLight (aLightNew, isGlobal);
7188       aLightNew.Nullify();
7189       if (++anArgIt >= theArgsNb)
7190       {
7191         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7192         return 1;
7193       }
7194
7195       const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
7196       Standard_Integer aLightIt = 0;
7197       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
7198       {
7199         if (aLightIt == aLightId)
7200         {
7201           aLightOld = aView->ActiveLight();
7202           break;
7203         }
7204       }
7205
7206       if (aLightOld.IsNull())
7207       {
7208         std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n";
7209         return 1;
7210       }
7211     }
7212     else if (anArgCase.IsEqual ("DEL")
7213           || anArgCase.IsEqual ("DELETE"))
7214     {
7215       Handle(V3d_Light) aLightDel;
7216       if (++anArgIt >= theArgsNb)
7217       {
7218         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7219         return 1;
7220       }
7221
7222       const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
7223       const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
7224       Standard_Integer aLightIt = 0;
7225       for (aView->InitActiveLights(); aView->MoreActiveLights(); aView->NextActiveLights(), ++aLightIt)
7226       {
7227         aLightDel = aView->ActiveLight();
7228         if (aLightIt == aLightDelId)
7229         {
7230           break;
7231         }
7232       }
7233       if (!aLightDel.IsNull())
7234       {
7235         aViewer->DelLight (aLightDel);
7236       }
7237     }
7238     else if (anArgCase.IsEqual ("COLOR")
7239           || anArgCase.IsEqual ("COLOUR"))
7240     {
7241       if (++anArgIt >= theArgsNb)
7242       {
7243         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7244         return 1;
7245       }
7246
7247       TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
7248       anArgNext.UpperCase();
7249       const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
7250       if (!aLightCurr.IsNull())
7251       {
7252         aLightCurr->SetColor (aColor);
7253       }
7254     }
7255     else if (anArgCase.IsEqual ("POS")
7256           || anArgCase.IsEqual ("POSITION"))
7257     {
7258       if ((anArgIt + 3) >= theArgsNb)
7259       {
7260         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7261         return 1;
7262       }
7263
7264       anXYZ[0] = Atof (theArgVec[++anArgIt]);
7265       anXYZ[1] = Atof (theArgVec[++anArgIt]);
7266       anXYZ[2] = Atof (theArgVec[++anArgIt]);
7267       if (!aLightDir.IsNull())
7268       {
7269         aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
7270       }
7271       else if (!aLightPos.IsNull())
7272       {
7273         aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
7274       }
7275       else if (!aLightSpot.IsNull())
7276       {
7277         aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
7278       }
7279       else
7280       {
7281         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7282         return 1;
7283       }
7284     }
7285     else if (anArgCase.IsEqual ("DIR")
7286           || anArgCase.IsEqual ("DIRECTION"))
7287     {
7288       if ((anArgIt + 3) >= theArgsNb)
7289       {
7290         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7291         return 1;
7292       }
7293
7294       anXYZ[0] = Atof (theArgVec[++anArgIt]);
7295       anXYZ[1] = Atof (theArgVec[++anArgIt]);
7296       anXYZ[2] = Atof (theArgVec[++anArgIt]);
7297       if (!aLightDir.IsNull())
7298       {
7299         aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
7300       }
7301       else if (!aLightSpot.IsNull())
7302       {
7303         aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
7304       }
7305       else
7306       {
7307         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7308         return 1;
7309       }
7310     }
7311     else if (anArgCase.IsEqual ("ANG")
7312           || anArgCase.IsEqual ("ANGLE"))
7313     {
7314       if (++anArgIt >= theArgsNb)
7315       {
7316         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7317         return 1;
7318       }
7319
7320       Standard_Real anAngle = Atof (theArgVec[anArgIt]);
7321
7322       if (!aLightSpot.IsNull())
7323       {
7324         aLightSpot->SetAngle (anAngle / 180.0 * M_PI);
7325       }
7326     }
7327     else if (anArgCase.IsEqual ("CONSTATTEN")
7328           || anArgCase.IsEqual ("CONSTATTENUATION"))
7329     {
7330       if (++anArgIt >= theArgsNb)
7331       {
7332         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7333         return 1;
7334       }
7335
7336       if (!aLightPos.IsNull())
7337       {
7338         aLightPos->Attenuation (anAtten[0], anAtten[1]);
7339         anAtten[0] = Atof (theArgVec[anArgIt]);
7340         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
7341       }
7342       else if (!aLightSpot.IsNull())
7343       {
7344         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
7345         anAtten[0] = Atof (theArgVec[anArgIt]);
7346         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
7347       }
7348       else
7349       {
7350         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7351         return 1;
7352       }
7353     }
7354     else if (anArgCase.IsEqual ("LINATTEN")
7355           || anArgCase.IsEqual ("LINEARATTEN")
7356           || anArgCase.IsEqual ("LINEARATTENUATION"))
7357     {
7358       if (++anArgIt >= theArgsNb)
7359       {
7360         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7361         return 1;
7362       }
7363
7364       if (!aLightPos.IsNull())
7365       {
7366         aLightPos->Attenuation (anAtten[0], anAtten[1]);
7367         anAtten[1] = Atof (theArgVec[anArgIt]);
7368         aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
7369       }
7370       else if (!aLightSpot.IsNull())
7371       {
7372         aLightSpot->Attenuation (anAtten[0], anAtten[1]);
7373         anAtten[1] = Atof (theArgVec[anArgIt]);
7374         aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
7375       }
7376       else
7377       {
7378         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7379         return 1;
7380       }
7381     }
7382     else if (anArgCase.IsEqual ("EXP")
7383           || anArgCase.IsEqual ("EXPONENT")
7384           || anArgCase.IsEqual ("SPOTEXP")
7385           || anArgCase.IsEqual ("SPOTEXPONENT"))
7386     {
7387       if (++anArgIt >= theArgsNb)
7388       {
7389         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7390         return 1;
7391       }
7392
7393       if (!aLightSpot.IsNull())
7394       {
7395         aLightSpot->SetConcentration (Atof (theArgVec[anArgIt]));
7396       }
7397       else
7398       {
7399         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7400         return 1;
7401       }
7402     }
7403     else if (anArgCase.IsEqual ("HEAD")
7404           || anArgCase.IsEqual ("HEADLIGHT"))
7405     {
7406       if (++anArgIt >= theArgsNb)
7407       {
7408         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7409         return 1;
7410       }
7411
7412       if (aLightAmb.IsNull()
7413        && !aLightCurr.IsNull())
7414       {
7415         aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0);
7416       }
7417       else
7418       {
7419         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
7420         return 1;
7421       }
7422     }
7423     else
7424     {
7425       std::cerr << "Warning: unknown argument '" << anArg << "'\n";
7426     }
7427   }
7428
7429   addLight (aLightNew, isGlobal);
7430   aViewer->UpdateLights();
7431
7432   return 0;
7433 }
7434
7435 //=======================================================================
7436 //function : VRenderParams
7437 //purpose  : Enables/disables rendering features
7438 //=======================================================================
7439
7440 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
7441                                        Standard_Integer  theArgNb,
7442                                        const char**      theArgVec)
7443 {
7444   Handle(V3d_View) aView = ViewerTest::CurrentView();
7445   if (aView.IsNull())
7446   {
7447     std::cerr << "Error: no active viewer!\n";
7448     return 1;
7449   }
7450
7451   Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
7452   TCollection_AsciiString aCmdName (theArgVec[0]);
7453   aCmdName.LowerCase();
7454   if (aCmdName == "vraytrace")
7455   {
7456     if (theArgNb == 1)
7457     {
7458       theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
7459       return 0;
7460     }
7461     else if (theArgNb == 2)
7462     {
7463       TCollection_AsciiString aValue (theArgVec[1]);
7464       aValue.LowerCase();
7465       if (aValue == "on"
7466        || aValue == "1")
7467       {
7468         aParams.Method = Graphic3d_RM_RAYTRACING;
7469         aView->Redraw();
7470         return 0;
7471       }
7472       else if (aValue == "off"
7473             || aValue == "0")
7474       {
7475         aParams.Method = Graphic3d_RM_RASTERIZATION;
7476         aView->Redraw();
7477         return 0;
7478       }
7479       else
7480       {
7481         std::cout << "Error: unknown argument '" << theArgVec[1] << "'\n";
7482         return 1;
7483       }
7484     }
7485     else
7486     {
7487       std::cout << "Error: wrong number of arguments\n";
7488       return 1;
7489     }
7490   }
7491
7492   if (theArgNb < 2)
7493   {
7494     theDI << "renderMode:  ";
7495     switch (aParams.Method)
7496     {
7497       case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
7498       case Graphic3d_RM_RAYTRACING:    theDI << "raytrace ";      break;
7499     }
7500     theDI << "\n";
7501     theDI << "fsaa:         " << (aParams.IsAntialiasingEnabled      ? "on" : "off") << "\n";
7502     theDI << "shadows:      " << (aParams.IsShadowEnabled            ? "on" : "off") << "\n";
7503     theDI << "reflections:  " << (aParams.IsReflectionEnabled        ? "on" : "off") << "\n";
7504     theDI << "rayDepth:     " <<  aParams.RaytracingDepth                            << "\n";
7505     theDI << "gleam:        " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
7506     theDI << "shadingModel: ";
7507     switch (aView->ShadingModel())
7508     {
7509       case V3d_COLOR:   theDI << "color";   break;
7510       case V3d_FLAT:    theDI << "flat";    break;
7511       case V3d_GOURAUD: theDI << "gouraud"; break;
7512       case V3d_PHONG:   theDI << "phong";   break;
7513     }
7514     theDI << "\n";
7515     return 0;
7516   }
7517
7518   Standard_Boolean toPrint = Standard_False;
7519   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7520   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7521   {
7522     Standard_CString        anArg (theArgVec[anArgIter]);
7523     TCollection_AsciiString aFlag (anArg);
7524     aFlag.LowerCase();
7525     if (anUpdateTool.parseRedrawMode (aFlag))
7526     {
7527       continue;
7528     }
7529     else if (aFlag == "-echo"
7530           || aFlag == "-print")
7531     {
7532       toPrint = Standard_True;
7533       anUpdateTool.Invalidate();
7534     }
7535     else if (aFlag == "-mode"
7536           || aFlag == "-rendermode"
7537           || aFlag == "-render_mode")
7538     {
7539       if (toPrint)
7540       {
7541         switch (aParams.Method)
7542         {
7543           case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
7544           case Graphic3d_RM_RAYTRACING:    theDI << "ray-tracing ";   break;
7545         }
7546         continue;
7547       }
7548       else
7549       {
7550         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
7551         return 1;
7552       }
7553     }
7554     else if (aFlag == "-ray"
7555           || aFlag == "-raytrace")
7556     {
7557       if (toPrint)
7558       {
7559         theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
7560         continue;
7561       }
7562
7563       aParams.Method = Graphic3d_RM_RAYTRACING;
7564     }
7565     else if (aFlag == "-rast"
7566           || aFlag == "-raster"
7567           || aFlag == "-rasterization")
7568     {
7569       if (toPrint)
7570       {
7571         theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
7572         continue;
7573       }
7574
7575       aParams.Method = Graphic3d_RM_RASTERIZATION;
7576     }
7577     else if (aFlag == "-raydepth"
7578           || aFlag == "-ray_depth")
7579     {
7580       if (toPrint)
7581       {
7582         theDI << aParams.RaytracingDepth << " ";
7583         continue;
7584       }
7585       else if (++anArgIter >= theArgNb)
7586       {
7587         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
7588         return 1;
7589       }
7590
7591       const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
7592       if (aDepth < 1 || aDepth > 10)
7593       {
7594         std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
7595         return 1;
7596       }
7597       else
7598       {
7599         aParams.RaytracingDepth = aDepth;
7600       }
7601     }
7602     else if (aFlag == "-shad"
7603           || aFlag == "-shadows")
7604     {
7605       if (toPrint)
7606       {
7607         theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
7608         continue;
7609       }
7610
7611       Standard_Boolean toEnable = Standard_True;
7612       if (++anArgIter < theArgNb
7613       && !parseOnOff (theArgVec[anArgIter], toEnable))
7614       {
7615         --anArgIter;
7616       }
7617       aParams.IsShadowEnabled = toEnable;
7618     }
7619     else if (aFlag == "-refl"
7620           || aFlag == "-reflections")
7621     {
7622       if (toPrint)
7623       {
7624         theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
7625         continue;
7626       }
7627
7628       Standard_Boolean toEnable = Standard_True;
7629       if (++anArgIter < theArgNb
7630       && !parseOnOff (theArgVec[anArgIter], toEnable))
7631       {
7632         --anArgIter;
7633       }
7634       aParams.IsReflectionEnabled = toEnable;
7635     }
7636     else if (aFlag == "-fsaa")
7637     {
7638       if (toPrint)
7639       {
7640         theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
7641         continue;
7642       }
7643
7644       Standard_Boolean toEnable = Standard_True;
7645       if (++anArgIter < theArgNb
7646       && !parseOnOff (theArgVec[anArgIter], toEnable))
7647       {
7648         --anArgIter;
7649       }
7650       aParams.IsAntialiasingEnabled = toEnable;
7651     }
7652     else if (aFlag == "-gleam")
7653     {
7654       if (toPrint)
7655       {
7656         theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
7657         continue;
7658       }
7659
7660       Standard_Boolean toEnable = Standard_True;
7661       if (++anArgIter < theArgNb
7662       && !parseOnOff (theArgVec[anArgIter], toEnable))
7663       {
7664         --anArgIter;
7665       }
7666       aParams.IsTransparentShadowEnabled = toEnable;
7667     }
7668     else if (aFlag == "-shademodel"
7669           || aFlag == "-shadingmodel"
7670           || aFlag == "-shading")
7671     {
7672       if (toPrint)
7673       {
7674         switch (aView->ShadingModel())
7675         {
7676           case V3d_COLOR:   theDI << "color ";   break;
7677           case V3d_FLAT:    theDI << "flat ";    break;
7678           case V3d_GOURAUD: theDI << "gouraud "; break;
7679           case V3d_PHONG:   theDI << "phong ";   break;
7680         }
7681         continue;
7682       }
7683
7684       if (++anArgIter >= theArgNb)
7685       {
7686         std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
7687       }
7688
7689       TCollection_AsciiString aMode (theArgVec[anArgIter]);
7690       aMode.LowerCase();
7691       if (aMode == "color"
7692        || aMode == "none")
7693       {
7694         aView->SetShadingModel (V3d_COLOR);
7695       }
7696       else if (aMode == "flat"
7697             || aMode == "facet")
7698       {
7699         aView->SetShadingModel (V3d_FLAT);
7700       }
7701       else if (aMode == "gouraud"
7702             || aMode == "vertex"
7703             || aMode == "vert")
7704       {
7705         aView->SetShadingModel (V3d_GOURAUD);
7706       }
7707       else if (aMode == "phong"
7708             || aMode == "fragment"
7709             || aMode == "frag"
7710             || aMode == "pixel")
7711       {
7712         aView->SetShadingModel (V3d_PHONG);
7713       }
7714       else
7715       {
7716         std::cout << "Error: unknown shading model '" << aMode << "'\n";
7717         return 1;
7718       }
7719     }
7720     else
7721     {
7722       std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
7723       return 1;
7724     }
7725   }
7726   return 0;
7727 }
7728
7729 //=======================================================================
7730 //function : VFrustumCulling
7731 //purpose  : enables/disables view volume's culling.
7732 //=======================================================================
7733 static int VFrustumCulling (Draw_Interpretor& theDI,
7734                             Standard_Integer  theArgNb,
7735                             const char**      theArgVec)
7736 {
7737   Handle(V3d_View) aView = ViewerTest::CurrentView();
7738   if (aView.IsNull())
7739   {
7740     std::cout << theArgVec[0] << " Error: Use 'vinit' command before\n";
7741     return 1;
7742   }
7743
7744   if (theArgNb < 2)
7745   {
7746     theDI << (aView->IsCullingEnabled() ? "on" : "off");
7747     return 0;
7748   }
7749   else if (theArgNb != 2)
7750   {
7751     std::cout << theArgVec[0] << " Syntax error: Specify the mode\n";
7752     return 1;
7753   }
7754
7755   TCollection_AsciiString aModeStr (theArgVec[1]);
7756   aModeStr.LowerCase();
7757   Standard_Boolean toEnable = 0;
7758   if (aModeStr == "on")
7759   {
7760     toEnable = 1;
7761   }
7762   else if (aModeStr == "off")
7763   {
7764     toEnable = 0;
7765   }
7766   else
7767   {
7768     toEnable = Draw::Atoi (theArgVec[1]) != 0;
7769   }
7770
7771   aView->SetFrustumCulling (toEnable);
7772   aView->Redraw();
7773   return 0;
7774 }
7775
7776 //=======================================================================
7777 //function : VHighlightSelected
7778 //purpose  : 
7779 //=======================================================================
7780 static int VHighlightSelected (Draw_Interpretor& theDI,
7781                                Standard_Integer  theArgNb,
7782                                const char**      theArgVec)
7783 {
7784   if (ViewerTest::GetAISContext().IsNull())
7785   {
7786     std::cout << theArgVec[0] << " error : Context is not created. Please call vinit before.\n";
7787     return 1;
7788   }
7789
7790   const Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7791
7792   if (theArgNb < 2)
7793   {
7794     theDI << (aContext->ToHilightSelected() ? "on" : "off");
7795     return 0;
7796   }
7797
7798   if (theArgNb != 2)
7799   {
7800     std::cout  << theArgVec[0] << " error : wrong number of parameters."
7801           << "Type 'help" << theArgVec[0] << "' for more information.";
7802     return 1;
7803   }
7804
7805   // Parse parameter
7806   TCollection_AsciiString aMode (theArgVec[1]);
7807   aMode.LowerCase();
7808   Standard_Boolean toEnable = Standard_False;
7809   if (aMode.IsEqual ("on"))
7810   {
7811     toEnable = Standard_True;
7812   }
7813   else if (aMode.IsEqual ("off"))
7814   {
7815     toEnable = Standard_False;
7816   }
7817   else
7818   {
7819     toEnable = Draw::Atoi (theArgVec[1]) != 0;
7820   }
7821
7822   if (toEnable != aContext->ToHilightSelected())
7823   {
7824     aContext->SetToHilightSelected (toEnable);
7825
7826     // Move cursor to null position and  back to process updating of detection
7827     // and highlighting of selected object immediatly.
7828     Standard_Integer aPixX = 0;
7829     Standard_Integer aPixY = 0;
7830     const Handle(ViewerTest_EventManager)& anEventManager =  ViewerTest::CurrentEventManager();
7831
7832     anEventManager->GetCurrentPosition (aPixX, aPixY);
7833     anEventManager->MoveTo (0, 0);
7834     anEventManager->MoveTo (aPixX, aPixY);
7835   }
7836
7837   return 0;
7838 }
7839
7840 //=======================================================================
7841 //function : VXRotate
7842 //purpose  :
7843 //=======================================================================
7844 static Standard_Integer VXRotate (Draw_Interpretor& di,
7845                                    Standard_Integer argc,
7846                                    const char ** argv)
7847 {
7848   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7849   if (aContext.IsNull())
7850   {
7851     di << argv[0] << "ERROR : use 'vinit' command before " << "\n";
7852     return 1;
7853   }
7854   
7855   if (argc != 3)
7856   {
7857     di << "ERROR : Usage : " << argv[0] << " name angle" << "\n";
7858     return 1;
7859   }
7860
7861   TCollection_AsciiString aName (argv[1]);
7862   Standard_Real anAngle = Draw::Atof (argv[2]);
7863
7864   // find object
7865   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
7866   Handle(AIS_InteractiveObject) anIObj;
7867   if (!aMap.IsBound2 (aName) )
7868   {
7869     di << "Use 'vdisplay' before" << "\n";
7870     return 1;
7871   }
7872   else
7873   {
7874     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
7875
7876     gp_Trsf aTransform;
7877     aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
7878     aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
7879
7880     aContext->SetLocation (anIObj, aTransform);
7881     aContext->UpdateCurrentViewer();
7882   }
7883
7884   return 0;
7885 }
7886
7887 //=======================================================================
7888 //function : ViewerCommands
7889 //purpose  :
7890 //=======================================================================
7891
7892 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
7893 {
7894
7895   const char *group = "ZeViewer";
7896   theCommands.Add("vinit",
7897 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7898     "[name=view_name] [display=display_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
7899 #else
7900     "[name=view_name] [l=leftPx t=topPx] [w=widthPx h=heightPx]\n"
7901 #endif
7902     " - Creates new View window with specified name view_name.\n"
7903     "By default the new view is created in the viewer and in"
7904     " graphic driver shared with active view.\n"
7905     " - name = {driverName/viewerName/viewName | viewerName/viewName | viewName}.\n"
7906     "If driverName isn't specified the driver will be shared with active view.\n"
7907     "If viewerName isn't specified the viewer will be shared with active view.\n"
7908 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7909     " - display = HostName.DisplayNumber[:ScreenNumber] : if specified"
7910     "is used in creation of graphic driver\n"
7911 #endif
7912     " - l, t: pixel position of left top corner of the window\n"
7913     " - w,h: width and heigth of window respectively.\n"
7914     "Additional commands for operations with views: vclose, vactivate, vviewlist.\n",
7915     __FILE__,VInit,group);
7916   theCommands.Add("vclose" ,
7917     "[view_id [keep_context=0|1]]\n"
7918     "or vclose ALL - to remove all created views\n"
7919     " - removes view(viewer window) defined by its view_id.\n"
7920     " - keep_context: by default 0; if 1 and the last view is deleted"
7921     " the current context is not removed.",
7922     __FILE__,VClose,group);
7923   theCommands.Add("vactivate" ,
7924     "view_id"
7925     " - activates view(viewer window) defined by its view_id",
7926     __FILE__,VActivate,group);
7927   theCommands.Add("vviewlist",
7928     "vviewlist [format={tree, long}]"
7929     " - prints current list of views per viewer and graphic_driver ID shared between viewers"
7930     " - format: format of result output, if tree the output is a tree view;"
7931     "otherwise it's a list of full view names. By default format = tree",
7932     __FILE__,VViewList,group);
7933   theCommands.Add("vhelp" ,
7934     "vhelp            : display help on the viewer commands",
7935     __FILE__,VHelp,group);
7936   theCommands.Add("vtop" ,
7937     "vtop or <T>      : Top view" ,
7938     __FILE__,VTop,group);
7939   theCommands.Add("vbottom" ,
7940     "vbottom          : Bottom view" ,
7941     __FILE__,VBottom,group);
7942   theCommands.Add("vleft" ,
7943     "vleft            : Left view" ,
7944     __FILE__,VLeft,group);
7945   theCommands.Add("vright" ,
7946     "vright           : Right view" ,
7947     __FILE__,VRight,group);
7948   theCommands.Add("vaxo" ,
7949     " vaxo or <A>     : Axonometric view ",
7950     __FILE__,VAxo,group);
7951   theCommands.Add("vfront" ,
7952     "vfront           : Front view" ,
7953     __FILE__,VFront,group);
7954   theCommands.Add("vback" ,
7955     "vback            : Back view" ,
7956     __FILE__,VBack,group);
7957   theCommands.Add("vpick" ,
7958     "vpick           : vpick X Y Z [shape subshape] ( all variables as string )",
7959     VPick,group);
7960   theCommands.Add("vfit"    ,
7961     "vfit or <F>         : vfit",
7962     __FILE__,VFit,group);
7963   theCommands.Add ("vfitarea",
7964     "vfitarea x1 y1 x2 y2"
7965     "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
7966     "\n\t\t: Fit view to show area located between two points"
7967     "\n\t\t: given in world 2D or 3D corrdinates.",
7968     __FILE__, VFitArea, group);
7969   theCommands.Add ("vzfit", "vzfit [scale]\n"
7970     "   Matches Z near, Z far view volume planes to the displayed objects.\n"
7971     "   \"scale\" - specifies factor to scale computed z range.\n",
7972     __FILE__, VZFit, group);
7973   theCommands.Add("vrepaint",
7974     "vrepaint        : vrepaint, force redraw",
7975     __FILE__,VRepaint,group);
7976   theCommands.Add("vclear",
7977     "vclear          : vclear",
7978     __FILE__,VClear,group);
7979   theCommands.Add("vsetbg",
7980     "vsetbg          : vsetbg imagefile [filltype] : Load image as background",
7981     __FILE__,VSetBg,group);
7982   theCommands.Add("vsetbgmode",
7983     "vsetbgmode      : vsetbgmode filltype : Change background image fill type",
7984     __FILE__,VSetBgMode,group);
7985   theCommands.Add("vsetgradientbg",
7986     "vsetgradientbg  : vsetgradientbg r1 g1 b1 r2 g2 b2 filltype : Mount gradient background",
7987     __FILE__,VSetGradientBg,group);
7988   theCommands.Add("vsetgrbgmode",
7989     "vsetgrbgmode    : vsetgrbgmode filltype : Change gradient background fill type",
7990     __FILE__,VSetGradientBgMode,group);
7991   theCommands.Add("vsetcolorbg",
7992     "vsetcolorbg     : vsetcolorbg r g b : Set background color",
7993     __FILE__,VSetColorBg,group);
7994   theCommands.Add("vscale",
7995     "vscale          : vscale X Y Z",
7996     __FILE__,VScale,group);
7997   theCommands.Add("vzbufftrihedron",
7998     "vzbufftrihedron [center|left_lower|left_upper|right_lower|right_upper"
7999     " textR=255 textG=255 textB=255 scale=0.1 wireframe|zbuffer]"
8000     " : Displays a V3d_ZBUFFER'ed or V3d_WIREFRAME'd trihedron",
8001     __FILE__,VTestZBuffTrihedron,group);
8002   theCommands.Add("vrotate",
8003     "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
8004     "\n                : Option -mouseStart starts rotation according to the mouse position"
8005     "\n                : Option -mouseMove continues rotation with angle computed"
8006     "\n                : from last and new mouse position."
8007     "\n                : vrotate AX AY AZ [X Y Z]",
8008     __FILE__,VRotate,group);
8009   theCommands.Add("vzoom",
8010     "vzoom           : vzoom coef",
8011     __FILE__,VZoom,group);
8012   theCommands.Add("vpan",
8013     "vpan            : vpan dx dy",
8014     __FILE__,VPan,group);
8015   theCommands.Add("vexport",
8016     "vexport         : vexport full_file_path {PS | EPS | TEX | PDF | SVG | PGF | EMF }"
8017     " : exports the view to a vector file of a given format"
8018     " : notice that EMF format requires patched gl2ps",
8019     __FILE__,VExport,group);
8020   theCommands.Add("vcolorscale",
8021     "vcolorscale     : vcolorscale [-range RangeMin = 0 RangeMax = 100 Intervals = 10 -font HeightFont = 16  -textpos "
8022     "Position = left -xy X = 0 Y = 0] [-noupdate|-update]: draw color scale\n"
8023     "-demo/-demoversion draw a demoversion of color scale.\n"
8024     "-show/display display color scale.\n"
8025     "-hide/erase erase color scale.\n"
8026     "Please note that -show/-hide option must be the first argument!\n"
8027     "-color Index R G B: set color for indexed interval\n"
8028     "-color Index ColorName: set color for indexed interval\n"
8029     "-colors R G B R G B ...: set colors for all intervals\n"
8030     "-colors ColorName1 ColorName2 ...: set colors for all intervals\n"
8031     "-colors supports both color names and rgb values in one call\n"
8032     "-label Index Text: set label for indexed interval\n"
8033     "-labels Text Text Text ...: set labels for all intervals\n"
8034     "-title Title [Position]: set the title for color scale with certain position. Default position = center;\n"
8035     "Available text positions: left, right, center, none;\n",
8036     __FILE__,VColorScale,group);
8037   theCommands.Add("vgraduatedtrihedron",
8038     "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
8039     "\t[-namefont Name] [-valuesfont Name]\n"
8040     "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
8041     "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
8042     "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
8043     "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
8044     "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
8045     "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
8046     "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
8047     "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
8048     "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
8049     " - Displays or erases graduated trihedron"
8050     " - xname, yname, zname - names of axes, default: X, Y, Z\n"
8051     " - namefont - font of axes names. Default: Arial\n"
8052     " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
8053     " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
8054     " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
8055     " - valuesfont - font of axes values. Default: Arial\n"
8056     " - xcolor, ycolor, zcolor - color of axis and values\n"
8057     " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
8058     " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
8059     __FILE__,VGraduatedTrihedron,group);
8060   theCommands.Add("vprintview" ,
8061     "vprintview : width height filename [algo=0] [tile_width tile_height] : Test print algorithm: algo = 0 - stretch, algo = 1 - tile",
8062     __FILE__,VPrintView,group);
8063   theCommands.Add("vzlayer",
8064     "vzlayer add/del/get/settings/enable/disable [id]\n"
8065     " add - add new z layer to viewer and print its id\n"
8066     " del - del z layer by its id\n"
8067     " get - print sequence of z layers in increasing order of their overlay level\n"
8068     " settings - print status of z layer settings\n"
8069     " enable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    enables given setting for the z layer\n"
8070     " enable (p[ositive]offset/n[egative]offset) \n    enables given setting for the z layer\n"
8071     " disable ([depth]test/[depth]write/[depth]clear/[depth]offset) \n    disables given setting for the z layer\n"
8072     "\nWhere id is the layer identificator\n"
8073     "\nExamples:\n"
8074     "   vzlayer add\n"
8075     "   vzlayer enable poffset 1\n"
8076     "   vzlayer disable depthtest 1\n"
8077     "   vzlayer del 1\n",
8078     __FILE__,VZLayer,group);
8079   theCommands.Add("voverlaytext",
8080     "voverlaytext : text x y [height] [font_name] [text_color: R G B] [display_type] [background_color: R G B]"
8081     " : height - pixel height of the text (default=10.0)"
8082     " : font_name - name of font (default=courier)"
8083     " : text_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0) "
8084     " : display_type = {normal/subtitle/decal/blend}, (default=normal) "
8085     " : background_color - three values: RedColor GreenColor BlueColor (default = 255.0 255.0 255.0), the parameter is defined for subtitle and decal display types ",
8086     __FILE__,VOverlayText,group);
8087   theCommands.Add("vlayerline",
8088     "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
8089     __FILE__,VLayerLine,group);
8090   theCommands.Add ("vgrid",
8091     "vgrid [off] [Mode={r|c}] [Type={l|p}] [OriginX OriginY [StepX/StepRadius StepY/DivNb RotAngle]]"
8092     " : Mode - rectangular or circular"
8093     " : Type - lines or points",
8094     __FILE__, VGrid, group);
8095   theCommands.Add ("vfps",
8096     "vfps [framesNb=100] : estimate average frame rate for active view",
8097     __FILE__, VFps, group);
8098   theCommands.Add ("vgldebug",
8099     "vgldebug [{0|1}] : request debug GL context, should be called before vinit\n"
8100     "                : this function is implemented only for Windows\n"
8101     "                : GL_ARB_debug_output extension should be exported by OpenGL driver!",
8102     __FILE__, VGlDebug, group);
8103   theCommands.Add ("vvbo",
8104     "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
8105     __FILE__, VVbo, group);
8106   theCommands.Add ("vstereo",
8107     "\nvstereo [{0|1}] : turn stereo usage On/Off; affects only newly displayed objects",
8108     __FILE__, VStereo, group);
8109   theCommands.Add ("vcaps",
8110             "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}]"
8111     "\n\t\t:       [-compatibleContext {0|1}]"
8112     "\n\t\t:       [-softMode {0|1}] [-noupdate|-update]"
8113     "\n\t\t: Modify particular graphic driver options:"
8114     "\n\t\t:  FFP      - use fixed-function pipeline instead of"
8115     "\n\t\t:             built-in GLSL programs"
8116     "\n\t\t:            (requires compatible profile)"
8117     "\n\t\t:  VBO      - use Vertex Buffer Object (copy vertex"
8118     "\n\t\t:             arrays to GPU memory)"
8119     "\n\t\t:  sprite   - use textured sprites instead of bitmaps"
8120     "\n\t\t: Context creation options:"
8121     "\n\t\t:  softMode          - software OpenGL implementation"
8122     "\n\t\t:  compatibleProfile - backward-compatible profile"
8123     "\n\t\t: Unlike vrenderparams, these parameters control alternative"
8124     "\n\t\t: rendering paths producing the same visual result when"
8125     "\n\t\t: possible."
8126     "\n\t\t: Command is intended for testing old hardware compatibility.",
8127     __FILE__, VCaps, group);
8128   theCommands.Add ("vmemgpu",
8129     "vmemgpu [f]: print system-dependent GPU memory information if available;"
8130     " with f option returns free memory in bytes",
8131     __FILE__, VMemGpu, group);
8132   theCommands.Add ("vreadpixel",
8133     "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]"
8134     " : Read pixel value for active view",
8135     __FILE__, VReadPixel, group);
8136   theCommands.Add("diffimage",
8137     "diffimage     : diffimage imageFile1 imageFile2 toleranceOfColor(0..1) blackWhite(1|0) borderFilter(1|0) [diffImageFile]",
8138     __FILE__, VDiffImage, group);
8139   theCommands.Add ("vselect",
8140     "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [shift_selection = 0|1]\n"
8141     "- emulates different types of selection:\n"
8142     "- 1) single click selection\n"
8143     "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
8144     "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
8145     "- 4) any of these selections with shift button pressed",
8146     __FILE__, VSelect, group);
8147   theCommands.Add ("vmoveto",
8148     "vmoveto x y"
8149     "- emulates cursor movement to pixel postion (x,y)",
8150     __FILE__, VMoveTo, group);
8151   theCommands.Add ("vviewparams", "vviewparams usage:\n"
8152     "- vviewparams\n"
8153     "- vviewparams [-scale [s]] [-eye [x y z]] [-at [x y z]] [-up [x y z]]\n"
8154     "              [-proj [x y z]] [-center x y] [-size sx]\n"
8155     "-   Gets or sets current view parameters.\n"
8156     "-   If called without arguments, all view parameters are printed.\n"
8157     "-   The options are:\n"
8158     "      -scale [s]    : prints or sets viewport relative scale.\n"
8159     "      -eye [x y z]  : prints or sets eye location.\n"
8160     "      -at [x y z]   : prints or sets center of look.\n"
8161     "      -up [x y z]   : prints or sets direction of up vector.\n"
8162     "      -proj [x y z] : prints or sets direction of look.\n"
8163     "      -center x y   : sets location of center of the screen in pixels.\n"
8164     "      -size [sx]    : prints viewport projection width and height sizes\n"
8165     "                    : or changes the size of its maximum dimension.\n",
8166     __FILE__, VViewParams, group);
8167   theCommands.Add("vchangeselected",
8168     "vchangeselected shape"
8169     "- adds to shape to selection or remove one from it",
8170                 __FILE__, VChangeSelected, group);
8171   theCommands.Add("vzclipping",
8172     "vzclipping [mode] [depth width]\n"
8173     "- mode = OFF|BACK|FRONT|SLICE depth = [0..1] width = [0..1]\n"
8174     "- gets or sets ZClipping mode, width and depth",
8175     __FILE__,VZClipping,group);
8176   theCommands.Add ("vnbselected",
8177     "vnbselected", __FILE__, VNbSelected, group);
8178   theCommands.Add ("vcamera",
8179               "vcamera [-ortho] [-projtype]"
8180       "\n\t\t:         [-persp]"
8181       "\n\t\t:         [-fovy   [Angle]] [-distance [Distance]]"
8182       "\n\t\t:         [-stereo] [-leftEye] [-rightEye]"
8183       "\n\t\t:         [-iod [Distance]] [-iodType    [absolute|relative]]"
8184       "\n\t\t:         [-zfocus [Value]] [-zfocusType [absolute|relative]]"
8185       "\n\t\t: Manage camera parameters."
8186       "\n\t\t: Prints current value when option called without argument."
8187       "\n\t\t: Orthographic camera:"
8188       "\n\t\t:   -ortho      activate orthographic projection"
8189       "\n\t\t: Perspective camera:"
8190       "\n\t\t:   -persp      activate perspective  projection (mono)"
8191       "\n\t\t:   -fovy       field of view in y axis, in degrees"
8192       "\n\t\t:   -distance   distance of eye from camera center"
8193       "\n\t\t: Stereoscopic camera:"
8194       "\n\t\t:   -stereo     perspective  projection (stereo)"
8195       "\n\t\t:   -leftEye    perspective  projection (left  eye)"
8196       "\n\t\t:   -rightEye   perspective  projection (right eye)"
8197       "\n\t\t:   -iod        intraocular distance value"
8198       "\n\t\t:   -iodType    distance type, absolute or relative"
8199       "\n\t\t:   -zfocus     stereographic focus value"
8200       "\n\t\t:   -zfocusType focus type, absolute or relative",
8201     __FILE__, VCamera, group);
8202   theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
8203     "- vautozfit [on={1|0}] [scale]\n"
8204     "    Prints or changes parameters of automatic z-fit mode:\n"
8205     "   \"on\" - turns automatic z-fit on or off\n"
8206     "   \"scale\" - specifies factor to scale computed z range.\n",
8207     __FILE__, VAutoZFit, group);
8208   theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
8209     "   vzrange                - without parameters shows current values\n"
8210     "   vzrange [znear] [zfar] - applies provided values to view",
8211     __FILE__,VZRange, group);
8212   theCommands.Add("vantialiasing",
8213     "vantialiasing 1|0",
8214     __FILE__,VAntialiasing,group);
8215   theCommands.Add ("vpurgedisplay",
8216     "vpurgedisplay"
8217     "- removes structures which don't belong to objects displayed in neutral point",
8218     __FILE__, VPurgeDisplay, group);
8219   theCommands.Add("vsetviewsize",
8220     "vsetviewsize size",
8221     __FILE__,VSetViewSize,group);
8222   theCommands.Add("vmoveview",
8223     "vmoveview Dx Dy Dz [Start = 1|0]",
8224     __FILE__,VMoveView,group);
8225   theCommands.Add("vtranslateview",
8226     "vtranslateview Dx Dy Dz [Start = 1|0)]",
8227     __FILE__,VTranslateView,group);
8228   theCommands.Add("vturnview",
8229     "vturnview Ax Ay Az [Start = 1|0]",
8230     __FILE__,VTurnView,group);
8231   theCommands.Add("vtextureenv",
8232     "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
8233     "or user-defined file and optionally applying texture mapping parameters\n"
8234     "                  Usage:\n"
8235     "                  vtextureenv off - disables environment mapping\n"
8236     "                  vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
8237     "                              std_texture = (0..7)\n"
8238     "                              rep         = {clamp|repeat}\n"
8239     "                              mod         = {decal|modulate}\n"
8240     "                              flt         = {nearest|bilinear|trilinear}\n"
8241     "                              ss, st      - scale factors for s and t texture coordinates\n"
8242     "                              ts, tt      - translation for s and t texture coordinates\n"
8243     "                              rot         - texture rotation angle in degrees",
8244     __FILE__, VTextureEnv, group);
8245   theCommands.Add("vhlr" ,
8246     "is_enabled={on|off} [show_hidden={1|0}]"
8247     " - Hidden line removal algorithm:"
8248     " - is_enabled: if is on HLR algorithm is applied\n"
8249     " - show_hidden: if equals to 1, hidden lines are drawn as dotted ones.\n",
8250     __FILE__,VHLR,group);
8251   theCommands.Add("vhlrtype" ,
8252     "algo_type={algo|polyalgo} [shape_1 ... shape_n]"
8253     " - Changes the type of HLR algorithm using for shapes."
8254     " - algo_type: if equals to algo, exact HLR algorithm is applied;\n"
8255     "   if equals to polyalgo, polygonal HLR algorithm is applied."
8256     "If shapes are not given HLR algoithm of given type is applied"
8257     " to all shapes in the view\n",
8258     __FILE__,VHLRType,group);
8259   theCommands.Add("vclipplane", "vclipplane usage: \n"
8260     "  maxplanes <view_name> - get plane limit for view.\n"
8261     "  create <plane_name> - create new plane.\n"
8262     "  delete <plane_name> - delete plane.\n"
8263     "  clone <source_plane> <plane_name> - clone the plane definition.\n"
8264     "  set/unset <plane_name> object <object list> - set/unset plane for IO.\n"
8265     "  set/unset <plane_name> view <view list> - set/unset plane for view.\n"
8266     "  change <plane_name> on/off - turn clipping on/off.\n"
8267     "  change <plane_name> equation <a> <b> <c> <d> - change plane equation.\n"
8268     "  change <plane_name> capping on/off - turn capping on/off.\n"
8269     "  change <plane_name> capping color <r> <g> <b> - set color.\n"
8270     "  change <plane name> capping texname <texture> - set texture.\n"
8271     "  change <plane_name> capping texscale <sx> <sy> - set tex scale.\n"
8272     "  change <plane_name> capping texorigin <tx> <ty> - set tex origin.\n"
8273     "  change <plane_name> capping texrotate <angle> - set tex rotation.\n"
8274     "  change <plane_name> capping hatch on/off/<id> - set hatching mask.\n"
8275     "  please use VSetTextureMode command to enable texture rendering in view.\n"
8276     , __FILE__, VClipPlane, group);
8277   theCommands.Add("vsettexturemode", "vsettexturemode view_name mode \n"
8278     "  mode can be:\n"
8279     "  0 - no textures enabled in view.\n"
8280     "  1 - only environment textures enabled.\n"
8281     "  2 - all textures enabled.\n"
8282     "  this command sets texture details mode for the specified view.\n"
8283     , __FILE__, VSetTextureMode, group);
8284   theCommands.Add("vdefaults",
8285                "vdefaults [-absDefl value]"
8286        "\n\t\t:           [-devCoeff value]"
8287        "\n\t\t:           [-angDefl value]"
8288        "\n\t\t:           [-autoTriang {off/on | 0/1}]"
8289     , __FILE__, VDefaults, group);
8290   theCommands.Add("vlight",
8291     "tool to manage light sources, without arguments shows list of lights."
8292     "\n    Main commands: "
8293     "\n      'clear' to clear lights"
8294     "\n      '{def}aults' to load deafault lights"
8295     "\n      'add' (or 'new') <type> to add any light source"
8296     "\n          where <type> is one of {amb}ient|directional|{spot}light|positional"
8297     "\n      'change' <lightId> to edit light source with specified lightId"
8298     "\n\n      In addition to 'add' and 'change' commands you can use light parameters:"
8299     "\n        {pos}ition X Y Z"
8300     "\n        {dir}ection X Y Z (for directional light or for spotlight)"
8301     "\n        color colorName"
8302     "\n        {head}light 0|1"
8303     "\n        {constAtten}uation value"
8304     "\n        {linearAtten}uation value"
8305     "\n        angle angleDeg"
8306     "\n        {spotexp}onent value"
8307     "\n        local|global"
8308     "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
8309     "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
8310     __FILE__, VLight, group);
8311   theCommands.Add("vraytrace",
8312             "vraytrace [0|1]"
8313     "\n\t\t: Turn on/off raytracing renderer."
8314     "\n\t\t:   'vraytrace 0' alias for 'vrenderparams -raster'."
8315     "\n\t\t:   'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
8316     __FILE__, VRenderParams, group);
8317   theCommands.Add("vrenderparams",
8318     "\n    Manages rendering parameters: "
8319     "\n      '-rayTrace'             Enables  GPU ray-tracing"
8320     "\n      '-raster'               Disables GPU ray-tracing"
8321     "\n      '-rayDepth     0..10'   Defines maximum ray-tracing depth"
8322     "\n      '-shadows      on|off'  Enables/disables shadows rendering"
8323     "\n      '-reflections  on|off'  Enables/disables specular reflections"
8324     "\n      '-fsaa         on|off'  Enables/disables adaptive anti-aliasing"
8325     "\n      '-gleam        on|off'  Enables/disables transparency shadow effects"
8326     "\n      '-shadingModel model'   Controls shading model from enumeration"
8327     "\n                              color, flat, gouraud, phong"
8328     "\n    Unlike vcaps, these parameters dramatically change visual properties."
8329     "\n    Command is intended to control presentation quality depending on"
8330     "\n    hardware capabilities and performance.",
8331     __FILE__, VRenderParams, group);
8332   theCommands.Add("vfrustumculling",
8333     "vfrustumculling [toEnable]: enables/disables objects clipping",
8334     __FILE__,VFrustumCulling,group);
8335   theCommands.Add("vhighlightselected",
8336     "vhighlightselected [0|1] or vhighlightselected [on|off]: enables/disables highlighting of selected objects.\n"
8337     "Without arguments it shows if highlighting of selected objects is enabled now.",
8338     __FILE__,VHighlightSelected,group);
8339   theCommands.Add ("vplace",
8340             "vplace dx dy"
8341     "\n\t\t: Places the point (in pixels) at the center of the window",
8342     __FILE__, VPlace, group);
8343   theCommands.Add("vxrotate",
8344     "vxrotate",
8345     __FILE__,VXRotate,group);
8346
8347 }