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