0030119: Visualization, OpenGl_ShaderManager - implement mechanism generating in...
[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
19 #include <AIS_Animation.hxx>
20 #include <AIS_AnimationCamera.hxx>
21 #include <AIS_AnimationObject.hxx>
22 #include <AIS_ColorScale.hxx>
23 #include <AIS_Manipulator.hxx>
24 #include <AIS_RubberBand.hxx>
25 #include <AIS_Shape.hxx>
26 #include <AIS_InteractiveObject.hxx>
27 #include <AIS_ListOfInteractive.hxx>
28 #include <AIS_ListIteratorOfListOfInteractive.hxx>
29 #include <Aspect_Grid.hxx>
30 #include <DBRep.hxx>
31 #include <Draw_ProgressIndicator.hxx>
32 #include <Graphic3d_ArrayOfPolylines.hxx>
33 #include <Graphic3d_AspectMarker3d.hxx>
34 #include <Graphic3d_NameOfTextureEnv.hxx>
35 #include <Graphic3d_GraduatedTrihedron.hxx>
36 #include <Graphic3d_TextureEnv.hxx>
37 #include <Graphic3d_TextureParams.hxx>
38 #include <Graphic3d_TypeOfTextureFilter.hxx>
39 #include <Graphic3d_AspectFillArea3d.hxx>
40 #include <ViewerTest.hxx>
41 #include <ViewerTest_AutoUpdater.hxx>
42 #include <ViewerTest_EventManager.hxx>
43 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
44 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
45 #include <ViewerTest_CmdParser.hxx>
46 #include <V3d_AmbientLight.hxx>
47 #include <V3d_DirectionalLight.hxx>
48 #include <V3d_PositionalLight.hxx>
49 #include <V3d_SpotLight.hxx>
50 #include <Message_ProgressSentry.hxx>
51 #include <NCollection_DoubleMap.hxx>
52 #include <NCollection_List.hxx>
53 #include <NCollection_Vector.hxx>
54 #include <AIS_InteractiveContext.hxx>
55 #include <Draw_Interpretor.hxx>
56 #include <Draw.hxx>
57 #include <Draw_Appli.hxx>
58 #include <Image_AlienPixMap.hxx>
59 #include <Image_VideoRecorder.hxx>
60 #include <OpenGl_GraphicDriver.hxx>
61 #include <OSD_Timer.hxx>
62 #include <TColStd_HSequenceOfAsciiString.hxx>
63 #include <TColStd_SequenceOfInteger.hxx>
64 #include <TColStd_HSequenceOfReal.hxx>
65 #include <TColgp_Array1OfPnt2d.hxx>
66 #include <TColStd_MapOfAsciiString.hxx>
67 #include <Aspect_TypeOfLine.hxx>
68 #include <Image_Diff.hxx>
69 #include <Aspect_DisplayConnection.hxx>
70 #include <gp_Pnt.hxx>
71 #include <gp_Dir.hxx>
72 #include <gp_Pln.hxx>
73 #include <PrsMgr_PresentableObject.hxx>
74 #include <Graphic3d_ClipPlane.hxx>
75 #include <NCollection_DataMap.hxx>
76 #include <Graphic3d_Texture2Dmanual.hxx>
77 #include <Prs3d_ShadingAspect.hxx>
78 #include <Prs3d_Drawer.hxx>
79 #include <Prs3d_LineAspect.hxx>
80 #include <Prs3d_Root.hxx>
81 #include <Prs3d_Text.hxx>
82 #include <Select3D_SensitivePrimitiveArray.hxx>
83
84 #ifdef _WIN32
85 #undef DrawText
86 #endif
87
88 #include <cstdlib>
89
90 #if defined(_WIN32)
91   #include <WNT_WClass.hxx>
92   #include <WNT_Window.hxx>
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 // Auxiliary definitions
103 static const char THE_KEY_DELETE = 127;
104 static const char THE_KEY_ESCAPE = 27;
105
106 //==============================================================================
107 //  VIEWER GLOBAL VARIABLES
108 //==============================================================================
109
110 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
111 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
112
113 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
114 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
115
116 extern int VErase (Draw_Interpretor& theDI,
117                    Standard_Integer  theArgNb,
118                    const char**      theArgVec);
119
120 #if defined(_WIN32)
121 static Handle(WNT_Window)& VT_GetWindow() {
122   static Handle(WNT_Window) WNTWin;
123   return WNTWin;
124 }
125 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
126 static Handle(Cocoa_Window)& VT_GetWindow()
127 {
128   static Handle(Cocoa_Window) aWindow;
129   return aWindow;
130 }
131 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
132 extern void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle);
133 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
134
135 #else
136 static Handle(Xw_Window)& VT_GetWindow(){
137   static Handle(Xw_Window) XWWin;
138   return XWWin;
139 }
140
141 static void VProcessEvents(ClientData,int);
142 #endif
143
144 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
145 {
146   static Handle(Aspect_DisplayConnection) aDisplayConnection;
147   return aDisplayConnection;
148 }
149
150 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
151 {
152   GetDisplayConnection() = theDisplayConnection;
153 }
154
155 #if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
156 Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow)
157 {
158   Aspect_Handle aWindowHandle = (Aspect_Handle)NULL;
159 #if defined(_WIN32)
160   const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow);
161   if (!aWindow.IsNull())
162     return aWindow->HWindow();
163 #elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
164   const Handle (Xw_Window) aWindow = Handle(Xw_Window)::DownCast (theWindow);
165   if (!aWindow.IsNull())
166   return aWindow->XWindow();
167 #endif
168   return aWindowHandle;
169 }
170 #endif
171
172 //! Setting additional flag to store 2D mode of the View to avoid scene rotation by mouse/key events
173 class ViewerTest_V3dView : public V3d_View
174 {
175   DEFINE_STANDARD_RTTI_INLINE(ViewerTest_V3dView, V3d_View)
176 public:
177   //! Initializes the view.
178   ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType = V3d_ORTHOGRAPHIC,
179                       bool theIs2dMode = false)
180   : V3d_View (theViewer, theType), myIs2dMode (theIs2dMode) {}
181
182   //! Initializes the view by copying.
183   ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
184   : V3d_View (theViewer, theView), myIs2dMode (false)
185   {
186     if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (theView))
187     {
188       myIs2dMode = aV3dView->IsViewIn2DMode();
189     }
190   }
191
192   //! Returns true if 2D mode is set for the view
193   bool IsViewIn2DMode() const { return myIs2dMode; }
194
195   //! Sets 2D mode for the view
196   void SetView2DMode (bool the2dMode) { myIs2dMode = the2dMode; }
197
198 public:
199
200   //! Returns true if active view in 2D mode.
201   static bool IsCurrentViewIn2DMode()
202   {
203     if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
204     {
205       return aV3dView->IsViewIn2DMode();
206     }
207     return false;
208   }
209
210   //! Set if active view in 2D mode.
211   static void SetCurrentView2DMode (bool theIs2d)
212   {
213     if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
214     {
215       aV3dView->SetView2DMode (theIs2d);
216     }
217   }
218
219 private:
220
221   Standard_Boolean myIs2dMode; //!< 2D mode flag
222
223 };
224
225 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
226 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>  ViewerTest_myContexts;
227 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
228 static OpenGl_Caps ViewerTest_myDefaultCaps;
229
230 static void OSWindowSetup();
231
232 static struct
233 {
234   Quantity_Color FlatColor;
235   Quantity_Color GradientColor1;
236   Quantity_Color GradientColor2;
237   Aspect_GradientFillMethod FillMethod;
238 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
239
240 //==============================================================================
241 //  EVENT GLOBAL VARIABLES
242 //==============================================================================
243
244 static int Start_Rot = 0;
245 Standard_Boolean HasHlrOnBeforeRotation = Standard_False;
246 int X_Motion = 0; // Current cursor position
247 int Y_Motion = 0;
248 int X_ButtonPress = 0; // Last ButtonPress position
249 int Y_ButtonPress = 0;
250 Standard_Boolean IsDragged = Standard_False;
251 Standard_Boolean DragFirst = Standard_False;
252 Standard_Boolean TheIsAnimating = Standard_False;
253 Standard_Boolean Draw_ToExitOnCloseView = Standard_False;
254 Standard_Boolean Draw_ToCloseViewOnEsc  = Standard_False;
255
256
257 Standard_EXPORT const Handle(AIS_RubberBand)& GetRubberBand()
258 {
259   static Handle(AIS_RubberBand) aBand;
260   if (aBand.IsNull())
261   {
262     aBand = new AIS_RubberBand (Quantity_NOC_LIGHTBLUE, Aspect_TOL_SOLID, Quantity_NOC_LIGHTBLUE, 0.4, 1.0);
263     aBand->SetDisplayMode (0);
264   }
265   return aBand;
266 }
267
268 typedef NCollection_Map<AIS_Manipulator*> ViewerTest_MapOfAISManipulators;
269
270 Standard_EXPORT ViewerTest_MapOfAISManipulators& GetMapOfAISManipulators()
271 {
272   static ViewerTest_MapOfAISManipulators aMap;
273   return aMap;
274 }
275
276 Standard_EXPORT Handle(AIS_Manipulator) GetActiveAISManipulator()
277 {
278   ViewerTest_MapOfAISManipulators::Iterator anIt (GetMapOfAISManipulators());
279   for (; anIt.More(); anIt.Next())
280   {
281     if (anIt.Value()->HasActiveMode())
282     {
283       return anIt.Value();
284     }
285   }
286   return NULL;
287 }
288
289 //==============================================================================
290
291 #ifdef _WIN32
292 static LRESULT WINAPI ViewerWindowProc(
293                                        HWND hwnd,
294                                        UINT uMsg,
295                                        WPARAM wParam,
296                                        LPARAM lParam );
297 static LRESULT WINAPI AdvViewerWindowProc(
298   HWND hwnd,
299   UINT uMsg,
300   WPARAM wParam,
301   LPARAM lParam );
302 #endif
303
304
305 //==============================================================================
306 //function : WClass
307 //purpose  :
308 //==============================================================================
309
310 const Handle(Standard_Transient)& ViewerTest::WClass()
311 {
312   static Handle(Standard_Transient) theWClass;
313 #if defined(_WIN32)
314   if (theWClass.IsNull())
315   {
316     theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
317                                 CS_VREDRAW | CS_HREDRAW, 0, 0,
318                                 ::LoadCursor (NULL, IDC_ARROW));
319   }
320 #endif
321   return theWClass;
322 }
323
324 //==============================================================================
325 //function : CreateName
326 //purpose  : Create numerical name for new object in theMap
327 //==============================================================================
328 template <typename ObjectType>
329 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
330                                     const TCollection_AsciiString& theDefaultString)
331 {
332   if (theObjectMap.IsEmpty())
333     return theDefaultString + TCollection_AsciiString(1);
334
335   Standard_Integer aNextKey = 1;
336   Standard_Boolean isFound = Standard_False;
337   while (!isFound)
338   {
339     TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
340     // Look for objects with default names
341     if (theObjectMap.IsBound1(aStringKey))
342     {
343       aNextKey++;
344     }
345     else
346       isFound = Standard_True;
347   }
348
349   return theDefaultString + TCollection_AsciiString(aNextKey);
350 }
351
352 //==============================================================================
353 //structure : ViewerTest_Names
354 //purpose   : Allow to operate with full view name: driverName/viewerName/viewName
355 //==============================================================================
356 struct ViewerTest_Names
357 {
358 private:
359   TCollection_AsciiString myDriverName;
360   TCollection_AsciiString myViewerName;
361   TCollection_AsciiString myViewName;
362
363 public:
364
365   const TCollection_AsciiString& GetDriverName () const
366   {
367     return myDriverName;
368   }
369   void SetDriverName (const TCollection_AsciiString& theDriverName)
370   {
371     myDriverName = theDriverName;
372   }
373   const TCollection_AsciiString& GetViewerName () const
374   {
375     return myViewerName;
376   }
377   void SetViewerName (const TCollection_AsciiString& theViewerName)
378   {
379     myViewerName = theViewerName;
380   }
381   const TCollection_AsciiString& GetViewName () const
382   {
383     return myViewName;
384   }
385   void SetViewName (const TCollection_AsciiString& theViewName)
386   {
387     myViewName = theViewName;
388   }
389
390   //===========================================================================
391   //function : Constructor for ViewerTest_Names
392   //purpose  : Get view, viewer, driver names from custom string
393   //===========================================================================
394
395   ViewerTest_Names (const TCollection_AsciiString& theInputString)
396   {
397     TCollection_AsciiString aName(theInputString);
398     if (theInputString.IsEmpty())
399     {
400       // Get current configuration
401       if (ViewerTest_myDrivers.IsEmpty())
402         myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
403           (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
404       else
405         myDriverName = ViewerTest_myDrivers.Find2
406         (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
407
408       if(ViewerTest_myContexts.IsEmpty())
409       {
410         myViewerName = CreateName <Handle(AIS_InteractiveContext)>
411           (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
412       }
413       else
414       {
415         myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
416       }
417
418       myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
419     }
420     else
421     {
422       // There is at least view name
423       Standard_Integer aParserNumber = 0;
424       for (Standard_Integer i = 0; i < 3; ++i)
425       {
426         Standard_Integer aParserPos = aName.SearchFromEnd("/");
427         if(aParserPos != -1)
428         {
429           aParserNumber++;
430           aName.Split(aParserPos-1);
431         }
432         else
433           break;
434       }
435       if (aParserNumber == 0)
436       {
437         // Only view name
438         if (!ViewerTest::GetAISContext().IsNull())
439         {
440           myDriverName = ViewerTest_myDrivers.Find2
441           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
442           myViewerName = ViewerTest_myContexts.Find2
443           (ViewerTest::GetAISContext());
444         }
445         else
446         {
447           // There is no opened contexts here, need to create names for viewer and driver
448           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
449             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
450
451           myViewerName = CreateName <Handle(AIS_InteractiveContext)>
452             (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
453         }
454         myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
455       }
456       else if (aParserNumber == 1)
457       {
458         // Here is viewerName/viewName
459         if (!ViewerTest::GetAISContext().IsNull())
460           myDriverName = ViewerTest_myDrivers.Find2
461           (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
462         else
463         {
464           // There is no opened contexts here, need to create name for driver
465           myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
466             (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
467         }
468         myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
469
470         myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
471       }
472       else
473       {
474         //Here is driverName/viewerName/viewName
475         myDriverName = TCollection_AsciiString(aName);
476
477         TCollection_AsciiString aViewerName(theInputString);
478         aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
479         myViewerName = TCollection_AsciiString(aViewerName);
480
481         myViewName = TCollection_AsciiString(theInputString);
482       }
483     }
484   }
485 };
486
487 //==============================================================================
488 //function : FindContextByView
489 //purpose  : Find AIS_InteractiveContext by View
490 //==============================================================================
491
492 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
493 {
494   Handle(AIS_InteractiveContext) anAISContext;
495
496   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
497        anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
498   {
499     if (anIter.Value()->CurrentViewer() == theView->Viewer())
500        return anIter.Key2();
501   }
502   return anAISContext;
503 }
504
505
506 //==============================================================================
507 //function : SetWindowTitle
508 //purpose  : Set window title
509 //==============================================================================
510
511 void SetWindowTitle (const Handle(Aspect_Window)& theWindow,
512                      Standard_CString theTitle)
513 {
514 #if defined(_WIN32)
515   const TCollection_ExtendedString theTitleW (theTitle);
516   SetWindowTextW ((HWND )Handle(WNT_Window)::DownCast(theWindow)->HWindow(), theTitleW.ToWideString());
517 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
518   SetCocoaWindowTitle (Handle(Cocoa_Window)::DownCast(theWindow), theTitle);
519 #else
520   if(GetDisplayConnection()->GetDisplay())
521   {
522     Window aWindow =
523       Handle(Xw_Window)::DownCast(theWindow)->XWindow();
524     XStoreName (GetDisplayConnection()->GetDisplay(), aWindow , theTitle);
525   }
526 #endif
527 }
528
529 //==============================================================================
530 //function : IsWindowOverlapped
531 //purpose  : Check if theWindow overlapp another view
532 //==============================================================================
533
534 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
535                                      const Standard_Integer thePxTop,
536                                      const Standard_Integer thePxRight,
537                                      const Standard_Integer thePxBottom,
538                                      TCollection_AsciiString& theViewId)
539 {
540   for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
541       anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
542   {
543     Standard_Integer aTop = 0,
544       aLeft = 0,
545       aRight = 0,
546       aBottom = 0;
547     anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
548     if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
549         (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
550         (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
551         (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
552     {
553       theViewId = anIter.Key1();
554       return Standard_True;
555     }
556   }
557   return Standard_False;
558 }
559
560 // Workaround: to create and delete non-orthographic views outside ViewerTest
561 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
562 {
563   ViewerTest_myViews.UnBind1 (theName);
564 }
565
566 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
567                                const Handle(V3d_View)& theView)
568 {
569   ViewerTest_myViews.Bind (theName, theView);
570 }
571
572 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
573 {
574   return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
575 }
576 //==============================================================================
577 //function : ViewerInit
578 //purpose  : Create the window viewer and initialize all the global variable
579 //==============================================================================
580
581 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
582                                                 const Standard_Integer thePxTop,
583                                                 const Standard_Integer thePxWidth,
584                                                 const Standard_Integer thePxHeight,
585                                                 const TCollection_AsciiString& theViewName,
586                                                 const TCollection_AsciiString& theDisplayName,
587                                                 const Handle(V3d_View)& theViewToClone)
588 {
589   // Default position and dimension of the viewer window.
590   // Note that left top corner is set to be sufficiently small to have
591   // window fit in the small screens (actual for remote desktops, see #23003).
592   // The position corresponds to the window's client area, thus some
593   // gap is added for window frame to be visible.
594   Standard_Integer aPxLeft   = 20;
595   Standard_Integer aPxTop    = 40;
596   Standard_Integer aPxWidth  = 409;
597   Standard_Integer aPxHeight = 409;
598   Standard_Boolean toCreateViewer = Standard_False;
599   if (!theViewToClone.IsNull())
600   {
601     theViewToClone->Window()->Size (aPxWidth, aPxHeight);
602   }
603
604   Handle(OpenGl_GraphicDriver) aGraphicDriver;
605   ViewerTest_Names aViewNames(theViewName);
606   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
607     aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
608
609   if (thePxLeft != 0)
610     aPxLeft = thePxLeft;
611   if (thePxTop != 0)
612     aPxTop = thePxTop;
613   if (thePxWidth != 0)
614     aPxWidth = thePxWidth;
615   if (thePxHeight != 0)
616     aPxHeight = thePxHeight;
617
618   // Get graphic driver (create it or get from another view)
619   if (!ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName()))
620   {
621     // Get connection string
622   #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
623     TCollection_AsciiString aDisplayName(theDisplayName);
624     if (!aDisplayName.IsEmpty())
625       SetDisplayConnection (new Aspect_DisplayConnection ());
626     else
627       SetDisplayConnection (new Aspect_DisplayConnection (aDisplayName));
628   #else
629     (void)theDisplayName; // avoid warning on unused argument
630     SetDisplayConnection (new Aspect_DisplayConnection ());
631   #endif
632
633     if (Draw_VirtualWindows)
634     {
635       // don't waste the time waiting for VSync when window is not displayed on the screen
636       ViewerTest_myDefaultCaps.swapInterval = 0;
637       // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
638       //ViewerTest_myDefaultCaps.buffersNoSwap = true;
639     }
640     aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
641     aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
642
643     ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
644     toCreateViewer = Standard_True;
645   }
646   else
647   {
648     aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
649   }
650
651   //Dispose the window if input parameters are default
652   if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
653   {
654     Standard_Integer aTop = 0,
655                      aLeft = 0,
656                      aRight = 0,
657                      aBottom = 0,
658                      aScreenWidth = 0,
659                      aScreenHeight = 0;
660
661     // Get screen resolution
662 #if defined(_WIN32) || defined(__WIN32__)
663     RECT aWindowSize;
664     GetClientRect(GetDesktopWindow(), &aWindowSize);
665     aScreenHeight = aWindowSize.bottom;
666     aScreenWidth = aWindowSize.right;
667 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
668     GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
669 #else
670     Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
671     aScreenWidth = WidthOfScreen(aScreen);
672     aScreenHeight = HeightOfScreen(aScreen);
673 #endif
674
675     TCollection_AsciiString anOverlappedViewId("");
676
677     while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
678     {
679       ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
680
681       if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
682         && aRight + 2*aPxWidth + 40 > aScreenWidth)
683       {
684         if (aBottom + aPxHeight + 40 > aScreenHeight)
685         {
686           aPxLeft = 20;
687           aPxTop = 40;
688           break;
689         }
690         aPxLeft = 20;
691         aPxTop = aBottom + 40;
692       }
693       else
694         aPxLeft = aRight + 20;
695     }
696   }
697
698   // Get viewer name
699   TCollection_AsciiString aTitle("3D View - ");
700   aTitle = aTitle + aViewNames.GetViewName() + "(*)";
701
702   // Change name of current active window
703   if (!ViewerTest::CurrentView().IsNull())
704   {
705     TCollection_AsciiString anActiveWindowTitle("3D View - ");
706     anActiveWindowTitle = anActiveWindowTitle
707       + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
708     SetWindowTitle (ViewerTest::CurrentView()->Window(), anActiveWindowTitle.ToCString());
709   }
710
711   // Create viewer
712   Handle(V3d_Viewer) a3DViewer;
713   // If it's the single view, we first look for empty context
714   if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
715   {
716     NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
717       anIter(ViewerTest_myContexts);
718     if (anIter.More())
719       ViewerTest::SetAISContext (anIter.Value());
720     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
721   }
722   else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
723   {
724     ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
725     a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
726   }
727   else if (a3DViewer.IsNull())
728   {
729     toCreateViewer = Standard_True;
730     a3DViewer = new V3d_Viewer(aGraphicDriver);
731     a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
732     a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
733                                            ViewerTest_DefaultBackground.GradientColor2,
734                                            ViewerTest_DefaultBackground.FillMethod);
735   }
736
737   // AIS context setup
738   if (ViewerTest::GetAISContext().IsNull() ||
739       !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
740   {
741     Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
742     ViewerTest::SetAISContext (aContext);
743     ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
744   }
745   else
746   {
747     ViewerTest::ResetEventManager();
748   }
749
750   // Create window
751 #if defined(_WIN32)
752   VT_GetWindow() = new WNT_Window (aTitle.ToCString(),
753                                     Handle(WNT_WClass)::DownCast (WClass()),
754                                     Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
755                                     aPxLeft, aPxTop,
756                                     aPxWidth, aPxHeight,
757                                     Quantity_NOC_BLACK);
758 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
759   VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
760                                      aPxLeft, aPxTop,
761                                      aPxWidth, aPxHeight);
762   ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
763 #else
764   VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
765                                   aTitle.ToCString(),
766                                   aPxLeft, aPxTop,
767                                   aPxWidth, aPxHeight);
768 #endif
769   VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
770
771   // View setup
772   Handle(V3d_View) aView;
773   if (!theViewToClone.IsNull())
774   {
775     aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
776   }
777   else
778   {
779     aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
780   }
781
782   aView->SetWindow (VT_GetWindow());
783   ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
784
785   ViewerTest::CurrentView(aView);
786   ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
787
788   // Setup for X11 or NT
789   OSWindowSetup();
790
791   // Set parameters for V3d_View and V3d_Viewer
792   const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
793   aV3dView->SetComputedMode(Standard_False);
794
795   a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
796   if (toCreateViewer)
797   {
798     a3DViewer->SetDefaultLights();
799     a3DViewer->SetLightOn();
800   }
801
802   #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
803   #if TCL_MAJOR_VERSION  < 8
804   Tk_CreateFileHandler((void*)XConnectionNumber(GetDisplayConnection()->GetDisplay()),
805       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
806   #else
807   Tk_CreateFileHandler(XConnectionNumber(GetDisplayConnection()->GetDisplay()),
808       TK_READABLE, VProcessEvents, (ClientData) VT_GetWindow()->XWindow() );
809   #endif
810   #endif
811
812   VT_GetWindow()->Map();
813
814   // Set the handle of created view in the event manager
815   ViewerTest::ResetEventManager();
816
817   ViewerTest::CurrentView()->Redraw();
818
819   aView.Nullify();
820   a3DViewer.Nullify();
821
822   return aViewNames.GetViewName();
823 }
824
825 //==============================================================================
826 //function : RedrawAllViews
827 //purpose  : Redraw all created views
828 //==============================================================================
829 void ViewerTest::RedrawAllViews()
830 {
831   NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
832   for (; aViewIt.More(); aViewIt.Next())
833   {
834     const Handle(V3d_View)& aView = aViewIt.Key2();
835     aView->Redraw();
836   }
837 }
838
839 //==============================================================================
840 //function : Vinit
841 //purpose  : Create the window viewer and initialize all the global variable
842 //    Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
843 //==============================================================================
844
845 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
846 {
847   TCollection_AsciiString aViewName, aDisplayName;
848   Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
849   Handle(V3d_View) aCopyFrom;
850   TCollection_AsciiString aName, aValue;
851   int is2dMode = -1;
852   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
853   {
854     const TCollection_AsciiString anArg = theArgVec[anArgIt];
855     TCollection_AsciiString anArgCase = anArg;
856     anArgCase.LowerCase();
857     if (anArgIt + 1 < theArgsNb
858      && anArgCase == "-name")
859     {
860       aViewName = theArgVec[++anArgIt];
861     }
862     else if (anArgIt + 1 < theArgsNb
863           && (anArgCase == "-left"
864            || anArgCase == "-l"))
865     {
866       aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
867     }
868     else if (anArgIt + 1 < theArgsNb
869           && (anArgCase == "-top"
870            || anArgCase == "-t"))
871     {
872       aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
873     }
874     else if (anArgIt + 1 < theArgsNb
875           && (anArgCase == "-width"
876            || anArgCase == "-w"))
877     {
878       aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
879     }
880     else if (anArgIt + 1 < theArgsNb
881           && (anArgCase == "-height"
882            || anArgCase == "-h"))
883     {
884       aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
885     }
886     else if (anArgCase == "-exitonclose")
887     {
888       Draw_ToExitOnCloseView = true;
889       if (anArgIt + 1 < theArgsNb
890        && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToExitOnCloseView))
891       {
892         ++anArgIt;
893       }
894     }
895     else if (anArgCase == "-closeonescape"
896           || anArgCase == "-closeonesc")
897     {
898       Draw_ToCloseViewOnEsc = true;
899       if (anArgIt + 1 < theArgsNb
900        && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToCloseViewOnEsc))
901       {
902         ++anArgIt;
903       }
904     }
905     else if (anArgCase == "-2d_mode"
906           || anArgCase == "-2dmode"
907           || anArgCase == "-2d")
908     {
909       bool toEnable = true;
910       if (anArgIt + 1 < theArgsNb
911        && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
912       {
913         ++anArgIt;
914       }
915       is2dMode = toEnable ? 1 : 0;
916     }
917     else if (anArgIt + 1 < theArgsNb
918           && (anArgCase == "-disp"
919            || anArgCase == "-display"))
920     {
921       aDisplayName = theArgVec[++anArgIt];
922     }
923     else if (!ViewerTest::CurrentView().IsNull()
924           &&  aCopyFrom.IsNull()
925           && (anArgCase == "-copy"
926            || anArgCase == "-clone"
927            || anArgCase == "-cloneactive"
928            || anArgCase == "-cloneactiveview"))
929     {
930       aCopyFrom = ViewerTest::CurrentView();
931     }
932     // old syntax
933     else if (ViewerTest::SplitParameter (anArg, aName, aValue))
934     {
935       aName.LowerCase();
936       if (aName == "name")
937       {
938         aViewName = aValue;
939       }
940       else if (aName == "l"
941             || aName == "left")
942       {
943         aPxLeft = aValue.IntegerValue();
944       }
945       else if (aName == "t"
946             || aName == "top")
947       {
948         aPxTop = aValue.IntegerValue();
949       }
950       else if (aName == "disp"
951             || aName == "display")
952       {
953         aDisplayName = aValue;
954       }
955       else if (aName == "w"
956             || aName == "width")
957       {
958         aPxWidth = aValue.IntegerValue();
959       }
960       else if (aName == "h"
961             || aName == "height")
962       {
963         aPxHeight = aValue.IntegerValue();
964       }
965       else
966       {
967         std::cout << "Syntax error: unknown argument " << anArg << ".\n";
968         return 1;
969       }
970     }
971     else if (aViewName.IsEmpty())
972     {
973       aViewName = anArg;
974     }
975     else
976     {
977       std::cout << "Syntax error: unknown argument " << anArg << ".\n";
978       return 1;
979     }
980   }
981
982 #if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
983   if (!aDisplayName.IsEmpty())
984   {
985     aDisplayName.Clear();
986     std::cout << "Warning: display parameter will be ignored.\n";
987   }
988 #endif
989
990   ViewerTest_Names aViewNames (aViewName);
991   if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
992   {
993     TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
994     theDi.Eval (aCommand.ToCString());
995     if (is2dMode != -1)
996     {
997       ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
998     }
999     return 0;
1000   }
1001
1002   TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
1003                                                             aViewName, aDisplayName, aCopyFrom);
1004   if (is2dMode != -1)
1005   {
1006     ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1007   }
1008   theDi << aViewId;
1009   return 0;
1010 }
1011
1012 //! Parse HLR algo type.
1013 static Standard_Boolean parseHlrAlgoType (const char* theName,
1014                                           Prs3d_TypeOfHLR& theType)
1015 {
1016   TCollection_AsciiString aName (theName);
1017   aName.LowerCase();
1018   if (aName == "polyalgo")
1019   {
1020     theType = Prs3d_TOH_PolyAlgo;
1021   }
1022   else if (aName == "algo")
1023   {
1024     theType = Prs3d_TOH_Algo;
1025   }
1026   else
1027   {
1028     return Standard_False;
1029   }
1030   return Standard_True;
1031 }
1032
1033 //==============================================================================
1034 //function : VHLR
1035 //purpose  : hidden lines removal algorithm
1036 //==============================================================================
1037
1038 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1039 {
1040   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1041   const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1042   if (aView.IsNull())
1043   {
1044     std::cerr << "Error: No opened viewer!\n";
1045     return 1;
1046   }
1047
1048   Standard_Boolean hasHlrOnArg = Standard_False;
1049   Standard_Boolean hasShowHiddenArg = Standard_False;
1050   Standard_Boolean isHLROn = Standard_False;
1051   Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
1052   Prs3d_TypeOfHLR  aTypeOfHLR = Prs3d_TOH_NotSet;
1053   ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1054   for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1055   {
1056     TCollection_AsciiString anArg (argv[anArgIter]);
1057     anArg.LowerCase();
1058     if (anUpdateTool.parseRedrawMode (anArg))
1059     {
1060       continue;
1061     }
1062     else if (anArg == "-showhidden"
1063           && anArgIter + 1 < argc
1064           && ViewerTest::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1065     {
1066       ++anArgIter;
1067       hasShowHiddenArg = Standard_True;
1068       continue;
1069     }
1070     else if ((anArg == "-type"
1071            || anArg == "-algo"
1072            || anArg == "-algotype")
1073           && anArgIter + 1 < argc
1074           && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1075     {
1076       ++anArgIter;
1077       continue;
1078     }
1079     else if (!hasHlrOnArg
1080           && ViewerTest::ParseOnOff (argv[anArgIter], isHLROn))
1081     {
1082       hasHlrOnArg = Standard_True;
1083       continue;
1084     }
1085     // old syntax
1086     else if (!hasShowHiddenArg
1087           && ViewerTest::ParseOnOff(argv[anArgIter], toShowHidden))
1088     {
1089       hasShowHiddenArg = Standard_True;
1090       continue;
1091     }
1092     else
1093     {
1094       std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
1095       return 1;
1096     }
1097   }
1098   if (!hasHlrOnArg)
1099   {
1100     di << "HLR:        " << aView->ComputedMode() << "\n";
1101     di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
1102     di << "HlrAlgo:    ";
1103     switch (aCtx->DefaultDrawer()->TypeOfHLR())
1104     {
1105       case Prs3d_TOH_NotSet:   di << "NotSet\n";   break;
1106       case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
1107       case Prs3d_TOH_Algo:     di << "Algo\n";     break;
1108     }
1109     anUpdateTool.Invalidate();
1110     return 0;
1111   }
1112
1113   Standard_Boolean toRecompute = Standard_False;
1114   if (aTypeOfHLR != Prs3d_TOH_NotSet
1115    && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
1116   {
1117     toRecompute = Standard_True;
1118     aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1119   }
1120   if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
1121   {
1122     toRecompute = Standard_True;
1123     if (toShowHidden)
1124     {
1125       aCtx->DefaultDrawer()->EnableDrawHiddenLine();
1126     }
1127     else
1128     {
1129       aCtx->DefaultDrawer()->DisableDrawHiddenLine();
1130     }
1131   }
1132
1133   // redisplay shapes
1134   if (aView->ComputedMode() && isHLROn && toRecompute)
1135   {
1136     AIS_ListOfInteractive aListOfShapes;
1137     aCtx->DisplayedObjects (aListOfShapes);
1138     for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
1139     {
1140       if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
1141       {
1142         aCtx->Redisplay (aShape, Standard_False);
1143       }
1144     }
1145   }
1146
1147   aView->SetComputedMode (isHLROn);
1148   return 0;
1149 }
1150
1151 //==============================================================================
1152 //function : VHLRType
1153 //purpose  : change type of using HLR algorithm
1154 //==============================================================================
1155
1156 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1157 {
1158   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1159   const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1160   if (aView.IsNull())
1161   {
1162     std::cerr << "Error: No opened viewer!\n";
1163     return 1;
1164   }
1165
1166   Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1167   ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1168   AIS_ListOfInteractive aListOfShapes;
1169   for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1170   {
1171     TCollection_AsciiString anArg (argv[anArgIter]);
1172     anArg.LowerCase();
1173     if (anUpdateTool.parseRedrawMode (anArg))
1174     {
1175       continue;
1176     }
1177     else if ((anArg == "-type"
1178            || anArg == "-algo"
1179            || anArg == "-algotype")
1180           && anArgIter + 1 < argc
1181           && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1182     {
1183       ++anArgIter;
1184       continue;
1185     }
1186     // old syntax
1187     else if (aTypeOfHLR == Prs3d_TOH_NotSet
1188           && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
1189     {
1190       continue;
1191     }
1192     else
1193     {
1194       ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1195       TCollection_AsciiString aName (argv[anArgIter]);
1196       if (!aMap.IsBound2 (aName))
1197       {
1198         std::cout << "Syntax error: Wrong shape name '" << aName << "'.\n";
1199         return 1;
1200       }
1201
1202       Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
1203       if (aShape.IsNull())
1204       {
1205         std::cout << "Syntax error: '" << aName << "' is not a shape presentation.\n";
1206         return 1;
1207       }
1208       aListOfShapes.Append (aShape);
1209       continue;
1210     }
1211   }
1212   if (aTypeOfHLR == Prs3d_TOH_NotSet)
1213   {
1214     std::cout << "Syntax error: wrong number of arguments!\n";
1215     return 1;
1216   }
1217
1218   const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
1219   if (isGlobal)
1220   {
1221     aCtx->DisplayedObjects (aListOfShapes);
1222     aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1223   }
1224
1225   for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
1226   {
1227     Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1228     if (aShape.IsNull())
1229     {
1230       continue;
1231     }
1232
1233     const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
1234                             && aView->ComputedMode();
1235     if (!isGlobal
1236      || aShape->TypeOfHLR() != aTypeOfHLR)
1237     {
1238       aShape->SetTypeOfHLR (aTypeOfHLR);
1239     }
1240     if (toUpdateShape)
1241     {
1242       aCtx->Redisplay (aShape, Standard_False);
1243     }
1244   }
1245   return 0;
1246 }
1247
1248 //==============================================================================
1249 //function : FindViewIdByWindowHandle
1250 //purpose  : Find theView Id in the map of views by window handle
1251 //==============================================================================
1252 #if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1253 TCollection_AsciiString FindViewIdByWindowHandle(const Aspect_Handle theWindowHandle)
1254 {
1255   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
1256        anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1257   {
1258     Aspect_Handle aWindowHandle = GetWindowHandle(anIter.Value()->Window());
1259     if (aWindowHandle == theWindowHandle)
1260       return anIter.Key1();
1261   }
1262   return TCollection_AsciiString("");
1263 }
1264 #endif
1265
1266 //==============================================================================
1267 //function : ActivateView
1268 //purpose  : Make the view active
1269 //==============================================================================
1270
1271 void ActivateView (const TCollection_AsciiString& theViewName)
1272 {
1273   const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1274   if (!aView.IsNull())
1275   {
1276     Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
1277     if (!anAISContext.IsNull())
1278     {
1279       if (!ViewerTest::CurrentView().IsNull())
1280       {
1281         TCollection_AsciiString aTitle("3D View - ");
1282         aTitle = aTitle + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
1283         SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1284       }
1285
1286       ViewerTest::CurrentView (aView);
1287       ViewerTest::SetAISContext (anAISContext);
1288       TCollection_AsciiString aTitle = TCollection_AsciiString("3D View - ") + theViewName + "(*)";
1289       SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1290 #if defined(_WIN32)
1291       VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
1292 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1293       VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
1294 #else
1295       VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
1296 #endif
1297       SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1298       ViewerTest::CurrentView()->Redraw();
1299     }
1300   }
1301 }
1302
1303 //==============================================================================
1304 //function : RemoveView
1305 //purpose  :
1306 //==============================================================================
1307 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
1308                              const Standard_Boolean  theToRemoveContext)
1309 {
1310   if (!ViewerTest_myViews.IsBound2 (theView))
1311   {
1312     return;
1313   }
1314
1315   const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
1316   RemoveView (aViewName, theToRemoveContext);
1317 }
1318
1319 //==============================================================================
1320 //function : RemoveView
1321 //purpose  : Close and remove view from display, clear maps if neccessary
1322 //==============================================================================
1323 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
1324 {
1325   if (!ViewerTest_myViews.IsBound1(theViewName))
1326   {
1327     cout << "Wrong view name\n";
1328     return;
1329   }
1330
1331   // Activate another view if it's active now
1332   if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
1333   {
1334     if (ViewerTest_myViews.Extent() > 1)
1335     {
1336       TCollection_AsciiString aNewViewName;
1337       for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1338            anIter.More(); anIter.Next())
1339       {
1340         if (anIter.Key1() != theViewName)
1341         {
1342           aNewViewName = anIter.Key1();
1343           break;
1344         }
1345       }
1346       ActivateView (aNewViewName);
1347     }
1348     else
1349     {
1350       Handle(V3d_View) anEmptyView;
1351 #if defined(_WIN32) || defined(__WIN32__)
1352       Handle(WNT_Window) anEmptyWindow;
1353 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1354       Handle(Cocoa_Window) anEmptyWindow;
1355 #else
1356       Handle(Xw_Window) anEmptyWindow;
1357 #endif
1358       VT_GetWindow() = anEmptyWindow;
1359       ViewerTest::CurrentView (anEmptyView);
1360       if (isContextRemoved)
1361       {
1362         Handle(AIS_InteractiveContext) anEmptyContext;
1363         ViewerTest::SetAISContext(anEmptyContext);
1364       }
1365     }
1366   }
1367
1368   // Delete view
1369   Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1370   Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1371
1372   // Remove view resources
1373   ViewerTest_myViews.UnBind1(theViewName);
1374   aView->Window()->Unmap();
1375   aView->Remove();
1376
1377 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1378   XFlush (GetDisplayConnection()->GetDisplay());
1379 #endif
1380
1381   // Keep context opened only if the closed view is last to avoid
1382   // unused empty contexts
1383   if (!aCurrentContext.IsNull())
1384   {
1385     // Check if there are more difined views in the viewer
1386     aCurrentContext->CurrentViewer()->InitDefinedViews();
1387     if ((isContextRemoved || ViewerTest_myContexts.Size() != 1) && !aCurrentContext->CurrentViewer()->MoreDefinedViews())
1388     {
1389       // Remove driver if there is no viewers that use it
1390       Standard_Boolean isRemoveDriver = Standard_True;
1391       for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1392           anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1393       {
1394         if (aCurrentContext != anIter.Key2() &&
1395           aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
1396         {
1397           isRemoveDriver = Standard_False;
1398           break;
1399         }
1400       }
1401
1402       aCurrentContext->RemoveAll (Standard_False);
1403       if(isRemoveDriver)
1404       {
1405         ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1406       #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1407         #if TCL_MAJOR_VERSION  < 8
1408         Tk_DeleteFileHandler((void*)XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1409         #else
1410         Tk_DeleteFileHandler(XConnectionNumber(aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
1411         #endif
1412       #endif
1413       }
1414
1415       ViewerTest_myContexts.UnBind2(aCurrentContext);
1416     }
1417   }
1418   cout << "3D View - " << theViewName << " was deleted.\n";
1419   if (Draw_ToExitOnCloseView)
1420   {
1421     Draw_Interprete ("exit");
1422   }
1423 }
1424
1425 //==============================================================================
1426 //function : VClose
1427 //purpose  : Remove the view defined by its name
1428 //==============================================================================
1429
1430 static int VClose (Draw_Interpretor& /*theDi*/,
1431                    Standard_Integer  theArgsNb,
1432                    const char**      theArgVec)
1433 {
1434   NCollection_List<TCollection_AsciiString> aViewList;
1435   if (theArgsNb > 1)
1436   {
1437     TCollection_AsciiString anArg (theArgVec[1]);
1438     anArg.UpperCase();
1439     if (anArg.IsEqual ("ALL")
1440      || anArg.IsEqual ("*"))
1441     {
1442       for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1443            anIter.More(); anIter.Next())
1444       {
1445         aViewList.Append (anIter.Key1());
1446       }
1447       if (aViewList.IsEmpty())
1448       {
1449         std::cout << "No view to close\n";
1450         return 0;
1451       }
1452     }
1453     else
1454     {
1455       ViewerTest_Names aViewName (theArgVec[1]);
1456       if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
1457       {
1458         std::cerr << "The view with name '" << theArgVec[1] << "' does not exist\n";
1459         return 1;
1460       }
1461       aViewList.Append (aViewName.GetViewName());
1462     }
1463   }
1464   else
1465   {
1466     // close active view
1467     if (ViewerTest::CurrentView().IsNull())
1468     {
1469       std::cerr << "No active view!\n";
1470       return 1;
1471     }
1472     aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1473   }
1474
1475   Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
1476   for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1477        anIter.More(); anIter.Next())
1478   {
1479     ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
1480   }
1481
1482   return 0;
1483 }
1484
1485 //==============================================================================
1486 //function : VActivate
1487 //purpose  : Activate the view defined by its ID
1488 //==============================================================================
1489
1490 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1491 {
1492   if (theArgsNb > 2)
1493   {
1494     theDi << theArgVec[0] << ": wrong number of command arguments.\n"
1495     << "Usage: " << theArgVec[0] << " ViewID\n";
1496     return 1;
1497   }
1498   if(theArgsNb == 1)
1499   {
1500     theDi.Eval("vviewlist");
1501     return 0;
1502   }
1503
1504   TCollection_AsciiString aNameString(theArgVec[1]);
1505   if ( strcasecmp( aNameString.ToCString(), "NONE" ) == 0 )
1506   {
1507     TCollection_AsciiString aTitle("3D View - ");
1508     aTitle = aTitle + ViewerTest_myViews.Find2(ViewerTest::CurrentView());
1509     SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1510     Handle(V3d_View) anEmptyView;
1511 #if defined(_WIN32) || defined(__WIN32__)
1512     Handle(WNT_Window) anEmptyWindow;
1513 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1514     Handle(Cocoa_Window) anEmptyWindow;
1515 #else
1516     Handle(Xw_Window) anEmptyWindow;
1517 #endif
1518     VT_GetWindow() = anEmptyWindow;
1519     ViewerTest::CurrentView (anEmptyView);
1520     ViewerTest::ResetEventManager();
1521     theDi << theArgVec[0] << ": all views are inactive\n";
1522     return 0;
1523   }
1524
1525   ViewerTest_Names aViewNames(aNameString);
1526
1527   // Check if this view exists in the viewer with the driver
1528   if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1529   {
1530     theDi << "Wrong view name\n";
1531     return 1;
1532   }
1533
1534   // Check if it is active already
1535   if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1536   {
1537     theDi << theArgVec[0] << ": the view is active already\n";
1538     return 0;
1539   }
1540
1541   ActivateView (aViewNames.GetViewName());
1542   return 0;
1543 }
1544
1545 //==============================================================================
1546 //function : VViewList
1547 //purpose  : Print current list of views per viewer and graphic driver ID
1548 //           shared between viewers
1549 //==============================================================================
1550
1551 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1552 {
1553   if (theArgsNb > 2)
1554   {
1555     theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1556           << "Usage: " << theArgVec[0] << " name";
1557     return 1;
1558   }
1559   if (ViewerTest_myContexts.Size() < 1)
1560     return 0;
1561
1562   Standard_Boolean isTreeView =
1563     (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1564
1565   if (isTreeView)
1566   {
1567     theDi << theArgVec[0] <<":\n";
1568   }
1569
1570   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
1571        aDriverIter.More(); aDriverIter.Next())
1572   {
1573     if (isTreeView)
1574       theDi << aDriverIter.Key1() << ":\n";
1575
1576     for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1577       aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1578     {
1579       if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1580       {
1581         if (isTreeView)
1582         {
1583           TCollection_AsciiString aContextName(aContextIter.Key1());
1584           theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
1585         }
1586
1587         for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
1588              aViewIter.More(); aViewIter.Next())
1589         {
1590           if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1591           {
1592             TCollection_AsciiString aViewName(aViewIter.Key1());
1593             if (isTreeView)
1594             {
1595               if (aViewIter.Value() == ViewerTest::CurrentView())
1596                 theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
1597               else
1598                 theDi << "  " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1599             }
1600             else
1601             {
1602               theDi << aViewName << " ";
1603             }
1604           }
1605         }
1606       }
1607     }
1608   }
1609   return 0;
1610 }
1611
1612 //==============================================================================
1613 //function : VT_ProcessKeyPress
1614 //purpose  : Handle KeyPress event from a CString
1615 //==============================================================================
1616 void VT_ProcessKeyPress (const char* buf_ret)
1617 {
1618   //cout << "KeyPress" << endl;
1619   const Handle(V3d_View) aView = ViewerTest::CurrentView();
1620   // Letter in alphabetic order
1621
1622   if (!strcasecmp (buf_ret, "A")
1623    && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1624   {
1625     // AXO
1626     aView->SetProj(V3d_XposYnegZpos);
1627   }
1628   else if (!strcasecmp (buf_ret, "D")
1629         && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1630   {
1631     // Reset
1632     aView->Reset();
1633   }
1634   else if (!strcasecmp (buf_ret, "F"))
1635   {
1636     if (ViewerTest::GetAISContext()->NbSelected() > 0)
1637     {
1638       ViewerTest::GetAISContext()->FitSelected (aView);
1639     }
1640     else
1641     {
1642       // FitAll
1643       aView->FitAll();
1644     }
1645   }
1646   else if (!strcasecmp (buf_ret, "H"))
1647   {
1648     // HLR
1649     std::cout << "HLR" << std::endl;
1650     aView->SetComputedMode (!aView->ComputedMode());
1651     aView->Redraw();
1652   }
1653   else if (!strcasecmp (buf_ret, "P"))
1654   {
1655     // Type of HLR
1656     Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1657     if (aContext->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo)
1658       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_PolyAlgo);
1659     else
1660       aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_Algo);
1661     if (aContext->NbSelected()==0)
1662     {
1663       AIS_ListOfInteractive aListOfShapes;
1664       aContext->DisplayedObjects(aListOfShapes);
1665       for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
1666         anIter.More(); anIter.Next())
1667       {
1668         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1669         if (aShape.IsNull())
1670           continue;
1671         if (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1672           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1673         else
1674           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1675         aContext->Redisplay (aShape, Standard_False);
1676       }
1677     }
1678     else
1679     {
1680       for (aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected())
1681       {
1682         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aContext->SelectedInteractive());
1683         if (aShape.IsNull())
1684           continue;
1685         if(aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
1686           aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
1687         else
1688           aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
1689         aContext->Redisplay (aShape, Standard_False);
1690       }
1691     }
1692
1693     aContext->UpdateCurrentViewer();
1694
1695   }
1696   else if (!strcasecmp (buf_ret, "S"))
1697   {
1698     std::cout << "setup Shaded display mode" << std::endl;
1699
1700     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1701     if(Ctx->NbSelected()==0)
1702       Ctx->SetDisplayMode (AIS_Shaded, Standard_True);
1703     else{
1704       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1705         Ctx->SetDisplayMode(Ctx->SelectedInteractive(),1,Standard_False);
1706       Ctx->UpdateCurrentViewer();
1707     }
1708   }
1709   else if (!strcasecmp (buf_ret, "U"))
1710   {
1711     // Unset display mode
1712     std::cout << "reset display mode to defaults" << std::endl;
1713
1714     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1715     if(Ctx->NbSelected()==0)
1716       Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
1717     else{
1718       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1719         Ctx->UnsetDisplayMode(Ctx->SelectedInteractive(),Standard_False);
1720       Ctx->UpdateCurrentViewer();
1721     }
1722
1723   }
1724   else if (!strcasecmp (buf_ret, "T")
1725         && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1726   {
1727     // Top
1728     aView->SetProj(V3d_Zpos);
1729   }
1730   else if (!strcasecmp (buf_ret, "B")
1731         && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1732   {
1733     // Bottom
1734     aView->SetProj(V3d_Zneg);
1735   }
1736   else if (!strcasecmp (buf_ret, "L")
1737         && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1738   {
1739     // Left
1740     aView->SetProj(V3d_Xneg);
1741   }
1742   else if (!strcasecmp (buf_ret, "R")
1743         && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
1744   {
1745     // Right
1746     aView->SetProj(V3d_Xpos);
1747   }
1748   else if (!strcasecmp (buf_ret, "W"))
1749   {
1750     std::cout << "setup WireFrame display mode" << std::endl;
1751     Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
1752     if(Ctx->NbSelected()==0)
1753       Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
1754     else{
1755       for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
1756         Ctx->SetDisplayMode(Ctx->SelectedInteractive(),0,Standard_False);
1757       Ctx->UpdateCurrentViewer();
1758     }
1759   }
1760   else if (!strcasecmp (buf_ret, ","))
1761   {
1762     ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
1763   }
1764   else if (!strcasecmp (buf_ret, "."))
1765   {
1766     ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
1767   }
1768   else if (!strcasecmp (buf_ret, "/"))
1769   {
1770     Handle(Graphic3d_Camera) aCamera = aView->Camera();
1771     if (aCamera->IsStereo())
1772     {
1773       aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
1774       aView->Redraw();
1775     }
1776   }
1777   else if (!strcasecmp (buf_ret, "*"))
1778   {
1779     Handle(Graphic3d_Camera) aCamera = aView->Camera();
1780     if (aCamera->IsStereo())
1781     {
1782       aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
1783       aView->Redraw();
1784     }
1785   }
1786   else if (*buf_ret == THE_KEY_DELETE)
1787   {
1788     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1789     if (!aCtx.IsNull()
1790      && aCtx->NbSelected() > 0)
1791     {
1792       Draw_Interprete ("verase");
1793     }
1794   }
1795   else if (*buf_ret == THE_KEY_ESCAPE)
1796   {
1797     Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1798     if (!aCtx.IsNull()
1799      && Draw_ToCloseViewOnEsc)
1800     {
1801       Draw_Interprete (Draw_ToExitOnCloseView ? "exit" : "vclose");
1802     }
1803   }
1804   else
1805   {
1806     // Number
1807     const Standard_Integer aSelMode = Draw::Atoi(buf_ret);
1808     if (aSelMode >= 0 && aSelMode <= 7)
1809     {
1810       bool toEnable = true;
1811       if (const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext())
1812       {
1813         AIS_ListOfInteractive aPrsList;
1814         aCtx->DisplayedObjects (aPrsList);
1815         for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
1816         {
1817           TColStd_ListOfInteger aModes;
1818           aCtx->ActivatedModes (aPrsIter.Value(), aModes);
1819           for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
1820           {
1821             if (aModeIter.Value() == aSelMode)
1822             {
1823               toEnable = false;
1824             }
1825           }
1826         }
1827       }
1828       TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
1829       Draw_Interprete (aCmd.ToCString());
1830     }
1831   }
1832 }
1833
1834 //==============================================================================
1835 //function : VT_ProcessExpose
1836 //purpose  : Redraw the View on an Expose Event
1837 //==============================================================================
1838 void VT_ProcessExpose()
1839 {
1840   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1841   if (!aView3d.IsNull())
1842   {
1843     aView3d->Redraw();
1844   }
1845 }
1846
1847 //==============================================================================
1848 //function : VT_ProcessConfigure
1849 //purpose  : Resize the View on an Configure Event
1850 //==============================================================================
1851 void VT_ProcessConfigure()
1852 {
1853   Handle(V3d_View) aView3d = ViewerTest::CurrentView();
1854   if (aView3d.IsNull())
1855   {
1856     return;
1857   }
1858
1859   aView3d->MustBeResized();
1860   aView3d->Update();
1861   aView3d->Redraw();
1862 }
1863
1864 //==============================================================================
1865 //function : VT_ProcessButton1Press
1866 //purpose  : Picking
1867 //==============================================================================
1868 Standard_Boolean VT_ProcessButton1Press (Standard_Integer ,
1869                                          const char**     theArgVec,
1870                                          Standard_Boolean theToPick,
1871                                          Standard_Boolean theIsShift)
1872 {
1873   if (TheIsAnimating)
1874   {
1875     TheIsAnimating = Standard_False;
1876     return Standard_False;
1877   }
1878
1879   if (theToPick)
1880   {
1881     Standard_Real X, Y, Z;
1882     ViewerTest::CurrentView()->Convert (X_Motion, Y_Motion, X, Y, Z);
1883
1884     Draw::Set (theArgVec[1], X);
1885     Draw::Set (theArgVec[2], Y);
1886     Draw::Set (theArgVec[3], Z);
1887   }
1888
1889   if (theIsShift)
1890   {
1891     ViewerTest::CurrentEventManager()->ShiftSelect();
1892   }
1893   else
1894   {
1895     ViewerTest::CurrentEventManager()->Select();
1896   }
1897
1898   return Standard_False;
1899 }
1900
1901 //==============================================================================
1902 //function : VT_ProcessButton1Release
1903 //purpose  : End selecting
1904 //==============================================================================
1905 void VT_ProcessButton1Release (Standard_Boolean theIsShift)
1906 {
1907   if (IsDragged)
1908   {
1909     IsDragged = Standard_False;
1910     Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
1911     if (theIsShift)
1912     {
1913       EM->ShiftSelect (X_ButtonPress, Y_ButtonPress,
1914                        X_Motion, Y_Motion);
1915     }
1916     else
1917     {
1918       EM->Select (X_ButtonPress, Y_ButtonPress,
1919                   X_Motion, Y_Motion);
1920     }
1921   }
1922 }
1923
1924 //==============================================================================
1925 //function : VT_ProcessButton3Press
1926 //purpose  : Start Rotation
1927 //==============================================================================
1928 void VT_ProcessButton3Press()
1929 {
1930   if (ViewerTest_V3dView::IsCurrentViewIn2DMode())
1931   {
1932     return;
1933   }
1934
1935   Start_Rot = 1;
1936   HasHlrOnBeforeRotation = ViewerTest::CurrentView()->ComputedMode();
1937   if (HasHlrOnBeforeRotation)
1938   {
1939     ViewerTest::CurrentView()->SetComputedMode (Standard_False);
1940   }
1941   ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
1942 }
1943
1944 //==============================================================================
1945 //function : VT_ProcessButton3Release
1946 //purpose  : End rotation
1947 //==============================================================================
1948 void VT_ProcessButton3Release()
1949 {
1950   if (Start_Rot)
1951   {
1952     Start_Rot = 0;
1953     if (HasHlrOnBeforeRotation)
1954     {
1955       HasHlrOnBeforeRotation = Standard_False;
1956       ViewerTest::CurrentView()->SetComputedMode (Standard_True);
1957       ViewerTest::CurrentView()->Redraw();
1958     }
1959   }
1960 }
1961
1962 //==============================================================================
1963 //function : ProcessControlButton1Motion
1964 //purpose  : Zoom
1965 //==============================================================================
1966
1967 #if defined(_WIN32) || ! defined(__APPLE__) || defined(MACOSX_USE_GLX)
1968 static void ProcessControlButton1Motion()
1969 {
1970   ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
1971
1972   X_ButtonPress = X_Motion;
1973   Y_ButtonPress = Y_Motion;
1974 }
1975 #endif
1976
1977 //==============================================================================
1978 //function : VT_ProcessControlButton2Motion
1979 //purpose  : Panning
1980 //==============================================================================
1981 void VT_ProcessControlButton2Motion()
1982 {
1983   Standard_Integer aDx = X_Motion - X_ButtonPress;
1984   Standard_Integer aDy = Y_Motion - Y_ButtonPress;
1985
1986   aDy = -aDy; // Xwindow Y axis is from top to Bottom
1987
1988   ViewerTest::CurrentView()->Pan (aDx, aDy);
1989
1990   X_ButtonPress = X_Motion;
1991   Y_ButtonPress = Y_Motion;
1992 }
1993
1994 //==============================================================================
1995 //function : VT_ProcessControlButton3Motion
1996 //purpose  : Rotation
1997 //==============================================================================
1998 void VT_ProcessControlButton3Motion()
1999 {
2000   if (Start_Rot)
2001   {
2002     ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
2003   }
2004 }
2005
2006 //==============================================================================
2007 //function : VT_ProcessMotion
2008 //purpose  :
2009 //==============================================================================
2010 void VT_ProcessMotion()
2011 {
2012   //pre-hilights detected objects at mouse position
2013
2014   Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
2015   EM->MoveTo(X_Motion, Y_Motion);
2016 }
2017
2018
2019 void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
2020 {
2021   Xpix = X_Motion;Ypix=Y_Motion;
2022 }
2023
2024 //==============================================================================
2025 //function : ViewProject: implements VAxo, VTop, VLeft, ...
2026 //purpose  : Switches to an axonometric, top, left and other views
2027 //==============================================================================
2028
2029 static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
2030 {
2031   if ( ViewerTest::CurrentView().IsNull() )
2032   {
2033     di<<"Call vinit before this command, please\n";
2034     return 1;
2035   }
2036
2037   ViewerTest::CurrentView()->SetProj(ori);
2038   return 0;
2039 }
2040
2041 //==============================================================================
2042 //function : VAxo
2043 //purpose  : Switch to an Axonometric view
2044 //Draw arg : No args
2045 //==============================================================================
2046
2047 static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
2048 {
2049   return ViewProject(di, V3d_XposYnegZpos);
2050 }
2051
2052 //==============================================================================
2053 //function : VTop
2054 //purpose  : Switch to a Top View
2055 //Draw arg : No args
2056 //==============================================================================
2057
2058 static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
2059 {
2060   return ViewProject(di, V3d_Zpos);
2061 }
2062
2063 //==============================================================================
2064 //function : VBottom
2065 //purpose  : Switch to a Bottom View
2066 //Draw arg : No args
2067 //==============================================================================
2068
2069 static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
2070 {
2071   return ViewProject(di, V3d_Zneg);
2072 }
2073
2074 //==============================================================================
2075 //function : VLeft
2076 //purpose  : Switch to a Left View
2077 //Draw arg : No args
2078 //==============================================================================
2079
2080 static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
2081 {
2082   return ViewProject(di, V3d_Xneg);
2083 }
2084
2085 //==============================================================================
2086 //function : VRight
2087 //purpose  : Switch to a Right View
2088 //Draw arg : No args
2089 //==============================================================================
2090
2091 static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
2092 {
2093   return ViewProject(di, V3d_Xpos);
2094 }
2095
2096 //==============================================================================
2097 //function : VFront
2098 //purpose  : Switch to a Front View
2099 //Draw arg : No args
2100 //==============================================================================
2101
2102 static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
2103 {
2104   return ViewProject(di, V3d_Yneg);
2105 }
2106
2107 //==============================================================================
2108 //function : VBack
2109 //purpose  : Switch to a Back View
2110 //Draw arg : No args
2111 //==============================================================================
2112
2113 static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
2114 {
2115   return ViewProject(di, V3d_Ypos);
2116 }
2117
2118 //==============================================================================
2119 //function : VHelp
2120 //purpose  : Dsiplay help on viewer Keyboead and mouse commands
2121 //Draw arg : No args
2122 //==============================================================================
2123
2124 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
2125 {
2126
2127   di << "Q : Quit the application\n";
2128
2129   di << "=========================\n";
2130   di << "F : FitAll\n";
2131   di << "T : TopView\n";
2132   di << "B : BottomView\n";
2133   di << "R : RightView\n";
2134   di << "L : LeftView\n";
2135   di << "A : AxonometricView\n";
2136   di << "D : ResetView\n";
2137
2138   di << "=========================\n";
2139   di << "S : Shading\n";
2140   di << "W : Wireframe\n";
2141   di << "H : HidelLineRemoval\n";
2142   di << "U : Unset display mode\n";
2143   di << "Delete : Remove selection from viewer\n";
2144
2145   di << "=========================\n";
2146   di << "Selection mode \n";
2147   di << "0 : Shape\n";
2148   di << "1 : Vertex\n";
2149   di << "2 : Edge\n";
2150   di << "3 : Wire\n";
2151   di << "4 : Face\n";
2152   di << "5 : Shell\n";
2153   di << "6 : Solid\n";
2154   di << "7 : Compound\n";
2155
2156   di << "=========================\n";
2157   di << "Z : Switch Z clipping On/Off\n";
2158   di << ", : Hilight next detected\n";
2159   di << ". : Hilight previous detected\n";
2160
2161   return 0;
2162 }
2163
2164 #ifdef _WIN32
2165
2166 static Standard_Boolean Ppick = 0;
2167 static Standard_Integer Pargc = 0;
2168 static const char**           Pargv = NULL;
2169
2170
2171 static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
2172                                           UINT Msg,
2173                                           WPARAM wParam,
2174                                           LPARAM lParam )
2175 {
2176   if (!ViewerTest_myViews.IsEmpty()) {
2177
2178     WPARAM fwKeys = wParam;
2179
2180     switch( Msg ) {
2181     case WM_CLOSE:
2182        {
2183          // Delete view from map of views
2184          ViewerTest::RemoveView(FindViewIdByWindowHandle(hwnd));
2185          return 0;
2186        }
2187        break;
2188     case WM_ACTIVATE:
2189       if(LOWORD(wParam) == WA_CLICKACTIVE || LOWORD(wParam) == WA_ACTIVE
2190         || ViewerTest::CurrentView().IsNull())
2191       {
2192         // Activate inactive window
2193         if(GetWindowHandle(VT_GetWindow()) != hwnd)
2194         {
2195           ActivateView (FindViewIdByWindowHandle(hwnd));
2196         }
2197       }
2198       break;
2199
2200     case WM_LBUTTONUP:
2201       if (IsDragged && !DragFirst)
2202       {
2203         if (!GetActiveAISManipulator().IsNull())
2204         {
2205           GetActiveAISManipulator()->StopTransform();
2206           ViewerTest::GetAISContext()->ClearSelected (Standard_True);
2207         }
2208
2209         if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
2210         {
2211           ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
2212           ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
2213         }
2214
2215         VT_ProcessButton1Release ((fwKeys & MK_SHIFT) != 0);
2216       }
2217       IsDragged = Standard_False;
2218       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
2219
2220     case WM_RBUTTONUP:
2221       if (IsDragged && !DragFirst)
2222       {
2223         if (!GetActiveAISManipulator().IsNull())
2224         {
2225           GetActiveAISManipulator()->StopTransform (Standard_False);
2226           ViewerTest::GetAISContext()->ClearSelected (Standard_True);
2227         }
2228         IsDragged = Standard_False;
2229       }
2230       return ViewerWindowProc (hwnd, Msg, wParam, lParam);
2231
2232     case WM_LBUTTONDOWN:
2233       if (!GetActiveAISManipulator().IsNull())
2234       {
2235         IsDragged = ( fwKeys == MK_LBUTTON );
2236       }
2237       else
2238       {
2239         IsDragged = ( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) );
2240       }
2241
2242       if (IsDragged)
2243       {
2244         DragFirst = Standard_True;
2245         X_ButtonPress = LOWORD(lParam);
2246         Y_ButtonPress = HIWORD(lParam);
2247       }
2248       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
2249
2250     case WM_MOUSEMOVE:
2251       if (IsDragged)
2252       {
2253         X_Motion = LOWORD (lParam);
2254         Y_Motion = HIWORD (lParam);
2255         if (!GetActiveAISManipulator().IsNull())
2256         {
2257           if (DragFirst)
2258           {
2259             GetActiveAISManipulator()->StartTransform (X_ButtonPress, Y_ButtonPress, ViewerTest::CurrentView());
2260           }
2261           else
2262           {
2263             GetActiveAISManipulator()->Transform (X_Motion, Y_Motion, ViewerTest::CurrentView());
2264             ViewerTest::GetAISContext()->CurrentViewer()->Redraw();
2265           }
2266         }
2267         else
2268         {
2269           bool toRedraw = false;
2270           if (!DragFirst && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
2271           {
2272             ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
2273             toRedraw = true;
2274           }
2275
2276           RECT aRect;
2277           if (GetClientRect (hwnd, &aRect))
2278           {
2279             int aHeight = aRect.bottom - aRect.top;
2280             GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
2281             ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
2282             toRedraw = true;
2283           }
2284           if (toRedraw)
2285           {
2286             ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
2287           }
2288         }
2289
2290         DragFirst = Standard_False;
2291       }
2292       else
2293         return ViewerWindowProc( hwnd, Msg, wParam, lParam );
2294       break;
2295
2296     default:
2297       return ViewerWindowProc( hwnd, Msg, wParam, lParam );
2298     }
2299     return 0;
2300   }
2301   return ViewerWindowProc( hwnd, Msg, wParam, lParam );
2302 }
2303
2304
2305 static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
2306                                        UINT Msg,
2307                                        WPARAM wParam,
2308                                        LPARAM lParam )
2309 {
2310   static int Up = 1;
2311   const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2312   if (aView.IsNull())
2313   {
2314     return DefWindowProcW (hwnd, Msg, wParam, lParam);
2315   }
2316
2317     PAINTSTRUCT    ps;
2318
2319     switch( Msg ) {
2320     case WM_PAINT:
2321       BeginPaint(hwnd, &ps);
2322       EndPaint(hwnd, &ps);
2323       VT_ProcessExpose();
2324       break;
2325
2326     case WM_SIZE:
2327       VT_ProcessConfigure();
2328       break;
2329     case WM_MOVE:
2330     case WM_MOVING:
2331     case WM_SIZING:
2332       switch (aView->RenderingParams().StereoMode)
2333       {
2334         case Graphic3d_StereoMode_RowInterlaced:
2335         case Graphic3d_StereoMode_ColumnInterlaced:
2336         case Graphic3d_StereoMode_ChessBoard:
2337           VT_ProcessConfigure(); // track window moves to reverse stereo pair
2338           break;
2339         default:
2340           break;
2341       }
2342       break;
2343
2344     case WM_KEYDOWN:
2345       if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
2346       {
2347         char c[2];
2348         c[0] = (char) wParam;
2349         c[1] = '\0';
2350         if (wParam == VK_DELETE)
2351         {
2352           c[0] = THE_KEY_DELETE;
2353         }
2354         else if (wParam == VK_ESCAPE)
2355         {
2356           c[0] = THE_KEY_ESCAPE;
2357         }
2358         // comma
2359         else if (wParam == VK_OEM_COMMA)
2360         {
2361           c[0] = ',';
2362         }
2363         // dot
2364         else if (wParam == VK_OEM_PERIOD)
2365         {
2366           c[0] = '.';
2367         }
2368         else if (wParam == VK_DIVIDE)
2369         {
2370           c[0] = '/';
2371         }
2372         // dot
2373         else if (wParam == VK_MULTIPLY)
2374         {
2375           c[0] = '*';
2376         }
2377         VT_ProcessKeyPress (c);
2378       }
2379       break;
2380
2381     case WM_LBUTTONUP:
2382     case WM_MBUTTONUP:
2383     case WM_RBUTTONUP:
2384       Up = 1;
2385       VT_ProcessButton3Release();
2386       break;
2387
2388     case WM_LBUTTONDOWN:
2389     case WM_MBUTTONDOWN:
2390     case WM_RBUTTONDOWN:
2391       {
2392         WPARAM fwKeys = wParam;
2393
2394         Up = 0;
2395
2396         X_ButtonPress = LOWORD(lParam);
2397         Y_ButtonPress = HIWORD(lParam);
2398
2399         if (Msg == WM_LBUTTONDOWN)
2400         {
2401           if ((fwKeys & MK_CONTROL) != 0)
2402           {
2403             Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
2404           }
2405           else
2406           {
2407             VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
2408           }
2409         }
2410         else if (Msg == WM_RBUTTONDOWN)
2411         {
2412           // Start rotation
2413           VT_ProcessButton3Press();
2414         }
2415       }
2416       break;
2417
2418     case WM_MOUSEWHEEL:
2419     {
2420       int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
2421       if (wParam & MK_CONTROL)
2422       {
2423         if (aView->Camera()->IsStereo())
2424         {
2425           Standard_Real aFocus = aView->Camera()->ZFocus() + (aDelta > 0 ? 0.05 : -0.05);
2426           if (aFocus > 0.2
2427            && aFocus < 2.0)
2428           {
2429             aView->Camera()->SetZFocus (aView->Camera()->ZFocusType(), aFocus);
2430             aView->Redraw();
2431           }
2432         }
2433       }
2434       else
2435       {
2436         aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
2437       }
2438       break;
2439     }
2440
2441     case WM_MOUSEMOVE:
2442       {
2443         //cout << "\t WM_MOUSEMOVE" << endl;
2444         WPARAM fwKeys = wParam;
2445         X_Motion = LOWORD(lParam);
2446         Y_Motion = HIWORD(lParam);
2447
2448         if ( Up &&
2449           (fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON )) != 0 )
2450           {
2451             Up = 0;
2452             X_ButtonPress = LOWORD(lParam);
2453             Y_ButtonPress = HIWORD(lParam);
2454
2455             if ((fwKeys & MK_RBUTTON) != 0) {
2456               // Start rotation
2457               VT_ProcessButton3Press();
2458             }
2459           }
2460
2461           if ((fwKeys & MK_CONTROL) != 0)
2462           {
2463             if ((fwKeys & MK_LBUTTON) != 0)
2464             {
2465               ProcessControlButton1Motion();
2466             }
2467             else if ((fwKeys & MK_MBUTTON) != 0
2468                  || ((fwKeys & MK_LBUTTON) != 0
2469                   && (fwKeys & MK_RBUTTON) != 0))
2470             {
2471               VT_ProcessControlButton2Motion();
2472             }
2473             else if ((fwKeys & MK_RBUTTON) != 0)
2474             {
2475               VT_ProcessControlButton3Motion();
2476             }
2477           }
2478           else if (GetWindowHandle (VT_GetWindow()) == hwnd)
2479           {
2480             VT_ProcessMotion();
2481           }
2482       }
2483       break;
2484
2485     default:
2486       return DefWindowProcW (hwnd, Msg, wParam, lParam);
2487     }
2488     return 0L;
2489 }
2490
2491 //==============================================================================
2492 //function : ViewerMainLoop
2493 //purpose  : Get a Event on the view and dispatch it
2494 //==============================================================================
2495
2496
2497 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2498 {
2499   Ppick = (argc > 0)? 1 : 0;
2500   Pargc = argc;
2501   Pargv = argv;
2502
2503   if ( Ppick ) {
2504     MSG msg;
2505     msg.wParam = 1;
2506
2507     cout << "Start picking" << endl;
2508
2509     while ( Ppick == 1 ) {
2510       // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2511       if (GetMessageW (&msg, NULL, 0, 0))
2512       {
2513         TranslateMessage (&msg);
2514         DispatchMessageW (&msg);
2515       }
2516     }
2517
2518     cout << "Picking done" << endl;
2519   }
2520
2521   return Ppick;
2522 }
2523
2524 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
2525
2526 int min( int a, int b )
2527 {
2528   if( a<b )
2529     return a;
2530   else
2531     return b;
2532 }
2533
2534 int max( int a, int b )
2535 {
2536   if( a>b )
2537     return a;
2538   else
2539     return b;
2540 }
2541
2542 int ViewerMainLoop(Standard_Integer argc, const char** argv)
2543
2544 {
2545   static XEvent aReport;
2546   Standard_Boolean pick = argc > 0;
2547   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2548   XNextEvent (aDisplay, &aReport);
2549
2550   // Handle event for the chosen display connection
2551   switch (aReport.type) {
2552       case ClientMessage:
2553         {
2554           if((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2555           {
2556             // Close the window
2557             ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2558           }
2559         }
2560         return 0;
2561      case FocusIn:
2562       {
2563          // Activate inactive view
2564          Window aWindow = GetWindowHandle(VT_GetWindow());
2565          if(aWindow != aReport.xfocus.window)
2566          {
2567            ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2568          }
2569       }
2570       break;
2571       case Expose:
2572         {
2573           VT_ProcessExpose();
2574         }
2575         break;
2576       case ConfigureNotify:
2577         {
2578           VT_ProcessConfigure();
2579         }
2580         break;
2581       case KeyPress:
2582         {
2583
2584           KeySym ks_ret ;
2585           char buf_ret[11] ;
2586           int ret_len ;
2587           XComposeStatus status_in_out;
2588
2589           ret_len = XLookupString( ( XKeyEvent *)&aReport ,
2590             (char *) buf_ret , 10 ,
2591             &ks_ret , &status_in_out ) ;
2592
2593
2594           buf_ret[ret_len] = '\0' ;
2595
2596           if (ret_len)
2597           {
2598             VT_ProcessKeyPress (buf_ret);
2599           }
2600         }
2601         break;
2602       case ButtonPress:
2603         {
2604           X_ButtonPress = aReport.xbutton.x;
2605           Y_ButtonPress = aReport.xbutton.y;
2606
2607           if (aReport.xbutton.button == Button1)
2608           {
2609             if (aReport.xbutton.state & ControlMask)
2610             {
2611               pick = VT_ProcessButton1Press (argc, argv, pick, (aReport.xbutton.state & ShiftMask));
2612             }
2613             else
2614             {
2615               IsDragged = Standard_True;
2616               DragFirst = Standard_True;
2617             }
2618           }
2619           else if (aReport.xbutton.button == Button3)
2620           {
2621             // Start rotation
2622             VT_ProcessButton3Press();
2623           }
2624         }
2625         break;
2626       case ButtonRelease:
2627         {
2628           if( IsDragged )
2629           {
2630             if( !DragFirst )
2631             {
2632               if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
2633               {
2634                 ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
2635                 ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
2636               }
2637             }
2638
2639             Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
2640             if( aContext.IsNull() )
2641             {
2642               cout << "The context is null. Please use vinit before createmesh" << endl;
2643               return 0;
2644             }
2645
2646             Standard_Boolean ShiftPressed = ( aReport.xbutton.state & ShiftMask );
2647             if( aReport.xbutton.button==1 )
2648               if( DragFirst )
2649                 if( ShiftPressed )
2650                 {
2651                   aContext->ShiftSelect (Standard_True);
2652                 }
2653                 else
2654                 {
2655                   aContext->Select (Standard_True);
2656                 }
2657               else
2658                 if( ShiftPressed )
2659                 {
2660                   aContext->ShiftSelect(Min(X_ButtonPress, X_Motion), Min(Y_ButtonPress, Y_Motion),
2661                                         Max(X_ButtonPress, X_Motion), Max(Y_ButtonPress, Y_Motion),
2662                                         ViewerTest::CurrentView(), Standard_True);
2663                 }
2664                 else
2665                 {
2666                   aContext->Select(Min(X_ButtonPress, X_Motion), Min(Y_ButtonPress, Y_Motion),
2667                                    Max(X_ButtonPress, X_Motion), Max(Y_ButtonPress, Y_Motion),
2668                                    ViewerTest::CurrentView(), Standard_True);
2669                 }
2670             else
2671               VT_ProcessButton3Release();
2672
2673             IsDragged = Standard_False;
2674           }
2675           else
2676             VT_ProcessButton3Release();
2677         }
2678         break;
2679       case MotionNotify:
2680         {
2681           if (GetWindowHandle (VT_GetWindow()) != aReport.xmotion.window)
2682           {
2683             break;
2684           }
2685           if( IsDragged )
2686           {
2687             if( !DragFirst )
2688             {
2689               if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
2690               {
2691                 ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
2692               }
2693             }
2694
2695             X_Motion = aReport.xmotion.x;
2696             Y_Motion = aReport.xmotion.y;
2697             DragFirst = Standard_False;
2698
2699             Window aWindow = GetWindowHandle(VT_GetWindow());
2700             Window aRoot;
2701             int anX, anY;
2702             unsigned int aWidth, aHeight, aBorderWidth, aDepth;
2703             XGetGeometry (aDisplay, aWindow, &aRoot, &anX, &anY, &aWidth, &aHeight, &aBorderWidth, &aDepth);
2704             GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
2705             ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
2706             ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
2707           }
2708           else
2709           {
2710             X_Motion = aReport.xmotion.x;
2711             Y_Motion = aReport.xmotion.y;
2712
2713             // remove all the ButtonMotionMaskr
2714             while( XCheckMaskEvent( aDisplay, ButtonMotionMask, &aReport) ) ;
2715
2716             if ( aReport.xmotion.state & ControlMask ) {
2717               if ( aReport.xmotion.state & Button1Mask ) {
2718                 ProcessControlButton1Motion();
2719               }
2720               else if ( aReport.xmotion.state & Button2Mask ) {
2721                 VT_ProcessControlButton2Motion();
2722               }
2723               else if ( aReport.xmotion.state & Button3Mask ) {
2724                 VT_ProcessControlButton3Motion();
2725               }
2726             }
2727             else
2728             {
2729               VT_ProcessMotion();
2730             }
2731           }
2732         }
2733         break;
2734 }
2735 return pick;
2736 }
2737
2738 //==============================================================================
2739 //function : VProcessEvents
2740 //purpose  : call by Tk_CreateFileHandler() to be able to manage the
2741 //       event in the Viewer window
2742 //==============================================================================
2743
2744 static void VProcessEvents(ClientData,int)
2745 {
2746   NCollection_Vector<int> anEventNumbers;
2747   // Get number of messages from every display
2748   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2749        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next())
2750   {
2751     anEventNumbers.Append(XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()));
2752   }
2753     // Handle events for every display
2754   int anEventIter = 0;
2755   for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2756        anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next(), anEventIter++)
2757   {
2758     for (int i = 0; i < anEventNumbers.Value(anEventIter) &&
2759          XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()) > 0; ++i)
2760     {
2761       SetDisplayConnection (anIter.Key2()->GetDisplayConnection());
2762       int anEventResult = ViewerMainLoop( 0, NULL);
2763       // If window is closed or context was not found finish current event processing loop
2764       if (!anEventResult)
2765         return;
2766     }
2767   }
2768
2769   SetDisplayConnection (ViewerTest::GetAISContext()->CurrentViewer()->Driver()->GetDisplayConnection());
2770
2771 }
2772 #endif
2773
2774 //==============================================================================
2775 //function : OSWindowSetup
2776 //purpose  : Setup for the X11 window to be able to cath the event
2777 //==============================================================================
2778
2779
2780 static void OSWindowSetup()
2781 {
2782 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2783   // X11
2784
2785   Window  window   = VT_GetWindow()->XWindow();
2786   SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2787   Display *aDisplay = GetDisplayConnection()->GetDisplay();
2788   XSynchronize(aDisplay, 1);
2789
2790   // X11 : For keyboard on SUN
2791   XWMHints wmhints;
2792   wmhints.flags = InputHint;
2793   wmhints.input = 1;
2794
2795   XSetWMHints( aDisplay, window, &wmhints);
2796
2797   XSelectInput( aDisplay, window,  ExposureMask | KeyPressMask |
2798     ButtonPressMask | ButtonReleaseMask |
2799     StructureNotifyMask |
2800     PointerMotionMask |
2801     Button1MotionMask | Button2MotionMask |
2802     Button3MotionMask | FocusChangeMask
2803     );
2804   Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
2805   XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
2806
2807   XSynchronize(aDisplay, 0);
2808
2809 #else
2810   // _WIN32
2811 #endif
2812
2813 }
2814
2815 //==============================================================================
2816 //function : VFit
2817 //purpose  :
2818 //==============================================================================
2819
2820 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
2821 {
2822   const Handle(V3d_View) aView = ViewerTest::CurrentView();
2823   if (aView.IsNull())
2824   {
2825     std::cout << "Error: no active viewer!\n";
2826     return 1;
2827   }
2828
2829   Standard_Boolean toFit = Standard_True;
2830   ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2831   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2832   {
2833     TCollection_AsciiString anArg (theArgv[anArgIter]);
2834     anArg.LowerCase();
2835     if (anUpdateTool.parseRedrawMode (anArg))
2836     {
2837       continue;
2838     }
2839     else if (anArg == "-selected")
2840     {
2841       ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
2842       toFit = Standard_False;
2843     }
2844     else
2845     {
2846       std::cout << "Syntax error at '" << anArg << "'\n";
2847     }
2848   }
2849
2850   if (toFit)
2851   {
2852     aView->FitAll (0.01, Standard_False);
2853   }
2854   return 0;
2855 }
2856
2857 //=======================================================================
2858 //function : VFitArea
2859 //purpose  : Fit view to show area located between two points
2860 //         : given in world 2D or 3D coordinates.
2861 //=======================================================================
2862 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer  theArgNb, const char** theArgVec)
2863 {
2864   Handle(V3d_View) aView = ViewerTest::CurrentView();
2865   if (aView.IsNull())
2866   {
2867     std::cerr << theArgVec[0] << "Error: No active view.\n";
2868     return 1;
2869   }
2870
2871   // Parse arguments.
2872   gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
2873   gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
2874
2875   if (theArgNb == 5)
2876   {
2877     aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2878     aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2879     aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
2880     aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
2881   }
2882   else if (theArgNb == 7)
2883   {
2884     aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2885     aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2886     aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
2887     aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
2888     aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
2889     aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
2890   }
2891   else
2892   {
2893     std::cerr << theArgVec[0] << "Error: Invalid number of arguments.\n";
2894     theDI.PrintHelp(theArgVec[0]);
2895     return 1;
2896   }
2897
2898   // Convert model coordinates to view space
2899   Handle(Graphic3d_Camera) aCamera = aView->Camera();
2900   gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
2901   gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
2902
2903   // Determine fit area
2904   gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
2905   gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
2906
2907   Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
2908
2909   if (aDiagonal < Precision::Confusion())
2910   {
2911     std::cerr << theArgVec[0] << "Error: view area is too small.\n";
2912     return 1;
2913   }
2914
2915   aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
2916   return 0;
2917 }
2918
2919 //==============================================================================
2920 //function : VZFit
2921 //purpose  : ZFitall, no DRAW arguments
2922 //Draw arg : No args
2923 //==============================================================================
2924 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2925 {
2926   const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2927
2928   if (aCurrentView.IsNull())
2929   {
2930     std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
2931     return 1;
2932   }
2933
2934   if (theArgsNb == 1)
2935   {
2936     aCurrentView->ZFitAll();
2937     aCurrentView->Redraw();
2938     return 0;
2939   }
2940
2941   Standard_Real aScale = 1.0;
2942
2943   if (theArgsNb >= 2)
2944   {
2945     aScale = Draw::Atoi (theArgVec[1]);
2946   }
2947
2948   aCurrentView->ZFitAll (aScale);
2949   aCurrentView->Redraw();
2950
2951   return 0;
2952 }
2953
2954 //==============================================================================
2955 //function : VRepaint
2956 //purpose  :
2957 //==============================================================================
2958 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
2959 {
2960   Handle(V3d_View) aView = ViewerTest::CurrentView();
2961   if (aView.IsNull())
2962   {
2963     std::cout << "Error: no active viewer!\n";
2964     return 1;
2965   }
2966
2967   Standard_Boolean isImmediateUpdate = Standard_False;
2968   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2969   {
2970     TCollection_AsciiString anArg (theArgVec[anArgIter]);
2971     anArg.LowerCase();
2972     if (anArg == "-immediate")
2973     {
2974       isImmediateUpdate = Standard_True;
2975       if (anArgIter + 1 < theArgNb
2976        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
2977       {
2978         ++anArgIter;
2979       }
2980     }
2981     else
2982     {
2983       std::cout << "Syntax error at '" << anArg << "'\n";
2984     }
2985   }
2986
2987   if (isImmediateUpdate)
2988   {
2989     aView->RedrawImmediate();
2990   }
2991   else
2992   {
2993     aView->Redraw();
2994   }
2995   return 0;
2996 }
2997
2998 //==============================================================================
2999 //function : VClear
3000 //purpose  : Remove all the object from the viewer
3001 //Draw arg : No args
3002 //==============================================================================
3003
3004 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3005 {
3006   Handle(V3d_View) V = ViewerTest::CurrentView();
3007   if(!V.IsNull())
3008     ViewerTest::Clear();
3009   return 0;
3010 }
3011
3012 //==============================================================================
3013 //function : VPick
3014 //purpose  :
3015 //==============================================================================
3016
3017 static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3018 { if (ViewerTest::CurrentView().IsNull() ) return 1;
3019
3020 if ( argc < 4 ) {
3021   di << argv[0] << "Invalid number of arguments\n";
3022   return 1;
3023 }
3024
3025 while (ViewerMainLoop( argc, argv)) {
3026 }
3027
3028 return 0;
3029 }
3030
3031 //==============================================================================
3032 //function : VSetBg
3033 //purpose  : Load image as background
3034 //==============================================================================
3035
3036 static int VSetBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3037 {
3038   if (argc < 2 || argc > 3)
3039   {
3040     di << "Usage : " << argv[0] << " imagefile [filltype] : Load image as background\n";
3041     di << "filltype can be one of CENTERED, TILED, STRETCH, NONE\n";
3042     return 1;
3043   }
3044
3045   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
3046   if(AISContext.IsNull())
3047   {
3048     di << "use 'vinit' command before " << argv[0] << "\n";
3049     return 1;
3050   }
3051
3052   Aspect_FillMethod aFillType = Aspect_FM_CENTERED;
3053   if (argc == 3)
3054   {
3055     const char* szType = argv[2];
3056     if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
3057     else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
3058     else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
3059     else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
3060     else
3061     {
3062       di << "Wrong fill type : " << szType << "\n";
3063       di << "Must be one of CENTERED, TILED, STRETCH, NONE\n";
3064       return 1;
3065     }
3066   }
3067
3068   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3069   V3dView->SetBackgroundImage(argv[1], aFillType, Standard_True);
3070
3071   return 0;
3072 }
3073
3074 //==============================================================================
3075 //function : VSetBgMode
3076 //purpose  : Change background image fill type
3077 //==============================================================================
3078
3079 static int VSetBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3080 {
3081   if (argc != 2)
3082   {
3083     di << "Usage : " << argv[0] << " filltype : Change background image mode\n";
3084     di << "filltype must be one of CENTERED, TILED, STRETCH, NONE\n";
3085     return 1;
3086   }
3087
3088   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
3089   if(AISContext.IsNull())
3090   {
3091     di << "use 'vinit' command before " << argv[0] << "\n";
3092     return 1;
3093   }
3094   Aspect_FillMethod aFillType = Aspect_FM_NONE;
3095   const char* szType = argv[1];
3096   if      (strcmp(szType, "NONE"    ) == 0) aFillType = Aspect_FM_NONE;
3097   else if (strcmp(szType, "CENTERED") == 0) aFillType = Aspect_FM_CENTERED;
3098   else if (strcmp(szType, "TILED"   ) == 0) aFillType = Aspect_FM_TILED;
3099   else if (strcmp(szType, "STRETCH" ) == 0) aFillType = Aspect_FM_STRETCH;
3100   else
3101   {
3102     di << "Wrong fill type : " << szType << "\n";
3103     di << "Must be one of CENTERED, TILED, STRETCH, NONE\n";
3104     return 1;
3105   }
3106   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3107   V3dView->SetBgImageStyle(aFillType, Standard_True);
3108   return 0;
3109 }
3110
3111 //==============================================================================
3112 //function : VSetGradientBg
3113 //purpose  : Mount gradient background
3114 //==============================================================================
3115 static int VSetGradientBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3116 {
3117   if (argc != 8 )
3118   {
3119     di << "Usage : " << argv[0] << " R1 G1 B1 R2 G2 B2 Type : Mount gradient background\n";
3120     di << "R1,G1,B1,R2,G2,B2 = [0..255]\n";
3121     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2\n";
3122     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4\n";
3123     return 1;
3124   }
3125
3126   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
3127   if(AISContext.IsNull())
3128   {
3129     di << "use 'vinit' command before " << argv[0] << "\n";
3130     return 1;
3131   }
3132   if (argc == 8)
3133   {
3134
3135     Standard_Real R1 = Draw::Atof(argv[1])/255.;
3136     Standard_Real G1 = Draw::Atof(argv[2])/255.;
3137     Standard_Real B1 = Draw::Atof(argv[3])/255.;
3138     Quantity_Color aColor1(R1,G1,B1,Quantity_TOC_RGB);
3139
3140     Standard_Real R2 = Draw::Atof(argv[4])/255.;
3141     Standard_Real G2 = Draw::Atof(argv[5])/255.;
3142     Standard_Real B2 = Draw::Atof(argv[6])/255.;
3143
3144     Quantity_Color aColor2(R2,G2,B2,Quantity_TOC_RGB);
3145     int aType = Draw::Atoi(argv[7]);
3146     if( aType < 0 || aType > 8 )
3147     {
3148       di << "Wrong fill type \n";
3149       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2\n";
3150       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4\n";
3151       return 1;
3152     }
3153
3154     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
3155
3156     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3157     V3dView->SetBgGradientColors( aColor1, aColor2, aMethod, 1);
3158   }
3159
3160   return 0;
3161 }
3162
3163 //==============================================================================
3164 //function : VSetGradientBgMode
3165 //purpose  : Change gradient background fill style
3166 //==============================================================================
3167 static int VSetGradientBgMode(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3168 {
3169   if (argc != 2 )
3170   {
3171     di << "Usage : " << argv[0] << " Type : Change gradient background fill type\n";
3172     di << "Type must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2\n";
3173     di << "                    5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4\n";
3174     return 1;
3175   }
3176
3177   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
3178   if(AISContext.IsNull())
3179   {
3180     di << "use 'vinit' command before " << argv[0] << "\n";
3181     return 1;
3182   }
3183   if (argc == 2)
3184   {
3185     int aType = Draw::Atoi(argv[1]);
3186     if( aType < 0 || aType > 8 )
3187     {
3188       di << "Wrong fill type \n";
3189       di << "Must be one of 0 = NONE, 1 = HOR, 2 = VER, 3 = DIAG1, 4 = DIAG2\n";
3190       di << "               5 = CORNER1, 6 = CORNER2, 7 = CORNER3, 8 = CORNER4\n";
3191       return 1;
3192     }
3193
3194     Aspect_GradientFillMethod aMethod = Aspect_GradientFillMethod(aType);
3195
3196     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3197     V3dView->SetBgGradientStyle( aMethod, 1 );
3198   }
3199
3200   return 0;
3201 }
3202
3203 //==============================================================================
3204 //function : VSetColorBg
3205 //purpose  : Set color background
3206 //==============================================================================
3207 static int VSetColorBg(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3208 {
3209   if (argc != 4 )
3210   {
3211     di << "Usage : " << argv[0] << " R G B : Set color background\n";
3212     di << "R,G,B = [0..255]\n";
3213     return 1;
3214   }
3215
3216   Handle(AIS_InteractiveContext) AISContext = ViewerTest::GetAISContext();
3217   if(AISContext.IsNull())
3218   {
3219     di << "use 'vinit' command before " << argv[0] << "\n";
3220     return 1;
3221   }
3222   if (argc == 4)
3223   {
3224
3225     Standard_Real R = Draw::Atof(argv[1])/255.;
3226     Standard_Real G = Draw::Atof(argv[2])/255.;
3227     Standard_Real B = Draw::Atof(argv[3])/255.;
3228     Quantity_Color aColor(R,G,B,Quantity_TOC_RGB);
3229
3230     Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3231     V3dView->SetBackgroundColor( aColor );
3232     V3dView->Update();
3233   }
3234
3235   return 0;
3236 }
3237
3238 //==============================================================================
3239 //function : VSetDefaultBg
3240 //purpose  : Set default viewer background fill color
3241 //==============================================================================
3242 static int VSetDefaultBg (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3243 {
3244   if (theArgNb != 4
3245    && theArgNb != 8)
3246   {
3247     std::cout << "Error: wrong syntax! See usage:\n";
3248     theDI.PrintHelp (theArgVec[0]);
3249     return 1;
3250   }
3251
3252   ViewerTest_DefaultBackground.FillMethod =
3253     theArgNb == 4 ? Aspect_GFM_NONE
3254                   : (Aspect_GradientFillMethod) Draw::Atoi (theArgVec[7]);
3255
3256   if (theArgNb == 4)
3257   {
3258     Standard_Real R = Draw::Atof (theArgVec[1]) / 255.;
3259     Standard_Real G = Draw::Atof (theArgVec[2]) / 255.;
3260     Standard_Real B = Draw::Atof (theArgVec[3]) / 255.;
3261     ViewerTest_DefaultBackground.FlatColor.SetValues (R, G, B, Quantity_TOC_RGB);
3262   }
3263   else
3264   {
3265     Standard_Real R1 = Draw::Atof (theArgVec[1]) / 255.;
3266     Standard_Real G1 = Draw::Atof (theArgVec[2]) / 255.;
3267     Standard_Real B1 = Draw::Atof (theArgVec[3]) / 255.;
3268     ViewerTest_DefaultBackground.GradientColor1.SetValues (R1, G1, B1, Quantity_TOC_RGB);
3269
3270     Standard_Real R2 = Draw::Atof (theArgVec[4]) / 255.;
3271     Standard_Real G2 = Draw::Atof (theArgVec[5]) / 255.;
3272     Standard_Real B2 = Draw::Atof (theArgVec[6]) / 255.;
3273     ViewerTest_DefaultBackground.GradientColor2.SetValues (R2, G2, B2, Quantity_TOC_RGB);
3274   }
3275
3276   for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
3277        anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
3278   {
3279     const Handle(V3d_Viewer)& aViewer = anIter.Value()->CurrentViewer();
3280     aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
3281     aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
3282                                          ViewerTest_DefaultBackground.GradientColor2,
3283                                          ViewerTest_DefaultBackground.FillMethod);
3284   }
3285
3286   return 0;
3287 }
3288
3289 //==============================================================================
3290 //function : VScale
3291 //purpose  : View Scaling
3292 //==============================================================================
3293
3294 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3295 {
3296   Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3297   if ( V3dView.IsNull() ) return 1;
3298
3299   if ( argc != 4 ) {
3300     di << argv[0] << "Invalid number of arguments\n";
3301     return 1;
3302   }
3303   V3dView->SetAxialScale( Draw::Atof(argv[1]),  Draw::Atof(argv[2]),  Draw::Atof(argv[3]) );
3304   return 0;
3305 }
3306 //==============================================================================
3307 //function : VZBuffTrihedron
3308 //purpose  :
3309 //==============================================================================
3310
3311 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3312                             Standard_Integer  theArgNb,
3313                             const char**      theArgVec)
3314 {
3315   Handle(V3d_View) aView = ViewerTest::CurrentView();
3316   if (aView.IsNull())
3317   {
3318     std::cout << "Error: no active viewer!\n";
3319     return 1;
3320   }
3321
3322   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
3323
3324   Aspect_TypeOfTriedronPosition aPosition     = Aspect_TOTP_LEFT_LOWER;
3325   V3d_TypeOfVisualization       aVisType      = V3d_ZBUFFER;
3326   Quantity_Color                aLabelsColor  = Quantity_NOC_WHITE;
3327   Quantity_Color                anArrowColorX = Quantity_NOC_RED;
3328   Quantity_Color                anArrowColorY = Quantity_NOC_GREEN;
3329   Quantity_Color                anArrowColorZ = Quantity_NOC_BLUE1;
3330   Standard_Real                 aScale        = 0.1;
3331   Standard_Real                 aSizeRatio    = 0.8;
3332   Standard_Real                 anArrowDiam   = 0.05;
3333   Standard_Integer              aNbFacets     = 12;
3334   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3335   {
3336     Standard_CString        anArg = theArgVec[anArgIter];
3337     TCollection_AsciiString aFlag (anArg);
3338     aFlag.LowerCase();
3339     if (anUpdateTool.parseRedrawMode (aFlag))
3340     {
3341       continue;
3342     }
3343     else if (aFlag == "-on")
3344     {
3345       continue;
3346     }
3347     else if (aFlag == "-off")
3348     {
3349       aView->TriedronErase();
3350       return 0;
3351     }
3352     else if (aFlag == "-pos"
3353           || aFlag == "-position"
3354           || aFlag == "-corner")
3355     {
3356       if (++anArgIter >= theArgNb)
3357       {
3358         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3359         return 1;
3360       }
3361
3362       TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3363       aPosName.LowerCase();
3364       if (aPosName == "center")
3365       {
3366         aPosition = Aspect_TOTP_CENTER;
3367       }
3368       else if (aPosName == "left_lower"
3369             || aPosName == "lower_left"
3370             || aPosName == "leftlower"
3371             || aPosName == "lowerleft")
3372       {
3373         aPosition = Aspect_TOTP_LEFT_LOWER;
3374       }
3375       else if (aPosName == "left_upper"
3376             || aPosName == "upper_left"
3377             || aPosName == "leftupper"
3378             || aPosName == "upperleft")
3379       {
3380         aPosition = Aspect_TOTP_LEFT_UPPER;
3381       }
3382       else if (aPosName == "right_lower"
3383             || aPosName == "lower_right"
3384             || aPosName == "rightlower"
3385             || aPosName == "lowerright")
3386       {
3387         aPosition = Aspect_TOTP_RIGHT_LOWER;
3388       }
3389       else if (aPosName == "right_upper"
3390             || aPosName == "upper_right"
3391             || aPosName == "rightupper"
3392             || aPosName == "upperright")
3393       {
3394         aPosition = Aspect_TOTP_RIGHT_UPPER;
3395       }
3396       else
3397       {
3398         std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'\n";
3399         return 1;
3400       }
3401     }
3402     else if (aFlag == "-type")
3403     {
3404       if (++anArgIter >= theArgNb)
3405       {
3406         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3407         return 1;
3408       }
3409
3410       TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3411       aTypeName.LowerCase();
3412       if (aTypeName == "wireframe"
3413        || aTypeName == "wire")
3414       {
3415         aVisType = V3d_WIREFRAME;
3416       }
3417       else if (aTypeName == "zbuffer"
3418             || aTypeName == "shaded")
3419       {
3420         aVisType = V3d_ZBUFFER;
3421       }
3422       else
3423       {
3424         std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'\n";
3425       }
3426     }
3427     else if (aFlag == "-scale")
3428     {
3429       if (++anArgIter >= theArgNb)
3430       {
3431         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3432         return 1;
3433       }
3434
3435       aScale = Draw::Atof (theArgVec[anArgIter]);
3436     }
3437     else if (aFlag == "-size"
3438           || aFlag == "-sizeratio")
3439     {
3440       if (++anArgIter >= theArgNb)
3441       {
3442         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3443         return 1;
3444       }
3445
3446       aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3447     }
3448     else if (aFlag == "-arrowdiam"
3449           || aFlag == "-arrowdiameter")
3450     {
3451       if (++anArgIter >= theArgNb)
3452       {
3453         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3454         return 1;
3455       }
3456
3457       anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3458     }
3459     else if (aFlag == "-nbfacets")
3460     {
3461       if (++anArgIter >= theArgNb)
3462       {
3463         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3464         return 1;
3465       }
3466
3467       aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3468     }
3469     else if (aFlag == "-colorlabel"
3470           || aFlag == "-colorlabels")
3471     {
3472       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3473                                                            theArgVec + anArgIter + 1,
3474                                                            aLabelsColor);
3475       if (aNbParsed == 0)
3476       {
3477         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3478         return 1;
3479       }
3480       anArgIter += aNbParsed;
3481     }
3482     else if (aFlag == "-colorarrowx")
3483     {
3484       Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb  - anArgIter - 1,
3485                                                            theArgVec + anArgIter + 1,
3486                                                            anArrowColorX);
3487       if (aNbParsed == 0)
3488       {
3489         std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
3490