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