1 // Created on: 1998-09-01
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <OpenGl_GlCore20.hxx>
18 #include <ViewerTest.hxx>
20 #include <AIS_AnimationCamera.hxx>
21 #include <AIS_AnimationObject.hxx>
22 #include <AIS_CameraFrustum.hxx>
23 #include <AIS_ColorScale.hxx>
24 #include <AIS_InteractiveContext.hxx>
25 #include <AIS_ListOfInteractive.hxx>
26 #include <AIS_ListIteratorOfListOfInteractive.hxx>
27 #include <AIS_Manipulator.hxx>
28 #include <AIS_ViewCube.hxx>
29 #include <AIS_Shape.hxx>
30 #include <Aspect_DisplayConnection.hxx>
31 #include <Aspect_Grid.hxx>
32 #include <Aspect_TypeOfLine.hxx>
34 #include <Draw_Appli.hxx>
35 #include <Draw_Interpretor.hxx>
36 #include <Draw_ProgressIndicator.hxx>
40 #include <Graphic3d_ArrayOfPolylines.hxx>
41 #include <Graphic3d_AspectFillArea3d.hxx>
42 #include <Graphic3d_AspectMarker3d.hxx>
43 #include <Graphic3d_ClipPlane.hxx>
44 #include <Graphic3d_CubeMapPacked.hxx>
45 #include <Graphic3d_CubeMapSeparate.hxx>
46 #include <Graphic3d_GraduatedTrihedron.hxx>
47 #include <Graphic3d_NameOfTextureEnv.hxx>
48 #include <Graphic3d_Texture2Dmanual.hxx>
49 #include <Graphic3d_TextureEnv.hxx>
50 #include <Graphic3d_TextureParams.hxx>
51 #include <Graphic3d_TypeOfTextureFilter.hxx>
52 #include <Image_AlienPixMap.hxx>
53 #include <Image_Diff.hxx>
54 #include <Image_VideoRecorder.hxx>
55 #include <Message_ProgressSentry.hxx>
56 #include <NCollection_DataMap.hxx>
57 #include <NCollection_List.hxx>
58 #include <NCollection_Vector.hxx>
60 #include <OSD_Timer.hxx>
61 #include <OpenGl_GraphicDriver.hxx>
62 #include <Prs3d_ShadingAspect.hxx>
63 #include <Prs3d_Drawer.hxx>
64 #include <Prs3d_LineAspect.hxx>
65 #include <Prs3d_Root.hxx>
66 #include <Prs3d_Text.hxx>
67 #include <Select3D_SensitivePrimitiveArray.hxx>
68 #include <TColStd_HSequenceOfAsciiString.hxx>
69 #include <TColStd_SequenceOfInteger.hxx>
70 #include <TColStd_HSequenceOfReal.hxx>
71 #include <TColgp_Array1OfPnt2d.hxx>
72 #include <TColStd_MapOfAsciiString.hxx>
73 #include <ViewerTest_AutoUpdater.hxx>
74 #include <ViewerTest_EventManager.hxx>
75 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
76 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
77 #include <ViewerTest_CmdParser.hxx>
78 #include <ViewerTest_V3dView.hxx>
79 #include <V3d_AmbientLight.hxx>
80 #include <V3d_DirectionalLight.hxx>
81 #include <V3d_PositionalLight.hxx>
82 #include <V3d_SpotLight.hxx>
89 #include <WNT_WClass.hxx>
90 #include <WNT_Window.hxx>
91 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
92 #include <Cocoa_Window.hxx>
94 #include <Xw_Window.hxx>
95 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
96 #include <X11/Xutil.h>
100 //==============================================================================
101 // VIEWER GLOBAL VARIABLES
102 //==============================================================================
104 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
105 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
107 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
108 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
111 static Handle(WNT_Window)& VT_GetWindow() {
112 static Handle(WNT_Window) WNTWin;
115 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
116 static Handle(Cocoa_Window)& VT_GetWindow()
118 static Handle(Cocoa_Window) aWindow;
121 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
122 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
125 static Handle(Xw_Window)& VT_GetWindow(){
126 static Handle(Xw_Window) XWWin;
130 static void VProcessEvents(ClientData,int);
133 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
135 static Handle(Aspect_DisplayConnection) aDisplayConnection;
136 return aDisplayConnection;
139 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
141 GetDisplayConnection() = theDisplayConnection;
144 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
145 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
146 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
147 static OpenGl_Caps ViewerTest_myDefaultCaps;
149 static void OSWindowSetup();
153 Quantity_Color FlatColor;
154 Quantity_Color GradientColor1;
155 Quantity_Color GradientColor2;
156 Aspect_GradientFillMethod FillMethod;
157 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
159 //==============================================================================
160 // EVENT GLOBAL VARIABLES
161 //==============================================================================
163 Standard_Boolean TheIsAnimating = Standard_False;
168 //! Checks if some set is a subset of other set
169 //! @tparam TheSuperSet the type of the superset
170 //! @tparam TheSubSet the type of the subset
171 //! @param theSuperSet the superset
172 //! @param theSubSet the subset to be checked
173 //! @return true if the superset includes subset, or false otherwise
174 template <typename TheSuperSet, typename TheSubSet>
175 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
177 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
180 //! A variable set of keys for command-line options.
181 //! It includes a set of mandatory keys and a set of all possible keys.
182 class CommandOptionKeyVariableSet
185 //! Default constructor
186 CommandOptionKeyVariableSet()
191 //! @param theMandatoryKeySet the set of the mandatory option keys
192 //! @param theAdditionalKeySet the set of additional options that could be omitted
193 CommandOptionKeyVariableSet (
194 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
195 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
196 : myMandatoryKeySet (theMandatoryKeySet)
198 std::set_union (theMandatoryKeySet.begin(),
199 theMandatoryKeySet.end(),
200 theAdditionalKeySet.begin(),
201 theAdditionalKeySet.end(),
202 std::inserter (myFullKeySet, myFullKeySet.begin()));
205 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
206 //! and be contained in the full key set)
207 //! @param theCheckedKeySet the set of option keys to be checked
208 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
210 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
214 //! A set of mandatory command-line option keys
215 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
217 //! A full set of command-line option keys (includes mandatory and additional option keys)
218 ViewerTest_CommandOptionKeySet myFullKeySet;
221 //! Gets some code by its name
222 //! @tparam TheCode the type of a code to be found
223 //! @param theCodeNameMap the map from code names to codes
224 //! @param theCodeName the name of a code to be found
225 //! @param theCode the code to be found
226 //! @return true if a code is found, or false otherwise
227 template <typename TheCode>
228 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
229 TCollection_AsciiString theCodeName,
232 theCodeName.LowerCase();
233 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
235 if (aCodeIterator == theCodeNameMap.end())
239 theCode = aCodeIterator->second;
243 // Defines possible commands related to background changing
244 enum BackgroundCommand
246 BackgroundCommand_Main, //!< The main command that manages other commands through options
247 BackgroundCommand_Image, //!< Sets an image as a background
248 BackgroundCommand_ImageMode, //!< Changes a background image mode
249 BackgroundCommand_Gradient, //!< Sets a gradient as a background
250 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
251 BackgroundCommand_Color, //!< Fills background with a specified color
252 BackgroundCommand_Default //!< Sets the background default color or gradient
255 //! Map from background command names to its codes
256 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
258 //! Creates a map from background command names to its codes
259 //! @return a map from background command names to its codes
260 static BackgroundCommandNameMap createBackgroundCommandNameMap()
262 BackgroundCommandNameMap aBackgroundCommandNameMap;
263 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
264 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
265 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
266 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
267 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
268 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
269 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
270 return aBackgroundCommandNameMap;
273 //! Gets a background command by its name
274 //! @param theBackgroundCommandName the name of the background command
275 //! @param theBackgroundCommand the background command to be found
276 //! @return true if a background command is found, or false otherwise
277 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
278 BackgroundCommand& theBackgroundCommand)
280 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
281 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
284 //! Map from background image fill method names to its codes
285 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
287 //! Creates a map from background image fill method names to its codes
288 //! @return a map from background image fill method names to its codes
289 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
291 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
292 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
293 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
294 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
295 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
296 return aBackgroundImageFillMethodNameMap;
299 //! Gets a background image fill method by its name
300 //! @param theBackgroundImageFillMethodName the name of the background image fill method
301 //! @param theBackgroundImageFillMethod the background image fill method to be found
302 //! @return true if a background image fill method is found, or false otherwise
303 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
304 Aspect_FillMethod& theBackgroundImageFillMethod)
306 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
307 createBackgroundImageFillMethodNameMap();
308 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
309 theBackgroundImageFillMethodName,
310 theBackgroundImageFillMethod);
313 //! Map from background gradient fill method names to its codes
314 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
316 //! Creates a map from background gradient fill method names to its codes
317 //! @return a map from background gradient fill method names to its codes
318 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
320 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
321 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
322 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
323 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
324 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
325 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
326 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
327 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
328 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
329 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
330 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
331 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
332 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
333 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
334 return aBackgroundGradientFillMethodNameMap;
337 //! Gets a gradient fill method by its name
338 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
339 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
340 //! @return true if a gradient fill method is found, or false otherwise
341 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
342 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
344 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
345 createBackgroundGradientFillMethodNameMap();
346 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
347 theBackgroundGradientFillMethodName,
348 theBackgroundGradientFillMethod);
351 //! Changes the background in accordance with passed command line options
352 class BackgroundChanger
355 //! Constructor. Prepares the command parser
358 prepareCommandParser();
361 //! Processes the command line and changes the background
362 //! @param theDrawInterpretor the interpreter of the Draw Harness application
363 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
364 //! @param theCommandLineArguments the array of command line arguments
365 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
366 const Standard_Integer theNumberOfCommandLineArguments,
367 const char* const* const theCommandLineArguments)
369 const char* const aBackgroundCommandName = theCommandLineArguments[0];
370 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
371 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
375 addCommandDescription (aBackgroundCommand);
376 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
377 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
381 //! The type of functions that are able to set gradient background filling
382 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
383 const Quantity_Color& /* theColor2 */,
384 const Aspect_GradientFillMethod /* theGradientMode */);
386 //! The type of functions that are able to fill a background with a specific color
387 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
389 //! the command parser used to parse command line options and its arguments
390 ViewerTest_CmdParser myCommandParser;
392 //! the option key for the command that sets an image as a background
393 ViewerTest_CommandOptionKey myImageOptionKey;
395 //! the option key for the command that sets a background image fill type
396 ViewerTest_CommandOptionKey myImageModeOptionKey;
398 //! the option key for the command that sets a gradient filling for the background
399 ViewerTest_CommandOptionKey myGradientOptionKey;
401 //! the option key for the command that sets a background gradient filling method
402 ViewerTest_CommandOptionKey myGradientModeOptionKey;
404 //! the option key for the command that fills background with a specific color
405 ViewerTest_CommandOptionKey myColorOptionKey;
407 //! the option key for the command that sets default background gradient or color
408 ViewerTest_CommandOptionKey myDefaultOptionKey;
410 //! the option key for the command that sets an environment cubemap as a background
411 ViewerTest_CommandOptionKey myCubeMapOptionKey;
413 //! the option key for the command that defines order of tiles in one image packed cubemap
414 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
416 //! the option key for the command that sets inversion of Z axis for background cubemap
417 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
419 //! the option key for the command that allows skip IBL map generation
420 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
422 //! the variable set of options that are allowed for the old scenario (without any option passed)
423 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
425 //! the variable set of options that are allowed for setting an environment cubemap as background
426 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
428 //! the variable set of options that are allowed for setting an image as a background
429 CommandOptionKeyVariableSet myImageOptionVariableSet;
431 //! the variable set of options that are allowed for setting a background image fill type
432 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
434 //! the variable set of options that are allowed for setting a gradient filling for the background
435 CommandOptionKeyVariableSet myGradientOptionVariableSet;
437 //! the variable set of options that are allowed for setting a background gradient filling method
438 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
440 //! the variable set of options that are allowed for filling a background with a specific color
441 CommandOptionKeyVariableSet myColorOptionVariableSet;
443 //! the variable set of options that are allowed for setting a default background gradient
444 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
446 //! the variable set of options that are allowed for setting a default background color
447 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
449 //! the variable set of options that are allowed for printing help
450 CommandOptionKeyVariableSet myHelpOptionVariableSet;
452 //! Adds options to command parser
453 void addOptionsToCommandParser()
455 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
456 "filename of image used as background");
457 myImageModeOptionKey = myCommandParser.AddOption (
458 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
459 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
460 "sets background gradient starting and ending colors");
461 myGradientModeOptionKey =
462 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
463 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
464 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
465 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
466 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
468 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
469 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
470 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
471 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
472 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
475 //! Creates option sets used to determine if a passed option set is valid or not
476 void createOptionSets()
478 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
479 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
480 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
482 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
483 aCubeMapOptionSet.insert (myCubeMapOptionKey);
484 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
485 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
486 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
487 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
488 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
490 ViewerTest_CommandOptionKeySet anImageOptionSet;
491 anImageOptionSet.insert (myImageOptionKey);
492 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
493 anImageModeOptionSet.insert (myImageModeOptionKey);
494 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
495 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
497 ViewerTest_CommandOptionKeySet aGradientOptionSet;
498 aGradientOptionSet.insert (myGradientOptionKey);
499 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
500 aGradientModeOptionSet.insert (myGradientModeOptionKey);
501 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
502 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
504 ViewerTest_CommandOptionKeySet aColorOptionSet;
505 aColorOptionSet.insert (myColorOptionKey);
506 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
508 aGradientOptionSet.insert (myDefaultOptionKey);
509 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
510 aColorOptionSet.insert (myDefaultOptionKey);
511 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
513 ViewerTest_CommandOptionKeySet aHelpOptionSet;
514 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
515 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
518 //! Prepares the command parser. Adds options and creates option sets used to determine
519 //! if a passed option set is valid or not
520 void prepareCommandParser()
522 addOptionsToCommandParser();
526 //! Adds a command description to the command parser
527 //! @param theBackgroundCommand the key of the command which description is added to the command parser
528 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
530 std::string aDescription;
531 bool isMainCommand = false;
532 switch (theBackgroundCommand)
534 case BackgroundCommand_Main:
535 aDescription = "Command: vbackground (changes background or some background settings)";
536 isMainCommand = true;
538 case BackgroundCommand_Image:
539 aDescription = "Command: vsetbg (loads image as a background)";
541 case BackgroundCommand_ImageMode:
542 aDescription = "Command: vsetbgmode (changes background fill type)";
544 case BackgroundCommand_Gradient:
545 aDescription = "Command: vsetgradientbg (mounts gradient background)";
547 case BackgroundCommand_GradientMode:
548 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
550 case BackgroundCommand_Color:
551 aDescription = "Command: vsetcolorbg (sets color background)";
553 case BackgroundCommand_Default:
554 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
561 aDescription += "\nThis command is obsolete. Use vbackground instead.";
563 myCommandParser.SetDescription (aDescription);
566 //! Check if a viewer is needed to be initialized
567 //! @param theBackgroundCommand the key of the command that changes the background
568 //! @return true if processing was successful, or false otherwise
569 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
571 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
572 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
573 const bool aViewerIsNotNeeded =
574 (theBackgroundCommand == BackgroundCommand_Default)
575 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
576 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
577 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
578 return !aViewerIsNotNeeded;
581 //! Check if a viewer is initialized
582 //! @param theBackgroundCommandName the name of the command that changes the background
583 //! @param theDrawInterpretor the interpreter of the Draw Harness application
584 //! @return true if a viewer is initialized, or false otherwise
585 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
586 Draw_Interpretor& theDrawInterpretor)
588 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
589 if (anAISContext.IsNull())
591 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
597 //! Processes command options
598 //! @param theBackgroundCommandName the name of the command that changes the background
599 //! @param theBackgroundCommand the key of the command that changes the background
600 //! @param theDrawInterpretor the interpreter of the Draw Harness application
601 //! @return true if processing was successful, or false otherwise
602 bool processCommandOptions (const char* const theBackgroundCommandName,
603 const BackgroundCommand theBackgroundCommand,
604 Draw_Interpretor& theDrawInterpretor) const
606 if (myCommandParser.HasNoOption())
608 return printHelp (theBackgroundCommandName, theDrawInterpretor);
610 if (checkViewerIsNeeded (theBackgroundCommand)
611 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
615 if (myCommandParser.HasOnlyUnnamedOption())
617 return processUnnamedOption (theBackgroundCommand);
619 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
622 //! Processes the unnamed option
623 //! @param theBackgroundCommand the key of the command that changes the background
624 //! @return true if processing was successful, or false otherwise
625 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
627 switch (theBackgroundCommand)
629 case BackgroundCommand_Main:
631 case BackgroundCommand_Image:
632 return processImageUnnamedOption();
633 case BackgroundCommand_ImageMode:
634 return processImageModeUnnamedOption();
635 case BackgroundCommand_Gradient:
636 return processGradientUnnamedOption();
637 case BackgroundCommand_GradientMode:
638 return processGradientModeUnnamedOption();
639 case BackgroundCommand_Color:
640 return processColorUnnamedOption();
641 case BackgroundCommand_Default:
642 return processDefaultUnnamedOption();
648 //! Processes the image unnamed option
649 //! @return true if processing was successful, or false otherwise
650 bool processImageUnnamedOption() const
652 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
653 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
654 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
658 std::string anImageFileName;
659 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
663 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
664 if (aNumberOfImageUnnamedOptionArguments == 2)
666 std::string anImageModeString;
667 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
671 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
676 setImage (anImageFileName.c_str(), anImageMode);
680 //! Processes the image mode unnamed option
681 //! @return true if processing was successful, or false otherwise
682 bool processImageModeUnnamedOption() const
684 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
687 //! Processes the gradient unnamed option
688 //! @param theSetGradient the function used to set a background gradient filling
689 //! @return true if processing was successful, or false otherwise
690 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
692 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
693 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
694 if (aNumberOfGradientUnnamedOptionArguments < 2)
699 Standard_Integer anArgumentIndex = 0;
700 Quantity_Color aColor1;
701 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
705 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
710 Quantity_Color aColor2;
711 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
715 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
720 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
721 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
723 std::string anGradientModeString;
725 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
727 anGradientModeString))
731 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
737 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
741 theSetGradient (aColor1, aColor2, aGradientMode);
745 //! Processes the gradient mode unnamed option
746 //! @return true if processing was successful, or false otherwise
747 bool processGradientModeUnnamedOption() const
749 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
752 //! Processes the color unnamed option
753 //! @param theSetColor the function used to set a background color
754 //! @return true if processing was successful, or false otherwise
755 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
757 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
760 //! Processes the default back unnamed option
761 //! @return true if processing was successful, or false otherwise
762 bool processDefaultUnnamedOption() const
764 if (processGradientUnnamedOption (setDefaultGradient))
768 return processColorUnnamedOption (setDefaultColor);
771 //! Processes named options
772 //! @param theBackgroundCommandName the name of the command that changes the background
773 //! @param theBackgroundCommand the key of the command that changes the background
774 //! @param theDrawInterpretor the interpreter of the Draw Harness application
775 //! @return true if processing was successful, or false otherwise
776 bool processNamedOptions (const char* const theBackgroundCommandName,
777 const BackgroundCommand theBackgroundCommand,
778 Draw_Interpretor& theDrawInterpretor) const
780 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
781 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
782 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
784 return processCubeMapOptionSet();
786 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
787 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
789 return processImageOptionSet();
791 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
792 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
794 return processImageModeOptionSet();
796 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
797 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
799 return processGradientOptionSet();
801 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
802 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
804 return processGradientModeOptionSet();
806 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
807 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
809 return processColorOptionSet();
811 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
812 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
813 && (theBackgroundCommand == BackgroundCommand_Default)))
815 return processDefaultGradientOptionSet();
817 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
818 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
820 return processDefaultColorOptionSet();
822 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
824 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
829 //! Process the cubemap option set in named and unnamed case.
830 //! @return true if processing was successful, or false otherwise
831 bool processCubeMapOptionSet() const
833 NCollection_Array1<TCollection_AsciiString> aFilePaths;
835 if (!processCubeMapOptions (aFilePaths))
840 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
842 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
844 if (!processCubeMapOrderOptions (anOrder))
850 bool aZIsInverted = false;
851 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
853 if (!processCubeMapInvertedZOptionSet())
860 bool aToGenPBREnv = true;
861 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
863 if (!processCubeMapDoNotGenPBREnvOptionSet())
867 aToGenPBREnv = false;
870 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
874 //! Processes the image option set
875 //! @return true if processing was successful, or false otherwise
876 bool processImageOptionSet() const
878 std::string anImageFileName;
879 if (!processImageOption (anImageFileName))
883 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
884 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
888 setImage (anImageFileName.c_str(), anImageMode);
892 //! Processes the image mode option set
893 //! @return true if processing was successful, or false otherwise
894 bool processImageModeOptionSet() const
896 return processImageModeOptionSet (myImageModeOptionKey);
899 //! Processes the image mode option set
900 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
901 //! @return true if processing was successful, or false otherwise
902 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
904 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
905 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
909 setImageMode (anImageMode);
913 //! Processes the gradient option set
914 //! @param theSetGradient the function used to set a background gradient filling
915 //! @return true if processing was successful, or false otherwise
916 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
918 Quantity_Color aColor1;
919 Quantity_Color aColor2;
920 if (!processGradientOption (aColor1, aColor2))
924 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
925 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
929 theSetGradient (aColor1, aColor2, aGradientMode);
933 //! Processes the gradient mode option set
934 //! @return true if processing was successful, or false otherwise
935 bool processGradientModeOptionSet() const
937 return processGradientModeOptionSet (myGradientModeOptionKey);
940 //! Processes the gradient mode option set
941 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
942 //! @return true if processing was successful, or false otherwise
943 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
945 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
946 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
950 setGradientMode (aGradientMode);
954 //! Processes the color option set
955 //! @param theSetColor the function used to set a background color
956 //! @return true if processing was successful, or false otherwise
957 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
959 return processColorOptionSet (myColorOptionKey, theSetColor);
962 //! Processes the default color option set
963 //! @return true if processing was successful, or false otherwise
964 bool processDefaultGradientOptionSet() const
966 return processGradientOptionSet (setDefaultGradient);
969 //! Processes the default gradient option set
970 //! @return true if processing was successful, or false otherwise
971 bool processDefaultColorOptionSet() const
973 return processColorOptionSet (setDefaultColor);
976 //! Processes the color option set
977 //! @param theColorOptionKey the key of the option that is interpreted as a color option
978 //! @param theSetColor the function used to set a background color
979 //! @return true if processing was successful, or false otherwise
980 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
981 SetColorFunction* const theSetColor = setColor) const
983 Quantity_Color aColor;
984 if (!processColorOption (theColorOptionKey, aColor))
988 theSetColor (aColor);
992 //! Processes the help option set
993 //! @param theBackgroundCommandName the name of the command that changes the background
994 //! @param theDrawInterpretor the interpreter of the Draw Harness application
995 //! @return true if processing was successful, or false otherwise
996 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
998 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
999 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1000 if (aNumberOfHelpOptionArguments != 0)
1004 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1007 //! Processes the cubemap option
1008 //! @param theFilePaths the array of filenames of cubemap sides
1009 //! @return true if processing was successful, or false otherwise
1010 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1012 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1014 if (aNumberOfCubeMapOptionArguments != 1
1015 && aNumberOfCubeMapOptionArguments != 6)
1020 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1022 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1024 std::string aCubeMapFileName;
1025 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1029 theFilePaths[i] = aCubeMapFileName.c_str();
1035 //! Processes the inverted z cubemap option
1036 //! @return true if processing was successful, or false otherwise
1037 bool processCubeMapInvertedZOptionSet () const
1039 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1040 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1042 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1050 //! Processes the option allowing to skip IBM maps generation
1051 //! @return true if processing was successful, or false otherwise
1052 bool processCubeMapDoNotGenPBREnvOptionSet() const
1054 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1055 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1057 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1065 //! Processes the tiles order option
1066 //! @param theOrder the array of indexes if cubemap sides in tile grid
1067 //! @return true if processing was successful, or false otherwise
1068 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1070 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1071 myCubeMapOrderOptionKey);
1073 if (aNumberOfCubeMapOrderOptionArguments != 6)
1079 for (unsigned int i = 0; i < 6; ++i)
1081 std::string anOrderItem;
1082 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1087 theOrder.Set (Graphic3d_CubeMapSide (i),
1088 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1091 return theOrder.IsValid();
1094 //! Processes the image option
1095 //! @param theImageFileName the filename of the image to be used as a background
1096 //! @return true if processing was successful, or false otherwise
1097 bool processImageOption (std::string& theImageFileName) const
1099 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1101 if (aNumberOfImageOptionArguments != 1)
1105 std::string anImageFileName;
1106 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1110 theImageFileName = anImageFileName;
1114 //! Processes the image mode option
1115 //! @param theImageMode the fill type used for a background image
1116 //! @return true if processing was successful, or false otherwise
1117 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1119 return processImageModeOption (myImageModeOptionKey, theImageMode);
1122 //! Processes the image mode option
1123 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1124 //! @param theImageMode the fill type used for a background image
1125 //! @return true if processing was successful, or false otherwise
1126 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1127 Aspect_FillMethod& theImageMode) const
1129 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1132 //! Processes the gradient option
1133 //! @param theColor1 the gradient starting color
1134 //! @param theColor2 the gradient ending color
1135 //! @return true if processing was successful, or false otherwise
1136 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1138 Standard_Integer anArgumentIndex = 0;
1139 Quantity_Color aColor1;
1140 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1144 Quantity_Color aColor2;
1145 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1149 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1150 myGradientOptionKey);
1151 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1155 theColor1 = aColor1;
1156 theColor2 = aColor2;
1160 //! Processes the gradient mode option
1161 //! @param theGradientMode the fill method used for a background gradient filling
1162 //! @return true if processing was successful, or false otherwise
1163 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1165 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1168 //! Processes the gradient mode option
1169 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1170 //! @param theGradientMode the fill method used for a background gradient filling
1171 //! @return true if processing was successful, or false otherwise
1172 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1173 Aspect_GradientFillMethod& theGradientMode) const
1175 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1178 //! Processes some mode option
1179 //! @tparam TheMode the type of a mode to be processed
1180 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1181 //! @param theMode a mode to be processed
1182 //! @return true if processing was successful, or false otherwise
1183 template <typename TheMode>
1184 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1185 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1186 TheMode& /* theMode */),
1187 TheMode& theMode) const
1189 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1191 if (aNumberOfModeOptionArguments != 1)
1195 std::string aModeString;
1196 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1200 TheMode aMode = TheMode();
1201 if (!theGetModeByName (aModeString.c_str(), aMode))
1209 //! Processes the color option
1210 //! @param theColor a color used for filling a background
1211 //! @return true if processing was successful, or false otherwise
1212 bool processColorOption (Quantity_Color& theColor) const
1214 return processColorOption (myColorOptionKey, theColor);
1217 //! Processes the color option
1218 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1219 //! @param theColor a color used for filling a background
1220 //! @return true if processing was successful, or false otherwise
1221 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1223 Standard_Integer anArgumentIndex = 0;
1224 Quantity_Color aColor;
1225 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1229 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1231 if (anArgumentIndex != aNumberOfColorOptionArguments)
1239 //! Prints helping message
1240 //! @param theBackgroundCommandName the name of the command that changes the background
1241 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1242 //! @return true if printing was successful, or false otherwise
1243 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1245 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1248 //! Sets the cubemap as a background
1249 //! @param theFileNames the array of filenames of packed or multifile cubemap
1250 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1251 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1252 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
1253 bool theZIsInverted = false,
1254 bool theToGenPBREnv = true)
1256 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1257 Handle(Graphic3d_CubeMap) aCubeMap;
1259 if (theFileNames.Size() == 1)
1260 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1262 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1264 aCubeMap->SetZInversion (theZIsInverted);
1266 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1267 aCubeMap->GetParams()->SetRepeat(Standard_False);
1268 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1270 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
1273 //! Sets the image as a background
1274 //! @param theImageFileName the filename of the image to be used as a background
1275 //! @param theImageMode the fill type used for a background image
1276 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1278 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1279 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1282 //! Sets the fill type used for a background image
1283 //! @param theImageMode the fill type used for a background image
1284 static void setImageMode (const Aspect_FillMethod theImageMode)
1286 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1287 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1290 //! Sets the gradient filling for a background
1291 //! @param theColor1 the gradient starting color
1292 //! @param theColor2 the gradient ending color
1293 //! @param theGradientMode the fill method used for a background gradient filling
1294 static void setGradient (const Quantity_Color& theColor1,
1295 const Quantity_Color& theColor2,
1296 const Aspect_GradientFillMethod theGradientMode)
1298 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1299 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1302 //! Sets the fill method used for a background gradient filling
1303 //! @param theGradientMode the fill method used for a background gradient filling
1304 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1306 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1307 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1310 //! Sets the color used for filling a background
1311 //! @param theColor the color used for filling a background
1312 static void setColor (const Quantity_Color& theColor)
1314 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1315 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1316 aCurrentView->SetBackgroundColor (theColor);
1317 aCurrentView->Update();
1320 //! Sets the gradient filling for a background in a default viewer
1321 //! @param theColor1 the gradient starting color
1322 //! @param theColor2 the gradient ending color
1323 //! @param theGradientMode the fill method used for a background gradient filling
1324 static void setDefaultGradient (const Quantity_Color& theColor1,
1325 const Quantity_Color& theColor2,
1326 const Aspect_GradientFillMethod theGradientMode)
1328 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1329 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1330 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1331 setDefaultGradient();
1334 //! Sets the color used for filling a background in a default viewer
1335 //! @param theColor the color used for filling a background
1336 static void setDefaultColor (const Quantity_Color& theColor)
1338 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1339 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1340 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1341 ViewerTest_DefaultBackground.FlatColor = theColor;
1342 setDefaultGradient();
1346 //! Sets the gradient filling for a background in a default viewer.
1347 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1348 static void setDefaultGradient()
1350 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1351 anInteractiveContextIterator (ViewerTest_myContexts);
1352 anInteractiveContextIterator.More();
1353 anInteractiveContextIterator.Next())
1355 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1356 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1357 ViewerTest_DefaultBackground.GradientColor2,
1358 ViewerTest_DefaultBackground.FillMethod);
1362 //! Sets the color used for filling a background in a default viewer.
1363 //! The color value is taken from ViewerTest_DefaultBackground structure
1364 static void setDefaultColor()
1366 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1367 anInteractiveContextIterator (ViewerTest_myContexts);
1368 anInteractiveContextIterator.More();
1369 anInteractiveContextIterator.Next())
1371 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1372 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1379 //==============================================================================
1382 static LRESULT WINAPI ViewerWindowProc(
1387 static LRESULT WINAPI AdvViewerWindowProc(
1395 //==============================================================================
1398 //==============================================================================
1400 const Handle(WNT_WClass)& ViewerTest::WClass()
1402 static Handle(WNT_WClass) theWClass;
1404 if (theWClass.IsNull())
1406 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
1407 CS_VREDRAW | CS_HREDRAW, 0, 0,
1408 ::LoadCursor (NULL, IDC_ARROW));
1414 //==============================================================================
1415 //function : CreateName
1416 //purpose : Create numerical name for new object in theMap
1417 //==============================================================================
1418 template <typename ObjectType>
1419 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1420 const TCollection_AsciiString& theDefaultString)
1422 if (theObjectMap.IsEmpty())
1423 return theDefaultString + TCollection_AsciiString(1);
1425 Standard_Integer aNextKey = 1;
1426 Standard_Boolean isFound = Standard_False;
1429 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1430 // Look for objects with default names
1431 if (theObjectMap.IsBound1(aStringKey))
1436 isFound = Standard_True;
1439 return theDefaultString + TCollection_AsciiString(aNextKey);
1442 //==============================================================================
1443 //structure : ViewerTest_Names
1444 //purpose : Allow to operate with full view name: driverName/viewerName/viewName
1445 //==============================================================================
1446 struct ViewerTest_Names
1449 TCollection_AsciiString myDriverName;
1450 TCollection_AsciiString myViewerName;
1451 TCollection_AsciiString myViewName;
1455 const TCollection_AsciiString& GetDriverName () const
1457 return myDriverName;
1459 void SetDriverName (const TCollection_AsciiString& theDriverName)
1461 myDriverName = theDriverName;
1463 const TCollection_AsciiString& GetViewerName () const
1465 return myViewerName;
1467 void SetViewerName (const TCollection_AsciiString& theViewerName)
1469 myViewerName = theViewerName;
1471 const TCollection_AsciiString& GetViewName () const
1475 void SetViewName (const TCollection_AsciiString& theViewName)
1477 myViewName = theViewName;
1480 //===========================================================================
1481 //function : Constructor for ViewerTest_Names
1482 //purpose : Get view, viewer, driver names from custom string
1483 //===========================================================================
1485 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1487 TCollection_AsciiString aName(theInputString);
1488 if (theInputString.IsEmpty())
1490 // Get current configuration
1491 if (ViewerTest_myDrivers.IsEmpty())
1492 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1493 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1495 myDriverName = ViewerTest_myDrivers.Find2
1496 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1498 if(ViewerTest_myContexts.IsEmpty())
1500 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1501 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1505 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
1508 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
1512 // There is at least view name
1513 Standard_Integer aParserNumber = 0;
1514 for (Standard_Integer i = 0; i < 3; ++i)
1516 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1517 if(aParserPos != -1)
1520 aName.Split(aParserPos-1);
1525 if (aParserNumber == 0)
1528 if (!ViewerTest::GetAISContext().IsNull())
1530 myDriverName = ViewerTest_myDrivers.Find2
1531 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1532 myViewerName = ViewerTest_myContexts.Find2
1533 (ViewerTest::GetAISContext());
1537 // There is no opened contexts here, need to create names for viewer and driver
1538 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1539 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1541 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1542 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1544 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1546 else if (aParserNumber == 1)
1548 // Here is viewerName/viewName
1549 if (!ViewerTest::GetAISContext().IsNull())
1550 myDriverName = ViewerTest_myDrivers.Find2
1551 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1554 // There is no opened contexts here, need to create name for driver
1555 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1556 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1558 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1560 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1564 //Here is driverName/viewerName/viewName
1565 myDriverName = TCollection_AsciiString(aName);
1567 TCollection_AsciiString aViewerName(theInputString);
1568 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1569 myViewerName = TCollection_AsciiString(aViewerName);
1571 myViewName = TCollection_AsciiString(theInputString);
1577 //==============================================================================
1578 //function : FindContextByView
1579 //purpose : Find AIS_InteractiveContext by View
1580 //==============================================================================
1582 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1584 Handle(AIS_InteractiveContext) anAISContext;
1586 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1587 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1589 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1590 return anIter.Key2();
1592 return anAISContext;
1595 //==============================================================================
1596 //function : IsWindowOverlapped
1597 //purpose : Check if theWindow overlapp another view
1598 //==============================================================================
1600 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1601 const Standard_Integer thePxTop,
1602 const Standard_Integer thePxRight,
1603 const Standard_Integer thePxBottom,
1604 TCollection_AsciiString& theViewId)
1606 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1607 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1609 Standard_Integer aTop = 0,
1613 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1614 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1615 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1616 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1617 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1619 theViewId = anIter.Key1();
1620 return Standard_True;
1623 return Standard_False;
1626 // Workaround: to create and delete non-orthographic views outside ViewerTest
1627 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1629 ViewerTest_myViews.UnBind1 (theName);
1632 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1633 const Handle(V3d_View)& theView)
1635 ViewerTest_myViews.Bind (theName, theView);
1638 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1640 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1643 //! Auxiliary tool performing continuous redraws of specified window.
1644 class ViewerTest_ContinuousRedrawer
1647 //! Return global instance.
1648 static ViewerTest_ContinuousRedrawer& Instance()
1650 static ViewerTest_ContinuousRedrawer aRedrawer;
1656 ~ViewerTest_ContinuousRedrawer()
1662 void Start (const Handle(Aspect_Window)& theWindow,
1663 Standard_Real theTargetFps)
1665 if (myWindow != theWindow
1666 || myTargetFps != theTargetFps)
1669 myWindow = theWindow;
1670 myTargetFps = theTargetFps;
1672 if (myThread.GetId() == 0)
1675 myThread.Run (this);
1680 void Stop (const Handle(Aspect_Window)& theWindow = NULL)
1682 if (!theWindow.IsNull()
1683 && myWindow != theWindow)
1689 Standard_Mutex::Sentry aLock (myMutex);
1702 Handle(Aspect_DisplayConnection) aDisp = new Aspect_DisplayConnection();
1705 Standard_Real aTimeOld = 0.0;
1706 const Standard_Real aTargetDur = myTargetFps > 0.0 ? 1.0 / myTargetFps : -1.0;
1710 Standard_Mutex::Sentry aLock (myMutex);
1716 if (myTargetFps > 0.0)
1718 const Standard_Real aTimeNew = aTimer.ElapsedTime();
1719 const Standard_Real aDuration = aTimeNew - aTimeOld;
1720 if (aDuration >= aTargetDur)
1722 myWindow->InvalidateContent (aDisp);
1723 aTimeOld = aTimeNew;
1728 myWindow->InvalidateContent (aDisp);
1731 OSD::MilliSecSleep (1);
1735 //! Thread creation callback.
1736 static Standard_Address doThreadWrapper (Standard_Address theData)
1738 ViewerTest_ContinuousRedrawer* aThis = (ViewerTest_ContinuousRedrawer* )theData;
1739 aThis->doThreadLoop();
1743 //! Empty constructor.
1744 ViewerTest_ContinuousRedrawer()
1745 : myThread (doThreadWrapper),
1750 Handle(Aspect_Window) myWindow;
1751 OSD_Thread myThread;
1752 Standard_Mutex myMutex;
1753 Standard_Real myTargetFps;
1754 volatile bool myToStop;
1757 //==============================================================================
1758 //function : ViewerInit
1759 //purpose : Create the window viewer and initialize all the global variable
1760 //==============================================================================
1762 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1763 const Standard_Integer thePxTop,
1764 const Standard_Integer thePxWidth,
1765 const Standard_Integer thePxHeight,
1766 const TCollection_AsciiString& theViewName,
1767 const TCollection_AsciiString& theDisplayName,
1768 const Handle(V3d_View)& theViewToClone)
1770 // Default position and dimension of the viewer window.
1771 // Note that left top corner is set to be sufficiently small to have
1772 // window fit in the small screens (actual for remote desktops, see #23003).
1773 // The position corresponds to the window's client area, thus some
1774 // gap is added for window frame to be visible.
1775 Standard_Integer aPxLeft = 20;
1776 Standard_Integer aPxTop = 40;
1777 Standard_Integer aPxWidth = 409;
1778 Standard_Integer aPxHeight = 409;
1779 Standard_Boolean toCreateViewer = Standard_False;
1780 if (!theViewToClone.IsNull())
1782 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1785 Handle(OpenGl_GraphicDriver) aGraphicDriver;
1786 ViewerTest_Names aViewNames(theViewName);
1787 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
1788 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1791 aPxLeft = thePxLeft;
1794 if (thePxWidth != 0)
1795 aPxWidth = thePxWidth;
1796 if (thePxHeight != 0)
1797 aPxHeight = thePxHeight;
1799 // Get graphic driver (create it or get from another view)
1800 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1803 // Get connection string
1804 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1805 if (!theDisplayName.IsEmpty())
1807 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1811 ::Display* aDispX = NULL;
1812 // create dedicated display connection instead of reusing Tk connection
1813 // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
1814 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1815 Tcl_Interp* aTclInterp = aCommands.Interp();
1816 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1817 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1818 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1821 (void)theDisplayName; // avoid warning on unused argument
1822 SetDisplayConnection (new Aspect_DisplayConnection ());
1825 if (Draw_VirtualWindows)
1827 // don't waste the time waiting for VSync when window is not displayed on the screen
1828 ViewerTest_myDefaultCaps.swapInterval = 0;
1829 // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
1830 //ViewerTest_myDefaultCaps.buffersNoSwap = true;
1832 aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection(), false);
1833 aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
1834 aGraphicDriver->InitContext();
1836 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1837 toCreateViewer = Standard_True;
1841 aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
1844 //Dispose the window if input parameters are default
1845 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
1847 Standard_Integer aTop = 0,
1854 // Get screen resolution
1855 #if defined(_WIN32) || defined(__WIN32__)
1857 GetClientRect(GetDesktopWindow(), &aWindowSize);
1858 aScreenHeight = aWindowSize.bottom;
1859 aScreenWidth = aWindowSize.right;
1860 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1861 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1863 Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
1864 aScreenWidth = WidthOfScreen(aScreen);
1865 aScreenHeight = HeightOfScreen(aScreen);
1868 TCollection_AsciiString anOverlappedViewId("");
1870 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
1872 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1874 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1875 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1877 if (aBottom + aPxHeight + 40 > aScreenHeight)
1884 aPxTop = aBottom + 40;
1887 aPxLeft = aRight + 20;
1892 TCollection_AsciiString aTitle("3D View - ");
1893 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1895 // Change name of current active window
1896 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
1898 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
1902 Handle(V3d_Viewer) a3DViewer;
1903 // If it's the single view, we first look for empty context
1904 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1906 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1907 anIter(ViewerTest_myContexts);
1909 ViewerTest::SetAISContext (anIter.Value());
1910 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
1912 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1914 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1915 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
1917 else if (a3DViewer.IsNull())
1919 toCreateViewer = Standard_True;
1920 a3DViewer = new V3d_Viewer(aGraphicDriver);
1921 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1922 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1923 ViewerTest_DefaultBackground.GradientColor2,
1924 ViewerTest_DefaultBackground.FillMethod);
1927 // AIS context setup
1928 if (ViewerTest::GetAISContext().IsNull() ||
1929 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1931 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
1932 ViewerTest::SetAISContext (aContext);
1933 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1937 ViewerTest::ResetEventManager();
1942 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
1943 Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
1945 aPxWidth, aPxHeight,
1946 Quantity_NOC_BLACK);
1947 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1948 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1950 aPxWidth, aPxHeight);
1951 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
1953 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1956 aPxWidth, aPxHeight);
1958 VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
1961 Handle(V3d_View) aView;
1962 if (!theViewToClone.IsNull())
1964 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
1968 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
1971 aView->SetWindow (VT_GetWindow());
1972 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
1974 ViewerTest::CurrentView(aView);
1975 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
1977 // Setup for X11 or NT
1980 // Set parameters for V3d_View and V3d_Viewer
1981 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1982 aV3dView->SetComputedMode(Standard_False);
1984 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1987 a3DViewer->SetDefaultLights();
1988 a3DViewer->SetLightOn();
1991 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1994 ::Display* aDispX = GetDisplayConnection()->GetDisplay();
1995 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1999 VT_GetWindow()->Map();
2001 // Set the handle of created view in the event manager
2002 ViewerTest::ResetEventManager();
2004 ViewerTest::CurrentView()->Redraw();
2007 a3DViewer.Nullify();
2009 return aViewNames.GetViewName();
2012 //==============================================================================
2013 //function : RedrawAllViews
2014 //purpose : Redraw all created views
2015 //==============================================================================
2016 void ViewerTest::RedrawAllViews()
2018 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
2019 for (; aViewIt.More(); aViewIt.Next())
2021 const Handle(V3d_View)& aView = aViewIt.Key2();
2026 //==============================================================================
2028 //purpose : Create the window viewer and initialize all the global variable
2029 // Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
2030 //==============================================================================
2032 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2034 TCollection_AsciiString aViewName, aDisplayName;
2035 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
2036 Handle(V3d_View) aCopyFrom;
2037 TCollection_AsciiString aName, aValue;
2039 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
2041 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2042 TCollection_AsciiString anArgCase = anArg;
2043 anArgCase.LowerCase();
2044 if (anArgIt + 1 < theArgsNb
2045 && anArgCase == "-name")
2047 aViewName = theArgVec[++anArgIt];
2049 else if (anArgIt + 1 < theArgsNb
2050 && (anArgCase == "-left"
2051 || anArgCase == "-l"))
2053 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2055 else if (anArgIt + 1 < theArgsNb
2056 && (anArgCase == "-top"
2057 || anArgCase == "-t"))
2059 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2061 else if (anArgIt + 1 < theArgsNb
2062 && (anArgCase == "-width"
2063 || anArgCase == "-w"))
2065 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2067 else if (anArgIt + 1 < theArgsNb
2068 && (anArgCase == "-height"
2069 || anArgCase == "-h"))
2071 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2073 else if (anArgCase == "-exitonclose")
2075 ViewerTest_EventManager::ToExitOnCloseView() = true;
2076 if (anArgIt + 1 < theArgsNb
2077 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
2082 else if (anArgCase == "-closeonescape"
2083 || anArgCase == "-closeonesc")
2085 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
2086 if (anArgIt + 1 < theArgsNb
2087 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
2092 else if (anArgCase == "-2d_mode"
2093 || anArgCase == "-2dmode"
2094 || anArgCase == "-2d")
2096 bool toEnable = true;
2097 if (anArgIt + 1 < theArgsNb
2098 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2102 is2dMode = toEnable ? 1 : 0;
2104 else if (anArgIt + 1 < theArgsNb
2105 && (anArgCase == "-disp"
2106 || anArgCase == "-display"))
2108 aDisplayName = theArgVec[++anArgIt];
2110 else if (!ViewerTest::CurrentView().IsNull()
2111 && aCopyFrom.IsNull()
2112 && (anArgCase == "-copy"
2113 || anArgCase == "-clone"
2114 || anArgCase == "-cloneactive"
2115 || anArgCase == "-cloneactiveview"))
2117 aCopyFrom = ViewerTest::CurrentView();
2120 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2123 if (aName == "name")
2127 else if (aName == "l"
2130 aPxLeft = aValue.IntegerValue();
2132 else if (aName == "t"
2135 aPxTop = aValue.IntegerValue();
2137 else if (aName == "disp"
2138 || aName == "display")
2140 aDisplayName = aValue;
2142 else if (aName == "w"
2143 || aName == "width")
2145 aPxWidth = aValue.IntegerValue();
2147 else if (aName == "h"
2148 || aName == "height")
2150 aPxHeight = aValue.IntegerValue();
2154 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2158 else if (aViewName.IsEmpty())
2164 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2169 #if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2170 if (!aDisplayName.IsEmpty())
2172 aDisplayName.Clear();
2173 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
2177 ViewerTest_Names aViewNames (aViewName);
2178 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
2180 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2181 theDi.Eval (aCommand.ToCString());
2184 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2189 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
2190 aViewName, aDisplayName, aCopyFrom);
2193 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2199 //! Parse HLR algo type.
2200 static Standard_Boolean parseHlrAlgoType (const char* theName,
2201 Prs3d_TypeOfHLR& theType)
2203 TCollection_AsciiString aName (theName);
2205 if (aName == "polyalgo")
2207 theType = Prs3d_TOH_PolyAlgo;
2209 else if (aName == "algo")
2211 theType = Prs3d_TOH_Algo;
2215 return Standard_False;
2217 return Standard_True;
2220 //==============================================================================
2222 //purpose : hidden lines removal algorithm
2223 //==============================================================================
2225 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2227 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2228 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2231 Message::SendFail ("Error: no active viewer");
2235 Standard_Boolean hasHlrOnArg = Standard_False;
2236 Standard_Boolean hasShowHiddenArg = Standard_False;
2237 Standard_Boolean isHLROn = Standard_False;
2238 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2239 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2240 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2241 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
2243 TCollection_AsciiString anArg (argv[anArgIter]);
2245 if (anUpdateTool.parseRedrawMode (anArg))
2249 else if (anArg == "-showhidden"
2250 && anArgIter + 1 < argc
2251 && ViewerTest::ParseOnOff (argv[anArgIter + 1], toShowHidden))
2254 hasShowHiddenArg = Standard_True;
2257 else if ((anArg == "-type"
2259 || anArg == "-algotype")
2260 && anArgIter + 1 < argc
2261 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2266 else if (!hasHlrOnArg
2267 && ViewerTest::ParseOnOff (argv[anArgIter], isHLROn))
2269 hasHlrOnArg = Standard_True;
2273 else if (!hasShowHiddenArg
2274 && ViewerTest::ParseOnOff(argv[anArgIter], toShowHidden))
2276 hasShowHiddenArg = Standard_True;
2281 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
2287 di << "HLR: " << aView->ComputedMode() << "\n";
2288 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2290 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2292 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2293 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2294 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2296 anUpdateTool.Invalidate();
2300 Standard_Boolean toRecompute = Standard_False;
2301 if (aTypeOfHLR != Prs3d_TOH_NotSet
2302 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
2304 toRecompute = Standard_True;
2305 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2307 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2309 toRecompute = Standard_True;
2312 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
2316 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
2321 if (aView->ComputedMode() && isHLROn && toRecompute)
2323 AIS_ListOfInteractive aListOfShapes;
2324 aCtx->DisplayedObjects (aListOfShapes);
2325 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
2327 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
2329 aCtx->Redisplay (aShape, Standard_False);
2334 aView->SetComputedMode (isHLROn);
2338 //==============================================================================
2339 //function : VHLRType
2340 //purpose : change type of using HLR algorithm
2341 //==============================================================================
2343 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
2345 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2346 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2349 Message::SendFail ("Error: no active viewer");
2353 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2354 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2355 AIS_ListOfInteractive aListOfShapes;
2356 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
2358 TCollection_AsciiString anArg (argv[anArgIter]);
2360 if (anUpdateTool.parseRedrawMode (anArg))
2364 else if ((anArg == "-type"
2366 || anArg == "-algotype")
2367 && anArgIter + 1 < argc
2368 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2374 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2375 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2381 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
2382 TCollection_AsciiString aName (argv[anArgIter]);
2383 if (!aMap.IsBound2 (aName))
2385 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
2389 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2390 if (aShape.IsNull())
2392 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
2395 aListOfShapes.Append (aShape);
2399 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2401 Message::SendFail ("Syntax error: wrong number of arguments");
2405 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2408 aCtx->DisplayedObjects (aListOfShapes);
2409 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2412 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2414 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2415 if (aShape.IsNull())
2420 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2421 && aView->ComputedMode();
2423 || aShape->TypeOfHLR() != aTypeOfHLR)
2425 aShape->SetTypeOfHLR (aTypeOfHLR);
2429 aCtx->Redisplay (aShape, Standard_False);
2435 //==============================================================================
2436 //function : FindViewIdByWindowHandle
2437 //purpose : Find theView Id in the map of views by window handle
2438 //==============================================================================
2439 #if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2440 TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
2442 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2443 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2445 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
2446 if (aWindowHandle == theWindowHandle)
2447 return anIter.Key1();
2449 return TCollection_AsciiString("");
2453 //! Make the view active
2454 void ActivateView (const TCollection_AsciiString& theViewName,
2455 Standard_Boolean theToUpdate = Standard_True)
2457 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2463 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2464 if (!anAISContext.IsNull())
2466 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
2468 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
2471 ViewerTest::CurrentView (aView);
2472 ViewerTest::SetAISContext (anAISContext);
2473 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
2475 VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
2476 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2477 VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
2479 VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
2481 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2484 ViewerTest::CurrentView()->Redraw();
2489 //==============================================================================
2490 //function : RemoveView
2492 //==============================================================================
2493 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2494 const Standard_Boolean theToRemoveContext)
2496 if (!ViewerTest_myViews.IsBound2 (theView))
2501 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2502 RemoveView (aViewName, theToRemoveContext);
2505 //==============================================================================
2506 //function : RemoveView
2507 //purpose : Close and remove view from display, clear maps if neccessary
2508 //==============================================================================
2509 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2511 if (!ViewerTest_myViews.IsBound1(theViewName))
2513 Message::SendFail() << "Wrong view name";
2517 // Activate another view if it's active now
2518 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2520 if (ViewerTest_myViews.Extent() > 1)
2522 TCollection_AsciiString aNewViewName;
2523 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2524 anIter.More(); anIter.Next())
2526 if (anIter.Key1() != theViewName)
2528 aNewViewName = anIter.Key1();
2532 ActivateView (aNewViewName);
2536 VT_GetWindow().Nullify();
2537 ViewerTest::CurrentView (Handle(V3d_View)());
2538 if (isContextRemoved)
2540 Handle(AIS_InteractiveContext) anEmptyContext;
2541 ViewerTest::SetAISContext(anEmptyContext);
2547 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2548 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
2549 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2550 aRedrawer.Stop (aView->Window());
2552 // Remove view resources
2553 ViewerTest_myViews.UnBind1(theViewName);
2554 aView->Window()->Unmap();
2557 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2558 XFlush (GetDisplayConnection()->GetDisplay());
2561 // Keep context opened only if the closed view is last to avoid
2562 // unused empty contexts
2563 if (!aCurrentContext.IsNull())
2565 // Check if there are more difined views in the viewer
2566 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2567 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
2569 // Remove driver if there is no viewers that use it
2570 Standard_Boolean isRemoveDriver = Standard_True;
2571 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2572 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2574 if (aCurrentContext != anIter.Key2() &&
2575 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2577 isRemoveDriver = Standard_False;
2582 aCurrentContext->RemoveAll (Standard_False);
2585 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2586 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2587 Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
2591 ViewerTest_myContexts.UnBind2(aCurrentContext);
2594 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
2595 if (ViewerTest_EventManager::ToExitOnCloseView())
2597 Draw_Interprete ("exit");
2601 //==============================================================================
2603 //purpose : Remove the view defined by its name
2604 //==============================================================================
2606 static int VClose (Draw_Interpretor& /*theDi*/,
2607 Standard_Integer theArgsNb,
2608 const char** theArgVec)
2610 NCollection_List<TCollection_AsciiString> aViewList;
2613 TCollection_AsciiString anArg (theArgVec[1]);
2615 if (anArg.IsEqual ("ALL")
2616 || anArg.IsEqual ("*"))
2618 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2619 anIter.More(); anIter.Next())
2621 aViewList.Append (anIter.Key1());
2623 if (aViewList.IsEmpty())
2625 std::cout << "No view to close\n";
2631 ViewerTest_Names aViewName (theArgVec[1]);
2632 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2634 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
2637 aViewList.Append (aViewName.GetViewName());
2642 // close active view
2643 if (ViewerTest::CurrentView().IsNull())
2645 Message::SendFail ("Error: no active view");
2648 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
2651 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
2652 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2653 anIter.More(); anIter.Next())
2655 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
2661 //==============================================================================
2662 //function : VActivate
2663 //purpose : Activate the view defined by its ID
2664 //==============================================================================
2666 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2670 theDi.Eval("vviewlist");
2674 TCollection_AsciiString aNameString;
2675 Standard_Boolean toUpdate = Standard_True;
2676 Standard_Boolean toActivate = Standard_True;
2677 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
2679 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2682 && anArg == "-noupdate")
2684 toUpdate = Standard_False;
2687 && aNameString.IsEmpty()
2690 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
2691 VT_GetWindow().Nullify();
2692 ViewerTest::CurrentView (Handle(V3d_View)());
2693 ViewerTest::ResetEventManager();
2694 theDi << theArgVec[0] << ": all views are inactive\n";
2695 toActivate = Standard_False;
2698 && aNameString.IsEmpty())
2700 aNameString = theArgVec[anArgIter];
2704 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2713 else if (aNameString.IsEmpty())
2715 Message::SendFail ("Syntax error: wrong number of arguments");
2719 // Check if this view exists in the viewer with the driver
2720 ViewerTest_Names aViewNames (aNameString);
2721 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2723 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
2727 // Check if it is active already
2728 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2730 theDi << theArgVec[0] << ": the view is active already\n";
2734 ActivateView (aViewNames.GetViewName(), toUpdate);
2738 //==============================================================================
2739 //function : VViewList
2740 //purpose : Print current list of views per viewer and graphic driver ID
2741 // shared between viewers
2742 //==============================================================================
2744 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2748 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
2749 << "Usage: " << theArgVec[0] << " name";
2752 if (ViewerTest_myContexts.Size() < 1)
2755 Standard_Boolean isTreeView =
2756 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
2760 theDi << theArgVec[0] <<":\n";
2763 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2764 aDriverIter.More(); aDriverIter.Next())
2767 theDi << aDriverIter.Key1() << ":\n";
2769 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2770 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2772 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
2776 TCollection_AsciiString aContextName(aContextIter.Key1());
2777 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2780 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2781 aViewIter.More(); aViewIter.Next())
2783 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
2785 TCollection_AsciiString aViewName(aViewIter.Key1());
2788 if (aViewIter.Value() == ViewerTest::CurrentView())
2789 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
2791 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2795 theDi << aViewName << " ";
2805 //==============================================================================
2806 //function : GetMousePosition
2808 //==============================================================================
2809 void ViewerTest::GetMousePosition (Standard_Integer& theX,
2810 Standard_Integer& theY)
2812 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
2814 theX = aViewCtrl->LastMousePosition().x();
2815 theY = aViewCtrl->LastMousePosition().y();
2819 //==============================================================================
2820 //function : VViewProj
2821 //purpose : Switch view projection
2822 //==============================================================================
2823 static int VViewProj (Draw_Interpretor& ,
2824 Standard_Integer theNbArgs,
2825 const char** theArgVec)
2827 static Standard_Boolean isYup = Standard_False;
2828 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2831 Message::SendFail ("Error: no active viewer");
2835 TCollection_AsciiString aCmdName (theArgVec[0]);
2836 Standard_Boolean isGeneralCmd = Standard_False;
2837 if (aCmdName == "vfront")
2839 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2841 else if (aCmdName == "vback")
2843 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2845 else if (aCmdName == "vtop")
2847 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2849 else if (aCmdName == "vbottom")
2851 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2853 else if (aCmdName == "vleft")
2855 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2857 else if (aCmdName == "vright")
2859 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2861 else if (aCmdName == "vaxo")
2863 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2867 isGeneralCmd = Standard_True;
2868 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2870 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2871 anArgCase.LowerCase();
2872 if (anArgCase == "-zup")
2874 isYup = Standard_False;
2876 else if (anArgCase == "-yup")
2878 isYup = Standard_True;
2880 else if (anArgCase == "-front"
2881 || anArgCase == "front"
2882 || anArgCase == "-f"
2883 || anArgCase == "f")
2885 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2887 else if (anArgCase == "-back"
2888 || anArgCase == "back"
2889 || anArgCase == "-b"
2890 || anArgCase == "b")
2892 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2894 else if (anArgCase == "-top"
2895 || anArgCase == "top"
2896 || anArgCase == "-t"
2897 || anArgCase == "t")
2899 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2901 else if (anArgCase == "-bottom"
2902 || anArgCase == "bottom"
2903 || anArgCase == "-bot"
2904 || anArgCase == "bot"
2905 || anArgCase == "-b"
2906 || anArgCase == "b")
2908 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2910 else if (anArgCase == "-left"
2911 || anArgCase == "left"
2912 || anArgCase == "-l"
2913 || anArgCase == "l")
2915 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2917 else if (anArgCase == "-right"
2918 || anArgCase == "right"
2919 || anArgCase == "-r"
2920 || anArgCase == "r")
2922 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2924 else if (anArgCase == "-axoleft"
2925 || anArgCase == "-leftaxo"
2926 || anArgCase == "axoleft"
2927 || anArgCase == "leftaxo")
2929 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
2931 else if (anArgCase == "-axo"
2932 || anArgCase == "axo"
2933 || anArgCase == "-a"
2935 || anArgCase == "-axoright"
2936 || anArgCase == "-rightaxo"
2937 || anArgCase == "axoright"
2938 || anArgCase == "rightaxo")
2940 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2942 else if (anArgCase == "+x")
2944 aView->SetProj (V3d_Xpos, isYup);
2946 else if (anArgCase == "-x")
2948 aView->SetProj (V3d_Xneg, isYup);
2950 else if (anArgCase == "+y")
2952 aView->SetProj (V3d_Ypos, isYup);
2954 else if (anArgCase == "-y")
2956 aView->SetProj (V3d_Yneg, isYup);
2958 else if (anArgCase == "+z")
2960 aView->SetProj (V3d_Zpos, isYup);
2962 else if (anArgCase == "-z")
2964 aView->SetProj (V3d_Zneg, isYup);
2966 else if (anArgCase == "+x+y+z")
2968 aView->SetProj (V3d_XposYposZpos, isYup);
2970 else if (anArgCase == "+x+y-z")
2972 aView->SetProj (V3d_XposYposZneg, isYup);
2974 else if (anArgCase == "+x-y+z")
2976 aView->SetProj (V3d_XposYnegZpos, isYup);
2978 else if (anArgCase == "+x-y-z")
2980 aView->SetProj (V3d_XposYnegZneg, isYup);
2982 else if (anArgCase == "-x+y+z")
2984 aView->SetProj (V3d_XnegYposZpos, isYup);
2986 else if (anArgCase == "-x+y-z")
2988 aView->SetProj (V3d_XnegYposZneg, isYup);
2990 else if (anArgCase == "-x-y+z")
2992 aView->SetProj (V3d_XnegYnegZpos, isYup);
2994 else if (anArgCase == "-x-y-z")
2996 aView->SetProj (V3d_XnegYnegZneg, isYup);
2998 else if (anArgCase == "+x+y")
3000 aView->SetProj (V3d_XposYpos, isYup);
3002 else if (anArgCase == "+x-y")
3004 aView->SetProj (V3d_XposYneg, isYup);
3006 else if (anArgCase == "-x+y")
3008 aView->SetProj (V3d_XnegYpos, isYup);
3010 else if (anArgCase == "-x-y")
3012 aView->SetProj (V3d_XnegYneg, isYup);
3014 else if (anArgCase == "+x+z")
3016 aView->SetProj (V3d_XposZpos, isYup);
3018 else if (anArgCase == "+x-z")
3020 aView->SetProj (V3d_XposZneg, isYup);
3022 else if (anArgCase == "-x+z")
3024 aView->SetProj (V3d_XnegZpos, isYup);
3026 else if (anArgCase == "-x-z")
3028 aView->SetProj (V3d_XnegZneg, isYup);
3030 else if (anArgCase == "+y+z")
3032 aView->SetProj (V3d_YposZpos, isYup);
3034 else if (anArgCase == "+y-z")
3036 aView->SetProj (V3d_YposZneg, isYup);
3038 else if (anArgCase == "-y+z")
3040 aView->SetProj (V3d_YnegZpos, isYup);
3042 else if (anArgCase == "-y-z")
3044 aView->SetProj (V3d_YnegZneg, isYup);
3046 else if (anArgIter + 1 < theNbArgs
3047 && anArgCase == "-frame"
3048 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
3050 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
3051 aFrameDef.LowerCase();
3052 gp_Dir aRight, anUp;
3053 if (aFrameDef.Value (2) == aFrameDef.Value (4))
3055 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3059 if (aFrameDef.Value (2) == 'x')
3061 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
3063 else if (aFrameDef.Value (2) == 'y')
3065 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
3067 else if (aFrameDef.Value (2) == 'z')
3069 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
3073 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3077 if (aFrameDef.Value (4) == 'x')
3079 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
3081 else if (aFrameDef.Value (4) == 'y')
3083 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
3085 else if (aFrameDef.Value (4) == 'z')
3087 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
3091 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3095 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3096 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3097 const gp_Dir aDir = anUp.Crossed (aRight);
3098 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3099 aCamera->SetDirection (aDir);
3100 aCamera->SetUp (anUp);
3101 aCamera->OrthogonalizeUp();
3103 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3108 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3117 Message::SendFail ("Syntax error: wrong number of arguments");
3123 //==============================================================================
3125 //purpose : Dsiplay help on viewer Keyboead and mouse commands
3126 //Draw arg : No args
3127 //==============================================================================
3129 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3131 di << "=========================\n";
3132 di << "F : FitAll\n";
3133 di << "T : TopView\n";
3134 di << "B : BottomView\n";
3135 di << "R : RightView\n";
3136 di << "L : LeftView\n";
3137 di << "A : AxonometricView\n";
3138 di << "D : ResetView\n";
3140 di << "=========================\n";
3141 di << "S : Shading\n";
3142 di << "W : Wireframe\n";
3143 di << "H : HiddenLineRemoval\n";
3144 di << "U : Unset display mode\n";
3145 di << "Delete : Remove selection from viewer\n";
3147 di << "=========================\n";
3148 di << "Selection mode \n";
3149 di << "0 : Shape\n";
3150 di << "1 : Vertex\n";
3154 di << "5 : Shell\n";
3155 di << "6 : Solid\n";
3156 di << "7 : Compound\n";
3158 di << "=========================\n";
3159 di << "< : Hilight next detected\n";
3160 di << "> : Hilight previous detected\n";
3167 static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3172 if (ViewerTest_myViews.IsEmpty())
3174 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
3181 // Delete view from map of views
3182 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3187 if (LOWORD(wParam) == WA_CLICKACTIVE
3188 || LOWORD(wParam) == WA_ACTIVE
3189 || ViewerTest::CurrentView().IsNull())
3191 // Activate inactive window
3192 if (VT_GetWindow().IsNull()
3193 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3195 ActivateView (FindViewIdByWindowHandle (theWinHandle));
3202 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
3208 static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
3213 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3216 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
3224 BeginPaint(theWinHandle, &aPaint);
3225 EndPaint (theWinHandle, &aPaint);
3226 ViewerTest::CurrentEventManager()->ProcessExpose();
3231 ViewerTest::CurrentEventManager()->ProcessConfigure();
3238 switch (aView->RenderingParams().StereoMode)
3240 case Graphic3d_StereoMode_RowInterlaced:
3241 case Graphic3d_StereoMode_ColumnInterlaced:
3242 case Graphic3d_StereoMode_ChessBoard:
3244 // track window moves to reverse stereo pair
3245 aView->MustBeResized();
3257 const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
3258 if (aVKey != Aspect_VKey_UNKNOWN)
3260 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3261 if (theMsg == WM_KEYDOWN)
3263 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
3267 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
3269 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3276 case WM_LBUTTONDOWN:
3277 case WM_MBUTTONDOWN:
3278 case WM_RBUTTONDOWN:
3280 const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3281 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3282 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3286 case WM_LBUTTONDOWN:
3287 aButton = Aspect_VKeyMouse_LeftButton;
3290 case WM_MBUTTONDOWN:
3291 aButton = Aspect_VKeyMouse_MiddleButton;
3294 case WM_RBUTTONDOWN:
3295 aButton = Aspect_VKeyMouse_RightButton;
3298 if (theMsg == WM_LBUTTONDOWN
3299 || theMsg == WM_MBUTTONDOWN
3300 || theMsg == WM_RBUTTONDOWN)
3302 if (aButton == Aspect_VKeyMouse_LeftButton)
3304 TheIsAnimating = Standard_False;
3307 SetFocus (theWinHandle);
3308 SetCapture(theWinHandle);
3309 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
3314 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
3316 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3321 const int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
3322 const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
3323 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3324 Graphic3d_Vec2i aPos (int(short(LOWORD(lParam))), int(short(HIWORD(lParam))));
3325 POINT aCursorPnt = { aPos.x(), aPos.y() };
3326 if (ScreenToClient (theWinHandle, &aCursorPnt))
3328 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3331 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3332 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3337 Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3338 Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (wParam);
3339 Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(wParam);
3341 // don't make a slide-show from input events - fetch the actual mouse cursor position
3343 aCursor.cbSize = sizeof(aCursor);
3344 if (::GetCursorInfo (&aCursor) != FALSE)
3346 POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
3347 if (ScreenToClient (theWinHandle, &aCursorPnt))
3349 // as we override mouse position, we need overriding also mouse state
3350 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3351 aButtons = WNT_Window::MouseButtonsAsync();
3352 aFlags = WNT_Window::MouseKeyFlagsAsync();
3356 if (VT_GetWindow().IsNull()
3357 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3359 // mouse move events come also for inactive windows
3363 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3364 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
3369 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
3375 //==============================================================================
3376 //function : ViewerMainLoop
3377 //purpose : Get a Event on the view and dispatch it
3378 //==============================================================================
3380 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
3382 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3383 if (aViewCtrl.IsNull()
3389 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3391 std::cout << "Start picking\n";
3395 while (aViewCtrl->ToPickPoint())
3397 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3398 if (GetMessageW (&aMsg, NULL, 0, 0))
3400 TranslateMessage (&aMsg);
3401 DispatchMessageW (&aMsg);
3405 std::cout << "Picking done\n";
3409 #elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
3411 int min( int a, int b )
3419 int max( int a, int b )
3427 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
3429 static XEvent aReport;
3430 const Standard_Boolean toPick = theNbArgs > 0;
3433 if (ViewerTest::CurrentEventManager().IsNull())
3437 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3440 Display* aDisplay = GetDisplayConnection()->GetDisplay();
3441 XNextEvent (aDisplay, &aReport);
3443 // Handle event for the chosen display connection
3444 switch (aReport.type)
3448 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3451 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3452 return toPick ? 0 : 1;
3458 // Activate inactive view
3459 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
3460 if (aWindow != aReport.xfocus.window)
3462 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3468 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
3469 if (anXWindow == aReport.xexpose.window)
3471 ViewerTest::CurrentEventManager()->ProcessExpose();
3474 // remove all the ExposureMask and process them at once
3475 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3477 if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
3485 case ConfigureNotify:
3487 // remove all the StructureNotifyMask and process them at once
3488 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
3489 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3491 if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
3497 if (anXWindow == aReport.xconfigure.window)
3499 ViewerTest::CurrentEventManager()->ProcessConfigure();
3506 XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
3507 const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
3508 const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
3509 if (aVKey != Aspect_VKey_UNKNOWN)
3511 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3512 if (aReport.type == KeyPress)
3514 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
3518 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
3520 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3527 const Graphic3d_Vec2i aPos (aReport.xbutton.x, aReport.xbutton.y);
3528 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3529 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3530 if (aReport.xbutton.button == Button1)
3532 aButton = Aspect_VKeyMouse_LeftButton;
3534 if (aReport.xbutton.button == Button2)
3536 aButton = Aspect_VKeyMouse_MiddleButton;
3538 if (aReport.xbutton.button == Button3)
3540 aButton = Aspect_VKeyMouse_RightButton;
3543 if (aReport.xbutton.state & ControlMask)
3545 aFlags |= Aspect_VKeyFlags_CTRL;
3547 if (aReport.xbutton.state & ShiftMask)
3549 aFlags |= Aspect_VKeyFlags_SHIFT;
3551 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3553 aFlags |= Aspect_VKeyFlags_ALT;
3556 if (aReport.xbutton.button == Button4
3557 || aReport.xbutton.button == Button5)
3559 if (aReport.type != ButtonPress)
3564 const double aDeltaF = (aReport.xbutton.button == Button4 ? 1.0 : -1.0);
3565 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3567 else if (aReport.type == ButtonPress)
3569 if (aButton == Aspect_VKeyMouse_LeftButton)
3571 TheIsAnimating = Standard_False;
3573 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
3577 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
3579 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3584 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
3585 if (anXWindow != aReport.xmotion.window)
3590 // remove all the ButtonMotionMask and process them at once
3591 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3593 if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
3599 Graphic3d_Vec2i aPos (aReport.xmotion.x, aReport.xmotion.y);
3600 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
3601 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3602 if ((aReport.xmotion.state & Button1Mask) != 0)
3604 aButtons |= Aspect_VKeyMouse_LeftButton;
3606 else if ((aReport.xmotion.state & Button2Mask) != 0)
3608 aButtons |= Aspect_VKeyMouse_MiddleButton;
3610 else if ((aReport.xmotion.state & Button3Mask) != 0)
3612 aButtons |= Aspect_VKeyMouse_RightButton;
3615 if (aReport.xmotion.state & ControlMask)
3617 aFlags |= Aspect_VKeyFlags_CTRL;
3619 if (aReport.xmotion.state & ShiftMask)
3621 aFlags |= Aspect_VKeyFlags_SHIFT;
3623 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3625 aFlags |= Aspect_VKeyFlags_ALT;
3628 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3629 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3633 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
3636 //==============================================================================
3637 //function : VProcessEvents
3638 //purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
3639 //==============================================================================
3640 static void VProcessEvents (ClientData theDispX, int)
3642 Display* aDispX = (Display* )theDispX;
3643 Handle(Aspect_DisplayConnection) aDispConn;
3644 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3645 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
3647 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3648 if (aDispConnTmp->GetDisplay() == aDispX)
3650 aDispConn = aDispConnTmp;
3654 if (aDispConn.IsNull())
3656 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
3660 // process new events in queue
3661 SetDisplayConnection (aDispConn);
3663 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
3665 const int anEventResult = ViewerMainLoop (0, NULL);
3666 if (anEventResult == 0)
3671 aNbRemain = XPending (aDispX);
3672 if (++anEventIter >= aNbEventsMax
3679 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3680 // it is possible that new events will arrive to queue before the end of this callback
3681 // so that either this callback should go into an infinite loop (blocking processing of other events)
3682 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3683 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3687 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3688 aDummyEvent.type = ClientMessage;
3689 aDummyEvent.xclient.format = 32;
3690 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3694 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3696 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3701 //==============================================================================
3702 //function : OSWindowSetup
3703 //purpose : Setup for the X11 window to be able to cath the event
3704 //==============================================================================
3707 static void OSWindowSetup()
3709 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
3712 Window window = VT_GetWindow()->XWindow();
3713 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
3714 Display *aDisplay = GetDisplayConnection()->GetDisplay();
3715 XSynchronize(aDisplay, 1);
3717 // X11 : For keyboard on SUN
3719 wmhints.flags = InputHint;
3722 XSetWMHints( aDisplay, window, &wmhints);
3724 XSelectInput( aDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask |
3725 ButtonPressMask | ButtonReleaseMask |
3726 StructureNotifyMask |
3728 Button1MotionMask | Button2MotionMask |
3729 Button3MotionMask | FocusChangeMask
3731 Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
3732 XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
3734 XSynchronize(aDisplay, 0);
3742 //==============================================================================
3745 //==============================================================================
3747 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
3749 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3752 Message::SendFail ("Error: no active viewer");
3756 Standard_Boolean toFit = Standard_True;
3757 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3758 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3760 TCollection_AsciiString anArg (theArgv[anArgIter]);
3762 if (anUpdateTool.parseRedrawMode (anArg))
3766 else if (anArg == "-selected")
3768 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3769 toFit = Standard_False;
3773 Message::SendFail() << "Syntax error at '" << anArg << "'";
3779 aView->FitAll (0.01, Standard_False);
3784 //=======================================================================
3785 //function : VFitArea
3786 //purpose : Fit view to show area located between two points
3787 // : given in world 2D or 3D coordinates.
3788 //=======================================================================
3789 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3791 Handle(V3d_View) aView = ViewerTest::CurrentView();
3794 Message::SendFail ("Error: No active viewer");
3799 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3800 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3804 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3805 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3806 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3807 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3809 else if (theArgNb == 7)
3811 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3812 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3813 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3814 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3815 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3816 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3820 Message::SendFail ("Syntax error: Invalid number of arguments");
3821 theDI.PrintHelp(theArgVec[0]);
3825 // Convert model coordinates to view space
3826 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3827 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3828 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3830 // Determine fit area
3831 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3832 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3834 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3836 if (aDiagonal < Precision::Confusion())
3838 Message::SendFail ("Error: view area is too small");
3842 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3846 //==============================================================================
3848 //purpose : ZFitall, no DRAW arguments
3849 //Draw arg : No args
3850 //==============================================================================
3851 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
3853 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3855 if (aCurrentView.IsNull())
3857 Message::SendFail ("Error: no active viewer");
3863 aCurrentView->ZFitAll();
3864 aCurrentView->Redraw();
3868 Standard_Real aScale = 1.0;
3872 aScale = Draw::Atoi (theArgVec[1]);
3875 aCurrentView->ZFitAll (aScale);
3876 aCurrentView->Redraw();
3881 //==============================================================================
3882 //function : VRepaint
3884 //==============================================================================
3885 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
3887 Handle(V3d_View) aView = ViewerTest::CurrentView();
3890 Message::SendFail ("Error: no active viewer");
3894 Standard_Boolean isImmediateUpdate = Standard_False;
3895 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3897 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3899 if (anArg == "-immediate"
3902 isImmediateUpdate = Standard_True;
3903 if (anArgIter + 1 < theArgNb
3904 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
3909 else if (anArg == "-continuous"
3912 || anArg == "-framerate")
3914 Standard_Real aFps = -1.0;
3915 if (anArgIter + 1 < theArgNb
3916 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
3918 aFps = Draw::Atof (theArgVec[++anArgIter]);
3921 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3922 if (Abs (aFps) >= 1.0)
3924 aRedrawer.Start (aView->Window(), aFps);
3933 Message::SendFail() << "Syntax error at '" << anArg << "'";
3938 if (isImmediateUpdate)
3940 aView->RedrawImmediate();
3949 //==============================================================================
3951 //purpose : Remove all the object from the viewer
3952 //Draw arg : No args
3953 //==============================================================================
3955 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3957 Handle(V3d_View) V = ViewerTest::CurrentView();
3959 ViewerTest::Clear();
3963 //==============================================================================
3966 //==============================================================================
3968 static int VPick (Draw_Interpretor& ,
3969 Standard_Integer theNbArgs,
3970 const char** theArgVec)
3972 if (ViewerTest::CurrentView().IsNull())
3979 Message::SendFail ("Syntax error: wrong number of arguments");
3983 while (ViewerMainLoop (theNbArgs, theArgVec))
3994 //! Changes the background
3995 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3996 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3997 //! @param theCommandLineArguments the array of command line arguments
3998 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3999 static int vbackground (Draw_Interpretor& theDrawInterpretor,
4000 const Standard_Integer theNumberOfCommandLineArguments,
4001 const char** const theCommandLineArguments)
4003 if (theNumberOfCommandLineArguments < 1)
4007 BackgroundChanger aBackgroundChanger;
4008 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
4009 theNumberOfCommandLineArguments,
4010 theCommandLineArguments))
4012 theDrawInterpretor << "Wrong command arguments.\n"
4014 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
4022 //==============================================================================
4024 //purpose : View Scaling
4025 //==============================================================================
4027 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4029 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4030 if ( V3dView.IsNull() ) return 1;
4033 di << argv[0] << "Invalid number of arguments\n";
4036 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
4039 //==============================================================================
4040 //function : VZBuffTrihedron
4042 //==============================================================================
4044 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
4045 Standard_Integer theArgNb,
4046 const char** theArgVec)
4048 Handle(V3d_View) aView = ViewerTest::CurrentView();
4051 Message::SendFail ("Error: no active viewer");
4055 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
4057 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
4058 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
4059 Quantity_Color aLabelsColor = Quantity_NOC_WHITE;
4060 Quantity_Color anArrowColorX = Quantity_NOC_RED;
4061 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
4062 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
4063 Standard_Real aScale = 0.1;
4064 Standard_Real aSizeRatio = 0.8;
4065 Standard_Real anArrowDiam = 0.05;
4066 Standard_Integer aNbFacets = 12;
4067 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4069 Standard_CString anArg = theArgVec[anArgIter];
4070 TCollection_AsciiString aFlag (anArg);
4072 if (anUpdateTool.parseRedrawMode (aFlag))
4076 else if (aFlag == "-on")
4080 else if (aFlag == "-off")
4082 aView->TriedronErase();
4085 else if (aFlag == "-pos"
4086 || aFlag == "-position"
4087 || aFlag == "-corner")
4089 if (++anArgIter >= theArgNb)
4091 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4095 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
4096 aPosName.LowerCase();
4097 if (aPosName == "center")
4099 aPosition = Aspect_TOTP_CENTER;
4101 else if (aPosName == "left_lower"
4102 || aPosName == "lower_left"
4103 || aPosName == "leftlower"
4104 || aPosName == "lowerleft")
4106 aPosition = Aspect_TOTP_LEFT_LOWER;
4108 else if (aPosName == "left_upper"
4109 || aPosName == "upper_left"
4110 || aPosName == "leftupper"
4111 || aPosName == "upperleft")
4113 aPosition = Aspect_TOTP_LEFT_UPPER;
4115 else if (aPosName == "right_lower"
4116 || aPosName == "lower_right"
4117 || aPosName == "rightlower"
4118 || aPosName == "lowerright")
4120 aPosition = Aspect_TOTP_RIGHT_LOWER;
4122 else if (aPosName == "right_upper"
4123 || aPosName == "upper_right"
4124 || aPosName == "rightupper"
4125 || aPosName == "upperright")
4127 aPosition = Aspect_TOTP_RIGHT_UPPER;
4131 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
4135 else if (aFlag == "-type")
4137 if (++anArgIter >= theArgNb)
4139 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4143 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
4144 aTypeName.LowerCase();
4145 if (aTypeName == "wireframe"
4146 || aTypeName == "wire")
4148 aVisType = V3d_WIREFRAME;
4150 else if (aTypeName == "zbuffer"
4151 || aTypeName == "shaded")
4153 aVisType = V3d_ZBUFFER;
4157 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
4160 else if (aFlag == "-scale")
4162 if (++anArgIter >= theArgNb)
4164 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4168 aScale = Draw::Atof (theArgVec[anArgIter]);
4170 else if (aFlag == "-size"
4171 || aFlag == "-sizeratio")
4173 if (++anArgIter >= theArgNb)
4175 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4179 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
4181 else if (aFlag == "-arrowdiam"
4182 || aFlag == "-arrowdiameter")
4184 if (++anArgIter >= theArgNb)
4186 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4190 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
4192 else if (aFlag == "-nbfacets")
4194 if (++anArgIter >= theArgNb)
4196 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4200 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
4202 else if (aFlag == "-colorlabel"
4203 || aFlag == "-colorlabels")
4205 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4206 theArgVec + anArgIter + 1,
4210 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4213 anArgIter += aNbParsed;
4215 else if (aFlag == "-colorarrowx")
4217 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4218 theArgVec + anArgIter + 1,
4222 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4225 anArgIter += aNbParsed;
4227 else if (aFlag == "-colorarrowy")
4229 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4230 theArgVec + anArgIter + 1,
4234 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4237 anArgIter += aNbParsed;
4239 else if (aFlag == "-colorarrowz")
4241 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4242 theArgVec + anArgIter + 1,
4246 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4249 anArgIter += aNbParsed;
4253 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4258 aView->ZBufferTriedronSetup (anArrowColorX.Name(), anArrowColorY.Name(), anArrowColorZ.Name(),
4259 aSizeRatio, anArrowDiam, aNbFacets);
4260 aView->TriedronDisplay (aPosition, aLabelsColor.Name(), aScale, aVisType);
4265 //==============================================================================
4266 //function : VRotate
4267 //purpose : Camera Rotating
4268 //==============================================================================
4270 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4272 Handle(V3d_View) aView = ViewerTest::CurrentView();
4275 Message::SendFail ("Error: no active viewer");
4279 Standard_Boolean hasFlags = Standard_False;
4280 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4282 Standard_CString anArg (theArgVec[anArgIter]);
4283 TCollection_AsciiString aFlag (anArg);
4285 if (aFlag == "-mousestart"
4286 || aFlag == "-mousefrom")
4288 hasFlags = Standard_True;
4289 if (anArgIter + 2 >= theArgNb)
4291 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4295 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4296 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4297 aView->StartRotation (anX, anY);
4299 else if (aFlag == "-mousemove")
4301 hasFlags = Standard_True;
4302 if (anArgIter + 2 >= theArgNb)
4304 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4308 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4309 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4310 aView->Rotation (anX, anY);
4312 else if (theArgNb != 4
4315 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4324 else if (theArgNb == 4)
4326 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4327 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4328 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4329 aView->Rotate (anAX, anAY, anAZ);
4332 else if (theArgNb == 7)
4334 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4335 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4336 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4338 Standard_Real anX = Draw::Atof (theArgVec[4]);
4339 Standard_Real anY = Draw::Atof (theArgVec[5]);
4340 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4342 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
4346 Message::SendFail ("Error: Invalid number of arguments");
4350 //==============================================================================
4352 //purpose : View zoom in / out (relative to current zoom)
4353 //==============================================================================
4355 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4356 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4357 if ( V3dView.IsNull() ) {
4362 Standard_Real coef = Draw::Atof(argv[1]);
4363 if ( coef <= 0.0 ) {
4364 di << argv[1] << "Invalid value\n";
4367 V3dView->SetZoom( Draw::Atof(argv[1]) );
4370 di << argv[0] << " Invalid number of arguments\n";
4375 //==============================================================================
4377 //purpose : View panning (in pixels)
4378 //==============================================================================
4380 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4381 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4382 if ( V3dView.IsNull() ) return 1;
4385 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
4388 di << argv[0] << " Invalid number of arguments\n";
4393 //==============================================================================
4395 //purpose : Place the point (in pixels) at the center of the window
4396 //==============================================================================
4397 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4399 Handle(V3d_View) aView = ViewerTest::CurrentView();
4402 Message::SendFail ("Error: no active viewer");
4408 Message::SendFail ("Syntax error: wrong number of arguments");
4412 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4417 static int VColorScale (Draw_Interpretor& theDI,
4418 Standard_Integer theArgNb,
4419 const char** theArgVec)
4421 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4422 Handle(V3d_View) aView = ViewerTest::CurrentView();
4423 if (aContext.IsNull())
4425 Message::SendFail ("Error: no active viewer");
4430 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
4434 Handle(AIS_ColorScale) aColorScale;
4435 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
4437 // find existing object
4438 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4439 if (aColorScale.IsNull())
4441 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
4448 if (aColorScale.IsNull())
4450 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4454 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4455 << "Min range: " << aColorScale->GetMin() << "\n"
4456 << "Max range: " << aColorScale->GetMax() << "\n"
4457 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4458 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4459 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4460 << "Color scale title: " << aColorScale->GetTitle() << "\n"
4461 << "Label position: ";
4462 switch (aColorScale->GetLabelPosition())
4464 case Aspect_TOCSP_NONE:
4467 case Aspect_TOCSP_LEFT:
4470 case Aspect_TOCSP_RIGHT:
4473 case Aspect_TOCSP_CENTER:
4474 theDI << "Center\n";
4480 if (aColorScale.IsNull())
4482 aColorScale = new AIS_ColorScale();
4483 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4484 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4487 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
4488 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
4490 Standard_CString anArg = theArgVec[anArgIter];
4491 TCollection_AsciiString aFlag (anArg);
4493 if (anUpdateTool.parseRedrawMode (aFlag))
4497 else if (aFlag == "-range")
4499 if (anArgIter + 3 >= theArgNb)
4501 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
4505 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4506 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4507 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
4508 if (!aRangeMin.IsRealValue()
4509 || !aRangeMax.IsRealValue())
4511 Message::SendFail ("Syntax error: the range values should be real");
4514 else if (!aNbIntervals.IsIntegerValue())
4516 Message::SendFail ("Syntax error: the number of intervals should be integer");
4520 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4521 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
4523 else if (aFlag == "-font")
4525 if (anArgIter + 1 >= theArgNb)
4527 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4530 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4531 if (!aFontArg.IsIntegerValue())
4533 Message::SendFail ("Syntax error: HeightFont value should be integer");
4537 aColorScale->SetTextHeight (aFontArg.IntegerValue());
4540 else if (aFlag == "-textpos")
4542 if (anArgIter + 1 >= theArgNb)
4544 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4548 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4549 aTextPosArg.LowerCase();
4550 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
4551 if (aTextPosArg == "none")
4553 aLabPosition = Aspect_TOCSP_NONE;
4555 else if (aTextPosArg == "left")
4557 aLabPosition = Aspect_TOCSP_LEFT;
4559 else if (aTextPosArg == "right")
4561 aLabPosition = Aspect_TOCSP_RIGHT;
4563 else if (aTextPosArg == "center")
4565 aLabPosition = Aspect_TOCSP_CENTER;
4569 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
4572 aColorScale->SetLabelPosition (aLabPosition);
4574 else if (aFlag == "-logarithmic"
4577 if (anArgIter + 1 >= theArgNb)
4579 Message::SendFail() << "Synta error at argument '" << anArg << "'";
4583 Standard_Boolean IsLog;
4584 if (!ViewerTest::ParseOnOff(theArgVec[++anArgIter], IsLog))
4586 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4589 aColorScale->SetLogarithmic (IsLog);
4591 else if (aFlag == "-huerange"
4594 if (anArgIter + 2 >= theArgNb)
4596 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4600 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4601 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4602 aColorScale->SetHueRange (aHueMin, aHueMax);
4604 else if (aFlag == "-colorrange")
4606 Quantity_Color aColorMin, aColorMax;
4607 Standard_Integer aNbParsed1 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4608 theArgVec + (anArgIter + 1),
4610 anArgIter += aNbParsed1;
4611 Standard_Integer aNbParsed2 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4612 theArgVec + (anArgIter + 1),
4614 anArgIter += aNbParsed2;
4618 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4622 aColorScale->SetColorRange (aColorMin, aColorMax);
4624 else if (aFlag == "-reversed"
4625 || aFlag == "-inverted"
4626 || aFlag == "-topdown"
4627 || aFlag == "-bottomup")
4629 Standard_Boolean toEnable = Standard_True;
4630 if (anArgIter + 1 < theArgNb
4631 && ViewerTest::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4635 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4637 else if (aFlag == "-smooth"
4638 || aFlag == "-smoothtransition")
4640 Standard_Boolean toEnable = Standard_True;
4641 if (anArgIter + 1 < theArgNb
4642 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4646 aColorScale->SetSmoothTransition (toEnable);
4648 else if (aFlag == "-xy")
4650 if (anArgIter + 2 >= theArgNb)
4652 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4656 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4657 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4658 if (!anX.IsIntegerValue()
4659 || !anY.IsIntegerValue())
4661 Message::SendFail ("Syntax error: coordinates should be integer values");
4665 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
4667 else if (aFlag == "-width"
4669 || aFlag == "-breadth")
4671 if (anArgIter + 1 >= theArgNb)
4673 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4677 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4678 if (!aBreadth.IsIntegerValue())
4680 Message::SendFail ("Syntax error: a width should be an integer value");
4683 aColorScale->SetBreadth (aBreadth.IntegerValue());
4685 else if (aFlag == "-height"
4688 if (anArgIter + 1 >= theArgNb)
4690 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4694 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4695 if (!aHeight.IsIntegerValue())
4697 Message::SendFail ("Syntax error: a width should be an integer value");
4700 aColorScale->SetHeight (aHeight.IntegerValue());
4702 else if (aFlag == "-color")
4704 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
4706 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
4709 else if (anArgIter + 2 >= theArgNb)
4711 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4715 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
4716 if (!anInd.IsIntegerValue())
4718 Message::SendFail ("Syntax error: Index value should be integer");
4721 const Standard_Integer anIndex = anInd.IntegerValue();
4722 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
4724 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
4728 Quantity_Color aColor;
4729 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4730 theArgVec + (anArgIter + 1),
4734 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4737 aColorScale->SetIntervalColor (aColor, anIndex);
4738 aColorScale->SetColorType (Aspect_TOCSD_USER);
4739 anArgIter += aNbParsed;
4741 else if (aFlag == "-label")
4743 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
4745 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
4748 else if (anArgIter + 2 >= theArgNb)
4750 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4754 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4755 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
4757 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
4761 TCollection_ExtendedString aText (theArgVec[anArgIter + 2]);
4762 aColorScale->SetLabel (aText, anIndex);
4763 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4766 else if (aFlag == "-labelat"
4767 || aFlag == "-labat"
4768 || aFlag == "-labelatborder"
4769 || aFlag == "-labatborder"
4770 || aFlag == "-labelatcenter"
4771 || aFlag == "-labatcenter")
4773 Standard_Boolean toEnable = Standard_True;
4774 if (aFlag == "-labelat"
4775 || aFlag == "-labat")
4777 Standard_Integer aLabAtBorder = -1;
4778 if (++anArgIter >= theArgNb)
4780 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4781 anAtBorder.LowerCase();
4782 if (anAtBorder == "border")
4786 else if (anAtBorder == "center")
4791 if (aLabAtBorder == -1)
4793 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4796 toEnable = (aLabAtBorder == 1);
4798 else if (anArgIter + 1 < theArgNb
4799 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4803 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4804 || aFlag == "-labatcenter"
4808 else if (aFlag == "-colors")
4810 Aspect_SequenceOfColor aSeq;
4813 Quantity_Color aColor;
4814 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4815 theArgVec + (anArgIter + 1),
4821 anArgIter += aNbParsed;
4822 aSeq.Append (aColor);
4824 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
4826 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4827 << aColorScale->GetNumberOfIntervals() << " intervals";
4831 aColorScale->SetColors (aSeq);
4832 aColorScale->SetColorType (Aspect_TOCSD_USER);
4834 else if (aFlag == "-uniform")
4836 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4837 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4838 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4839 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4840 aColorScale->SetColorType (Aspect_TOCSD_USER);
4842 else if (aFlag == "-labels"
4843 || aFlag == "-freelabels")
4845 if (anArgIter + 1 >= theArgNb)
4847 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4851 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4852 ? aColorScale->GetNumberOfIntervals() + 1
4853 : aColorScale->GetNumberOfIntervals();
4854 if (aFlag == "-freelabels")
4857 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4859 if (anArgIter + aNbLabels >= theArgNb)
4861 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
4865 TColStd_SequenceOfExtendedString aSeq;
4866 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
4868 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter]));
4870 aColorScale->SetLabels (aSeq);
4871 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4873 else if (aFlag == "-title")
4875 if (anArgIter + 1 >= theArgNb)
4877 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4881 Standard_Boolean isTwoArgs = Standard_False;
4882 if (anArgIter + 2 < theArgNb)
4884 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4885 aSecondArg.LowerCase();
4886 Standard_DISABLE_DEPRECATION_WARNINGS
4887 if (aSecondArg == "none")
4889 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
4890 isTwoArgs = Standard_True;
4892 else if (aSecondArg == "left")
4894 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
4895 isTwoArgs = Standard_True;
4897 else if (aSecondArg == "right")
4899 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
4900 isTwoArgs = Standard_True;
4902 else if (aSecondArg == "center")
4904 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
4905 isTwoArgs = Standard_True;
4907 Standard_ENABLE_DEPRECATION_WARNINGS
4910 aColorScale->SetTitle (theArgVec[anArgIter + 1]);
4917 else if (aFlag == "-demoversion"
4918 || aFlag == "-demo")
4920 aColorScale->SetPosition (0, 0);
4921 aColorScale->SetTextHeight (16);
4922 aColorScale->SetRange (0.0, 100.0);
4923 aColorScale->SetNumberOfIntervals (10);
4924 aColorScale->SetBreadth (0);
4925 aColorScale->SetHeight (0);
4926 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4927 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4928 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
4930 else if (aFlag == "-findcolor")
4932 if (anArgIter + 1 >= theArgNb)
4934 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4938 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4940 if (!anArg1.IsRealValue())
4942 Message::SendFail ("Syntax error: the value should be real");
4946 Quantity_Color aColor;
4947 aColorScale->FindColor (anArg1.RealValue(), aColor);
4948 theDI << Quantity_Color::StringName (aColor.Name());
4953 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
4958 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4959 aView->Window()->Size (aWinWidth, aWinHeight);
4960 if (aColorScale->GetBreadth() == 0)
4962 aColorScale->SetBreadth (aWinWidth);
4964 if (aColorScale->GetHeight() == 0)
4966 aColorScale->SetHeight (aWinHeight);
4968 aColorScale->SetToUpdate();
4969 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
4973 //==============================================================================
4974 //function : VGraduatedTrihedron
4975 //purpose : Displays or hides a graduated trihedron
4976 //==============================================================================
4977 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4978 Quantity_Color& theColor)
4980 Quantity_NameOfColor aColorName;
4981 TCollection_AsciiString aVal = theValue;
4983 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
4985 return Standard_False;
4987 theColor = Quantity_Color (aColorName);
4988 return Standard_True;
4991 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
4995 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4996 << theArgs[0] <<"' for more information";
5000 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
5001 TCollection_AsciiString aParseKey;
5002 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
5004 TCollection_AsciiString anArg (theArgs [anArgIt]);
5006 if (anArg.Value (1) == '-' && !anArg.IsRealValue())
5009 aParseKey.Remove (1);
5010 aParseKey.LowerCase();
5011 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
5015 if (aParseKey.IsEmpty())
5020 aMapOfArgs(aParseKey)->Append (anArg);
5024 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
5025 aMapIt.More(); aMapIt.Next())
5027 const TCollection_AsciiString& aKey = aMapIt.Key();
5028 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
5030 // Bool key, without arguments
5031 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
5032 && anArgs->IsEmpty())
5038 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
5039 && anArgs->Length() == 1)
5045 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
5046 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
5047 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
5048 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
5049 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
5054 // One string argument
5055 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
5056 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
5057 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
5062 // One integer argument
5063 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
5064 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
5065 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
5066 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
5067 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
5072 // One real argument
5073 if ( aKey.IsEqual ("arrowlength")
5074 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue()))
5079 // Two string arguments
5080 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
5081 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
5086 TCollection_AsciiString aLowerKey;
5089 aLowerKey.LowerCase();
5090 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
5091 << "Type help for more information";
5095 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5096 if (anAISContext.IsNull())
5098 Message::SendFail ("Error: no active viewer");
5102 Standard_Boolean toDisplay = Standard_True;
5103 Quantity_Color aColor;
5104 Graphic3d_GraduatedTrihedron aTrihedronData;
5105 // Process parameters
5106 Handle(TColStd_HSequenceOfAsciiString) aValues;
5107 if (aMapOfArgs.Find ("off", aValues))
5109 toDisplay = Standard_False;
5113 if (aMapOfArgs.Find ("xname", aValues))
5115 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
5117 if (aMapOfArgs.Find ("yname", aValues))
5119 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
5121 if (aMapOfArgs.Find ("zname", aValues))
5123 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
5125 if (aMapOfArgs.Find ("xdrawname", aValues))
5127 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
5129 if (aMapOfArgs.Find ("ydrawname", aValues))
5131 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
5133 if (aMapOfArgs.Find ("zdrawname", aValues))
5135 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
5137 if (aMapOfArgs.Find ("xnameoffset", aValues))
5139 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5141 if (aMapOfArgs.Find ("ynameoffset", aValues))
5143 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5145 if (aMapOfArgs.Find ("znameoffset", aValues))
5147 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5151 if (aMapOfArgs.Find ("xnamecolor", aValues))
5153 if (!GetColor (aValues->Value(1), aColor))
5155 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
5158 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
5160 if (aMapOfArgs.Find ("ynamecolor", aValues))
5162 if (!GetColor (aValues->Value(1), aColor))
5164 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
5167 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
5169 if (aMapOfArgs.Find ("znamecolor", aValues))
5171 if (!GetColor (aValues->Value(1), aColor))
5173 Message::SendFail ("Syntax error: -znamecolor wrong color name");
5176 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
5178 if (aMapOfArgs.Find ("xcolor", aValues))
5180 if (!GetColor (aValues->Value(1), aColor))
5182 Message::SendFail ("Syntax error: -xcolor wrong color name");
5185 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
5187 if (aMapOfArgs.Find ("ycolor", aValues))
5189 if (!GetColor (aValues->Value(1), aColor))
5191 Message::SendFail ("Syntax error: -ycolor wrong color name");
5194 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
5196 if (aMapOfArgs.Find ("zcolor", aValues))
5198 if (!GetColor (aValues->Value(1), aColor))
5200 Message::SendFail ("Syntax error: -zcolor wrong color name");
5203 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
5207 if (aMapOfArgs.Find ("xticks", aValues))
5209 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5211 if (aMapOfArgs.Find ("yticks", aValues))
5213 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5215 if (aMapOfArgs.Find ("zticks", aValues))
5217 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5219 if (aMapOfArgs.Find ("xticklength", aValues))
5221 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5223 if (aMapOfArgs.Find ("yticklength", aValues))
5225 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5227 if (aMapOfArgs.Find ("zticklength", aValues))
5229 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5231 if (aMapOfArgs.Find ("xdrawticks", aValues))
5233 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5235 if (aMapOfArgs.Find ("ydrawticks", aValues))
5237 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5239 if (aMapOfArgs.Find ("zdrawticks", aValues))
5241 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5245 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5247 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5249 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5251 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5253 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5255 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5257 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5259 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5261 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5263 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5265 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5267 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5271 if (aMapOfArgs.Find ("arrowlength", aValues))
5273 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
5277 if (aMapOfArgs.Find ("namefont", aValues))
5279 aTrihedronData.SetNamesFont (aValues->Value(1));
5281 if (aMapOfArgs.Find ("valuesfont", aValues))
5283 aTrihedronData.SetValuesFont (aValues->Value(1));
5286 if (aMapOfArgs.Find ("drawgrid", aValues))
5288 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5290 if (aMapOfArgs.Find ("drawaxes", aValues))
5292 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5295 // The final step: display of erase trihedron
5298 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
5302 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5305 ViewerTest::GetAISContext()->UpdateCurrentViewer();
5306 ViewerTest::CurrentView()->Redraw();
5311 //==============================================================================
5314 //==============================================================================
5315 static int VTile (Draw_Interpretor& theDI,
5316 Standard_Integer theArgNb,
5317 const char** theArgVec)
5319 Handle(V3d_View) aView = ViewerTest::CurrentView();
5322 Message::SendFail ("Error: no active viewer");
5326 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5329 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5330 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5331 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5335 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5336 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5338 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5340 if (anArg == "-lowerleft"
5341 || anArg == "-upperleft")
5343 if (anArgIter + 3 < theArgNb)
5345 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5348 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5349 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5350 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5352 else if (anArg == "-total"
5353 || anArg == "-totalsize"
5354 || anArg == "-viewsize")
5356 if (anArgIter + 3 < theArgNb)
5358 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5361 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5362 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5363 if (aTile.TotalSize.x() < 1
5364 || aTile.TotalSize.y() < 1)
5366 Message::SendFail ("Error: total size is incorrect");
5370 else if (anArg == "-tilesize")
5372 if (anArgIter + 3 < theArgNb)
5374 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5378 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5379 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5380 if (aTile.TileSize.x() < 1
5381 || aTile.TileSize.y() < 1)
5383 Message::SendFail ("Error: tile size is incorrect");
5387 else if (anArg == "-unset")
5389 aView->Camera()->SetTile (Graphic3d_CameraTile());
5395 if (aTile.TileSize.x() < 1
5396 || aTile.TileSize.y() < 1)
5398 Message::SendFail ("Error: tile size is undefined");
5401 else if (aTile.TotalSize.x() < 1
5402 || aTile.TotalSize.y() < 1)
5404 Message::SendFail ("Error: total size is undefined");
5408 aView->Camera()->SetTile (aTile);
5413 //! Format ZLayer ID.
5414 inline const char* formZLayerId (const Standard_Integer theLayerId)
5418 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5419 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5420 case Graphic3d_ZLayerId_Top: return "[TOP]";
5421 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5422 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5423 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5428 //! Print the ZLayer information.
5429 inline void printZLayerInfo (Draw_Interpretor& theDI,
5430 const Graphic3d_ZLayerSettings& theLayer)
5432 if (!theLayer.Name().IsEmpty())
5434 theDI << " Name: " << theLayer.Name() << "\n";
5436 if (theLayer.IsImmediate())
5438 theDI << " Immediate: TRUE\n";
5440 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
5441 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5442 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
5443 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5444 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5445 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5446 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5448 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5452 //==============================================================================
5453 //function : VZLayer
5454 //purpose : Test z layer operations for v3d viewer
5455 //==============================================================================
5456 static int VZLayer (Draw_Interpretor& theDI,
5457 Standard_Integer theArgNb,
5458 const char** theArgVec)
5460 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5461 if (aContextAIS.IsNull())
5463 Message::SendFail ("Error: no active viewer");
5467 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
5470 TColStd_SequenceOfInteger aLayers;
5471 aViewer->GetAllZLayers (aLayers);
5472 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5474 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5475 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5476 printZLayerInfo (theDI, aSettings);
5481 Standard_Integer anArgIter = 1;
5482 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5483 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5484 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5490 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5491 if (aFirstArg.IsIntegerValue())
5494 aLayerId = aFirstArg.IntegerValue();
5498 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
5505 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
5506 for (; anArgIter < theArgNb; ++anArgIter)
5508 // perform operation
5509 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5511 if (anUpdateTool.parseRedrawMode (anArg))
5515 else if (anArg == "-add"
5518 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5519 if (!aViewer->AddZLayer (aLayerId))
5521 Message::SendFail ("Error: can not add a new z layer");
5527 else if (anArg == "-insertbefore"
5528 && anArgIter + 1 < theArgNb
5529 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5532 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5533 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5535 Message::SendFail ("Error: can not add a new z layer");
5541 else if (anArg == "-insertafter"
5542 && anArgIter + 1 < theArgNb
5543 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5546 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5547 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5549 Message::SendFail ("Error: can not add a new z layer");
5555 else if (anArg == "-del"
5556 || anArg == "-delete"
5559 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5561 if (++anArgIter >= theArgNb)
5563 Message::SendFail ("Syntax error: id of z layer to remove is missing");
5567 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5570 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5571 || aLayerId == Graphic3d_ZLayerId_Default
5572 || aLayerId == Graphic3d_ZLayerId_Top
5573 || aLayerId == Graphic3d_ZLayerId_Topmost
5574 || aLayerId == Graphic3d_ZLayerId_TopOSD
5575 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5577 Message::SendFail ("Syntax error: standard Z layer can not be removed");
5581 // move all object displayed in removing layer to default layer
5582 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5583 anObjIter.More(); anObjIter.Next())
5585 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
5587 || aPrs->ZLayer() != aLayerId)
5591 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5594 if (!aViewer->RemoveZLayer (aLayerId))
5596 Message::SendFail ("Z layer can not be removed");
5600 theDI << aLayerId << " ";
5603 else if (anArg == "-get"
5606 TColStd_SequenceOfInteger aLayers;
5607 aViewer->GetAllZLayers (aLayers);
5608 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5610 theDI << aLayeriter.Value() << " ";
5615 else if (anArg == "-name")
5617 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5619 Message::SendFail ("Syntax error: id of Z layer is missing");
5623 if (++anArgIter >= theArgNb)
5625 Message::SendFail ("Syntax error: name is missing");
5629 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5630 aSettings.SetName (theArgVec[anArgIter]);
5631 aViewer->SetZLayerSettings (aLayerId, aSettings);
5633 else if (anArg == "-origin")
5635 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5637 Message::SendFail ("Syntax error: id of Z layer is missing");
5641 if (anArgIter + 2 >= theArgNb)
5643 Message::SendFail ("Syntax error: origin coordinates are missing");
5647 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5649 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5650 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5651 anOrigin.SetZ (0.0);
5652 if (anArgIter + 3 < theArgNb)
5654 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5661 aSettings.SetOrigin (anOrigin);
5662 aViewer->SetZLayerSettings (aLayerId, aSettings);
5664 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5665 && anArgIter + 1 < theArgNb
5666 && (anArg == "-cullingdistance"
5667 || anArg == "-cullingdist"
5668 || anArg == "-culldistance"
5669 || anArg == "-culldist"
5670 || anArg == "-distcull"
5671 || anArg == "-distculling"
5672 || anArg == "-distanceculling"))
5674 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5675 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5676 aSettings.SetCullingDistance (aDist);
5677 aViewer->SetZLayerSettings (aLayerId, aSettings);
5679 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5680 && anArgIter + 1 < theArgNb
5681 && (anArg == "-cullingsize"
5682 || anArg == "-cullsize"
5683 || anArg == "-sizecull"
5684 || anArg == "-sizeculling"))
5686 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5687 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5688 aSettings.SetCullingSize (aSize);
5689 aViewer->SetZLayerSettings (aLayerId, aSettings);
5691 else if (anArg == "-settings"
5692 || anArg == "settings")
5694 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5696 if (++anArgIter >= theArgNb)
5698 Message::SendFail ("Syntax error: id of Z layer is missing");
5702 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5705 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5706 printZLayerInfo (theDI, aSettings);
5708 else if (anArg == "-enable"
5709 || anArg == "enable"
5710 || anArg == "-disable"
5711 || anArg == "disable")
5713 const Standard_Boolean toEnable = anArg == "-enable"
5714 || anArg == "enable";
5715 if (++anArgIter >= theArgNb)
5717 Message::SendFail ("Syntax error: option name is missing");
5721 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5723 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5725 if (++anArgIter >= theArgNb)
5727 Message::SendFail ("Syntax error: id of Z layer is missing");
5731 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5734 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5735 if (aSubOp == "depthtest"
5736 || aSubOp == "test")
5738 aSettings.SetEnableDepthTest (toEnable);
5740 else if (aSubOp == "depthwrite"
5741 || aSubOp == "write")
5743 aSettings.SetEnableDepthWrite (toEnable);
5745 else if (aSubOp == "depthclear"
5746 || aSubOp == "clear")
5748 aSettings.SetClearDepth (toEnable);
5750 else if (aSubOp == "depthoffset"
5751 || aSubOp == "offset")
5753 Graphic3d_PolygonOffset aParams;
5754 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5757 if (anArgIter + 2 >= theArgNb)
5759 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
5763 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5764 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5766 aSettings.SetPolygonOffset (aParams);
5768 else if (aSubOp == "positiveoffset"
5769 || aSubOp == "poffset")
5773 aSettings.SetDepthOffsetPositive();
5777 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5780 else if (aSubOp == "negativeoffset"
5781 || aSubOp == "noffset")
5785 aSettings.SetDepthOffsetNegative();
5789 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5792 else if (aSubOp == "textureenv")
5794 aSettings.SetEnvironmentTexture (toEnable);
5796 else if (aSubOp == "raytracing")
5798 aSettings.SetRaytracable (toEnable);
5801 aViewer->SetZLayerSettings (aLayerId, aSettings);
5805 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
5813 // The interactive presentation of 2d layer item
5814 // for "vlayerline" command it provides a presentation of
5815 // line with user-defined linewidth, linetype and transparency.
5816 class V3d_LineItem : public AIS_InteractiveObject
5820 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
5823 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5824 Standard_Real X2, Standard_Real Y2,
5825 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5826 Standard_Real theWidth = 0.5,
5827 Standard_Real theTransp = 1.0);
5831 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
5832 const Handle(Prs3d_Presentation)& thePresentation,
5833 const Standard_Integer theMode) Standard_OVERRIDE;
5835 void ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/,
5836 const Standard_Integer /*aMode*/) Standard_OVERRIDE
5841 Standard_Real myX1, myY1, myX2, myY2;
5842 Aspect_TypeOfLine myType;
5843 Standard_Real myWidth;
5846 // default constructor for line item
5847 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5848 Standard_Real X2, Standard_Real Y2,
5849 Aspect_TypeOfLine theType,
5850 Standard_Real theWidth,
5851 Standard_Real theTransp) :
5852 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5853 myType(theType), myWidth(theWidth)
5855 SetTransparency (1-theTransp);
5859 void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
5860 const Handle(Prs3d_Presentation)& thePresentation,
5861 const Standard_Integer /*theMode*/)
5863 thePresentation->Clear();
5864 Quantity_Color aColor (Quantity_NOC_RED);
5865 Standard_Integer aWidth, aHeight;
5866 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
5867 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
5868 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5869 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5870 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5871 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5872 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5873 aGroup->AddPrimitiveArray (aPrim);
5876 //=============================================================================
5877 //function : VLayerLine
5878 //purpose : Draws line in the v3d view layer with given attributes: linetype,
5879 // : linewidth, transparency coefficient
5880 //============================================================================
5881 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5883 // get the active view
5884 Handle(V3d_View) aView = ViewerTest::CurrentView();
5887 di << "Call vinit before!\n";
5892 di << "Use: " << argv[0];
5893 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5894 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5895 di << " 0 - solid \n";
5896 di << " 1 - dashed \n";
5897 di << " 2 - dot \n";
5898 di << " 3 - dashdot\n";
5899 di << " transparency : { 0.0 - 1.0 } \n";
5900 di << " 0.0 - transparent\n";
5901 di << " 1.0 - visible \n";
5905 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5906 // get the input params
5907 Standard_Real X1 = Draw::Atof(argv[1]);
5908 Standard_Real Y1 = Draw::Atof(argv[2]);
5909 Standard_Real X2 = Draw::Atof(argv[3]);
5910 Standard_Real Y2 = Draw::Atof(argv[4]);
5912 Standard_Real aWidth = 0.5;
5913 Standard_Real aTransparency = 1.0;
5917 aWidth = Draw::Atof(argv[5]);
5919 // select appropriate line type
5920 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5922 && !ViewerTest::ParseLineType (argv[6], aLineType))
5924 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
5931 aTransparency = Draw::Atof(argv[7]);
5932 if (aTransparency < 0 || aTransparency > 1.0)
5933 aTransparency = 1.0;
5936 static Handle (V3d_LineItem) aLine;
5937 if (!aLine.IsNull())
5939 aContext->Erase (aLine, Standard_False);
5941 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5945 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
5946 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5947 aLine->SetToUpdate();
5948 aContext->Display (aLine, Standard_True);
5954 //==============================================================================
5957 //==============================================================================
5959 static int VGrid (Draw_Interpretor& /*theDI*/,
5960 Standard_Integer theArgNb,
5961 const char** theArgVec)
5963 Handle(V3d_View) aView = ViewerTest::CurrentView();
5964 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5965 if (aView.IsNull() || aViewer.IsNull())
5967 Message::SendFail ("Error: no active viewer");
5971 Aspect_GridType aType = aViewer->GridType();
5972 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
5973 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5974 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5975 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
5976 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
5977 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5979 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5981 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5985 else if (anArgIter + 1 < theArgNb
5986 && anArg == "-type")
5988 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5989 anArgNext.LowerCase();
5990 if (anArgNext == "r"
5991 || anArgNext == "rect"
5992 || anArgNext == "rectangular")
5994 aType = Aspect_GT_Rectangular;
5996 else if (anArgNext == "c"
5997 || anArgNext == "circ"
5998 || anArgNext == "circular")
6000 aType = Aspect_GT_Circular;
6004 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
6008 else if (anArgIter + 1 < theArgNb
6009 && anArg == "-mode")
6011 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6012 anArgNext.LowerCase();
6013 if (anArgNext == "l"
6014 || anArgNext == "line"
6015 || anArgNext == "lines")
6017 aMode = Aspect_GDM_Lines;
6019 else if (anArgNext == "p"
6020 || anArgNext == "point"
6021 || anArgNext == "points")
6023 aMode = Aspect_GDM_Points;
6027 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
6031 else if (anArgIter + 2 < theArgNb
6032 && (anArg == "-origin"
6033 || anArg == "-orig"))
6036 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6037 Draw::Atof (theArgVec[anArgIter + 2]));
6040 else if (anArgIter + 2 < theArgNb
6041 && anArg == "-step")
6044 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6045 Draw::Atof (theArgVec[anArgIter + 2]));
6046 if (aNewStepXY.x() <= 0.0
6047 || aNewStepXY.y() <= 0.0)
6049 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
6054 else if (anArgIter + 1 < theArgNb
6055 && (anArg == "-angle"
6056 || anArg == "-rotangle"
6057 || anArg == "-rotationangle"))
6060 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
6062 else if (anArgIter + 1 < theArgNb
6063 && (anArg == "-zoffset"
6067 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
6069 else if (anArgIter + 1 < theArgNb
6070 && anArg == "-radius")
6074 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
6075 if (aNewStepXY.x() <= 0.0)
6077 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
6081 else if (anArgIter + 2 < theArgNb
6082 && anArg == "-size")
6085 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6086 Draw::Atof (theArgVec[anArgIter + 2]));
6087 if (aNewStepXY.x() <= 0.0
6088 || aNewStepXY.y() <= 0.0)
6090 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
6095 else if (anArg == "r"
6097 || anArg == "rectangular")
6099 aType = Aspect_GT_Rectangular;
6101 else if (anArg == "c"
6103 || anArg == "circular")
6105 aType = Aspect_GT_Circular;
6107 else if (anArg == "l"
6109 || anArg == "lines")
6111 aMode = Aspect_GDM_Lines;
6113 else if (anArg == "p"
6115 || anArg == "points")
6117 aMode = Aspect_GDM_Points;
6119 else if (anArgIter + 1 >= theArgNb
6122 aViewer->DeactivateGrid();
6127 Message::SendFail() << "Syntax error at '" << anArg << "'";
6132 if (aType == Aspect_GT_Rectangular)
6134 Graphic3d_Vec2d anOrigXY, aStepXY;
6135 Standard_Real aRotAngle = 0.0;
6136 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6139 anOrigXY = aNewOriginXY;
6143 aStepXY = aNewStepXY;
6147 aRotAngle = aNewRotAngle;
6149 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6150 if (hasSize || hasZOffset)
6152 Graphic3d_Vec3d aSize;
6153 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6156 aSize.x() = aNewSizeXY.x();
6157 aSize.y() = aNewSizeXY.y();
6161 aSize.z() = aNewZOffset;
6163 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6166 else if (aType == Aspect_GT_Circular)
6168 Graphic3d_Vec2d anOrigXY;
6169 Standard_Real aRadiusStep;
6170 Standard_Integer aDivisionNumber;
6171 Standard_Real aRotAngle = 0.0;
6172 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6175 anOrigXY = aNewOriginXY;
6179 aRadiusStep = aNewStepXY[0];
6180 aDivisionNumber = (int )aNewStepXY[1];
6181 if (aDivisionNumber < 1)
6183 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
6189 aRotAngle = aNewRotAngle;
6192 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6193 if (hasSize || hasZOffset)
6195 Standard_Real aRadius = 0.0, aZOffset = 0.0;
6196 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
6199 aRadius = aNewSizeXY.x();
6200 if (aNewSizeXY.y() != 0.0)
6202 Message::SendFail ("Syntax error: circular size should be specified as radius");
6208 aZOffset = aNewZOffset;
6210 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6213 aViewer->ActivateGrid (aType, aMode);
6217 //==============================================================================
6218 //function : VPriviledgedPlane
6220 //==============================================================================
6222 static int VPriviledgedPlane (Draw_Interpretor& theDI,
6223 Standard_Integer theArgNb,
6224 const char** theArgVec)
6226 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6228 Message::SendFail ("Error: wrong number of arguments! See usage:");
6229 theDI.PrintHelp (theArgVec[0]);
6233 // get the active viewer
6234 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6235 if (aViewer.IsNull())
6237 Message::SendFail ("Error: no active viewer");
6243 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6244 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6245 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6246 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6247 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6248 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6249 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6253 Standard_Integer anArgIdx = 1;
6254 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6255 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6256 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6257 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6258 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6259 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6261 gp_Ax3 aPriviledgedPlane;
6262 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6263 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6266 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6267 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6268 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6269 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6270 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6274 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6277 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6282 //==============================================================================
6283 //function : VConvert
6285 //==============================================================================
6287 static int VConvert (Draw_Interpretor& theDI,
6288 Standard_Integer theArgNb,
6289 const char** theArgVec)
6291 // get the active view
6292 Handle(V3d_View) aView = ViewerTest::CurrentView();
6295 Message::SendFail ("Error: no active viewer");
6299 enum { Model, Ray, View, Window, Grid } aMode = Model;
6301 // access coordinate arguments
6302 TColStd_SequenceOfReal aCoord;
6303 Standard_Integer anArgIdx = 1;
6304 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6306 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6307 if (!anArg.IsRealValue())
6311 aCoord.Append (anArg.RealValue());
6314 // non-numeric argument too early
6315 if (aCoord.IsEmpty())
6317 Message::SendFail ("Error: wrong number of arguments! See usage:");
6318 theDI.PrintHelp (theArgVec[0]);
6322 // collect all other arguments and options
6323 for (; anArgIdx < theArgNb; ++anArgIdx)
6325 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6327 if (anArg == "window") aMode = Window;
6328 else if (anArg == "view") aMode = View;
6329 else if (anArg == "grid") aMode = Grid;
6330 else if (anArg == "ray") aMode = Ray;
6333 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
6334 theDI.PrintHelp (theArgVec[0]);
6339 // complete input checks
6340 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6341 (aCoord.Length() == 2 && theArgNb > 4) ||
6342 (aCoord.Length() == 3 && theArgNb > 5))
6344 Message::SendFail ("Error: wrong number of arguments! See usage:");
6345 theDI.PrintHelp (theArgVec[0]);
6349 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6350 Standard_Integer aXYp[2] = {0, 0};
6352 // convert one-dimensional coordinate
6353 if (aCoord.Length() == 1)
6357 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6358 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
6360 Message::SendFail ("Error: wrong arguments! See usage:");
6361 theDI.PrintHelp (theArgVec[0]);
6366 // convert 2D coordinates from projection or view reference space
6367 if (aCoord.Length() == 2)
6372 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6373 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6377 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6378 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6382 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
6383 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6387 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6388 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6389 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6393 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6394 (Standard_Integer) aCoord (2),
6395 aXYZ[0], aXYZ[1], aXYZ[2],
6396 aXYZ[3], aXYZ[4], aXYZ[5]);
6397 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6401 Message::SendFail ("Error: wrong arguments! See usage:");
6402 theDI.PrintHelp (theArgVec[0]);
6407 // convert 3D coordinates from view reference space
6408 else if (aCoord.Length() == 3)
6413 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6414 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6418 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6419 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6423 Message::SendFail ("Error: wrong arguments! See usage:");
6424 theDI.PrintHelp (theArgVec[0]);
6432 //==============================================================================
6435 //==============================================================================
6437 static int VFps (Draw_Interpretor& theDI,
6438 Standard_Integer theArgNb,
6439 const char** theArgVec)
6441 // get the active view
6442 Handle(V3d_View) aView = ViewerTest::CurrentView();
6445 Message::SendFail ("Error: no active viewer");
6449 Standard_Integer aFramesNb = -1;
6450 Standard_Real aDuration = -1.0;
6451 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6453 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6456 && anArgIter + 1 < theArgNb
6457 && (anArg == "-duration"
6459 || anArg == "-time"))
6461 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6463 else if (aFramesNb < 0
6464 && anArg.IsIntegerValue())
6466 aFramesNb = anArg.IntegerValue();
6469 Message::SendFail() << "Syntax error at '" << anArg << "'";
6475 Message::SendFail() << "Syntax error at '" << anArg << "'";
6479 if (aFramesNb < 0 && aDuration < 0.0)
6484 // the time is meaningless for first call
6485 // due to async OpenGl rendering
6488 // redraw view in loop to estimate average values
6491 Standard_Integer aFrameIter = 1;
6492 for (;; ++aFrameIter)
6496 && aFrameIter >= aFramesNb)
6498 && aTimer.ElapsedTime() >= aDuration))
6505 const Standard_Real aTime = aTimer.ElapsedTime();
6506 aTimer.OSD_Chronometer::Show (aCpu);
6508 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6509 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
6511 // return statistics
6512 theDI << "FPS: " << aFpsAver << "\n"
6513 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6515 // compute additional statistics in ray-tracing mode
6516 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
6517 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6519 Graphic3d_Vec2i aWinSize (0, 0);
6520 aView->Window()->Size (aWinSize.x(), aWinSize.y());
6522 // 1 shadow ray and 1 secondary ray pew each bounce
6523 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
6524 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6530 //! Auxiliary function for parsing glsl dump level argument.
6531 static Standard_Boolean parseGlslSourceFlag (Standard_CString theArg,
6532 OpenGl_ShaderProgramDumpLevel& theGlslDumpLevel)
6534 TCollection_AsciiString aTypeStr (theArg);
6535 aTypeStr.LowerCase();
6536 if (aTypeStr == "off"
6539 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6541 else if (aTypeStr == "short")
6543 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Short;
6545 else if (aTypeStr == "full"
6548 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6552 return Standard_False;
6554 return Standard_True;
6557 //==============================================================================
6558 //function : VGlDebug
6560 //==============================================================================
6562 static int VGlDebug (Draw_Interpretor& theDI,
6563 Standard_Integer theArgNb,
6564 const char** theArgVec)
6566 Handle(OpenGl_GraphicDriver) aDriver;
6567 Handle(V3d_View) aView = ViewerTest::CurrentView();
6568 if (!aView.IsNull())
6570 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
6572 OpenGl_Caps* aDefCaps = &ViewerTest_myDefaultCaps;
6573 OpenGl_Caps* aCaps = !aDriver.IsNull() ? &aDriver->ChangeOptions() : NULL;
6577 TCollection_AsciiString aDebActive, aSyncActive;
6584 Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )::glGetString (GL_EXTENSIONS),
6585 "GL_ARB_debug_output");
6586 aDebActive = isActive ? " (active)" : " (inactive)";
6589 // GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
6590 aSyncActive = ::glIsEnabled (0x8242) == GL_TRUE ? " (active)" : " (inactive)";
6594 TCollection_AsciiString aGlslCodeDebugStatus = TCollection_AsciiString()
6595 + "glslSourceCode: "
6596 + (aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Off
6598 : aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short
6602 theDI << "debug: " << (aCaps->contextDebug ? "1" : "0") << aDebActive << "\n"
6603 << "sync: " << (aCaps->contextSyncDebug ? "1" : "0") << aSyncActive << "\n"
6604 << "glslWarn: " << (aCaps->glslWarnings ? "1" : "0") << "\n"
6605 << aGlslCodeDebugStatus
6606 << "extraMsg: " << (aCaps->suppressExtraMsg ? "0" : "1") << "\n";
6610 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6612 Standard_CString anArg = theArgVec[anArgIter];
6613 TCollection_AsciiString anArgCase (anArg);
6614 anArgCase.LowerCase();
6615 Standard_Boolean toEnableDebug = Standard_True;
6616 if (anArgCase == "-glsl"
6617 || anArgCase == "-glslwarn"
6618 || anArgCase == "-glslwarns"
6619 || anArgCase == "-glslwarnings")
6621 Standard_Boolean toShowWarns = Standard_True;
6622 if (++anArgIter < theArgNb
6623 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toShowWarns))
6627 aDefCaps->glslWarnings = toShowWarns;
6630 aCaps->glslWarnings = toShowWarns;
6633 else if (anArgCase == "-extra"
6634 || anArgCase == "-extramsg"
6635 || anArgCase == "-extramessages")
6637 Standard_Boolean toShow = Standard_True;
6638 if (++anArgIter < theArgNb
6639 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toShow))
6643 aDefCaps->suppressExtraMsg = !toShow;
6646 aCaps->suppressExtraMsg = !toShow;
6649 else if (anArgCase == "-noextra"
6650 || anArgCase == "-noextramsg"
6651 || anArgCase == "-noextramessages")
6653 Standard_Boolean toSuppress = Standard_True;
6654 if (++anArgIter < theArgNb
6655 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toSuppress))
6659 aDefCaps->suppressExtraMsg = toSuppress;
6662 aCaps->suppressExtraMsg = toSuppress;
6665 else if (anArgCase == "-sync")
6667 Standard_Boolean toSync = Standard_True;
6668 if (++anArgIter < theArgNb
6669 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toSync))
6673 aDefCaps->contextSyncDebug = toSync;
6676 aDefCaps->contextDebug = Standard_True;
6679 else if (anArgCase == "-glslsourcecode"
6680 || anArgCase == "-glslcode")
6682 OpenGl_ShaderProgramDumpLevel aGslsDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6683 if (++anArgIter < theArgNb
6684 && !parseGlslSourceFlag (theArgVec[anArgIter], aGslsDumpLevel))
6688 aDefCaps->glslDumpLevel = aGslsDumpLevel;
6691 aCaps->glslDumpLevel = aGslsDumpLevel;
6694 else if (anArgCase == "-debug")
6696 if (++anArgIter < theArgNb
6697 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnableDebug))
6701 aDefCaps->contextDebug = toEnableDebug;
6703 else if (ViewerTest::ParseOnOff (anArg, toEnableDebug)
6704 && (anArgIter + 1 == theArgNb))
6706 // simple alias to turn on almost everything
6707 aDefCaps->contextDebug = toEnableDebug;
6708 aDefCaps->contextSyncDebug = toEnableDebug;
6709 aDefCaps->glslWarnings = toEnableDebug;
6712 aDefCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6714 aDefCaps->suppressExtraMsg = !toEnableDebug;
6717 aCaps->contextDebug = toEnableDebug;
6718 aCaps->contextSyncDebug = toEnableDebug;
6719 aCaps->glslWarnings = toEnableDebug;
6722 aCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6724 aCaps->suppressExtraMsg = !toEnableDebug;
6729 Message::SendFail() << "Syntax error at '" << anArg << "'";
6737 //==============================================================================
6740 //==============================================================================
6742 static int VVbo (Draw_Interpretor& theDI,
6743 Standard_Integer theArgNb,
6744 const char** theArgVec)
6746 const Standard_Boolean toSet = (theArgNb > 1);
6747 const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
6750 ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
6754 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6755 if (aContextAIS.IsNull())
6759 Message::SendFail ("Error: no active viewer");
6763 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
6764 if (!aDriver.IsNull())
6768 theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
6772 aDriver->ChangeOptions().vboDisable = toUseVbo;
6779 //==============================================================================
6782 //==============================================================================
6784 static int VCaps (Draw_Interpretor& theDI,
6785 Standard_Integer theArgNb,
6786 const char** theArgVec)
6788 OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
6789 Handle(OpenGl_GraphicDriver) aDriver;
6790 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6791 if (!aContext.IsNull())
6793 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
6794 aCaps = &aDriver->ChangeOptions();
6799 theDI << "sRGB: " << (aCaps->sRGBDisable ? "0" : "1") << "\n";
6800 theDI << "VBO: " << (aCaps->vboDisable ? "0" : "1") << "\n";
6801 theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
6802 theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
6803 theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
6804 theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
6805 theDI << "VSync: " << aCaps->swapInterval << "\n";
6806 theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
6807 theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
6808 theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n";
6809 theDI << "NoExt:" << (aCaps->contextNoExtensions ? "1" : "0") << "\n";
6810 theDI << "MaxVersion:" << aCaps->contextMajorVersionUpper << "." << aCaps->contextMinorVersionUpper << "\n";
6814 ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
6815 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6817 Standard_CString anArg = theArgVec[anArgIter];
6818 TCollection_AsciiString anArgCase (anArg);
6819 anArgCase.LowerCase();
6820 if (anUpdateTool.parseRedrawMode (anArg))
6824 else if (anArgCase == "-vsync"
6825 || anArgCase == "-swapinterval")
6827 Standard_Boolean toEnable = Standard_True;
6828 if (++anArgIter < theArgNb
6829 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6833 aCaps->swapInterval = toEnable;
6835 else if (anArgCase == "-ffp")
6837 Standard_Boolean toEnable = Standard_True;
6838 if (++anArgIter < theArgNb
6839 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6843 aCaps->ffpEnable = toEnable;
6845 else if (anArgCase == "-polygonmode")
6847 Standard_Boolean toEnable = Standard_True;
6848 if (++anArgIter < theArgNb
6849 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6853 aCaps->usePolygonMode = toEnable;
6855 else if (anArgCase == "-srgb")
6857 Standard_Boolean toEnable = Standard_True;
6858 if (++anArgIter < theArgNb
6859 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6863 aCaps->sRGBDisable = !toEnable;
6865 else if (anArgCase == "-vbo")
6867 Standard_Boolean toEnable = Standard_True;
6868 if (++anArgIter < theArgNb
6869 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6873 aCaps->vboDisable = !toEnable;
6875 else if (anArgCase == "-sprite"
6876 || anArgCase == "-sprites")
6878 Standard_Boolean toEnable = Standard_True;
6879 if (++anArgIter < theArgNb
6880 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6884 aCaps->pntSpritesDisable = !toEnable;
6886 else if (anArgCase == "-softmode")
6888 Standard_Boolean toEnable = Standard_True;
6889 if (++anArgIter < theArgNb
6890 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6894 aCaps->contextNoAccel = toEnable;
6896 else if (anArgCase == "-winbuffer"
6897 || anArgCase == "-windowbuffer"
6898 || anArgCase == "-usewinbuffer"
6899 || anArgCase == "-usewindowbuffer"
6900 || anArgCase == "-usesystembuffer")
6902 Standard_Boolean toEnable = Standard_True;
6903 if (++anArgIter < theArgNb
6904 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6908 aCaps->useSystemBuffer = toEnable;
6910 else if (anArgCase == "-accel"
6911 || anArgCase == "-acceleration")
6913 Standard_Boolean toEnable = Standard_True;
6914 if (++anArgIter < theArgNb
6915 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6919 aCaps->contextNoAccel = !toEnable;
6921 else if (anArgCase == "-compat"
6922 || anArgCase == "-compatprofile"
6923 || anArgCase == "-compatible"
6924 || anArgCase == "-compatibleprofile")
6926 Standard_Boolean toEnable = Standard_True;
6927 if (++anArgIter < theArgNb
6928 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6932 aCaps->contextCompatible = toEnable;
6933 if (!aCaps->contextCompatible)
6935 aCaps->ffpEnable = Standard_False;
6938 else if (anArgCase == "-core"
6939 || anArgCase == "-coreprofile")
6941 Standard_Boolean toEnable = Standard_True;
6942 if (++anArgIter < theArgNb
6943 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6947 aCaps->contextCompatible = !toEnable;
6948 if (!aCaps->contextCompatible)
6950 aCaps->ffpEnable = Standard_False;
6953 else if (anArgCase == "-stereo"
6954 || anArgCase == "-quadbuffer")
6956 Standard_Boolean toEnable = Standard_True;
6957 if (++anArgIter < theArgNb
6958 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
6962 aCaps->contextStereo = toEnable;
6964 else if (anArgCase == "-noext"
6965 || anArgCase == "-noextensions"
6966 || anArgCase == "-noextension")
6968 Standard_Boolean toDisable = Standard_True;
6969 if (++anArgIter < theArgNb
6970 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toDisable))
6974 aCaps->contextNoExtensions = toDisable;
6976 else if (anArgCase == "-maxversion"
6977 || anArgCase == "-upperversion"
6978 || anArgCase == "-limitversion")
6980 Standard_Integer aVer[2] = { -2, -1 };
6981 for (Standard_Integer aValIter = 0; aValIter < 2; ++aValIter)
6983 if (anArgIter + 1 < theArgNb)
6985 const TCollection_AsciiString aStr (theArgVec[anArgIter + 1]);
6986 if (aStr.IsIntegerValue())
6988 aVer[aValIter] = aStr.IntegerValue();
6996 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
6999 aCaps->contextMajorVersionUpper = aVer[0];
7000 aCaps->contextMinorVersionUpper = aVer[1];
7004 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
7008 if (aCaps != &ViewerTest_myDefaultCaps)
7010 ViewerTest_myDefaultCaps = *aCaps;
7015 //==============================================================================
7016 //function : VMemGpu
7018 //==============================================================================
7020 static int VMemGpu (Draw_Interpretor& theDI,
7021 Standard_Integer theArgNb,
7022 const char** theArgVec)
7025 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
7026 if (aContextAIS.IsNull())
7028 Message::SendFail ("Error: no active viewer");
7032 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
7033 if (aDriver.IsNull())
7035 Message::SendFail ("Error: graphic driver not available");
7039 Standard_Size aFreeBytes = 0;
7040 TCollection_AsciiString anInfo;
7041 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
7043 Message::SendFail ("Error: information not available");
7047 if (theArgNb > 1 && *theArgVec[1] == 'f')
7049 theDI << Standard_Real (aFreeBytes);
7059 // ==============================================================================
7060 // function : VReadPixel
7062 // ==============================================================================
7063 static int VReadPixel (Draw_Interpretor& theDI,
7064 Standard_Integer theArgNb,
7065 const char** theArgVec)
7067 // get the active view
7068 Handle(V3d_View) aView = ViewerTest::CurrentView();
7071 Message::SendFail ("Error: no active viewer");
7074 else if (theArgNb < 3)
7076 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
7077 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
7081 Image_Format aFormat = Image_Format_RGBA;
7082 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
7084 Standard_Integer aWidth, aHeight;
7085 aView->Window()->Size (aWidth, aHeight);
7086 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
7087 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
7088 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
7090 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
7094 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
7095 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
7097 TCollection_AsciiString aParam (theArgVec[anIter]);
7099 if (aParam == "-rgb"
7101 || aParam == "-srgb"
7102 || aParam == "srgb")
7104 aFormat = Image_Format_RGB;
7105 aBufferType = Graphic3d_BT_RGB;
7106 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
7108 else if (aParam == "-hls"
7111 aFormat = Image_Format_RGB;
7112 aBufferType = Graphic3d_BT_RGB;
7113 toShowHls = Standard_True;
7115 else if (aParam == "-rgbf"
7116 || aParam == "rgbf")
7118 aFormat = Image_Format_RGBF;
7119 aBufferType = Graphic3d_BT_RGB;
7121 else if (aParam == "-rgba"
7123 || aParam == "-srgba"
7124 || aParam == "srgba")
7126 aFormat = Image_Format_RGBA;
7127 aBufferType = Graphic3d_BT_RGBA;
7128 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
7130 else if (aParam == "-rgbaf"
7131 || aParam == "rgbaf")
7133 aFormat = Image_Format_RGBAF;
7134 aBufferType = Graphic3d_BT_RGBA;
7136 else if (aParam == "-depth"
7137 || aParam == "depth")
7139 aFormat = Image_Format_GrayF;
7140 aBufferType = Graphic3d_BT_Depth;
7142 else if (aParam == "-name"
7143 || aParam == "name")
7145 toShowName = Standard_True;
7147 else if (aParam == "-hex"
7150 toShowHex = Standard_True;
7154 Message::SendFail() << "Syntax error at '" << aParam << "'";
7159 Image_PixMap anImage;
7160 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
7162 Message::SendFail ("Error: image allocation failed");
7165 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
7167 Message::SendFail ("Error: image dump failed");
7171 // redirect possible warning messages that could have been added by ToPixMap
7172 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
7173 // contaminate result of the command
7174 Standard_CString aWarnLog = theDI.Result();
7175 if (aWarnLog != NULL && aWarnLog[0] != '\0')
7177 std::cout << aWarnLog << std::endl;
7181 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
7184 if (aBufferType == Graphic3d_BT_RGBA)
7186 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
7190 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
7195 if (aBufferType == Graphic3d_BT_RGBA)
7197 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
7201 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
7206 switch (aBufferType)
7209 case Graphic3d_BT_RGB:
7213 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
7215 else if (toShow_sRGB)
7217 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
7218 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
7222 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
7226 case Graphic3d_BT_RGBA:
7228 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
7229 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
7232 case Graphic3d_BT_Depth:
7234 theDI << aColor.GetRGB().Red();
7243 //! Auxiliary presentation for an image plane.
7244 class ViewerTest_ImagePrs : public AIS_InteractiveObject
7247 //! Main constructor.
7248 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
7249 const Standard_Real theWidth,
7250 const Standard_Real theHeight,
7251 const TCollection_AsciiString& theLabel)
7252 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
7256 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
7258 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
7259 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
7260 Graphic3d_MaterialAspect aMat;
7261 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
7262 aMat.SetAmbientColor (Quantity_NOC_BLACK);
7263 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
7264 aMat.SetSpecularColor (Quantity_NOC_BLACK);
7265 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
7266 aFillAspect->SetFrontMaterial (aMat);
7267 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
7268 aFillAspect->SetTextureMapOn();
7271 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
7272 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
7273 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
7274 myDrawer->SetTextAspect (aTextAspect);
7277 const gp_Dir aNorm (0.0, 0.0, 1.0);
7278 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
7279 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
7280 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
7281 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
7282 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
7283 myTris->AddEdge (1);
7284 myTris->AddEdge (2);
7285 myTris->AddEdge (3);
7286 myTris->AddEdge (3);
7287 myTris->AddEdge (2);
7288 myTris->AddEdge (4);
7290 myRect = new Graphic3d_ArrayOfPolylines (4);
7291 myRect->AddVertex (myTris->Vertice (1));
7292 myRect->AddVertex (myTris->Vertice (3));
7293 myRect->AddVertex (myTris->Vertice (4));
7294 myRect->AddVertex (myTris->Vertice (2));
7298 //! Returns TRUE for accepted display modes.
7299 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
7301 //! Compute presentation.
7302 virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& , const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) Standard_OVERRIDE
7308 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7309 aGroup->AddPrimitiveArray (myTris);
7310 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
7311 aGroup->AddPrimitiveArray (myRect);
7312 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7317 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
7318 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7319 aGroup->AddPrimitiveArray (myRect);
7320 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7326 //! Compute selection.
7327 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
7331 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
7332 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
7333 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
7334 theSel->Add (aSensitive);
7339 Handle(Graphic3d_ArrayOfTriangles) myTris;
7340 Handle(Graphic3d_ArrayOfPolylines) myRect;
7341 TCollection_AsciiString myLabel;
7342 Standard_Real myWidth;
7343 Standard_Real myHeight;
7346 //==============================================================================
7347 //function : VDiffImage
7348 //purpose : The draw-command compares two images.
7349 //==============================================================================
7351 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
7355 Message::SendFail ("Syntax error: not enough arguments");
7359 Standard_Integer anArgIter = 1;
7360 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
7361 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
7362 TCollection_AsciiString aDiffImagePath;
7363 Standard_Real aTolColor = -1.0;
7364 Standard_Integer toBlackWhite = -1;
7365 Standard_Integer isBorderFilterOn = -1;
7366 Standard_Boolean isOldSyntax = Standard_False;
7367 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
7368 for (; anArgIter < theArgNb; ++anArgIter)
7370 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7372 if (anArgIter + 1 < theArgNb
7373 && (anArg == "-toleranceofcolor"
7374 || anArg == "-tolerancecolor"
7375 || anArg == "-tolerance"
7376 || anArg == "-toler"))
7378 aTolColor = Atof (theArgVec[++anArgIter]);
7379 if (aTolColor < 0.0 || aTolColor > 1.0)
7381 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
7385 else if (anArg == "-blackwhite")
7387 Standard_Boolean toEnable = Standard_True;
7388 if (anArgIter + 1 < theArgNb
7389 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
7393 toBlackWhite = toEnable ? 1 : 0;
7395 else if (anArg == "-borderfilter")
7397 Standard_Boolean toEnable = Standard_True;
7398 if (anArgIter + 1 < theArgNb
7399 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
7403 isBorderFilterOn = toEnable ? 1 : 0;
7405 else if (anArg == "-exitonclose")
7407 ViewerTest_EventManager::ToExitOnCloseView() = true;
7408 if (anArgIter + 1 < theArgNb
7409 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
7414 else if (anArg == "-closeonescape"
7415 || anArg == "-closeonesc")
7417 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
7418 if (anArgIter + 1 < theArgNb
7419 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
7424 else if (anArgIter + 3 < theArgNb
7425 && anArg == "-display")
7427 aViewName = theArgVec[++anArgIter];
7428 aPrsNameRef = theArgVec[++anArgIter];
7429 aPrsNameNew = theArgVec[++anArgIter];
7430 if (anArgIter + 1 < theArgNb
7431 && *theArgVec[anArgIter + 1] != '-')
7433 aPrsNameDiff = theArgVec[++anArgIter];
7436 else if (aTolColor < 0.0
7437 && anArg.IsRealValue())
7439 isOldSyntax = Standard_True;
7440 aTolColor = anArg.RealValue();
7441 if (aTolColor < 0.0 || aTolColor > 1.0)
7443 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
7447 else if (isOldSyntax
7448 && toBlackWhite == -1
7449 && (anArg == "0" || anArg == "1"))
7451 toBlackWhite = anArg == "1" ? 1 : 0;
7453 else if (isOldSyntax
7454 && isBorderFilterOn == -1
7455 && (anArg == "0" || anArg == "1"))
7457 isBorderFilterOn = anArg == "1" ? 1 : 0;
7459 else if (aDiffImagePath.IsEmpty())
7461 aDiffImagePath = theArgVec[anArgIter];
7465 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7470 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
7471 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
7472 if (!anImgRef->Load (anImgPathRef))
7474 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
7477 if (!anImgNew->Load (anImgPathNew))
7479 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
7483 // compare the images
7484 Image_Diff aComparer;
7485 Standard_Integer aDiffColorsNb = -1;
7486 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
7488 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
7489 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
7490 aDiffColorsNb = aComparer.Compare();
7491 theDI << aDiffColorsNb << "\n";
7494 // save image of difference
7495 Handle(Image_AlienPixMap) aDiff;
7496 if (aDiffColorsNb > 0
7497 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
7499 aDiff = new Image_AlienPixMap();
7500 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
7502 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
7505 aComparer.SaveDiffImage (*aDiff);
7506 if (!aDiffImagePath.IsEmpty()
7507 && !aDiff->Save (aDiffImagePath))
7509 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
7514 if (aViewName.IsEmpty())
7519 ViewerTest_Names aViewNames (aViewName);
7520 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
7522 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
7523 theDI.Eval (aCommand.ToCString());
7526 Standard_Integer aPxLeft = 0;
7527 Standard_Integer aPxTop = 0;
7528 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
7529 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
7530 ? int(anImgRef->SizeY() * 2)
7531 : int(anImgRef->SizeY());
7532 TCollection_AsciiString aDisplayName;
7533 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
7534 aViewName, aDisplayName);
7536 Standard_Real aRatio = anImgRef->Ratio();
7537 Standard_Real aSizeX = 1.0;
7538 Standard_Real aSizeY = aSizeX / aRatio;
7540 OSD_Path aPath (anImgPathRef);
7541 TCollection_AsciiString aLabelRef;
7542 if (!aPath.Name().IsEmpty())
7544 aLabelRef = aPath.Name() + aPath.Extension();
7546 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
7548 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
7550 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
7551 anImgRefPrs->SetLocalTransformation (aTrsfRef);
7552 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
7555 OSD_Path aPath (anImgPathNew);
7556 TCollection_AsciiString aLabelNew;
7557 if (!aPath.Name().IsEmpty())
7559 aLabelNew = aPath.Name() + aPath.Extension();
7561 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
7563 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
7565 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
7566 anImgNewPrs->SetLocalTransformation (aTrsfRef);
7567 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
7569 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
7570 if (!aDiff.IsNull())
7572 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
7574 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
7575 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
7577 if (!aPrsNameDiff.IsEmpty())
7579 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
7581 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
7582 ViewerTest::CurrentView()->FitAll();
7586 //=======================================================================
7587 //function : VSelect
7588 //purpose : Emulates different types of selection by mouse:
7589 // 1) single click selection
7590 // 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
7591 // 3) selection with polygon having corners at
7592 // pixel positions (x1,y1),...,(xn,yn)
7593 // 4) any of these selections with shift button pressed
7594 //=======================================================================
7595 static Standard_Integer VSelect (Draw_Interpretor& ,
7596 Standard_Integer theNbArgs,
7597 const char** theArgVec)
7599 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
7602 Message::SendFail ("Error: no active viewer");
7606 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
7607 bool isShiftSelection = false, toAllowOverlap = false;
7608 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7610 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7612 if (anArg == "-allowoverlap")
7614 toAllowOverlap = true;
7615 if (anArgIter + 1 < theNbArgs
7616 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
7621 else if (anArgIter + 1 < theNbArgs
7622 && anArg.IsIntegerValue()
7623 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
7625 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
7626 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
7628 else if (anArgIter + 1 == theNbArgs
7629 && anArg.IsIntegerValue())
7631 isShiftSelection = anArg.IntegerValue() == 1;
7635 Message::SendFail() << "Syntax error at '" << anArg << "'";
7642 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
7645 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
7646 if (aPnts.IsEmpty())
7648 if (isShiftSelection)
7650 aCtx->ShiftSelect (false);
7654 aCtx->Select (false);
7656 aCtx->CurrentViewer()->Invalidate();
7658 else if (aPnts.Length() == 2)
7661 && aPnts.First().y() < aPnts.Last().y())
7663 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7665 else if (!toAllowOverlap
7666 && aPnts.First().y() > aPnts.Last().y())
7668 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7670 aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
7674 aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
7676 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
7680 //=======================================================================
7681 //function : VMoveTo
7682 //purpose : Emulates cursor movement to defined pixel position
7683 //=======================================================================
7684 static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
7685 Standard_Integer theNbArgs,
7686 const char** theArgVec)
7688 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7689 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7690 if (aContext.IsNull())
7692 Message::SendFail ("Error: no active viewer");
7696 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7697 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7699 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7700 anArgStr.LowerCase();
7701 if (anArgStr == "-reset"
7702 || anArgStr == "-clear")
7704 if (anArgIter + 1 < theNbArgs)
7706 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
7710 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->Grid()->IsActive()
7711 && aContext->CurrentViewer()->GridEcho();
7714 aContext->CurrentViewer()->HideGridEcho (aView);
7716 if (aContext->ClearDetected() || toEchoGrid)
7718 aContext->CurrentViewer()->RedrawImmediate();
7722 else if (aMousePos.x() == IntegerLast()
7723 && anArgStr.IsIntegerValue())
7725 aMousePos.x() = anArgStr.IntegerValue();
7727 else if (aMousePos.y() == IntegerLast()
7728 && anArgStr.IsIntegerValue())
7730 aMousePos.y() = anArgStr.IntegerValue();
7734 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7739 if (aMousePos.x() == IntegerLast()
7740 || aMousePos.y() == IntegerLast())
7742 Message::SendFail ("Syntax error: wrong number of arguments");
7746 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7747 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7748 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7750 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7751 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7752 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7754 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7756 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7760 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
7766 //! Global map storing all animations registered in ViewerTest.
7767 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7769 //! The animation calling the Draw Harness command.
7770 class ViewerTest_AnimationProc : public AIS_Animation
7774 //! Main constructor.
7775 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7776 Draw_Interpretor* theDI,
7777 const TCollection_AsciiString& theCommand)
7778 : AIS_Animation (theAnimationName),
7780 myCommand (theCommand)
7787 //! Evaluate the command.
7788 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7790 TCollection_AsciiString aCmd = myCommand;
7791 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7792 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7793 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7794 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7795 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7796 myDrawInter->Eval (aCmd.ToCString());
7799 //! Find the keyword in the command and replace it with value.
7800 //! @return the position of the keyword to pass value
7801 void replace (TCollection_AsciiString& theCmd,
7802 const TCollection_AsciiString& theKey,
7803 const TCollection_AsciiString& theVal)
7805 TCollection_AsciiString aCmd (theCmd);
7807 const Standard_Integer aPos = aCmd.Search (theKey);
7813 TCollection_AsciiString aPart1, aPart2;
7814 Standard_Integer aPart1To = aPos - 1;
7816 && aPart1To <= theCmd.Length())
7818 aPart1 = theCmd.SubString (1, aPart1To);
7821 Standard_Integer aPart2From = aPos + theKey.Length();
7823 && aPart2From <= theCmd.Length())
7825 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7828 theCmd = aPart1 + theVal + aPart2;
7833 Draw_Interpretor* myDrawInter;
7834 TCollection_AsciiString myCommand;
7838 //! Replace the animation with the new one.
7839 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7840 Handle(AIS_Animation)& theAnimation,
7841 const Handle(AIS_Animation)& theAnimationNew)
7843 theAnimationNew->CopyFrom (theAnimation);
7844 if (!theParentAnimation.IsNull())
7846 theParentAnimation->Replace (theAnimation, theAnimationNew);
7850 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7851 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7853 theAnimation = theAnimationNew;
7856 //! Parse the point.
7857 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7859 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
7860 if (!anXYZ[0].IsRealValue()
7861 || !anXYZ[1].IsRealValue()
7862 || !anXYZ[2].IsRealValue())
7864 return Standard_False;
7867 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7868 return Standard_True;
7871 //! Parse the quaternion.
7872 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7874 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
7875 if (!anXYZW[0].IsRealValue()
7876 || !anXYZW[1].IsRealValue()
7877 || !anXYZW[2].IsRealValue()
7878 || !anXYZW[3].IsRealValue())
7880 return Standard_False;
7883 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7884 return Standard_True;
7887 //! Auxiliary class for flipping image upside-down.
7892 //! Empty constructor.
7893 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7895 //! Perform flipping.
7896 Standard_Boolean FlipY (Image_PixMap& theImage)
7898 if (theImage.IsEmpty()
7899 || theImage.SizeX() == 0
7900 || theImage.SizeY() == 0)
7902 return Standard_False;
7905 const Standard_Size aRowSize = theImage.SizeRowBytes();
7906 if (myTmp.Size() < aRowSize
7907 && !myTmp.Allocate (aRowSize))
7909 return Standard_False;
7912 // for odd height middle row should be left as is
7913 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7914 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7916 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7917 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7918 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7919 memcpy (aTop, aBot, aRowSize);
7920 memcpy (aBot, myTmp.Data(), aRowSize);
7922 return Standard_True;
7926 NCollection_Buffer myTmp;
7931 //=================================================================================================
7932 //function : VViewParams
7933 //purpose : Gets or sets AIS View characteristics
7934 //=================================================================================================
7935 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7937 Handle(V3d_View) aView = ViewerTest::CurrentView();
7940 Message::SendFail ("Error: no active viewer");
7944 Standard_Boolean toSetProj = Standard_False;
7945 Standard_Boolean toSetUp = Standard_False;
7946 Standard_Boolean toSetAt = Standard_False;
7947 Standard_Boolean toSetEye = Standard_False;
7948 Standard_Boolean toSetScale = Standard_False;
7949 Standard_Boolean toSetSize = Standard_False;
7950 Standard_Boolean toSetCenter2d = Standard_False;
7951 Standard_Real aViewScale = aView->Scale();
7952 Standard_Real aViewSize = 1.0;
7953 Graphic3d_Vec2i aCenter2d;
7954 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7955 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7956 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7957 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7958 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
7961 // print all of the available view parameters
7965 "Proj: %12g %12g %12g\n"
7966 "Up: %12g %12g %12g\n"
7967 "At: %12g %12g %12g\n"
7968 "Eye: %12g %12g %12g\n",
7970 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7971 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7972 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7973 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7978 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7979 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
7981 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7983 if (anUpdateTool.parseRedrawMode (anArg))
7987 else if (anArg == "-cmd"
7988 || anArg == "-command"
7989 || anArg == "-args")
7998 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7999 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
8000 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8003 else if (anArg == "-scale"
8004 || anArg == "-size")
8006 if (anArgIter + 1 < theArgsNb
8007 && *theArgVec[anArgIter + 1] != '-')
8009 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
8010 if (aValueArg.IsRealValue())
8013 if (anArg == "-scale")
8015 toSetScale = Standard_True;
8016 aViewScale = aValueArg.RealValue();
8018 else if (anArg == "-size")
8020 toSetSize = Standard_True;
8021 aViewSize = aValueArg.RealValue();
8026 if (anArg == "-scale")
8028 theDi << "Scale: " << aView->Scale() << "\n";
8030 else if (anArg == "-size")
8032 Graphic3d_Vec2d aSizeXY;
8033 aView->Size (aSizeXY.x(), aSizeXY.y());
8034 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
8037 else if (anArg == "-eye"
8040 || anArg == "-proj")
8042 if (anArgIter + 3 < theArgsNb)
8045 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
8048 if (anArg == "-eye")
8050 toSetEye = Standard_True;
8053 else if (anArg == "-at")
8055 toSetAt = Standard_True;
8058 else if (anArg == "-up")
8060 toSetUp = Standard_True;
8063 else if (anArg == "-proj")
8065 toSetProj = Standard_True;
8072 if (anArg == "-eye")
8074 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
8076 else if (anArg == "-at")
8078 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
8080 else if (anArg == "-up")
8082 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
8084 else if (anArg == "-proj")
8086 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
8089 else if (anArg == "-center")
8091 if (anArgIter + 2 < theArgsNb)
8093 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
8094 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
8095 if (anX.IsIntegerValue()
8096 && anY.IsIntegerValue())
8098 toSetCenter2d = Standard_True;
8099 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
8105 Message::SendFail() << "Syntax error at '" << anArg << "'";
8110 // change view parameters in proper order
8113 aView->SetScale (aViewScale);
8117 aView->SetSize (aViewSize);
8121 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
8125 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8129 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
8133 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
8137 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
8143 //==============================================================================
8144 //function : V2DMode
8146 //==============================================================================
8147 static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
8149 bool is2dMode = true;
8150 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
8151 if (aV3dView.IsNull())
8153 Message::SendFail ("Error: no active viewer");
8156 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
8158 const TCollection_AsciiString anArg = theArgVec[anArgIt];
8159 TCollection_AsciiString anArgCase = anArg;
8160 anArgCase.LowerCase();
8161 if (anArgIt + 1 < theArgsNb
8162 && anArgCase == "-name")
8164 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
8165 TCollection_AsciiString aViewName = aViewNames.GetViewName();
8166 if (!ViewerTest_myViews.IsBound1 (aViewName))
8168 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
8171 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
8173 else if (anArgCase == "-mode")
8175 if (anArgIt + 1 < theArgsNb
8176 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
8181 else if (ViewerTest::ParseOnOff (theArgVec[anArgIt], is2dMode))
8187 Message::SendFail() << "Syntax error: unknown argument " << anArg;
8192 aV3dView->SetView2DMode (is2dMode);
8196 //==============================================================================
8197 //function : VAnimation
8199 //==============================================================================
8200 static Standard_Integer VAnimation (Draw_Interpretor& theDI,
8201 Standard_Integer theArgNb,
8202 const char** theArgVec)
8204 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
8207 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
8208 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
8210 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
8216 Message::SendFail ("Error: no active viewer");
8220 Standard_Integer anArgIter = 1;
8221 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
8222 if (aNameArg.IsEmpty())
8224 Message::SendFail ("Syntax error: animation name is not defined");
8228 TCollection_AsciiString aNameArgLower = aNameArg;
8229 aNameArgLower.LowerCase();
8230 if (aNameArgLower == "-reset"
8231 || aNameArgLower == "-clear")
8233 ViewerTest_AnimationTimelineMap.Clear();
8236 else if (aNameArg.Value (1) == '-')
8238 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
8242 const char* aNameSplitter = "/";
8243 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
8244 if (aSplitPos == -1)
8246 aNameSplitter = ".";
8247 aSplitPos = aNameArg.Search (aNameSplitter);
8250 // find existing or create a new animation by specified name within syntax "parent.child".
8251 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
8252 for (; !aNameArg.IsEmpty();)
8254 TCollection_AsciiString aNameParent;
8255 if (aSplitPos != -1)
8257 if (aSplitPos == aNameArg.Length())
8259 Message::SendFail ("Syntax error: animation name is not defined");
8263 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
8264 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
8266 aSplitPos = aNameArg.Search (aNameSplitter);
8270 aNameParent = aNameArg;
8274 if (anAnimation.IsNull())
8276 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
8278 anAnimation = new AIS_Animation (aNameParent);
8279 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
8281 aRootAnimation = anAnimation;
8285 aParentAnimation = anAnimation;
8286 anAnimation = aParentAnimation->Find (aNameParent);
8287 if (anAnimation.IsNull())
8289 anAnimation = new AIS_Animation (aNameParent);
8290 aParentAnimation->Add (anAnimation);
8295 if (anArgIter >= theArgNb)
8297 // just print the list of children
8298 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
8300 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
8305 // animation parameters
8306 Standard_Boolean toPlay = Standard_False;
8307 Standard_Real aPlaySpeed = 1.0;
8308 Standard_Real aPlayStartTime = anAnimation->StartPts();
8309 Standard_Real aPlayDuration = anAnimation->Duration();
8310 Standard_Boolean isFreeCamera = Standard_False;
8311 Standard_Boolean isLockLoop = Standard_False;
8313 // video recording parameters
8314 TCollection_AsciiString aRecFile;
8315 Image_VideoParams aRecParams;
8317 Handle(V3d_View) aView = ViewerTest::CurrentView();
8318 for (; anArgIter < theArgNb; ++anArgIter)
8320 TCollection_AsciiString anArg (theArgVec[anArgIter]);
8323 if (anArg == "-reset"
8324 || anArg == "-clear")
8326 anAnimation->Clear();
8328 else if (anArg == "-remove"
8330 || anArg == "-delete")
8332 if (!aParentAnimation.IsNull())
8334 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
8338 aParentAnimation->Remove (anAnimation);
8342 else if (anArg == "-play")
8344 toPlay = Standard_True;
8345 if (++anArgIter < theArgNb)
8347 if (*theArgVec[anArgIter] == '-')
8352 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
8354 if (++anArgIter < theArgNb)
8356 if (*theArgVec[anArgIter] == '-')
8361 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8365 else if (anArg == "-resume")
8367 toPlay = Standard_True;
8368 aPlayStartTime = anAnimation->ElapsedTime();
8369 if (++anArgIter < theArgNb)
8371 if (*theArgVec[anArgIter] == '-')
8377 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8380 else if (anArg == "-playspeed"
8381 || anArg == "-speed")
8383 if (++anArgIter >= theArgNb)
8385 Message::SendFail() << "Syntax error at " << anArg << "";
8388 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8390 else if (anArg == "-lock"
8391 || anArg == "-lockloop"
8392 || anArg == "-playlockloop")
8394 isLockLoop = Standard_True;
8396 else if (anArg == "-freecamera"
8397 || anArg == "-playfreecamera"
8398 || anArg == "-freelook")
8400 isFreeCamera = Standard_True;
8402 // video recodring options
8403 else if (anArg == "-rec"
8404 || anArg == "-record")
8406 if (++anArgIter >= theArgNb)
8408 Message::SendFail() << "Syntax error at " << anArg;
8412 aRecFile = theArgVec[anArgIter];
8413 if (aRecParams.FpsNum <= 0)
8415 aRecParams.FpsNum = 24;
8418 if (anArgIter + 2 < theArgNb
8419 && *theArgVec[anArgIter + 1] != '-'
8420 && *theArgVec[anArgIter + 2] != '-')
8422 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8423 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8424 if (aWidthArg .IsIntegerValue()
8425 && aHeightArg.IsIntegerValue())
8427 aRecParams.Width = aWidthArg .IntegerValue();
8428 aRecParams.Height = aHeightArg.IntegerValue();
8433 else if (anArg == "-fps")
8435 if (++anArgIter >= theArgNb)
8437 Message::SendFail() << "Syntax error at " << anArg;
8441 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8442 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8443 if (aSplitIndex == 0)
8445 aRecParams.FpsNum = aFpsArg.IntegerValue();
8449 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8450 aFpsArg.Split (aFpsArg.Length() - 1);
8451 const TCollection_AsciiString aNumStr = aFpsArg;
8452 aRecParams.FpsNum = aNumStr.IntegerValue();
8453 aRecParams.FpsDen = aDenStr.IntegerValue();
8454 if (aRecParams.FpsDen < 1)
8456 Message::SendFail() << "Syntax error at " << anArg;
8461 else if (anArg == "-format")
8463 if (++anArgIter >= theArgNb)
8465 Message::SendFail() << "Syntax error at " << anArg;
8468 aRecParams.Format = theArgVec[anArgIter];
8470 else if (anArg == "-pix_fmt"
8471 || anArg == "-pixfmt"
8472 || anArg == "-pixelformat")
8474 if (++anArgIter >= theArgNb)
8476 Message::SendFail() << "Syntax error at " << anArg;
8479 aRecParams.PixelFormat = theArgVec[anArgIter];
8481 else if (anArg == "-codec"
8482 || anArg == "-vcodec"
8483 || anArg == "-videocodec")
8485 if (++anArgIter >= theArgNb)
8487 Message::SendFail() << "Syntax error at " << anArg;
8490 aRecParams.VideoCodec = theArgVec[anArgIter];
8492 else if (anArg == "-crf"
8493 || anArg == "-preset"
8496 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8497 if (++anArgIter >= theArgNb)
8499 Message::SendFail() << "Syntax error at " << anArg;
8503 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8505 // animation definition options
8506 else if (anArg == "-start"
8507 || anArg == "-starttime"
8508 || anArg == "-startpts")
8510 if (++anArgIter >= theArgNb)
8512 Message::SendFail() << "Syntax error at " << anArg;
8516 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8517 aRootAnimation->UpdateTotalDuration();
8519 else if (anArg == "-end"
8520 || anArg == "-endtime"
8521 || anArg == "-endpts")
8523 if (++anArgIter >= theArgNb)
8525 Message::SendFail() << "Syntax error at " << anArg;
8529 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8530 aRootAnimation->UpdateTotalDuration();
8532 else if (anArg == "-dur"
8533 || anArg == "-duration")
8535 if (++anArgIter >= theArgNb)
8537 Message::SendFail() << "Syntax error at " << anArg;
8541 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8542 aRootAnimation->UpdateTotalDuration();
8544 else if (anArg == "-command"
8546 || anArg == "-invoke"
8548 || anArg == "-proc")
8550 if (++anArgIter >= theArgNb)
8552 Message::SendFail() << "Syntax error at " << anArg;
8556 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8557 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8559 else if (anArg == "-objecttrsf"
8560 || anArg == "-objectransformation"
8561 || anArg == "-objtransformation"
8562 || anArg == "-objtrsf"
8563 || anArg == "-object"
8566 if (++anArgIter >= theArgNb)
8568 Message::SendFail() << "Syntax error at " << anArg;
8572 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8573 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8574 Handle(AIS_InteractiveObject) anObject;
8575 if (!aMapOfAIS.Find2 (anObjName, anObject))
8577 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
8581 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8582 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8583 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8584 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8585 Standard_Boolean isTrsfSet = Standard_False;
8586 Standard_Integer aTrsfArgIter = anArgIter + 1;
8587 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8589 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8590 aTrsfArg.LowerCase();
8591 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8592 if (aTrsfArg.StartsWith ("-rotation")
8593 || aTrsfArg.StartsWith ("-rot"))
8595 isTrsfSet = Standard_True;
8596 if (aTrsfArgIter + 4 >= theArgNb
8597 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8599 Message::SendFail() << "Syntax error at " << aTrsfArg;
8604 else if (aTrsfArg.StartsWith ("-location")
8605 || aTrsfArg.StartsWith ("-loc"))
8607 isTrsfSet = Standard_True;
8608 if (aTrsfArgIter + 3 >= theArgNb
8609 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8611 Message::SendFail() << "Syntax error at " << aTrsfArg;
8616 else if (aTrsfArg.StartsWith ("-scale"))
8618 isTrsfSet = Standard_True;
8619 if (++aTrsfArgIter >= theArgNb)
8621 Message::SendFail() << "Syntax error at " << aTrsfArg;
8625 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
8626 if (!aScaleStr.IsRealValue())
8628 Message::SendFail() << "Syntax error at " << aTrsfArg;
8631 aScales[anIndex] = aScaleStr.RealValue();
8635 anArgIter = aTrsfArgIter - 1;
8641 Message::SendFail() << "Syntax error at " << anArg;
8644 else if (aTrsfArgIter >= theArgNb)
8646 anArgIter = theArgNb;
8649 aTrsfs[0].SetRotation (aRotQuats[0]);
8650 aTrsfs[1].SetRotation (aRotQuats[1]);
8651 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8652 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8653 aTrsfs[0].SetScaleFactor (aScales[0]);
8654 aTrsfs[1].SetScaleFactor (aScales[1]);
8656 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8657 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8659 else if (anArg == "-viewtrsf"
8660 || anArg == "-view")
8662 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8663 if (aCamAnimation.IsNull())
8665 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8666 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8669 Handle(Graphic3d_Camera) aCams[2] =
8671 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8672 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8675 Standard_Boolean isTrsfSet = Standard_False;
8676 Standard_Integer aViewArgIter = anArgIter + 1;
8677 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8679 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8680 aViewArg.LowerCase();
8681 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8682 if (aViewArg.StartsWith ("-scale"))
8684 isTrsfSet = Standard_True;
8685 if (++aViewArgIter >= theArgNb)
8687 Message::SendFail() << "Syntax error at " << anArg;
8691 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
8692 if (!aScaleStr.IsRealValue())
8694 Message::SendFail() << "Syntax error at " << aViewArg;
8697 Standard_Real aScale = aScaleStr.RealValue();
8698 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8699 aCams[anIndex]->SetScale (aScale);
8701 else if (aViewArg.StartsWith ("-eye")
8702 || aViewArg.StartsWith ("-center")
8703 || aViewArg.StartsWith ("-at")
8704 || aViewArg.StartsWith ("-up"))
8706 isTrsfSet = Standard_True;
8708 if (aViewArgIter + 3 >= theArgNb
8709 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8711 Message::SendFail() << "Syntax error at " << aViewArg;
8716 if (aViewArg.StartsWith ("-eye"))
8718 aCams[anIndex]->SetEye (anXYZ);
8720 else if (aViewArg.StartsWith ("-center")
8721 || aViewArg.StartsWith ("-at"))
8723 aCams[anIndex]->SetCenter (anXYZ);
8725 else if (aViewArg.StartsWith ("-up"))
8727 aCams[anIndex]->SetUp (anXYZ);
8732 anArgIter = aViewArgIter - 1;
8738 Message::SendFail() << "Syntax error at " << anArg;
8741 else if (aViewArgIter >= theArgNb)
8743 anArgIter = theArgNb;
8746 aCamAnimation->SetCameraStart(aCams[0]);
8747 aCamAnimation->SetCameraEnd (aCams[1]);
8751 Message::SendFail() << "Syntax error at " << anArg;
8756 if (!toPlay && aRecFile.IsEmpty())
8761 // Start animation timeline and process frame updating.
8762 TheIsAnimating = Standard_True;
8763 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8764 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
8765 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
8768 aView->Camera()->Copy (aCameraBack);
8771 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
8772 if (aRecParams.FpsNum <= 0)
8774 while (!anAnimation->IsStopped())
8776 aCameraBack->Copy (aView->Camera());
8777 const Standard_Real aPts = anAnimation->UpdateTimer();
8780 aView->Camera()->Copy (aCameraBack);
8783 if (aPts >= anUpperPts)
8785 anAnimation->Pause();
8789 if (aView->IsInvalidated())
8795 aView->RedrawImmediate();
8800 // handle user events
8801 theDI.Eval ("after 1 set waiter 1");
8802 theDI.Eval ("vwait waiter");
8804 if (!TheIsAnimating)
8806 anAnimation->Pause();
8812 if (aView->IsInvalidated())
8818 aView->RedrawImmediate();
8823 OSD_Timer aPerfTimer;
8826 Handle(Image_VideoRecorder) aRecorder;
8827 ImageFlipper aFlipper;
8828 Handle(Draw_ProgressIndicator) aProgress;
8829 if (!aRecFile.IsEmpty())
8831 if (aRecParams.Width <= 0
8832 || aRecParams.Height <= 0)
8834 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8837 aRecorder = new Image_VideoRecorder();
8838 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8840 Message::SendFail ("Error: failed to open video file for recording");
8844 aProgress = new Draw_ProgressIndicator (theDI, 1);
8847 // Manage frame-rated animation here
8848 Standard_Real aPts = aPlayStartTime;
8849 int64_t aNbFrames = 0;
8850 Message_ProgressSentry aPSentry (aProgress, "Video recording, sec", 0, Max (1, Standard_Integer(aPlayDuration / aPlaySpeed)), 1);
8851 Standard_Integer aSecondsProgress = 0;
8852 for (; aPts <= anUpperPts && aPSentry.More();)
8854 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
8855 aPts = aPlayStartTime + aRecPts;
8857 if (!anAnimation->Update (aPts))
8862 if (!aRecorder.IsNull())
8864 V3d_ImageDumpOptions aDumpParams;
8865 aDumpParams.Width = aRecParams.Width;
8866 aDumpParams.Height = aRecParams.Height;
8867 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8868 aDumpParams.StereoOptions = V3d_SDO_MONO;
8869 aDumpParams.ToAdjustAspect = Standard_True;
8870 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8872 Message::SendFail ("Error: view dump is failed");
8875 aFlipper.FlipY (aRecorder->ChangeFrame());
8876 if (!aRecorder->PushFrame())
8886 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8894 anAnimation->Stop();
8895 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8896 theDI << "Average FPS: " << aRecFps << "\n"
8897 << "Nb. Frames: " << Standard_Real(aNbFrames);
8902 aView->SetImmediateUpdate (wasImmediateUpdate);
8903 TheIsAnimating = Standard_False;
8908 //=======================================================================
8909 //function : VChangeSelected
8910 //purpose : Adds the shape to selection or remove one from it
8911 //=======================================================================
8912 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8913 Standard_Integer argc,
8918 di<<"Usage : " << argv[0] << " shape \n";
8922 TCollection_AsciiString aName(argv[1]);
8923 Handle(AIS_InteractiveObject) anAISObject;
8924 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8925 || anAISObject.IsNull())
8927 di<<"Use 'vdisplay' before";
8931 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
8935 //=======================================================================
8936 //function : VNbSelected
8937 //purpose : Returns number of selected objects
8938 //=======================================================================
8939 static Standard_Integer VNbSelected (Draw_Interpretor& di,
8940 Standard_Integer argc,
8945 di << "Usage : " << argv[0] << "\n";
8948 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8949 if(aContext.IsNull())
8951 di << "use 'vinit' command before " << argv[0] << "\n";
8954 di << aContext->NbSelected() << "\n";
8958 //=======================================================================
8959 //function : VPurgeDisplay
8960 //purpose : Switches altialiasing on or off
8961 //=======================================================================
8962 static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
8963 Standard_Integer argc,
8968 di << "Usage : " << argv[0] << "\n";
8971 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8972 if (aContext.IsNull())
8974 di << "use 'vinit' command before " << argv[0] << "\n";
8978 di << aContext->PurgeDisplay() << "\n";
8982 //=======================================================================
8983 //function : VSetViewSize
8985 //=======================================================================
8986 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8987 Standard_Integer argc,
8990 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8991 if(aContext.IsNull())
8993 di << "use 'vinit' command before " << argv[0] << "\n";
8998 di<<"Usage : " << argv[0] << " Size\n";
9001 Standard_Real aSize = Draw::Atof (argv[1]);
9004 di<<"Bad Size value : " << aSize << "\n";
9008 Handle(V3d_View) aView = ViewerTest::CurrentView();
9009 aView->SetSize(aSize);
9013 //=======================================================================
9014 //function : VMoveView
9016 //=======================================================================
9017 static Standard_Integer VMoveView (Draw_Interpretor& di,
9018 Standard_Integer argc,
9021 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9022 if(aContext.IsNull())
9024 di << "use 'vinit' command before " << argv[0] << "\n";
9027 if(argc < 4 || argc > 5)
9029 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9032 Standard_Real Dx = Draw::Atof (argv[1]);
9033 Standard_Real Dy = Draw::Atof (argv[2]);
9034 Standard_Real Dz = Draw::Atof (argv[3]);
9035 Standard_Boolean aStart = Standard_True;
9038 aStart = (Draw::Atoi (argv[4]) > 0);
9041 Handle(V3d_View) aView = ViewerTest::CurrentView();
9042 aView->Move(Dx,Dy,Dz,aStart);
9046 //=======================================================================
9047 //function : VTranslateView
9049 //=======================================================================
9050 static Standard_Integer VTranslateView (Draw_Interpretor& di,
9051 Standard_Integer argc,
9054 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9055 if(aContext.IsNull())
9057 di << "use 'vinit' command before " << argv[0] << "\n";
9060 if(argc < 4 || argc > 5)
9062 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9065 Standard_Real Dx = Draw::Atof (argv[1]);
9066 Standard_Real Dy = Draw::Atof (argv[2]);
9067 Standard_Real Dz = Draw::Atof (argv[3]);
9068 Standard_Boolean aStart = Standard_True;
9071 aStart = (Draw::Atoi (argv[4]) > 0);
9074 Handle(V3d_View) aView = ViewerTest::CurrentView();
9075 aView->Translate(Dx,Dy,Dz,aStart);
9079 //=======================================================================
9080 //function : VTurnView
9082 //=======================================================================
9083 static Standard_Integer VTurnView (Draw_Interpretor& di,
9084 Standard_Integer argc,
9087 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9088 if(aContext.IsNull()) {
9089 di << "use 'vinit' command before " << argv[0] << "\n";
9092 if(argc < 4 || argc > 5){
9093 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
9096 Standard_Real Ax = Draw::Atof (argv[1]);
9097 Standard_Real Ay = Draw::Atof (argv[2]);
9098 Standard_Real Az = Draw::Atof (argv[3]);
9099 Standard_Boolean aStart = Standard_True;
9102 aStart = (Draw::Atoi (argv[4]) > 0);
9105 Handle(V3d_View) aView = ViewerTest::CurrentView();
9106 aView->Turn(Ax,Ay,Az,aStart);
9110 //==============================================================================
9111 //function : VTextureEnv
9112 //purpose : ENables or disables environment mapping
9113 //==============================================================================
9114 class OCC_TextureEnv : public Graphic3d_TextureEnv
9117 OCC_TextureEnv(const Standard_CString FileName);
9118 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
9119 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
9120 const Standard_Boolean theModulateFlag,
9121 const Graphic3d_TypeOfTextureFilter theFilter,
9122 const Standard_ShortReal theXScale,
9123 const Standard_ShortReal theYScale,
9124 const Standard_ShortReal theXShift,
9125 const Standard_ShortReal theYShift,
9126 const Standard_ShortReal theAngle);
9127 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
9129 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
9131 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
9132 : Graphic3d_TextureEnv(theFileName)
9136 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
9137 : Graphic3d_TextureEnv(theTexId)
9141 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
9142 const Standard_Boolean theModulateFlag,
9143 const Graphic3d_TypeOfTextureFilter theFilter,
9144 const Standard_ShortReal theXScale,
9145 const Standard_ShortReal theYScale,
9146 const Standard_ShortReal theXShift,
9147 const Standard_ShortReal theYShift,
9148 const Standard_ShortReal theAngle)
9150 myParams->SetRepeat (theRepeatFlag);
9151 myParams->SetModulate (theModulateFlag);
9152 myParams->SetFilter (theFilter);
9153 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
9154 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
9155 myParams->SetRotation (theAngle);
9158 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
9160 // get the active view
9161 Handle(V3d_View) aView = ViewerTest::CurrentView();
9164 Message::SendFail ("Error: no active viewer");
9168 // Checking the input arguments
9169 Standard_Boolean anEnableFlag = Standard_False;
9170 Standard_Boolean isOk = theArgNb >= 2;
9173 TCollection_AsciiString anEnableOpt(theArgVec[1]);
9174 anEnableFlag = anEnableOpt.IsEqual("on");
9175 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
9179 isOk = (theArgNb == 3 || theArgNb == 11);
9182 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9183 isOk = (!aTextureOpt.IsIntegerValue() ||
9184 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
9186 if (isOk && theArgNb == 11)
9188 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
9189 aModulateOpt(theArgVec[4]),
9190 aFilterOpt (theArgVec[5]),
9191 aSScaleOpt (theArgVec[6]),
9192 aTScaleOpt (theArgVec[7]),
9193 aSTransOpt (theArgVec[8]),
9194 aTTransOpt (theArgVec[9]),
9195 anAngleOpt (theArgVec[10]);
9196 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
9197 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
9198 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
9199 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
9200 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
9201 anAngleOpt.IsRealValue());
9208 Message::SendFail() << "Usage:\n"
9209 << theArgVec[0] << " off\n"
9210 << theArgVec[0] << " on {index_of_std_texture(0..7)|texture_file_name} [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} scale_s scale_t translation_s translation_t rotation_degrees]";
9216 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9217 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
9218 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
9219 new OCC_TextureEnv(theArgVec[2]);
9223 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
9224 aTexEnv->SetTextureParameters(
9225 aRepeatOpt. IsEqual("repeat"),
9226 aModulateOpt.IsEqual("modulate"),
9227 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
9228 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
9229 Graphic3d_TOTF_TRILINEAR,
9230 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
9231 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
9232 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
9233 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
9234 (Standard_ShortReal)Draw::Atof(theArgVec[10])
9237 aView->SetTextureEnv(aTexEnv);
9239 else // Disabling environment mapping
9241 Handle(Graphic3d_TextureEnv) aTexture;
9242 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
9251 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
9253 //! Remove registered clipping plane from all views and objects.
9254 static void removePlane (MapOfPlanes& theRegPlanes,
9255 const TCollection_AsciiString& theName)
9257 Handle(Graphic3d_ClipPlane) aClipPlane;
9258 if (!theRegPlanes.Find (theName, aClipPlane))
9260 Message::SendWarning ("Warning: no such plane");
9264 theRegPlanes.UnBind (theName);
9265 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
9266 anIObjIt.More(); anIObjIt.Next())
9268 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
9269 aPrs->RemoveClipPlane (aClipPlane);
9272 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
9273 aViewIt.More(); aViewIt.Next())
9275 const Handle(V3d_View)& aView = aViewIt.Key2();
9276 aView->RemoveClipPlane(aClipPlane);
9279 ViewerTest::RedrawAllViews();
9283 //===============================================================================================
9284 //function : VClipPlane
9286 //===============================================================================================
9287 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9289 // use short-cut for created clip planes map of created (or "registered by name") clip planes
9290 static MapOfPlanes aRegPlanes;
9294 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
9296 theDi << aPlaneIter.Key() << " ";
9301 TCollection_AsciiString aCommand (theArgVec[1]);
9302 aCommand.LowerCase();
9303 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
9304 if (anActiveView.IsNull())
9306 Message::SendFail ("Error: no active viewer");
9310 // print maximum number of planes for current viewer
9311 if (aCommand == "-maxplanes"
9312 || aCommand == "maxplanes")
9314 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
9315 << " plane slots provided by driver.\n";
9319 // create / delete plane instance
9320 if (aCommand == "-create"
9321 || aCommand == "create"
9322 || aCommand == "-delete"
9323 || aCommand == "delete"
9324 || aCommand == "-clone"
9325 || aCommand == "clone")
9329 Message::SendFail ("Syntax error: plane name is required");
9333 Standard_Boolean toCreate = aCommand == "-create"
9334 || aCommand == "create";
9335 Standard_Boolean toClone = aCommand == "-clone"
9336 || aCommand == "clone";
9337 Standard_Boolean toDelete = aCommand == "-delete"
9338 || aCommand == "delete";
9339 TCollection_AsciiString aPlane (theArgVec[2]);
9343 if (aRegPlanes.IsBound (aPlane))
9345 std::cout << "Warning: existing plane has been overridden.\n";
9350 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9354 else if (toClone) // toClone
9356 if (!aRegPlanes.IsBound (aPlane))
9358 Message::SendFail ("Error: no such plane");
9361 else if (theArgsNb < 4)
9363 Message::SendFail ("Syntax error: enter name for new plane");
9367 TCollection_AsciiString aClone (theArgVec[3]);
9368 if (aRegPlanes.IsBound (aClone))
9370 Message::SendFail ("Error: plane name is in use");
9374 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
9376 aRegPlanes.Bind (aClone, aClipPlane->Clone());
9386 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
9388 aPlane = aPlaneIter.Key();
9389 removePlane (aRegPlanes, aPlane);
9390 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
9395 removePlane (aRegPlanes, aPlane);
9401 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9406 // set / unset plane command
9407 if (aCommand == "set"
9408 || aCommand == "unset")
9412 Message::SendFail ("Syntax error: need more arguments");
9416 // redirect to new syntax
9417 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
9418 anArgVec.SetValue (1, theArgVec[0]);
9419 anArgVec.SetValue (2, theArgVec[2]);
9420 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
9421 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
9423 anArgVec.SetValue (anIt, theArgVec[anIt]);
9426 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
9429 // change plane command
9430 TCollection_AsciiString aPlaneName;
9431 Handle(Graphic3d_ClipPlane) aClipPlane;
9432 Standard_Integer anArgIter = 0;
9433 if (aCommand == "-change"
9434 || aCommand == "change")
9436 // old syntax support
9439 Message::SendFail ("Syntax error: need more arguments");
9444 aPlaneName = theArgVec[2];
9445 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
9447 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
9451 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9454 aPlaneName = theArgVec[1];
9459 aPlaneName = theArgVec[1];
9460 aClipPlane = new Graphic3d_ClipPlane();
9461 aRegPlanes.Bind (aPlaneName, aClipPlane);
9462 theDi << "Created new plane " << aPlaneName << ".\n";
9465 if (theArgsNb - anArgIter < 1)
9467 Message::SendFail ("Syntax error: need more arguments");
9471 for (; anArgIter < theArgsNb; ++anArgIter)
9473 const char** aChangeArgs = theArgVec + anArgIter;
9474 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9475 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9476 aChangeArg.LowerCase();
9478 Standard_Boolean toEnable = Standard_True;
9479 if (ViewerTest::ParseOnOff (aChangeArgs[0], toEnable))
9481 aClipPlane->SetOn (toEnable);
9483 else if (aChangeArg.StartsWith ("-equation")
9484 || aChangeArg.StartsWith ("equation"))
9486 if (aNbChangeArgs < 5)
9488 Message::SendFail ("Syntax error: need more arguments");
9492 Standard_Integer aSubIndex = 1;
9493 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9494 if (aPrefixLen < aChangeArg.Length())
9496 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9497 if (!aSubStr.IsIntegerValue()
9498 || aSubStr.IntegerValue() <= 0)
9500 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
9503 aSubIndex = aSubStr.IntegerValue();
9506 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9507 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9508 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9509 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9510 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9511 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9513 if (aSubPln->ChainNextPlane().IsNull())
9515 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9517 aSubPln = aSubPln->ChainNextPlane();
9519 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9520 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
9523 else if ((aChangeArg == "-boxinterior"
9524 || aChangeArg == "-boxint"
9525 || aChangeArg == "-box")
9526 && aNbChangeArgs >= 7)
9528 Graphic3d_BndBox3d aBndBox;
9529 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9530 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9533 Standard_Integer aNbSubPlanes = 6;
9534 const Graphic3d_Vec3d aDirArray[6] =
9536 Graphic3d_Vec3d (-1, 0, 0),
9537 Graphic3d_Vec3d ( 1, 0, 0),
9538 Graphic3d_Vec3d ( 0,-1, 0),
9539 Graphic3d_Vec3d ( 0, 1, 0),
9540 Graphic3d_Vec3d ( 0, 0,-1),
9541 Graphic3d_Vec3d ( 0, 0, 1),
9543 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9544 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9546 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9547 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9548 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9549 if (aSubPlaneIter + 1 == aNbSubPlanes)
9551 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9555 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9557 aSubPln = aSubPln->ChainNextPlane();
9560 else if (aChangeArg == "-capping"
9561 || aChangeArg == "capping")
9563 if (aNbChangeArgs < 2)
9565 Message::SendFail ("Syntax error: need more arguments");
9569 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9571 aClipPlane->SetCapping (toEnable);
9576 // just skip otherwise (old syntax)
9579 else if (aChangeArg == "-useobjectmaterial"
9580 || aChangeArg == "-useobjectmat"
9581 || aChangeArg == "-useobjmat"
9582 || aChangeArg == "-useobjmaterial")
9584 if (aNbChangeArgs < 2)
9586 Message::SendFail ("Syntax error: need more arguments");
9590 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9592 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9596 else if (aChangeArg == "-useobjecttexture"
9597 || aChangeArg == "-useobjecttex"
9598 || aChangeArg == "-useobjtexture"
9599 || aChangeArg == "-useobjtex")
9601 if (aNbChangeArgs < 2)
9603 Message::SendFail ("Syntax error: need more arguments");
9607 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9609 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9613 else if (aChangeArg == "-useobjectshader"
9614 || aChangeArg == "-useobjshader")
9616 if (aNbChangeArgs < 2)
9618 Message::SendFail ("Syntax error: need more arguments");
9622 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9624 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9628 else if (aChangeArg == "-color"
9629 || aChangeArg == "color")
9631 Quantity_Color aColor;
9632 Standard_Integer aNbParsed = ViewerTest::ParseColor (aNbChangeArgs - 1,
9637 Message::SendFail ("Syntax error: need more arguments");
9640 aClipPlane->SetCappingColor (aColor);
9641 anArgIter += aNbParsed;
9643 else if (aNbChangeArgs >= 1
9644 && (aChangeArg == "-material"
9645 || aChangeArg == "material"))
9648 Graphic3d_NameOfMaterial aMatName;
9649 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9651 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
9654 aClipPlane->SetCappingMaterial (aMatName);
9656 else if ((aChangeArg == "-transparency"
9657 || aChangeArg == "-transp")
9658 && aNbChangeArgs >= 2)
9660 TCollection_AsciiString aValStr (aChangeArgs[1]);
9661 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
9662 if (aValStr.IsRealValue())
9664 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9665 aMat.SetTransparency ((float )aValStr.RealValue());
9666 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9667 aClipPlane->SetCappingMaterial (aMat);
9671 aValStr.LowerCase();
9672 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9673 if (aValStr == "opaque")
9675 aMode = Graphic3d_AlphaMode_Opaque;
9677 else if (aValStr == "mask")
9679 aMode = Graphic3d_AlphaMode_Mask;
9681 else if (aValStr == "blend")
9683 aMode = Graphic3d_AlphaMode_Blend;
9685 else if (aValStr == "blendauto")
9687 aMode = Graphic3d_AlphaMode_BlendAuto;
9691 Message::SendFail() << "Syntax error at '" << aValStr << "'";
9694 anAspect->SetAlphaMode (aMode);
9695 aClipPlane->SetCappingAspect (anAspect);
9699 else if (aChangeArg == "-texname"
9700 || aChangeArg == "texname")
9702 if (aNbChangeArgs < 2)
9704 Message::SendFail ("Syntax error: need more arguments");
9708 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9709 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9710 if (!aTexture->IsDone())
9712 aClipPlane->SetCappingTexture (NULL);
9716 aTexture->EnableModulate();
9717 aTexture->EnableRepeat();
9718 aClipPlane->SetCappingTexture (aTexture);
9722 else if (aChangeArg == "-texscale"
9723 || aChangeArg == "texscale")
9725 if (aClipPlane->CappingTexture().IsNull())
9727 Message::SendFail ("Error: no texture is set");
9731 if (aNbChangeArgs < 3)
9733 Message::SendFail ("Syntax error: need more arguments");
9737 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9738 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9739 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9742 else if (aChangeArg == "-texorigin"
9743 || aChangeArg == "texorigin") // texture origin
9745 if (aClipPlane->CappingTexture().IsNull())
9747 Message::SendFail ("Error: no texture is set");
9751 if (aNbChangeArgs < 3)
9753 Message::SendFail ("Syntax error: need more arguments");
9757 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9758 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9760 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9763 else if (aChangeArg == "-texrotate"
9764 || aChangeArg == "texrotate") // texture rotation
9766 if (aClipPlane->CappingTexture().IsNull())
9768 Message::SendFail ("Error: no texture is set");
9772 if (aNbChangeArgs < 2)
9774 Message::SendFail ("Syntax error: need more arguments");
9778 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9779 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9782 else if (aChangeArg == "-hatch"
9783 || aChangeArg == "hatch")
9785 if (aNbChangeArgs < 2)
9787 Message::SendFail ("Syntax error: need more arguments");
9791 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9792 aHatchStr.LowerCase();
9793 if (aHatchStr == "on")
9795 aClipPlane->SetCappingHatchOn();
9797 else if (aHatchStr == "off")
9799 aClipPlane->SetCappingHatchOff();
9803 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9807 else if (aChangeArg == "-delete"
9808 || aChangeArg == "delete")
9810 removePlane (aRegPlanes, aPlaneName);
9813 else if (aChangeArg == "-set"
9814 || aChangeArg == "-unset"
9815 || aChangeArg == "-setoverrideglobal")
9817 // set / unset plane command
9818 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9819 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
9820 Standard_Integer anIt = 1;
9821 for (; anIt < aNbChangeArgs; ++anIt)
9823 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9824 if (anEntityName.IsEmpty()
9825 || anEntityName.Value (1) == '-')
9829 else if (!toOverrideGlobal
9830 && ViewerTest_myViews.IsBound1 (anEntityName))
9832 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9835 aView->AddClipPlane (aClipPlane);
9839 aView->RemoveClipPlane (aClipPlane);
9843 else if (GetMapOfAIS().IsBound2 (anEntityName))
9845 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
9848 aIObj->AddClipPlane (aClipPlane);
9852 aIObj->RemoveClipPlane (aClipPlane);
9854 if (!aIObj->ClipPlanes().IsNull())
9856 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9861 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
9868 // apply to active view
9871 anActiveView->AddClipPlane (aClipPlane);
9875 anActiveView->RemoveClipPlane (aClipPlane);
9880 anArgIter = anArgIter + anIt - 1;
9885 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
9890 ViewerTest::RedrawAllViews();
9894 //===============================================================================================
9895 //function : VZRange
9897 //===============================================================================================
9898 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9900 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9902 if (aCurrentView.IsNull())
9904 Message::SendFail ("Error: no active viewer");
9908 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
9912 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9913 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9919 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9920 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
9922 if (aNewZNear >= aNewZFar)
9924 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
9928 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9930 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
9934 aCamera->SetZRange (aNewZNear, aNewZFar);
9938 Message::SendFail ("Syntax error: wrong command arguments");
9942 aCurrentView->Redraw();
9947 //===============================================================================================
9948 //function : VAutoZFit
9950 //===============================================================================================
9951 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9953 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9955 if (aCurrentView.IsNull())
9957 Message::SendFail ("Error: no active viewer");
9961 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
9965 Message::SendFail ("Syntax error: wrong command arguments");
9971 theDi << "Auto z-fit mode: \n"
9972 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
9973 << "Scale: " << aScale << "\n";
9977 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9981 aScale = Draw::Atoi (theArgVec[2]);
9984 aCurrentView->SetAutoZFitMode (isOn, aScale);
9985 aCurrentView->AutoZFit();
9986 aCurrentView->Redraw();
9991 //! Auxiliary function to print projection type
9992 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9994 switch (theProjType)
9996 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9997 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9998 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9999 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
10000 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
10005 //===============================================================================================
10006 //function : VCamera
10008 //===============================================================================================
10009 static int VCamera (Draw_Interpretor& theDI,
10010 Standard_Integer theArgsNb,
10011 const char** theArgVec)
10013 Handle(V3d_View) aView = ViewerTest::CurrentView();
10014 if (aView.IsNull())
10016 Message::SendFail ("Error: no active viewer");
10020 Handle(Graphic3d_Camera) aCamera = aView->Camera();
10023 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
10024 theDI << "FOVy: " << aCamera->FOVy() << "\n";
10025 theDI << "Distance: " << aCamera->Distance() << "\n";
10026 theDI << "IOD: " << aCamera->IOD() << "\n";
10027 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
10028 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
10029 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
10033 TCollection_AsciiString aPrsName;
10034 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10036 Standard_CString anArg = theArgVec[anArgIter];
10037 TCollection_AsciiString anArgCase (anArg);
10038 anArgCase.LowerCase();
10039 if (anArgCase == "-proj"
10040 || anArgCase == "-projection"
10041 || anArgCase == "-projtype"
10042 || anArgCase == "-projectiontype")
10044 theDI << projTypeName (aCamera->ProjectionType()) << " ";
10046 else if (anArgCase == "-ortho"
10047 || anArgCase == "-orthographic")
10049 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
10051 else if (anArgCase == "-persp"
10052 || anArgCase == "-perspective"
10053 || anArgCase == "-perspmono"
10054 || anArgCase == "-perspectivemono"
10055 || anArgCase == "-mono")
10057 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10059 else if (anArgCase == "-stereo"
10060 || anArgCase == "-stereoscopic"
10061 || anArgCase == "-perspstereo"
10062 || anArgCase == "-perspectivestereo")
10064 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10066 else if (anArgCase == "-left"
10067 || anArgCase == "-lefteye"
10068 || anArgCase == "-monoleft"
10069 || anArgCase == "-monolefteye"
10070 || anArgCase == "-perpsleft"
10071 || anArgCase == "-perpslefteye")
10073 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
10075 else if (anArgCase == "-right"
10076 || anArgCase == "-righteye"
10077 || anArgCase == "-monoright"
10078 || anArgCase == "-monorighteye"
10079 || anArgCase == "-perpsright")
10081 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
10083 else if (anArgCase == "-dist"
10084 || anArgCase == "-distance")
10086 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10087 if (anArgValue != NULL
10088 && *anArgValue != '-')
10091 aCamera->SetDistance (Draw::Atof (anArgValue));
10094 theDI << aCamera->Distance() << " ";
10096 else if (anArgCase == "-iod")
10098 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10099 if (anArgValue != NULL
10100 && *anArgValue != '-')
10103 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
10106 theDI << aCamera->IOD() << " ";
10108 else if (anArgCase == "-iodtype")
10110 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10111 TCollection_AsciiString anValueCase (anArgValue);
10112 anValueCase.LowerCase();
10113 if (anValueCase == "abs"
10114 || anValueCase == "absolute")
10117 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
10120 else if (anValueCase == "rel"
10121 || anValueCase == "relative")
10124 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
10127 else if (*anArgValue != '-')
10129 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
10132 switch (aCamera->GetIODType())
10134 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
10135 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
10138 else if (anArgCase == "-zfocus")
10140 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10141 if (anArgValue != NULL
10142 && *anArgValue != '-')
10145 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
10148 theDI << aCamera->ZFocus() << " ";
10150 else if (anArgCase == "-zfocustype")
10152 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10153 TCollection_AsciiString anValueCase (anArgValue);
10154 anValueCase.LowerCase();
10155 if (anValueCase == "abs"
10156 || anValueCase == "absolute")
10159 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
10162 else if (anValueCase == "rel"
10163 || anValueCase == "relative")
10166 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
10169 else if (*anArgValue != '-')
10171 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
10174 switch (aCamera->ZFocusType())
10176 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
10177 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
10180 else if (anArgCase == "-fov"
10181 || anArgCase == "-fovy")
10183 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10184 if (anArgValue != NULL
10185 && *anArgValue != '-')
10188 aCamera->SetFOVy (Draw::Atof (anArgValue));
10191 theDI << aCamera->FOVy() << " ";
10193 else if (aPrsName.IsEmpty()
10194 && !anArgCase.StartsWith ("-"))
10200 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
10205 if (aPrsName.IsEmpty()
10212 if (!aPrsName.IsEmpty())
10214 Handle(AIS_CameraFrustum) aCameraFrustum;
10215 if (GetMapOfAIS().IsBound2 (aPrsName))
10217 // find existing object
10218 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
10219 if (aCameraFrustum.IsNull())
10221 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
10226 if (aCameraFrustum.IsNull())
10228 aCameraFrustum = new AIS_CameraFrustum();
10232 // not include displayed object of old camera frustum in the new one.
10233 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
10236 aCameraFrustum->SetCameraFrustum (aView->Camera());
10238 ViewerTest::Display (aPrsName, aCameraFrustum);
10244 //! Parse stereo output mode
10245 inline Standard_Boolean parseStereoMode (Standard_CString theArg,
10246 Graphic3d_StereoMode& theMode)
10248 TCollection_AsciiString aFlag (theArg);
10250 if (aFlag == "quadbuffer")
10252 theMode = Graphic3d_StereoMode_QuadBuffer;
10254 else if (aFlag == "anaglyph")
10256 theMode = Graphic3d_StereoMode_Anaglyph;
10258 else if (aFlag == "row"
10259 || aFlag == "rowinterlaced")
10261 theMode = Graphic3d_StereoMode_RowInterlaced;
10263 else if (aFlag == "col"
10264 || aFlag == "colinterlaced"
10265 || aFlag == "columninterlaced")
10267 theMode = Graphic3d_StereoMode_ColumnInterlaced;
10269 else if (aFlag == "chess"
10270 || aFlag == "chessboard")
10272 theMode = Graphic3d_StereoMode_ChessBoard;
10274 else if (aFlag == "sbs"
10275 || aFlag == "sidebyside")
10277 theMode = Graphic3d_StereoMode_SideBySide;
10279 else if (aFlag == "ou"
10280 || aFlag == "overunder")
10282 theMode = Graphic3d_StereoMode_OverUnder;
10284 else if (aFlag == "pageflip"
10285 || aFlag == "softpageflip")
10287 theMode = Graphic3d_StereoMode_SoftPageFlip;
10291 return Standard_False;
10293 return Standard_True;
10296 //! Parse anaglyph filter
10297 inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
10298 Graphic3d_RenderingParams::Anaglyph& theFilter)
10300 TCollection_AsciiString aFlag (theArg);
10302 if (aFlag == "redcyansimple")
10304 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10306 else if (aFlag == "redcyan"
10307 || aFlag == "redcyanoptimized")
10309 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
10311 else if (aFlag == "yellowbluesimple")
10313 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
10315 else if (aFlag == "yellowblue"
10316 || aFlag == "yellowblueoptimized")
10318 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
10320 else if (aFlag == "greenmagenta"
10321 || aFlag == "greenmagentasimple")
10323 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
10327 return Standard_False;
10329 return Standard_True;
10332 //==============================================================================
10333 //function : VStereo
10335 //==============================================================================
10337 static int VStereo (Draw_Interpretor& theDI,
10338 Standard_Integer theArgNb,
10339 const char** theArgVec)
10341 Handle(V3d_View) aView = ViewerTest::CurrentView();
10344 if (aView.IsNull())
10346 Message::SendFail ("Error: no active viewer");
10350 Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
10351 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
10354 TCollection_AsciiString aMode;
10355 switch (aView->RenderingParams().StereoMode)
10357 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10358 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10359 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10360 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10361 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10362 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10363 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
10364 case Graphic3d_StereoMode_Anaglyph :
10365 aMode = "anaglyph";
10366 switch (aView->RenderingParams().AnaglyphFilter)
10368 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10369 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10370 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10371 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10372 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10377 theDI << "Mode " << aMode << "\n";
10382 Handle(Graphic3d_Camera) aCamera;
10383 Graphic3d_RenderingParams* aParams = NULL;
10384 Graphic3d_StereoMode aMode = Graphic3d_StereoMode_QuadBuffer;
10385 if (!aView.IsNull())
10387 aParams = &aView->ChangeRenderingParams();
10388 aMode = aParams->StereoMode;
10389 aCamera = aView->Camera();
10392 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10393 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10395 Standard_CString anArg = theArgVec[anArgIter];
10396 TCollection_AsciiString aFlag (anArg);
10398 if (anUpdateTool.parseRedrawMode (aFlag))
10402 else if (aFlag == "0"
10405 if (++anArgIter < theArgNb)
10407 Message::SendFail ("Error: wrong number of arguments");
10411 if (!aCamera.IsNull()
10412 && aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
10414 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10416 ViewerTest_myDefaultCaps.contextStereo = Standard_False;
10419 else if (aFlag == "1"
10422 if (++anArgIter < theArgNb)
10424 Message::SendFail ("Error: wrong number of arguments");
10428 if (!aCamera.IsNull())
10430 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10432 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10435 else if (aFlag == "-reverse"
10436 || aFlag == "-reversed"
10437 || aFlag == "-swap")
10439 Standard_Boolean toEnable = Standard_True;
10440 if (++anArgIter < theArgNb
10441 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
10445 aParams->ToReverseStereo = toEnable;
10447 else if (aFlag == "-noreverse"
10448 || aFlag == "-noswap")
10450 Standard_Boolean toDisable = Standard_True;
10451 if (++anArgIter < theArgNb
10452 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toDisable))
10456 aParams->ToReverseStereo = !toDisable;
10458 else if (aFlag == "-mode"
10459 || aFlag == "-stereomode")
10461 if (++anArgIter >= theArgNb
10462 || !parseStereoMode (theArgVec[anArgIter], aMode))
10464 Message::SendFail() << "Syntax error at '" << anArg << "'";
10468 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10470 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10473 else if (aFlag == "-anaglyph"
10474 || aFlag == "-anaglyphfilter")
10476 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10477 if (++anArgIter >= theArgNb
10478 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10480 Message::SendFail() << "Syntax error at '" << anArg << "'";
10484 aMode = Graphic3d_StereoMode_Anaglyph;
10485 aParams->AnaglyphFilter = aFilter;
10487 else if (parseStereoMode (anArg, aMode)) // short syntax
10489 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10491 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10496 Message::SendFail() << "Syntax error at '" << anArg << "'";
10501 if (!aView.IsNull())
10503 aParams->StereoMode = aMode;
10504 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10509 //===============================================================================================
10510 //function : VDefaults
10512 //===============================================================================================
10513 static int VDefaults (Draw_Interpretor& theDi,
10514 Standard_Integer theArgsNb,
10515 const char** theArgVec)
10517 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10520 Message::SendFail ("Error: no active viewer");
10524 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10527 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10529 theDi << "DeflType: relative\n"
10530 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10534 theDi << "DeflType: absolute\n"
10535 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10537 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
10538 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
10542 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10544 TCollection_AsciiString anArg (theArgVec[anArgIter]);
10546 if (anArg == "-ABSDEFL"
10547 || anArg == "-ABSOLUTEDEFLECTION"
10548 || anArg == "-DEFL"
10549 || anArg == "-DEFLECTION")
10551 if (++anArgIter >= theArgsNb)
10553 Message::SendFail() << "Syntax error at " << anArg;
10556 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
10557 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
10559 else if (anArg == "-RELDEFL"
10560 || anArg == "-RELATIVEDEFLECTION"
10561 || anArg == "-DEVCOEFF"
10562 || anArg == "-DEVIATIONCOEFF"
10563 || anArg == "-DEVIATIONCOEFFICIENT")
10565 if (++anArgIter >= theArgsNb)
10567 Message::SendFail() << "Syntax error at " << anArg;
10570 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
10571 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
10573 else if (anArg == "-ANGDEFL"
10574 || anArg == "-ANGULARDEFL"
10575 || anArg == "-ANGULARDEFLECTION")
10577 if (++anArgIter >= theArgsNb)
10579 Message::SendFail() << "Syntax error at " << anArg;
10582 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
10584 else if (anArg == "-AUTOTR"
10585 || anArg == "-AUTOTRIANG"
10586 || anArg == "-AUTOTRIANGULATION")
10589 bool toTurnOn = true;
10590 if (anArgIter >= theArgsNb
10591 || !ViewerTest::ParseOnOff (theArgVec[anArgIter], toTurnOn))
10593 Message::SendFail() << "Syntax error at '" << anArg << "'";
10596 aDefParams->SetAutoTriangulation (toTurnOn);
10600 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
10608 //! Auxiliary method
10609 inline void addLight (const Handle(V3d_Light)& theLightNew,
10610 const Graphic3d_ZLayerId theLayer,
10611 const Standard_Boolean theIsGlobal)
10613 if (theLightNew.IsNull())
10618 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10619 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
10621 aViewer->AddLight (theLightNew);
10624 aViewer->SetLightOn (theLightNew);
10628 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10633 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10634 if (aSettings.Lights().IsNull())
10636 aSettings.SetLights (new Graphic3d_LightSet());
10638 aSettings.Lights()->Add (theLightNew);
10639 aViewer->SetZLayerSettings (theLayer, aSettings);
10643 //! Auxiliary method
10644 inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10646 TCollection_AsciiString anArgNextCase (theArgNext);
10647 anArgNextCase.UpperCase();
10648 if (anArgNextCase.Length() > 5
10649 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10651 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10655 return theArgNext.IntegerValue();
10659 //===============================================================================================
10660 //function : VLight
10662 //===============================================================================================
10663 static int VLight (Draw_Interpretor& theDi,
10664 Standard_Integer theArgsNb,
10665 const char** theArgVec)
10667 Handle(V3d_View) aView = ViewerTest::CurrentView();
10668 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10670 || aViewer.IsNull())
10672 Message::SendFail ("Error: no active viewer");
10676 Standard_Real anXYZ[3] = {};
10677 Standard_Real anAtten[2] = {};
10680 // print lights info
10681 Standard_Integer aLightId = 0;
10682 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
10684 Handle(V3d_Light) aLight = aLightIter.Value();
10685 const Quantity_Color aColor = aLight->Color();
10686 theDi << "Light #" << aLightId
10687 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10688 << " [" << aLight->GetId() << "]" << "\n";
10689 switch (aLight->Type())
10693 theDi << " Type: Ambient\n";
10694 theDi << " Intensity: " << aLight->Intensity() << "\n";
10697 case V3d_DIRECTIONAL:
10699 theDi << " Type: Directional\n";
10700 theDi << " Intensity: " << aLight->Intensity() << "\n";
10701 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10702 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
10703 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10704 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10707 case V3d_POSITIONAL:
10709 theDi << " Type: Positional\n";
10710 theDi << " Intensity: " << aLight->Intensity() << "\n";
10711 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10712 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
10713 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10714 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10715 aLight->Attenuation (anAtten[0], anAtten[1]);
10716 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10717 theDi << " Range: " << aLight->Range() << "\n";
10722 theDi << " Type: Spot\n";
10723 theDi << " Intensity: " << aLight->Intensity() << "\n";
10724 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10725 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10726 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10727 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10728 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10729 aLight->Attenuation (anAtten[0], anAtten[1]);
10730 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10731 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10732 theDi << " Exponent: " << aLight->Concentration() << "\n";
10733 theDi << " Range: " << aLight->Range() << "\n";
10738 theDi << " Type: UNKNOWN\n";
10742 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
10746 Handle(V3d_Light) aLightNew;
10747 Handle(V3d_Light) aLightOld;
10748 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
10749 Standard_Boolean isGlobal = Standard_True;
10750 Standard_Boolean toCreate = Standard_False;
10751 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10752 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10754 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
10756 TCollection_AsciiString aName, aValue;
10757 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10758 TCollection_AsciiString anArgCase (anArg);
10759 anArgCase.UpperCase();
10760 if (anUpdateTool.parseRedrawMode (anArg))
10765 if (anArgCase.IsEqual ("NEW")
10766 || anArgCase.IsEqual ("ADD")
10767 || anArgCase.IsEqual ("CREATE")
10768 || anArgCase.IsEqual ("-NEW")
10769 || anArgCase.IsEqual ("-ADD")
10770 || anArgCase.IsEqual ("-CREATE"))
10772 toCreate = Standard_True;
10774 else if (anArgCase.IsEqual ("-LAYER")
10775 || anArgCase.IsEqual ("-ZLAYER"))
10777 if (++anArgIt >= theArgsNb)
10779 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10783 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10784 aValStr.LowerCase();
10785 if (aValStr == "default"
10786 || aValStr == "def")
10788 aLayer = Graphic3d_ZLayerId_Default;
10790 else if (aValStr == "top")
10792 aLayer = Graphic3d_ZLayerId_Top;
10794 else if (aValStr == "topmost")
10796 aLayer = Graphic3d_ZLayerId_Topmost;
10798 else if (aValStr == "toposd"
10799 || aValStr == "osd")
10801 aLayer = Graphic3d_ZLayerId_TopOSD;
10803 else if (aValStr == "botosd"
10804 || aValStr == "bottom")
10806 aLayer = Graphic3d_ZLayerId_BotOSD;
10808 else if (aValStr.IsIntegerValue())
10810 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10814 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10818 else if (anArgCase.IsEqual ("GLOB")
10819 || anArgCase.IsEqual ("GLOBAL")
10820 || anArgCase.IsEqual ("-GLOB")
10821 || anArgCase.IsEqual ("-GLOBAL"))
10823 isGlobal = Standard_True;
10825 else if (anArgCase.IsEqual ("LOC")
10826 || anArgCase.IsEqual ("LOCAL")
10827 || anArgCase.IsEqual ("-LOC")
10828 || anArgCase.IsEqual ("-LOCAL"))
10830 isGlobal = Standard_False;
10832 else if (anArgCase.IsEqual ("DEF")
10833 || anArgCase.IsEqual ("DEFAULTS")
10834 || anArgCase.IsEqual ("-DEF")
10835 || anArgCase.IsEqual ("-DEFAULTS"))
10837 toCreate = Standard_False;
10838 aViewer->SetDefaultLights();
10840 else if (anArgCase.IsEqual ("CLR")
10841 || anArgCase.IsEqual ("CLEAR")
10842 || anArgCase.IsEqual ("-CLR")
10843 || anArgCase.IsEqual ("-CLEAR"))
10845 toCreate = Standard_False;
10847 TColStd_SequenceOfInteger aLayers;
10848 aViewer->GetAllZLayers (aLayers);
10849 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10851 if (aLayeriter.Value() == aLayer
10852 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10854 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10855 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10856 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10857 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10864 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10866 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10868 Handle(V3d_Light) aLight = aLightIter.Value();
10869 aViewer->DelLight (aLight);
10870 aLightIter = aView->ActiveLightIterator();
10874 else if (anArgCase.IsEqual ("AMB")
10875 || anArgCase.IsEqual ("AMBIENT")
10876 || anArgCase.IsEqual ("AMBLIGHT"))
10880 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10884 addLight (aLightNew, aLayer, isGlobal);
10885 toCreate = Standard_False;
10886 aLightNew = new V3d_AmbientLight();
10888 else if (anArgCase.IsEqual ("DIRECTIONAL")
10889 || anArgCase.IsEqual ("DIRLIGHT"))
10893 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10897 addLight (aLightNew, aLayer, isGlobal);
10898 toCreate = Standard_False;
10899 aLightNew = new V3d_DirectionalLight();
10901 else if (anArgCase.IsEqual ("SPOT")
10902 || anArgCase.IsEqual ("SPOTLIGHT"))
10906 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10910 addLight (aLightNew, aLayer, isGlobal);
10911 toCreate = Standard_False;
10912 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
10914 else if (anArgCase.IsEqual ("POSLIGHT")
10915 || anArgCase.IsEqual ("POSITIONAL"))
10919 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10923 addLight (aLightNew, aLayer, isGlobal);
10924 toCreate = Standard_False;
10925 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
10927 else if (anArgCase.IsEqual ("CHANGE")
10928 || anArgCase.IsEqual ("-CHANGE"))
10930 if (++anArgIt >= theArgsNb)
10932 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10936 addLight (aLightNew, aLayer, isGlobal);
10937 aLightNew.Nullify();
10938 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
10939 Standard_Integer aLightIt = 0;
10940 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
10942 if (aLightIt == aLightId)
10944 aLightOld = aLightIter.Value();
10949 if (aLightOld.IsNull())
10951 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
10955 else if (anArgCase.IsEqual ("DEL")
10956 || anArgCase.IsEqual ("DELETE")
10957 || anArgCase.IsEqual ("-DEL")
10958 || anArgCase.IsEqual ("-DELETE"))
10960 Handle(V3d_Light) aLightDel;
10961 if (++anArgIt >= theArgsNb)
10963 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10967 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
10968 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
10969 Standard_Integer aLightIt = 0;
10970 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
10972 aLightDel = aLightIter.Value();
10973 if (aLightIt == aLightDelId)
10978 if (aLightDel.IsNull())
10983 TColStd_SequenceOfInteger aLayers;
10984 aViewer->GetAllZLayers (aLayers);
10985 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10987 if (aLayeriter.Value() == aLayer
10988 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10990 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10991 if (!aSettings.Lights().IsNull())
10993 aSettings.Lights()->Remove (aLightDel);
10994 if (aSettings.Lights()->IsEmpty())
10996 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10999 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
11000 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
11007 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
11009 aViewer->DelLight (aLightDel);
11012 else if (anArgCase.IsEqual ("COLOR")
11013 || anArgCase.IsEqual ("COLOUR")
11014 || anArgCase.IsEqual ("-COLOR")
11015 || anArgCase.IsEqual ("-COLOUR"))
11017 if (++anArgIt >= theArgsNb
11018 || aLightCurr.IsNull())
11020 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11024 TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
11025 anArgNext.UpperCase();
11026 const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
11027 aLightCurr->SetColor (aColor);
11029 else if (anArgCase.IsEqual ("POS")
11030 || anArgCase.IsEqual ("POSITION")
11031 || anArgCase.IsEqual ("-POS")
11032 || anArgCase.IsEqual ("-POSITION"))
11034 if ((anArgIt + 3) >= theArgsNb
11035 || aLightCurr.IsNull()
11036 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11037 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
11039 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11043 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11044 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11045 anXYZ[2] = Atof (theArgVec[++anArgIt]);
11046 aLightCurr->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
11048 else if (anArgCase.IsEqual ("DIR")
11049 || anArgCase.IsEqual ("DIRECTION")
11050 || anArgCase.IsEqual ("-DIR")
11051 || anArgCase.IsEqual ("-DIRECTION"))
11053 if ((anArgIt + 3) >= theArgsNb
11054 || aLightCurr.IsNull()
11055 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
11056 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
11058 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11062 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11063 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11064 anXYZ[2] = Atof (theArgVec[++anArgIt]);
11065 aLightCurr->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
11067 else if (anArgCase.IsEqual ("SM")
11068 || anArgCase.IsEqual ("SMOOTHNESS")
11069 || anArgCase.IsEqual ("-SM")
11070 || anArgCase.IsEqual ("-SMOOTHNESS"))
11072 if (++anArgIt >= theArgsNb
11073 || aLightCurr.IsNull())
11075 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11079 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11080 if (Abs (aSmoothness) <= ShortRealEpsilon())
11082 aLightCurr->SetIntensity (1.f);
11084 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
11086 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
11090 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
11091 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
11094 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
11096 aLightCurr->SetSmoothRadius (aSmoothness);
11098 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
11100 aLightCurr->SetSmoothAngle (aSmoothness);
11103 else if (anArgCase.IsEqual ("INT")
11104 || anArgCase.IsEqual ("INTENSITY")
11105 || anArgCase.IsEqual ("-INT")
11106 || anArgCase.IsEqual ("-INTENSITY"))
11108 if (++anArgIt >= theArgsNb
11109 || aLightCurr.IsNull())
11111 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11115 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11116 aLightCurr->SetIntensity (aIntensity);
11118 else if (anArgCase.IsEqual ("ANG")
11119 || anArgCase.IsEqual ("ANGLE")
11120 || anArgCase.IsEqual ("-ANG")
11121 || anArgCase.IsEqual ("-ANGLE"))
11123 if (++anArgIt >= theArgsNb
11124 || aLightCurr.IsNull()
11125 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
11127 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11131 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11132 aLightCurr->SetAngle (Standard_ShortReal (anAngle / 180.0 * M_PI));
11134 else if (anArgCase.IsEqual ("CONSTATTEN")
11135 || anArgCase.IsEqual ("CONSTATTENUATION")
11136 || anArgCase.IsEqual ("-CONSTATTEN")
11137 || anArgCase.IsEqual ("-CONSTATTENUATION"))
11139 if (++anArgIt >= theArgsNb
11140 || aLightCurr.IsNull()
11141 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11142 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
11144 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11148 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11149 anAtten[0] = Atof (theArgVec[anArgIt]);
11150 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
11152 else if (anArgCase.IsEqual ("LINATTEN")
11153 || anArgCase.IsEqual ("LINEARATTEN")
11154 || anArgCase.IsEqual ("LINEARATTENUATION")
11155 || anArgCase.IsEqual ("-LINATTEN")
11156 || anArgCase.IsEqual ("-LINEARATTEN")
11157 || anArgCase.IsEqual ("-LINEARATTENUATION"))
11159 if (++anArgIt >= theArgsNb
11160 || aLightCurr.IsNull()
11161 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11162 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
11164 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11168 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11169 anAtten[1] = Atof (theArgVec[anArgIt]);
11170 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
11172 else if (anArgCase.IsEqual ("EXP")
11173 || anArgCase.IsEqual ("EXPONENT")
11174 || anArgCase.IsEqual ("SPOTEXP")
11175 || anArgCase.IsEqual ("SPOTEXPONENT")
11176 || anArgCase.IsEqual ("-EXP")
11177 || anArgCase.IsEqual ("-EXPONENT")
11178 || anArgCase.IsEqual ("-SPOTEXP")
11179 || anArgCase.IsEqual ("-SPOTEXPONENT"))
11181 if (++anArgIt >= theArgsNb
11182 || aLightCurr.IsNull()
11183 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
11185 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11189 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
11191 else if (anArgCase.IsEqual("RANGE")
11192 || anArgCase.IsEqual("-RANGE"))
11194 if (++anArgIt >= theArgsNb
11195 || aLightCurr.IsNull()
11196 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
11197 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
11199 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11203 aLightCurr->SetRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
11205 else if (anArgCase.IsEqual ("HEAD")
11206 || anArgCase.IsEqual ("HEADLIGHT")
11207 || anArgCase.IsEqual ("-HEAD")
11208 || anArgCase.IsEqual ("-HEADLIGHT"))
11210 if (aLightCurr.IsNull()
11211 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
11213 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11217 Standard_Boolean isHeadLight = Standard_True;
11218 if (anArgIt + 1 < theArgsNb
11219 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
11223 aLightCurr->SetHeadlight (isHeadLight);
11227 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
11231 addLight (aLightNew, aLayer, isGlobal);
11235 //===============================================================================================
11236 //function : VPBREnvironment
11238 //===============================================================================================
11239 static int VPBREnvironment (Draw_Interpretor&,
11240 Standard_Integer theArgsNb,
11241 const char** theArgVec)
11245 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
11249 Handle(V3d_View) aView = ViewerTest::CurrentView();
11250 if (aView.IsNull())
11252 Message::SendFail ("Error: no active viewer");
11256 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11259 if (anArg == "-generate"
11260 || anArg == "-gen")
11262 aView->GeneratePBREnvironment (Standard_True);
11264 else if (anArg == "-clear")
11266 aView->ClearPBREnvironment (Standard_True);
11270 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
11277 //! Read Graphic3d_RenderingParams::PerfCounters flag.
11278 static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11279 Standard_Boolean& theToReset,
11280 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11281 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11283 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11284 TCollection_AsciiString aVal = theValue;
11285 Standard_Boolean toReverse = Standard_False;
11286 if (aVal == "none")
11288 theToReset = Standard_True;
11289 return Standard_True;
11291 else if (aVal.StartsWith ("-"))
11293 toReverse = Standard_True;
11294 aVal = aVal.SubString (2, aVal.Length());
11296 else if (aVal.StartsWith ("no"))
11298 toReverse = Standard_True;
11299 aVal = aVal.SubString (3, aVal.Length());
11301 else if (aVal.StartsWith ("+"))
11303 aVal = aVal.SubString (2, aVal.Length());
11307 theToReset = Standard_True;
11311 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11312 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11313 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11314 else if (aVal == "structs"
11315 || aVal == "structures"
11316 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11317 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11318 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11319 else if (aVal == "tris"
11320 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11321 else if (aVal == "pnts"
11322 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
11323 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
11324 else if (aVal == "mem"
11325 || aVal == "gpumem"
11326 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
11327 else if (aVal == "skipimmediate"
11328 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11329 else if (aVal == "frametime"
11330 || aVal == "frametimers"
11331 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
11332 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11333 else if (aVal == "extended"
11334 || aVal == "verbose"
11335 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
11336 else if (aVal == "full"
11337 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
11340 return Standard_False;
11345 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11349 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11351 return Standard_True;
11354 //! Read Graphic3d_RenderingParams::PerfCounters flags.
11355 static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11356 Graphic3d_RenderingParams::PerfCounters& theFlags)
11358 TCollection_AsciiString aValue = theValue;
11359 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11360 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11361 Standard_Boolean toReset = Standard_False;
11364 Standard_Integer aSplitPos = aValue.Search ("|");
11365 if (aSplitPos <= 0)
11367 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11369 return Standard_False;
11373 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11375 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11376 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11377 return Standard_True;
11382 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11383 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11385 return Standard_False;
11388 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11392 //=======================================================================
11393 //function : VRenderParams
11394 //purpose : Enables/disables rendering features
11395 //=======================================================================
11397 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11398 Standard_Integer theArgNb,
11399 const char** theArgVec)
11401 Handle(V3d_View) aView = ViewerTest::CurrentView();
11402 if (aView.IsNull())
11404 Message::SendFail ("Error: no active viewer");
11408 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
11409 TCollection_AsciiString aCmdName (theArgVec[0]);
11410 aCmdName.LowerCase();
11411 if (aCmdName == "vraytrace")
11415 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11418 else if (theArgNb == 2)
11420 TCollection_AsciiString aValue (theArgVec[1]);
11421 aValue.LowerCase();
11425 aParams.Method = Graphic3d_RM_RAYTRACING;
11429 else if (aValue == "off"
11432 aParams.Method = Graphic3d_RM_RASTERIZATION;
11438 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
11444 Message::SendFail ("Syntax error: wrong number of arguments");
11451 theDI << "renderMode: ";
11452 switch (aParams.Method)
11454 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11455 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11458 theDI << "transparency: ";
11459 switch (aParams.TransparencyMethod)
11461 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11462 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11463 << TCollection_AsciiString (aParams.OitDepthFactor); break;
11466 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
11467 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
11468 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11469 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11470 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
11471 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11472 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11473 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11474 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11475 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11476 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11477 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
11478 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
11479 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
11480 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
11481 theDI << "shadingModel: ";
11482 switch (aView->ShadingModel())
11484 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11485 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11486 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11487 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11488 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11489 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11490 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
11493 theDI << "perfCounters:";
11494 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11498 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11502 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11504 theDI << " structs";
11506 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11508 theDI << " groups";
11510 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11512 theDI << " arrays";
11514 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11518 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11522 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11526 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11528 theDI << " gpumem";
11530 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11532 theDI << " frameTime";
11534 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11536 theDI << " skipimmediate";
11538 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11544 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
11545 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
11546 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11547 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11548 "noUpdate") << "\n";
11553 Standard_Boolean toPrint = Standard_False;
11554 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
11555 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11557 Standard_CString anArg (theArgVec[anArgIter]);
11558 TCollection_AsciiString aFlag (anArg);
11560 if (anUpdateTool.parseRedrawMode (aFlag))
11564 else if (aFlag == "-echo"
11565 || aFlag == "-print")
11567 toPrint = Standard_True;
11568 anUpdateTool.Invalidate();
11570 else if (aFlag == "-mode"
11571 || aFlag == "-rendermode"
11572 || aFlag == "-render_mode")
11576 switch (aParams.Method)
11578 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11579 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11585 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11589 else if (aFlag == "-ray"
11590 || aFlag == "-raytrace")
11594 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11598 aParams.Method = Graphic3d_RM_RAYTRACING;
11600 else if (aFlag == "-rast"
11601 || aFlag == "-raster"
11602 || aFlag == "-rasterization")
11606 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11610 aParams.Method = Graphic3d_RM_RASTERIZATION;
11612 else if (aFlag == "-msaa")
11616 theDI << aParams.NbMsaaSamples << " ";
11619 else if (++anArgIter >= theArgNb)
11621 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11625 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11626 if (aNbSamples < 0)
11628 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
11633 aParams.NbMsaaSamples = aNbSamples;
11636 else if (aFlag == "-linefeather"
11637 || aFlag == "-edgefeather"
11638 || aFlag == "-feather")
11642 theDI << " " << aParams.LineFeather << " ";
11645 else if (++anArgIter >= theArgNb)
11647 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11651 TCollection_AsciiString aParam = theArgVec[anArgIter];
11652 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11653 if (aFeather <= 0.0f)
11655 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
11658 aParams.LineFeather = aFeather;
11660 else if (aFlag == "-oit")
11664 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11666 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11670 theDI << "off" << " ";
11674 else if (++anArgIter >= theArgNb)
11676 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11680 TCollection_AsciiString aParam = theArgVec[anArgIter];
11681 aParam.LowerCase();
11682 if (aParam.IsRealValue())
11684 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11685 if (aWeight < 0.f || aWeight > 1.f)
11687 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11691 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11692 aParams.OitDepthFactor = aWeight;
11694 else if (aParam == "off")
11696 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11700 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11704 else if (aFlag == "-depthprepass")
11708 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11711 aParams.ToEnableDepthPrepass = Standard_True;
11712 if (anArgIter + 1 < theArgNb
11713 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
11718 else if (aFlag == "-samplealphatocoverage"
11719 || aFlag == "-alphatocoverage")
11723 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11726 aParams.ToEnableAlphaToCoverage = Standard_True;
11727 if (anArgIter + 1 < theArgNb
11728 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
11733 else if (aFlag == "-rendscale"
11734 || aFlag == "-renderscale"
11735 || aFlag == "-renderresolutionscale")
11739 theDI << aParams.RenderResolutionScale << " ";
11742 else if (++anArgIter >= theArgNb)
11744 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11748 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11751 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
11756 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11759 else if (aFlag == "-raydepth"
11760 || aFlag == "-ray_depth")
11764 theDI << aParams.RaytracingDepth << " ";
11767 else if (++anArgIter >= theArgNb)
11769 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11773 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
11775 // We allow RaytracingDepth be more than 10 in case of GI enabled
11776 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
11778 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
11783 aParams.RaytracingDepth = aDepth;
11786 else if (aFlag == "-shad"
11787 || aFlag == "-shadows")
11791 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11795 Standard_Boolean toEnable = Standard_True;
11796 if (++anArgIter < theArgNb
11797 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11801 aParams.IsShadowEnabled = toEnable;
11803 else if (aFlag == "-refl"
11804 || aFlag == "-reflections")
11808 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11812 Standard_Boolean toEnable = Standard_True;
11813 if (++anArgIter < theArgNb
11814 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11818 aParams.IsReflectionEnabled = toEnable;
11820 else if (aFlag == "-fsaa")
11824 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11828 Standard_Boolean toEnable = Standard_True;
11829 if (++anArgIter < theArgNb
11830 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11834 aParams.IsAntialiasingEnabled = toEnable;
11836 else if (aFlag == "-gleam")
11840 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11844 Standard_Boolean toEnable = Standard_True;
11845 if (++anArgIter < theArgNb
11846 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11850 aParams.IsTransparentShadowEnabled = toEnable;
11852 else if (aFlag == "-gi")
11856 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11860 Standard_Boolean toEnable = Standard_True;
11861 if (++anArgIter < theArgNb
11862 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11866 aParams.IsGlobalIlluminationEnabled = toEnable;
11869 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11872 else if (aFlag == "-blockedrng"
11873 || aFlag == "-brng")
11877 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11881 Standard_Boolean toEnable = Standard_True;
11882 if (++anArgIter < theArgNb
11883 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11887 aParams.CoherentPathTracingMode = toEnable;
11889 else if (aFlag == "-maxrad")
11893 theDI << aParams.RadianceClampingValue << " ";
11896 else if (++anArgIter >= theArgNb)
11898 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11902 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11903 if (!aMaxRadStr.IsRealValue())
11905 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11909 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11910 if (aMaxRadiance <= 0.0)
11912 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
11917 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11920 else if (aFlag == "-iss")
11924 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11928 Standard_Boolean toEnable = Standard_True;
11929 if (++anArgIter < theArgNb
11930 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11934 aParams.AdaptiveScreenSampling = toEnable;
11936 else if (aFlag == "-issatomic")
11940 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
11944 Standard_Boolean toEnable = Standard_True;
11945 if (++anArgIter < theArgNb
11946 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11950 aParams.AdaptiveScreenSamplingAtomic = toEnable;
11952 else if (aFlag == "-issd")
11956 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
11960 Standard_Boolean toEnable = Standard_True;
11961 if (++anArgIter < theArgNb
11962 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
11966 aParams.ShowSamplingTiles = toEnable;
11968 else if (aFlag == "-tilesize")
11972 theDI << aParams.RayTracingTileSize << " ";
11975 else if (++anArgIter >= theArgNb)
11977 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11981 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
11984 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
11987 aParams.RayTracingTileSize = aTileSize;
11989 else if (aFlag == "-nbtiles")
11993 theDI << aParams.NbRayTracingTiles << " ";
11996 else if (++anArgIter >= theArgNb)
11998 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12002 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
12005 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
12008 else if (aNbTiles > 0
12010 || aNbTiles > 1024))
12012 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
12014 aParams.NbRayTracingTiles = aNbTiles;
12016 else if (aFlag == "-env")
12020 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12024 Standard_Boolean toEnable = Standard_True;
12025 if (++anArgIter < theArgNb
12026 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12030 aParams.UseEnvironmentMapBackground = toEnable;
12032 else if (aFlag == "-ignorenormalmap")
12036 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12040 Standard_Boolean toEnable = Standard_True;
12041 if (++anArgIter < theArgNb
12042 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12046 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12048 else if (aFlag == "-twoside")
12052 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12056 Standard_Boolean toEnable = Standard_True;
12057 if (++anArgIter < theArgNb
12058 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12062 aParams.TwoSidedBsdfModels = toEnable;
12064 else if (aFlag == "-shademodel"
12065 || aFlag == "-shadingmodel"
12066 || aFlag == "-shading")
12070 switch (aView->ShadingModel())
12072 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12073 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12074 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12075 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12076 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12077 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12078 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
12083 if (++anArgIter >= theArgNb)
12085 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12088 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12089 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12090 && aModel != Graphic3d_TOSM_DEFAULT)
12092 aView->SetShadingModel (aModel);
12096 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
12100 else if (aFlag == "-pbrenvpow2size"
12101 || aFlag == "-pbrenvp2s"
12102 || aFlag == "-pep2s")
12104 if (++anArgIter >= theArgNb)
12106 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12110 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12111 if (aPbrEnvPow2Size < 1)
12113 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
12116 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12118 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12119 || aFlag == "-pbrenvspecmapnblevels"
12120 || aFlag == "-pbrenvspecmaplevels"
12121 || aFlag == "-pbrenvsmln"
12122 || aFlag == "-pesmln")
12124 if (++anArgIter >= theArgNb)
12126 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12130 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12131 if (aPbrEnvSpecMapNbLevels < 2)
12133 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
12136 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12138 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12139 || aFlag == "-pbrenvbakingdiffsamples"
12140 || aFlag == "-pbrenvbdsn")
12142 if (++anArgIter >= theArgNb)
12144 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12148 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12149 if (aPbrEnvBakingDiffNbSamples < 1)
12151 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environtment has to be greater or equal 1");
12154 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12156 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12157 || aFlag == "-pbrenvbakingspecsamples"
12158 || aFlag == "-pbrenvbssn")
12160 if (++anArgIter >= theArgNb)
12162 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12166 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12167 if (aPbrEnvBakingSpecNbSamples < 1)
12169 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environtment has to be greater or equal 1");
12172 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12174 else if (aFlag == "-pbrenvbakingprobability"
12175 || aFlag == "-pbrenvbp")
12177 if (++anArgIter >= theArgNb)
12179 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12182 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12183 if (aPbrEnvBakingProbability < 0.f
12184 || aPbrEnvBakingProbability > 1.f)
12186 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environtment has to be in range of [0, 1]");
12189 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12191 else if (aFlag == "-resolution")
12193 if (++anArgIter >= theArgNb)
12195 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12199 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12200 if (aResolution.IsIntegerValue())
12202 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12206 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
12210 else if (aFlag == "-rebuildglsl"
12211 || aFlag == "-rebuild")
12215 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12219 Standard_Boolean toEnable = Standard_True;
12220 if (++anArgIter < theArgNb
12221 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12225 aParams.RebuildRayTracingShaders = toEnable;
12227 else if (aFlag == "-focal")
12229 if (++anArgIter >= theArgNb)
12231 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12235 TCollection_AsciiString aParam (theArgVec[anArgIter]);
12236 if (aParam.IsRealValue())
12238 float aFocalDist = static_cast<float> (aParam.RealValue());
12239 if (aFocalDist < 0)
12241 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
12244 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12248 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12252 else if (aFlag == "-aperture")
12254 if (++anArgIter >= theArgNb)
12256 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12260 TCollection_AsciiString aParam(theArgVec[anArgIter]);
12261 if (aParam.IsRealValue())
12263 float aApertureSize = static_cast<float> (aParam.RealValue());
12264 if (aApertureSize < 0)
12266 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
12269 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12273 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12277 else if (aFlag == "-exposure")
12279 if (++anArgIter >= theArgNb)
12281 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12285 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
12286 if (anExposure.IsRealValue())
12288 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12292 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12296 else if (aFlag == "-whitepoint")
12298 if (++anArgIter >= theArgNb)
12300 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12304 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
12305 if (aWhitePoint.IsRealValue())
12307 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12311 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12315 else if (aFlag == "-tonemapping")
12317 if (++anArgIter >= theArgNb)
12319 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12323 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12326 if (aMode == "disabled")
12328 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12330 else if (aMode == "filmic")
12332 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12336 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12340 else if (aFlag == "-performancestats"
12341 || aFlag == "-performancecounters"
12342 || aFlag == "-perfstats"
12343 || aFlag == "-perfcounters"
12344 || aFlag == "-stats")
12346 if (++anArgIter >= theArgNb)
12348 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12352 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12353 aFlagsStr.LowerCase();
12354 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12355 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12357 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12360 aView->ChangeRenderingParams().CollectedStats = aFlags;
12361 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12363 else if (aFlag == "-perfupdateinterval"
12364 || aFlag == "-statsupdateinterval")
12366 if (++anArgIter >= theArgNb)
12368 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12371 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12373 else if (aFlag == "-perfchart"
12374 || aFlag == "-statschart")
12376 if (++anArgIter >= theArgNb)
12378 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12383 else if (aFlag == "-perfchartmax"
12384 || aFlag == "-statschartmax")
12386 if (++anArgIter >= theArgNb)
12388 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12391 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12393 else if (aFlag == "-frustumculling"
12394 || aFlag == "-culling")
12398 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12399 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12400 "noUpdate") << " ";
12404 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12405 if (++anArgIter < theArgNb)
12407 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12408 aStateStr.LowerCase();
12409 bool toEnable = true;
12410 if (ViewerTest::ParseOnOff (aStateStr.ToCString(), toEnable))
12412 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12414 else if (aStateStr == "noupdate"
12415 || aStateStr == "freeze")
12417 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12424 aParams.FrustumCullingState = aState;
12428 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
12436 //=======================================================================
12437 //function : searchInfo
12439 //=======================================================================
12440 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12441 const TCollection_AsciiString& theKey)
12443 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12445 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12447 return anIter.Value();
12450 return TCollection_AsciiString();
12453 //=======================================================================
12454 //function : VStatProfiler
12456 //=======================================================================
12457 static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12458 Standard_Integer theArgNb,
12459 const char** theArgVec)
12461 Handle(V3d_View) aView = ViewerTest::CurrentView();
12462 if (aView.IsNull())
12464 Message::SendFail ("Error: no active viewer");
12468 Standard_Boolean toRedraw = Standard_True;
12469 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12470 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12471 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12472 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12474 Standard_CString anArg (theArgVec[anArgIter]);
12475 TCollection_AsciiString aFlag (anArg);
12477 if (aFlag == "-noredraw")
12479 toRedraw = Standard_False;
12483 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12484 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12485 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12486 else if (aFlag == "alllayers"
12487 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12488 else if (aFlag == "allstructs"
12489 || aFlag == "allstructures"
12490 || aFlag == "structs"
12491 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
12492 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12493 else if (aFlag == "allarrays"
12494 || aFlag == "fillarrays"
12495 || aFlag == "linearrays"
12496 || aFlag == "pointarrays"
12497 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12498 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
12499 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
12500 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12501 else if (aFlag == "geommem"
12502 || aFlag == "texturemem"
12503 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12504 else if (aFlag == "elapsedframe"
12505 || aFlag == "cpuframeaverage"
12506 || aFlag == "cpupickingaverage"
12507 || aFlag == "cpucullingaverage"
12508 || aFlag == "cpudynaverage"
12509 || aFlag == "cpuframemax"
12510 || aFlag == "cpupickingmax"
12511 || aFlag == "cpucullingmax"
12512 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12515 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
12519 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12523 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12525 aView->ChangeRenderingParams().CollectedStats =
12526 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12530 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12532 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12535 TColStd_IndexedDataMapOfStringString aDict;
12536 aView->StatisticInformation (aDict);
12538 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12540 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12542 Standard_CString anArg(theArgVec[anArgIter]);
12543 TCollection_AsciiString aFlag(anArg);
12545 if (aFlag == "fps")
12547 theDI << searchInfo (aDict, "FPS") << " ";
12549 else if (aFlag == "cpu")
12551 theDI << searchInfo (aDict, "CPU FPS") << " ";
12553 else if (aFlag == "alllayers")
12555 theDI << searchInfo (aDict, "Layers") << " ";
12557 else if (aFlag == "layers")
12559 theDI << searchInfo (aDict, "Rendered layers") << " ";
12561 else if (aFlag == "allstructs"
12562 || aFlag == "allstructures")
12564 theDI << searchInfo (aDict, "Structs") << " ";
12566 else if (aFlag == "structs"
12567 || aFlag == "structures")
12569 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12570 if (aRend.IsEmpty()) // all structures rendered
12572 aRend = searchInfo (aDict, "Structs");
12574 theDI << aRend << " ";
12576 else if (aFlag == "groups")
12578 theDI << searchInfo (aDict, "Rendered groups") << " ";
12580 else if (aFlag == "allarrays")
12582 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12584 else if (aFlag == "fillarrays")
12586 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12588 else if (aFlag == "linearrays")
12590 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12592 else if (aFlag == "pointarrays")
12594 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12596 else if (aFlag == "textarrays")
12598 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12600 else if (aFlag == "triangles")
12602 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12604 else if (aFlag == "points")
12606 theDI << searchInfo (aDict, "Rendered points") << " ";
12608 else if (aFlag == "geommem")
12610 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12612 else if (aFlag == "texturemem")
12614 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12616 else if (aFlag == "framemem")
12618 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12620 else if (aFlag == "elapsedframe")
12622 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12624 else if (aFlag == "cpuframe_average")
12626 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12628 else if (aFlag == "cpupicking_average")
12630 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12632 else if (aFlag == "cpuculling_average")
12634 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12636 else if (aFlag == "cpudyn_average")
12638 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12640 else if (aFlag == "cpuframe_max")
12642 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12644 else if (aFlag == "cpupicking_max")
12646 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12648 else if (aFlag == "cpuculling_max")
12650 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12652 else if (aFlag == "cpudyn_max")
12654 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12662 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12664 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12666 theDI << "Statistic info:\n" << aView->StatisticInformation();
12671 //=======================================================================
12672 //function : VXRotate
12674 //=======================================================================
12675 static Standard_Integer VXRotate (Draw_Interpretor& di,
12676 Standard_Integer argc,
12677 const char ** argv)
12679 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12680 if (aContext.IsNull())
12682 di << argv[0] << "ERROR : use 'vinit' command before \n";
12688 di << "ERROR : Usage : " << argv[0] << " name angle\n";
12692 TCollection_AsciiString aName (argv[1]);
12693 Standard_Real anAngle = Draw::Atof (argv[2]);
12696 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12697 Handle(AIS_InteractiveObject) anIObj;
12698 if (!aMap.Find2 (aName, anIObj))
12700 di << "Use 'vdisplay' before\n";
12704 gp_Trsf aTransform;
12705 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12706 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
12708 aContext->SetLocation (anIObj, aTransform);
12709 aContext->UpdateCurrentViewer();
12713 //===============================================================================================
12714 //function : VManipulator
12716 //===============================================================================================
12717 static int VManipulator (Draw_Interpretor& theDi,
12718 Standard_Integer theArgsNb,
12719 const char** theArgVec)
12721 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
12722 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12723 ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False);
12724 if (aCurrentView.IsNull()
12725 || aViewer.IsNull())
12727 Message::SendFail ("Error: no active viewer");
12731 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12732 Standard_Integer anArgIter = 1;
12733 for (; anArgIter < theArgsNb; ++anArgIter)
12735 anUpdateTool.parseRedrawMode (theArgVec[anArgIter]);
12738 ViewerTest_CmdParser aCmd;
12739 aCmd.SetDescription ("Manages manipulator for interactive objects:");
12740 aCmd.AddOption ("attach", "... object - attach manipulator to an object");
12741 aCmd.AddOption ("adjustPosition", "... {0|1} - adjust position when attaching");
12742 aCmd.AddOption ("adjustSize", "... {0|1} - adjust size when attaching ");
12743 aCmd.AddOption ("enableModes", "... {0|1} - enable modes when attaching ");
12744 aCmd.AddOption ("view", "... {active | [view name]} - define view in which manipulator will be displayed, 'all' by default");
12745 aCmd.AddOption ("detach", "... - detach manipulator");
12747 aCmd.AddOption ("startTransform", "... mouse_x mouse_y - invoke start transformation");
12748 aCmd.AddOption ("transform", "... mouse_x mouse_y - invoke transformation");
12749 aCmd.AddOption ("stopTransform", "... [abort] - invoke stop transformation");
12751 aCmd.AddOption ("move", "... x y z - move object");
12752 aCmd.AddOption ("rotate", "... x y z dx dy dz angle - rotate object");
12753 aCmd.AddOption ("scale", "... factor - scale object");
12755 aCmd.AddOption ("autoActivate", "... {0|1} - set activation on detection");
12756 aCmd.AddOption ("followTranslation", "... {0|1} - set following translation transform");
12757 aCmd.AddOption ("followRotation", "... {0|1} - set following rotation transform");
12758 aCmd.AddOption ("followDragging", "... {0|1} - set following dragging transform");
12759 aCmd.AddOption ("gap", "... value - set gap between sub-parts");
12760 aCmd.AddOption ("part", "... axis mode {0|1} - set visual part");
12761 aCmd.AddOption ("parts", "... all axes mode {0|1} - set visual part");
12762 aCmd.AddOption ("pos", "... x y z [nx ny nz [xx xy xz]] - set position of manipulator");
12763 aCmd.AddOption ("size", "... size - set size of manipulator");
12764 aCmd.AddOption ("zoomable", "... {0|1} - set zoom persistence");
12766 aCmd.Parse (theArgsNb, theArgVec);
12768 if (aCmd.HasOption ("help"))
12770 theDi.PrintHelp (theArgVec[0]);
12774 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12776 TCollection_AsciiString aName (aCmd.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0).c_str());
12778 if (aName.IsEmpty())
12780 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
12784 // ----------------------------------
12785 // detach existing manipulator object
12786 // ----------------------------------
12788 if (aCmd.HasOption ("detach"))
12790 if (!aMapAIS.IsBound2 (aName))
12792 Message::SendFail() << "Syntax error: could not find \"" << aName << "\" AIS object";
12796 Handle(AIS_Manipulator) aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12797 if (aManipulator.IsNull())
12799 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
12803 aManipulator->Detach();
12804 aMapAIS.UnBind2 (aName);
12805 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_True);
12810 // -----------------------------------------------
12811 // find or create manipulator if it does not exist
12812 // -----------------------------------------------
12814 Handle(AIS_Manipulator) aManipulator;
12815 if (!aMapAIS.IsBound2 (aName))
12817 std::cout << theArgVec[0] << ": AIS object \"" << aName << "\" has been created.\n";
12819 aManipulator = new AIS_Manipulator();
12820 aManipulator->SetModeActivationOnDetection (true);
12821 aMapAIS.Bind (aManipulator, aName);
12825 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12826 if (aManipulator.IsNull())
12828 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
12833 // -----------------------------------------
12834 // change properties of manipulator instance
12835 // -----------------------------------------
12837 if (aCmd.HasOption ("autoActivate", 1, Standard_True))
12839 aManipulator->SetModeActivationOnDetection (aCmd.ArgBool ("autoActivate"));
12841 if (aCmd.HasOption ("followTranslation", 1, Standard_True))
12843 aManipulator->ChangeTransformBehavior().SetFollowTranslation (aCmd.ArgBool ("followTranslation"));
12845 if (aCmd.HasOption ("followRotation", 1, Standard_True))
12847 aManipulator->ChangeTransformBehavior().SetFollowRotation (aCmd.ArgBool ("followRotation"));
12849 if (aCmd.HasOption("followDragging", 1, Standard_True))
12851 aManipulator->ChangeTransformBehavior().SetFollowDragging(aCmd.ArgBool("followDragging"));
12853 if (aCmd.HasOption ("gap", 1, Standard_True))
12855 aManipulator->SetGap (aCmd.ArgFloat ("gap"));
12857 if (aCmd.HasOption ("part", 3, Standard_True))
12859 Standard_Integer anAxis = aCmd.ArgInt ("part", 0);
12860 Standard_Integer aMode = aCmd.ArgInt ("part", 1);
12861 Standard_Boolean aOnOff = aCmd.ArgBool ("part", 2);
12862 if (aMode < 1 || aMode > 4)
12864 Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
12868 aManipulator->SetPart (anAxis, static_cast<AIS_ManipulatorMode> (aMode), aOnOff);
12870 if (aCmd.HasOption("parts", 2, Standard_True))
12872 Standard_Integer aMode = aCmd.ArgInt("parts", 0);
12873 Standard_Boolean aOnOff = aCmd.ArgBool("parts", 1);
12874 if (aMode < 1 || aMode > 4)
12876 Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
12880 aManipulator->SetPart(static_cast<AIS_ManipulatorMode>(aMode), aOnOff);
12882 if (aCmd.HasOption ("pos", 3, Standard_True))
12884 gp_Pnt aLocation = aCmd.ArgPnt ("pos", 0);
12885 gp_Dir aVDir = aCmd.HasOption ("pos", 6) ? gp_Dir (aCmd.ArgVec ("pos", 3)) : aManipulator->Position().Direction();
12886 gp_Dir aXDir = aCmd.HasOption ("pos", 9) ? gp_Dir (aCmd.ArgVec ("pos", 6)) : aManipulator->Position().XDirection();
12888 aManipulator->SetPosition (gp_Ax2 (aLocation, aVDir, aXDir));
12890 if (aCmd.HasOption ("size", 1, Standard_True))
12892 aManipulator->SetSize (aCmd.ArgFloat ("size"));
12894 if (aCmd.HasOption ("zoomable", 1, Standard_True))
12896 aManipulator->SetZoomPersistence (!aCmd.ArgBool ("zoomable"));
12898 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12900 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
12901 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
12905 // ---------------------------------------------------
12906 // attach, detach or access manipulator from an object
12907 // ---------------------------------------------------
12909 if (aCmd.HasOption ("attach"))
12911 // Find an object and attach manipulator to it
12912 if (!aCmd.HasOption ("attach", 1, Standard_True))
12917 TCollection_AsciiString anObjName (aCmd.Arg ("attach", 0).c_str());
12918 Handle(AIS_InteractiveObject) anObject;
12919 if (!aMapAIS.Find2 (anObjName, anObject))
12921 Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" does not exist";
12925 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS);
12926 anIter.More(); anIter.Next())
12928 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
12929 if (!aManip.IsNull()
12930 && aManip->IsAttached()
12931 && aManip->Object() == anObject)
12933 Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" already has manipulator";
12938 AIS_Manipulator::OptionsForAttach anOptions;
12939 if (aCmd.HasOption ("adjustPosition", 1, Standard_True))
12941 anOptions.SetAdjustPosition (aCmd.ArgBool ("adjustPosition"));
12943 if (aCmd.HasOption ("adjustSize", 1, Standard_True))
12945 anOptions.SetAdjustSize (aCmd.ArgBool ("adjustSize"));
12947 if (aCmd.HasOption ("enableModes", 1, Standard_True))
12949 anOptions.SetEnableModes (aCmd.ArgBool ("enableModes"));
12952 aManipulator->Attach (anObject, anOptions);
12954 // Check view option
12955 if (aCmd.HasOption ("view"))
12957 if (!aCmd.HasOption ("view", 1, Standard_True))
12961 TCollection_AsciiString aViewString (aCmd.Arg ("view", 0).c_str());
12962 Handle(V3d_View) aView;
12963 if (aViewString.IsEqual ("active"))
12965 aView = ViewerTest::CurrentView();
12967 else // Check view name
12969 ViewerTest_Names aViewNames (aViewString);
12970 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
12972 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
12975 aView = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
12976 if (aView.IsNull())
12978 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
12982 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
12983 anIter (ViewerTest_myViews); anIter.More(); anIter.Next())
12985 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), Standard_False);
12987 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aView, Standard_True);
12991 // --------------------------------------
12992 // apply transformation using manipulator
12993 // --------------------------------------
12995 if (aCmd.HasOption ("startTransform", 2, Standard_True))
12997 aManipulator->StartTransform (aCmd.ArgInt ("startTransform", 0), aCmd.ArgInt ("startTransform", 1), ViewerTest::CurrentView());
12999 if (aCmd.HasOption ("transform", 2, Standard_True))
13001 aManipulator->Transform (aCmd.ArgInt ("transform", 0), aCmd.ArgInt ("transform", 1), ViewerTest::CurrentView());
13003 if (aCmd.HasOption ("stopTransform"))
13005 Standard_Boolean toApply = !aCmd.HasOption ("stopTransform", 1) || (aCmd.Arg ("stopTransform", 0) != "abort");
13007 aManipulator->StopTransform (toApply);
13011 if (aCmd.HasOption ("move", 3, Standard_True))
13013 aT.SetTranslationPart (aCmd.ArgVec ("move"));
13015 if (aCmd.HasOption ("rotate", 7, Standard_True))
13017 aT.SetRotation (gp_Ax1 (aCmd.ArgPnt ("rotate", 0), aCmd.ArgVec ("rotate", 3)), aCmd.ArgDouble ("rotate", 6));
13019 if (aCmd.HasOption ("scale", 1))
13021 aT.SetScale (gp_Pnt(), aCmd.ArgDouble("scale"));
13024 if (aT.Form() != gp_Identity)
13026 aManipulator->Transform (aT);
13029 ViewerTest::GetAISContext()->Redisplay (aManipulator, Standard_True);
13034 //===============================================================================================
13035 //function : VSelectionProperties
13037 //===============================================================================================
13038 static int VSelectionProperties (Draw_Interpretor& theDi,
13039 Standard_Integer theArgsNb,
13040 const char** theArgVec)
13042 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13045 Message::SendFail ("Error: no active viewer");
13049 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13051 // handle obsolete alias
13052 bool toEnable = true;
13055 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13058 else if (theArgsNb != 2
13059 || !ViewerTest::ParseOnOff (theArgVec[1], toEnable))
13061 Message::SendFail ("Syntax error: wrong number of parameters");
13064 if (toEnable != aCtx->ToHilightSelected())
13066 aCtx->ClearDetected();
13067 aCtx->SetToHilightSelected (toEnable);
13072 Standard_Boolean toPrint = theArgsNb == 1;
13073 Standard_Boolean toRedraw = Standard_False;
13074 Standard_Integer anArgIter = 1;
13075 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13076 if (anArgIter < theArgsNb)
13078 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13079 anArgFirst.LowerCase();
13081 if (anArgFirst == "dynhighlight"
13082 || anArgFirst == "dynhilight"
13083 || anArgFirst == "dynamichighlight"
13084 || anArgFirst == "dynamichilight")
13086 aType = Prs3d_TypeOfHighlight_Dynamic;
13088 else if (anArgFirst == "localdynhighlight"
13089 || anArgFirst == "localdynhilight"
13090 || anArgFirst == "localdynamichighlight"
13091 || anArgFirst == "localdynamichilight")
13093 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13095 else if (anArgFirst == "selhighlight"
13096 || anArgFirst == "selhilight"
13097 || anArgFirst == "selectedhighlight"
13098 || anArgFirst == "selectedhilight")
13100 aType = Prs3d_TypeOfHighlight_Selected;
13102 else if (anArgFirst == "localselhighlight"
13103 || anArgFirst == "localselhilight"
13104 || anArgFirst == "localselectedhighlight"
13105 || anArgFirst == "localselectedhilight")
13107 aType = Prs3d_TypeOfHighlight_LocalSelected;
13114 for (; anArgIter < theArgsNb; ++anArgIter)
13116 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13118 if (anArg == "-help")
13120 theDi.PrintHelp (theArgVec[0]);
13123 else if (anArg == "-print")
13125 toPrint = Standard_True;
13127 else if (anArg == "-autoactivate")
13129 Standard_Boolean toEnable = Standard_True;
13130 if (anArgIter + 1 < theArgsNb
13131 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13135 aCtx->SetAutoActivateSelection (toEnable);
13137 else if (anArg == "-automatichighlight"
13138 || anArg == "-automatichilight"
13139 || anArg == "-autohighlight"
13140 || anArg == "-autohilight")
13142 Standard_Boolean toEnable = Standard_True;
13143 if (anArgIter + 1 < theArgsNb
13144 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13148 aCtx->ClearSelected (false);
13149 aCtx->ClearDetected();
13150 aCtx->SetAutomaticHilight (toEnable);
13153 else if (anArg == "-highlightselected"
13154 || anArg == "-hilightselected")
13156 Standard_Boolean toEnable = Standard_True;
13157 if (anArgIter + 1 < theArgsNb
13158 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13162 aCtx->ClearDetected();
13163 aCtx->SetToHilightSelected (toEnable);
13166 else if (anArg == "-pickstrategy"
13167 || anArg == "-pickingstrategy")
13169 if (++anArgIter >= theArgsNb)
13171 Message::SendFail ("Syntax error: type of highlighting is undefined");
13175 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13176 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13178 if (aVal == "first"
13179 || aVal == "firstaccepted"
13180 || aVal == "firstacceptable")
13182 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13184 else if (aVal == "topmost"
13185 || aVal == "onlyTopmost")
13187 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13191 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
13195 aCtx->SetPickingStrategy (aStrategy);
13197 else if (anArg == "-pixtol"
13198 && anArgIter + 1 < theArgsNb)
13200 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13202 else if ((anArg == "-mode"
13203 || anArg == "-dispmode")
13204 && anArgIter + 1 < theArgsNb)
13206 if (aType == Prs3d_TypeOfHighlight_None)
13208 Message::SendFail ("Syntax error: type of highlighting is undefined");
13212 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13213 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13214 aStyle->SetDisplayMode (aDispMode);
13215 toRedraw = Standard_True;
13217 else if (anArg == "-layer"
13218 && anArgIter + 1 < theArgsNb)
13220 if (aType == Prs3d_TypeOfHighlight_None)
13222 Message::SendFail ("Syntax error: type of highlighting is undefined");
13227 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13228 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
13230 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
13234 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13235 aStyle->SetZLayer (aNewLayer);
13236 toRedraw = Standard_True;
13238 else if (anArg == "-hicolor"
13239 || anArg == "-selcolor"
13240 || anArg == "-color")
13242 if (anArg.StartsWith ("-hi"))
13244 aType = Prs3d_TypeOfHighlight_Dynamic;
13246 else if (anArg.StartsWith ("-sel"))
13248 aType = Prs3d_TypeOfHighlight_Selected;
13250 else if (aType == Prs3d_TypeOfHighlight_None)
13252 Message::SendFail ("Syntax error: type of highlighting is undefined");
13256 Quantity_Color aColor;
13257 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgsNb - anArgIter - 1,
13258 theArgVec + anArgIter + 1,
13260 if (aNbParsed == 0)
13262 Message::SendFail ("Syntax error: need more arguments");
13265 anArgIter += aNbParsed;
13267 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13268 aStyle->SetColor (aColor);
13269 toRedraw = Standard_True;
13271 else if ((anArg == "-transp"
13272 || anArg == "-transparency"
13273 || anArg == "-hitransp"
13274 || anArg == "-seltransp"
13275 || anArg == "-hitransplocal"
13276 || anArg == "-seltransplocal")
13277 && anArgIter + 1 < theArgsNb)
13279 if (anArg.StartsWith ("-hi"))
13281 aType = Prs3d_TypeOfHighlight_Dynamic;
13283 else if (anArg.StartsWith ("-sel"))
13285 aType = Prs3d_TypeOfHighlight_Selected;
13287 else if (aType == Prs3d_TypeOfHighlight_None)
13289 Message::SendFail ("Syntax error: type of highlighting is undefined");
13293 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13294 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13295 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13296 toRedraw = Standard_True;
13298 else if ((anArg == "-mat"
13299 || anArg == "-material")
13300 && anArgIter + 1 < theArgsNb)
13302 if (aType == Prs3d_TypeOfHighlight_None)
13304 Message::SendFail ("Syntax error: type of highlighting is undefined");
13308 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13309 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
13310 if (aMatName != Graphic3d_NOM_DEFAULT)
13313 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13314 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13315 Graphic3d_MaterialAspect aMat (aMatName);
13316 aMat.SetColor (aStyle->Color());
13317 aMat.SetTransparency (aStyle->Transparency());
13318 anAspect->SetFrontMaterial (aMat);
13319 anAspect->SetInteriorColor (aStyle->Color());
13320 aStyle->SetBasicFillAreaAspect (anAspect);
13324 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13326 toRedraw = Standard_True;
13330 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
13336 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13337 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
13338 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
13339 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13340 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
13341 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
13342 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13343 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13344 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13345 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13346 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13347 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13348 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13349 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
13352 if (aCtx->NbSelected() != 0 && toRedraw)
13354 aCtx->HilightSelected (Standard_True);
13360 //===============================================================================================
13361 //function : VDumpSelectionImage
13363 //===============================================================================================
13364 static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13365 Standard_Integer theArgsNb,
13366 const char** theArgVec)
13370 Message::SendFail() << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'";
13374 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13375 if (aContext.IsNull())
13377 Message::SendFail ("Error: no active viewer");
13381 TCollection_AsciiString aFile;
13382 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13383 Image_Format anImgFormat = Image_Format_BGR;
13384 Standard_Integer aPickedIndex = 1;
13385 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13387 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13388 aParam.LowerCase();
13389 if (aParam == "-type")
13391 if (++anArgIter >= theArgsNb)
13393 Message::SendFail ("Syntax error: wrong number parameters of flag '-depth'");
13397 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13398 aValue.LowerCase();
13399 if (aValue == "depth"
13400 || aValue == "normdepth"
13401 || aValue == "normalizeddepth")
13403 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13404 anImgFormat = Image_Format_GrayF;
13406 if (aValue == "depthinverted"
13407 || aValue == "normdepthinverted"
13408 || aValue == "normalizeddepthinverted"
13409 || aValue == "inverted")
13411 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
13412 anImgFormat = Image_Format_GrayF;
13414 else if (aValue == "unnormdepth"
13415 || aValue == "unnormalizeddepth")
13417 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
13418 anImgFormat = Image_Format_GrayF;
13420 else if (aValue == "objectcolor"
13421 || aValue == "object"
13422 || aValue == "color")
13424 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13426 else if (aValue == "entitycolor"
13427 || aValue == "entity")
13429 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13431 else if (aValue == "ownercolor"
13432 || aValue == "owner")
13434 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13436 else if (aValue == "selectionmodecolor"
13437 || aValue == "selectionmode"
13438 || aValue == "selmodecolor"
13439 || aValue == "selmode")
13441 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13444 else if (aParam == "-picked"
13445 || aParam == "-pickeddepth"
13446 || aParam == "-pickedindex")
13448 if (++anArgIter >= theArgsNb)
13450 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
13454 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13456 else if (aFile.IsEmpty())
13458 aFile = theArgVec[anArgIter];
13462 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13466 if (aFile.IsEmpty())
13468 Message::SendFail ("Syntax error: image file name is missing");
13472 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13473 Standard_Integer aWidth = 0, aHeight = 0;
13474 aView->Window()->Size (aWidth, aHeight);
13476 Image_AlienPixMap aPixMap;
13477 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13479 Message::SendFail ("Error: can't allocate image");
13482 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13484 Message::SendFail ("Error: can't generate selection image");
13487 if (!aPixMap.Save (aFile))
13489 Message::SendFail ("Error: can't save selection image");
13495 //===============================================================================================
13496 //function : VViewCube
13498 //===============================================================================================
13499 static int VViewCube (Draw_Interpretor& ,
13500 Standard_Integer theNbArgs,
13501 const char** theArgVec)
13503 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13504 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13505 if (aContext.IsNull() || aView.IsNull())
13507 Message::SendFail ("Error: no active viewer");
13510 else if (theNbArgs < 2)
13512 Message::SendFail ("Syntax error: wrong number arguments");
13516 Handle(AIS_ViewCube) aViewCube;
13517 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13518 Quantity_Color aColorRgb;
13519 TCollection_AsciiString aName;
13520 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13522 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13524 if (anUpdateTool.parseRedrawMode (anArg))
13528 else if (aViewCube.IsNull())
13530 aName = theArgVec[anArgIter];
13531 if (aName.StartsWith ("-"))
13533 Message::SendFail ("Syntax error: object name should be specified");
13536 Handle(AIS_InteractiveObject) aPrs;
13537 GetMapOfAIS().Find2 (aName, aPrs);
13538 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13539 if (aViewCube.IsNull())
13541 aViewCube = new AIS_ViewCube();
13542 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13543 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13544 aViewCube->SetFixedAnimationLoop (false);
13547 else if (anArg == "-reset")
13549 aViewCube->ResetStyles();
13551 else if (anArg == "-color"
13552 || anArg == "-boxcolor"
13553 || anArg == "-boxsidecolor"
13554 || anArg == "-sidecolor"
13555 || anArg == "-boxedgecolor"
13556 || anArg == "-edgecolor"
13557 || anArg == "-boxcornercolor"
13558 || anArg == "-cornercolor"
13559 || anArg == "-innercolor"
13560 || anArg == "-textcolor")
13562 Standard_Integer aNbParsed = ViewerTest::ParseColor (theNbArgs - anArgIter - 1,
13563 theArgVec + anArgIter + 1,
13565 if (aNbParsed == 0)
13567 Message::SendFail() << "Syntax error at '" << anArg << "'";
13570 anArgIter += aNbParsed;
13571 if (anArg == "-boxcolor")
13573 aViewCube->SetBoxColor (aColorRgb);
13575 else if (anArg == "-boxsidecolor"
13576 || anArg == "-sidecolor")
13578 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13579 aViewCube->SynchronizeAspects();
13581 else if (anArg == "-boxedgecolor"
13582 || anArg == "-edgecolor")
13584 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13585 aViewCube->SynchronizeAspects();
13587 else if (anArg == "-boxcornercolor"
13588 || anArg == "-cornercolor")
13590 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13591 aViewCube->SynchronizeAspects();
13593 else if (anArg == "-innercolor")
13595 aViewCube->SetInnerColor (aColorRgb);
13597 else if (anArg == "-textcolor")
13599 aViewCube->SetTextColor (aColorRgb);
13603 aViewCube->SetColor (aColorRgb);
13606 else if (anArgIter + 1 < theNbArgs
13607 && (anArg == "-transparency"
13608 || anArg == "-boxtransparency"))
13610 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13611 if (aValue < 0.0 || aValue > 1.0)
13613 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
13617 if (anArg == "-boxtransparency")
13619 aViewCube->SetBoxTransparency (aValue);
13623 aViewCube->SetTransparency (aValue);
13626 else if (anArg == "-axes"
13627 || anArg == "-edges"
13628 || anArg == "-vertices"
13629 || anArg == "-vertexes"
13630 || anArg == "-fixedanimation")
13632 bool toShow = true;
13633 if (anArgIter + 1 < theNbArgs
13634 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toShow))
13638 if (anArg == "-fixedanimation")
13640 aViewCube->SetFixedAnimationLoop (toShow);
13642 else if (anArg == "-axes")
13644 aViewCube->SetDrawAxes (toShow);
13646 else if (anArg == "-edges")
13648 aViewCube->SetDrawEdges (toShow);
13652 aViewCube->SetDrawVertices (toShow);
13655 else if (anArg == "-yup"
13656 || anArg == "-zup")
13659 if (anArgIter + 1 < theNbArgs
13660 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isOn))
13664 if (anArg == "-yup")
13666 aViewCube->SetYup (isOn);
13670 aViewCube->SetYup (!isOn);
13673 else if (anArgIter + 1 < theNbArgs
13674 && anArg == "-font")
13676 aViewCube->SetFont (theArgVec[++anArgIter]);
13678 else if (anArgIter + 1 < theNbArgs
13679 && anArg == "-fontheight")
13681 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13683 else if (anArgIter + 1 < theNbArgs
13684 && (anArg == "-size"
13685 || anArg == "-boxsize"))
13687 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13688 anArg != "-boxsize");
13690 else if (anArgIter + 1 < theNbArgs
13691 && (anArg == "-boxfacet"
13692 || anArg == "-boxfacetextension"
13693 || anArg == "-facetextension"
13694 || anArg == "-extension"))
13696 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13698 else if (anArgIter + 1 < theNbArgs
13699 && (anArg == "-boxedgegap"
13700 || anArg == "-edgegap"))
13702 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13704 else if (anArgIter + 1 < theNbArgs
13705 && (anArg == "-boxedgeminsize"
13706 || anArg == "-edgeminsize"))
13708 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
13710 else if (anArgIter + 1 < theNbArgs
13711 && (anArg == "-boxcornerminsize"
13712 || anArg == "-cornerminsize"))
13714 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
13716 else if (anArgIter + 1 < theNbArgs
13717 && anArg == "-axespadding")
13719 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
13721 else if (anArgIter + 1 < theNbArgs
13722 && anArg == "-roundradius")
13724 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
13726 else if (anArgIter + 1 < theNbArgs
13727 && anArg == "-duration")
13729 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
13731 else if (anArgIter + 1 < theNbArgs
13732 && anArg == "-axesradius")
13734 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
13736 else if (anArgIter + 1 < theNbArgs
13737 && anArg == "-axesconeradius")
13739 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
13741 else if (anArgIter + 1 < theNbArgs
13742 && anArg == "-axessphereradius")
13744 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
13748 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13752 if (aViewCube.IsNull())
13754 Message::SendFail ("Syntax error: wrong number of arguments");
13758 ViewerTest::Display (aName, aViewCube, false);
13762 //===============================================================================================
13763 //function : VColorConvert
13765 //===============================================================================================
13766 static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13768 if (theNbArgs != 6)
13770 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13774 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
13775 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
13777 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
13781 const char* aTypeStr = theArgVec[2];
13782 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
13783 if (! strcasecmp (aTypeStr, "srgb"))
13785 aType = Quantity_TOC_sRGB;
13787 else if (! strcasecmp (aTypeStr, "hls"))
13789 aType = Quantity_TOC_HLS;
13791 else if (! strcasecmp (aTypeStr, "lab"))
13793 aType = Quantity_TOC_CIELab;
13795 else if (! strcasecmp (aTypeStr, "lch"))
13797 aType = Quantity_TOC_CIELch;
13801 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
13805 double aC1 = Draw::Atof (theArgVec[3]);
13806 double aC2 = Draw::Atof (theArgVec[4]);
13807 double aC3 = Draw::Atof (theArgVec[5]);
13809 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
13810 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
13812 // print values with 6 decimal digits
13814 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
13820 //===============================================================================================
13821 //function : VColorDiff
13823 //===============================================================================================
13824 static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13826 if (theNbArgs != 7)
13828 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13832 double aR1 = Draw::Atof (theArgVec[1]);
13833 double aG1 = Draw::Atof (theArgVec[2]);
13834 double aB1 = Draw::Atof (theArgVec[3]);
13835 double aR2 = Draw::Atof (theArgVec[4]);
13836 double aG2 = Draw::Atof (theArgVec[5]);
13837 double aB2 = Draw::Atof (theArgVec[6]);
13839 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
13840 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
13842 theDI << aColor1.DeltaE2000 (aColor2);
13847 //=======================================================================
13848 //function : ViewerCommands
13850 //=======================================================================
13852 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
13855 const char *group = "ZeViewer";
13856 theCommands.Add("vinit",
13857 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
13858 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-2d_mode {on|off}=off]"
13859 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
13860 "\n\t\t: [-display displayName]"
13862 "\n\t\t: Creates new View window with specified name viewName."
13863 "\n\t\t: By default the new view is created in the viewer and in"
13864 "\n\t\t: graphic driver shared with active view."
13865 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
13866 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
13867 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
13868 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
13869 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
13870 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
13872 "\n\t\t: -left, -top pixel position of left top corner of the window."
13873 "\n\t\t: -width, -height width and heigth of window respectively."
13874 "\n\t\t: -cloneActive floag to copy camera and dimensions of active view."
13875 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
13876 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
13877 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
13878 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
13879 __FILE__,VInit,group);
13880 theCommands.Add("vclose" ,
13881 "[view_id [keep_context=0|1]]\n"
13882 "or vclose ALL - to remove all created views\n"
13883 " - removes view(viewer window) defined by its view_id.\n"
13884 " - keep_context: by default 0; if 1 and the last view is deleted"
13885 " the current context is not removed.",
13886 __FILE__,VClose,group);
13887 theCommands.Add("vactivate" ,
13888 "vactivate view_id [-noUpdate]"
13889 " - activates view(viewer window) defined by its view_id",
13890 __FILE__,VActivate,group);
13891 theCommands.Add("vviewlist",
13892 "vviewlist [format={tree, long}]"
13893 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
13894 " - format: format of result output, if tree the output is a tree view;"
13895 "otherwise it's a list of full view names. By default format = tree",
13896 __FILE__,VViewList,group);
13897 theCommands.Add("vhelp" ,
13898 "vhelp : display help on the viewer commands",
13899 __FILE__,VHelp,group);
13900 theCommands.Add("vviewproj",
13901 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
13902 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
13903 "\n\t\t: Setup view direction"
13904 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
13905 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
13906 "\n\t\t: for example '+Z' will show front of the model,"
13907 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
13908 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
13909 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
13910 __FILE__,VViewProj,group);
13911 theCommands.Add("vtop" ,
13912 "vtop or <T> : Top view. Orientation +X+Y" ,
13913 __FILE__,VViewProj,group);
13914 theCommands.Add("vbottom" ,
13915 "vbottom : Bottom view. Orientation +X-Y" ,
13916 __FILE__,VViewProj,group);
13917 theCommands.Add("vleft" ,
13918 "vleft : Left view. Orientation -Y+Z" ,
13919 __FILE__,VViewProj,group);
13920 theCommands.Add("vright" ,
13921 "vright : Right view. Orientation +Y+Z" ,
13922 __FILE__,VViewProj,group);
13923 theCommands.Add("vaxo" ,
13924 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
13925 __FILE__,VViewProj,group);
13926 theCommands.Add("vfront" ,
13927 "vfront : Front view. Orientation +X+Z" ,
13928 __FILE__,VViewProj,group);
13929 theCommands.Add("vback" ,
13930 "vback : Back view. Orientation -X+Z" ,
13931 __FILE__,VViewProj,group);
13932 theCommands.Add("vpick" ,
13933 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
13935 theCommands.Add("vfit",
13936 "vfit or <F> [-selected] [-noupdate]"
13937 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
13938 __FILE__,VFit,group);
13939 theCommands.Add ("vfitarea",
13940 "vfitarea x1 y1 x2 y2"
13941 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
13942 "\n\t\t: Fit view to show area located between two points"
13943 "\n\t\t: given in world 2D or 3D corrdinates.",
13944 __FILE__, VFitArea, group);
13945 theCommands.Add ("vzfit", "vzfit [scale]\n"
13946 " Matches Z near, Z far view volume planes to the displayed objects.\n"
13947 " \"scale\" - specifies factor to scale computed z range.\n",
13948 __FILE__, VZFit, group);
13949 theCommands.Add("vrepaint",
13950 "vrepaint [-immediate] [-continuous FPS]"
13951 "\n\t\t: force redraw of active View"
13952 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
13953 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
13954 "\n\t\t: 0 means no continuous rendering,"
13955 "\n\t\t: -1 means non-stop redraws,"
13956 "\n\t\t: >0 specifies target framerate,",
13957 __FILE__,VRepaint,group);
13958 theCommands.Add("vclear",
13960 "\n\t\t: remove all the object from the viewer",
13961 __FILE__,VClear,group);
13964 "Changes background or some background settings.\n"
13967 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
13968 " vbackground -imageMode FillType\n"
13969 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
13970 " vbackground -gradientMode FillMethod\n"
13971 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
13972 " vbackground -color Color\n"
13973 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
13974 " vbackground -default -color Color\n"
13975 " vbackground -help\n"
13978 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
13979 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
13980 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
13981 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
13982 " -cubemap (-cmap, -cm): sets environmet cubemap as background\n"
13983 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
13984 " -order (-o): defines order of tiles in one image cubemap\n"
13985 " (has no effect in case of multi image cubemaps)\n"
13986 " -color (-col): sets background color\n"
13987 " -default (-def): sets background default gradient or color\n"
13988 " -help (-h): outputs short help message\n"
13991 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
13992 " or reals within the range [0.0, 1.0]\n"
13993 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
13994 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
13995 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
13997 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
13998 " ImageFile: a name of the file with the image used as a background\n"
13999 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14000 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
14004 theCommands.Add ("vsetbg",
14005 "Loads image as background."
14006 "\n\t\t: vsetbg ImageFile [FillType]"
14007 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14008 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14012 theCommands.Add ("vsetbgmode",
14013 "Changes background image fill type."
14014 "\n\t\t: vsetbgmode [-imageMode] FillType"
14015 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14019 theCommands.Add ("vsetgradientbg",
14020 "Mounts gradient background."
14021 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14022 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14023 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14027 theCommands.Add ("vsetgrbgmode",
14028 "Changes gradient background fill method."
14029 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14030 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14034 theCommands.Add ("vsetcolorbg",
14035 "Sets background color."
14036 "\n\t\t: vsetcolorbg [-color] Color."
14037 "\n\t\t: Alias for 'vbackground -color Color'.",
14041 theCommands.Add ("vsetdefaultbg",
14042 "Sets default viewer background fill color (flat/gradient)."
14043 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14044 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14045 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14046 "\n\t\t: vsetdefaultbg [-color] Color"
14047 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14051 theCommands.Add("vscale",
14052 "vscale : vscale X Y Z",
14053 __FILE__,VScale,group);
14054 theCommands.Add("vzbufftrihedron",
14055 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14056 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14057 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14058 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14059 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
14060 "\n\t\t: Displays a trihedron",
14061 __FILE__,VZBuffTrihedron,group);
14062 theCommands.Add("vrotate",
14063 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14064 "\n : Option -mouseStart starts rotation according to the mouse position"
14065 "\n : Option -mouseMove continues rotation with angle computed"
14066 "\n : from last and new mouse position."
14067 "\n : vrotate AX AY AZ [X Y Z]",
14068 __FILE__,VRotate,group);
14069 theCommands.Add("vzoom",
14070 "vzoom : vzoom coef",
14071 __FILE__,VZoom,group);
14072 theCommands.Add("vpan",
14073 "vpan : vpan dx dy",
14074 __FILE__,VPan,group);
14075 theCommands.Add("vcolorscale",
14076 "vcolorscale name [-noupdate|-update] [-demo]"
14077 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14078 "\n\t\t: [-font HeightFont=20]"
14079 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14080 "\n\t\t: [-smoothTransition {on|off}=off]"
14081 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14082 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14083 "\n\t\t: [-textpos {left|right|center|none}=right]"
14084 "\n\t\t: [-labelAtBorder {on|off}=on]"
14085 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14086 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14087 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14088 "\n\t\t: [-xy Left=0 Bottom=0]"
14089 "\n\t\t: [-uniform lightness hue_from hue_to]"
14090 "\n\t\t: -demo - displays a color scale with demonstratio values"
14091 "\n\t\t: -colors - set colors for all intervals"
14092 "\n\t\t: -color - set color for specific interval"
14093 "\n\t\t: -uniform - generate colors with the same lightness"
14094 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14095 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14096 "\n\t\t: at border means the value inbetween neighbor intervals,"
14097 "\n\t\t: at center means the center value within current interval"
14098 "\n\t\t: -labels - set labels for all intervals"
14099 "\n\t\t: -freeLabels - same as -labels but does not require"
14100 "\n\t\t: matching the number of intervals"
14101 "\n\t\t: -label - set label for specific interval"
14102 "\n\t\t: -title - set title"
14103 "\n\t\t: -reversed - setup smooth color transition between intervals"
14104 "\n\t\t: -smoothTransition - swap colorscale direction"
14105 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
14106 __FILE__, VColorScale, group);
14107 theCommands.Add("vgraduatedtrihedron",
14108 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14109 "\t[-namefont Name] [-valuesfont Name]\n"
14110 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14111 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14112 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14113 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14114 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14115 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14116 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14117 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14118 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
14119 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
14120 " - Displays or erases graduated trihedron"
14121 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14122 " - namefont - font of axes names. Default: Arial\n"
14123 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14124 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14125 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14126 " - valuesfont - font of axes values. Default: Arial\n"
14127 " - xcolor, ycolor, zcolor - color of axis and values\n"
14128 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14129 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
14130 __FILE__,VGraduatedTrihedron,group);
14131 theCommands.Add("vtile" ,
14132 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14133 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14134 "\n\t\t: -totalSize the size of virtual bigger viewport"
14135 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14136 "\n\t\t: -lowerLeft tile offset as lower left corner"
14137 "\n\t\t: -upperLeft tile offset as upper left corner",
14138 __FILE__, VTile, group);
14139 theCommands.Add("vzlayer",
14140 "vzlayer [layerId]"
14141 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
14142 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
14143 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
14144 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
14145 "\n\t\t: ZLayer list management:"
14146 "\n\t\t: -add add new z layer to viewer and print its id"
14147 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14148 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
14149 "\n\t\t: -delete delete z layer"
14150 "\n\t\t: -get print sequence of z layers"
14151 "\n\t\t: -settings print status of z layer settings"
14152 "\n\t\t: -disable disables given setting"
14153 "\n\t\t: -enable enables given setting",
14154 __FILE__,VZLayer,group);
14155 theCommands.Add("vlayerline",
14156 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14157 __FILE__,VLayerLine,group);
14158 theCommands.Add("vgrid",
14159 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14160 "\n\t\t: [-step X Y] [-size DX DY]"
14161 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
14162 __FILE__, VGrid, group);
14163 theCommands.Add ("vpriviledgedplane",
14164 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14165 "\n\t\t: Ox, Oy, Oz - plane origin"
14166 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14167 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14168 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14169 __FILE__, VPriviledgedPlane, group);
14170 theCommands.Add ("vconvert",
14171 "vconvert v [Mode={window|view}]"
14172 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14173 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14174 "\n\t\t: window - convert to window coordinates, pixels"
14175 "\n\t\t: view - convert to view projection plane"
14176 "\n\t\t: grid - convert to model coordinates, given on grid"
14177 "\n\t\t: ray - convert projection ray to model coordiantes"
14178 "\n\t\t: - vconvert v window : convert view to window;"
14179 "\n\t\t: - vconvert v view : convert window to view;"
14180 "\n\t\t: - vconvert x y window : convert view to window;"
14181 "\n\t\t: - vconvert x y view : convert window to view;"
14182 "\n\t\t: - vconvert x y : convert window to model;"
14183 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14184 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14185 "\n\t\t: - vconvert x y z window : convert model to window;"
14186 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14187 "\n\t\t: Converts the given coordinates to window/view/model space.",
14188 __FILE__, VConvert, group);
14189 theCommands.Add ("vfps",
14190 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
14191 __FILE__, VFps, group);
14192 theCommands.Add ("vgldebug",
14193 "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
14194 "\n\t\t: [-glslCode {off|short|full}] [-extraMsg {0|1}] [{0|1}]"
14195 "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
14196 "\n\t\t: Debug context can be requested only on Windows"
14197 "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
14198 "\n\t\t: -sync - request synchronized debug GL context"
14199 "\n\t\t: -glslWarn - log GLSL compiler/linker warnings,"
14200 "\n\t\t: which are suppressed by default,"
14201 "\n\t\t: -glslCode - log GLSL program source code,"
14202 "\n\t\t: which are suppressed by default,"
14203 "\n\t\t: -extraMsg - log extra diagnostic messages from GL context,"
14204 "\n\t\t: which are suppressed by default",
14205 __FILE__, VGlDebug, group);
14206 theCommands.Add ("vvbo",
14207 "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
14208 __FILE__, VVbo, group);
14209 theCommands.Add ("vstereo",
14210 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
14211 "\n\t\t: [-anaglyph Filter]"
14212 "\n\t\t: Control stereo output mode. Available modes for -mode:"
14213 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14214 "\n\t\t: requires driver support."
14215 "\n\t\t: Should be called BEFORE vinit!"
14216 "\n\t\t: anaglyph - Anaglyph glasses"
14217 "\n\t\t: rowInterlaced - row-interlaced display"
14218 "\n\t\t: columnInterlaced - column-interlaced display"
14219 "\n\t\t: chessBoard - chess-board output"
14220 "\n\t\t: sideBySide - horizontal pair"
14221 "\n\t\t: overUnder - vertical pair"
14222 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14223 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14224 "\n\t\t: greenMagentaSimple",
14225 __FILE__, VStereo, group);
14226 theCommands.Add ("vcaps",
14227 "vcaps [-sRGB {0|1}] [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
14228 "\n\t\t: [-compatibleProfile {0|1}]"
14229 "\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}]"
14230 "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
14231 "\n\t\t: [-softMode {0|1}] [-noupdate|-update]"
14232 "\n\t\t: [-noExtensions {0|1}] [-maxVersion Major Minor]"
14233 "\n\t\t: Modify particular graphic driver options:"
14234 "\n\t\t: sRGB - enable/disable sRGB rendering"
14235 "\n\t\t: FFP - use fixed-function pipeline instead of"
14236 "\n\t\t: built-in GLSL programs"
14237 "\n\t\t: (requires compatible profile)"
14238 "\n\t\t: polygonMode - use Polygon Mode instead of built-in GLSL programs"
14239 "\n\t\t: VBO - use Vertex Buffer Object (copy vertex"
14240 "\n\t\t: arrays to GPU memory)"
14241 "\n\t\t: sprite - use textured sprites instead of bitmaps"
14242 "\n\t\t: vsync - switch VSync on or off"
14243 "\n\t\t: winBuffer - allow using window buffer for rendering"
14244 "\n\t\t: Context creation options:"
14245 "\n\t\t: softMode - software OpenGL implementation"
14246 "\n\t\t: compatibleProfile - backward-compatible profile"
14247 "\n\t\t: quadbuffer - QuadBuffer"
14248 "\n\t\t: noExtensions - disallow usage of extensions"
14249 "\n\t\t: maxVersion - force upper OpenGL version to be used"
14250 "\n\t\t: Unlike vrenderparams, these parameters control alternative"
14251 "\n\t\t: rendering paths producing the same visual result when"
14252 "\n\t\t: possible."
14253 "\n\t\t: Command is intended for testing old hardware compatibility.",
14254 __FILE__, VCaps, group);
14255 theCommands.Add ("vmemgpu",
14256 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14257 " with f option returns free memory in bytes",
14258 __FILE__, VMemGpu, group);
14259 theCommands.Add ("vreadpixel",
14260 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
14261 " : Read pixel value for active view",
14262 __FILE__, VReadPixel, group);
14263 theCommands.Add("diffimage",
14264 "diffimage imageFile1 imageFile2 [diffImageFile]"
14265 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14266 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14267 "\n\t\t: Compare two images by content and generate difference image."
14268 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14269 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
14270 __FILE__, VDiffImage, group);
14271 theCommands.Add ("vselect",
14272 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [shift_selection = 0|1]\n"
14273 "- emulates different types of selection:\n"
14274 "- 1) single click selection\n"
14275 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14276 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
14277 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14278 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14279 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14280 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
14281 "- 5) any of these selections with shift button pressed",
14282 __FILE__, VSelect, group);
14283 theCommands.Add ("vmoveto",
14284 "vmoveto [x y] [-reset]"
14285 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14286 "\n\t\t: -reset resets current highlighting",
14287 __FILE__, VMoveTo, group);
14288 theCommands.Add ("vviewparams",
14289 "vviewparams [-args] [-scale [s]]"
14290 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14291 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14292 "\n\t\t: Manage current view parameters or prints all"
14293 "\n\t\t: current values when called without argument."
14294 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14295 "\n\t\t: -eye [x y z] prints or sets eye location"
14296 "\n\t\t: -at [x y z] prints or sets center of look"
14297 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14298 "\n\t\t: -proj [x y z] prints or sets direction of look"
14299 "\n\t\t: -center x y sets location of center of the screen in pixels"
14300 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14301 "\n\t\t: or changes the size of its maximum dimension"
14302 "\n\t\t: -args prints vviewparams arguments for restoring current view",
14303 __FILE__, VViewParams, group);
14305 theCommands.Add("v2dmode",
14306 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14307 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14308 "\n\t\t: mode - switches On/Off rotation mode"
14309 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14310 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14311 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14312 "\n\t\t: View camera position might be changed only by commands.",
14313 __FILE__, V2DMode, group);
14315 theCommands.Add("vanimation", "Alias for vanim",
14316 __FILE__, VAnimation, group);
14318 theCommands.Add("vanim",
14319 "List existing animations:"
14321 "\n\t\t: Animation playback:"
14322 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14323 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14324 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14325 "\n\t\t: -freeLook skip camera animations"
14326 "\n\t\t: -lockLoop disable any interactions"
14328 "\n\t\t: Animation definition:"
14329 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14330 "\n\t\t: [start TimeSec] [duration TimeSec]"
14332 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14333 "\n\t\t: specifies nested animations."
14334 "\n\t\t: There is no syntax to explicitly add new animation,"
14335 "\n\t\t: and all non-existing animations within the name will be"
14336 "\n\t\t: implicitly created on first use (including parents)."
14338 "\n\t\t: Each animation might define the SINGLE action (see below),"
14339 "\n\t\t: like camera transition, object transformation or custom callback."
14340 "\n\t\t: Child animations can be used for defining concurrent actions."
14342 "\n\t\t: Camera animation:"
14343 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14344 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14345 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14346 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14347 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14348 "\n\t\t: -atX camera Center positions pair"
14349 "\n\t\t: -upX camera Up directions pair"
14350 "\n\t\t: -scaleX camera Scale factors pair"
14351 "\n\t\t: Object animation:"
14352 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14353 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14354 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14355 "\n\t\t: -locX object Location points pair (translation)"
14356 "\n\t\t: -rotX object Orientations pair (quaternions)"
14357 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14358 "\n\t\t: Custom callback:"
14359 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14360 "\n\t\t: %Pts overall animation presentation timestamp"
14361 "\n\t\t: %LocalPts local animation timestamp"
14362 "\n\t\t: %Normalized local animation normalized value in range 0..1"
14364 "\n\t\t: Video recording:"
14365 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14366 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14367 "\n\t\t: [-crf Value] [-preset Preset]"
14368 "\n\t\t: -fps video framerate"
14369 "\n\t\t: -format file format, container (matroska, etc.)"
14370 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14371 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14372 "\n\t\t: -crf constant rate factor (specific to codec)"
14373 "\n\t\t: -preset codec parameters preset (specific to codec)"
14374 __FILE__, VAnimation, group);
14376 theCommands.Add("vchangeselected",
14377 "vchangeselected shape"
14378 "- adds to shape to selection or remove one from it",
14379 __FILE__, VChangeSelected, group);
14380 theCommands.Add ("vnbselected",
14382 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
14383 theCommands.Add ("vcamera",
14384 "vcamera [PrsName] [-ortho] [-projtype]"
14386 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14387 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14388 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14389 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
14390 "\n\t\t: Manages camera parameters."
14391 "\n\t\t: Displays frustum when presntation name PrsName is specified."
14392 "\n\t\t: Prints current value when option called without argument."
14393 "\n\t\t: Orthographic camera:"
14394 "\n\t\t: -ortho activate orthographic projection"
14395 "\n\t\t: Perspective camera:"
14396 "\n\t\t: -persp activate perspective projection (mono)"
14397 "\n\t\t: -fovy field of view in y axis, in degrees"
14398 "\n\t\t: -distance distance of eye from camera center"
14399 "\n\t\t: Stereoscopic camera:"
14400 "\n\t\t: -stereo perspective projection (stereo)"
14401 "\n\t\t: -leftEye perspective projection (left eye)"
14402 "\n\t\t: -rightEye perspective projection (right eye)"
14403 "\n\t\t: -iod intraocular distance value"
14404 "\n\t\t: -iodType distance type, absolute or relative"
14405 "\n\t\t: -zfocus stereographic focus value"
14406 "\n\t\t: -zfocusType focus type, absolute or relative",
14407 __FILE__, VCamera, group);
14408 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
14409 "- vautozfit [on={1|0}] [scale]\n"
14410 " Prints or changes parameters of automatic z-fit mode:\n"
14411 " \"on\" - turns automatic z-fit on or off\n"
14412 " \"scale\" - specifies factor to scale computed z range.\n",
14413 __FILE__, VAutoZFit, group);
14414 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14415 " vzrange - without parameters shows current values\n"
14416 " vzrange [znear] [zfar] - applies provided values to view",
14417 __FILE__,VZRange, group);
14418 theCommands.Add ("vpurgedisplay",
14420 "- removes structures which don't belong to objects displayed in neutral point",
14421 __FILE__, VPurgeDisplay, group);
14422 theCommands.Add("vsetviewsize",
14423 "vsetviewsize size",
14424 __FILE__,VSetViewSize,group);
14425 theCommands.Add("vmoveview",
14426 "vmoveview Dx Dy Dz [Start = 1|0]",
14427 __FILE__,VMoveView,group);
14428 theCommands.Add("vtranslateview",
14429 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14430 __FILE__,VTranslateView,group);
14431 theCommands.Add("vturnview",
14432 "vturnview Ax Ay Az [Start = 1|0]",
14433 __FILE__,VTurnView,group);
14434 theCommands.Add("vtextureenv",
14435 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14436 "or user-defined file and optionally applying texture mapping parameters\n"
14438 " vtextureenv off - disables environment mapping\n"
14439 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14440 " std_texture = (0..7)\n"
14441 " rep = {clamp|repeat}\n"
14442 " mod = {decal|modulate}\n"
14443 " flt = {nearest|bilinear|trilinear}\n"
14444 " ss, st - scale factors for s and t texture coordinates\n"
14445 " ts, tt - translation for s and t texture coordinates\n"
14446 " rot - texture rotation angle in degrees",
14447 __FILE__, VTextureEnv, group);
14448 theCommands.Add("vhlr",
14449 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14450 "\n\t\t: Hidden Line Removal algorithm."
14451 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14452 "\n\t\t: -algoType type of HLR algorithm.\n",
14453 __FILE__,VHLR,group);
14454 theCommands.Add("vhlrtype",
14455 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14456 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14457 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14458 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14459 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
14460 __FILE__,VHLRType,group);
14461 theCommands.Add("vclipplane",
14462 "vclipplane planeName [{0|1}]"
14463 "\n\t\t: [-equation1 A B C D]"
14464 "\n\t\t: [-equation2 A B C D]"
14465 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
14466 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
14467 "\n\t\t: [-maxPlanes]"
14468 "\n\t\t: [-capping {0|1}]"
14469 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
14470 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14471 "\n\t\t: [-texRotate Angle]"
14472 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14473 "\n\t\t: [-useObjShader {0|1}]"
14474 "\n\t\t: Clipping planes management:"
14475 "\n\t\t: -maxPlanes print plane limit for view"
14476 "\n\t\t: -delete delete plane with given name"
14477 "\n\t\t: {off|on|0|1} turn clipping on/off"
14478 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14479 "\n\t\t: applied to active View when list is omitted"
14480 "\n\t\t: -equation A B C D change plane equation"
14481 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14482 "\n\t\t: Capping options:"
14483 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14484 "\n\t\t: -color R G B set capping color"
14485 "\n\t\t: -transparency Value set capping transparency 0..1"
14486 "\n\t\t: -texName Texture set capping texture"
14487 "\n\t\t: -texScale SX SY set capping tex scale"
14488 "\n\t\t: -texOrigin TX TY set capping tex origin"
14489 "\n\t\t: -texRotate Angle set capping tex rotation"
14490 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14491 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14492 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14493 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14494 __FILE__, VClipPlane, group);
14495 theCommands.Add("vdefaults",
14496 "vdefaults [-absDefl value]"
14497 "\n\t\t: [-devCoeff value]"
14498 "\n\t\t: [-angDefl value]"
14499 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14500 , __FILE__, VDefaults, group);
14501 theCommands.Add("vlight",
14502 "tool to manage light sources, without arguments shows list of lights."
14503 "\n Main commands: "
14504 "\n '-clear' to clear lights"
14505 "\n '-{def}aults' to load deafault lights"
14506 "\n '-add' <type> to add any light source"
14507 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
14508 "\n 'change' <lightId> to edit light source with specified lightId"
14509 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
14511 "\n -{pos}ition X Y Z"
14512 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
14513 "\n -color colorName"
14514 "\n -{head}light 0|1"
14515 "\n -{sm}oothness value"
14516 "\n -{int}ensity value"
14517 "\n -{constAtten}uation value"
14518 "\n -{linearAtten}uation value"
14519 "\n -angle angleDeg"
14520 "\n -{spotexp}onent value"
14522 "\n -local|-global"
14523 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
14524 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
14525 __FILE__, VLight, group);
14526 theCommands.Add("vpbrenv",
14527 "vpbrenv -clear|-generate"
14528 "\n\t\t: Clears or generates PBR environment map of active view."
14529 "\n\t\t: -clear clears PBR environment (fills by white color)"
14530 "\n\t\t: -generate generates PBR environment from current background cubemap",
14531 __FILE__, VPBREnvironment, group);
14532 theCommands.Add("vraytrace",
14534 "\n\t\t: Turns on/off ray-tracing renderer."
14535 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
14536 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
14537 __FILE__, VRenderParams, group);
14538 theCommands.Add("vrenderparams",
14539 "\n Manages rendering parameters: "
14540 "\n '-raster' Disables GPU ray-tracing"
14541 "\n '-msaa 0..4' Specifies number of samples for MSAA"
14542 "\n '-lineFeather > 0' Sets line feather factor"
14543 "\n '-oit off|0.0-1.0' Enables/disables OIT and sets depth weight factor"
14544 "\n '-depthPrePass on|off' Enables/disables depth pre-pass"
14545 "\n '-alphatocoverage on|off' Enables/disables alpha to coverage (needs MSAA)"
14546 "\n '-rendScale value Rendering resolution scale factor"
14547 "\n '-rayTrace' Enables GPU ray-tracing"
14548 "\n '-rayDepth 0..10' Defines maximum ray-tracing depth"
14549 "\n '-shadows on|off' Enables/disables shadows rendering"
14550 "\n '-reflections on|off' Enables/disables specular reflections"
14551 "\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
14552 "\n '-gleam on|off' Enables/disables transparency shadow effects"
14553 "\n '-gi on|off' Enables/disables global illumination effects"
14554 "\n '-brng on|off' Enables/disables blocked RNG (fast coherent PT)"
14555 "\n '-env on|off' Enables/disables environment map background"
14556 "\n '-ignoreNormalMap on|off' Enables/disables normal map ignoring during path tracing"
14557 "\n '-twoside on|off' Enables/disables two-sided BSDF models (PT mode)"
14558 "\n '-iss on|off' Enables/disables adaptive screen sampling (PT mode)"
14559 "\n '-issd on|off' Shows screen sampling distribution in ISS mode"
14560 "\n '-maxrad > 0.0' Value used for clamping radiance estimation (PT mode)"
14561 "\n '-tileSize 1..4096' Specifies size of screen tiles in ISS mode (32 by default)"
14562 "\n '-nbtiles 64..1024' Specifies number of screen tiles per Redraw in ISS mode (256 by default)"
14563 "\n '-rebuildGlsl on|off' Rebuild Ray-Tracing GLSL programs (for debugging)"
14564 "\n '-shadingModel model' Controls shading model from enumeration"
14565 "\n unlit, flat, gouraud, phong"
14566 "\n '-pbrEnvPow2size > 0' Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)"
14567 "\n '-pbrEnvSMLN > 1' Controls number of mipmap levels used in specular IBL map"
14568 "\n '-pbrEnvBDSN > 0' Controls number of samples in Monte-Carlo integration during diffuse IBL map's sherical harmonics calculation"
14569 "\n '-pbrEnvBSSN > 0' Controls maximum number of samples per mipmap level in Monte-Carlo integration during specular IBL maps generation"
14570 "\n '-pbrEnvBP [0, 1]' Controls strength of samples number reducing during specular IBL maps generation (1 disables reducing)"
14571 "\n '-resolution value' Sets a new pixels density (PPI), defines scaling factor for parameters like text size"
14572 "\n '-aperture >= 0.0' Aperture size of perspective camera for depth-of-field effect (0 disables DOF)"
14573 "\n '-focal >= 0.0' Focal distance of perspective camera for depth-of-field effect"
14574 "\n '-exposure value' Exposure value for tone mapping (0.0 value disables the effect)"
14575 "\n '-whitepoint value' White point value for filmic tone mapping"
14576 "\n '-tonemapping mode' Tone mapping mode (disabled, filmic)"
14577 "\n '-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
14578 "\n ' |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate'"
14579 "\n Show/hide performance counters (flags can be combined)"
14580 "\n '-perfUpdateInterval nbSeconds' Performance counters update interval"
14581 "\n '-perfChart nbFrames' Show frame timers chart limited by specified number of frames"
14582 "\n '-perfChartMax seconds' Maximum time in seconds with the chart"
14583 "\n '-frustumCulling on|off|noupdate' Enable/disable objects frustum clipping or"
14584 "\n set state to check structures culled previously."
14585 "\n Unlike vcaps, these parameters dramatically change visual properties."
14586 "\n Command is intended to control presentation quality depending on"
14587 "\n hardware capabilities and performance.",
14588 __FILE__, VRenderParams, group);
14589 theCommands.Add("vstatprofiler",
14590 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
14591 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
14592 "\n |triangles|points|geomMem|textureMem|frameMem"
14593 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
14594 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
14596 "\n\t\t: Prints rendering statistics."
14597 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
14598 "\n\t\t: else - print all performance counters set previously."
14599 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
14600 __FILE__, VStatProfiler, group);
14601 theCommands.Add ("vplace",
14603 "\n\t\t: Places the point (in pixels) at the center of the window",
14604 __FILE__, VPlace, group);
14605 theCommands.Add("vxrotate",
14607 __FILE__,VXRotate,group);
14609 theCommands.Add("vmanipulator",
14610 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
14611 "\n tool to create and manage AIS manipulators."
14613 "\n '-attach AISObject' attach manipulator to AISObject"
14614 "\n '-adjustPosition {0|1}' adjust position when attaching"
14615 "\n '-adjustSize {0|1}' adjust size when attaching"
14616 "\n '-enableModes {0|1}' enable modes when attaching"
14617 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
14618 "\n by default it is displayed in all views of the current viewer"
14619 "\n '-detach' detach manipulator"
14620 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
14621 "\n '-transform mouse_x mouse_y' - invoke transformation"
14622 "\n '-stopTransform [abort]' - invoke stop of transformation"
14623 "\n '-move x y z' - move attached object"
14624 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
14625 "\n '-scale factor' - scale attached object"
14626 "\n '-autoActivate {0|1}' - set activation on detection"
14627 "\n '-followTranslation {0|1}' - set following translation transform"
14628 "\n '-followRotation {0|1}' - set following rotation transform"
14629 "\n '-followDragging {0|1}' - set following dragging transform"
14630 "\n '-gap value' - set gap between sub-parts"
14631 "\n '-part axis mode {0|1}' - set visual part"
14632 "\n '-parts axis mode {0|1}' - set visual part"
14633 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
14634 "\n '-size value' - set size of manipulator"
14635 "\n '-zoomable {0|1}' - set zoom persistence",
14636 __FILE__, VManipulator, group);
14638 theCommands.Add("vselprops",
14639 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
14640 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
14641 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
14642 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
14643 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14644 "\n -pickStrategy {first|topmost} : defines picking strategy"
14645 "\n 'first' to pick first acceptable (default)"
14646 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
14647 "\n -pixTol value : sets up pixel tolerance"
14648 "\n -dispMode dispMode : sets display mode for highlighting"
14649 "\n -layer ZLayer : sets ZLayer for highlighting"
14650 "\n -color {name|r g b} : sets highlight color"
14651 "\n -transp value : sets transparency coefficient for highlight"
14652 "\n -material material : sets highlight material"
14653 "\n -print : prints current state of all mentioned parameters",
14654 __FILE__, VSelectionProperties, group);
14655 theCommands.Add ("vhighlightselected",
14656 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
14657 __FILE__, VSelectionProperties, group);
14659 theCommands.Add ("vseldump",
14660 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
14661 "\n\t\t: Generate an image based on detection results:"
14662 "\n\t\t: depth normalized depth values"
14663 "\n\t\t: unnormDepth unnormalized depth values"
14664 "\n\t\t: object color of detected object"
14665 "\n\t\t: owner color of detected owner"
14666 "\n\t\t: selMode color of selection mode"
14667 "\n\t\t: entity color of etected entity",
14668 __FILE__, VDumpSelectionImage, group);
14670 theCommands.Add ("vviewcube",
14672 "\n\t\t: Displays interactive view manipualtion object."
14673 "\n\t\t: Options: "
14674 "\n\t\t: -reset reset geomertical and visual attributes'"
14675 "\n\t\t: -size Size adapted size of View Cube"
14676 "\n\t\t: -boxSize Size box size"
14677 "\n\t\t: -axes {0|1 } show/hide axes (trihedron)"
14678 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
14679 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
14680 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
14681 "\n\t\t: -color Color color of View Cube"
14682 "\n\t\t: -boxColor Color box color"
14683 "\n\t\t: -boxSideColor Color box sides color"
14684 "\n\t\t: -boxEdgeColor Color box edges color"
14685 "\n\t\t: -boxCornerColor Color box corner color"
14686 "\n\t\t: -textColor Color color of side text of view cube"
14687 "\n\t\t: -innerColor Color inner box color"
14688 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
14689 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
14690 "\n\t\t: -font Name font name"
14691 "\n\t\t: -fontHeight Value font height"
14692 "\n\t\t: -boxFacetExtension Value box facet extension"
14693 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
14694 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
14695 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
14696 "\n\t\t: -axesPadding Value padding between box and arrows"
14697 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
14698 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
14699 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
14700 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
14701 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
14702 "\n\t\t: -duration Seconds animation duration in seconds",
14703 __FILE__, VViewCube, group);
14705 theCommands.Add("vcolorconvert" ,
14706 "vcolorconvert {from|to} type C1 C2 C2"
14707 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
14708 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
14709 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
14710 __FILE__,VColorConvert,group);
14711 theCommands.Add("vcolordiff" ,
14712 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
14713 __FILE__,VColorDiff,group);