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