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