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.
21 #include <ViewerTest.hxx>
23 #include <AIS_AnimationCamera.hxx>
24 #include <AIS_AnimationObject.hxx>
25 #include <AIS_Axis.hxx>
26 #include <AIS_CameraFrustum.hxx>
27 #include <AIS_ColorScale.hxx>
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_LightSource.hxx>
30 #include <AIS_ListOfInteractive.hxx>
31 #include <AIS_ListIteratorOfListOfInteractive.hxx>
32 #include <AIS_Manipulator.hxx>
33 #include <AIS_ViewCube.hxx>
34 #include <AIS_Shape.hxx>
35 #include <AIS_Point.hxx>
36 #include <Aspect_DisplayConnection.hxx>
37 #include <Aspect_Grid.hxx>
38 #include <Aspect_TypeOfLine.hxx>
40 #include <Draw_Appli.hxx>
41 #include <Draw_Interpretor.hxx>
42 #include <Draw_ProgressIndicator.hxx>
46 #include <Geom_Axis2Placement.hxx>
47 #include <Geom_CartesianPoint.hxx>
48 #include <Graphic3d_ArrayOfPolylines.hxx>
49 #include <Graphic3d_AspectFillArea3d.hxx>
50 #include <Graphic3d_AspectMarker3d.hxx>
51 #include <Graphic3d_ClipPlane.hxx>
52 #include <Graphic3d_CubeMapPacked.hxx>
53 #include <Graphic3d_CubeMapSeparate.hxx>
54 #include <Graphic3d_GraduatedTrihedron.hxx>
55 #include <Graphic3d_GraphicDriver.hxx>
56 #include <Graphic3d_GraphicDriverFactory.hxx>
57 #include <Graphic3d_NameOfTextureEnv.hxx>
58 #include <Graphic3d_Texture2Dmanual.hxx>
59 #include <Graphic3d_TextureEnv.hxx>
60 #include <Graphic3d_TextureParams.hxx>
61 #include <Graphic3d_TypeOfTextureFilter.hxx>
62 #include <Image_AlienPixMap.hxx>
63 #include <Image_Diff.hxx>
64 #include <Image_VideoRecorder.hxx>
65 #include <Message.hxx>
66 #include <Message_ProgressScope.hxx>
67 #include <Message_ProgressRange.hxx>
68 #include <NCollection_DataMap.hxx>
69 #include <NCollection_List.hxx>
70 #include <NCollection_LocalArray.hxx>
71 #include <NCollection_Vector.hxx>
73 #include <OSD_Parallel.hxx>
74 #include <OSD_Timer.hxx>
75 #include <Prs3d_ShadingAspect.hxx>
76 #include <Prs3d_DatumAspect.hxx>
77 #include <Prs3d_Drawer.hxx>
78 #include <Prs3d_LineAspect.hxx>
79 #include <Prs3d_Text.hxx>
80 #include <Select3D_SensitivePrimitiveArray.hxx>
81 #include <TColStd_HSequenceOfAsciiString.hxx>
82 #include <TColStd_SequenceOfInteger.hxx>
83 #include <TColStd_HSequenceOfReal.hxx>
84 #include <TColgp_Array1OfPnt2d.hxx>
85 #include <TColStd_MapOfAsciiString.hxx>
86 #include <ViewerTest_AutoUpdater.hxx>
87 #include <ViewerTest_ContinuousRedrawer.hxx>
88 #include <ViewerTest_EventManager.hxx>
89 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
90 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
91 #include <ViewerTest_CmdParser.hxx>
92 #include <ViewerTest_V3dView.hxx>
93 #include <V3d_AmbientLight.hxx>
94 #include <V3d_DirectionalLight.hxx>
95 #include <V3d_PositionalLight.hxx>
96 #include <V3d_SpotLight.hxx>
97 #include <V3d_Trihedron.hxx>
98 #include <V3d_Viewer.hxx>
99 #include <UnitsAPI.hxx>
106 #include <WNT_WClass.hxx>
107 #include <WNT_Window.hxx>
108 #include <WNT_HIDSpaceMouse.hxx>
109 #elif defined(HAVE_XLIB)
110 #include <Xw_Window.hxx>
111 #include <X11/Xlib.h>
112 #include <X11/Xutil.h>
113 #elif defined(__APPLE__)
114 #include <Cocoa_Window.hxx>
115 #elif defined(__EMSCRIPTEN__)
116 #include <Wasm_Window.hxx>
117 #include <emscripten/emscripten.h>
119 #include <Aspect_NeutralWindow.hxx>
122 //==============================================================================
123 // VIEWER GLOBAL VARIABLES
124 //==============================================================================
126 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
127 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
129 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
130 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
133 typedef WNT_Window ViewerTest_Window;
134 #elif defined(HAVE_XLIB)
135 typedef Xw_Window ViewerTest_Window;
136 static void VProcessEvents(ClientData,int);
137 #elif defined(__APPLE__)
138 typedef Cocoa_Window ViewerTest_Window;
139 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
140 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
141 #elif defined(__EMSCRIPTEN__)
142 typedef Wasm_Window ViewerTest_Window;
144 typedef Aspect_NeutralWindow ViewerTest_Window;
147 #if defined(__EMSCRIPTEN__)
148 //! Return DOM id of default WebGL canvas from Module.canvas.
149 EM_JS(char*, occJSModuleCanvasId, (), {
150 const aCanvasId = Module.canvas.id;
151 const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
152 const aStrPtr = Module._malloc (aNbBytes);
153 stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
157 //! Return DOM id of default WebGL canvas from Module.canvas.
158 static TCollection_AsciiString getModuleCanvasId()
160 char* aRawId = occJSModuleCanvasId();
161 TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
167 static Handle(ViewerTest_Window)& VT_GetWindow()
169 static Handle(ViewerTest_Window) aWindow;
173 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
175 static Handle(Aspect_DisplayConnection) aDisplayConnection;
176 return aDisplayConnection;
179 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
181 GetDisplayConnection() = theDisplayConnection;
184 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
185 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
186 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
190 Quantity_Color FlatColor;
191 Quantity_Color GradientColor1;
192 Quantity_Color GradientColor2;
193 Aspect_GradientFillMethod FillMethod;
194 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
196 //==============================================================================
197 // EVENT GLOBAL VARIABLES
198 //==============================================================================
203 //! Checks if some set is a subset of other set
204 //! @tparam TheSuperSet the type of the superset
205 //! @tparam TheSubSet the type of the subset
206 //! @param theSuperSet the superset
207 //! @param theSubSet the subset to be checked
208 //! @return true if the superset includes subset, or false otherwise
209 template <typename TheSuperSet, typename TheSubSet>
210 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
212 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
215 //! A variable set of keys for command-line options.
216 //! It includes a set of mandatory keys and a set of all possible keys.
217 class CommandOptionKeyVariableSet
220 //! Default constructor
221 CommandOptionKeyVariableSet()
226 //! @param theMandatoryKeySet the set of the mandatory option keys
227 //! @param theAdditionalKeySet the set of additional options that could be omitted
228 CommandOptionKeyVariableSet (
229 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
230 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
231 : myMandatoryKeySet (theMandatoryKeySet)
233 std::set_union (theMandatoryKeySet.begin(),
234 theMandatoryKeySet.end(),
235 theAdditionalKeySet.begin(),
236 theAdditionalKeySet.end(),
237 std::inserter (myFullKeySet, myFullKeySet.begin()));
240 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
241 //! and be contained in the full key set)
242 //! @param theCheckedKeySet the set of option keys to be checked
243 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
245 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
249 //! A set of mandatory command-line option keys
250 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
252 //! A full set of command-line option keys (includes mandatory and additional option keys)
253 ViewerTest_CommandOptionKeySet myFullKeySet;
256 //! Gets some code by its name
257 //! @tparam TheCode the type of a code to be found
258 //! @param theCodeNameMap the map from code names to codes
259 //! @param theCodeName the name of a code to be found
260 //! @param theCode the code to be found
261 //! @return true if a code is found, or false otherwise
262 template <typename TheCode>
263 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
264 TCollection_AsciiString theCodeName,
267 theCodeName.LowerCase();
268 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
270 if (aCodeIterator == theCodeNameMap.end())
274 theCode = aCodeIterator->second;
278 // Defines possible commands related to background changing
279 enum BackgroundCommand
281 BackgroundCommand_Main, //!< The main command that manages other commands through options
282 BackgroundCommand_Image, //!< Sets an image as a background
283 BackgroundCommand_ImageMode, //!< Changes a background image mode
284 BackgroundCommand_Gradient, //!< Sets a gradient as a background
285 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
286 BackgroundCommand_Color, //!< Fills background with a specified color
287 BackgroundCommand_Default //!< Sets the background default color or gradient
290 //! Map from background command names to its codes
291 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
293 //! Creates a map from background command names to its codes
294 //! @return a map from background command names to its codes
295 static BackgroundCommandNameMap createBackgroundCommandNameMap()
297 BackgroundCommandNameMap aBackgroundCommandNameMap;
298 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
299 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
300 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
301 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
302 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
303 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
304 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
305 return aBackgroundCommandNameMap;
308 //! Gets a background command by its name
309 //! @param theBackgroundCommandName the name of the background command
310 //! @param theBackgroundCommand the background command to be found
311 //! @return true if a background command is found, or false otherwise
312 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
313 BackgroundCommand& theBackgroundCommand)
315 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
316 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
319 //! Map from background image fill method names to its codes
320 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
322 //! Creates a map from background image fill method names to its codes
323 //! @return a map from background image fill method names to its codes
324 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
326 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
327 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
328 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
329 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
330 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
331 return aBackgroundImageFillMethodNameMap;
334 //! Gets a background image fill method by its name
335 //! @param theBackgroundImageFillMethodName the name of the background image fill method
336 //! @param theBackgroundImageFillMethod the background image fill method to be found
337 //! @return true if a background image fill method is found, or false otherwise
338 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
339 Aspect_FillMethod& theBackgroundImageFillMethod)
341 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
342 createBackgroundImageFillMethodNameMap();
343 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
344 theBackgroundImageFillMethodName,
345 theBackgroundImageFillMethod);
348 //! Map from background gradient fill method names to its codes
349 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
351 //! Creates a map from background gradient fill method names to its codes
352 //! @return a map from background gradient fill method names to its codes
353 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
355 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
356 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
357 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
358 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
359 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
360 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
361 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
362 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
363 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
364 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
365 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
366 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
367 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
368 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
369 return aBackgroundGradientFillMethodNameMap;
372 //! Gets a gradient fill method by its name
373 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
374 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
375 //! @return true if a gradient fill method is found, or false otherwise
376 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
377 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
379 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
380 createBackgroundGradientFillMethodNameMap();
381 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
382 theBackgroundGradientFillMethodName,
383 theBackgroundGradientFillMethod);
386 //! Changes the background in accordance with passed command line options
387 class BackgroundChanger
390 //! Constructor. Prepares the command parser
393 prepareCommandParser();
396 //! Processes the command line and changes the background
397 //! @param theDrawInterpretor the interpreter of the Draw Harness application
398 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
399 //! @param theCommandLineArguments the array of command line arguments
400 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
401 const Standard_Integer theNumberOfCommandLineArguments,
402 const char* const* const theCommandLineArguments)
404 const char* const aBackgroundCommandName = theCommandLineArguments[0];
405 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
406 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
410 addCommandDescription (aBackgroundCommand);
411 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
412 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
416 //! The type of functions that are able to set gradient background filling
417 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
418 const Quantity_Color& /* theColor2 */,
419 const Aspect_GradientFillMethod /* theGradientMode */);
421 //! The type of functions that are able to fill a background with a specific color
422 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
424 //! the command parser used to parse command line options and its arguments
425 ViewerTest_CmdParser myCommandParser;
427 //! the option key for the command that sets an image as a background
428 ViewerTest_CommandOptionKey myImageOptionKey;
430 //! the option key for the command that sets a background image fill type
431 ViewerTest_CommandOptionKey myImageModeOptionKey;
433 //! the option key for the command that sets a gradient filling for the background
434 ViewerTest_CommandOptionKey myGradientOptionKey;
436 //! the option key for the command that sets a background gradient filling method
437 ViewerTest_CommandOptionKey myGradientModeOptionKey;
439 //! the option key for the command that fills background with a specific color
440 ViewerTest_CommandOptionKey myColorOptionKey;
442 //! the option key for the command that sets default background gradient or color
443 ViewerTest_CommandOptionKey myDefaultOptionKey;
445 //! the option key for the command that sets an environment cubemap as a background
446 ViewerTest_CommandOptionKey myCubeMapOptionKey;
448 //! the option key for the command that defines order of tiles in one image packed cubemap
449 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
451 //! the option key for the command that sets inversion of Z axis for background cubemap
452 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
454 //! the option key for the command that allows skip IBL map generation
455 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
457 //! the variable set of options that are allowed for the old scenario (without any option passed)
458 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
460 //! the variable set of options that are allowed for setting an environment cubemap as background
461 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
463 //! the variable set of options that are allowed for setting an image as a background
464 CommandOptionKeyVariableSet myImageOptionVariableSet;
466 //! the variable set of options that are allowed for setting a background image fill type
467 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
469 //! the variable set of options that are allowed for setting a gradient filling for the background
470 CommandOptionKeyVariableSet myGradientOptionVariableSet;
472 //! the variable set of options that are allowed for setting a background gradient filling method
473 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
475 //! the variable set of options that are allowed for filling a background with a specific color
476 CommandOptionKeyVariableSet myColorOptionVariableSet;
478 //! the variable set of options that are allowed for setting a default background gradient
479 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
481 //! the variable set of options that are allowed for setting a default background color
482 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
484 //! the variable set of options that are allowed for printing help
485 CommandOptionKeyVariableSet myHelpOptionVariableSet;
487 //! Adds options to command parser
488 void addOptionsToCommandParser()
490 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
491 "filename of image used as background");
492 myImageModeOptionKey = myCommandParser.AddOption (
493 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
494 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
495 "sets background gradient starting and ending colors");
496 myGradientModeOptionKey =
497 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
498 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
499 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
500 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
501 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
503 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
504 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
505 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
506 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
507 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
510 //! Creates option sets used to determine if a passed option set is valid or not
511 void createOptionSets()
513 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
514 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
515 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
517 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
518 aCubeMapOptionSet.insert (myCubeMapOptionKey);
519 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
520 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
521 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
522 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
523 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
525 ViewerTest_CommandOptionKeySet anImageOptionSet;
526 anImageOptionSet.insert (myImageOptionKey);
527 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
528 anImageModeOptionSet.insert (myImageModeOptionKey);
529 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
530 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
532 ViewerTest_CommandOptionKeySet aGradientOptionSet;
533 aGradientOptionSet.insert (myGradientOptionKey);
534 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
535 aGradientModeOptionSet.insert (myGradientModeOptionKey);
536 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
537 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
539 ViewerTest_CommandOptionKeySet aColorOptionSet;
540 aColorOptionSet.insert (myColorOptionKey);
541 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
543 aGradientOptionSet.insert (myDefaultOptionKey);
544 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
545 aColorOptionSet.insert (myDefaultOptionKey);
546 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
548 ViewerTest_CommandOptionKeySet aHelpOptionSet;
549 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
550 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
553 //! Prepares the command parser. Adds options and creates option sets used to determine
554 //! if a passed option set is valid or not
555 void prepareCommandParser()
557 addOptionsToCommandParser();
561 //! Adds a command description to the command parser
562 //! @param theBackgroundCommand the key of the command which description is added to the command parser
563 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
565 std::string aDescription;
566 bool isMainCommand = false;
567 switch (theBackgroundCommand)
569 case BackgroundCommand_Main:
570 aDescription = "Command: vbackground (changes background or some background settings)";
571 isMainCommand = true;
573 case BackgroundCommand_Image:
574 aDescription = "Command: vsetbg (loads image as a background)";
576 case BackgroundCommand_ImageMode:
577 aDescription = "Command: vsetbgmode (changes background fill type)";
579 case BackgroundCommand_Gradient:
580 aDescription = "Command: vsetgradientbg (mounts gradient background)";
582 case BackgroundCommand_GradientMode:
583 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
585 case BackgroundCommand_Color:
586 aDescription = "Command: vsetcolorbg (sets color background)";
588 case BackgroundCommand_Default:
589 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
596 aDescription += "\nThis command is obsolete. Use vbackground instead.";
598 myCommandParser.SetDescription (aDescription);
601 //! Check if a viewer is needed to be initialized
602 //! @param theBackgroundCommand the key of the command that changes the background
603 //! @return true if processing was successful, or false otherwise
604 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
606 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
607 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
608 const bool aViewerIsNotNeeded =
609 (theBackgroundCommand == BackgroundCommand_Default)
610 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
611 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
612 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
613 return !aViewerIsNotNeeded;
616 //! Check if a viewer is initialized
617 //! @param theBackgroundCommandName the name of the command that changes the background
618 //! @param theDrawInterpretor the interpreter of the Draw Harness application
619 //! @return true if a viewer is initialized, or false otherwise
620 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
621 Draw_Interpretor& theDrawInterpretor)
623 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
624 if (anAISContext.IsNull())
626 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
632 //! Processes command options
633 //! @param theBackgroundCommandName the name of the command that changes the background
634 //! @param theBackgroundCommand the key of the command that changes the background
635 //! @param theDrawInterpretor the interpreter of the Draw Harness application
636 //! @return true if processing was successful, or false otherwise
637 bool processCommandOptions (const char* const theBackgroundCommandName,
638 const BackgroundCommand theBackgroundCommand,
639 Draw_Interpretor& theDrawInterpretor) const
641 if (myCommandParser.HasNoOption())
643 return printHelp (theBackgroundCommandName, theDrawInterpretor);
645 if (checkViewerIsNeeded (theBackgroundCommand)
646 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
650 if (myCommandParser.HasOnlyUnnamedOption())
652 return processUnnamedOption (theBackgroundCommand);
654 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
657 //! Processes the unnamed option
658 //! @param theBackgroundCommand the key of the command that changes the background
659 //! @return true if processing was successful, or false otherwise
660 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
662 switch (theBackgroundCommand)
664 case BackgroundCommand_Main:
666 case BackgroundCommand_Image:
667 return processImageUnnamedOption();
668 case BackgroundCommand_ImageMode:
669 return processImageModeUnnamedOption();
670 case BackgroundCommand_Gradient:
671 return processGradientUnnamedOption();
672 case BackgroundCommand_GradientMode:
673 return processGradientModeUnnamedOption();
674 case BackgroundCommand_Color:
675 return processColorUnnamedOption();
676 case BackgroundCommand_Default:
677 return processDefaultUnnamedOption();
683 //! Processes the image unnamed option
684 //! @return true if processing was successful, or false otherwise
685 bool processImageUnnamedOption() const
687 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
688 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
689 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
693 std::string anImageFileName;
694 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
698 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
699 if (aNumberOfImageUnnamedOptionArguments == 2)
701 std::string anImageModeString;
702 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
706 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
711 setImage (anImageFileName.c_str(), anImageMode);
715 //! Processes the image mode unnamed option
716 //! @return true if processing was successful, or false otherwise
717 bool processImageModeUnnamedOption() const
719 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
722 //! Processes the gradient unnamed option
723 //! @param theSetGradient the function used to set a background gradient filling
724 //! @return true if processing was successful, or false otherwise
725 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
727 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
728 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
729 if (aNumberOfGradientUnnamedOptionArguments < 2)
734 Standard_Integer anArgumentIndex = 0;
735 Quantity_Color aColor1;
736 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
740 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
745 Quantity_Color aColor2;
746 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
750 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
755 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
756 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
758 std::string anGradientModeString;
760 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
762 anGradientModeString))
766 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
772 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
776 theSetGradient (aColor1, aColor2, aGradientMode);
780 //! Processes the gradient mode unnamed option
781 //! @return true if processing was successful, or false otherwise
782 bool processGradientModeUnnamedOption() const
784 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
787 //! Processes the color unnamed option
788 //! @param theSetColor the function used to set a background color
789 //! @return true if processing was successful, or false otherwise
790 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
792 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
795 //! Processes the default back unnamed option
796 //! @return true if processing was successful, or false otherwise
797 bool processDefaultUnnamedOption() const
799 if (processGradientUnnamedOption (setDefaultGradient))
803 return processColorUnnamedOption (setDefaultColor);
806 //! Processes named options
807 //! @param theBackgroundCommandName the name of the command that changes the background
808 //! @param theBackgroundCommand the key of the command that changes the background
809 //! @param theDrawInterpretor the interpreter of the Draw Harness application
810 //! @return true if processing was successful, or false otherwise
811 bool processNamedOptions (const char* const theBackgroundCommandName,
812 const BackgroundCommand theBackgroundCommand,
813 Draw_Interpretor& theDrawInterpretor) const
815 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
816 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
817 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
819 return processCubeMapOptionSet();
821 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
822 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
824 return processImageOptionSet();
826 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
827 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
829 return processImageModeOptionSet();
831 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
832 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
834 return processGradientOptionSet();
836 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
837 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
839 return processGradientModeOptionSet();
841 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
842 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
844 return processColorOptionSet();
846 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
847 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
848 && (theBackgroundCommand == BackgroundCommand_Default)))
850 return processDefaultGradientOptionSet();
852 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
853 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
855 return processDefaultColorOptionSet();
857 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
859 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
864 //! Process the cubemap option set in named and unnamed case.
865 //! @return true if processing was successful, or false otherwise
866 bool processCubeMapOptionSet() const
868 NCollection_Array1<TCollection_AsciiString> aFilePaths;
870 if (!processCubeMapOptions (aFilePaths))
875 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
877 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
879 if (!processCubeMapOrderOptions (anOrder))
885 bool aZIsInverted = false;
886 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
888 if (!processCubeMapInvertedZOptionSet())
895 bool aToGenPBREnv = true;
896 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
898 if (!processCubeMapDoNotGenPBREnvOptionSet())
902 aToGenPBREnv = false;
905 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
909 //! Processes the image option set
910 //! @return true if processing was successful, or false otherwise
911 bool processImageOptionSet() const
913 std::string anImageFileName;
914 if (!processImageOption (anImageFileName))
918 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
919 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
923 setImage (anImageFileName.c_str(), anImageMode);
927 //! Processes the image mode option set
928 //! @return true if processing was successful, or false otherwise
929 bool processImageModeOptionSet() const
931 return processImageModeOptionSet (myImageModeOptionKey);
934 //! Processes the image mode option set
935 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
936 //! @return true if processing was successful, or false otherwise
937 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
939 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
940 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
944 setImageMode (anImageMode);
948 //! Processes the gradient option set
949 //! @param theSetGradient the function used to set a background gradient filling
950 //! @return true if processing was successful, or false otherwise
951 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
953 Quantity_Color aColor1;
954 Quantity_Color aColor2;
955 if (!processGradientOption (aColor1, aColor2))
959 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
960 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
964 theSetGradient (aColor1, aColor2, aGradientMode);
968 //! Processes the gradient mode option set
969 //! @return true if processing was successful, or false otherwise
970 bool processGradientModeOptionSet() const
972 return processGradientModeOptionSet (myGradientModeOptionKey);
975 //! Processes the gradient mode option set
976 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
977 //! @return true if processing was successful, or false otherwise
978 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
980 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
981 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
985 setGradientMode (aGradientMode);
989 //! Processes the color option set
990 //! @param theSetColor the function used to set a background color
991 //! @return true if processing was successful, or false otherwise
992 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
994 return processColorOptionSet (myColorOptionKey, theSetColor);
997 //! Processes the default color option set
998 //! @return true if processing was successful, or false otherwise
999 bool processDefaultGradientOptionSet() const
1001 return processGradientOptionSet (setDefaultGradient);
1004 //! Processes the default gradient option set
1005 //! @return true if processing was successful, or false otherwise
1006 bool processDefaultColorOptionSet() const
1008 return processColorOptionSet (setDefaultColor);
1011 //! Processes the color option set
1012 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1013 //! @param theSetColor the function used to set a background color
1014 //! @return true if processing was successful, or false otherwise
1015 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
1016 SetColorFunction* const theSetColor = setColor) const
1018 Quantity_Color aColor;
1019 if (!processColorOption (theColorOptionKey, aColor))
1023 theSetColor (aColor);
1027 //! Processes the help option set
1028 //! @param theBackgroundCommandName the name of the command that changes the background
1029 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1030 //! @return true if processing was successful, or false otherwise
1031 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1033 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1034 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1035 if (aNumberOfHelpOptionArguments != 0)
1039 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1042 //! Processes the cubemap option
1043 //! @param theFilePaths the array of filenames of cubemap sides
1044 //! @return true if processing was successful, or false otherwise
1045 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1047 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1049 if (aNumberOfCubeMapOptionArguments != 1
1050 && aNumberOfCubeMapOptionArguments != 6)
1055 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1057 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1059 std::string aCubeMapFileName;
1060 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1064 theFilePaths[i] = aCubeMapFileName.c_str();
1070 //! Processes the inverted z cubemap option
1071 //! @return true if processing was successful, or false otherwise
1072 bool processCubeMapInvertedZOptionSet () const
1074 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1075 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1077 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1085 //! Processes the option allowing to skip IBM maps generation
1086 //! @return true if processing was successful, or false otherwise
1087 bool processCubeMapDoNotGenPBREnvOptionSet() const
1089 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1090 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1092 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1100 //! Processes the tiles order option
1101 //! @param theOrder the array of indexes if cubemap sides in tile grid
1102 //! @return true if processing was successful, or false otherwise
1103 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1105 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1106 myCubeMapOrderOptionKey);
1108 if (aNumberOfCubeMapOrderOptionArguments != 6)
1114 for (unsigned int i = 0; i < 6; ++i)
1116 std::string anOrderItem;
1117 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1122 theOrder.Set (Graphic3d_CubeMapSide (i),
1123 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1126 return theOrder.IsValid();
1129 //! Processes the image option
1130 //! @param theImageFileName the filename of the image to be used as a background
1131 //! @return true if processing was successful, or false otherwise
1132 bool processImageOption (std::string& theImageFileName) const
1134 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1136 if (aNumberOfImageOptionArguments != 1)
1140 std::string anImageFileName;
1141 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1145 theImageFileName = anImageFileName;
1149 //! Processes the image mode option
1150 //! @param theImageMode the fill type used for a background image
1151 //! @return true if processing was successful, or false otherwise
1152 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1154 return processImageModeOption (myImageModeOptionKey, theImageMode);
1157 //! Processes the image mode option
1158 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1159 //! @param theImageMode the fill type used for a background image
1160 //! @return true if processing was successful, or false otherwise
1161 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1162 Aspect_FillMethod& theImageMode) const
1164 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1167 //! Processes the gradient option
1168 //! @param theColor1 the gradient starting color
1169 //! @param theColor2 the gradient ending color
1170 //! @return true if processing was successful, or false otherwise
1171 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1173 Standard_Integer anArgumentIndex = 0;
1174 Quantity_Color aColor1;
1175 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1179 Quantity_Color aColor2;
1180 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1184 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1185 myGradientOptionKey);
1186 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1190 theColor1 = aColor1;
1191 theColor2 = aColor2;
1195 //! Processes the gradient mode option
1196 //! @param theGradientMode the fill method used for a background gradient filling
1197 //! @return true if processing was successful, or false otherwise
1198 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1200 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1203 //! Processes the gradient mode option
1204 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1205 //! @param theGradientMode the fill method used for a background gradient filling
1206 //! @return true if processing was successful, or false otherwise
1207 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1208 Aspect_GradientFillMethod& theGradientMode) const
1210 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1213 //! Processes some mode option
1214 //! @tparam TheMode the type of a mode to be processed
1215 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1216 //! @param theMode a mode to be processed
1217 //! @return true if processing was successful, or false otherwise
1218 template <typename TheMode>
1219 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1220 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1221 TheMode& /* theMode */),
1222 TheMode& theMode) const
1224 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1226 if (aNumberOfModeOptionArguments != 1)
1230 std::string aModeString;
1231 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1235 TheMode aMode = TheMode();
1236 if (!theGetModeByName (aModeString.c_str(), aMode))
1244 //! Processes the color option
1245 //! @param theColor a color used for filling a background
1246 //! @return true if processing was successful, or false otherwise
1247 bool processColorOption (Quantity_Color& theColor) const
1249 return processColorOption (myColorOptionKey, theColor);
1252 //! Processes the color option
1253 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1254 //! @param theColor a color used for filling a background
1255 //! @return true if processing was successful, or false otherwise
1256 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1258 Standard_Integer anArgumentIndex = 0;
1259 Quantity_Color aColor;
1260 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1264 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1266 if (anArgumentIndex != aNumberOfColorOptionArguments)
1274 //! Prints helping message
1275 //! @param theBackgroundCommandName the name of the command that changes the background
1276 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1277 //! @return true if printing was successful, or false otherwise
1278 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1280 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1283 //! Sets the cubemap as a background
1284 //! @param theFileNames the array of filenames of packed or multifile cubemap
1285 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1286 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1287 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
1288 bool theZIsInverted = false,
1289 bool theToGenPBREnv = true)
1291 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1292 Handle(Graphic3d_CubeMap) aCubeMap;
1294 if (theFileNames.Size() == 1)
1295 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1297 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1299 aCubeMap->SetZInversion (theZIsInverted);
1301 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1302 aCubeMap->GetParams()->SetRepeat(Standard_False);
1303 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1305 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
1308 //! Sets the image as a background
1309 //! @param theImageFileName the filename of the image to be used as a background
1310 //! @param theImageMode the fill type used for a background image
1311 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1313 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1314 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1317 //! Sets the fill type used for a background image
1318 //! @param theImageMode the fill type used for a background image
1319 static void setImageMode (const Aspect_FillMethod theImageMode)
1321 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1322 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1325 //! Sets the gradient filling for a background
1326 //! @param theColor1 the gradient starting color
1327 //! @param theColor2 the gradient ending color
1328 //! @param theGradientMode the fill method used for a background gradient filling
1329 static void setGradient (const Quantity_Color& theColor1,
1330 const Quantity_Color& theColor2,
1331 const Aspect_GradientFillMethod theGradientMode)
1333 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1334 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1337 //! Sets the fill method used for a background gradient filling
1338 //! @param theGradientMode the fill method used for a background gradient filling
1339 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1341 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1342 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1345 //! Sets the color used for filling a background
1346 //! @param theColor the color used for filling a background
1347 static void setColor (const Quantity_Color& theColor)
1349 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1350 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1351 aCurrentView->SetBackgroundColor (theColor);
1352 aCurrentView->Update();
1355 //! Sets the gradient filling for a background in a default viewer
1356 //! @param theColor1 the gradient starting color
1357 //! @param theColor2 the gradient ending color
1358 //! @param theGradientMode the fill method used for a background gradient filling
1359 static void setDefaultGradient (const Quantity_Color& theColor1,
1360 const Quantity_Color& theColor2,
1361 const Aspect_GradientFillMethod theGradientMode)
1363 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1364 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1365 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1366 setDefaultGradient();
1369 //! Sets the color used for filling a background in a default viewer
1370 //! @param theColor the color used for filling a background
1371 static void setDefaultColor (const Quantity_Color& theColor)
1373 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1374 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1375 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1376 ViewerTest_DefaultBackground.FlatColor = theColor;
1377 setDefaultGradient();
1381 //! Sets the gradient filling for a background in a default viewer.
1382 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1383 static void setDefaultGradient()
1385 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1386 anInteractiveContextIterator (ViewerTest_myContexts);
1387 anInteractiveContextIterator.More();
1388 anInteractiveContextIterator.Next())
1390 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1391 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1392 ViewerTest_DefaultBackground.GradientColor2,
1393 ViewerTest_DefaultBackground.FillMethod);
1397 //! Sets the color used for filling a background in a default viewer.
1398 //! The color value is taken from ViewerTest_DefaultBackground structure
1399 static void setDefaultColor()
1401 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1402 anInteractiveContextIterator (ViewerTest_myContexts);
1403 anInteractiveContextIterator.More();
1404 anInteractiveContextIterator.Next())
1406 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1407 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1414 //==============================================================================
1417 static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
1420 //==============================================================================
1423 //==============================================================================
1425 const Handle(WNT_WClass)& ViewerTest::WClass()
1427 static Handle(WNT_WClass) theWClass;
1429 if (theWClass.IsNull())
1431 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
1432 CS_VREDRAW | CS_HREDRAW, 0, 0,
1433 ::LoadCursor (NULL, IDC_ARROW));
1439 //==============================================================================
1440 //function : CreateName
1441 //purpose : Create numerical name for new object in theMap
1442 //==============================================================================
1443 template <typename ObjectType>
1444 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1445 const TCollection_AsciiString& theDefaultString)
1447 if (theObjectMap.IsEmpty())
1448 return theDefaultString + TCollection_AsciiString(1);
1450 Standard_Integer aNextKey = 1;
1451 Standard_Boolean isFound = Standard_False;
1454 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1455 // Look for objects with default names
1456 if (theObjectMap.IsBound1(aStringKey))
1461 isFound = Standard_True;
1464 return theDefaultString + TCollection_AsciiString(aNextKey);
1467 //==============================================================================
1468 //structure : ViewerTest_Names
1469 //purpose : Allow to operate with full view name: driverName/viewerName/viewName
1470 //==============================================================================
1471 struct ViewerTest_Names
1474 TCollection_AsciiString myDriverName;
1475 TCollection_AsciiString myViewerName;
1476 TCollection_AsciiString myViewName;
1480 const TCollection_AsciiString& GetDriverName () const
1482 return myDriverName;
1484 void SetDriverName (const TCollection_AsciiString& theDriverName)
1486 myDriverName = theDriverName;
1488 const TCollection_AsciiString& GetViewerName () const
1490 return myViewerName;
1492 void SetViewerName (const TCollection_AsciiString& theViewerName)
1494 myViewerName = theViewerName;
1496 const TCollection_AsciiString& GetViewName () const
1500 void SetViewName (const TCollection_AsciiString& theViewName)
1502 myViewName = theViewName;
1505 //===========================================================================
1506 //function : Constructor for ViewerTest_Names
1507 //purpose : Get view, viewer, driver names from custom string
1508 //===========================================================================
1510 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1512 TCollection_AsciiString aName(theInputString);
1513 if (theInputString.IsEmpty())
1515 // Get current configuration
1516 if (ViewerTest_myDrivers.IsEmpty())
1517 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1518 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1520 myDriverName = ViewerTest_myDrivers.Find2
1521 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1523 if(ViewerTest_myContexts.IsEmpty())
1525 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1526 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1530 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
1533 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
1537 // There is at least view name
1538 Standard_Integer aParserNumber = 0;
1539 for (Standard_Integer i = 0; i < 3; ++i)
1541 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1542 if(aParserPos != -1)
1545 aName.Split(aParserPos-1);
1550 if (aParserNumber == 0)
1553 if (!ViewerTest::GetAISContext().IsNull())
1555 myDriverName = ViewerTest_myDrivers.Find2
1556 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1557 myViewerName = ViewerTest_myContexts.Find2
1558 (ViewerTest::GetAISContext());
1562 // There is no opened contexts here, need to create names for viewer and driver
1563 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1564 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1566 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1567 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1569 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1571 else if (aParserNumber == 1)
1573 // Here is viewerName/viewName
1574 if (!ViewerTest::GetAISContext().IsNull())
1575 myDriverName = ViewerTest_myDrivers.Find2
1576 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1579 // There is no opened contexts here, need to create name for driver
1580 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1581 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1583 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1585 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1589 //Here is driverName/viewerName/viewName
1590 myDriverName = TCollection_AsciiString(aName);
1592 TCollection_AsciiString aViewerName(theInputString);
1593 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1594 myViewerName = TCollection_AsciiString(aViewerName);
1596 myViewName = TCollection_AsciiString(theInputString);
1602 //==============================================================================
1603 //function : FindContextByView
1604 //purpose : Find AIS_InteractiveContext by View
1605 //==============================================================================
1607 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1609 Handle(AIS_InteractiveContext) anAISContext;
1611 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1612 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1614 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1615 return anIter.Key2();
1617 return anAISContext;
1620 //==============================================================================
1621 //function : IsWindowOverlapped
1622 //purpose : Check if theWindow overlapp another view
1623 //==============================================================================
1625 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1626 const Standard_Integer thePxTop,
1627 const Standard_Integer thePxRight,
1628 const Standard_Integer thePxBottom,
1629 TCollection_AsciiString& theViewId)
1631 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1632 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1634 Standard_Integer aTop = 0,
1638 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1639 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1640 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1641 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1642 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1644 theViewId = anIter.Key1();
1645 return Standard_True;
1648 return Standard_False;
1651 // Workaround: to create and delete non-orthographic views outside ViewerTest
1652 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1654 ViewerTest_myViews.UnBind1 (theName);
1657 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1658 const Handle(V3d_View)& theView)
1660 ViewerTest_myViews.Bind (theName, theView);
1663 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1665 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1668 //==============================================================================
1669 //function : ViewerInit
1670 //purpose : Create the window viewer and initialize all the global variable
1671 //==============================================================================
1673 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1674 const Standard_Integer thePxTop,
1675 const Standard_Integer thePxWidth,
1676 const Standard_Integer thePxHeight,
1677 const TCollection_AsciiString& theViewName,
1678 const TCollection_AsciiString& theDisplayName,
1679 const Handle(V3d_View)& theViewToClone,
1680 const Standard_Boolean theIsVirtual)
1682 // Default position and dimension of the viewer window.
1683 // Note that left top corner is set to be sufficiently small to have
1684 // window fit in the small screens (actual for remote desktops, see #23003).
1685 // The position corresponds to the window's client area, thus some
1686 // gap is added for window frame to be visible.
1687 Standard_Integer aPxLeft = 20, aPxTop = 40;
1688 Standard_Integer aPxWidth = 409, aPxHeight = 409;
1689 Standard_Boolean isDefViewSize = Standard_True;
1690 Standard_Boolean toCreateViewer = Standard_False;
1691 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
1692 if (!theViewToClone.IsNull())
1694 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1695 isDefViewSize = Standard_False;
1696 #if !defined(__EMSCRIPTEN__)
1697 (void )isDefViewSize;
1701 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1702 if (aFactory.IsNull())
1704 Draw::GetInterpretor().Eval ("pload OPENGL");
1705 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1706 if (aFactory.IsNull())
1708 Draw::GetInterpretor().Eval ("pload GLES");
1709 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1710 if (aFactory.IsNull())
1712 throw Standard_ProgramError("Error: no graphic driver factory found");
1717 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
1718 ViewerTest_Names aViewNames(theViewName);
1719 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1721 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1726 aPxLeft = thePxLeft;
1732 if (thePxWidth != 0)
1734 isDefViewSize = Standard_False;
1735 aPxWidth = thePxWidth;
1737 if (thePxHeight != 0)
1739 isDefViewSize = Standard_False;
1740 aPxHeight = thePxHeight;
1743 // Get graphic driver (create it or get from another view)
1744 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1747 // Get connection string
1748 #if defined(HAVE_XLIB)
1749 if (!theDisplayName.IsEmpty())
1751 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1755 Aspect_XDisplay* aDispX = NULL;
1756 // create dedicated display connection instead of reusing Tk connection
1757 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
1758 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1759 Tcl_Interp* aTclInterp = aCommands.Interp();
1760 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1761 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1762 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1765 (void)theDisplayName; // avoid warning on unused argument
1766 SetDisplayConnection (new Aspect_DisplayConnection ());
1769 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
1772 // don't waste the time waiting for VSync when window is not displayed on the screen
1773 aGraphicDriver->SetVerticalSync (false);
1776 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1777 toCreateViewer = Standard_True;
1781 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
1784 //Dispose the window if input parameters are default
1785 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
1787 Standard_Integer aTop = 0,
1794 // Get screen resolution
1797 GetClientRect(GetDesktopWindow(), &aWindowSize);
1798 aScreenHeight = aWindowSize.bottom;
1799 aScreenWidth = aWindowSize.right;
1800 #elif defined(HAVE_XLIB)
1801 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
1802 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
1803 aScreenWidth = WidthOfScreen(aScreen);
1804 aScreenHeight = HeightOfScreen(aScreen);
1805 #elif defined(__APPLE__)
1806 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1811 TCollection_AsciiString anOverlappedViewId("");
1813 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
1815 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1817 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1818 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1820 if (aBottom + aPxHeight + 40 > aScreenHeight)
1827 aPxTop = aBottom + 40;
1830 aPxLeft = aRight + 20;
1835 TCollection_AsciiString aTitle("3D View - ");
1836 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1838 // Change name of current active window
1839 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
1841 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
1845 Handle(V3d_Viewer) a3DViewer;
1846 // If it's the single view, we first look for empty context
1847 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1849 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1850 anIter(ViewerTest_myContexts);
1852 ViewerTest::SetAISContext (anIter.Value());
1853 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
1855 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1857 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1858 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
1860 else if (a3DViewer.IsNull())
1862 toCreateViewer = Standard_True;
1863 a3DViewer = new V3d_Viewer(aGraphicDriver);
1864 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1865 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1866 ViewerTest_DefaultBackground.GradientColor2,
1867 ViewerTest_DefaultBackground.FillMethod);
1870 // AIS context setup
1871 if (ViewerTest::GetAISContext().IsNull() ||
1872 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1874 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
1875 ViewerTest::SetAISContext (aContext);
1876 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1880 ViewerTest::ResetEventManager();
1885 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
1886 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
1888 aPxWidth, aPxHeight,
1889 Quantity_NOC_BLACK);
1890 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
1891 #elif defined(HAVE_XLIB)
1892 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1895 aPxWidth, aPxHeight);
1896 #elif defined(__APPLE__)
1897 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1899 aPxWidth, aPxHeight);
1900 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
1901 #elif defined(__EMSCRIPTEN__)
1902 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
1903 // the code should be revised for handling multiple canvas elements (which is technically also possible)
1904 TCollection_AsciiString aCanvasId = getModuleCanvasId();
1905 if (!aCanvasId.IsEmpty())
1907 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
1910 VT_GetWindow() = new Wasm_Window (aCanvasId);
1911 Graphic3d_Vec2i aRealSize;
1912 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
1913 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
1915 // Wasm_Window wraps an existing HTML element without creating a new one.
1916 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
1917 // but resize canvas if vinit has been called with explicitly specified dimensions.
1918 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxWidth, aPxHeight));
1922 VT_GetWindow() = new Aspect_NeutralWindow();
1923 VT_GetWindow()->SetSize (aPxWidth, aPxHeight);
1925 VT_GetWindow()->SetVirtual (isVirtual);
1928 Handle(V3d_View) aView;
1929 if (!theViewToClone.IsNull())
1931 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
1935 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
1938 aView->SetWindow (VT_GetWindow());
1939 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
1941 ViewerTest::CurrentView(aView);
1942 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
1944 // Setup for X11 or NT
1945 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1946 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
1948 // Set parameters for V3d_View and V3d_Viewer
1949 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1950 aV3dView->SetComputedMode(Standard_False);
1952 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1955 a3DViewer->SetDefaultLights();
1956 a3DViewer->SetLightOn();
1959 #if defined(HAVE_XLIB)
1962 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
1963 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1967 VT_GetWindow()->Map();
1969 // Set the handle of created view in the event manager
1970 ViewerTest::ResetEventManager();
1972 ViewerTest::CurrentView()->Redraw();
1975 a3DViewer.Nullify();
1977 return aViewNames.GetViewName();
1980 //==============================================================================
1981 //function : RedrawAllViews
1982 //purpose : Redraw all created views
1983 //==============================================================================
1984 void ViewerTest::RedrawAllViews()
1986 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1987 for (; aViewIt.More(); aViewIt.Next())
1989 const Handle(V3d_View)& aView = aViewIt.Key2();
1994 //==============================================================================
1995 //function : VDriver
1997 //==============================================================================
1998 static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2002 theDi << "Registered: ";
2003 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2004 aFactoryIter.More(); aFactoryIter.Next())
2006 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2007 theDi << aFactory->Name() << " ";
2011 theDi << "Default: ";
2012 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2014 theDi << aFactory->Name();
2023 TCollection_AsciiString aNewActive;
2024 bool toLoad = false;
2025 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
2027 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2028 anArgCase.LowerCase();
2029 if (anArgCase == "-list")
2031 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2032 aFactoryIter.More(); aFactoryIter.Next())
2034 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2035 theDi << aFactory->Name() << " ";
2038 else if ((anArgCase == "-default"
2039 || anArgCase == "-load")
2040 && aNewActive.IsEmpty())
2042 toLoad = (anArgCase == "-load");
2043 if (anArgIter + 1 < theArgsNb)
2045 aNewActive = theArgVec[++anArgIter];
2049 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
2054 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2056 theDi << aFactory->Name();
2064 else if (aNewActive.IsEmpty())
2066 aNewActive = theArgVec[anArgIter];
2070 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
2075 if (!aNewActive.IsEmpty())
2077 const TCollection_AsciiString aNameCopy = aNewActive;
2078 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
2079 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
2080 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
2082 aNewActive = "tkopengl";
2084 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
2085 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
2086 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
2088 aNewActive = "tkopengles";
2090 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
2091 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
2092 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
2094 aNewActive = "tkd3dhost";
2099 if (aNewActive == "tkopengl")
2101 Draw::GetInterpretor().Eval ("pload OPENGL");
2103 else if (aNewActive == "tkopengles")
2105 Draw::GetInterpretor().Eval ("pload GLES");
2107 else if (aNewActive == "tkd3dhost")
2109 Draw::GetInterpretor().Eval ("pload D3DHOST");
2113 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
2118 bool isFound = false;
2119 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2120 aFactoryIter.More(); aFactoryIter.Next())
2122 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
2123 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
2125 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
2133 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
2141 //==============================================================================
2143 //purpose : Create the window viewer and initialize all the global variable
2144 // Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
2145 //==============================================================================
2146 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2148 TCollection_AsciiString aViewName, aDisplayName;
2149 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
2150 Standard_Boolean isVirtual = false;
2151 Handle(V3d_View) aCopyFrom;
2152 TCollection_AsciiString aName, aValue;
2154 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
2156 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2157 TCollection_AsciiString anArgCase = anArg;
2158 anArgCase.LowerCase();
2159 if (anArgIt + 1 < theArgsNb
2160 && anArgCase == "-name")
2162 aViewName = theArgVec[++anArgIt];
2164 else if (anArgIt + 1 < theArgsNb
2165 && (anArgCase == "-left"
2166 || anArgCase == "-l"))
2168 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2170 else if (anArgIt + 1 < theArgsNb
2171 && (anArgCase == "-top"
2172 || anArgCase == "-t"))
2174 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2176 else if (anArgIt + 1 < theArgsNb
2177 && (anArgCase == "-width"
2178 || anArgCase == "-w"))
2180 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2182 else if (anArgIt + 1 < theArgsNb
2183 && (anArgCase == "-height"
2184 || anArgCase == "-h"))
2186 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2188 else if (anArgCase == "-virtual"
2189 || anArgCase == "-offscreen")
2192 if (anArgIt + 1 < theArgsNb
2193 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
2198 else if (anArgCase == "-exitonclose")
2200 ViewerTest_EventManager::ToExitOnCloseView() = true;
2201 if (anArgIt + 1 < theArgsNb
2202 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
2207 else if (anArgCase == "-closeonescape"
2208 || anArgCase == "-closeonesc")
2210 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
2211 if (anArgIt + 1 < theArgsNb
2212 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
2217 else if (anArgCase == "-2d_mode"
2218 || anArgCase == "-2dmode"
2219 || anArgCase == "-2d")
2221 bool toEnable = true;
2222 if (anArgIt + 1 < theArgsNb
2223 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2227 is2dMode = toEnable ? 1 : 0;
2229 else if (anArgIt + 1 < theArgsNb
2230 && (anArgCase == "-disp"
2231 || anArgCase == "-display"))
2233 aDisplayName = theArgVec[++anArgIt];
2235 else if (!ViewerTest::CurrentView().IsNull()
2236 && aCopyFrom.IsNull()
2237 && (anArgCase == "-copy"
2238 || anArgCase == "-clone"
2239 || anArgCase == "-cloneactive"
2240 || anArgCase == "-cloneactiveview"))
2242 aCopyFrom = ViewerTest::CurrentView();
2245 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2248 if (aName == "name")
2252 else if (aName == "l"
2255 aPxLeft = aValue.IntegerValue();
2257 else if (aName == "t"
2260 aPxTop = aValue.IntegerValue();
2262 else if (aName == "disp"
2263 || aName == "display")
2265 aDisplayName = aValue;
2267 else if (aName == "w"
2268 || aName == "width")
2270 aPxWidth = aValue.IntegerValue();
2272 else if (aName == "h"
2273 || aName == "height")
2275 aPxHeight = aValue.IntegerValue();
2279 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2283 else if (aViewName.IsEmpty())
2289 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2294 #if !defined(HAVE_XLIB)
2295 if (!aDisplayName.IsEmpty())
2297 aDisplayName.Clear();
2298 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
2302 ViewerTest_Names aViewNames (aViewName);
2303 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
2305 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2306 theDi.Eval (aCommand.ToCString());
2309 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2314 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
2315 aViewName, aDisplayName, aCopyFrom, isVirtual);
2318 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2324 //! Parse HLR algo type.
2325 static Standard_Boolean parseHlrAlgoType (const char* theName,
2326 Prs3d_TypeOfHLR& theType)
2328 TCollection_AsciiString aName (theName);
2330 if (aName == "polyalgo")
2332 theType = Prs3d_TOH_PolyAlgo;
2334 else if (aName == "algo")
2336 theType = Prs3d_TOH_Algo;
2340 return Standard_False;
2342 return Standard_True;
2345 //==============================================================================
2347 //purpose : hidden lines removal algorithm
2348 //==============================================================================
2350 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2352 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2353 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2356 Message::SendFail ("Error: no active viewer");
2360 Standard_Boolean hasHlrOnArg = Standard_False;
2361 Standard_Boolean hasShowHiddenArg = Standard_False;
2362 Standard_Boolean isHLROn = Standard_False;
2363 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2364 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2365 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2366 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
2368 TCollection_AsciiString anArg (argv[anArgIter]);
2370 if (anUpdateTool.parseRedrawMode (anArg))
2374 else if (anArg == "-showhidden"
2375 && anArgIter + 1 < argc
2376 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
2379 hasShowHiddenArg = Standard_True;
2382 else if ((anArg == "-type"
2384 || anArg == "-algotype")
2385 && anArgIter + 1 < argc
2386 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2391 else if (!hasHlrOnArg
2392 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
2394 hasHlrOnArg = Standard_True;
2398 else if (!hasShowHiddenArg
2399 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
2401 hasShowHiddenArg = Standard_True;
2406 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
2412 di << "HLR: " << aView->ComputedMode() << "\n";
2413 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2415 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2417 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2418 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2419 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2421 anUpdateTool.Invalidate();
2425 Standard_Boolean toRecompute = Standard_False;
2426 if (aTypeOfHLR != Prs3d_TOH_NotSet
2427 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
2429 toRecompute = Standard_True;
2430 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2432 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2434 toRecompute = Standard_True;
2437 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
2441 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
2446 if (aView->ComputedMode() && isHLROn && toRecompute)
2448 AIS_ListOfInteractive aListOfShapes;
2449 aCtx->DisplayedObjects (aListOfShapes);
2450 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
2452 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
2454 aCtx->Redisplay (aShape, Standard_False);
2459 aView->SetComputedMode (isHLROn);
2463 //==============================================================================
2464 //function : VHLRType
2465 //purpose : change type of using HLR algorithm
2466 //==============================================================================
2468 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
2470 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2471 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2474 Message::SendFail ("Error: no active viewer");
2478 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2479 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2480 AIS_ListOfInteractive aListOfShapes;
2481 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
2483 TCollection_AsciiString anArg (argv[anArgIter]);
2485 if (anUpdateTool.parseRedrawMode (anArg))
2489 else if ((anArg == "-type"
2491 || anArg == "-algotype")
2492 && anArgIter + 1 < argc
2493 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2499 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2500 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2506 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
2507 TCollection_AsciiString aName (argv[anArgIter]);
2508 if (!aMap.IsBound2 (aName))
2510 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
2514 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2515 if (aShape.IsNull())
2517 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
2520 aListOfShapes.Append (aShape);
2524 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2526 Message::SendFail ("Syntax error: wrong number of arguments");
2530 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2533 aCtx->DisplayedObjects (aListOfShapes);
2534 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2537 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2539 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2540 if (aShape.IsNull())
2545 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2546 && aView->ComputedMode();
2548 || aShape->TypeOfHLR() != aTypeOfHLR)
2550 aShape->SetTypeOfHLR (aTypeOfHLR);
2554 aCtx->Redisplay (aShape, Standard_False);
2560 //==============================================================================
2561 //function : FindViewIdByWindowHandle
2562 //purpose : Find theView Id in the map of views by window handle
2563 //==============================================================================
2564 #if defined(_WIN32) || defined(HAVE_XLIB)
2565 static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
2567 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2568 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2570 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
2571 if (aWindowHandle == theWindowHandle)
2572 return anIter.Key1();
2574 return TCollection_AsciiString("");
2578 //! Make the view active
2579 void ActivateView (const TCollection_AsciiString& theViewName,
2580 Standard_Boolean theToUpdate = Standard_True)
2582 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2588 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2589 if (!anAISContext.IsNull())
2591 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
2593 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
2596 ViewerTest::CurrentView (aView);
2597 ViewerTest::SetAISContext (anAISContext);
2598 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
2599 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(ViewerTest::CurrentView()->Window());
2600 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2603 ViewerTest::CurrentView()->Redraw();
2608 //==============================================================================
2609 //function : RemoveView
2611 //==============================================================================
2612 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2613 const Standard_Boolean theToRemoveContext)
2615 if (!ViewerTest_myViews.IsBound2 (theView))
2620 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2621 RemoveView (aViewName, theToRemoveContext);
2624 //==============================================================================
2625 //function : RemoveView
2626 //purpose : Close and remove view from display, clear maps if necessary
2627 //==============================================================================
2628 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2630 if (!ViewerTest_myViews.IsBound1(theViewName))
2632 Message::SendFail() << "Wrong view name";
2636 // Activate another view if it's active now
2637 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2639 if (ViewerTest_myViews.Extent() > 1)
2641 TCollection_AsciiString aNewViewName;
2642 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2643 anIter.More(); anIter.Next())
2645 if (anIter.Key1() != theViewName)
2647 aNewViewName = anIter.Key1();
2651 ActivateView (aNewViewName);
2655 VT_GetWindow().Nullify();
2656 ViewerTest::CurrentView (Handle(V3d_View)());
2657 if (isContextRemoved)
2659 Handle(AIS_InteractiveContext) anEmptyContext;
2660 ViewerTest::SetAISContext(anEmptyContext);
2666 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2667 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
2668 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2669 aRedrawer.Stop (aView);
2671 // Remove view resources
2672 ViewerTest_myViews.UnBind1(theViewName);
2673 aView->Window()->Unmap();
2676 #if defined(HAVE_XLIB)
2677 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
2680 // Keep context opened only if the closed view is last to avoid
2681 // unused empty contexts
2682 if (!aCurrentContext.IsNull())
2684 // Check if there are more defined views in the viewer
2685 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2686 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
2688 // Remove driver if there is no viewers that use it
2689 Standard_Boolean isRemoveDriver = Standard_True;
2690 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2691 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2693 if (aCurrentContext != anIter.Key2() &&
2694 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2696 isRemoveDriver = Standard_False;
2701 aCurrentContext->RemoveAll (Standard_False);
2704 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2705 #if defined(HAVE_XLIB)
2706 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
2710 ViewerTest_myContexts.UnBind2(aCurrentContext);
2713 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
2714 if (ViewerTest_EventManager::ToExitOnCloseView())
2716 Draw_Interprete ("exit");
2720 //==============================================================================
2722 //purpose : Remove the view defined by its name
2723 //==============================================================================
2725 static int VClose (Draw_Interpretor& /*theDi*/,
2726 Standard_Integer theArgsNb,
2727 const char** theArgVec)
2729 NCollection_List<TCollection_AsciiString> aViewList;
2732 TCollection_AsciiString anArg (theArgVec[1]);
2734 if (anArg.IsEqual ("ALL")
2735 || anArg.IsEqual ("*"))
2737 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2738 anIter.More(); anIter.Next())
2740 aViewList.Append (anIter.Key1());
2742 if (aViewList.IsEmpty())
2744 std::cout << "No view to close\n";
2750 ViewerTest_Names aViewName (theArgVec[1]);
2751 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2753 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
2756 aViewList.Append (aViewName.GetViewName());
2761 // close active view
2762 if (ViewerTest::CurrentView().IsNull())
2764 Message::SendFail ("Error: no active view");
2767 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
2770 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
2771 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2772 anIter.More(); anIter.Next())
2774 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
2780 //==============================================================================
2781 //function : VActivate
2782 //purpose : Activate the view defined by its ID
2783 //==============================================================================
2785 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2789 theDi.Eval("vviewlist");
2793 TCollection_AsciiString aNameString;
2794 Standard_Boolean toUpdate = Standard_True;
2795 Standard_Boolean toActivate = Standard_True;
2796 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
2798 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2801 && anArg == "-noupdate")
2803 toUpdate = Standard_False;
2806 && aNameString.IsEmpty()
2809 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
2810 VT_GetWindow().Nullify();
2811 ViewerTest::CurrentView (Handle(V3d_View)());
2812 ViewerTest::ResetEventManager();
2813 theDi << theArgVec[0] << ": all views are inactive\n";
2814 toActivate = Standard_False;
2817 && aNameString.IsEmpty())
2819 aNameString = theArgVec[anArgIter];
2823 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2832 else if (aNameString.IsEmpty())
2834 Message::SendFail ("Syntax error: wrong number of arguments");
2838 // Check if this view exists in the viewer with the driver
2839 ViewerTest_Names aViewNames (aNameString);
2840 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2842 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
2846 // Check if it is active already
2847 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2849 theDi << theArgVec[0] << ": the view is active already\n";
2853 ActivateView (aViewNames.GetViewName(), toUpdate);
2857 //==============================================================================
2858 //function : VViewList
2859 //purpose : Print current list of views per viewer and graphic driver ID
2860 // shared between viewers
2861 //==============================================================================
2863 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2867 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
2868 << "Usage: " << theArgVec[0] << " name";
2871 if (ViewerTest_myContexts.Size() < 1)
2874 Standard_Boolean isTreeView =
2875 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
2879 theDi << theArgVec[0] <<":\n";
2882 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2883 aDriverIter.More(); aDriverIter.Next())
2886 theDi << aDriverIter.Key1() << ":\n";
2888 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2889 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2891 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
2895 TCollection_AsciiString aContextName(aContextIter.Key1());
2896 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2899 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2900 aViewIter.More(); aViewIter.Next())
2902 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
2904 TCollection_AsciiString aViewName(aViewIter.Key1());
2907 if (aViewIter.Value() == ViewerTest::CurrentView())
2908 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
2910 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2914 theDi << aViewName << " ";
2924 //==============================================================================
2925 //function : GetMousePosition
2927 //==============================================================================
2928 void ViewerTest::GetMousePosition (Standard_Integer& theX,
2929 Standard_Integer& theY)
2931 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
2933 theX = aViewCtrl->LastMousePosition().x();
2934 theY = aViewCtrl->LastMousePosition().y();
2938 //==============================================================================
2939 //function : VViewProj
2940 //purpose : Switch view projection
2941 //==============================================================================
2942 static int VViewProj (Draw_Interpretor& ,
2943 Standard_Integer theNbArgs,
2944 const char** theArgVec)
2946 static Standard_Boolean isYup = Standard_False;
2947 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2950 Message::SendFail ("Error: no active viewer");
2954 TCollection_AsciiString aCmdName (theArgVec[0]);
2955 Standard_Boolean isGeneralCmd = Standard_False;
2956 if (aCmdName == "vfront")
2958 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2960 else if (aCmdName == "vback")
2962 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2964 else if (aCmdName == "vtop")
2966 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2968 else if (aCmdName == "vbottom")
2970 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2972 else if (aCmdName == "vleft")
2974 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2976 else if (aCmdName == "vright")
2978 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2980 else if (aCmdName == "vaxo")
2982 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2986 isGeneralCmd = Standard_True;
2987 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2989 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2990 anArgCase.LowerCase();
2991 if (anArgCase == "-zup")
2993 isYup = Standard_False;
2995 else if (anArgCase == "-yup")
2997 isYup = Standard_True;
2999 else if (anArgCase == "-front"
3000 || anArgCase == "front"
3001 || anArgCase == "-f"
3002 || anArgCase == "f")
3004 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
3006 else if (anArgCase == "-back"
3007 || anArgCase == "back"
3008 || anArgCase == "-b"
3009 || anArgCase == "b")
3011 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
3013 else if (anArgCase == "-top"
3014 || anArgCase == "top"
3015 || anArgCase == "-t"
3016 || anArgCase == "t")
3018 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
3020 else if (anArgCase == "-bottom"
3021 || anArgCase == "bottom"
3022 || anArgCase == "-bot"
3023 || anArgCase == "bot"
3024 || anArgCase == "-b"
3025 || anArgCase == "b")
3027 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
3029 else if (anArgCase == "-left"
3030 || anArgCase == "left"
3031 || anArgCase == "-l"
3032 || anArgCase == "l")
3034 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
3036 else if (anArgCase == "-right"
3037 || anArgCase == "right"
3038 || anArgCase == "-r"
3039 || anArgCase == "r")
3041 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
3043 else if (anArgCase == "-axoleft"
3044 || anArgCase == "-leftaxo"
3045 || anArgCase == "axoleft"
3046 || anArgCase == "leftaxo")
3048 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
3050 else if (anArgCase == "-axo"
3051 || anArgCase == "axo"
3052 || anArgCase == "-a"
3054 || anArgCase == "-axoright"
3055 || anArgCase == "-rightaxo"
3056 || anArgCase == "axoright"
3057 || anArgCase == "rightaxo")
3059 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
3061 else if (anArgCase == "+x")
3063 aView->SetProj (V3d_Xpos, isYup);
3065 else if (anArgCase == "-x")
3067 aView->SetProj (V3d_Xneg, isYup);
3069 else if (anArgCase == "+y")
3071 aView->SetProj (V3d_Ypos, isYup);
3073 else if (anArgCase == "-y")
3075 aView->SetProj (V3d_Yneg, isYup);
3077 else if (anArgCase == "+z")
3079 aView->SetProj (V3d_Zpos, isYup);
3081 else if (anArgCase == "-z")
3083 aView->SetProj (V3d_Zneg, isYup);
3085 else if (anArgCase == "+x+y+z")
3087 aView->SetProj (V3d_XposYposZpos, isYup);
3089 else if (anArgCase == "+x+y-z")
3091 aView->SetProj (V3d_XposYposZneg, isYup);
3093 else if (anArgCase == "+x-y+z")
3095 aView->SetProj (V3d_XposYnegZpos, isYup);
3097 else if (anArgCase == "+x-y-z")
3099 aView->SetProj (V3d_XposYnegZneg, isYup);
3101 else if (anArgCase == "-x+y+z")
3103 aView->SetProj (V3d_XnegYposZpos, isYup);
3105 else if (anArgCase == "-x+y-z")
3107 aView->SetProj (V3d_XnegYposZneg, isYup);
3109 else if (anArgCase == "-x-y+z")
3111 aView->SetProj (V3d_XnegYnegZpos, isYup);
3113 else if (anArgCase == "-x-y-z")
3115 aView->SetProj (V3d_XnegYnegZneg, isYup);
3117 else if (anArgCase == "+x+y")
3119 aView->SetProj (V3d_XposYpos, isYup);
3121 else if (anArgCase == "+x-y")
3123 aView->SetProj (V3d_XposYneg, isYup);
3125 else if (anArgCase == "-x+y")
3127 aView->SetProj (V3d_XnegYpos, isYup);
3129 else if (anArgCase == "-x-y")
3131 aView->SetProj (V3d_XnegYneg, isYup);
3133 else if (anArgCase == "+x+z")
3135 aView->SetProj (V3d_XposZpos, isYup);
3137 else if (anArgCase == "+x-z")
3139 aView->SetProj (V3d_XposZneg, isYup);
3141 else if (anArgCase == "-x+z")
3143 aView->SetProj (V3d_XnegZpos, isYup);
3145 else if (anArgCase == "-x-z")
3147 aView->SetProj (V3d_XnegZneg, isYup);
3149 else if (anArgCase == "+y+z")
3151 aView->SetProj (V3d_YposZpos, isYup);
3153 else if (anArgCase == "+y-z")
3155 aView->SetProj (V3d_YposZneg, isYup);
3157 else if (anArgCase == "-y+z")
3159 aView->SetProj (V3d_YnegZpos, isYup);
3161 else if (anArgCase == "-y-z")
3163 aView->SetProj (V3d_YnegZneg, isYup);
3165 else if (anArgIter + 1 < theNbArgs
3166 && anArgCase == "-frame"
3167 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
3169 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
3170 aFrameDef.LowerCase();
3171 gp_Dir aRight, anUp;
3172 if (aFrameDef.Value (2) == aFrameDef.Value (4))
3174 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3178 if (aFrameDef.Value (2) == 'x')
3180 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
3182 else if (aFrameDef.Value (2) == 'y')
3184 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
3186 else if (aFrameDef.Value (2) == 'z')
3188 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
3192 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3196 if (aFrameDef.Value (4) == 'x')
3198 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
3200 else if (aFrameDef.Value (4) == 'y')
3202 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
3204 else if (aFrameDef.Value (4) == 'z')
3206 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
3210 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3214 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3215 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3216 const gp_Dir aDir = anUp.Crossed (aRight);
3217 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3218 aCamera->SetDirection (aDir);
3219 aCamera->SetUp (anUp);
3220 aCamera->OrthogonalizeUp();
3222 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3227 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3236 Message::SendFail ("Syntax error: wrong number of arguments");
3242 //==============================================================================
3244 //purpose : Dsiplay help on viewer Keyboead and mouse commands
3245 //Draw arg : No args
3246 //==============================================================================
3248 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3250 di << "=========================\n";
3251 di << "F : FitAll\n";
3252 di << "T : TopView\n";
3253 di << "B : BottomView\n";
3254 di << "R : RightView\n";
3255 di << "L : LeftView\n";
3256 di << "Backspace : AxonometricView\n";
3258 di << "=========================\n";
3259 di << "W, S : Fly forward/backward\n";
3260 di << "A, D : Slide left/right\n";
3261 di << "Q, E : Bank left/right\n";
3262 di << "-, + : Change flying speed\n";
3263 di << "Arrows : look left/right/up/down\n";
3264 di << "Arrows+Shift : slide left/right/up/down\n";
3266 di << "=========================\n";
3267 di << "S + Ctrl : Shading\n";
3268 di << "W + Ctrl : Wireframe\n";
3269 di << "H : HiddenLineRemoval\n";
3270 di << "U : Unset display mode\n";
3271 di << "Delete : Remove selection from viewer\n";
3273 di << "=========================\n";
3274 di << "Selection mode \n";
3275 di << "0 : Shape\n";
3276 di << "1 : Vertex\n";
3280 di << "5 : Shell\n";
3281 di << "6 : Solid\n";
3282 di << "7 : Compound\n";
3284 di << "=========================\n";
3285 di << "< : Hilight next detected\n";
3286 di << "> : Hilight previous detected\n";
3293 static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3298 if (ViewerTest_myViews.IsEmpty())
3300 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
3307 // Delete view from map of views
3308 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3313 if (LOWORD(wParam) == WA_CLICKACTIVE
3314 || LOWORD(wParam) == WA_ACTIVE
3315 || ViewerTest::CurrentView().IsNull())
3317 // Activate inactive window
3318 if (VT_GetWindow().IsNull()
3319 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3321 ActivateView (FindViewIdByWindowHandle (theWinHandle));
3328 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3330 && !VT_GetWindow().IsNull())
3333 aMsg.hwnd = theWinHandle;
3334 aMsg.message = theMsg;
3335 aMsg.wParam = wParam;
3336 aMsg.lParam = lParam;
3337 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
3344 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
3347 //==============================================================================
3348 //function : ViewerMainLoop
3349 //purpose : Get a Event on the view and dispatch it
3350 //==============================================================================
3352 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
3354 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3355 if (aViewCtrl.IsNull()
3361 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3363 std::cout << "Start picking\n";
3367 while (aViewCtrl->ToPickPoint())
3369 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3370 if (GetMessageW (&aMsg, NULL, 0, 0))
3372 TranslateMessage (&aMsg);
3373 DispatchMessageW (&aMsg);
3377 std::cout << "Picking done\n";
3381 #elif defined(HAVE_XLIB)
3383 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
3385 static XEvent aReport;
3386 const Standard_Boolean toPick = theNbArgs > 0;
3389 if (ViewerTest::CurrentEventManager().IsNull())
3393 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3396 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
3397 XNextEvent (aDisplay, &aReport);
3399 // Handle event for the chosen display connection
3400 switch (aReport.type)
3404 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3407 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3408 return toPick ? 0 : 1;
3414 // Activate inactive view
3415 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
3416 if (aWindow != aReport.xfocus.window)
3418 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3424 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3426 && !VT_GetWindow().IsNull())
3428 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
3433 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
3436 //==============================================================================
3437 //function : VProcessEvents
3438 //purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
3439 //==============================================================================
3440 static void VProcessEvents (ClientData theDispX, int)
3442 Display* aDispX = (Display* )theDispX;
3443 Handle(Aspect_DisplayConnection) aDispConn;
3444 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3445 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
3447 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3448 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
3450 aDispConn = aDispConnTmp;
3454 if (aDispConn.IsNull())
3456 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
3460 // process new events in queue
3461 SetDisplayConnection (aDispConn);
3463 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
3465 const int anEventResult = ViewerMainLoop (0, NULL);
3466 if (anEventResult == 0)
3471 aNbRemain = XPending (aDispX);
3472 if (++anEventIter >= aNbEventsMax
3479 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3480 // it is possible that new events will arrive to queue before the end of this callback
3481 // so that either this callback should go into an infinite loop (blocking processing of other events)
3482 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3483 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3487 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3488 aDummyEvent.type = ClientMessage;
3489 aDummyEvent.xclient.format = 32;
3490 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3494 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3496 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3499 #elif !defined(__APPLE__)
3500 // =======================================================================
3501 // function : ViewerMainLoop
3503 // =======================================================================
3504 int ViewerMainLoop (Standard_Integer , const char** )
3511 //==============================================================================
3514 //==============================================================================
3516 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
3518 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3521 Message::SendFail ("Error: no active viewer");
3525 Standard_Boolean toFit = Standard_True;
3526 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3527 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3529 TCollection_AsciiString anArg (theArgv[anArgIter]);
3531 if (anUpdateTool.parseRedrawMode (anArg))
3535 else if (anArg == "-selected")
3537 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3538 toFit = Standard_False;
3542 Message::SendFail() << "Syntax error at '" << anArg << "'";
3548 aView->FitAll (0.01, Standard_False);
3553 //=======================================================================
3554 //function : VFitArea
3555 //purpose : Fit view to show area located between two points
3556 // : given in world 2D or 3D coordinates.
3557 //=======================================================================
3558 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3560 Handle(V3d_View) aView = ViewerTest::CurrentView();
3563 Message::SendFail ("Error: No active viewer");
3568 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3569 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3573 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3574 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3575 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3576 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3578 else if (theArgNb == 7)
3580 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3581 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3582 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3583 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3584 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3585 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3589 Message::SendFail ("Syntax error: Invalid number of arguments");
3590 theDI.PrintHelp(theArgVec[0]);
3594 // Convert model coordinates to view space
3595 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3596 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3597 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3599 // Determine fit area
3600 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3601 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3603 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3605 if (aDiagonal < Precision::Confusion())
3607 Message::SendFail ("Error: view area is too small");
3611 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3615 //==============================================================================
3617 //purpose : ZFitall, no DRAW arguments
3618 //Draw arg : No args
3619 //==============================================================================
3620 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
3622 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3624 if (aCurrentView.IsNull())
3626 Message::SendFail ("Error: no active viewer");
3632 aCurrentView->ZFitAll();
3633 aCurrentView->Redraw();
3637 Standard_Real aScale = 1.0;
3641 aScale = Draw::Atoi (theArgVec[1]);
3644 aCurrentView->ZFitAll (aScale);
3645 aCurrentView->Redraw();
3650 //==============================================================================
3651 //function : VRepaint
3653 //==============================================================================
3654 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
3656 Handle(V3d_View) aView = ViewerTest::CurrentView();
3659 Message::SendFail ("Error: no active viewer");
3663 Standard_Boolean isImmediateUpdate = Standard_False;
3664 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3666 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3668 if (anArg == "-immediate"
3671 isImmediateUpdate = Standard_True;
3672 if (anArgIter + 1 < theArgNb
3673 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
3678 else if (anArg == "-continuous"
3681 || anArg == "-framerate")
3683 Standard_Real aFps = -1.0;
3684 if (anArgIter + 1 < theArgNb
3685 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
3687 aFps = Draw::Atof (theArgVec[++anArgIter]);
3690 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3691 ViewerTest::CurrentEventManager()->SetContinuousRedraw (false);
3694 aRedrawer.Start (aView, aFps);
3696 else if (aFps < 0.0)
3698 if (ViewerTest::GetViewerFromContext()->ActiveViews().Extent() == 1)
3701 ViewerTest::CurrentEventManager()->SetContinuousRedraw (true);
3702 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3705 aRedrawer.Start (aView, aFps);
3714 Message::SendFail() << "Syntax error at '" << anArg << "'";
3719 if (isImmediateUpdate)
3721 aView->RedrawImmediate();
3730 //==============================================================================
3732 //purpose : Remove all the object from the viewer
3733 //Draw arg : No args
3734 //==============================================================================
3736 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3738 Handle(V3d_View) V = ViewerTest::CurrentView();
3740 ViewerTest::Clear();
3744 //==============================================================================
3747 //==============================================================================
3749 static int VPick (Draw_Interpretor& ,
3750 Standard_Integer theNbArgs,
3751 const char** theArgVec)
3753 if (ViewerTest::CurrentView().IsNull())
3760 Message::SendFail ("Syntax error: wrong number of arguments");
3764 while (ViewerMainLoop (theNbArgs, theArgVec))
3775 //! Changes the background
3776 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3777 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3778 //! @param theCommandLineArguments the array of command line arguments
3779 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3780 static int vbackground (Draw_Interpretor& theDrawInterpretor,
3781 const Standard_Integer theNumberOfCommandLineArguments,
3782 const char** const theCommandLineArguments)
3784 if (theNumberOfCommandLineArguments < 1)
3788 BackgroundChanger aBackgroundChanger;
3789 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
3790 theNumberOfCommandLineArguments,
3791 theCommandLineArguments))
3793 theDrawInterpretor << "Wrong command arguments.\n"
3795 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
3803 //==============================================================================
3805 //purpose : View Scaling
3806 //==============================================================================
3808 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3810 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3811 if ( V3dView.IsNull() ) return 1;
3814 di << argv[0] << "Invalid number of arguments\n";
3817 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
3820 //==============================================================================
3821 //function : VZBuffTrihedron
3823 //==============================================================================
3825 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3826 Standard_Integer theArgNb,
3827 const char** theArgVec)
3829 Handle(V3d_View) aView = ViewerTest::CurrentView();
3832 Message::SendFail ("Error: no active viewer");
3836 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
3838 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3839 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
3840 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3841 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3842 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
3843 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3844 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3845 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3846 Standard_Real aScale = 0.1;
3847 Standard_Real aSizeRatio = 0.8;
3848 Standard_Real anArrowDiam = 0.05;
3849 Standard_Integer aNbFacets = 12;
3850 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3852 Standard_CString anArg = theArgVec[anArgIter];
3853 TCollection_AsciiString aFlag (anArg);
3855 if (anUpdateTool.parseRedrawMode (aFlag))
3859 else if (aFlag == "-on")
3863 else if (aFlag == "-off")
3865 aView->TriedronErase();
3868 else if (aFlag == "-pos"
3869 || aFlag == "-position"
3870 || aFlag == "-corner")
3872 if (++anArgIter >= theArgNb)
3874 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3878 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3879 aPosName.LowerCase();
3880 if (aPosName == "center")
3882 aPosition = Aspect_TOTP_CENTER;
3884 else if (aPosName == "left_lower"
3885 || aPosName == "lower_left"
3886 || aPosName == "leftlower"
3887 || aPosName == "lowerleft")
3889 aPosition = Aspect_TOTP_LEFT_LOWER;
3891 else if (aPosName == "left_upper"
3892 || aPosName == "upper_left"
3893 || aPosName == "leftupper"
3894 || aPosName == "upperleft")
3896 aPosition = Aspect_TOTP_LEFT_UPPER;
3898 else if (aPosName == "right_lower"
3899 || aPosName == "lower_right"
3900 || aPosName == "rightlower"
3901 || aPosName == "lowerright")
3903 aPosition = Aspect_TOTP_RIGHT_LOWER;
3905 else if (aPosName == "right_upper"
3906 || aPosName == "upper_right"
3907 || aPosName == "rightupper"
3908 || aPosName == "upperright")
3910 aPosition = Aspect_TOTP_RIGHT_UPPER;
3914 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
3918 else if (aFlag == "-type")
3920 if (++anArgIter >= theArgNb)
3922 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3926 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3927 aTypeName.LowerCase();
3928 if (aTypeName == "wireframe"
3929 || aTypeName == "wire")
3931 aVisType = V3d_WIREFRAME;
3933 else if (aTypeName == "zbuffer"
3934 || aTypeName == "shaded")
3936 aVisType = V3d_ZBUFFER;
3940 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
3943 else if (aFlag == "-scale")
3945 if (++anArgIter >= theArgNb)
3947 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3951 aScale = Draw::Atof (theArgVec[anArgIter]);
3953 else if (aFlag == "-size"
3954 || aFlag == "-sizeratio")
3956 if (++anArgIter >= theArgNb)
3958 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3962 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3964 else if (aFlag == "-arrowdiam"
3965 || aFlag == "-arrowdiameter")
3967 if (++anArgIter >= theArgNb)
3969 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3973 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3975 else if (aFlag == "-nbfacets")
3977 if (++anArgIter >= theArgNb)
3979 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3983 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3985 else if (aFlag == "-colorlabel"
3986 || aFlag == "-colorlabels"
3987 || aFlag == "-colorlabelx"
3988 || aFlag == "-colorlabely"
3989 || aFlag == "-colorlabelz"
3990 || aFlag == "-colorarrowx"
3991 || aFlag == "-colorarrowy"
3992 || aFlag == "-colorarrowz")
3994 Quantity_Color aColor;
3995 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3996 theArgVec + anArgIter + 1,
4000 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4004 if (aFlag == "-colorarrowx")
4006 anArrowColorX = aColor;
4008 else if (aFlag == "-colorarrowy")
4010 anArrowColorY = aColor;
4012 else if (aFlag == "-colorarrowz")
4014 anArrowColorZ = aColor;
4016 else if (aFlag == "-colorlabelx")
4018 aLabelsColorX = aColor;
4020 else if (aFlag == "-colorlabely")
4022 aLabelsColorY = aColor;
4024 else if (aFlag == "-colorlabelz")
4026 aLabelsColorZ = aColor;
4030 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
4032 anArgIter += aNbParsed;
4036 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4041 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
4042 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
4043 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
4044 aTrihedron->SetSizeRatio (aSizeRatio);
4045 aTrihedron->SetNbFacets (aNbFacets);
4046 aTrihedron->SetArrowDiameter(anArrowDiam);
4047 aTrihedron->SetScale (aScale);
4048 aTrihedron->SetPosition (aPosition);
4049 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
4050 aTrihedron->Display (aView);
4056 //==============================================================================
4057 //function : VRotate
4058 //purpose : Camera Rotating
4059 //==============================================================================
4061 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4063 Handle(V3d_View) aView = ViewerTest::CurrentView();
4066 Message::SendFail ("Error: no active viewer");
4070 Standard_Boolean hasFlags = Standard_False;
4071 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4073 Standard_CString anArg (theArgVec[anArgIter]);
4074 TCollection_AsciiString aFlag (anArg);
4076 if (aFlag == "-mousestart"
4077 || aFlag == "-mousefrom")
4079 hasFlags = Standard_True;
4080 if (anArgIter + 2 >= theArgNb)
4082 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4086 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4087 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4088 aView->StartRotation (anX, anY);
4090 else if (aFlag == "-mousemove")
4092 hasFlags = Standard_True;
4093 if (anArgIter + 2 >= theArgNb)
4095 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4099 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4100 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4101 aView->Rotation (anX, anY);
4103 else if (theArgNb != 4
4106 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4115 else if (theArgNb == 4)
4117 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4118 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4119 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4120 aView->Rotate (anAX, anAY, anAZ);
4123 else if (theArgNb == 7)
4125 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4126 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4127 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4129 Standard_Real anX = Draw::Atof (theArgVec[4]);
4130 Standard_Real anY = Draw::Atof (theArgVec[5]);
4131 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4133 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
4137 Message::SendFail ("Error: Invalid number of arguments");
4141 //==============================================================================
4143 //purpose : View zoom in / out (relative to current zoom)
4144 //==============================================================================
4146 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4147 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4148 if ( V3dView.IsNull() ) {
4153 Standard_Real coef = Draw::Atof(argv[1]);
4154 if ( coef <= 0.0 ) {
4155 di << argv[1] << "Invalid value\n";
4158 V3dView->SetZoom( Draw::Atof(argv[1]) );
4161 di << argv[0] << " Invalid number of arguments\n";
4166 //==============================================================================
4168 //purpose : View panning (in pixels)
4169 //==============================================================================
4171 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4172 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4173 if ( V3dView.IsNull() ) return 1;
4176 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
4179 di << argv[0] << " Invalid number of arguments\n";
4184 //==============================================================================
4186 //purpose : Place the point (in pixels) at the center of the window
4187 //==============================================================================
4188 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4190 Handle(V3d_View) aView = ViewerTest::CurrentView();
4193 Message::SendFail ("Error: no active viewer");
4199 Message::SendFail ("Syntax error: wrong number of arguments");
4203 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4208 static int VColorScale (Draw_Interpretor& theDI,
4209 Standard_Integer theArgNb,
4210 const char** theArgVec)
4212 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4213 Handle(V3d_View) aView = ViewerTest::CurrentView();
4214 if (aContext.IsNull())
4216 Message::SendFail ("Error: no active viewer");
4221 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
4225 Handle(AIS_ColorScale) aColorScale;
4226 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
4228 // find existing object
4229 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4230 if (aColorScale.IsNull())
4232 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
4239 if (aColorScale.IsNull())
4241 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4245 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4246 << "Min range: " << aColorScale->GetMin() << "\n"
4247 << "Max range: " << aColorScale->GetMax() << "\n"
4248 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4249 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4250 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4251 << "Color scale title: " << aColorScale->GetTitle() << "\n"
4252 << "Label position: ";
4253 switch (aColorScale->GetLabelPosition())
4255 case Aspect_TOCSP_NONE:
4258 case Aspect_TOCSP_LEFT:
4261 case Aspect_TOCSP_RIGHT:
4264 case Aspect_TOCSP_CENTER:
4265 theDI << "Center\n";
4271 if (aColorScale.IsNull())
4273 aColorScale = new AIS_ColorScale();
4274 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4275 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4278 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
4279 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
4281 Standard_CString anArg = theArgVec[anArgIter];
4282 TCollection_AsciiString aFlag (anArg);
4284 if (anUpdateTool.parseRedrawMode (aFlag))
4288 else if (aFlag == "-range")
4290 if (anArgIter + 3 >= theArgNb)
4292 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
4296 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4297 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4298 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
4299 if (!aRangeMin.IsRealValue (Standard_True)
4300 || !aRangeMax.IsRealValue (Standard_True))
4302 Message::SendFail ("Syntax error: the range values should be real");
4305 else if (!aNbIntervals.IsIntegerValue())
4307 Message::SendFail ("Syntax error: the number of intervals should be integer");
4311 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4312 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
4314 else if (aFlag == "-font")
4316 if (anArgIter + 1 >= theArgNb)
4318 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4321 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4322 if (!aFontArg.IsIntegerValue())
4324 Message::SendFail ("Syntax error: HeightFont value should be integer");
4328 aColorScale->SetTextHeight (aFontArg.IntegerValue());
4331 else if (aFlag == "-textpos")
4333 if (anArgIter + 1 >= theArgNb)
4335 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4339 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4340 aTextPosArg.LowerCase();
4341 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
4342 if (aTextPosArg == "none")
4344 aLabPosition = Aspect_TOCSP_NONE;
4346 else if (aTextPosArg == "left")
4348 aLabPosition = Aspect_TOCSP_LEFT;
4350 else if (aTextPosArg == "right")
4352 aLabPosition = Aspect_TOCSP_RIGHT;
4354 else if (aTextPosArg == "center")
4356 aLabPosition = Aspect_TOCSP_CENTER;
4360 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
4363 aColorScale->SetLabelPosition (aLabPosition);
4365 else if (aFlag == "-logarithmic"
4368 if (anArgIter + 1 >= theArgNb)
4370 Message::SendFail() << "Synta error at argument '" << anArg << "'";
4374 Standard_Boolean IsLog;
4375 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
4377 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4380 aColorScale->SetLogarithmic (IsLog);
4382 else if (aFlag == "-huerange"
4385 if (anArgIter + 2 >= theArgNb)
4387 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4391 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4392 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4393 aColorScale->SetHueRange (aHueMin, aHueMax);
4395 else if (aFlag == "-colorrange")
4397 Quantity_Color aColorMin, aColorMax;
4398 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4399 theArgVec + (anArgIter + 1),
4401 anArgIter += aNbParsed1;
4402 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4403 theArgVec + (anArgIter + 1),
4405 anArgIter += aNbParsed2;
4409 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4413 aColorScale->SetColorRange (aColorMin, aColorMax);
4415 else if (aFlag == "-reversed"
4416 || aFlag == "-inverted"
4417 || aFlag == "-topdown"
4418 || aFlag == "-bottomup")
4420 Standard_Boolean toEnable = Standard_True;
4421 if (anArgIter + 1 < theArgNb
4422 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4426 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4428 else if (aFlag == "-smooth"
4429 || aFlag == "-smoothtransition")
4431 Standard_Boolean toEnable = Standard_True;
4432 if (anArgIter + 1 < theArgNb
4433 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4437 aColorScale->SetSmoothTransition (toEnable);
4439 else if (aFlag == "-xy")
4441 if (anArgIter + 2 >= theArgNb)
4443 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4447 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4448 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4449 if (!anX.IsIntegerValue()
4450 || !anY.IsIntegerValue())
4452 Message::SendFail ("Syntax error: coordinates should be integer values");
4456 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
4458 else if (aFlag == "-width"
4460 || aFlag == "-breadth")
4462 if (anArgIter + 1 >= theArgNb)
4464 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4468 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4469 if (!aBreadth.IsIntegerValue())
4471 Message::SendFail ("Syntax error: a width should be an integer value");
4474 aColorScale->SetBreadth (aBreadth.IntegerValue());
4476 else if (aFlag == "-height"
4479 if (anArgIter + 1 >= theArgNb)
4481 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4485 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4486 if (!aHeight.IsIntegerValue())
4488 Message::SendFail ("Syntax error: a width should be an integer value");
4491 aColorScale->SetHeight (aHeight.IntegerValue());
4493 else if (aFlag == "-color")
4495 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
4497 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
4500 else if (anArgIter + 2 >= theArgNb)
4502 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4506 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
4507 if (!anInd.IsIntegerValue())
4509 Message::SendFail ("Syntax error: Index value should be integer");
4512 const Standard_Integer anIndex = anInd.IntegerValue();
4513 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
4515 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
4519 Quantity_Color aColor;
4520 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4521 theArgVec + (anArgIter + 1),
4525 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4528 aColorScale->SetIntervalColor (aColor, anIndex);
4529 aColorScale->SetColorType (Aspect_TOCSD_USER);
4530 anArgIter += aNbParsed;
4532 else if (aFlag == "-label")
4534 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
4536 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
4539 else if (anArgIter + 2 >= theArgNb)
4541 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4545 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4546 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
4548 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
4552 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4553 aColorScale->SetLabel (aText, anIndex);
4554 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4557 else if (aFlag == "-labelat"
4558 || aFlag == "-labat"
4559 || aFlag == "-labelatborder"
4560 || aFlag == "-labatborder"
4561 || aFlag == "-labelatcenter"
4562 || aFlag == "-labatcenter")
4564 Standard_Boolean toEnable = Standard_True;
4565 if (aFlag == "-labelat"
4566 || aFlag == "-labat")
4568 Standard_Integer aLabAtBorder = -1;
4569 if (++anArgIter >= theArgNb)
4571 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4572 anAtBorder.LowerCase();
4573 if (anAtBorder == "border")
4577 else if (anAtBorder == "center")
4582 if (aLabAtBorder == -1)
4584 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4587 toEnable = (aLabAtBorder == 1);
4589 else if (anArgIter + 1 < theArgNb
4590 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4594 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4595 || aFlag == "-labatcenter"
4599 else if (aFlag == "-colors")
4601 Aspect_SequenceOfColor aSeq;
4604 Quantity_Color aColor;
4605 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4606 theArgVec + (anArgIter + 1),
4612 anArgIter += aNbParsed;
4613 aSeq.Append (aColor);
4615 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
4617 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4618 << aColorScale->GetNumberOfIntervals() << " intervals";
4622 aColorScale->SetColors (aSeq);
4623 aColorScale->SetColorType (Aspect_TOCSD_USER);
4625 else if (aFlag == "-uniform")
4627 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4628 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4629 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4630 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4631 aColorScale->SetColorType (Aspect_TOCSD_USER);
4633 else if (aFlag == "-labels"
4634 || aFlag == "-freelabels")
4636 if (anArgIter + 1 >= theArgNb)
4638 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4642 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4643 ? aColorScale->GetNumberOfIntervals() + 1
4644 : aColorScale->GetNumberOfIntervals();
4645 if (aFlag == "-freelabels")
4648 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4650 if (anArgIter + aNbLabels >= theArgNb)
4652 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
4656 TColStd_SequenceOfExtendedString aSeq;
4657 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
4659 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
4661 aColorScale->SetLabels (aSeq);
4662 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4664 else if (aFlag == "-title")
4666 if (anArgIter + 1 >= theArgNb)
4668 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4672 Standard_Boolean isTwoArgs = Standard_False;
4673 if (anArgIter + 2 < theArgNb)
4675 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4676 aSecondArg.LowerCase();
4677 Standard_DISABLE_DEPRECATION_WARNINGS
4678 if (aSecondArg == "none")
4680 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
4681 isTwoArgs = Standard_True;
4683 else if (aSecondArg == "left")
4685 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
4686 isTwoArgs = Standard_True;
4688 else if (aSecondArg == "right")
4690 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
4691 isTwoArgs = Standard_True;
4693 else if (aSecondArg == "center")
4695 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
4696 isTwoArgs = Standard_True;
4698 Standard_ENABLE_DEPRECATION_WARNINGS
4701 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4702 aColorScale->SetTitle (aTitle);
4709 else if (aFlag == "-demoversion"
4710 || aFlag == "-demo")
4712 aColorScale->SetPosition (0, 0);
4713 aColorScale->SetTextHeight (16);
4714 aColorScale->SetRange (0.0, 100.0);
4715 aColorScale->SetNumberOfIntervals (10);
4716 aColorScale->SetBreadth (0);
4717 aColorScale->SetHeight (0);
4718 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4719 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4720 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
4722 else if (aFlag == "-findcolor")
4724 if (anArgIter + 1 >= theArgNb)
4726 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4730 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4732 if (!anArg1.IsRealValue (Standard_True))
4734 Message::SendFail ("Syntax error: the value should be real");
4738 Quantity_Color aColor;
4739 aColorScale->FindColor (anArg1.RealValue(), aColor);
4740 theDI << Quantity_Color::StringName (aColor.Name());
4745 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
4750 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4751 aView->Window()->Size (aWinWidth, aWinHeight);
4752 if (aColorScale->GetBreadth() == 0)
4754 aColorScale->SetBreadth (aWinWidth);
4756 if (aColorScale->GetHeight() == 0)
4758 aColorScale->SetHeight (aWinHeight);
4760 aColorScale->SetToUpdate();
4761 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
4765 //==============================================================================
4766 //function : VGraduatedTrihedron
4767 //purpose : Displays or hides a graduated trihedron
4768 //==============================================================================
4769 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4770 Quantity_Color& theColor)
4772 Quantity_NameOfColor aColorName;
4773 TCollection_AsciiString aVal = theValue;
4775 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
4777 return Standard_False;
4779 theColor = Quantity_Color (aColorName);
4780 return Standard_True;
4783 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
4787 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4788 << theArgs[0] <<"' for more information";
4792 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4793 TCollection_AsciiString aParseKey;
4794 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4796 TCollection_AsciiString anArg (theArgs [anArgIt]);
4798 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
4801 aParseKey.Remove (1);
4802 aParseKey.LowerCase();
4803 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4807 if (aParseKey.IsEmpty())
4812 aMapOfArgs(aParseKey)->Append (anArg);
4816 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4817 aMapIt.More(); aMapIt.Next())
4819 const TCollection_AsciiString& aKey = aMapIt.Key();
4820 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4822 // Bool key, without arguments
4823 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4824 && anArgs->IsEmpty())
4830 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4831 && anArgs->Length() == 1)
4837 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4838 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
4839 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4840 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
4841 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4846 // One string argument
4847 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4848 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
4849 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4854 // One integer argument
4855 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4856 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4857 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4858 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4859 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4864 // One real argument
4865 if ( aKey.IsEqual ("arrowlength")
4866 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
4871 // Two string arguments
4872 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
4873 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4878 TCollection_AsciiString aLowerKey;
4881 aLowerKey.LowerCase();
4882 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4883 << "Type help for more information";
4887 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4888 if (anAISContext.IsNull())
4890 Message::SendFail ("Error: no active viewer");
4894 Standard_Boolean toDisplay = Standard_True;
4895 Quantity_Color aColor;
4896 Graphic3d_GraduatedTrihedron aTrihedronData;
4897 // Process parameters
4898 Handle(TColStd_HSequenceOfAsciiString) aValues;
4899 if (aMapOfArgs.Find ("off", aValues))
4901 toDisplay = Standard_False;
4905 if (aMapOfArgs.Find ("xname", aValues))
4907 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4909 if (aMapOfArgs.Find ("yname", aValues))
4911 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4913 if (aMapOfArgs.Find ("zname", aValues))
4915 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4917 if (aMapOfArgs.Find ("xdrawname", aValues))
4919 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4921 if (aMapOfArgs.Find ("ydrawname", aValues))
4923 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4925 if (aMapOfArgs.Find ("zdrawname", aValues))
4927 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4929 if (aMapOfArgs.Find ("xnameoffset", aValues))
4931 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4933 if (aMapOfArgs.Find ("ynameoffset", aValues))
4935 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4937 if (aMapOfArgs.Find ("znameoffset", aValues))
4939 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4943 if (aMapOfArgs.Find ("xnamecolor", aValues))
4945 if (!GetColor (aValues->Value(1), aColor))
4947 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
4950 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4952 if (aMapOfArgs.Find ("ynamecolor", aValues))
4954 if (!GetColor (aValues->Value(1), aColor))
4956 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
4959 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4961 if (aMapOfArgs.Find ("znamecolor", aValues))
4963 if (!GetColor (aValues->Value(1), aColor))
4965 Message::SendFail ("Syntax error: -znamecolor wrong color name");
4968 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4970 if (aMapOfArgs.Find ("xcolor", aValues))
4972 if (!GetColor (aValues->Value(1), aColor))
4974 Message::SendFail ("Syntax error: -xcolor wrong color name");
4977 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4979 if (aMapOfArgs.Find ("ycolor", aValues))
4981 if (!GetColor (aValues->Value(1), aColor))
4983 Message::SendFail ("Syntax error: -ycolor wrong color name");
4986 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4988 if (aMapOfArgs.Find ("zcolor", aValues))
4990 if (!GetColor (aValues->Value(1), aColor))
4992 Message::SendFail ("Syntax error: -zcolor wrong color name");
4995 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4999 if (aMapOfArgs.Find ("xticks", aValues))
5001 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5003 if (aMapOfArgs.Find ("yticks", aValues))
5005 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5007 if (aMapOfArgs.Find ("zticks", aValues))
5009 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
5011 if (aMapOfArgs.Find ("xticklength", aValues))
5013 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5015 if (aMapOfArgs.Find ("yticklength", aValues))
5017 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5019 if (aMapOfArgs.Find ("zticklength", aValues))
5021 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
5023 if (aMapOfArgs.Find ("xdrawticks", aValues))
5025 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5027 if (aMapOfArgs.Find ("ydrawticks", aValues))
5029 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5031 if (aMapOfArgs.Find ("zdrawticks", aValues))
5033 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
5037 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5039 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5041 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5043 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5045 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5047 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
5049 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5051 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5053 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5055 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5057 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5059 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5063 if (aMapOfArgs.Find ("arrowlength", aValues))
5065 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
5069 if (aMapOfArgs.Find ("namefont", aValues))
5071 aTrihedronData.SetNamesFont (aValues->Value(1));
5073 if (aMapOfArgs.Find ("valuesfont", aValues))
5075 aTrihedronData.SetValuesFont (aValues->Value(1));
5078 if (aMapOfArgs.Find ("drawgrid", aValues))
5080 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5082 if (aMapOfArgs.Find ("drawaxes", aValues))
5084 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5087 // The final step: display of erase trihedron
5090 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
5094 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5097 ViewerTest::GetAISContext()->UpdateCurrentViewer();
5098 ViewerTest::CurrentView()->Redraw();
5103 //==============================================================================
5106 //==============================================================================
5107 static int VTile (Draw_Interpretor& theDI,
5108 Standard_Integer theArgNb,
5109 const char** theArgVec)
5111 Handle(V3d_View) aView = ViewerTest::CurrentView();
5114 Message::SendFail ("Error: no active viewer");
5118 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5121 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5122 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5123 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5127 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5128 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5130 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5132 if (anArg == "-lowerleft"
5133 || anArg == "-upperleft")
5135 if (anArgIter + 3 < theArgNb)
5137 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5140 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5141 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5142 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5144 else if (anArg == "-total"
5145 || anArg == "-totalsize"
5146 || anArg == "-viewsize")
5148 if (anArgIter + 3 < theArgNb)
5150 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5153 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5154 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5155 if (aTile.TotalSize.x() < 1
5156 || aTile.TotalSize.y() < 1)
5158 Message::SendFail ("Error: total size is incorrect");
5162 else if (anArg == "-tilesize")
5164 if (anArgIter + 3 < theArgNb)
5166 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
5170 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5171 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5172 if (aTile.TileSize.x() < 1
5173 || aTile.TileSize.y() < 1)
5175 Message::SendFail ("Error: tile size is incorrect");
5179 else if (anArg == "-unset")
5181 aView->Camera()->SetTile (Graphic3d_CameraTile());
5187 if (aTile.TileSize.x() < 1
5188 || aTile.TileSize.y() < 1)
5190 Message::SendFail ("Error: tile size is undefined");
5193 else if (aTile.TotalSize.x() < 1
5194 || aTile.TotalSize.y() < 1)
5196 Message::SendFail ("Error: total size is undefined");
5200 aView->Camera()->SetTile (aTile);
5205 //! Format ZLayer ID.
5206 inline const char* formZLayerId (const Standard_Integer theLayerId)
5210 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5211 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5212 case Graphic3d_ZLayerId_Top: return "[TOP]";
5213 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5214 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5215 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5220 //! Print the ZLayer information.
5221 inline void printZLayerInfo (Draw_Interpretor& theDI,
5222 const Graphic3d_ZLayerSettings& theLayer)
5224 if (!theLayer.Name().IsEmpty())
5226 theDI << " Name: " << theLayer.Name() << "\n";
5228 if (theLayer.IsImmediate())
5230 theDI << " Immediate: TRUE\n";
5232 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
5233 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5234 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
5235 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5236 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5237 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5238 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5240 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5244 //==============================================================================
5245 //function : VZLayer
5246 //purpose : Test z layer operations for v3d viewer
5247 //==============================================================================
5248 static int VZLayer (Draw_Interpretor& theDI,
5249 Standard_Integer theArgNb,
5250 const char** theArgVec)
5252 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5253 if (aContextAIS.IsNull())
5255 Message::SendFail ("Error: no active viewer");
5259 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
5262 TColStd_SequenceOfInteger aLayers;
5263 aViewer->GetAllZLayers (aLayers);
5264 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5266 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5267 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5268 printZLayerInfo (theDI, aSettings);
5273 Standard_Integer anArgIter = 1;
5274 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5275 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5276 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5282 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5283 if (aFirstArg.IsIntegerValue())
5286 aLayerId = aFirstArg.IntegerValue();
5290 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
5297 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
5298 for (; anArgIter < theArgNb; ++anArgIter)
5300 // perform operation
5301 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5303 if (anUpdateTool.parseRedrawMode (anArg))
5307 else if (anArg == "-add"
5310 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5311 if (!aViewer->AddZLayer (aLayerId))
5313 Message::SendFail ("Error: can not add a new z layer");
5319 else if (anArg == "-insertbefore"
5320 && anArgIter + 1 < theArgNb
5321 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5324 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5325 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5327 Message::SendFail ("Error: can not add a new z layer");
5333 else if (anArg == "-insertafter"
5334 && anArgIter + 1 < theArgNb
5335 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5338 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5339 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5341 Message::SendFail ("Error: can not add a new z layer");
5347 else if (anArg == "-del"
5348 || anArg == "-delete"
5351 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5353 if (++anArgIter >= theArgNb)
5355 Message::SendFail ("Syntax error: id of z layer to remove is missing");
5359 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5362 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5363 || aLayerId == Graphic3d_ZLayerId_Default
5364 || aLayerId == Graphic3d_ZLayerId_Top
5365 || aLayerId == Graphic3d_ZLayerId_Topmost
5366 || aLayerId == Graphic3d_ZLayerId_TopOSD
5367 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5369 Message::SendFail ("Syntax error: standard Z layer can not be removed");
5373 // move all object displayed in removing layer to default layer
5374 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5375 anObjIter.More(); anObjIter.Next())
5377 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
5379 || aPrs->ZLayer() != aLayerId)
5383 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5386 if (!aViewer->RemoveZLayer (aLayerId))
5388 Message::SendFail ("Z layer can not be removed");
5392 theDI << aLayerId << " ";
5395 else if (anArg == "-get"
5398 TColStd_SequenceOfInteger aLayers;
5399 aViewer->GetAllZLayers (aLayers);
5400 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5402 theDI << aLayeriter.Value() << " ";
5407 else if (anArg == "-name")
5409 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5411 Message::SendFail ("Syntax error: id of Z layer is missing");
5415 if (++anArgIter >= theArgNb)
5417 Message::SendFail ("Syntax error: name is missing");
5421 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5422 aSettings.SetName (theArgVec[anArgIter]);
5423 aViewer->SetZLayerSettings (aLayerId, aSettings);
5425 else if (anArg == "-origin")
5427 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5429 Message::SendFail ("Syntax error: id of Z layer is missing");
5433 if (anArgIter + 2 >= theArgNb)
5435 Message::SendFail ("Syntax error: origin coordinates are missing");
5439 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5441 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5442 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5443 anOrigin.SetZ (0.0);
5444 if (anArgIter + 3 < theArgNb)
5446 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5453 aSettings.SetOrigin (anOrigin);
5454 aViewer->SetZLayerSettings (aLayerId, aSettings);
5456 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5457 && anArgIter + 1 < theArgNb
5458 && (anArg == "-cullingdistance"
5459 || anArg == "-cullingdist"
5460 || anArg == "-culldistance"
5461 || anArg == "-culldist"
5462 || anArg == "-distcull"
5463 || anArg == "-distculling"
5464 || anArg == "-distanceculling"))
5466 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5467 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5468 aSettings.SetCullingDistance (aDist);
5469 aViewer->SetZLayerSettings (aLayerId, aSettings);
5471 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5472 && anArgIter + 1 < theArgNb
5473 && (anArg == "-cullingsize"
5474 || anArg == "-cullsize"
5475 || anArg == "-sizecull"
5476 || anArg == "-sizeculling"))
5478 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5479 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5480 aSettings.SetCullingSize (aSize);
5481 aViewer->SetZLayerSettings (aLayerId, aSettings);
5483 else if (anArg == "-settings"
5484 || anArg == "settings")
5486 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5488 if (++anArgIter >= theArgNb)
5490 Message::SendFail ("Syntax error: id of Z layer is missing");
5494 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5497 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5498 printZLayerInfo (theDI, aSettings);
5500 else if (anArg == "-enable"
5501 || anArg == "enable"
5502 || anArg == "-disable"
5503 || anArg == "disable")
5505 const Standard_Boolean toEnable = anArg == "-enable"
5506 || anArg == "enable";
5507 if (++anArgIter >= theArgNb)
5509 Message::SendFail ("Syntax error: option name is missing");
5513 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5515 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5517 if (++anArgIter >= theArgNb)
5519 Message::SendFail ("Syntax error: id of Z layer is missing");
5523 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5526 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5527 if (aSubOp == "depthtest"
5528 || aSubOp == "test")
5530 aSettings.SetEnableDepthTest (toEnable);
5532 else if (aSubOp == "depthwrite"
5533 || aSubOp == "write")
5535 aSettings.SetEnableDepthWrite (toEnable);
5537 else if (aSubOp == "depthclear"
5538 || aSubOp == "clear")
5540 aSettings.SetClearDepth (toEnable);
5542 else if (aSubOp == "depthoffset"
5543 || aSubOp == "offset")
5545 Graphic3d_PolygonOffset aParams;
5546 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5549 if (anArgIter + 2 >= theArgNb)
5551 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
5555 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5556 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5558 aSettings.SetPolygonOffset (aParams);
5560 else if (aSubOp == "positiveoffset"
5561 || aSubOp == "poffset")
5565 aSettings.SetDepthOffsetPositive();
5569 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5572 else if (aSubOp == "negativeoffset"
5573 || aSubOp == "noffset")
5577 aSettings.SetDepthOffsetNegative();
5581 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5584 else if (aSubOp == "textureenv")
5586 aSettings.SetEnvironmentTexture (toEnable);
5588 else if (aSubOp == "raytracing")
5590 aSettings.SetRaytracable (toEnable);
5593 aViewer->SetZLayerSettings (aLayerId, aSettings);
5597 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
5605 // The interactive presentation of 2d layer item
5606 // for "vlayerline" command it provides a presentation of
5607 // line with user-defined linewidth, linetype and transparency.
5608 class V3d_LineItem : public AIS_InteractiveObject
5612 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
5615 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5616 Standard_Real X2, Standard_Real Y2,
5617 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5618 Standard_Real theWidth = 0.5,
5619 Standard_Real theTransp = 1.0);
5623 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5624 const Handle(Prs3d_Presentation)& thePrs,
5625 const Standard_Integer theMode) Standard_OVERRIDE;
5627 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5628 const Standard_Integer ) Standard_OVERRIDE
5633 Standard_Real myX1, myY1, myX2, myY2;
5634 Aspect_TypeOfLine myType;
5635 Standard_Real myWidth;
5638 // default constructor for line item
5639 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5640 Standard_Real X2, Standard_Real Y2,
5641 Aspect_TypeOfLine theType,
5642 Standard_Real theWidth,
5643 Standard_Real theTransp) :
5644 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5645 myType(theType), myWidth(theWidth)
5647 SetTransparency (1-theTransp);
5651 void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
5652 const Handle(Prs3d_Presentation)& thePresentation,
5653 const Standard_Integer )
5655 thePresentation->Clear();
5656 Quantity_Color aColor (Quantity_NOC_RED);
5657 Standard_Integer aWidth, aHeight;
5658 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
5659 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
5660 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5661 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5662 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5663 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5664 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5665 aGroup->AddPrimitiveArray (aPrim);
5668 //=============================================================================
5669 //function : VLayerLine
5670 //purpose : Draws line in the v3d view layer with given attributes: linetype,
5671 // : linewidth, transparency coefficient
5672 //============================================================================
5673 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5675 // get the active view
5676 Handle(V3d_View) aView = ViewerTest::CurrentView();
5679 di << "Call vinit before!\n";
5684 di << "Use: " << argv[0];
5685 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5686 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5687 di << " 0 - solid \n";
5688 di << " 1 - dashed \n";
5689 di << " 2 - dot \n";
5690 di << " 3 - dashdot\n";
5691 di << " transparency : { 0.0 - 1.0 } \n";
5692 di << " 0.0 - transparent\n";
5693 di << " 1.0 - visible \n";
5697 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5698 // get the input params
5699 Standard_Real X1 = Draw::Atof(argv[1]);
5700 Standard_Real Y1 = Draw::Atof(argv[2]);
5701 Standard_Real X2 = Draw::Atof(argv[3]);
5702 Standard_Real Y2 = Draw::Atof(argv[4]);
5704 Standard_Real aWidth = 0.5;
5705 Standard_Real aTransparency = 1.0;
5709 aWidth = Draw::Atof(argv[5]);
5711 // select appropriate line type
5712 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5714 && !ViewerTest::ParseLineType (argv[6], aLineType))
5716 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
5723 aTransparency = Draw::Atof(argv[7]);
5724 if (aTransparency < 0 || aTransparency > 1.0)
5725 aTransparency = 1.0;
5728 static Handle (V3d_LineItem) aLine;
5729 if (!aLine.IsNull())
5731 aContext->Erase (aLine, Standard_False);
5733 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5737 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
5738 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5739 aLine->SetToUpdate();
5740 aContext->Display (aLine, Standard_True);
5746 //==============================================================================
5749 //==============================================================================
5751 static int VGrid (Draw_Interpretor& /*theDI*/,
5752 Standard_Integer theArgNb,
5753 const char** theArgVec)
5755 Handle(V3d_View) aView = ViewerTest::CurrentView();
5756 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5757 if (aView.IsNull() || aViewer.IsNull())
5759 Message::SendFail ("Error: no active viewer");
5763 Aspect_GridType aType = aViewer->GridType();
5764 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
5765 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5766 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5767 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
5768 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
5769 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5771 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5773 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5777 else if (anArgIter + 1 < theArgNb
5778 && anArg == "-type")
5780 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5781 anArgNext.LowerCase();
5782 if (anArgNext == "r"
5783 || anArgNext == "rect"
5784 || anArgNext == "rectangular")
5786 aType = Aspect_GT_Rectangular;
5788 else if (anArgNext == "c"
5789 || anArgNext == "circ"
5790 || anArgNext == "circular")
5792 aType = Aspect_GT_Circular;
5796 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5800 else if (anArgIter + 1 < theArgNb
5801 && anArg == "-mode")
5803 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5804 anArgNext.LowerCase();
5805 if (anArgNext == "l"
5806 || anArgNext == "line"
5807 || anArgNext == "lines")
5809 aMode = Aspect_GDM_Lines;
5811 else if (anArgNext == "p"
5812 || anArgNext == "point"
5813 || anArgNext == "points")
5815 aMode = Aspect_GDM_Points;
5819 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5823 else if (anArgIter + 2 < theArgNb
5824 && (anArg == "-origin"
5825 || anArg == "-orig"))
5828 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5829 Draw::Atof (theArgVec[anArgIter + 2]));
5832 else if (anArgIter + 2 < theArgNb
5833 && anArg == "-step")
5836 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5837 Draw::Atof (theArgVec[anArgIter + 2]));
5838 if (aNewStepXY.x() <= 0.0
5839 || aNewStepXY.y() <= 0.0)
5841 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5846 else if (anArgIter + 1 < theArgNb
5847 && (anArg == "-angle"
5848 || anArg == "-rotangle"
5849 || anArg == "-rotationangle"))
5852 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5854 else if (anArgIter + 1 < theArgNb
5855 && (anArg == "-zoffset"
5859 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5861 else if (anArgIter + 1 < theArgNb
5862 && anArg == "-radius")
5866 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5867 if (aNewStepXY.x() <= 0.0)
5869 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
5873 else if (anArgIter + 2 < theArgNb
5874 && anArg == "-size")
5877 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5878 Draw::Atof (theArgVec[anArgIter + 2]));
5879 if (aNewStepXY.x() <= 0.0
5880 || aNewStepXY.y() <= 0.0)
5882 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5887 else if (anArg == "r"
5889 || anArg == "rectangular")
5891 aType = Aspect_GT_Rectangular;
5893 else if (anArg == "c"
5895 || anArg == "circular")
5897 aType = Aspect_GT_Circular;
5899 else if (anArg == "l"
5901 || anArg == "lines")
5903 aMode = Aspect_GDM_Lines;
5905 else if (anArg == "p"
5907 || anArg == "points")
5909 aMode = Aspect_GDM_Points;
5911 else if (anArgIter + 1 >= theArgNb
5914 aViewer->DeactivateGrid();
5919 Message::SendFail() << "Syntax error at '" << anArg << "'";
5924 if (aType == Aspect_GT_Rectangular)
5926 Graphic3d_Vec2d anOrigXY, aStepXY;
5927 Standard_Real aRotAngle = 0.0;
5928 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5931 anOrigXY = aNewOriginXY;
5935 aStepXY = aNewStepXY;
5939 aRotAngle = aNewRotAngle;
5941 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5942 if (hasSize || hasZOffset)
5944 Graphic3d_Vec3d aSize;
5945 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5948 aSize.x() = aNewSizeXY.x();
5949 aSize.y() = aNewSizeXY.y();
5953 aSize.z() = aNewZOffset;
5955 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5958 else if (aType == Aspect_GT_Circular)
5960 Graphic3d_Vec2d anOrigXY;
5961 Standard_Real aRadiusStep;
5962 Standard_Integer aDivisionNumber;
5963 Standard_Real aRotAngle = 0.0;
5964 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5967 anOrigXY = aNewOriginXY;
5971 aRadiusStep = aNewStepXY[0];
5972 aDivisionNumber = (int )aNewStepXY[1];
5973 if (aDivisionNumber < 1)
5975 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
5981 aRotAngle = aNewRotAngle;
5984 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5985 if (hasSize || hasZOffset)
5987 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5988 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5991 aRadius = aNewSizeXY.x();
5992 if (aNewSizeXY.y() != 0.0)
5994 Message::SendFail ("Syntax error: circular size should be specified as radius");
6000 aZOffset = aNewZOffset;
6002 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6005 aViewer->ActivateGrid (aType, aMode);
6009 //==============================================================================
6010 //function : VPriviledgedPlane
6012 //==============================================================================
6014 static int VPriviledgedPlane (Draw_Interpretor& theDI,
6015 Standard_Integer theArgNb,
6016 const char** theArgVec)
6018 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6020 Message::SendFail ("Error: wrong number of arguments! See usage:");
6021 theDI.PrintHelp (theArgVec[0]);
6025 // get the active viewer
6026 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6027 if (aViewer.IsNull())
6029 Message::SendFail ("Error: no active viewer");
6035 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6036 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6037 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6038 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6039 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6040 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6041 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6045 Standard_Integer anArgIdx = 1;
6046 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6047 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6048 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6049 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6050 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6051 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6053 gp_Ax3 aPriviledgedPlane;
6054 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6055 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6058 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6059 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6060 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6061 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6062 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6066 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6069 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6074 //==============================================================================
6075 //function : VConvert
6077 //==============================================================================
6079 static int VConvert (Draw_Interpretor& theDI,
6080 Standard_Integer theArgNb,
6081 const char** theArgVec)
6083 // get the active view
6084 Handle(V3d_View) aView = ViewerTest::CurrentView();
6087 Message::SendFail ("Error: no active viewer");
6091 enum { Model, Ray, View, Window, Grid } aMode = Model;
6093 // access coordinate arguments
6094 TColStd_SequenceOfReal aCoord;
6095 Standard_Integer anArgIdx = 1;
6096 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6098 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6099 if (!anArg.IsRealValue (Standard_True))
6103 aCoord.Append (anArg.RealValue());
6106 // non-numeric argument too early
6107 if (aCoord.IsEmpty())
6109 Message::SendFail ("Error: wrong number of arguments! See usage:");
6110 theDI.PrintHelp (theArgVec[0]);
6114 // collect all other arguments and options
6115 for (; anArgIdx < theArgNb; ++anArgIdx)
6117 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6119 if (anArg == "window") aMode = Window;
6120 else if (anArg == "view") aMode = View;
6121 else if (anArg == "grid") aMode = Grid;
6122 else if (anArg == "ray") aMode = Ray;
6125 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
6126 theDI.PrintHelp (theArgVec[0]);
6131 // complete input checks
6132 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6133 (aCoord.Length() == 2 && theArgNb > 4) ||
6134 (aCoord.Length() == 3 && theArgNb > 5))
6136 Message::SendFail ("Error: wrong number of arguments! See usage:");
6137 theDI.PrintHelp (theArgVec[0]);
6141 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6142 Standard_Integer aXYp[2] = {0, 0};
6144 // convert one-dimensional coordinate
6145 if (aCoord.Length() == 1)
6149 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6150 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
6152 Message::SendFail ("Error: wrong arguments! See usage:");
6153 theDI.PrintHelp (theArgVec[0]);
6158 // convert 2D coordinates from projection or view reference space
6159 if (aCoord.Length() == 2)
6164 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6165 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6169 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6170 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6174 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
6175 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6179 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6180 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6181 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6185 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6186 (Standard_Integer) aCoord (2),
6187 aXYZ[0], aXYZ[1], aXYZ[2],
6188 aXYZ[3], aXYZ[4], aXYZ[5]);
6189 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6193 Message::SendFail ("Error: wrong arguments! See usage:");
6194 theDI.PrintHelp (theArgVec[0]);
6199 // convert 3D coordinates from view reference space
6200 else if (aCoord.Length() == 3)
6205 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6206 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6210 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6211 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6215 Message::SendFail ("Error: wrong arguments! See usage:");
6216 theDI.PrintHelp (theArgVec[0]);
6224 //==============================================================================
6227 //==============================================================================
6229 static int VFps (Draw_Interpretor& theDI,
6230 Standard_Integer theArgNb,
6231 const char** theArgVec)
6233 // get the active view
6234 Handle(V3d_View) aView = ViewerTest::CurrentView();
6237 Message::SendFail ("Error: no active viewer");
6241 Standard_Integer aFramesNb = -1;
6242 Standard_Real aDuration = -1.0;
6243 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6245 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6248 && anArgIter + 1 < theArgNb
6249 && (anArg == "-duration"
6251 || anArg == "-time"))
6253 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6255 else if (aFramesNb < 0
6256 && anArg.IsIntegerValue())
6258 aFramesNb = anArg.IntegerValue();
6261 Message::SendFail() << "Syntax error at '" << anArg << "'";
6267 Message::SendFail() << "Syntax error at '" << anArg << "'";
6271 if (aFramesNb < 0 && aDuration < 0.0)
6276 // the time is meaningless for first call
6277 // due to async OpenGl rendering
6280 // redraw view in loop to estimate average values
6283 Standard_Integer aFrameIter = 1;
6284 for (;; ++aFrameIter)
6288 && aFrameIter >= aFramesNb)
6290 && aTimer.ElapsedTime() >= aDuration))
6297 const Standard_Real aTime = aTimer.ElapsedTime();
6298 aTimer.OSD_Chronometer::Show (aCpu);
6300 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6301 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
6303 // return statistics
6304 theDI << "FPS: " << aFpsAver << "\n"
6305 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6307 // compute additional statistics in ray-tracing mode
6308 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
6309 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6311 Graphic3d_Vec2i aWinSize (0, 0);
6312 aView->Window()->Size (aWinSize.x(), aWinSize.y());
6314 // 1 shadow ray and 1 secondary ray pew each bounce
6315 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
6316 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6323 //==============================================================================
6324 //function : VMemGpu
6326 //==============================================================================
6328 static int VMemGpu (Draw_Interpretor& theDI,
6329 Standard_Integer theArgNb,
6330 const char** theArgVec)
6333 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6334 if (aContextAIS.IsNull())
6336 Message::SendFail ("Error: no active viewer");
6340 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
6341 if (aDriver.IsNull())
6343 Message::SendFail ("Error: graphic driver not available");
6347 Standard_Size aFreeBytes = 0;
6348 TCollection_AsciiString anInfo;
6349 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
6351 Message::SendFail ("Error: information not available");
6355 if (theArgNb > 1 && *theArgVec[1] == 'f')
6357 theDI << Standard_Real (aFreeBytes);
6367 // ==============================================================================
6368 // function : VReadPixel
6370 // ==============================================================================
6371 static int VReadPixel (Draw_Interpretor& theDI,
6372 Standard_Integer theArgNb,
6373 const char** theArgVec)
6375 // get the active view
6376 Handle(V3d_View) aView = ViewerTest::CurrentView();
6379 Message::SendFail ("Error: no active viewer");
6382 else if (theArgNb < 3)
6384 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
6385 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
6389 Image_Format aFormat = Image_Format_RGBA;
6390 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
6392 Standard_Integer aWidth, aHeight;
6393 aView->Window()->Size (aWidth, aHeight);
6394 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
6395 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
6396 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
6398 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
6402 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
6403 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
6405 TCollection_AsciiString aParam (theArgVec[anIter]);
6407 if (aParam == "-rgb"
6409 || aParam == "-srgb"
6410 || aParam == "srgb")
6412 aFormat = Image_Format_RGB;
6413 aBufferType = Graphic3d_BT_RGB;
6414 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
6416 else if (aParam == "-hls"
6419 aFormat = Image_Format_RGB;
6420 aBufferType = Graphic3d_BT_RGB;
6421 toShowHls = Standard_True;
6423 else if (aParam == "-rgbf"
6424 || aParam == "rgbf")
6426 aFormat = Image_Format_RGBF;
6427 aBufferType = Graphic3d_BT_RGB;
6429 else if (aParam == "-rgba"
6431 || aParam == "-srgba"
6432 || aParam == "srgba")
6434 aFormat = Image_Format_RGBA;
6435 aBufferType = Graphic3d_BT_RGBA;
6436 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
6438 else if (aParam == "-rgbaf"
6439 || aParam == "rgbaf")
6441 aFormat = Image_Format_RGBAF;
6442 aBufferType = Graphic3d_BT_RGBA;
6444 else if (aParam == "-depth"
6445 || aParam == "depth")
6447 aFormat = Image_Format_GrayF;
6448 aBufferType = Graphic3d_BT_Depth;
6450 else if (aParam == "-name"
6451 || aParam == "name")
6453 toShowName = Standard_True;
6455 else if (aParam == "-hex"
6458 toShowHex = Standard_True;
6462 Message::SendFail() << "Syntax error at '" << aParam << "'";
6467 Image_PixMap anImage;
6468 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
6470 Message::SendFail ("Error: image allocation failed");
6473 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
6475 Message::SendFail ("Error: image dump failed");
6479 // redirect possible warning messages that could have been added by ToPixMap
6480 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
6481 // contaminate result of the command
6482 Standard_CString aWarnLog = theDI.Result();
6483 if (aWarnLog != NULL && aWarnLog[0] != '\0')
6485 std::cout << aWarnLog << std::endl;
6489 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
6492 if (aBufferType == Graphic3d_BT_RGBA)
6494 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
6498 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
6503 if (aBufferType == Graphic3d_BT_RGBA)
6505 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
6509 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
6514 switch (aBufferType)
6517 case Graphic3d_BT_RGB:
6521 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
6523 else if (toShow_sRGB)
6525 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
6526 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
6530 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
6534 case Graphic3d_BT_RGBA:
6536 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
6537 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
6540 case Graphic3d_BT_Depth:
6542 theDI << aColor.GetRGB().Red();
6551 //! Auxiliary presentation for an image plane.
6552 class ViewerTest_ImagePrs : public AIS_InteractiveObject
6555 //! Main constructor.
6556 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
6557 const Standard_Real theWidth,
6558 const Standard_Real theHeight,
6559 const TCollection_AsciiString& theLabel)
6560 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
6564 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
6566 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6567 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
6568 Graphic3d_MaterialAspect aMat;
6569 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
6570 aMat.SetAmbientColor (Quantity_NOC_BLACK);
6571 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
6572 aMat.SetSpecularColor (Quantity_NOC_BLACK);
6573 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
6574 aFillAspect->SetFrontMaterial (aMat);
6575 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
6576 aFillAspect->SetTextureMapOn();
6579 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
6580 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
6581 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
6582 myDrawer->SetTextAspect (aTextAspect);
6585 const gp_Dir aNorm (0.0, 0.0, 1.0);
6586 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
6587 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
6588 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
6589 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
6590 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
6591 myTris->AddEdge (1);
6592 myTris->AddEdge (2);
6593 myTris->AddEdge (3);
6594 myTris->AddEdge (3);
6595 myTris->AddEdge (2);
6596 myTris->AddEdge (4);
6598 myRect = new Graphic3d_ArrayOfPolylines (4);
6599 myRect->AddVertex (myTris->Vertice (1));
6600 myRect->AddVertex (myTris->Vertice (3));
6601 myRect->AddVertex (myTris->Vertice (4));
6602 myRect->AddVertex (myTris->Vertice (2));
6606 //! Returns TRUE for accepted display modes.
6607 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
6609 //! Compute presentation.
6610 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
6611 const Handle(Prs3d_Presentation)& thePrs,
6612 const Standard_Integer theMode) Standard_OVERRIDE
6618 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6619 aGroup->AddPrimitiveArray (myTris);
6620 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6621 aGroup->AddPrimitiveArray (myRect);
6622 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6627 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6628 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6629 aGroup->AddPrimitiveArray (myRect);
6630 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6636 //! Compute selection.
6637 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6641 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6642 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6643 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6644 theSel->Add (aSensitive);
6649 Handle(Graphic3d_ArrayOfTriangles) myTris;
6650 Handle(Graphic3d_ArrayOfPolylines) myRect;
6651 TCollection_AsciiString myLabel;
6652 Standard_Real myWidth;
6653 Standard_Real myHeight;
6656 //==============================================================================
6657 //function : VDiffImage
6658 //purpose : The draw-command compares two images.
6659 //==============================================================================
6661 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6665 Message::SendFail ("Syntax error: not enough arguments");
6669 Standard_Integer anArgIter = 1;
6670 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
6671 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
6672 TCollection_AsciiString aDiffImagePath;
6673 Standard_Real aTolColor = -1.0;
6674 Standard_Integer toBlackWhite = -1;
6675 Standard_Integer isBorderFilterOn = -1;
6676 Standard_Boolean isOldSyntax = Standard_False;
6677 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
6678 for (; anArgIter < theArgNb; ++anArgIter)
6680 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6682 if (anArgIter + 1 < theArgNb
6683 && (anArg == "-toleranceofcolor"
6684 || anArg == "-tolerancecolor"
6685 || anArg == "-tolerance"
6686 || anArg == "-toler"))
6688 aTolColor = Atof (theArgVec[++anArgIter]);
6689 if (aTolColor < 0.0 || aTolColor > 1.0)
6691 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6695 else if (anArg == "-blackwhite")
6697 Standard_Boolean toEnable = Standard_True;
6698 if (anArgIter + 1 < theArgNb
6699 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6703 toBlackWhite = toEnable ? 1 : 0;
6705 else if (anArg == "-borderfilter")
6707 Standard_Boolean toEnable = Standard_True;
6708 if (anArgIter + 1 < theArgNb
6709 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6713 isBorderFilterOn = toEnable ? 1 : 0;
6715 else if (anArg == "-exitonclose")
6717 ViewerTest_EventManager::ToExitOnCloseView() = true;
6718 if (anArgIter + 1 < theArgNb
6719 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
6724 else if (anArg == "-closeonescape"
6725 || anArg == "-closeonesc")
6727 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
6728 if (anArgIter + 1 < theArgNb
6729 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
6734 else if (anArgIter + 3 < theArgNb
6735 && anArg == "-display")
6737 aViewName = theArgVec[++anArgIter];
6738 aPrsNameRef = theArgVec[++anArgIter];
6739 aPrsNameNew = theArgVec[++anArgIter];
6740 if (anArgIter + 1 < theArgNb
6741 && *theArgVec[anArgIter + 1] != '-')
6743 aPrsNameDiff = theArgVec[++anArgIter];
6746 else if (aTolColor < 0.0
6747 && anArg.IsRealValue (Standard_True))
6749 isOldSyntax = Standard_True;
6750 aTolColor = anArg.RealValue();
6751 if (aTolColor < 0.0 || aTolColor > 1.0)
6753 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6757 else if (isOldSyntax
6758 && toBlackWhite == -1
6759 && (anArg == "0" || anArg == "1"))
6761 toBlackWhite = anArg == "1" ? 1 : 0;
6763 else if (isOldSyntax
6764 && isBorderFilterOn == -1
6765 && (anArg == "0" || anArg == "1"))
6767 isBorderFilterOn = anArg == "1" ? 1 : 0;
6769 else if (aDiffImagePath.IsEmpty())
6771 aDiffImagePath = theArgVec[anArgIter];
6775 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6780 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6781 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6782 if (!anImgRef->Load (anImgPathRef))
6784 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
6787 if (!anImgNew->Load (anImgPathNew))
6789 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
6793 // compare the images
6794 Image_Diff aComparer;
6795 Standard_Integer aDiffColorsNb = -1;
6796 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
6798 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6799 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6800 aDiffColorsNb = aComparer.Compare();
6801 theDI << aDiffColorsNb << "\n";
6804 // save image of difference
6805 Handle(Image_AlienPixMap) aDiff;
6806 if (aDiffColorsNb > 0
6807 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6809 aDiff = new Image_AlienPixMap();
6810 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6812 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
6815 aComparer.SaveDiffImage (*aDiff);
6816 if (!aDiffImagePath.IsEmpty()
6817 && !aDiff->Save (aDiffImagePath))
6819 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
6824 if (aViewName.IsEmpty())
6829 ViewerTest_Names aViewNames (aViewName);
6830 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6832 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6833 theDI.Eval (aCommand.ToCString());
6836 Standard_Integer aPxLeft = 0;
6837 Standard_Integer aPxTop = 0;
6838 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
6839 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6840 ? int(anImgRef->SizeY() * 2)
6841 : int(anImgRef->SizeY());
6842 TCollection_AsciiString aDisplayName;
6843 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
6844 aViewName, aDisplayName);
6846 Standard_Real aRatio = anImgRef->Ratio();
6847 Standard_Real aSizeX = 1.0;
6848 Standard_Real aSizeY = aSizeX / aRatio;
6850 OSD_Path aPath (anImgPathRef);
6851 TCollection_AsciiString aLabelRef;
6852 if (!aPath.Name().IsEmpty())
6854 aLabelRef = aPath.Name() + aPath.Extension();
6856 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6858 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6860 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6861 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6862 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
6865 OSD_Path aPath (anImgPathNew);
6866 TCollection_AsciiString aLabelNew;
6867 if (!aPath.Name().IsEmpty())
6869 aLabelNew = aPath.Name() + aPath.Extension();
6871 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
6873 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6875 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6876 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6877 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6879 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6880 if (!aDiff.IsNull())
6882 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6884 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6885 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6887 if (!aPrsNameDiff.IsEmpty())
6889 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6891 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6892 ViewerTest::CurrentView()->FitAll();
6896 //=======================================================================
6897 //function : VSelect
6898 //purpose : Emulates different types of selection by mouse:
6899 // 1) single click selection
6900 // 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6901 // 3) selection with polygon having corners at
6902 // pixel positions (x1,y1),...,(xn,yn)
6903 // 4) any of these selections with shift button pressed
6904 //=======================================================================
6905 static Standard_Integer VSelect (Draw_Interpretor& ,
6906 Standard_Integer theNbArgs,
6907 const char** theArgVec)
6909 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6912 Message::SendFail ("Error: no active viewer");
6916 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
6917 bool toAllowOverlap = false;
6918 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
6919 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6921 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6923 if (anArg == "-allowoverlap")
6925 toAllowOverlap = true;
6926 if (anArgIter + 1 < theNbArgs
6927 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
6932 else if (anArg == "-replace")
6934 aSelScheme = AIS_SelectionScheme_Replace;
6936 else if (anArg == "-replaceextra")
6938 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6940 else if (anArg == "-xor"
6941 || anArg == "-shift")
6943 aSelScheme = AIS_SelectionScheme_XOR;
6945 else if (anArg == "-add")
6947 aSelScheme = AIS_SelectionScheme_Add;
6949 else if (anArg == "-remove")
6951 aSelScheme = AIS_SelectionScheme_Remove;
6953 else if (anArgIter + 1 < theNbArgs
6954 && anArg.IsIntegerValue()
6955 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
6957 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6958 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6960 else if (anArgIter + 1 == theNbArgs
6961 && anArg.IsIntegerValue())
6963 if (anArg.IntegerValue() == 1)
6965 aSelScheme = AIS_SelectionScheme_XOR;
6970 Message::SendFail() << "Syntax error at '" << anArg << "'";
6977 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
6980 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
6981 if (aPnts.IsEmpty())
6983 aCtx->SelectDetected (aSelScheme);
6984 aCtx->CurrentViewer()->Invalidate();
6986 else if (aPnts.Length() == 2)
6989 && aPnts.First().y() < aPnts.Last().y())
6991 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6993 else if (!toAllowOverlap
6994 && aPnts.First().y() > aPnts.Last().y())
6996 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6999 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
7003 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
7005 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
7009 //=======================================================================
7010 //function : VMoveTo
7011 //purpose : Emulates cursor movement to defined pixel position
7012 //=======================================================================
7013 static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
7014 Standard_Integer theNbArgs,
7015 const char** theArgVec)
7017 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7018 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7019 if (aContext.IsNull())
7021 Message::SendFail ("Error: no active viewer");
7025 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7026 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7028 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7029 anArgStr.LowerCase();
7030 if (anArgStr == "-reset"
7031 || anArgStr == "-clear")
7033 if (anArgIter + 1 < theNbArgs)
7035 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
7039 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
7040 && aContext->CurrentViewer()->GridEcho();
7043 aContext->CurrentViewer()->HideGridEcho (aView);
7045 if (aContext->ClearDetected() || toEchoGrid)
7047 aContext->CurrentViewer()->RedrawImmediate();
7051 else if (aMousePos.x() == IntegerLast()
7052 && anArgStr.IsIntegerValue())
7054 aMousePos.x() = anArgStr.IntegerValue();
7056 else if (aMousePos.y() == IntegerLast()
7057 && anArgStr.IsIntegerValue())
7059 aMousePos.y() = anArgStr.IntegerValue();
7063 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7068 if (aMousePos.x() == IntegerLast()
7069 || aMousePos.y() == IntegerLast())
7071 Message::SendFail ("Syntax error: wrong number of arguments");
7075 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7076 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7077 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7079 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7080 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7081 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7083 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7085 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7089 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
7093 //=======================================================================
7094 //function : VSelectByAxis
7096 //=======================================================================
7097 static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
7098 Standard_Integer theNbArgs,
7099 const char** theArgVec)
7101 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7102 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7103 if (aContext.IsNull())
7105 Message::SendFail ("Error: no active viewer");
7109 TCollection_AsciiString aName;
7110 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
7111 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
7112 Standard_Boolean isOnlyTop = true;
7113 Standard_Boolean toShowNormal = false;
7114 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7116 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7117 anArgStr.LowerCase();
7118 if (anArgStr == "-display")
7120 if (anArgIter + 1 >= theNbArgs)
7122 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
7125 aName = theArgVec[++anArgIter];
7127 else if (anArgStr == "-onlytop")
7130 if (anArgIter + 1 < theNbArgs
7131 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
7136 else if (anArgStr == "-shownormal")
7138 toShowNormal = true;
7139 if (anArgIter + 1 < theNbArgs
7140 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
7145 else if (Precision::IsInfinite(anAxisLocation.X())
7146 && anArgStr.IsRealValue())
7148 anAxisLocation.SetX (anArgStr.RealValue());
7150 else if (Precision::IsInfinite(anAxisLocation.Y())
7151 && anArgStr.IsRealValue())
7153 anAxisLocation.SetY (anArgStr.RealValue());
7155 else if (Precision::IsInfinite(anAxisLocation.Z())
7156 && anArgStr.IsRealValue())
7158 anAxisLocation.SetZ (anArgStr.RealValue());
7160 else if (Precision::IsInfinite(anAxisDirection.X())
7161 && anArgStr.IsRealValue())
7163 anAxisDirection.SetX (anArgStr.RealValue());
7165 else if (Precision::IsInfinite(anAxisDirection.Y())
7166 && anArgStr.IsRealValue())
7168 anAxisDirection.SetY (anArgStr.RealValue());
7170 else if (Precision::IsInfinite(anAxisDirection.Z())
7171 && anArgStr.IsRealValue())
7173 anAxisDirection.SetZ (anArgStr.RealValue());
7177 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7182 if (Precision::IsInfinite (anAxisLocation.X()) ||
7183 Precision::IsInfinite (anAxisLocation.Y()) ||
7184 Precision::IsInfinite (anAxisLocation.Z()) ||
7185 Precision::IsInfinite (anAxisDirection.X()) ||
7186 Precision::IsInfinite (anAxisDirection.Y()) ||
7187 Precision::IsInfinite (anAxisDirection.Z()))
7189 Message::SendFail() << "Invalid axis location and direction";
7193 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
7195 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
7197 theDI << "There are no any intersections with this axis.";
7200 NCollection_Sequence<gp_Pnt> aPoints;
7201 NCollection_Sequence<Graphic3d_Vec3> aNormals;
7202 NCollection_Sequence<Standard_Real> aNormalLengths;
7203 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
7205 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
7206 aPoints.Append (aPickedData.Point);
7207 aNormals.Append (aPickedData.Normal);
7208 Standard_Real aNormalLength = 1.0;
7209 if (!aPickedData.Entity.IsNull())
7211 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
7213 aNormalLengths.Append (aNormalLength);
7215 if (!aName.IsEmpty())
7217 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
7218 aContext->SetAutoActivateSelection (false);
7221 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
7222 Handle(Geom_Axis2Placement) anAx2Axis =
7223 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
7224 Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
7225 anAISAxis->SetColor (anAxisColor);
7226 ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
7228 // Display axis start point
7229 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
7230 anAISStartPnt->SetMarker (Aspect_TOM_O);
7231 anAISStartPnt->SetColor (anAxisColor);
7232 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
7234 Standard_Integer anIndex = 0;
7235 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
7237 const gp_Pnt& aPoint = aPntIter.Value();
7239 // Display normals in intersection points
7242 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
7243 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
7244 if (aNormal.SquareModulus() > ShortRealEpsilon())
7246 gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
7247 Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
7248 anAISNormal->SetColor (Quantity_NOC_BLUE);
7249 anAISNormal->SetInfiniteState (false);
7250 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
7254 // Display intersection points
7255 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
7256 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
7257 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
7258 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
7259 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
7262 aContext->SetAutoActivateSelection (wasAuto);
7265 Standard_Integer anIndex = 0;
7266 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
7268 const gp_Pnt& aPnt = anIter.Value();
7269 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
7276 //! Global map storing all animations registered in ViewerTest.
7277 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7279 //! The animation calling the Draw Harness command.
7280 class ViewerTest_AnimationProc : public AIS_Animation
7282 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
7285 //! Main constructor.
7286 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7287 Draw_Interpretor* theDI,
7288 const TCollection_AsciiString& theCommand)
7289 : AIS_Animation (theAnimationName),
7291 myCommand (theCommand)
7298 //! Evaluate the command.
7299 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7301 TCollection_AsciiString aCmd = myCommand;
7302 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7303 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7304 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7305 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7306 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7307 myDrawInter->Eval (aCmd.ToCString());
7310 //! Find the keyword in the command and replace it with value.
7311 //! @return the position of the keyword to pass value
7312 void replace (TCollection_AsciiString& theCmd,
7313 const TCollection_AsciiString& theKey,
7314 const TCollection_AsciiString& theVal)
7316 TCollection_AsciiString aCmd (theCmd);
7318 const Standard_Integer aPos = aCmd.Search (theKey);
7324 TCollection_AsciiString aPart1, aPart2;
7325 Standard_Integer aPart1To = aPos - 1;
7327 && aPart1To <= theCmd.Length())
7329 aPart1 = theCmd.SubString (1, aPart1To);
7332 Standard_Integer aPart2From = aPos + theKey.Length();
7334 && aPart2From <= theCmd.Length())
7336 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7339 theCmd = aPart1 + theVal + aPart2;
7344 Draw_Interpretor* myDrawInter;
7345 TCollection_AsciiString myCommand;
7349 //! Auxiliary animation holder.
7350 class ViewerTest_AnimationHolder : public AIS_AnimationCamera
7352 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
7354 ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
7355 const Handle(V3d_View)& theView,
7356 const Standard_Boolean theIsFreeView)
7357 : AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
7359 if (theAnim->Timer().IsNull())
7361 theAnim->SetTimer (new Media_Timer());
7363 myTimer = theAnim->Timer();
7367 myCamStart = new Graphic3d_Camera (theView->Camera());
7373 virtual void StartTimer (const Standard_Real theStartPts,
7374 const Standard_Real thePlaySpeed,
7375 const Standard_Boolean theToUpdate,
7376 const Standard_Boolean theToStopTimer) Standard_OVERRIDE
7378 base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
7385 //! Pause animation.
7386 virtual void Pause() Standard_OVERRIDE
7388 myState = AnimationState_Paused;
7389 // default implementation would stop all children,
7390 // but we want to keep wrapped animation paused
7391 myAnimations.First()->Pause();
7396 virtual void Stop() Standard_OVERRIDE
7402 //! Process one step of the animation according to the input time progress, including all children.
7403 virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
7405 Handle(V3d_View) aView = myView;
7407 && !myCamStart.IsNull())
7409 myCamStart->Copy (aView->Camera());
7411 base_type::updateWithChildren (thePosition);
7413 && !myCamStart.IsNull())
7415 aView->Camera()->Copy (myCamStart);
7419 void abortPlayback()
7421 if (!myView.IsNull())
7428 //! Replace the animation with the new one.
7429 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7430 Handle(AIS_Animation)& theAnimation,
7431 const Handle(AIS_Animation)& theAnimationNew)
7433 theAnimationNew->CopyFrom (theAnimation);
7434 if (!theParentAnimation.IsNull())
7436 theParentAnimation->Replace (theAnimation, theAnimationNew);
7440 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7441 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7443 theAnimation = theAnimationNew;
7446 //! Parse the point.
7447 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7449 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
7450 if (!anXYZ[0].IsRealValue (Standard_True)
7451 || !anXYZ[1].IsRealValue (Standard_True)
7452 || !anXYZ[2].IsRealValue (Standard_True))
7454 return Standard_False;
7457 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7458 return Standard_True;
7461 //! Parse the quaternion.
7462 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7464 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
7465 if (!anXYZW[0].IsRealValue (Standard_True)
7466 || !anXYZW[1].IsRealValue (Standard_True)
7467 || !anXYZW[2].IsRealValue (Standard_True)
7468 || !anXYZW[3].IsRealValue (Standard_True))
7470 return Standard_False;
7473 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7474 return Standard_True;
7477 //! Auxiliary class for flipping image upside-down.
7482 //! Empty constructor.
7483 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7485 //! Perform flipping.
7486 Standard_Boolean FlipY (Image_PixMap& theImage)
7488 if (theImage.IsEmpty()
7489 || theImage.SizeX() == 0
7490 || theImage.SizeY() == 0)
7492 return Standard_False;
7495 const Standard_Size aRowSize = theImage.SizeRowBytes();
7496 if (myTmp.Size() < aRowSize
7497 && !myTmp.Allocate (aRowSize))
7499 return Standard_False;
7502 // for odd height middle row should be left as is
7503 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7504 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7506 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7507 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7508 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7509 memcpy (aTop, aBot, aRowSize);
7510 memcpy (aBot, myTmp.Data(), aRowSize);
7512 return Standard_True;
7516 NCollection_Buffer myTmp;
7521 //=================================================================================================
7522 //function : VViewParams
7523 //purpose : Gets or sets AIS View characteristics
7524 //=================================================================================================
7525 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7527 Handle(V3d_View) aView = ViewerTest::CurrentView();
7530 Message::SendFail ("Error: no active viewer");
7534 Standard_Boolean toSetProj = Standard_False;
7535 Standard_Boolean toSetUp = Standard_False;
7536 Standard_Boolean toSetAt = Standard_False;
7537 Standard_Boolean toSetEye = Standard_False;
7538 Standard_Boolean toSetScale = Standard_False;
7539 Standard_Boolean toSetSize = Standard_False;
7540 Standard_Boolean toSetCenter2d = Standard_False;
7541 Standard_Real aViewScale = aView->Scale();
7542 Standard_Real aViewAspect = aView->Camera()->Aspect();
7543 Standard_Real aViewSize = 1.0;
7544 Graphic3d_Vec2i aCenter2d;
7545 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7546 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7547 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7548 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7549 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
7550 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
7551 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
7554 // print all of the available view parameters
7559 "Proj: %12g %12g %12g\n"
7560 "Up: %12g %12g %12g\n"
7561 "At: %12g %12g %12g\n"
7562 "Eye: %12g %12g %12g\n"
7563 "OrientMat: %12g %12g %12g %12g\n"
7564 " %12g %12g %12g %12g\n"
7565 " %12g %12g %12g %12g\n"
7566 " %12g %12g %12g %12g\n"
7567 "ProjMat: %12g %12g %12g %12g\n"
7568 " %12g %12g %12g %12g\n"
7569 " %12g %12g %12g %12g\n"
7570 " %12g %12g %12g %12g\n",
7571 aViewScale, aViewAspect,
7572 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7573 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7574 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7575 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
7576 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
7577 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
7578 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
7579 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
7580 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
7581 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
7582 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
7583 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
7588 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7589 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
7591 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7593 if (anUpdateTool.parseRedrawMode (anArg))
7597 else if (anArg == "-cmd"
7598 || anArg == "-command"
7599 || anArg == "-args")
7608 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7609 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7610 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7613 else if (anArg == "-scale"
7614 || anArg == "-size")
7616 if (anArgIter + 1 < theArgsNb
7617 && *theArgVec[anArgIter + 1] != '-')
7619 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
7620 if (aValueArg.IsRealValue (Standard_True))
7623 if (anArg == "-scale")
7625 toSetScale = Standard_True;
7626 aViewScale = aValueArg.RealValue();
7628 else if (anArg == "-size")
7630 toSetSize = Standard_True;
7631 aViewSize = aValueArg.RealValue();
7636 if (anArg == "-scale")
7638 theDi << "Scale: " << aView->Scale() << "\n";
7640 else if (anArg == "-size")
7642 Graphic3d_Vec2d aSizeXY;
7643 aView->Size (aSizeXY.x(), aSizeXY.y());
7644 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7647 else if (anArg == "-eye"
7650 || anArg == "-proj")
7652 if (anArgIter + 3 < theArgsNb)
7655 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7658 if (anArg == "-eye")
7660 toSetEye = Standard_True;
7663 else if (anArg == "-at")
7665 toSetAt = Standard_True;
7668 else if (anArg == "-up")
7670 toSetUp = Standard_True;
7673 else if (anArg == "-proj")
7675 toSetProj = Standard_True;
7682 if (anArg == "-eye")
7684 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7686 else if (anArg == "-at")
7688 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7690 else if (anArg == "-up")
7692 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7694 else if (anArg == "-proj")
7696 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7699 else if (anArg == "-center")
7701 if (anArgIter + 2 < theArgsNb)
7703 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7704 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7705 if (anX.IsIntegerValue()
7706 && anY.IsIntegerValue())
7708 toSetCenter2d = Standard_True;
7709 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7715 Message::SendFail() << "Syntax error at '" << anArg << "'";
7720 // change view parameters in proper order
7723 aView->SetScale (aViewScale);
7727 aView->SetSize (aViewSize);
7731 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7735 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7739 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7743 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7747 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
7753 //==============================================================================
7754 //function : V2DMode
7756 //==============================================================================
7757 static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7759 bool is2dMode = true;
7760 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7761 if (aV3dView.IsNull())
7763 Message::SendFail ("Error: no active viewer");
7766 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7768 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7769 TCollection_AsciiString anArgCase = anArg;
7770 anArgCase.LowerCase();
7771 if (anArgIt + 1 < theArgsNb
7772 && anArgCase == "-name")
7774 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7775 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7776 if (!ViewerTest_myViews.IsBound1 (aViewName))
7778 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
7781 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7783 else if (anArgCase == "-mode")
7785 if (anArgIt + 1 < theArgsNb
7786 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
7791 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
7797 Message::SendFail() << "Syntax error: unknown argument " << anArg;
7802 aV3dView->SetView2DMode (is2dMode);
7806 //==============================================================================
7807 //function : VAnimation
7809 //==============================================================================
7810 static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7811 Standard_Integer theArgNb,
7812 const char** theArgVec)
7814 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7817 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7818 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7820 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
7826 Message::SendFail ("Error: no active viewer");
7830 Standard_Integer anArgIter = 1;
7831 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7832 if (aNameArg.IsEmpty())
7834 Message::SendFail ("Syntax error: animation name is not defined");
7838 TCollection_AsciiString aNameArgLower = aNameArg;
7839 aNameArgLower.LowerCase();
7840 if (aNameArgLower == "-reset"
7841 || aNameArgLower == "-clear")
7843 ViewerTest_AnimationTimelineMap.Clear();
7846 else if (aNameArg.Value (1) == '-')
7848 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
7852 const char* aNameSplitter = "/";
7853 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7854 if (aSplitPos == -1)
7856 aNameSplitter = ".";
7857 aSplitPos = aNameArg.Search (aNameSplitter);
7860 // find existing or create a new animation by specified name within syntax "parent.child".
7861 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7862 for (; !aNameArg.IsEmpty();)
7864 TCollection_AsciiString aNameParent;
7865 if (aSplitPos != -1)
7867 if (aSplitPos == aNameArg.Length())
7869 Message::SendFail ("Syntax error: animation name is not defined");
7873 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7874 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7876 aSplitPos = aNameArg.Search (aNameSplitter);
7880 aNameParent = aNameArg;
7884 if (anAnimation.IsNull())
7886 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7888 anAnimation = new AIS_Animation (aNameParent);
7889 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7891 aRootAnimation = anAnimation;
7895 aParentAnimation = anAnimation;
7896 anAnimation = aParentAnimation->Find (aNameParent);
7897 if (anAnimation.IsNull())
7899 anAnimation = new AIS_Animation (aNameParent);
7900 aParentAnimation->Add (anAnimation);
7905 if (anArgIter >= theArgNb)
7907 // just print the list of children
7908 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
7910 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
7915 // animation parameters
7916 Standard_Boolean toPlay = Standard_False;
7917 Standard_Real aPlaySpeed = 1.0;
7918 Standard_Real aPlayStartTime = anAnimation->StartPts();
7919 Standard_Real aPlayDuration = anAnimation->Duration();
7920 Standard_Boolean isFreeCamera = Standard_False;
7921 Standard_Boolean toPauseOnClick = Standard_True;
7922 Standard_Boolean isLockLoop = Standard_False;
7924 // video recording parameters
7925 TCollection_AsciiString aRecFile;
7926 Image_VideoParams aRecParams;
7928 Handle(V3d_View) aView = ViewerTest::CurrentView();
7929 for (; anArgIter < theArgNb; ++anArgIter)
7931 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7934 if (anArg == "-reset"
7935 || anArg == "-clear")
7937 anAnimation->Clear();
7939 else if (anArg == "-remove"
7941 || anArg == "-delete")
7943 if (!aParentAnimation.IsNull())
7945 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7949 aParentAnimation->Remove (anAnimation);
7953 else if (anArg == "-play")
7955 toPlay = Standard_True;
7956 if (++anArgIter < theArgNb)
7958 if (*theArgVec[anArgIter] == '-')
7963 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7965 if (++anArgIter < theArgNb)
7967 if (*theArgVec[anArgIter] == '-')
7972 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7976 else if (anArg == "-resume")
7978 toPlay = Standard_True;
7979 aPlayStartTime = anAnimation->ElapsedTime();
7980 if (++anArgIter < theArgNb)
7982 if (*theArgVec[anArgIter] == '-')
7988 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7991 else if (anArg == "-pause")
7993 anAnimation->Pause();
7995 else if (anArg == "-stop")
7997 anAnimation->Stop();
7999 else if (anArg == "-playspeed"
8000 || anArg == "-speed")
8002 if (++anArgIter >= theArgNb)
8004 Message::SendFail() << "Syntax error at " << anArg << "";
8007 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8009 else if (anArg == "-lock"
8010 || anArg == "-lockloop"
8011 || anArg == "-playlockloop")
8013 isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
8015 else if (anArg == "-freecamera"
8016 || anArg == "-nofreecamera"
8017 || anArg == "-playfreecamera"
8018 || anArg == "-noplayfreecamera"
8019 || anArg == "-freelook"
8020 || anArg == "-nofreelook")
8022 isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
8024 else if (anArg == "-pauseonclick"
8025 || anArg == "-nopauseonclick"
8026 || anArg == "-nopause")
8028 toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
8030 // video recodring options
8031 else if (anArg == "-rec"
8032 || anArg == "-record")
8034 if (++anArgIter >= theArgNb)
8036 Message::SendFail() << "Syntax error at " << anArg;
8040 aRecFile = theArgVec[anArgIter];
8041 if (aRecParams.FpsNum <= 0)
8043 aRecParams.FpsNum = 24;
8046 if (anArgIter + 2 < theArgNb
8047 && *theArgVec[anArgIter + 1] != '-'
8048 && *theArgVec[anArgIter + 2] != '-')
8050 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8051 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8052 if (aWidthArg .IsIntegerValue()
8053 && aHeightArg.IsIntegerValue())
8055 aRecParams.Width = aWidthArg .IntegerValue();
8056 aRecParams.Height = aHeightArg.IntegerValue();
8061 else if (anArg == "-fps")
8063 if (++anArgIter >= theArgNb)
8065 Message::SendFail() << "Syntax error at " << anArg;
8069 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8070 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8071 if (aSplitIndex == 0)
8073 aRecParams.FpsNum = aFpsArg.IntegerValue();
8077 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8078 aFpsArg.Split (aFpsArg.Length() - 1);
8079 const TCollection_AsciiString aNumStr = aFpsArg;
8080 aRecParams.FpsNum = aNumStr.IntegerValue();
8081 aRecParams.FpsDen = aDenStr.IntegerValue();
8082 if (aRecParams.FpsDen < 1)
8084 Message::SendFail() << "Syntax error at " << anArg;
8089 else if (anArg == "-format")
8091 if (++anArgIter >= theArgNb)
8093 Message::SendFail() << "Syntax error at " << anArg;
8096 aRecParams.Format = theArgVec[anArgIter];
8098 else if (anArg == "-pix_fmt"
8099 || anArg == "-pixfmt"
8100 || anArg == "-pixelformat")
8102 if (++anArgIter >= theArgNb)
8104 Message::SendFail() << "Syntax error at " << anArg;
8107 aRecParams.PixelFormat = theArgVec[anArgIter];
8109 else if (anArg == "-codec"
8110 || anArg == "-vcodec"
8111 || anArg == "-videocodec")
8113 if (++anArgIter >= theArgNb)
8115 Message::SendFail() << "Syntax error at " << anArg;
8118 aRecParams.VideoCodec = theArgVec[anArgIter];
8120 else if (anArg == "-crf"
8121 || anArg == "-preset"
8124 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8125 if (++anArgIter >= theArgNb)
8127 Message::SendFail() << "Syntax error at " << anArg;
8131 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8133 // animation definition options
8134 else if (anArg == "-start"
8135 || anArg == "-starttime"
8136 || anArg == "-startpts")
8138 if (++anArgIter >= theArgNb)
8140 Message::SendFail() << "Syntax error at " << anArg;
8144 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8145 aRootAnimation->UpdateTotalDuration();
8147 else if (anArg == "-end"
8148 || anArg == "-endtime"
8149 || anArg == "-endpts")
8151 if (++anArgIter >= theArgNb)
8153 Message::SendFail() << "Syntax error at " << anArg;
8157 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8158 aRootAnimation->UpdateTotalDuration();
8160 else if (anArg == "-dur"
8161 || anArg == "-duration")
8163 if (++anArgIter >= theArgNb)
8165 Message::SendFail() << "Syntax error at " << anArg;
8169 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8170 aRootAnimation->UpdateTotalDuration();
8172 else if (anArg == "-command"
8174 || anArg == "-invoke"
8176 || anArg == "-proc")
8178 if (++anArgIter >= theArgNb)
8180 Message::SendFail() << "Syntax error at " << anArg;
8184 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8185 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8187 else if (anArg == "-objecttrsf"
8188 || anArg == "-objectransformation"
8189 || anArg == "-objtransformation"
8190 || anArg == "-objtrsf"
8191 || anArg == "-object"
8194 if (++anArgIter >= theArgNb)
8196 Message::SendFail() << "Syntax error at " << anArg;
8200 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8201 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8202 Handle(AIS_InteractiveObject) anObject;
8203 if (!aMapOfAIS.Find2 (anObjName, anObject))
8205 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
8209 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8210 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8211 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8212 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8213 Standard_Boolean isTrsfSet = Standard_False;
8214 Standard_Integer aTrsfArgIter = anArgIter + 1;
8215 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8217 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8218 aTrsfArg.LowerCase();
8219 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8220 if (aTrsfArg.StartsWith ("-rotation")
8221 || aTrsfArg.StartsWith ("-rot"))
8223 isTrsfSet = Standard_True;
8224 if (aTrsfArgIter + 4 >= theArgNb
8225 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8227 Message::SendFail() << "Syntax error at " << aTrsfArg;
8232 else if (aTrsfArg.StartsWith ("-location")
8233 || aTrsfArg.StartsWith ("-loc"))
8235 isTrsfSet = Standard_True;
8236 if (aTrsfArgIter + 3 >= theArgNb
8237 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8239 Message::SendFail() << "Syntax error at " << aTrsfArg;
8244 else if (aTrsfArg.StartsWith ("-scale"))
8246 isTrsfSet = Standard_True;
8247 if (++aTrsfArgIter >= theArgNb)
8249 Message::SendFail() << "Syntax error at " << aTrsfArg;
8253 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
8254 if (!aScaleStr.IsRealValue (Standard_True))
8256 Message::SendFail() << "Syntax error at " << aTrsfArg;
8259 aScales[anIndex] = aScaleStr.RealValue();
8263 anArgIter = aTrsfArgIter - 1;
8269 Message::SendFail() << "Syntax error at " << anArg;
8272 else if (aTrsfArgIter >= theArgNb)
8274 anArgIter = theArgNb;
8277 aTrsfs[0].SetRotation (aRotQuats[0]);
8278 aTrsfs[1].SetRotation (aRotQuats[1]);
8279 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8280 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8281 aTrsfs[0].SetScaleFactor (aScales[0]);
8282 aTrsfs[1].SetScaleFactor (aScales[1]);
8284 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8285 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8287 else if (anArg == "-viewtrsf"
8288 || anArg == "-view")
8290 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8291 if (aCamAnimation.IsNull())
8293 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8294 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8297 Handle(Graphic3d_Camera) aCams[2] =
8299 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8300 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8303 Standard_Boolean isTrsfSet = Standard_False;
8304 Standard_Integer aViewArgIter = anArgIter + 1;
8305 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8307 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8308 aViewArg.LowerCase();
8309 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8310 if (aViewArg.StartsWith ("-scale"))
8312 isTrsfSet = Standard_True;
8313 if (++aViewArgIter >= theArgNb)
8315 Message::SendFail() << "Syntax error at " << anArg;
8319 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
8320 if (!aScaleStr.IsRealValue (Standard_True))
8322 Message::SendFail() << "Syntax error at " << aViewArg;
8325 Standard_Real aScale = aScaleStr.RealValue();
8326 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8327 aCams[anIndex]->SetScale (aScale);
8329 else if (aViewArg.StartsWith ("-eye")
8330 || aViewArg.StartsWith ("-center")
8331 || aViewArg.StartsWith ("-at")
8332 || aViewArg.StartsWith ("-up"))
8334 isTrsfSet = Standard_True;
8336 if (aViewArgIter + 3 >= theArgNb
8337 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8339 Message::SendFail() << "Syntax error at " << aViewArg;
8344 if (aViewArg.StartsWith ("-eye"))
8346 aCams[anIndex]->SetEye (anXYZ);
8348 else if (aViewArg.StartsWith ("-center")
8349 || aViewArg.StartsWith ("-at"))
8351 aCams[anIndex]->SetCenter (anXYZ);
8353 else if (aViewArg.StartsWith ("-up"))
8355 aCams[anIndex]->SetUp (anXYZ);
8360 anArgIter = aViewArgIter - 1;
8366 Message::SendFail() << "Syntax error at " << anArg;
8369 else if (aViewArgIter >= theArgNb)
8371 anArgIter = theArgNb;
8374 aCamAnimation->SetCameraStart(aCams[0]);
8375 aCamAnimation->SetCameraEnd (aCams[1]);
8379 Message::SendFail() << "Syntax error at " << anArg;
8384 ViewerTest::CurrentEventManager()->AbortViewAnimation();
8385 ViewerTest::CurrentEventManager()->SetObjectsAnimation (Handle(AIS_Animation)());
8386 if (!toPlay && aRecFile.IsEmpty())
8391 // Start animation timeline and process frame updating.
8392 if (aRecParams.FpsNum <= 0
8395 Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
8396 aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
8397 ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
8398 ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
8399 ViewerTest::CurrentEventManager()->ProcessExpose();
8403 // Perform video recording
8404 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8405 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
8406 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
8408 OSD_Timer aPerfTimer;
8411 Handle(Image_VideoRecorder) aRecorder;
8412 ImageFlipper aFlipper;
8413 Handle(Draw_ProgressIndicator) aProgress;
8414 if (!aRecFile.IsEmpty())
8416 if (aRecParams.Width <= 0
8417 || aRecParams.Height <= 0)
8419 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8422 aRecorder = new Image_VideoRecorder();
8423 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8425 Message::SendFail ("Error: failed to open video file for recording");
8429 aProgress = new Draw_ProgressIndicator (theDI, 1);
8432 // Manage frame-rated animation here
8433 Standard_Real aPts = aPlayStartTime;
8434 int64_t aNbFrames = 0;
8435 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8436 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
8437 Standard_Integer aSecondsProgress = 0;
8438 for (; aPts <= anUpperPts && aPS.More();)
8440 Standard_Real aRecPts = 0.0;
8441 if (aRecParams.FpsNum > 0)
8443 aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
8447 aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
8450 aPts = aPlayStartTime + aRecPts;
8452 if (!anAnimation->Update (aPts))
8457 if (!aRecorder.IsNull())
8459 V3d_ImageDumpOptions aDumpParams;
8460 aDumpParams.Width = aRecParams.Width;
8461 aDumpParams.Height = aRecParams.Height;
8462 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8463 aDumpParams.StereoOptions = V3d_SDO_MONO;
8464 aDumpParams.ToAdjustAspect = Standard_True;
8465 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8467 Message::SendFail ("Error: view dump is failed");
8470 aFlipper.FlipY (aRecorder->ChangeFrame());
8471 if (!aRecorder->PushFrame())
8481 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8489 anAnimation->Stop();
8490 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8491 theDI << "Average FPS: " << aRecFps << "\n"
8492 << "Nb. Frames: " << Standard_Real(aNbFrames);
8495 aView->SetImmediateUpdate (wasImmediateUpdate);
8500 //=======================================================================
8501 //function : VChangeSelected
8502 //purpose : Adds the shape to selection or remove one from it
8503 //=======================================================================
8504 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8505 Standard_Integer argc,
8510 di<<"Usage : " << argv[0] << " shape \n";
8514 TCollection_AsciiString aName(argv[1]);
8515 Handle(AIS_InteractiveObject) anAISObject;
8516 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8517 || anAISObject.IsNull())
8519 di<<"Use 'vdisplay' before";
8523 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
8527 //=======================================================================
8528 //function : VNbSelected
8529 //purpose : Returns number of selected objects
8530 //=======================================================================
8531 static Standard_Integer VNbSelected (Draw_Interpretor& di,
8532 Standard_Integer argc,
8537 di << "Usage : " << argv[0] << "\n";
8540 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8541 if(aContext.IsNull())
8543 di << "use 'vinit' command before " << argv[0] << "\n";
8546 di << aContext->NbSelected() << "\n";
8550 //=======================================================================
8551 //function : VSetViewSize
8553 //=======================================================================
8554 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8555 Standard_Integer argc,
8558 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8559 if(aContext.IsNull())
8561 di << "use 'vinit' command before " << argv[0] << "\n";
8566 di<<"Usage : " << argv[0] << " Size\n";
8569 Standard_Real aSize = Draw::Atof (argv[1]);
8572 di<<"Bad Size value : " << aSize << "\n";
8576 Handle(V3d_View) aView = ViewerTest::CurrentView();
8577 aView->SetSize(aSize);
8581 //=======================================================================
8582 //function : VMoveView
8584 //=======================================================================
8585 static Standard_Integer VMoveView (Draw_Interpretor& di,
8586 Standard_Integer argc,
8589 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8590 if(aContext.IsNull())
8592 di << "use 'vinit' command before " << argv[0] << "\n";
8595 if(argc < 4 || argc > 5)
8597 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8600 Standard_Real Dx = Draw::Atof (argv[1]);
8601 Standard_Real Dy = Draw::Atof (argv[2]);
8602 Standard_Real Dz = Draw::Atof (argv[3]);
8603 Standard_Boolean aStart = Standard_True;
8606 aStart = (Draw::Atoi (argv[4]) > 0);
8609 Handle(V3d_View) aView = ViewerTest::CurrentView();
8610 aView->Move(Dx,Dy,Dz,aStart);
8614 //=======================================================================
8615 //function : VTranslateView
8617 //=======================================================================
8618 static Standard_Integer VTranslateView (Draw_Interpretor& di,
8619 Standard_Integer argc,
8622 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8623 if(aContext.IsNull())
8625 di << "use 'vinit' command before " << argv[0] << "\n";
8628 if(argc < 4 || argc > 5)
8630 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8633 Standard_Real Dx = Draw::Atof (argv[1]);
8634 Standard_Real Dy = Draw::Atof (argv[2]);
8635 Standard_Real Dz = Draw::Atof (argv[3]);
8636 Standard_Boolean aStart = Standard_True;
8639 aStart = (Draw::Atoi (argv[4]) > 0);
8642 Handle(V3d_View) aView = ViewerTest::CurrentView();
8643 aView->Translate(Dx,Dy,Dz,aStart);
8647 //=======================================================================
8648 //function : VTurnView
8650 //=======================================================================
8651 static Standard_Integer VTurnView (Draw_Interpretor& di,
8652 Standard_Integer argc,
8655 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8656 if(aContext.IsNull()) {
8657 di << "use 'vinit' command before " << argv[0] << "\n";
8660 if(argc < 4 || argc > 5){
8661 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8664 Standard_Real Ax = Draw::Atof (argv[1]);
8665 Standard_Real Ay = Draw::Atof (argv[2]);
8666 Standard_Real Az = Draw::Atof (argv[3]);
8667 Standard_Boolean aStart = Standard_True;
8670 aStart = (Draw::Atoi (argv[4]) > 0);
8673 Handle(V3d_View) aView = ViewerTest::CurrentView();
8674 aView->Turn(Ax,Ay,Az,aStart);
8678 //==============================================================================
8679 //function : VTextureEnv
8680 //purpose : ENables or disables environment mapping
8681 //==============================================================================
8682 class OCC_TextureEnv : public Graphic3d_TextureEnv
8685 OCC_TextureEnv(const Standard_CString FileName);
8686 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8687 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8688 const Standard_Boolean theModulateFlag,
8689 const Graphic3d_TypeOfTextureFilter theFilter,
8690 const Standard_ShortReal theXScale,
8691 const Standard_ShortReal theYScale,
8692 const Standard_ShortReal theXShift,
8693 const Standard_ShortReal theYShift,
8694 const Standard_ShortReal theAngle);
8695 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
8697 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
8699 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8700 : Graphic3d_TextureEnv(theFileName)
8704 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8705 : Graphic3d_TextureEnv(theTexId)
8709 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8710 const Standard_Boolean theModulateFlag,
8711 const Graphic3d_TypeOfTextureFilter theFilter,
8712 const Standard_ShortReal theXScale,
8713 const Standard_ShortReal theYScale,
8714 const Standard_ShortReal theXShift,
8715 const Standard_ShortReal theYShift,
8716 const Standard_ShortReal theAngle)
8718 myParams->SetRepeat (theRepeatFlag);
8719 myParams->SetModulate (theModulateFlag);
8720 myParams->SetFilter (theFilter);
8721 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8722 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8723 myParams->SetRotation (theAngle);
8726 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
8728 // get the active view
8729 Handle(V3d_View) aView = ViewerTest::CurrentView();
8732 Message::SendFail ("Error: no active viewer");
8736 // Checking the input arguments
8737 Standard_Boolean anEnableFlag = Standard_False;
8738 Standard_Boolean isOk = theArgNb >= 2;
8741 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8742 anEnableFlag = anEnableOpt.IsEqual("on");
8743 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8747 isOk = (theArgNb == 3 || theArgNb == 11);
8750 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8751 isOk = (!aTextureOpt.IsIntegerValue() ||
8752 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8754 if (isOk && theArgNb == 11)
8756 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8757 aModulateOpt(theArgVec[4]),
8758 aFilterOpt (theArgVec[5]),
8759 aSScaleOpt (theArgVec[6]),
8760 aTScaleOpt (theArgVec[7]),
8761 aSTransOpt (theArgVec[8]),
8762 aTTransOpt (theArgVec[9]),
8763 anAngleOpt (theArgVec[10]);
8764 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8765 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8766 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
8767 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8768 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8769 anAngleOpt.IsRealValue (Standard_True));
8776 Message::SendFail() << "Usage:\n"
8777 << theArgVec[0] << " off\n"
8778 << 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]";
8784 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8785 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8786 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8787 new OCC_TextureEnv(theArgVec[2]);
8791 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8792 aTexEnv->SetTextureParameters(
8793 aRepeatOpt. IsEqual("repeat"),
8794 aModulateOpt.IsEqual("modulate"),
8795 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8796 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8797 Graphic3d_TOTF_TRILINEAR,
8798 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8799 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8800 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8801 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8802 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8805 aView->SetTextureEnv(aTexEnv);
8807 else // Disabling environment mapping
8809 Handle(Graphic3d_TextureEnv) aTexture;
8810 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8819 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8821 //! Remove registered clipping plane from all views and objects.
8822 static void removePlane (MapOfPlanes& theRegPlanes,
8823 const TCollection_AsciiString& theName)
8825 Handle(Graphic3d_ClipPlane) aClipPlane;
8826 if (!theRegPlanes.Find (theName, aClipPlane))
8828 Message::SendWarning ("Warning: no such plane");
8832 theRegPlanes.UnBind (theName);
8833 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8834 anIObjIt.More(); anIObjIt.Next())
8836 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
8837 aPrs->RemoveClipPlane (aClipPlane);
8840 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8841 aViewIt.More(); aViewIt.Next())
8843 const Handle(V3d_View)& aView = aViewIt.Key2();
8844 aView->RemoveClipPlane(aClipPlane);
8847 ViewerTest::RedrawAllViews();
8851 //===============================================================================================
8852 //function : VClipPlane
8854 //===============================================================================================
8855 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8857 // use short-cut for created clip planes map of created (or "registered by name") clip planes
8858 static MapOfPlanes aRegPlanes;
8862 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8864 theDi << aPlaneIter.Key() << " ";
8869 TCollection_AsciiString aCommand (theArgVec[1]);
8870 aCommand.LowerCase();
8871 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8872 if (anActiveView.IsNull())
8874 Message::SendFail ("Error: no active viewer");
8878 // print maximum number of planes for current viewer
8879 if (aCommand == "-maxplanes"
8880 || aCommand == "maxplanes")
8882 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8883 << " plane slots provided by driver.\n";
8887 // create / delete plane instance
8888 if (aCommand == "-create"
8889 || aCommand == "create"
8890 || aCommand == "-delete"
8891 || aCommand == "delete"
8892 || aCommand == "-clone"
8893 || aCommand == "clone")
8897 Message::SendFail ("Syntax error: plane name is required");
8901 Standard_Boolean toCreate = aCommand == "-create"
8902 || aCommand == "create";
8903 Standard_Boolean toClone = aCommand == "-clone"
8904 || aCommand == "clone";
8905 Standard_Boolean toDelete = aCommand == "-delete"
8906 || aCommand == "delete";
8907 TCollection_AsciiString aPlane (theArgVec[2]);
8911 if (aRegPlanes.IsBound (aPlane))
8913 std::cout << "Warning: existing plane has been overridden.\n";
8918 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8922 else if (toClone) // toClone
8924 if (!aRegPlanes.IsBound (aPlane))
8926 Message::SendFail ("Error: no such plane");
8929 else if (theArgsNb < 4)
8931 Message::SendFail ("Syntax error: enter name for new plane");
8935 TCollection_AsciiString aClone (theArgVec[3]);
8936 if (aRegPlanes.IsBound (aClone))
8938 Message::SendFail ("Error: plane name is in use");
8942 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8944 aRegPlanes.Bind (aClone, aClipPlane->Clone());
8954 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8956 aPlane = aPlaneIter.Key();
8957 removePlane (aRegPlanes, aPlane);
8958 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8963 removePlane (aRegPlanes, aPlane);
8969 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8974 // set / unset plane command
8975 if (aCommand == "set"
8976 || aCommand == "unset")
8980 Message::SendFail ("Syntax error: need more arguments");
8984 // redirect to new syntax
8985 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8986 anArgVec.SetValue (1, theArgVec[0]);
8987 anArgVec.SetValue (2, theArgVec[2]);
8988 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8989 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
8991 anArgVec.SetValue (anIt, theArgVec[anIt]);
8994 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
8997 // change plane command
8998 TCollection_AsciiString aPlaneName;
8999 Handle(Graphic3d_ClipPlane) aClipPlane;
9000 Standard_Integer anArgIter = 0;
9001 if (aCommand == "-change"
9002 || aCommand == "change")
9004 // old syntax support
9007 Message::SendFail ("Syntax error: need more arguments");
9012 aPlaneName = theArgVec[2];
9013 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
9015 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
9019 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9022 aPlaneName = theArgVec[1];
9027 aPlaneName = theArgVec[1];
9028 aClipPlane = new Graphic3d_ClipPlane();
9029 aRegPlanes.Bind (aPlaneName, aClipPlane);
9030 theDi << "Created new plane " << aPlaneName << ".\n";
9033 if (theArgsNb - anArgIter < 1)
9035 Message::SendFail ("Syntax error: need more arguments");
9039 for (; anArgIter < theArgsNb; ++anArgIter)
9041 const char** aChangeArgs = theArgVec + anArgIter;
9042 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9043 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9044 aChangeArg.LowerCase();
9046 Standard_Boolean toEnable = Standard_True;
9047 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
9049 aClipPlane->SetOn (toEnable);
9051 else if (aChangeArg.StartsWith ("-equation")
9052 || aChangeArg.StartsWith ("equation"))
9054 if (aNbChangeArgs < 5)
9056 Message::SendFail ("Syntax error: need more arguments");
9060 Standard_Integer aSubIndex = 1;
9061 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9062 if (aPrefixLen < aChangeArg.Length())
9064 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9065 if (!aSubStr.IsIntegerValue()
9066 || aSubStr.IntegerValue() <= 0)
9068 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
9071 aSubIndex = aSubStr.IntegerValue();
9074 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9075 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9076 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9077 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9078 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9079 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9081 if (aSubPln->ChainNextPlane().IsNull())
9083 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9085 aSubPln = aSubPln->ChainNextPlane();
9087 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9088 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
9091 else if ((aChangeArg == "-boxinterior"
9092 || aChangeArg == "-boxint"
9093 || aChangeArg == "-box")
9094 && aNbChangeArgs >= 7)
9096 Graphic3d_BndBox3d aBndBox;
9097 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9098 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9101 Standard_Integer aNbSubPlanes = 6;
9102 const Graphic3d_Vec3d aDirArray[6] =
9104 Graphic3d_Vec3d (-1, 0, 0),
9105 Graphic3d_Vec3d ( 1, 0, 0),
9106 Graphic3d_Vec3d ( 0,-1, 0),
9107 Graphic3d_Vec3d ( 0, 1, 0),
9108 Graphic3d_Vec3d ( 0, 0,-1),
9109 Graphic3d_Vec3d ( 0, 0, 1),
9111 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9112 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9114 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9115 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9116 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9117 if (aSubPlaneIter + 1 == aNbSubPlanes)
9119 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9123 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9125 aSubPln = aSubPln->ChainNextPlane();
9128 else if (aChangeArg == "-capping"
9129 || aChangeArg == "capping")
9131 if (aNbChangeArgs < 2)
9133 Message::SendFail ("Syntax error: need more arguments");
9137 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
9139 aClipPlane->SetCapping (toEnable);
9144 // just skip otherwise (old syntax)
9147 else if (aChangeArg == "-useobjectmaterial"
9148 || aChangeArg == "-useobjectmat"
9149 || aChangeArg == "-useobjmat"
9150 || aChangeArg == "-useobjmaterial")
9152 if (aNbChangeArgs < 2)
9154 Message::SendFail ("Syntax error: need more arguments");
9158 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
9160 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9164 else if (aChangeArg == "-useobjecttexture"
9165 || aChangeArg == "-useobjecttex"
9166 || aChangeArg == "-useobjtexture"
9167 || aChangeArg == "-useobjtex")
9169 if (aNbChangeArgs < 2)
9171 Message::SendFail ("Syntax error: need more arguments");
9175 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
9177 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9181 else if (aChangeArg == "-useobjectshader"
9182 || aChangeArg == "-useobjshader")
9184 if (aNbChangeArgs < 2)
9186 Message::SendFail ("Syntax error: need more arguments");
9190 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
9192 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9196 else if (aChangeArg == "-color"
9197 || aChangeArg == "color")
9199 Quantity_Color aColor;
9200 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9205 Message::SendFail ("Syntax error: need more arguments");
9208 aClipPlane->SetCappingColor (aColor);
9209 anArgIter += aNbParsed;
9211 else if (aNbChangeArgs >= 1
9212 && (aChangeArg == "-material"
9213 || aChangeArg == "material"))
9216 Graphic3d_NameOfMaterial aMatName;
9217 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9219 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
9222 aClipPlane->SetCappingMaterial (aMatName);
9224 else if ((aChangeArg == "-transparency"
9225 || aChangeArg == "-transp")
9226 && aNbChangeArgs >= 2)
9228 TCollection_AsciiString aValStr (aChangeArgs[1]);
9229 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
9230 if (aValStr.IsRealValue (Standard_True))
9232 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9233 aMat.SetTransparency ((float )aValStr.RealValue());
9234 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9235 aClipPlane->SetCappingMaterial (aMat);
9239 aValStr.LowerCase();
9240 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9241 if (aValStr == "opaque")
9243 aMode = Graphic3d_AlphaMode_Opaque;
9245 else if (aValStr == "mask")
9247 aMode = Graphic3d_AlphaMode_Mask;
9249 else if (aValStr == "blend")
9251 aMode = Graphic3d_AlphaMode_Blend;
9253 else if (aValStr == "maskblend"
9254 || aValStr == "blendmask")
9256 aMode = Graphic3d_AlphaMode_MaskBlend;
9258 else if (aValStr == "blendauto")
9260 aMode = Graphic3d_AlphaMode_BlendAuto;
9264 Message::SendFail() << "Syntax error at '" << aValStr << "'";
9267 anAspect->SetAlphaMode (aMode);
9268 aClipPlane->SetCappingAspect (anAspect);
9272 else if (aChangeArg == "-texname"
9273 || aChangeArg == "texname")
9275 if (aNbChangeArgs < 2)
9277 Message::SendFail ("Syntax error: need more arguments");
9281 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9282 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9283 if (!aTexture->IsDone())
9285 aClipPlane->SetCappingTexture (NULL);
9289 aTexture->EnableModulate();
9290 aTexture->EnableRepeat();
9291 aClipPlane->SetCappingTexture (aTexture);
9295 else if (aChangeArg == "-texscale"
9296 || aChangeArg == "texscale")
9298 if (aClipPlane->CappingTexture().IsNull())
9300 Message::SendFail ("Error: no texture is set");
9304 if (aNbChangeArgs < 3)
9306 Message::SendFail ("Syntax error: need more arguments");
9310 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9311 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9312 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9315 else if (aChangeArg == "-texorigin"
9316 || aChangeArg == "texorigin") // texture origin
9318 if (aClipPlane->CappingTexture().IsNull())
9320 Message::SendFail ("Error: no texture is set");
9324 if (aNbChangeArgs < 3)
9326 Message::SendFail ("Syntax error: need more arguments");
9330 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9331 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9333 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9336 else if (aChangeArg == "-texrotate"
9337 || aChangeArg == "texrotate") // texture rotation
9339 if (aClipPlane->CappingTexture().IsNull())
9341 Message::SendFail ("Error: no texture is set");
9345 if (aNbChangeArgs < 2)
9347 Message::SendFail ("Syntax error: need more arguments");
9351 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9352 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9355 else if (aChangeArg == "-hatch"
9356 || aChangeArg == "hatch")
9358 if (aNbChangeArgs < 2)
9360 Message::SendFail ("Syntax error: need more arguments");
9364 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9365 aHatchStr.LowerCase();
9366 if (aHatchStr == "on")
9368 aClipPlane->SetCappingHatchOn();
9370 else if (aHatchStr == "off")
9372 aClipPlane->SetCappingHatchOff();
9376 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9380 else if (aChangeArg == "-delete"
9381 || aChangeArg == "delete")
9383 removePlane (aRegPlanes, aPlaneName);
9386 else if (aChangeArg == "-set"
9387 || aChangeArg == "-unset"
9388 || aChangeArg == "-setoverrideglobal")
9390 // set / unset plane command
9391 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9392 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
9393 Standard_Integer anIt = 1;
9394 for (; anIt < aNbChangeArgs; ++anIt)
9396 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9397 if (anEntityName.IsEmpty()
9398 || anEntityName.Value (1) == '-')
9402 else if (!toOverrideGlobal
9403 && ViewerTest_myViews.IsBound1 (anEntityName))
9405 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9408 aView->AddClipPlane (aClipPlane);
9412 aView->RemoveClipPlane (aClipPlane);
9416 else if (GetMapOfAIS().IsBound2 (anEntityName))
9418 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
9421 aIObj->AddClipPlane (aClipPlane);
9425 aIObj->RemoveClipPlane (aClipPlane);
9427 if (!aIObj->ClipPlanes().IsNull())
9429 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9434 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
9441 // apply to active view
9444 anActiveView->AddClipPlane (aClipPlane);
9448 anActiveView->RemoveClipPlane (aClipPlane);
9453 anArgIter = anArgIter + anIt - 1;
9458 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
9463 ViewerTest::RedrawAllViews();
9467 //===============================================================================================
9468 //function : VZRange
9470 //===============================================================================================
9471 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9473 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9475 if (aCurrentView.IsNull())
9477 Message::SendFail ("Error: no active viewer");
9481 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
9485 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9486 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9492 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9493 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
9495 if (aNewZNear >= aNewZFar)
9497 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
9501 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9503 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
9507 aCamera->SetZRange (aNewZNear, aNewZFar);
9511 Message::SendFail ("Syntax error: wrong command arguments");
9515 aCurrentView->Redraw();
9520 //===============================================================================================
9521 //function : VAutoZFit
9523 //===============================================================================================
9524 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9526 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9528 if (aCurrentView.IsNull())
9530 Message::SendFail ("Error: no active viewer");
9534 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
9538 Message::SendFail ("Syntax error: wrong command arguments");
9544 theDi << "Auto z-fit mode: \n"
9545 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
9546 << "Scale: " << aScale << "\n";
9550 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9554 aScale = Draw::Atoi (theArgVec[2]);
9557 aCurrentView->SetAutoZFitMode (isOn, aScale);
9558 aCurrentView->Redraw();
9562 //! Auxiliary function to print projection type
9563 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9565 switch (theProjType)
9567 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9568 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9569 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9570 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9571 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9576 //===============================================================================================
9577 //function : VCamera
9579 //===============================================================================================
9580 static int VCamera (Draw_Interpretor& theDI,
9581 Standard_Integer theArgsNb,
9582 const char** theArgVec)
9584 Handle(V3d_View) aView = ViewerTest::CurrentView();
9587 Message::SendFail ("Error: no active viewer");
9591 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9594 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9595 theDI << "FOVy: " << aCamera->FOVy() << "\n";
9596 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9597 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
9598 theDI << "Distance: " << aCamera->Distance() << "\n";
9599 theDI << "IOD: " << aCamera->IOD() << "\n";
9600 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9601 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9602 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
9603 theDI << "ZNear: " << aCamera->ZNear() << "\n";
9604 theDI << "ZFar: " << aCamera->ZFar() << "\n";
9608 TCollection_AsciiString aPrsName;
9609 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9611 Standard_CString anArg = theArgVec[anArgIter];
9612 TCollection_AsciiString anArgCase (anArg);
9613 anArgCase.LowerCase();
9614 if (anArgCase == "-proj"
9615 || anArgCase == "-projection"
9616 || anArgCase == "-projtype"
9617 || anArgCase == "-projectiontype")
9619 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9621 else if (anArgCase == "-ortho"
9622 || anArgCase == "-orthographic")
9624 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
9626 else if (anArgCase == "-persp"
9627 || anArgCase == "-perspective"
9628 || anArgCase == "-perspmono"
9629 || anArgCase == "-perspectivemono"
9630 || anArgCase == "-mono")
9632 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9634 else if (anArgCase == "-stereo"
9635 || anArgCase == "-stereoscopic"
9636 || anArgCase == "-perspstereo"
9637 || anArgCase == "-perspectivestereo")
9639 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9641 else if (anArgCase == "-left"
9642 || anArgCase == "-lefteye"
9643 || anArgCase == "-monoleft"
9644 || anArgCase == "-monolefteye"
9645 || anArgCase == "-perpsleft"
9646 || anArgCase == "-perpslefteye")
9648 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9650 else if (anArgCase == "-right"
9651 || anArgCase == "-righteye"
9652 || anArgCase == "-monoright"
9653 || anArgCase == "-monorighteye"
9654 || anArgCase == "-perpsright")
9656 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9658 else if (anArgCase == "-dist"
9659 || anArgCase == "-distance")
9661 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9662 if (anArgValue != NULL
9663 && *anArgValue != '-')
9666 aCamera->SetDistance (Draw::Atof (anArgValue));
9669 theDI << aCamera->Distance() << " ";
9671 else if (anArgCase == "-iod")
9673 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9674 if (anArgValue != NULL
9675 && *anArgValue != '-')
9678 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9681 theDI << aCamera->IOD() << " ";
9683 else if (anArgCase == "-iodtype")
9685 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9686 TCollection_AsciiString anValueCase (anArgValue);
9687 anValueCase.LowerCase();
9688 if (anValueCase == "abs"
9689 || anValueCase == "absolute")
9692 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9695 else if (anValueCase == "rel"
9696 || anValueCase == "relative")
9699 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9702 else if (*anArgValue != '-')
9704 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
9707 switch (aCamera->GetIODType())
9709 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9710 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9713 else if (anArgCase == "-zfocus")
9715 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9716 if (anArgValue != NULL
9717 && *anArgValue != '-')
9720 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9723 theDI << aCamera->ZFocus() << " ";
9725 else if (anArgCase == "-zfocustype")
9727 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9728 TCollection_AsciiString anValueCase (anArgValue);
9729 anValueCase.LowerCase();
9730 if (anValueCase == "abs"
9731 || anValueCase == "absolute")
9734 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9737 else if (anValueCase == "rel"
9738 || anValueCase == "relative")
9741 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9744 else if (*anArgValue != '-')
9746 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
9749 switch (aCamera->ZFocusType())
9751 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9752 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9755 else if (anArgCase == "-lockzup"
9756 || anArgCase == "-turntable")
9758 bool toLockUp = true;
9759 if (++anArgIter < theArgsNb
9760 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
9764 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9766 else if (anArgCase == "-fov"
9767 || anArgCase == "-fovy"
9768 || anArgCase == "-fovx"
9769 || anArgCase == "-fov2d")
9771 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9772 if (anArgValue != NULL
9773 && *anArgValue != '-')
9776 if (anArgCase == "-fov2d")
9778 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9780 else if (anArgCase == "-fovx")
9782 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9786 aCamera->SetFOVy (Draw::Atof (anArgValue));
9790 if (anArgCase == "-fov2d")
9792 theDI << aCamera->FOV2d() << " ";
9794 else if (anArgCase == "-fovx")
9796 theDI << aCamera->FOVx() << " ";
9800 theDI << aCamera->FOVy() << " ";
9803 else if (anArgIter + 1 < theArgsNb
9804 && anArgCase == "-xrpose")
9806 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9807 anXRArg.LowerCase();
9808 if (anXRArg == "base")
9810 aCamera = aView->View()->BaseXRCamera();
9812 else if (anXRArg == "head")
9814 aCamera = aView->View()->PosedXRCamera();
9818 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9821 if (aCamera.IsNull())
9823 Message::SendFail() << "Error: undefined XR pose";
9826 if (aView->AutoZFitMode())
9828 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9829 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9830 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9833 else if (aPrsName.IsEmpty()
9834 && !anArgCase.StartsWith ("-"))
9840 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
9845 if (aPrsName.IsEmpty()
9851 if (!aPrsName.IsEmpty())
9853 Handle(AIS_CameraFrustum) aCameraFrustum;
9854 if (GetMapOfAIS().IsBound2 (aPrsName))
9856 // find existing object
9857 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9858 if (aCameraFrustum.IsNull())
9860 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
9865 if (aCameraFrustum.IsNull())
9867 aCameraFrustum = new AIS_CameraFrustum();
9871 // not include displayed object of old camera frustum in the new one.
9872 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9875 aCameraFrustum->SetCameraFrustum (aCamera);
9877 ViewerTest::Display (aPrsName, aCameraFrustum);
9883 //! Parse stereo output mode
9884 inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9885 Graphic3d_StereoMode& theMode)
9887 TCollection_AsciiString aFlag (theArg);
9889 if (aFlag == "quadbuffer")
9891 theMode = Graphic3d_StereoMode_QuadBuffer;
9893 else if (aFlag == "anaglyph")
9895 theMode = Graphic3d_StereoMode_Anaglyph;
9897 else if (aFlag == "row"
9898 || aFlag == "rowinterlaced")
9900 theMode = Graphic3d_StereoMode_RowInterlaced;
9902 else if (aFlag == "col"
9903 || aFlag == "colinterlaced"
9904 || aFlag == "columninterlaced")
9906 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9908 else if (aFlag == "chess"
9909 || aFlag == "chessboard")
9911 theMode = Graphic3d_StereoMode_ChessBoard;
9913 else if (aFlag == "sbs"
9914 || aFlag == "sidebyside")
9916 theMode = Graphic3d_StereoMode_SideBySide;
9918 else if (aFlag == "ou"
9919 || aFlag == "overunder")
9921 theMode = Graphic3d_StereoMode_OverUnder;
9923 else if (aFlag == "pageflip"
9924 || aFlag == "softpageflip")
9926 theMode = Graphic3d_StereoMode_SoftPageFlip;
9928 else if (aFlag == "openvr"
9931 theMode = Graphic3d_StereoMode_OpenVR;
9935 return Standard_False;
9937 return Standard_True;
9940 //! Parse anaglyph filter
9941 inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9942 Graphic3d_RenderingParams::Anaglyph& theFilter)
9944 TCollection_AsciiString aFlag (theArg);
9946 if (aFlag == "redcyansimple")
9948 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9950 else if (aFlag == "redcyan"
9951 || aFlag == "redcyanoptimized")
9953 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9955 else if (aFlag == "yellowbluesimple")
9957 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9959 else if (aFlag == "yellowblue"
9960 || aFlag == "yellowblueoptimized")
9962 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9964 else if (aFlag == "greenmagenta"
9965 || aFlag == "greenmagentasimple")
9967 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9971 return Standard_False;
9973 return Standard_True;
9976 //==============================================================================
9977 //function : VStereo
9979 //==============================================================================
9981 static int VStereo (Draw_Interpretor& theDI,
9982 Standard_Integer theArgNb,
9983 const char** theArgVec)
9985 Handle(V3d_View) aView = ViewerTest::CurrentView();
9988 Message::SendFail ("Error: no active viewer");
9992 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9993 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9996 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
9997 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
10000 TCollection_AsciiString aMode;
10001 switch (aView->RenderingParams().StereoMode)
10003 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10004 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10005 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10006 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10007 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10008 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10009 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
10010 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
10011 case Graphic3d_StereoMode_Anaglyph :
10012 aMode = "anaglyph";
10013 switch (aView->RenderingParams().AnaglyphFilter)
10015 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10016 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10017 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10018 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10019 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10024 theDI << "Mode " << aMode << "\n";
10029 Graphic3d_StereoMode aMode = aParams->StereoMode;
10030 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10031 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10033 Standard_CString anArg = theArgVec[anArgIter];
10034 TCollection_AsciiString aFlag (anArg);
10036 if (anUpdateTool.parseRedrawMode (aFlag))
10040 else if (aFlag == "0"
10043 if (++anArgIter < theArgNb)
10045 Message::SendFail ("Error: wrong number of arguments");
10049 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
10051 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10055 else if (aFlag == "1"
10058 if (++anArgIter < theArgNb)
10060 Message::SendFail ("Error: wrong number of arguments");
10064 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10065 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10070 else if (aFlag == "-reverse"
10071 || aFlag == "-reversed"
10072 || aFlag == "-swap")
10074 Standard_Boolean toEnable = Standard_True;
10075 if (++anArgIter < theArgNb
10076 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
10080 aParams->ToReverseStereo = toEnable;
10082 else if (aFlag == "-noreverse"
10083 || aFlag == "-noswap")
10085 Standard_Boolean toDisable = Standard_True;
10086 if (++anArgIter < theArgNb
10087 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
10091 aParams->ToReverseStereo = !toDisable;
10093 else if (aFlag == "-mode"
10094 || aFlag == "-stereomode")
10096 if (++anArgIter >= theArgNb
10097 || !parseStereoMode (theArgVec[anArgIter], aMode))
10099 Message::SendFail() << "Syntax error at '" << anArg << "'";
10103 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10105 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
10108 else if (aFlag == "-anaglyph"
10109 || aFlag == "-anaglyphfilter")
10111 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10112 if (++anArgIter >= theArgNb
10113 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10115 Message::SendFail() << "Syntax error at '" << anArg << "'";
10119 aMode = Graphic3d_StereoMode_Anaglyph;
10120 aParams->AnaglyphFilter = aFilter;
10122 else if (parseStereoMode (anArg, aMode)) // short syntax
10124 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10126 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
10129 else if (anArgIter + 1 < theArgNb
10130 && aFlag == "-hmdfov2d")
10132 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10133 if (aParams->HmdFov2d < 10.0f
10134 || aParams->HmdFov2d > 180.0f)
10136 Message::SendFail() << "Error: FOV is out of range";
10140 else if (aFlag == "-mirror"
10141 || aFlag == "-mirrorcomposer")
10143 Standard_Boolean toEnable = Standard_True;
10144 if (++anArgIter < theArgNb
10145 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
10149 aParams->ToMirrorComposer = toEnable;
10151 else if (anArgIter + 1 < theArgNb
10152 && (aFlag == "-unitfactor"
10153 || aFlag == "-unitscale"))
10155 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10159 Message::SendFail() << "Syntax error at '" << anArg << "'";
10164 aParams->StereoMode = aMode;
10165 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10166 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
10168 // initiate implicit continuous rendering
10169 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
10174 //===============================================================================================
10175 //function : VDefaults
10177 //===============================================================================================
10178 static int VDefaults (Draw_Interpretor& theDi,
10179 Standard_Integer theArgsNb,
10180 const char** theArgVec)
10182 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10185 Message::SendFail ("Error: no active viewer");
10189 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10192 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10194 theDi << "DeflType: relative\n"
10195 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10199 theDi << "DeflType: absolute\n"
10200 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10202 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
10203 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
10207 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10209 TCollection_AsciiString anArg (theArgVec[anArgIter]);
10211 if (anArg == "-ABSDEFL"
10212 || anArg == "-ABSOLUTEDEFLECTION"
10213 || anArg == "-DEFL"
10214 || anArg == "-DEFLECTION")
10216 if (++anArgIter >= theArgsNb)
10218 Message::SendFail() << "Syntax error at " << anArg;
10221 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
10222 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
10224 else if (anArg == "-RELDEFL"
10225 || anArg == "-RELATIVEDEFLECTION"
10226 || anArg == "-DEVCOEFF"
10227 || anArg == "-DEVIATIONCOEFF"
10228 || anArg == "-DEVIATIONCOEFFICIENT")
10230 if (++anArgIter >= theArgsNb)
10232 Message::SendFail() << "Syntax error at " << anArg;
10235 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
10236 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
10238 else if (anArg == "-ANGDEFL"
10239 || anArg == "-ANGULARDEFL"
10240 || anArg == "-ANGULARDEFLECTION")
10242 if (++anArgIter >= theArgsNb)
10244 Message::SendFail() << "Syntax error at " << anArg;
10247 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
10249 else if (anArg == "-AUTOTR"
10250 || anArg == "-AUTOTRIANG"
10251 || anArg == "-AUTOTRIANGULATION")
10254 bool toTurnOn = true;
10255 if (anArgIter >= theArgsNb
10256 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
10258 Message::SendFail() << "Syntax error at '" << anArg << "'";
10261 aDefParams->SetAutoTriangulation (toTurnOn);
10265 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
10273 //! Parse light source type from string.
10274 static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
10275 Graphic3d_TypeOfLightSource& theType)
10277 TCollection_AsciiString aType (theTypeName);
10280 || aType == "ambient"
10281 || aType == "amblight")
10283 theType = Graphic3d_TypeOfLightSource_Ambient;
10285 else if (aType == "directional"
10286 || aType == "dirlight")
10288 theType = Graphic3d_TypeOfLightSource_Directional;
10290 else if (aType == "spot"
10291 || aType == "spotlight")
10293 theType = Graphic3d_TypeOfLightSource_Spot;
10295 else if (aType == "poslight"
10296 || aType == "positional"
10297 || aType == "point"
10300 theType = Graphic3d_TypeOfLightSource_Positional;
10309 //! Find existing light by name or index.
10310 static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
10312 Handle(V3d_Light) aLight;
10313 Standard_Integer aLightIndex = -1;
10314 Draw::ParseInteger (theName.ToCString(), aLightIndex);
10315 Standard_Integer aLightIt = 0;
10316 Handle(V3d_View) aView = ViewerTest::CurrentView();
10317 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
10319 if (aLightIndex != -1)
10321 if (aLightIt == aLightIndex)
10323 return aLightIter.Value();
10326 else if (aLightIter.Value()->GetId() == theName
10327 || aLightIter.Value()->Name() == theName)
10329 if (!aLight.IsNull())
10331 Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
10334 aLight = aLightIter.Value();
10340 //===============================================================================================
10341 //function : VLight
10343 //===============================================================================================
10344 static int VLight (Draw_Interpretor& theDi,
10345 Standard_Integer theArgsNb,
10346 const char** theArgVec)
10348 Handle(V3d_View) aView = ViewerTest::CurrentView();
10349 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10350 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10352 || aViewer.IsNull())
10354 Message::SendFail ("Error: no active viewer");
10360 // print lights info
10361 Standard_Integer aLightId = 0;
10362 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
10364 Handle(V3d_Light) aLight = aLightIter.Value();
10365 const Quantity_Color aColor = aLight->Color();
10366 theDi << "Light #" << aLightId
10367 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10368 << " [" << aLight->GetId() << "] "
10369 << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
10370 switch (aLight->Type())
10374 theDi << " Type: Ambient\n"
10375 << " Intensity: " << aLight->Intensity() << "\n";
10378 case V3d_DIRECTIONAL:
10380 theDi << " Type: Directional\n"
10381 << " Intensity: " << aLight->Intensity() << "\n"
10382 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10383 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10384 << " Smoothness: " << aLight->Smoothness() << "\n"
10385 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
10388 case V3d_POSITIONAL:
10390 theDi << " Type: Positional\n"
10391 << " Intensity: " << aLight->Intensity() << "\n"
10392 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10393 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10394 << " Smoothness: " << aLight->Smoothness() << "\n"
10395 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
10396 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
10397 << " Range: " << aLight->Range() << "\n";
10402 theDi << " Type: Spot\n"
10403 << " Intensity: " << aLight->Intensity() << "\n"
10404 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10405 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10406 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
10407 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
10408 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
10409 << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
10410 << " Exponent: " << aLight->Concentration() << "\n"
10411 << " Range: " << aLight->Range() << "\n";
10416 theDi << " Type: UNKNOWN\n";
10420 theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
10424 Handle(V3d_Light) aLightOld, aLightNew;
10425 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
10426 bool isGlobal = true;
10427 ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
10428 Handle(AIS_LightSource) aLightPrs;
10429 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10431 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10432 TCollection_AsciiString anArgCase (anArg);
10433 anArgCase.LowerCase();
10434 if (anUpdateTool.parseRedrawMode (anArg))
10438 else if (anArgCase == "-new"
10439 || anArgCase == "-add"
10440 || anArgCase == "-create"
10441 || anArgCase == "-type"
10442 || (anArgCase == "-reset"
10443 && !aLightNew.IsNull())
10444 || (anArgCase == "-defaults"
10445 && !aLightNew.IsNull())
10446 || anArgCase == "add"
10447 || anArgCase == "new"
10448 || anArgCase == "create")
10450 Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
10451 if (anArgCase == "-reset")
10453 aType = aLightNew->Type();
10455 else if (anArgIt + 1 >= theArgsNb
10456 || !parseLightSourceType (theArgVec[++anArgIt], aType))
10458 theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
10462 TCollection_AsciiString aName;
10463 if (!aLightNew.IsNull())
10465 aName = aLightNew->Name();
10469 case Graphic3d_TypeOfLightSource_Ambient:
10471 aLightNew = new V3d_AmbientLight();
10474 case Graphic3d_TypeOfLightSource_Directional:
10476 aLightNew = new V3d_DirectionalLight();
10479 case Graphic3d_TypeOfLightSource_Spot:
10481 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
10484 case Graphic3d_TypeOfLightSource_Positional:
10486 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
10491 if (anArgCase == "-type"
10492 && !aLightOld.IsNull())
10494 aLightNew->CopyFrom (aLightOld);
10496 aLightNew->SetName (aName);
10498 else if ((anArgCase == "-layer"
10499 || anArgCase == "-zlayer")
10500 && anArgIt + 1 < theArgsNb)
10502 if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
10503 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10505 Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
10509 else if (anArgCase == "-glob"
10510 || anArgCase == "-global"
10511 || anArgCase == "-loc"
10512 || anArgCase == "-local")
10514 isGlobal = anArgCase.StartsWith ("-glob");
10516 else if (anArgCase == "-def"
10517 || anArgCase == "-defaults"
10518 || anArgCase == "-reset")
10520 aViewer->SetDefaultLights();
10521 aLightOld.Nullify();
10522 aLightNew.Nullify();
10523 aLightPrs.Nullify();
10525 else if (anArgCase == "-clr"
10526 || anArgCase == "-clear"
10527 || anArgCase == "clear")
10529 TColStd_SequenceOfInteger aLayers;
10530 aViewer->GetAllZLayers (aLayers);
10531 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10533 if (aLayeriter.Value() == aLayer
10534 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10536 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10537 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10538 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10539 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10546 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10548 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
10549 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10551 Handle(V3d_Light) aLight = aLightIter.Value();
10552 Handle(AIS_InteractiveObject) aPrsObject;
10553 GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
10554 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10556 aCtx->Remove (aLightSourceDel, false);
10557 aMap.UnBind1 (aLightSourceDel);
10559 aViewer->DelLight (aLight);
10560 aLightIter = aView->ActiveLightIterator();
10564 aLightOld.Nullify();
10565 aLightNew.Nullify();
10566 aLightPrs.Nullify();
10568 else if (!aLightNew.IsNull()
10569 && (anArgCase == "-display"
10570 || anArgCase == "-disp"
10571 || anArgCase == "-presentation"
10572 || anArgCase == "-prs"))
10574 TCollection_AsciiString aLightName = aLightNew->Name();
10575 if (anArgIt + 1 < theArgsNb
10576 && theArgVec[anArgIt + 1][0] != '-')
10579 aLightName = theArgVec[++anArgIt];
10580 if (aLightNew->Name() != aLightName)
10582 if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
10584 theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
10587 aLightNew->SetName (aLightName);
10590 if (aLightName.IsEmpty())
10592 Message::SendFail() << "Error: nameless light source cannot be displayed";
10595 if (aLightPrs.IsNull())
10597 aLightPrs = new AIS_LightSource (aLightNew);
10599 theDi << aLightName << " ";
10601 else if (!aLightNew.IsNull()
10602 && (anArgCase == "-disable"
10603 || anArgCase == "-disabled"
10604 || anArgCase == "-enable"
10605 || anArgCase == "-enabled"))
10607 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10608 if (anArgCase == "-disable"
10609 || anArgCase == "-disabled")
10611 toEnable = !toEnable;
10613 aLightNew->SetEnabled (toEnable);
10615 else if (!aLightNew.IsNull()
10616 && (anArgCase == "-color"
10617 || anArgCase == "-colour"
10618 || anArgCase == "color"))
10620 Quantity_Color aColor;
10621 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10622 theArgVec + anArgIt + 1,
10624 anArgIt += aNbParsed;
10625 if (aNbParsed == 0)
10627 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10630 aLightNew->SetColor (aColor);
10632 else if (!aLightNew.IsNull()
10633 && (anArgCase == "-pos"
10634 || anArgCase == "-position"
10635 || anArgCase == "-prsposition"
10636 || anArgCase == "-prspos"
10637 || anArgCase == "pos"
10638 || anArgCase == "position")
10639 && (anArgIt + 3) < theArgsNb)
10642 if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
10644 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10649 if (anArgCase == "-prsposition"
10650 || anArgCase == "-prspos")
10652 aLightNew->SetDisplayPosition (aPosXYZ);
10656 if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
10657 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
10659 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10663 aLightNew->SetPosition (aPosXYZ);
10666 else if (!aLightNew.IsNull()
10667 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
10668 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10669 && (anArgCase == "-dir"
10670 || anArgCase == "-direction")
10671 && (anArgIt + 3) < theArgsNb)
10674 if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
10676 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10681 aLightNew->SetDirection (gp_Dir (aDirXYZ));
10683 else if (!aLightNew.IsNull()
10684 && (anArgCase == "-smoothangle"
10685 || anArgCase == "-smoothradius"
10686 || anArgCase == "-sm"
10687 || anArgCase == "-smoothness")
10688 && anArgIt + 1 < theArgsNb)
10690 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10691 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10693 aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
10695 if (Abs (aSmoothness) <= ShortRealEpsilon())
10697 aLightNew->SetIntensity (1.f);
10699 else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
10701 aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10705 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
10706 aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10709 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10711 aLightNew->SetSmoothRadius (aSmoothness);
10713 else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10715 aLightNew->SetSmoothAngle (aSmoothness);
10718 else if (!aLightNew.IsNull()
10719 && (anArgCase == "-int"
10720 || anArgCase == "-intensity")
10721 && anArgIt + 1 < theArgsNb)
10723 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10724 aLightNew->SetIntensity (aIntensity);
10726 else if (!aLightNew.IsNull()
10727 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10728 && (anArgCase == "-spotangle"
10729 || anArgCase == "-ang"
10730 || anArgCase == "-angle")
10731 && anArgIt + 1 < theArgsNb)
10733 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10734 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10735 aLightNew->SetAngle (anAngle);
10737 else if (!aLightNew.IsNull()
10738 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10739 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10740 && (anArgCase == "-constatten"
10741 || anArgCase == "-constattenuation")
10742 && anArgIt + 1 < theArgsNb)
10744 const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10745 aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
10747 else if (!aLightNew.IsNull()
10748 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10749 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10750 && (anArgCase == "-linatten"
10751 || anArgCase == "-linearatten"
10752 || anArgCase == "-linearattenuation")
10753 && anArgIt + 1 < theArgsNb)
10755 const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10756 aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
10758 else if (!aLightNew.IsNull()
10759 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10760 && (anArgCase == "-spotexp"
10761 || anArgCase == "-spotexponent"
10762 || anArgCase == "-exp"
10763 || anArgCase == "-exponent")
10764 && anArgIt + 1 < theArgsNb)
10766 aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
10768 else if (!aLightNew.IsNull()
10769 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10770 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
10771 && anArgCase == "-range"
10772 && anArgIt + 1 < theArgsNb)
10774 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
10775 aLightNew->SetRange (aRange);
10777 else if (!aLightNew.IsNull()
10778 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10779 && (anArgCase == "-head"
10780 || anArgCase == "-headlight"))
10782 Standard_Boolean isHeadLight = Standard_True;
10783 if (anArgIt + 1 < theArgsNb
10784 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
10788 aLightNew->SetHeadlight (isHeadLight);
10790 else if (!aLightNew.IsNull()
10791 && anArgCase == "-name"
10792 && anArgIt + 1 < theArgsNb)
10794 const TCollection_AsciiString aName = theArgVec[++anArgIt];
10795 if (aLightNew->Name() == aName)
10800 if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
10802 theDi << "Syntax error: light with name '" << aName << "' is already defined";
10805 aLightNew->SetName (aName);
10807 else if (!aLightPrs.IsNull()
10808 && (anArgCase == "-showzoomable"
10809 || anArgCase == "-prszoomable"
10810 || anArgCase == "-zoomable"))
10812 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10813 aLightPrs->SetZoomable (isZoomable);
10815 else if (!aLightPrs.IsNull()
10816 && (anArgCase == "-showdraggable"
10817 || anArgCase == "-prsdraggable"
10818 || anArgCase == "-draggable"))
10820 const bool isDraggable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10821 aLightPrs->SetDraggable (isDraggable);
10823 else if (!aLightPrs.IsNull()
10824 && (anArgCase == "-showname"
10825 || anArgCase == "-prsname"))
10827 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10828 aLightPrs->SetDisplayName (toDisplay);
10830 else if (!aLightPrs.IsNull()
10831 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10832 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10833 && (anArgCase == "-showrange"
10834 || anArgCase == "-prsrange"))
10836 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10837 aLightPrs->SetDisplayRange (toDisplay);
10839 else if (!aLightPrs.IsNull()
10840 && (anArgCase == "-showsize"
10841 || anArgCase == "-prssize")
10842 && anArgIt + 1 < theArgsNb)
10844 Standard_Real aSize = 0.0;
10845 if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
10847 || aLightPrs.IsNull())
10849 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10853 aLightPrs->SetSize (aSize);
10855 else if (!aLightPrs.IsNull()
10856 && (anArgCase == "-dirarcsize"
10857 || anArgCase == "-arcsize"
10858 || anArgCase == "-arc")
10859 && anArgIt + 1 < theArgsNb)
10861 Standard_Integer aSize = 0;
10862 if (!Draw::ParseInteger (theArgVec[anArgIt + 1], aSize)
10864 || aLightPrs->Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
10866 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10870 aLightPrs->SetArcSize (aSize);
10872 else if (!aLightNew.IsNull()
10873 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10874 && (anArgCase == "-castshadow"
10875 || anArgCase == "-castshadows"
10876 || anArgCase == "-shadows"))
10878 bool toCastShadows = true;
10879 if (anArgIt + 1 < theArgsNb
10880 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
10884 aLightNew->SetCastShadows (toCastShadows);
10886 else if (anArgCase == "-del"
10887 || anArgCase == "-delete"
10888 || anArgCase == "-remove"
10889 || anArgCase == "del"
10890 || anArgCase == "delete"
10891 || anArgCase == "remove")
10893 if (aLightOld.IsNull())
10895 if (!aLightNew.IsNull())
10897 aLightNew.Nullify();
10901 if (++anArgIt >= theArgsNb)
10903 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10907 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10908 aLightOld = findLightSource (anOldName);
10909 if (aLightOld.IsNull())
10911 Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
10916 aLightNew.Nullify();
10917 aLightPrs.Nullify();
10919 else if (anArgCase == "-change"
10920 || anArgCase == "change")
10922 // just skip old syntax
10924 else if (aLightNew.IsNull()
10925 && !anArgCase.StartsWith ("-"))
10927 if (!aLightNew.IsNull())
10932 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10933 aLightOld = findLightSource (anOldName);
10934 if (!aLightOld.IsNull())
10936 aLightNew = aLightOld;
10938 Handle(AIS_InteractiveObject) aPrsObject;
10939 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10940 aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
10944 Standard_Integer aLightIndex = -1;
10945 Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
10946 if (aLightIndex != -1)
10948 Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
10952 aLightNew = new V3d_AmbientLight();
10953 aLightNew->SetName (anOldName);
10958 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
10963 // delete old light source
10964 if (!aLightOld.IsNull()
10965 && aLightOld != aLightNew)
10967 TColStd_SequenceOfInteger aLayers;
10968 aViewer->GetAllZLayers (aLayers);
10969 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
10971 if (aLayerIter.Value() == aLayer
10972 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10974 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
10975 if (!aSettings.Lights().IsNull())
10977 aSettings.Lights()->Remove (aLightOld);
10978 if (aSettings.Lights()->IsEmpty())
10980 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10983 aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
10984 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10991 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10993 Handle(AIS_InteractiveObject) aPrsObject;
10994 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10995 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10997 aCtx->Remove (aLightSourceDel, false);
10998 GetMapOfAIS().UnBind1 (aLightSourceDel);
11000 aViewer->DelLight (aLightOld);
11002 aLightOld.Nullify();
11005 // add new light source
11006 if (!aLightNew.IsNull())
11008 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
11010 aViewer->AddLight (aLightNew);
11013 aViewer->SetLightOn (aLightNew);
11017 aView->SetLightOn (aLightNew);
11022 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
11023 if (aSettings.Lights().IsNull())
11025 aSettings.SetLights (new Graphic3d_LightSet());
11027 aSettings.Lights()->Add (aLightNew);
11028 aViewer->SetZLayerSettings (aLayer, aSettings);
11031 if (!aLightPrs.IsNull())
11033 aLightPrs->SetLight (aLightNew);
11034 ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
11038 // manage presentations
11039 struct LightPrsSort
11041 bool operator() (const Handle(AIS_LightSource)& theLeft,
11042 const Handle(AIS_LightSource)& theRight)
11044 return theLeft->Light()->GetId() < theRight->Light()->GetId();
11048 AIS_ListOfInteractive aPrsList;
11049 aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
11050 if (!aPrsList.IsEmpty())
11052 // update light source presentations
11053 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
11054 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
11056 if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
11058 aLightPrsVec.push_back (aLightPrs2);
11062 // sort objects by id as AIS_InteractiveContext stores them in unordered map
11063 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
11065 Standard_Integer aTopStack = 0;
11066 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
11068 Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
11069 if (!aLightPrs2->TransformPersistence().IsNull()
11070 && aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
11072 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
11073 aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
11074 aTopStack += aPrsSize + aPrsSize / 2;
11076 aCtx->Redisplay (aLightPrs2, false);
11077 aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
11083 //===============================================================================================
11084 //function : VPBREnvironment
11086 //===============================================================================================
11087 static int VPBREnvironment (Draw_Interpretor&,
11088 Standard_Integer theArgsNb,
11089 const char** theArgVec)
11093 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
11097 Handle(V3d_View) aView = ViewerTest::CurrentView();
11098 if (aView.IsNull())
11100 Message::SendFail ("Error: no active viewer");
11104 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11107 if (anArg == "-generate"
11108 || anArg == "-gen")
11110 aView->GeneratePBREnvironment (Standard_True);
11112 else if (anArg == "-clear")
11114 aView->ClearPBREnvironment (Standard_True);
11118 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
11125 //! Read Graphic3d_RenderingParams::PerfCounters flag.
11126 static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11127 Standard_Boolean& theToReset,
11128 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11129 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11131 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11132 TCollection_AsciiString aVal = theValue;
11133 Standard_Boolean toReverse = Standard_False;
11134 if (aVal == "none")
11136 theToReset = Standard_True;
11137 return Standard_True;
11139 else if (aVal.StartsWith ("-"))
11141 toReverse = Standard_True;
11142 aVal = aVal.SubString (2, aVal.Length());
11144 else if (aVal.StartsWith ("no"))
11146 toReverse = Standard_True;
11147 aVal = aVal.SubString (3, aVal.Length());
11149 else if (aVal.StartsWith ("+"))
11151 aVal = aVal.SubString (2, aVal.Length());
11155 theToReset = Standard_True;
11159 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11160 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11161 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11162 else if (aVal == "structs"
11163 || aVal == "structures"
11164 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11165 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11166 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11167 else if (aVal == "tris"
11168 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11169 else if (aVal == "pnts"
11170 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
11171 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
11172 else if (aVal == "mem"
11173 || aVal == "gpumem"
11174 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
11175 else if (aVal == "skipimmediate"
11176 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11177 else if (aVal == "frametime"
11178 || aVal == "frametimers"
11179 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
11180 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11181 else if (aVal == "extended"
11182 || aVal == "verbose"
11183 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
11184 else if (aVal == "full"
11185 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
11188 return Standard_False;
11193 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11197 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11199 return Standard_True;
11202 //! Read Graphic3d_RenderingParams::PerfCounters flags.
11203 static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11204 Graphic3d_RenderingParams::PerfCounters& theFlags)
11206 TCollection_AsciiString aValue = theValue;
11207 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11208 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11209 Standard_Boolean toReset = Standard_False;
11212 Standard_Integer aSplitPos = aValue.Search ("|");
11213 if (aSplitPos <= 0)
11215 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11217 return Standard_False;
11221 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11223 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11224 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11225 return Standard_True;
11230 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11231 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11233 return Standard_False;
11236 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11240 //=======================================================================
11241 //function : VRenderParams
11242 //purpose : Enables/disables rendering features
11243 //=======================================================================
11245 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11246 Standard_Integer theArgNb,
11247 const char** theArgVec)
11249 Handle(V3d_View) aView = ViewerTest::CurrentView();
11250 if (aView.IsNull())
11252 Message::SendFail ("Error: no active viewer");
11256 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
11257 TCollection_AsciiString aCmdName (theArgVec[0]);
11258 aCmdName.LowerCase();
11259 if (aCmdName == "vraytrace")
11263 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11266 else if (theArgNb == 2)
11268 TCollection_AsciiString aValue (theArgVec[1]);
11269 aValue.LowerCase();
11273 aParams.Method = Graphic3d_RM_RAYTRACING;
11277 else if (aValue == "off"
11280 aParams.Method = Graphic3d_RM_RASTERIZATION;
11286 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
11292 Message::SendFail ("Syntax error: wrong number of arguments");
11299 theDI << "renderMode: ";
11300 switch (aParams.Method)
11302 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11303 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11306 theDI << "transparency: ";
11307 switch (aParams.TransparencyMethod)
11309 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11310 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11311 << TCollection_AsciiString (aParams.OitDepthFactor); break;
11312 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11313 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
11316 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
11317 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
11318 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11319 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11320 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
11321 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11322 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
11323 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11324 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11325 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11326 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11327 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11328 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11329 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
11330 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
11331 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
11332 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
11333 theDI << "shadingModel: ";
11334 switch (aView->ShadingModel())
11336 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11337 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11338 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11339 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11340 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11341 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11342 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
11346 theDI << "perfCounters:";
11347 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11351 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11355 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11357 theDI << " structs";
11359 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11361 theDI << " groups";
11363 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11365 theDI << " arrays";
11367 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11371 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11375 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11379 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11381 theDI << " gpumem";
11383 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11385 theDI << " frameTime";
11387 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11389 theDI << " skipimmediate";
11391 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11397 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
11398 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
11399 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11400 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11401 "noUpdate") << "\n";
11406 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
11407 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
11408 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11410 Standard_CString anArg (theArgVec[anArgIter]);
11411 TCollection_AsciiString aFlag (anArg);
11413 if (anUpdateTool.parseRedrawMode (aFlag))
11417 else if (aFlag == "-echo"
11418 || aFlag == "-print")
11420 toPrint = Standard_True;
11421 anUpdateTool.Invalidate();
11423 else if (aFlag == "-reset")
11425 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11427 else if (aFlag == "-sync"
11428 && (anArgIter + 1 < theArgNb))
11430 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11431 aSyncFlag.LowerCase();
11432 if (aSyncFlag == "default"
11433 || aSyncFlag == "defaults"
11434 || aSyncFlag == "viewer")
11436 toSyncDefaults = true;
11438 else if (aSyncFlag == "allviews"
11439 || aSyncFlag == "views")
11441 toSyncAllViews = true;
11445 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11449 else if (aFlag == "-mode"
11450 || aFlag == "-rendermode"
11451 || aFlag == "-render_mode")
11455 switch (aParams.Method)
11457 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11458 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11464 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11468 else if (aFlag == "-ray"
11469 || aFlag == "-raytrace")
11473 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11477 bool isRayTrace = true;
11478 if (anArgIter + 1 < theArgNb
11479 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
11483 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
11485 else if (aFlag == "-rast"
11486 || aFlag == "-raster"
11487 || aFlag == "-rasterization")
11491 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11495 bool isRaster = true;
11496 if (anArgIter + 1 < theArgNb
11497 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
11501 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
11503 else if (aFlag == "-msaa")
11507 theDI << aParams.NbMsaaSamples << " ";
11510 else if (++anArgIter >= theArgNb)
11512 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11516 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11517 if (aNbSamples < 0)
11519 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
11524 aParams.NbMsaaSamples = aNbSamples;
11527 else if (aFlag == "-linefeather"
11528 || aFlag == "-edgefeather"
11529 || aFlag == "-feather")
11533 theDI << " " << aParams.LineFeather << " ";
11536 else if (++anArgIter >= theArgNb)
11538 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11542 TCollection_AsciiString aParam = theArgVec[anArgIter];
11543 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11544 if (aFeather <= 0.0f)
11546 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
11549 aParams.LineFeather = aFeather;
11551 else if (aFlag == "-oit")
11555 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11557 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11559 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11561 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11565 theDI << "off" << " ";
11569 else if (++anArgIter >= theArgNb)
11571 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11575 TCollection_AsciiString aParam = theArgVec[anArgIter];
11576 aParam.LowerCase();
11577 if (aParam == "peeling"
11578 || aParam == "peel")
11580 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11581 if (anArgIter + 1 < theArgNb
11582 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11585 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11588 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11591 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11594 else if (aParam == "weighted"
11595 || aParam == "weight")
11597 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11598 if (anArgIter + 1 < theArgNb
11599 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11602 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11603 if (aWeight < 0.f || aWeight > 1.f)
11605 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11608 aParams.OitDepthFactor = aWeight;
11611 else if (aParam.IsRealValue())
11613 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11614 if (aWeight < 0.f || aWeight > 1.f)
11616 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11620 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11621 aParams.OitDepthFactor = aWeight;
11623 else if (aParam == "off")
11625 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11629 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11633 else if (aFlag == "-fonthinting"
11634 || aFlag == "-fonthint")
11638 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11640 theDI << "normal" << " ";
11642 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11644 theDI << "light" << " ";
11648 theDI << "off" << " ";
11652 else if (anArgIter + 1 >= theArgNb)
11654 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11658 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11659 aHintStyle.LowerCase();
11660 if (aHintStyle == "normal"
11661 || aHintStyle == "on"
11662 || aHintStyle == "1")
11664 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11665 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11667 else if (aHintStyle == "light")
11669 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11670 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11672 else if (aHintStyle == "no"
11673 || aHintStyle == "off"
11674 || aHintStyle == "0")
11676 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11677 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11681 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11685 else if (aFlag == "-fontautohinting"
11686 || aFlag == "-fontautohint")
11690 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11692 theDI << "force" << " ";
11694 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11696 theDI << "disallow" << " ";
11700 theDI << "auto" << " ";
11704 else if (anArgIter + 1 >= theArgNb)
11706 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11710 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11711 aHintStyle.LowerCase();
11712 if (aHintStyle == "force")
11714 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11715 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11717 else if (aHintStyle == "disallow"
11718 || aHintStyle == "no")
11720 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11721 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11723 else if (aHintStyle == "auto")
11725 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11726 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11730 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11734 else if (aFlag == "-depthprepass")
11738 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11741 aParams.ToEnableDepthPrepass = Standard_True;
11742 if (anArgIter + 1 < theArgNb
11743 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
11748 else if (aFlag == "-samplealphatocoverage"
11749 || aFlag == "-alphatocoverage")
11753 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11756 aParams.ToEnableAlphaToCoverage = Standard_True;
11757 if (anArgIter + 1 < theArgNb
11758 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
11763 else if (aFlag == "-rendscale"
11764 || aFlag == "-renderscale"
11765 || aFlag == "-renderresolutionscale")
11769 theDI << aParams.RenderResolutionScale << " ";
11772 else if (++anArgIter >= theArgNb)
11774 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11778 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11781 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
11786 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11789 else if (aFlag == "-raydepth"
11790 || aFlag == "-ray_depth")
11794 theDI << aParams.RaytracingDepth << " ";
11797 else if (++anArgIter >= theArgNb)
11799 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11803 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
11805 // We allow RaytracingDepth be more than 10 in case of GI enabled
11806 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
11808 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
11813 aParams.RaytracingDepth = aDepth;
11816 else if (aFlag == "-shad"
11817 || aFlag == "-shadows")
11821 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11825 Standard_Boolean toEnable = Standard_True;
11826 if (++anArgIter < theArgNb
11827 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11831 aParams.IsShadowEnabled = toEnable;
11833 else if (aFlag == "-shadowmapresolution"
11834 || aFlag == "-shadowmap")
11838 theDI << aParams.ShadowMapResolution << " ";
11841 else if (++anArgIter >= theArgNb)
11843 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11847 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11849 else if (aFlag == "-shadowmapbias")
11853 theDI << aParams.ShadowMapBias << " ";
11856 else if (++anArgIter >= theArgNb)
11858 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11862 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11864 else if (aFlag == "-refl"
11865 || aFlag == "-reflections")
11869 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11873 Standard_Boolean toEnable = Standard_True;
11874 if (++anArgIter < theArgNb
11875 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11879 aParams.IsReflectionEnabled = toEnable;
11881 else if (aFlag == "-fsaa")
11885 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11889 Standard_Boolean toEnable = Standard_True;
11890 if (++anArgIter < theArgNb
11891 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11895 aParams.IsAntialiasingEnabled = toEnable;
11897 else if (aFlag == "-gleam")
11901 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11905 Standard_Boolean toEnable = Standard_True;
11906 if (++anArgIter < theArgNb
11907 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11911 aParams.IsTransparentShadowEnabled = toEnable;
11913 else if (aFlag == "-gi")
11917 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11921 Standard_Boolean toEnable = Standard_True;
11922 if (++anArgIter < theArgNb
11923 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11927 aParams.IsGlobalIlluminationEnabled = toEnable;
11930 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11933 else if (aFlag == "-blockedrng"
11934 || aFlag == "-brng")
11938 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11942 Standard_Boolean toEnable = Standard_True;
11943 if (++anArgIter < theArgNb
11944 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11948 aParams.CoherentPathTracingMode = toEnable;
11950 else if (aFlag == "-maxrad")
11954 theDI << aParams.RadianceClampingValue << " ";
11957 else if (++anArgIter >= theArgNb)
11959 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11963 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11964 if (!aMaxRadStr.IsRealValue (Standard_True))
11966 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11970 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11971 if (aMaxRadiance <= 0.0)
11973 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
11978 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11981 else if (aFlag == "-iss")
11985 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11989 Standard_Boolean toEnable = Standard_True;
11990 if (++anArgIter < theArgNb
11991 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11995 aParams.AdaptiveScreenSampling = toEnable;
11997 else if (aFlag == "-issatomic")
12001 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12005 Standard_Boolean toEnable = Standard_True;
12006 if (++anArgIter < theArgNb
12007 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12011 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12013 else if (aFlag == "-issd")
12017 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12021 Standard_Boolean toEnable = Standard_True;
12022 if (++anArgIter < theArgNb
12023 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12027 aParams.ShowSamplingTiles = toEnable;
12029 else if (aFlag == "-tilesize")
12033 theDI << aParams.RayTracingTileSize << " ";
12036 else if (++anArgIter >= theArgNb)
12038 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12042 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12045 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
12048 aParams.RayTracingTileSize = aTileSize;
12050 else if (aFlag == "-nbtiles")
12054 theDI << aParams.NbRayTracingTiles << " ";
12057 else if (++anArgIter >= theArgNb)
12059 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12063 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
12066 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
12069 else if (aNbTiles > 0
12071 || aNbTiles > 1024))
12073 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
12075 aParams.NbRayTracingTiles = aNbTiles;
12077 else if (aFlag == "-env")
12081 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12085 Standard_Boolean toEnable = Standard_True;
12086 if (++anArgIter < theArgNb
12087 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12091 aParams.UseEnvironmentMapBackground = toEnable;
12093 else if (aFlag == "-ignorenormalmap")
12097 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12101 Standard_Boolean toEnable = Standard_True;
12102 if (++anArgIter < theArgNb
12103 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12107 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12109 else if (aFlag == "-twoside")
12113 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12117 Standard_Boolean toEnable = Standard_True;
12118 if (++anArgIter < theArgNb
12119 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12123 aParams.TwoSidedBsdfModels = toEnable;
12125 else if (aFlag == "-shademodel"
12126 || aFlag == "-shadingmodel"
12127 || aFlag == "-shading")
12131 switch (aView->ShadingModel())
12133 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12134 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12135 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12136 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12137 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12138 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12139 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
12144 if (++anArgIter >= theArgNb)
12146 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12149 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12150 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12151 && aModel != Graphic3d_TOSM_DEFAULT)
12153 aView->SetShadingModel (aModel);
12157 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
12161 else if (aFlag == "-pbrenvpow2size"
12162 || aFlag == "-pbrenvp2s"
12163 || aFlag == "-pep2s")
12165 if (++anArgIter >= theArgNb)
12167 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12171 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12172 if (aPbrEnvPow2Size < 1)
12174 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
12177 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12179 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12180 || aFlag == "-pbrenvspecmapnblevels"
12181 || aFlag == "-pbrenvspecmaplevels"
12182 || aFlag == "-pbrenvsmln"
12183 || aFlag == "-pesmln")
12185 if (++anArgIter >= theArgNb)
12187 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12191 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12192 if (aPbrEnvSpecMapNbLevels < 2)
12194 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
12197 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12199 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12200 || aFlag == "-pbrenvbakingdiffsamples"
12201 || aFlag == "-pbrenvbdsn")
12203 if (++anArgIter >= theArgNb)
12205 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12209 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12210 if (aPbrEnvBakingDiffNbSamples < 1)
12212 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
12215 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12217 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12218 || aFlag == "-pbrenvbakingspecsamples"
12219 || aFlag == "-pbrenvbssn")
12221 if (++anArgIter >= theArgNb)
12223 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12227 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12228 if (aPbrEnvBakingSpecNbSamples < 1)
12230 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
12233 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12235 else if (aFlag == "-pbrenvbakingprobability"
12236 || aFlag == "-pbrenvbp")
12238 if (++anArgIter >= theArgNb)
12240 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12243 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12244 if (aPbrEnvBakingProbability < 0.f
12245 || aPbrEnvBakingProbability > 1.f)
12247 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
12250 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12252 else if (aFlag == "-resolution")
12254 if (++anArgIter >= theArgNb)
12256 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12260 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12261 if (aResolution.IsIntegerValue())
12263 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12267 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
12271 else if (aFlag == "-rebuildglsl"
12272 || aFlag == "-rebuild")
12276 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12280 Standard_Boolean toEnable = Standard_True;
12281 if (++anArgIter < theArgNb
12282 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
12286 aParams.RebuildRayTracingShaders = toEnable;
12288 else if (aFlag == "-focal")
12290 if (++anArgIter >= theArgNb)
12292 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12296 TCollection_AsciiString aParam (theArgVec[anArgIter]);
12297 if (aParam.IsRealValue (Standard_True))
12299 float aFocalDist = static_cast<float> (aParam.RealValue());
12300 if (aFocalDist < 0)
12302 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
12305 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12309 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12313 else if (aFlag == "-aperture")
12315 if (++anArgIter >= theArgNb)
12317 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12321 TCollection_AsciiString aParam(theArgVec[anArgIter]);
12322 if (aParam.IsRealValue (Standard_True))
12324 float aApertureSize = static_cast<float> (aParam.RealValue());
12325 if (aApertureSize < 0)
12327 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
12330 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12334 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12338 else if (aFlag == "-exposure")
12340 if (++anArgIter >= theArgNb)
12342 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12346 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
12347 if (anExposure.IsRealValue (Standard_True))
12349 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12353 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12357 else if (aFlag == "-whitepoint")
12359 if (++anArgIter >= theArgNb)
12361 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12365 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
12366 if (aWhitePoint.IsRealValue (Standard_True))
12368 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12372 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12376 else if (aFlag == "-tonemapping")
12378 if (++anArgIter >= theArgNb)
12380 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12384 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12387 if (aMode == "disabled")
12389 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12391 else if (aMode == "filmic")
12393 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12397 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
12401 else if (aFlag == "-performancestats"
12402 || aFlag == "-performancecounters"
12403 || aFlag == "-perfstats"
12404 || aFlag == "-perfcounters"
12405 || aFlag == "-stats")
12407 if (++anArgIter >= theArgNb)
12409 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12413 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12414 aFlagsStr.LowerCase();
12415 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12416 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12418 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12421 aView->ChangeRenderingParams().CollectedStats = aFlags;
12422 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12424 else if (aFlag == "-perfupdateinterval"
12425 || aFlag == "-statsupdateinterval")
12427 if (++anArgIter >= theArgNb)
12429 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12432 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12434 else if (aFlag == "-perfchart"
12435 || aFlag == "-statschart")
12437 if (++anArgIter >= theArgNb)
12439 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12442 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12444 else if (aFlag == "-perfchartmax"
12445 || aFlag == "-statschartmax")
12447 if (++anArgIter >= theArgNb)
12449 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12452 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12454 else if (aFlag == "-frustumculling"
12455 || aFlag == "-culling")
12459 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12460 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12461 "noUpdate") << " ";
12465 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12466 if (++anArgIter < theArgNb)
12468 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12469 aStateStr.LowerCase();
12470 bool toEnable = true;
12471 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
12473 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12475 else if (aStateStr == "noupdate"
12476 || aStateStr == "freeze")
12478 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12485 aParams.FrustumCullingState = aState;
12489 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
12494 // set current view parameters as defaults
12495 if (toSyncDefaults)
12497 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12499 if (toSyncAllViews)
12501 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12503 aViewIter.Value()->ChangeRenderingParams() = aParams;
12509 //=======================================================================
12510 //function : searchInfo
12512 //=======================================================================
12513 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12514 const TCollection_AsciiString& theKey)
12516 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12518 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12520 return anIter.Value();
12523 return TCollection_AsciiString();
12526 //=======================================================================
12527 //function : VStatProfiler
12529 //=======================================================================
12530 static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12531 Standard_Integer theArgNb,
12532 const char** theArgVec)
12534 Handle(V3d_View) aView = ViewerTest::CurrentView();
12535 if (aView.IsNull())
12537 Message::SendFail ("Error: no active viewer");
12541 Standard_Boolean toRedraw = Standard_True;
12542 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12543 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12544 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12545 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12547 Standard_CString anArg (theArgVec[anArgIter]);
12548 TCollection_AsciiString aFlag (anArg);
12550 if (aFlag == "-noredraw")
12552 toRedraw = Standard_False;
12556 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12557 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12558 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12559 else if (aFlag == "alllayers"
12560 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12561 else if (aFlag == "allstructs"
12562 || aFlag == "allstructures"
12563 || aFlag == "structs"
12564 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
12565 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12566 else if (aFlag == "allarrays"
12567 || aFlag == "fillarrays"
12568 || aFlag == "linearrays"
12569 || aFlag == "pointarrays"
12570 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12571 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
12572 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
12573 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12574 else if (aFlag == "geommem"
12575 || aFlag == "texturemem"
12576 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12577 else if (aFlag == "elapsedframe"
12578 || aFlag == "cpuframeaverage"
12579 || aFlag == "cpupickingaverage"
12580 || aFlag == "cpucullingaverage"
12581 || aFlag == "cpudynaverage"
12582 || aFlag == "cpuframemax"
12583 || aFlag == "cpupickingmax"
12584 || aFlag == "cpucullingmax"
12585 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12588 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
12592 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12596 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12598 aView->ChangeRenderingParams().CollectedStats =
12599 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12603 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12605 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12608 TColStd_IndexedDataMapOfStringString aDict;
12609 aView->StatisticInformation (aDict);
12611 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12613 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12615 Standard_CString anArg(theArgVec[anArgIter]);
12616 TCollection_AsciiString aFlag(anArg);
12618 if (aFlag == "fps")
12620 theDI << searchInfo (aDict, "FPS") << " ";
12622 else if (aFlag == "cpu")
12624 theDI << searchInfo (aDict, "CPU FPS") << " ";
12626 else if (aFlag == "alllayers")
12628 theDI << searchInfo (aDict, "Layers") << " ";
12630 else if (aFlag == "layers")
12632 theDI << searchInfo (aDict, "Rendered layers") << " ";
12634 else if (aFlag == "allstructs"
12635 || aFlag == "allstructures")
12637 theDI << searchInfo (aDict, "Structs") << " ";
12639 else if (aFlag == "structs"
12640 || aFlag == "structures")
12642 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12643 if (aRend.IsEmpty()) // all structures rendered
12645 aRend = searchInfo (aDict, "Structs");
12647 theDI << aRend << " ";
12649 else if (aFlag == "groups")
12651 theDI << searchInfo (aDict, "Rendered groups") << " ";
12653 else if (aFlag == "allarrays")
12655 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12657 else if (aFlag == "fillarrays")
12659 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12661 else if (aFlag == "linearrays")
12663 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12665 else if (aFlag == "pointarrays")
12667 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12669 else if (aFlag == "textarrays")
12671 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12673 else if (aFlag == "triangles")
12675 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12677 else if (aFlag == "points")
12679 theDI << searchInfo (aDict, "Rendered points") << " ";
12681 else if (aFlag == "geommem")
12683 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12685 else if (aFlag == "texturemem")
12687 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12689 else if (aFlag == "framemem")
12691 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12693 else if (aFlag == "elapsedframe")
12695 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12697 else if (aFlag == "cpuframe_average")
12699 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12701 else if (aFlag == "cpupicking_average")
12703 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12705 else if (aFlag == "cpuculling_average")
12707 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12709 else if (aFlag == "cpudyn_average")
12711 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12713 else if (aFlag == "cpuframe_max")
12715 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12717 else if (aFlag == "cpupicking_max")
12719 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12721 else if (aFlag == "cpuculling_max")
12723 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12725 else if (aFlag == "cpudyn_max")
12727 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12735 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12737 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12739 theDI << "Statistic info:\n" << aView->StatisticInformation();
12744 //=======================================================================
12745 //function : VXRotate
12747 //=======================================================================
12748 static Standard_Integer VXRotate (Draw_Interpretor& di,
12749 Standard_Integer argc,
12750 const char ** argv)
12752 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12753 if (aContext.IsNull())
12755 di << argv[0] << "ERROR : use 'vinit' command before \n";
12761 di << "ERROR : Usage : " << argv[0] << " name angle\n";
12765 TCollection_AsciiString aName (argv[1]);
12766 Standard_Real anAngle = Draw::Atof (argv[2]);
12769 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12770 Handle(AIS_InteractiveObject) anIObj;
12771 if (!aMap.Find2 (aName, anIObj))
12773 di << "Use 'vdisplay' before\n";
12777 gp_Trsf aTransform;
12778 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12779 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
12781 aContext->SetLocation (anIObj, aTransform);
12782 aContext->UpdateCurrentViewer();
12788 //! Structure for setting AIS_Manipulator::SetPart() property.
12789 struct ManipAxisModeOnOff
12791 Standard_Integer Axis;
12792 AIS_ManipulatorMode Mode;
12793 Standard_Boolean ToEnable;
12795 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12798 enum ManipAjustPosition
12800 ManipAjustPosition_Off,
12801 ManipAjustPosition_Center,
12802 ManipAjustPosition_Location,
12803 ManipAjustPosition_ShapeLocation,
12807 //===============================================================================================
12808 //function : VManipulator
12810 //===============================================================================================
12811 static int VManipulator (Draw_Interpretor& theDi,
12812 Standard_Integer theArgsNb,
12813 const char** theArgVec)
12815 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
12816 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12817 if (aCurrentView.IsNull()
12818 || aViewer.IsNull())
12820 Message::SendFail ("Error: no active viewer");
12824 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12825 Standard_Integer anArgIter = 1;
12826 Handle(AIS_Manipulator) aManipulator;
12827 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12828 TCollection_AsciiString aName;
12830 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12831 Standard_Real aGap = -1.0, aSize = -1.0;
12832 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12833 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12835 bool toDetach = false;
12836 AIS_Manipulator::OptionsForAttach anAttachOptions;
12837 Handle(AIS_InteractiveObject) anAttachObject;
12838 Handle(V3d_View) aViewAffinity;
12839 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12841 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12842 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12843 Standard_Integer toStopMouseTransform = -1;
12844 // explicit transformation
12847 Standard_Real aTmpReal = 0.0;
12848 gp_XYZ aRotPnt, aRotAxis;
12849 for (; anArgIter < theArgsNb; ++anArgIter)
12851 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12853 if (anUpdateTool.parseRedrawMode (anArg))
12857 else if (anArg == "-help")
12859 theDi.PrintHelp (theArgVec[0]);
12863 else if (anArg == "-autoactivate"
12864 || anArg == "-noautoactivate")
12866 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12868 else if (anArg == "-followtranslation"
12869 || anArg == "-nofollowtranslation")
12871 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12873 else if (anArg == "-followrotation"
12874 || anArg == "-nofollowrotation")
12876 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12878 else if (anArg == "-followdragging"
12879 || anArg == "-nofollowdragging")
12881 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12883 else if (anArg == "-gap"
12884 && anArgIter + 1 < theArgsNb
12885 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12890 else if (anArg == "-size"
12891 && anArgIter + 1 < theArgsNb
12892 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12897 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12898 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12900 ManipAxisModeOnOff aPart;
12901 Standard_Integer aMode = 0;
12902 if (anArg == "-part")
12904 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12905 || aPart.Axis < 0 || aPart.Axis > 3)
12907 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12911 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12912 || aMode < 1 || aMode > 4)
12914 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12917 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12919 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12922 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12923 aParts.Append (aPart);
12925 else if (anArg == "-pos"
12926 && anArgIter + 3 < theArgsNb
12927 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12930 if (anArgIter + 3 < theArgsNb
12931 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12932 && aVDir.Modulus() > Precision::Confusion())
12936 if (anArgIter + 3 < theArgsNb
12937 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12938 && anXDir.Modulus() > Precision::Confusion())
12943 else if (anArg == "-zoomable"
12944 || anArg == "-notzoomable")
12946 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12949 else if (anArg == "-adjustposition"
12950 || anArg == "-noadjustposition")
12952 anAttachPos = ManipAjustPosition_Center;
12953 if (anArgIter + 1 < theArgsNb)
12955 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12956 aPosName.LowerCase();
12957 if (aPosName == "0")
12959 anAttachPos = ManipAjustPosition_Off;
12961 else if (aPosName == "1"
12962 || aPosName == "center")
12964 anAttachPos = ManipAjustPosition_Center;
12966 else if (aPosName == "transformation"
12967 || aPosName == "trsf"
12968 || aPosName == "location"
12969 || aPosName == "loc")
12971 anAttachPos = ManipAjustPosition_Location;
12973 else if (aPosName == "shapelocation"
12974 || aPosName == "shapeloc")
12976 anAttachPos = ManipAjustPosition_ShapeLocation;
12983 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12985 else if (anArg == "-adjustsize"
12986 || anArg == "-noadjustsize")
12988 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12990 else if (anArg == "-enablemodes"
12991 || anArg == "-enablemodes")
12993 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12996 else if (anArg == "-starttransform"
12997 && anArgIter + 2 < theArgsNb
12998 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12999 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
13003 else if (anArg == "-transform"
13004 && anArgIter + 2 < theArgsNb
13005 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
13006 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
13010 else if (anArg == "-stoptransform")
13012 toStopMouseTransform = 1;
13013 if (anArgIter + 1 < theArgsNb
13014 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
13017 toStopMouseTransform = 0;
13021 else if (anArg == "-move"
13022 && anArgIter + 3 < theArgsNb
13023 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
13026 aTrsf.SetTranslationPart (aTmpXYZ);
13028 else if (anArg == "-scale"
13029 && anArgIter + 1 < theArgsNb
13030 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
13033 aTrsf.SetScale (gp_Pnt(), aTmpReal);
13035 else if (anArg == "-rotate"
13036 && anArgIter + 7 < theArgsNb
13037 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
13038 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
13039 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
13042 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
13045 else if (anArg == "-detach")
13049 else if (anArg == "-attach"
13050 && anArgIter + 1 < theArgsNb)
13052 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
13053 if (!aMapAIS.Find2 (anObjName, anAttachObject))
13055 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
13059 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
13061 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13062 if (!aManip.IsNull()
13063 && aManip->IsAttached()
13064 && aManip->Object() == anAttachObject)
13066 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
13071 else if (anArg == "-view"
13072 && anArgIter + 1 < theArgsNb
13073 && aViewAffinity.IsNull())
13075 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
13076 if (aViewString == "active")
13078 aViewAffinity = ViewerTest::CurrentView();
13080 else // Check view name
13082 ViewerTest_Names aViewNames (aViewString);
13083 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13085 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13088 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13089 if (aViewAffinity.IsNull())
13091 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13096 else if (aName.IsEmpty())
13098 aName = theArgVec[anArgIter];
13099 if (!aMapAIS.IsBound2 (aName))
13101 aManipulator = new AIS_Manipulator();
13102 aManipulator->SetModeActivationOnDetection (true);
13103 aMapAIS.Bind (aManipulator, aName);
13107 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13108 if (aManipulator.IsNull())
13110 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13117 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13121 if (aName.IsEmpty())
13123 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
13127 && aManipulator.IsNull())
13129 aManipulator = new AIS_Manipulator();
13130 aManipulator->SetModeActivationOnDetection (true);
13131 aMapAIS.Bind (aManipulator, aName);
13134 // -----------------------------------------
13135 // change properties of manipulator instance
13136 // -----------------------------------------
13138 if (toAutoActivate != -1)
13140 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
13142 if (toFollowTranslation != -1)
13144 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
13146 if (toFollowRotation != -1)
13148 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
13150 if (toFollowDragging != -1)
13152 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
13156 aManipulator->SetGap ((float )aGap);
13159 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
13161 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13162 if (aPart.Axis == -1)
13164 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
13168 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
13174 aManipulator->SetSize ((float )aSize);
13176 if (isZoomable != -1)
13178 aManipulator->SetZoomPersistence (isZoomable == 0);
13180 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13182 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13183 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13187 // ----------------------------------
13188 // detach existing manipulator object
13189 // ----------------------------------
13193 aManipulator->Detach();
13194 aMapAIS.UnBind2 (aName);
13195 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13198 // ---------------------------------------------------
13199 // attach, detach or access manipulator from an object
13200 // ---------------------------------------------------
13202 if (!anAttachObject.IsNull())
13204 aManipulator->Attach (anAttachObject, anAttachOptions);
13206 if (!aViewAffinity.IsNull())
13208 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
13209 anIter.More(); anIter.Next())
13211 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
13213 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13216 if (anAttachPos != ManipAjustPosition_Off
13217 && aManipulator->IsAttached()
13218 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13220 gp_Ax2 aPosition = gp::XOY();
13221 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13222 switch (anAttachPos)
13224 case ManipAjustPosition_Off:
13228 case ManipAjustPosition_Location:
13230 aPosition = gp::XOY().Transformed (aBaseTrsf);
13233 case ManipAjustPosition_ShapeLocation:
13235 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
13237 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
13241 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
13246 case ManipAjustPosition_Center:
13249 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13252 anObjIter.Value()->BoundingBox (anObjBox);
13253 aBox.Add (anObjBox);
13255 aBox = aBox.FinitePart();
13256 if (!aBox.IsVoid())
13258 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13259 aPosition.SetLocation (aCenter);
13264 aManipulator->SetPosition (aPosition);
13266 if (!Precision::IsInfinite (aLocation.X()))
13268 if (aVDir.Modulus() <= Precision::Confusion())
13270 aVDir = aManipulator->Position().Direction().XYZ();
13272 if (anXDir.Modulus() <= Precision::Confusion())
13274 anXDir = aManipulator->Position().XDirection().XYZ();
13276 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
13279 // --------------------------------------
13280 // apply transformation using manipulator
13281 // --------------------------------------
13283 if (aMousePosFrom.x() != IntegerLast())
13285 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
13287 if (aMousePosTo.x() != IntegerLast())
13289 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
13291 if (toStopMouseTransform != -1)
13293 aManipulator->StopTransform (toStopMouseTransform == 1);
13296 if (aTrsf.Form() != gp_Identity)
13298 aManipulator->Transform (aTrsf);
13301 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13303 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
13308 //===============================================================================================
13309 //function : VSelectionProperties
13311 //===============================================================================================
13312 static int VSelectionProperties (Draw_Interpretor& theDi,
13313 Standard_Integer theArgsNb,
13314 const char** theArgVec)
13316 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13319 Message::SendFail ("Error: no active viewer");
13323 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13325 // handle obsolete alias
13326 bool toEnable = true;
13329 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13332 else if (theArgsNb != 2
13333 || !Draw::ParseOnOff (theArgVec[1], toEnable))
13335 Message::SendFail ("Syntax error: wrong number of parameters");
13338 if (toEnable != aCtx->ToHilightSelected())
13340 aCtx->ClearDetected();
13341 aCtx->SetToHilightSelected (toEnable);
13346 Standard_Boolean toPrint = theArgsNb == 1;
13347 Standard_Boolean toRedraw = Standard_False;
13348 Standard_Integer anArgIter = 1;
13349 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13350 if (anArgIter < theArgsNb)
13352 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13353 anArgFirst.LowerCase();
13355 if (anArgFirst == "dynhighlight"
13356 || anArgFirst == "dynhilight"
13357 || anArgFirst == "dynamichighlight"
13358 || anArgFirst == "dynamichilight")
13360 aType = Prs3d_TypeOfHighlight_Dynamic;
13362 else if (anArgFirst == "localdynhighlight"
13363 || anArgFirst == "localdynhilight"
13364 || anArgFirst == "localdynamichighlight"
13365 || anArgFirst == "localdynamichilight")
13367 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13369 else if (anArgFirst == "selhighlight"
13370 || anArgFirst == "selhilight"
13371 || anArgFirst == "selectedhighlight"
13372 || anArgFirst == "selectedhilight")
13374 aType = Prs3d_TypeOfHighlight_Selected;
13376 else if (anArgFirst == "localselhighlight"
13377 || anArgFirst == "localselhilight"
13378 || anArgFirst == "localselectedhighlight"
13379 || anArgFirst == "localselectedhilight")
13381 aType = Prs3d_TypeOfHighlight_LocalSelected;
13388 for (; anArgIter < theArgsNb; ++anArgIter)
13390 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13392 if (anArg == "-help")
13394 theDi.PrintHelp (theArgVec[0]);
13397 else if (anArg == "-print")
13399 toPrint = Standard_True;
13401 else if (anArg == "-autoactivate")
13403 Standard_Boolean toEnable = Standard_True;
13404 if (anArgIter + 1 < theArgsNb
13405 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13409 aCtx->SetAutoActivateSelection (toEnable);
13411 else if (anArg == "-automatichighlight"
13412 || anArg == "-automatichilight"
13413 || anArg == "-autohighlight"
13414 || anArg == "-autohilight")
13416 Standard_Boolean toEnable = Standard_True;
13417 if (anArgIter + 1 < theArgsNb
13418 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13422 aCtx->ClearSelected (false);
13423 aCtx->ClearDetected();
13424 aCtx->SetAutomaticHilight (toEnable);
13427 else if (anArg == "-highlightselected"
13428 || anArg == "-hilightselected")
13430 Standard_Boolean toEnable = Standard_True;
13431 if (anArgIter + 1 < theArgsNb
13432 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13436 aCtx->ClearDetected();
13437 aCtx->SetToHilightSelected (toEnable);
13440 else if (anArg == "-pickstrategy"
13441 || anArg == "-pickingstrategy")
13443 if (++anArgIter >= theArgsNb)
13445 Message::SendFail ("Syntax error: type of highlighting is undefined");
13449 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13450 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13452 if (aVal == "first"
13453 || aVal == "firstaccepted"
13454 || aVal == "firstacceptable")
13456 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13458 else if (aVal == "topmost"
13459 || aVal == "onlyTopmost")
13461 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13465 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
13469 aCtx->SetPickingStrategy (aStrategy);
13471 else if (anArg == "-pixtol"
13472 && anArgIter + 1 < theArgsNb)
13474 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13476 else if (anArg == "-preferclosest")
13478 bool toPreferClosest = true;
13479 if (anArgIter + 1 < theArgsNb
13480 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13484 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13486 else if ((anArg == "-depthtol"
13487 || anArg == "-depthtolerance")
13488 && anArgIter + 1 < theArgsNb)
13490 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13491 aTolType.LowerCase();
13492 if (aTolType == "uniform")
13494 if (anArgIter + 1 >= theArgsNb)
13496 Message::SendFail() << "Syntax error: wrong number of arguments";
13499 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13500 Draw::Atof (theArgVec[++anArgIter]));
13502 else if (aTolType == "uniformpx")
13504 if (anArgIter + 1 >= theArgsNb)
13506 Message::SendFail() << "Syntax error: wrong number of arguments";
13509 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13510 Draw::Atof (theArgVec[++anArgIter]));
13512 else if (aTolType == "sensfactor")
13514 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13518 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13522 else if ((anArg == "-mode"
13523 || anArg == "-dispmode")
13524 && anArgIter + 1 < theArgsNb)
13526 if (aType == Prs3d_TypeOfHighlight_None)
13528 Message::SendFail ("Syntax error: type of highlighting is undefined");
13532 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13533 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13534 aStyle->SetDisplayMode (aDispMode);
13535 toRedraw = Standard_True;
13537 else if (anArg == "-layer"
13538 && anArgIter + 1 < theArgsNb)
13540 if (aType == Prs3d_TypeOfHighlight_None)
13542 Message::SendFail ("Syntax error: type of highlighting is undefined");
13547 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13548 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
13550 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
13554 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13555 aStyle->SetZLayer (aNewLayer);
13556 toRedraw = Standard_True;
13558 else if (anArg == "-hicolor"
13559 || anArg == "-selcolor"
13560 || anArg == "-color")
13562 if (anArg.StartsWith ("-hi"))
13564 aType = Prs3d_TypeOfHighlight_Dynamic;
13566 else if (anArg.StartsWith ("-sel"))
13568 aType = Prs3d_TypeOfHighlight_Selected;
13570 else if (aType == Prs3d_TypeOfHighlight_None)
13572 Message::SendFail ("Syntax error: type of highlighting is undefined");
13576 Quantity_Color aColor;
13577 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13578 theArgVec + anArgIter + 1,
13580 if (aNbParsed == 0)
13582 Message::SendFail ("Syntax error: need more arguments");
13585 anArgIter += aNbParsed;
13587 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13588 aStyle->SetColor (aColor);
13589 toRedraw = Standard_True;
13591 else if ((anArg == "-transp"
13592 || anArg == "-transparency"
13593 || anArg == "-hitransp"
13594 || anArg == "-seltransp"
13595 || anArg == "-hitransplocal"
13596 || anArg == "-seltransplocal")
13597 && anArgIter + 1 < theArgsNb)
13599 if (anArg.StartsWith ("-hi"))
13601 aType = Prs3d_TypeOfHighlight_Dynamic;
13603 else if (anArg.StartsWith ("-sel"))
13605 aType = Prs3d_TypeOfHighlight_Selected;
13607 else if (aType == Prs3d_TypeOfHighlight_None)
13609 Message::SendFail ("Syntax error: type of highlighting is undefined");
13613 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13614 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13615 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13616 toRedraw = Standard_True;
13618 else if ((anArg == "-mat"
13619 || anArg == "-material")
13620 && anArgIter + 1 < theArgsNb)
13622 if (aType == Prs3d_TypeOfHighlight_None)
13624 Message::SendFail ("Syntax error: type of highlighting is undefined");
13628 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13629 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
13630 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
13633 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13634 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13635 Graphic3d_MaterialAspect aMat (aMatName);
13636 aMat.SetColor (aStyle->Color());
13637 aMat.SetTransparency (aStyle->Transparency());
13638 anAspect->SetFrontMaterial (aMat);
13639 anAspect->SetInteriorColor (aStyle->Color());
13640 aStyle->SetBasicFillAreaAspect (anAspect);
13644 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13646 toRedraw = Standard_True;
13650 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
13657 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13658 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
13659 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
13660 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13661 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
13662 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
13663 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13664 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13665 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13666 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13667 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13668 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13669 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13670 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
13673 if (aCtx->NbSelected() != 0 && toRedraw)
13675 aCtx->HilightSelected (Standard_True);
13681 //===============================================================================================
13682 //function : VDumpSelectionImage
13684 //===============================================================================================
13685 static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13686 Standard_Integer theArgsNb,
13687 const char** theArgVec)
13689 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13690 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13691 if (aContext.IsNull())
13693 Message::SendFail ("Error: no active viewer");
13697 TCollection_AsciiString aFile;
13698 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13699 Handle(Graphic3d_Camera) aCustomCam;
13700 Image_Format anImgFormat = Image_Format_BGR;
13701 Standard_Integer aPickedIndex = 1;
13702 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13704 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13705 aParam.LowerCase();
13706 if (aParam == "-type")
13708 if (++anArgIter >= theArgsNb)
13710 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
13714 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13715 aValue.LowerCase();
13716 if (aValue == "depth"
13717 || aValue == "normdepth"
13718 || aValue == "normalizeddepth")
13720 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13721 anImgFormat = Image_Format_GrayF;
13723 else if (aValue == "depthinverted"
13724 || aValue == "normdepthinverted"
13725 || aValue == "normalizeddepthinverted"
13726 || aValue == "inverted")
13728 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
13729 anImgFormat = Image_Format_GrayF;
13731 else if (aValue == "unnormdepth"
13732 || aValue == "unnormalizeddepth")
13734 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
13735 anImgFormat = Image_Format_GrayF;
13737 else if (aValue == "objectcolor"
13738 || aValue == "object"
13739 || aValue == "color")
13741 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13743 else if (aValue == "entitycolor"
13744 || aValue == "entity")
13746 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13748 else if (aValue == "entitytypecolor"
13749 || aValue == "entitytype")
13751 aType = StdSelect_TypeOfSelectionImage_ColoredEntityType;
13753 else if (aValue == "ownercolor"
13754 || aValue == "owner")
13756 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13758 else if (aValue == "selectionmodecolor"
13759 || aValue == "selectionmode"
13760 || aValue == "selmodecolor"
13761 || aValue == "selmode")
13763 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13765 else if (aValue == "surfnormal"
13766 || aValue == "surfacenormal"
13767 || aValue == "normal")
13769 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13773 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13777 else if (aParam == "-picked"
13778 || aParam == "-pickeddepth"
13779 || aParam == "-pickedindex")
13781 if (++anArgIter >= theArgsNb)
13783 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
13787 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13789 else if (anArgIter + 1 < theArgsNb
13790 && aParam == "-xrpose")
13792 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13793 anXRArg.LowerCase();
13794 if (anXRArg == "base")
13796 aCustomCam = aView->View()->BaseXRCamera();
13798 else if (anXRArg == "head")
13800 aCustomCam = aView->View()->PosedXRCamera();
13804 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13807 if (aCustomCam.IsNull())
13809 Message::SendFail() << "Error: undefined XR pose";
13813 else if (aFile.IsEmpty())
13815 aFile = theArgVec[anArgIter];
13819 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13823 if (aFile.IsEmpty())
13825 Message::SendFail ("Syntax error: image file name is missing");
13829 Standard_Integer aWidth = 0, aHeight = 0;
13830 aView->Window()->Size (aWidth, aHeight);
13832 Image_AlienPixMap aPixMap;
13833 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13835 Message::SendFail ("Error: can't allocate image");
13839 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13840 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13841 if (!aCustomCam.IsNull())
13843 aView->SetCamera (aCustomCam);
13845 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13847 Message::SendFail ("Error: can't generate selection image");
13850 if (!aCustomCam.IsNull())
13852 aView->SetCamera (aCamBack);
13854 aView->SetImmediateUpdate (wasImmUpdate);
13856 if (!aPixMap.Save (aFile))
13858 Message::SendFail ("Error: can't save selection image");
13864 //===============================================================================================
13865 //function : VViewCube
13867 //===============================================================================================
13868 static int VViewCube (Draw_Interpretor& ,
13869 Standard_Integer theNbArgs,
13870 const char** theArgVec)
13872 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13873 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13874 if (aContext.IsNull() || aView.IsNull())
13876 Message::SendFail ("Error: no active viewer");
13879 else if (theNbArgs < 2)
13881 Message::SendFail ("Syntax error: wrong number arguments");
13885 Handle(AIS_ViewCube) aViewCube;
13886 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13887 Quantity_Color aColorRgb;
13888 TCollection_AsciiString aName;
13889 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13891 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13893 if (anUpdateTool.parseRedrawMode (anArg))
13897 else if (aViewCube.IsNull())
13899 aName = theArgVec[anArgIter];
13900 if (aName.StartsWith ("-"))
13902 Message::SendFail ("Syntax error: object name should be specified");
13905 Handle(AIS_InteractiveObject) aPrs;
13906 GetMapOfAIS().Find2 (aName, aPrs);
13907 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13908 if (aViewCube.IsNull())
13910 aViewCube = new AIS_ViewCube();
13911 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13912 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13913 aViewCube->SetFixedAnimationLoop (false);
13916 else if (anArg == "-reset")
13918 aViewCube->ResetStyles();
13920 else if (anArg == "-color"
13921 || anArg == "-boxcolor"
13922 || anArg == "-boxsidecolor"
13923 || anArg == "-sidecolor"
13924 || anArg == "-boxedgecolor"
13925 || anArg == "-edgecolor"
13926 || anArg == "-boxcornercolor"
13927 || anArg == "-cornercolor"
13928 || anArg == "-innercolor"
13929 || anArg == "-textcolor"
13930 || anArg == "-xaxistextcolor"
13931 || anArg == "-yaxistextcolor"
13932 || anArg == "-zaxistextcolor")
13934 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13935 theArgVec + anArgIter + 1,
13937 if (aNbParsed == 0)
13939 Message::SendFail() << "Syntax error at '" << anArg << "'";
13942 anArgIter += aNbParsed;
13943 if (anArg == "-boxcolor")
13945 aViewCube->SetBoxColor (aColorRgb);
13947 else if (anArg == "-boxsidecolor"
13948 || anArg == "-sidecolor")
13950 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13951 aViewCube->SynchronizeAspects();
13953 else if (anArg == "-boxedgecolor"
13954 || anArg == "-edgecolor")
13956 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13957 aViewCube->SynchronizeAspects();
13959 else if (anArg == "-boxcornercolor"
13960 || anArg == "-cornercolor")
13962 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13963 aViewCube->SynchronizeAspects();
13965 else if (anArg == "-innercolor")
13967 aViewCube->SetInnerColor (aColorRgb);
13969 else if (anArg == "-textcolor")
13971 aViewCube->SetTextColor (aColorRgb);
13973 else if (anArg == "-xaxistextcolor"
13974 || anArg == "-yaxistextcolor"
13975 || anArg == "-zaxistextcolor")
13977 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13978 ? Prs3d_DatumParts_XAxis
13979 : (anArg.Value (2) == 'y'
13980 ? Prs3d_DatumParts_YAxis
13981 : Prs3d_DatumParts_ZAxis);
13982 aViewCube->Attributes()->SetOwnDatumAspects();
13983 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13987 aViewCube->SetColor (aColorRgb);
13990 else if (anArgIter + 1 < theNbArgs
13991 && (anArg == "-transparency"
13992 || anArg == "-boxtransparency"))
13994 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13995 if (aValue < 0.0 || aValue > 1.0)
13997 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
14001 if (anArg == "-boxtransparency")
14003 aViewCube->SetBoxTransparency (aValue);
14007 aViewCube->SetTransparency (aValue);
14010 else if (anArg == "-axes"
14011 || anArg == "-edges"
14012 || anArg == "-vertices"
14013 || anArg == "-vertexes"
14014 || anArg == "-fixedanimation")
14016 bool toShow = true;
14017 if (anArgIter + 1 < theNbArgs
14018 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
14022 if (anArg == "-fixedanimation")
14024 aViewCube->SetFixedAnimationLoop (toShow);
14026 else if (anArg == "-axes")
14028 aViewCube->SetDrawAxes (toShow);
14030 else if (anArg == "-edges")
14032 aViewCube->SetDrawEdges (toShow);
14036 aViewCube->SetDrawVertices (toShow);
14039 else if (anArg == "-yup"
14040 || anArg == "-zup")
14043 if (anArgIter + 1 < theNbArgs
14044 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
14048 if (anArg == "-yup")
14050 aViewCube->SetYup (isOn);
14054 aViewCube->SetYup (!isOn);
14057 else if (anArgIter + 1 < theNbArgs
14058 && anArg == "-font")
14060 aViewCube->SetFont (theArgVec[++anArgIter]);
14062 else if (anArgIter + 1 < theNbArgs
14063 && anArg == "-fontheight")
14065 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
14067 else if (anArgIter + 1 < theNbArgs
14068 && (anArg == "-size"
14069 || anArg == "-boxsize"))
14071 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
14072 anArg != "-boxsize");
14074 else if (anArgIter + 1 < theNbArgs
14075 && (anArg == "-boxfacet"
14076 || anArg == "-boxfacetextension"
14077 || anArg == "-facetextension"
14078 || anArg == "-extension"))
14080 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
14082 else if (anArgIter + 1 < theNbArgs
14083 && (anArg == "-boxedgegap"
14084 || anArg == "-edgegap"))
14086 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
14088 else if (anArgIter + 1 < theNbArgs
14089 && (anArg == "-boxedgeminsize"
14090 || anArg == "-edgeminsize"))
14092 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14094 else if (anArgIter + 1 < theNbArgs
14095 && (anArg == "-boxcornerminsize"
14096 || anArg == "-cornerminsize"))
14098 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14100 else if (anArgIter + 1 < theNbArgs
14101 && anArg == "-axespadding")
14103 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14105 else if (anArgIter + 1 < theNbArgs
14106 && anArg == "-roundradius")
14108 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14110 else if (anArgIter + 1 < theNbArgs
14111 && anArg == "-duration")
14113 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14115 else if (anArgIter + 1 < theNbArgs
14116 && anArg == "-axesradius")
14118 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14120 else if (anArgIter + 1 < theNbArgs
14121 && anArg == "-axesconeradius")
14123 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14125 else if (anArgIter + 1 < theNbArgs
14126 && anArg == "-axessphereradius")
14128 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14132 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14136 if (aViewCube.IsNull())
14138 Message::SendFail ("Syntax error: wrong number of arguments");
14142 ViewerTest::Display (aName, aViewCube, false);
14146 //===============================================================================================
14147 //function : VColorConvert
14149 //===============================================================================================
14150 static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14152 if (theNbArgs != 6)
14154 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14158 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14159 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14161 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14165 const char* aTypeStr = theArgVec[2];
14166 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14167 if (! strcasecmp (aTypeStr, "srgb"))
14169 aType = Quantity_TOC_sRGB;
14171 else if (! strcasecmp (aTypeStr, "hls"))
14173 aType = Quantity_TOC_HLS;
14175 else if (! strcasecmp (aTypeStr, "lab"))
14177 aType = Quantity_TOC_CIELab;
14179 else if (! strcasecmp (aTypeStr, "lch"))
14181 aType = Quantity_TOC_CIELch;
14185 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14189 double aC1 = Draw::Atof (theArgVec[3]);
14190 double aC2 = Draw::Atof (theArgVec[4]);
14191 double aC3 = Draw::Atof (theArgVec[5]);
14193 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14194 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14196 // print values with 6 decimal digits
14198 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14204 //===============================================================================================
14205 //function : VColorDiff
14207 //===============================================================================================
14208 static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14210 if (theNbArgs != 7)
14212 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14216 double aR1 = Draw::Atof (theArgVec[1]);
14217 double aG1 = Draw::Atof (theArgVec[2]);
14218 double aB1 = Draw::Atof (theArgVec[3]);
14219 double aR2 = Draw::Atof (theArgVec[4]);
14220 double aG2 = Draw::Atof (theArgVec[5]);
14221 double aB2 = Draw::Atof (theArgVec[6]);
14223 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14224 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14226 theDI << aColor1.DeltaE2000 (aColor2);
14231 //===============================================================================================
14232 //function : VSelBvhBuild
14234 //===============================================================================================
14235 static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14237 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14240 Message::SendFail ("Error: no active viewer");
14246 Message::SendFail ("Error: command syntax is incorrect, see help");
14250 Standard_Integer toEnable = -1;
14251 Standard_Integer aThreadsNb = -1;
14252 Standard_Boolean toWait = Standard_False;
14254 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14256 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14259 if (anArg == "-nbthreads"
14260 && anArgIter + 1 < theNbArgs)
14262 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14263 if (aThreadsNb < 1)
14265 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14268 else if (anArg == "-wait")
14270 toWait = Standard_True;
14272 else if (toEnable == -1)
14274 Standard_Boolean toEnableValue = Standard_True;
14275 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14277 toEnable = toEnableValue ? 1 : 0;
14281 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14287 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14292 if (aThreadsNb == -1)
14296 if (toEnable != -1)
14298 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14302 aCtx->MainSelector()->WaitForBVHBuild();
14308 //=======================================================================
14309 //function : ViewerTest_ExitProc
14311 //=======================================================================
14312 static void ViewerTest_ExitProc (ClientData )
14314 NCollection_List<TCollection_AsciiString> aViewList;
14315 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14316 anIter.More(); anIter.Next())
14318 aViewList.Append (anIter.Key1());
14321 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14322 anIter.More(); anIter.Next())
14324 ViewerTest::RemoveView (anIter.Value(), true);
14328 //=======================================================================
14329 //function : ViewerCommands
14331 //=======================================================================
14333 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14335 static bool TheIsInitialized = false;
14336 if (TheIsInitialized)
14341 TheIsInitialized = true;
14342 // define destruction callback to destroy views in a well-defined order
14343 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
14345 const char *group = "ZeViewer";
14346 theCommands.Add("vdriver",
14347 "vdriver [-list] [-default DriverName] [-load DriverName]"
14348 "\n\t\t: Manages active graphic driver factory."
14349 "\n\t\t: Prints current active driver when called without arguments."
14350 "\n\t\t: Makes specified driver active when ActiveName argument is specified."
14351 "\n\t\t: -list print registered factories"
14352 "\n\t\t: -default define which factory should be used by default (to be used by next vinit call)"
14353 "\n\t\t: -load try loading factory plugin and set it as default one",
14354 __FILE__, VDriver, group);
14355 theCommands.Add("vinit",
14356 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
14357 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
14358 #if defined(HAVE_XLIB)
14359 "\n\t\t: [-display displayName]"
14361 "\n\t\t: Creates new View window with specified name viewName."
14362 "\n\t\t: By default the new view is created in the viewer and in"
14363 "\n\t\t: graphic driver shared with active view."
14364 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14365 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14366 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
14367 #if defined(HAVE_XLIB)
14368 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14369 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
14371 "\n\t\t: -left, -top pixel position of left top corner of the window."
14372 "\n\t\t: -width, -height width and height of window respectively."
14373 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
14374 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14375 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
14376 "\n\t\t: -virtual create an offscreen window within interactive session"
14377 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
14378 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
14379 __FILE__,VInit,group);
14380 theCommands.Add("vclose" ,
14381 "[view_id [keep_context=0|1]]\n"
14382 "or vclose ALL - to remove all created views\n"
14383 " - removes view(viewer window) defined by its view_id.\n"
14384 " - keep_context: by default 0; if 1 and the last view is deleted"
14385 " the current context is not removed.",
14386 __FILE__,VClose,group);
14387 theCommands.Add("vactivate" ,
14388 "vactivate view_id [-noUpdate]"
14389 " - activates view(viewer window) defined by its view_id",
14390 __FILE__,VActivate,group);
14391 theCommands.Add("vviewlist",
14392 "vviewlist [format={tree, long}]"
14393 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14394 " - format: format of result output, if tree the output is a tree view;"
14395 "otherwise it's a list of full view names. By default format = tree",
14396 __FILE__,VViewList,group);
14397 theCommands.Add("vhelp" ,
14398 "vhelp : display help on the viewer commands",
14399 __FILE__,VHelp,group);
14400 theCommands.Add("vviewproj",
14401 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14402 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14403 "\n\t\t: Setup view direction"
14404 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14405 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14406 "\n\t\t: for example '+Z' will show front of the model,"
14407 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14408 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14409 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14410 __FILE__,VViewProj,group);
14411 theCommands.Add("vtop" ,
14412 "vtop or <T> : Top view. Orientation +X+Y" ,
14413 __FILE__,VViewProj,group);
14414 theCommands.Add("vbottom" ,
14415 "vbottom : Bottom view. Orientation +X-Y" ,
14416 __FILE__,VViewProj,group);
14417 theCommands.Add("vleft" ,
14418 "vleft : Left view. Orientation -Y+Z" ,
14419 __FILE__,VViewProj,group);
14420 theCommands.Add("vright" ,
14421 "vright : Right view. Orientation +Y+Z" ,
14422 __FILE__,VViewProj,group);
14423 theCommands.Add("vaxo" ,
14424 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
14425 __FILE__,VViewProj,group);
14426 theCommands.Add("vfront" ,
14427 "vfront : Front view. Orientation +X+Z" ,
14428 __FILE__,VViewProj,group);
14429 theCommands.Add("vback" ,
14430 "vback : Back view. Orientation -X+Z" ,
14431 __FILE__,VViewProj,group);
14432 theCommands.Add("vpick" ,
14433 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14435 theCommands.Add("vfit",
14436 "vfit or <F> [-selected] [-noupdate]"
14437 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
14438 __FILE__,VFit,group);
14439 theCommands.Add ("vfitarea",
14440 "vfitarea x1 y1 x2 y2"
14441 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14442 "\n\t\t: Fit view to show area located between two points"
14443 "\n\t\t: given in world 2D or 3D corrdinates.",
14444 __FILE__, VFitArea, group);
14445 theCommands.Add ("vzfit", "vzfit [scale]\n"
14446 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14447 " \"scale\" - specifies factor to scale computed z range.\n",
14448 __FILE__, VZFit, group);
14449 theCommands.Add("vrepaint",
14450 "vrepaint [-immediate] [-continuous FPS]"
14451 "\n\t\t: force redraw of active View"
14452 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14453 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14454 "\n\t\t: 0 means no continuous rendering,"
14455 "\n\t\t: -1 means non-stop redraws,"
14456 "\n\t\t: >0 specifies target framerate,",
14457 __FILE__,VRepaint,group);
14458 theCommands.Add("vclear",
14460 "\n\t\t: remove all the object from the viewer",
14461 __FILE__,VClear,group);
14464 "Changes background or some background settings.\n"
14467 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14468 " vbackground -imageMode FillType\n"
14469 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14470 " vbackground -gradientMode FillMethod\n"
14471 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
14472 " vbackground -color Color\n"
14473 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14474 " vbackground -default -color Color\n"
14475 " vbackground -help\n"
14478 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14479 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14480 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14481 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
14482 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
14483 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14484 " -order (-o): defines order of tiles in one image cubemap\n"
14485 " (has no effect in case of multi image cubemaps)\n"
14486 " -color (-col): sets background color\n"
14487 " -default (-def): sets background default gradient or color\n"
14488 " -help (-h): outputs short help message\n"
14491 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
14492 " or reals within the range [0.0, 1.0]\n"
14493 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14494 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14495 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
14497 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14498 " ImageFile: a name of the file with the image used as a background\n"
14499 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14500 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
14504 theCommands.Add ("vsetbg",
14505 "Loads image as background."
14506 "\n\t\t: vsetbg ImageFile [FillType]"
14507 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14508 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14512 theCommands.Add ("vsetbgmode",
14513 "Changes background image fill type."
14514 "\n\t\t: vsetbgmode [-imageMode] FillType"
14515 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14519 theCommands.Add ("vsetgradientbg",
14520 "Mounts gradient background."
14521 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14522 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14523 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14527 theCommands.Add ("vsetgrbgmode",
14528 "Changes gradient background fill method."
14529 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14530 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14534 theCommands.Add ("vsetcolorbg",
14535 "Sets background color."
14536 "\n\t\t: vsetcolorbg [-color] Color."
14537 "\n\t\t: Alias for 'vbackground -color Color'.",
14541 theCommands.Add ("vsetdefaultbg",
14542 "Sets default viewer background fill color (flat/gradient)."
14543 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14544 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14545 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14546 "\n\t\t: vsetdefaultbg [-color] Color"
14547 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14551 theCommands.Add("vscale",
14552 "vscale : vscale X Y Z",
14553 __FILE__,VScale,group);
14554 theCommands.Add("vzbufftrihedron",
14555 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14556 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14557 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14558 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14559 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
14560 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
14561 "\n\t\t: Displays a trihedron",
14562 __FILE__,VZBuffTrihedron,group);
14563 theCommands.Add("vrotate",
14564 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14565 "\n : Option -mouseStart starts rotation according to the mouse position"
14566 "\n : Option -mouseMove continues rotation with angle computed"
14567 "\n : from last and new mouse position."
14568 "\n : vrotate AX AY AZ [X Y Z]",
14569 __FILE__,VRotate,group);
14570 theCommands.Add("vzoom",
14571 "vzoom : vzoom coef",
14572 __FILE__,VZoom,group);
14573 theCommands.Add("vpan",
14574 "vpan : vpan dx dy",
14575 __FILE__,VPan,group);
14576 theCommands.Add("vcolorscale",
14577 "vcolorscale name [-noupdate|-update] [-demo]"
14578 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14579 "\n\t\t: [-font HeightFont=20]"
14580 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14581 "\n\t\t: [-smoothTransition {on|off}=off]"
14582 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14583 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14584 "\n\t\t: [-textpos {left|right|center|none}=right]"
14585 "\n\t\t: [-labelAtBorder {on|off}=on]"
14586 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14587 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14588 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14589 "\n\t\t: [-xy Left=0 Bottom=0]"
14590 "\n\t\t: [-uniform lightness hue_from hue_to]"
14591 "\n\t\t: -demo - displays a color scale with demonstratio values"
14592 "\n\t\t: -colors - set colors for all intervals"
14593 "\n\t\t: -color - set color for specific interval"
14594 "\n\t\t: -uniform - generate colors with the same lightness"
14595 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14596 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14597 "\n\t\t: at border means the value inbetween neighbor intervals,"
14598 "\n\t\t: at center means the center value within current interval"
14599 "\n\t\t: -labels - set labels for all intervals"
14600 "\n\t\t: -freeLabels - same as -labels but does not require"
14601 "\n\t\t: matching the number of intervals"
14602 "\n\t\t: -label - set label for specific interval"
14603 "\n\t\t: -title - set title"
14604 "\n\t\t: -reversed - setup smooth color transition between intervals"
14605 "\n\t\t: -smoothTransition - swap colorscale direction"
14606 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
14607 __FILE__, VColorScale, group);
14608 theCommands.Add("vgraduatedtrihedron",
14609 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14610 "\t[-namefont Name] [-valuesfont Name]\n"
14611 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14612 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14613 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14614 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14615 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14616 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14617 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14618 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14619 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
14620 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
14621 " - Displays or erases graduated trihedron"
14622 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14623 " - namefont - font of axes names. Default: Arial\n"
14624 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14625 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14626 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14627 " - valuesfont - font of axes values. Default: Arial\n"
14628 " - xcolor, ycolor, zcolor - color of axis and values\n"
14629 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14630 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
14631 __FILE__,VGraduatedTrihedron,group);
14632 theCommands.Add("vtile" ,
14633 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14634 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14635 "\n\t\t: -totalSize the size of virtual bigger viewport"
14636 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14637 "\n\t\t: -lowerLeft tile offset as lower left corner"
14638 "\n\t\t: -upperLeft tile offset as upper left corner",
14639 __FILE__, VTile, group);
14640 theCommands.Add("vzlayer",
14641 "vzlayer [layerId]"
14642 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
14643 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
14644 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
14645 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
14646 "\n\t\t: ZLayer list management:"
14647 "\n\t\t: -add add new z layer to viewer and print its id"
14648 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14649 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
14650 "\n\t\t: -delete delete z layer"
14651 "\n\t\t: -get print sequence of z layers"
14652 "\n\t\t: -settings print status of z layer settings"
14653 "\n\t\t: -disable disables given setting"
14654 "\n\t\t: -enable enables given setting",
14655 __FILE__,VZLayer,group);
14656 theCommands.Add("vlayerline",
14657 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14658 __FILE__,VLayerLine,group);
14659 theCommands.Add("vgrid",
14660 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14661 "\n\t\t: [-step X Y] [-size DX DY]"
14662 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
14663 __FILE__, VGrid, group);
14664 theCommands.Add ("vpriviledgedplane",
14665 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14666 "\n\t\t: Ox, Oy, Oz - plane origin"
14667 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14668 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14669 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14670 __FILE__, VPriviledgedPlane, group);
14671 theCommands.Add ("vconvert",
14672 "vconvert v [Mode={window|view}]"
14673 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14674 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14675 "\n\t\t: window - convert to window coordinates, pixels"
14676 "\n\t\t: view - convert to view projection plane"
14677 "\n\t\t: grid - convert to model coordinates, given on grid"
14678 "\n\t\t: ray - convert projection ray to model coordinates"
14679 "\n\t\t: - vconvert v window : convert view to window;"
14680 "\n\t\t: - vconvert v view : convert window to view;"
14681 "\n\t\t: - vconvert x y window : convert view to window;"
14682 "\n\t\t: - vconvert x y view : convert window to view;"
14683 "\n\t\t: - vconvert x y : convert window to model;"
14684 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14685 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14686 "\n\t\t: - vconvert x y z window : convert model to window;"
14687 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14688 "\n\t\t: Converts the given coordinates to window/view/model space.",
14689 __FILE__, VConvert, group);
14690 theCommands.Add ("vfps",
14691 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
14692 __FILE__, VFps, group);
14693 theCommands.Add ("vstereo",
14694 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
14695 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
14696 "\n\t\t: [-anaglyph Filter]"
14697 "\n\t\t: Control stereo output mode."
14698 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14699 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14700 "\n\t\t: Available modes for -mode:"
14701 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14702 "\n\t\t: requires driver support."
14703 "\n\t\t: Should be called BEFORE vinit!"
14704 "\n\t\t: anaglyph - Anaglyph glasses"
14705 "\n\t\t: rowInterlaced - row-interlaced display"
14706 "\n\t\t: columnInterlaced - column-interlaced display"
14707 "\n\t\t: chessBoard - chess-board output"
14708 "\n\t\t: sideBySide - horizontal pair"
14709 "\n\t\t: overUnder - vertical pair"
14710 "\n\t\t: openVR - OpenVR (HMD)"
14711 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14712 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14713 "\n\t\t: greenMagentaSimple",
14714 __FILE__, VStereo, group);
14715 theCommands.Add ("vmemgpu",
14716 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14717 " with f option returns free memory in bytes",
14718 __FILE__, VMemGpu, group);
14719 theCommands.Add ("vreadpixel",
14720 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
14721 " : Read pixel value for active view",
14722 __FILE__, VReadPixel, group);
14723 theCommands.Add("diffimage",
14724 "diffimage imageFile1 imageFile2 [diffImageFile]"
14725 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14726 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14727 "\n\t\t: Compare two images by content and generate difference image."
14728 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14729 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
14730 __FILE__, VDiffImage, group);
14731 theCommands.Add ("vselect",
14732 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-replaceextra|-xor|-add|-remove]\n"
14733 "- emulates different types of selection:\n"
14734 "- 1) single click selection\n"
14735 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14736 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
14737 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14738 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14739 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14740 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
14741 "- 5) selection scheme replace, replaceextra, xor, add or remove (replace by default)",
14742 __FILE__, VSelect, group);
14743 theCommands.Add ("vmoveto",
14744 "vmoveto [x y] [-reset]"
14745 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14746 "\n\t\t: -reset resets current highlighting",
14747 __FILE__, VMoveTo, group);
14748 theCommands.Add ("vselaxis",
14749 "vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14750 "\n\t\t: Provides intersection by given axis and print result intersection points"
14751 "\n\t\t: -onlyTop switches On/Off mode to find only top point or all"
14752 "\n\t\t: -display Name displays intersecting axis and result intersection points for debug goals"
14753 "\n\t\t: -showNormal adds displaying of normal in intersection point or not",
14754 __FILE__, VSelectByAxis, group);
14755 theCommands.Add ("vviewparams",
14756 "vviewparams [-args] [-scale [s]]"
14757 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14758 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14759 "\n\t\t: Manage current view parameters or prints all"
14760 "\n\t\t: current values when called without argument."
14761 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14762 "\n\t\t: -eye [x y z] prints or sets eye location"
14763 "\n\t\t: -at [x y z] prints or sets center of look"
14764 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14765 "\n\t\t: -proj [x y z] prints or sets direction of look"
14766 "\n\t\t: -center x y sets location of center of the screen in pixels"
14767 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14768 "\n\t\t: or changes the size of its maximum dimension"
14769 "\n\t\t: -args prints vviewparams arguments for restoring current view",
14770 __FILE__, VViewParams, group);
14772 theCommands.Add("v2dmode",
14773 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14774 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14775 "\n\t\t: mode - switches On/Off rotation mode"
14776 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14777 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14778 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14779 "\n\t\t: View camera position might be changed only by commands.",
14780 __FILE__, V2DMode, group);
14782 theCommands.Add("vanimation", "Alias for vanim",
14783 __FILE__, VAnimation, group);
14785 theCommands.Add("vanim",
14786 "List existing animations:"
14788 "\n\t\t: Animation playback:"
14789 "\n\t\t: vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]]"
14790 "\n\t\t: [-speed Coeff] [-freeLook] [-noPauseOnClick] [-lockLoop]"
14791 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14792 "\n\t\t: -freeLook skip camera animations"
14793 "\n\t\t: -noPauseOnClick do not pause animation on mouse click"
14794 "\n\t\t: -lockLoop disable any interactions"
14796 "\n\t\t: Animation definition:"
14797 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14798 "\n\t\t: [start TimeSec] [duration TimeSec]"
14800 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14801 "\n\t\t: specifies nested animations."
14802 "\n\t\t: There is no syntax to explicitly add new animation,"
14803 "\n\t\t: and all non-existing animations within the name will be"
14804 "\n\t\t: implicitly created on first use (including parents)."
14806 "\n\t\t: Each animation might define the SINGLE action (see below),"
14807 "\n\t\t: like camera transition, object transformation or custom callback."
14808 "\n\t\t: Child animations can be used for defining concurrent actions."
14810 "\n\t\t: Camera animation:"
14811 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14812 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14813 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14814 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14815 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14816 "\n\t\t: -atX camera Center positions pair"
14817 "\n\t\t: -upX camera Up directions pair"
14818 "\n\t\t: -scaleX camera Scale factors pair"
14819 "\n\t\t: Object animation:"
14820 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14821 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14822 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14823 "\n\t\t: -locX object Location points pair (translation)"
14824 "\n\t\t: -rotX object Orientations pair (quaternions)"
14825 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14826 "\n\t\t: Custom callback:"
14827 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14828 "\n\t\t: %Pts overall animation presentation timestamp"
14829 "\n\t\t: %LocalPts local animation timestamp"
14830 "\n\t\t: %Normalized local animation normalized value in range 0..1"
14832 "\n\t\t: Video recording:"
14833 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14834 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14835 "\n\t\t: [-crf Value] [-preset Preset]"
14836 "\n\t\t: -fps video framerate"
14837 "\n\t\t: -format file format, container (matroska, etc.)"
14838 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14839 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14840 "\n\t\t: -crf constant rate factor (specific to codec)"
14841 "\n\t\t: -preset codec parameters preset (specific to codec)",
14842 __FILE__, VAnimation, group);
14844 theCommands.Add("vchangeselected",
14845 "vchangeselected shape"
14846 "- adds to shape to selection or remove one from it",
14847 __FILE__, VChangeSelected, group);
14848 theCommands.Add ("vnbselected",
14850 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
14851 theCommands.Add ("vcamera",
14852 "vcamera [PrsName] [-ortho] [-projtype]"
14854 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14855 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14856 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14857 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
14858 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14859 "\n\t\t: [-xrPose base|head=base]"
14860 "\n\t\t: Manages camera parameters."
14861 "\n\t\t: Displays frustum when presentation name PrsName is specified."
14862 "\n\t\t: Prints current value when option called without argument."
14863 "\n\t\t: Orthographic camera:"
14864 "\n\t\t: -ortho activate orthographic projection"
14865 "\n\t\t: Perspective camera:"
14866 "\n\t\t: -persp activate perspective projection (mono)"
14867 "\n\t\t: -fovy field of view in y axis, in degrees"
14868 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
14869 "\n\t\t: -distance distance of eye from camera center"
14870 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
14871 "\n\t\t: Stereoscopic camera:"
14872 "\n\t\t: -stereo perspective projection (stereo)"
14873 "\n\t\t: -leftEye perspective projection (left eye)"
14874 "\n\t\t: -rightEye perspective projection (right eye)"
14875 "\n\t\t: -iod intraocular distance value"
14876 "\n\t\t: -iodType distance type, absolute or relative"
14877 "\n\t\t: -zfocus stereographic focus value"
14878 "\n\t\t: -zfocusType focus type, absolute or relative",
14879 __FILE__, VCamera, group);
14880 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
14881 "- vautozfit [on={1|0}] [scale]\n"
14882 " Prints or changes parameters of automatic z-fit mode:\n"
14883 " \"on\" - turns automatic z-fit on or off\n"
14884 " \"scale\" - specifies factor to scale computed z range.\n",
14885 __FILE__, VAutoZFit, group);
14886 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14887 " vzrange - without parameters shows current values\n"
14888 " vzrange [znear] [zfar] - applies provided values to view",
14889 __FILE__,VZRange, group);
14890 theCommands.Add("vsetviewsize",
14891 "vsetviewsize size",
14892 __FILE__,VSetViewSize,group);
14893 theCommands.Add("vmoveview",
14894 "vmoveview Dx Dy Dz [Start = 1|0]",
14895 __FILE__,VMoveView,group);
14896 theCommands.Add("vtranslateview",
14897 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14898 __FILE__,VTranslateView,group);
14899 theCommands.Add("vturnview",
14900 "vturnview Ax Ay Az [Start = 1|0]",
14901 __FILE__,VTurnView,group);
14902 theCommands.Add("vtextureenv",
14903 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14904 "or user-defined file and optionally applying texture mapping parameters\n"
14906 " vtextureenv off - disables environment mapping\n"
14907 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14908 " std_texture = (0..7)\n"
14909 " rep = {clamp|repeat}\n"
14910 " mod = {decal|modulate}\n"
14911 " flt = {nearest|bilinear|trilinear}\n"
14912 " ss, st - scale factors for s and t texture coordinates\n"
14913 " ts, tt - translation for s and t texture coordinates\n"
14914 " rot - texture rotation angle in degrees",
14915 __FILE__, VTextureEnv, group);
14916 theCommands.Add("vhlr",
14917 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14918 "\n\t\t: Hidden Line Removal algorithm."
14919 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14920 "\n\t\t: -algoType type of HLR algorithm.\n",
14921 __FILE__,VHLR,group);
14922 theCommands.Add("vhlrtype",
14923 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14924 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14925 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14926 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14927 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
14928 __FILE__,VHLRType,group);
14929 theCommands.Add("vclipplane",
14930 "vclipplane planeName [{0|1}]"
14931 "\n\t\t: [-equation1 A B C D]"
14932 "\n\t\t: [-equation2 A B C D]"
14933 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
14934 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
14935 "\n\t\t: [-maxPlanes]"
14936 "\n\t\t: [-capping {0|1}]"
14937 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
14938 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14939 "\n\t\t: [-texRotate Angle]"
14940 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14941 "\n\t\t: [-useObjShader {0|1}]"
14942 "\n\t\t: Clipping planes management:"
14943 "\n\t\t: -maxPlanes print plane limit for view"
14944 "\n\t\t: -delete delete plane with given name"
14945 "\n\t\t: {off|on|0|1} turn clipping on/off"
14946 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14947 "\n\t\t: applied to active View when list is omitted"
14948 "\n\t\t: -equation A B C D change plane equation"
14949 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14950 "\n\t\t: Capping options:"
14951 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14952 "\n\t\t: -color R G B set capping color"
14953 "\n\t\t: -transparency Value set capping transparency 0..1"
14954 "\n\t\t: -texName Texture set capping texture"
14955 "\n\t\t: -texScale SX SY set capping tex scale"
14956 "\n\t\t: -texOrigin TX TY set capping tex origin"
14957 "\n\t\t: -texRotate Angle set capping tex rotation"
14958 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14959 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14960 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14961 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14962 __FILE__, VClipPlane, group);
14963 theCommands.Add("vdefaults",
14964 "vdefaults [-absDefl value]"
14965 "\n\t\t: [-devCoeff value]"
14966 "\n\t\t: [-angDefl value]"
14967 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14968 , __FILE__, VDefaults, group);
14969 theCommands.Add("vlight",
14970 "vlight [lightName] [-noupdate]"
14971 "\n\t\t: [-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]"
14972 "\n\t\t: [-type {ambient|directional|spotlight|positional}] [-name value]"
14973 "\n\t\t: [-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]"
14974 "\n\t\t: [-headlight 0|1] [-castShadows 0|1]"
14975 "\n\t\t: [-range value] [-constAttenuation value] [-linearAttenuation value]"
14976 "\n\t\t: [-spotExponent value] [-spotAngle angleDeg]"
14977 "\n\t\t: [-smoothAngle value] [-smoothRadius value]"
14978 "\n\t\t: [-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]"
14979 "\n\t\t: [-arcSize Value]"
14980 "\n\t\t: Command manages light sources. Without arguments shows list of lights."
14981 "\n\t\t: Arguments affecting the list of defined/active lights:"
14982 "\n\t\t: -clear remove all light sources"
14983 "\n\t\t: -defaults defines two standard light sources"
14984 "\n\t\t: -reset resets light source parameters to default values"
14985 "\n\t\t: -type sets type of light source"
14986 "\n\t\t: -name sets new name to light source"
14987 "\n\t\t: -global assigns light source to all views (default state)"
14988 "\n\t\t: -local assigns light source to active view"
14989 "\n\t\t: -zlayer assigns light source to specified Z-Layer"
14990 "\n\t\t: Ambient light parameters:"
14991 "\n\t\t: -color sets (normalized) light color"
14992 "\n\t\t: -intensity sets intensity of light source, 1.0 by default;"
14993 "\n\t\t: affects also environment cubemap intensity"
14994 "\n\t\t: Point light parameters:"
14995 "\n\t\t: -color sets (normalized) light color"
14996 "\n\t\t: -intensity sets PBR intensity"
14997 "\n\t\t: -range sets clamping distance"
14998 "\n\t\t: -constAtten (obsolete) sets constant attenuation factor"
14999 "\n\t\t: -linearAtten (obsolete) sets linear attenuation factor"
15000 "\n\t\t: -smoothRadius sets PBR smoothing radius"
15001 "\n\t\t: Directional light parameters:"
15002 "\n\t\t: -color sets (normalized) light color"
15003 "\n\t\t: -intensity sets PBR intensity"
15004 "\n\t\t: -direction sets direction"
15005 "\n\t\t: -headlight sets headlight flag"
15006 "\n\t\t: -castShadows enables/disables shadow casting"
15007 "\n\t\t: -smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range"
15008 "\n\t\t: Spot light parameters:"
15009 "\n\t\t: -color sets (normalized) light color"
15010 "\n\t\t: -intensity sets PBR intensity"
15011 "\n\t\t: -range sets clamping distance"
15012 "\n\t\t: -position sets position"
15013 "\n\t\t: -direction sets direction"
15014 "\n\t\t: -spotAngle sets spotlight angle"
15015 "\n\t\t: -spotExp sets spotlight exponenta"
15016 "\n\t\t: -headlight sets headlight flag"
15017 "\n\t\t: -constAtten (obsolete) sets constant attenuation factor"
15018 "\n\t\t: -linearAtten (obsolete) sets linear attenuation factor"
15019 "\n\t\t: Light presentation parameters:"
15020 "\n\t\t: -display adds light source presentation"
15021 "\n\t\t: -showName shows/hides the name of light source; 1 by default"
15022 "\n\t\t: -showRange shows/hides the range of spot/positional light source; 1 by default"
15023 "\n\t\t: -prsZoomable makes light presentation zoomable/non-zoomable"
15024 "\n\t\t: -prsDraggable makes light presentation draggable/non-draggable"
15025 "\n\t\t: -prsSize sets light presentation size"
15026 "\n\t\t: -arcSize sets arc presentation size(in pixels) for rotation directional light source; 25 by default"
15027 "\n\t\t: Examples:"
15028 "\n\t\t: vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED"
15029 "\n\t\t: vlight redlight -delete",
15030 __FILE__, VLight, group);
15031 theCommands.Add("vpbrenv",
15032 "vpbrenv -clear|-generate"
15033 "\n\t\t: Clears or generates PBR environment map of active view."
15034 "\n\t\t: -clear clears PBR environment (fills by white color)"
15035 "\n\t\t: -generate generates PBR environment from current background cubemap",
15036 __FILE__, VPBREnvironment, group);
15037 theCommands.Add("vraytrace",
15039 "\n\t\t: Turns on/off ray-tracing renderer."
15040 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
15041 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
15042 __FILE__, VRenderParams, group);
15043 theCommands.Add("vrenderparams",
15044 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
15045 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
15046 "\n\t\t: Common parameters:"
15047 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
15048 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1]"
15049 "\n\t\t: [-resolution value=72] [-fontHinting {off|normal|light}=off]"
15050 "\n\t\t: [-fontAutoHinting {auto|force|disallow}=auto]"
15051 "\n\t\t: [-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]"
15052 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
15053 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
15054 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
15055 "\n\t\t: [-sync {default|views}] [-reset]"
15056 "\n\t\t: -raster Disables GPU ray-tracing."
15057 "\n\t\t: -shadingModel Controls shading model."
15058 "\n\t\t: -msaa Specifies number of samples for MSAA."
15059 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
15060 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
15061 "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens."
15062 "\n\t\t: -fontAutoHinting Manages font autohinting."
15063 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
15064 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
15065 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
15066 "\n\t\t: off unordered transparency (but opaque objects implicitly draw first);"
15067 "\n\t\t: weighted weight OIT is managed by depth weight factor 0.0..1.0;"
15068 "\n\t\t: peeling depth peeling OIT is managed by number of peeling layers."
15069 "\n\t\t: -shadows Enables/disables shadows rendering."
15070 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
15071 "\n\t\t: -shadowMapBias Shadow map bias."
15072 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
15073 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
15074 "\n\t\t: sets state to check structures culled previously."
15075 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
15076 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
15077 "\n\t\t: Diagnostic output (on-screen overlay):"
15078 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
15079 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
15080 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
15081 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
15082 "\n\t\t: -perfUpdateInterval Performance counters update interval."
15083 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
15084 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
15085 "\n\t\t: Ray-Tracing options:"
15086 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
15087 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
15088 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
15089 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
15090 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
15091 "\n\t\t: [-maxRad {value>0}=30.0]"
15092 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15093 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15094 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15095 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
15096 "\n\t\t: -reflections Enables/disables specular reflections."
15097 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15098 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15099 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15100 "\n\t\t: -env Enables/disables environment map background."
15101 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15102 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15103 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15104 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15105 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15106 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15107 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15108 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15109 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15110 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15111 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15112 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15113 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15114 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15115 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15116 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15117 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15118 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15119 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15120 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15121 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15122 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15123 "\n\t\t: Debug options:"
15124 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15125 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15126 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15127 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
15128 __FILE__, VRenderParams, group);
15129 theCommands.Add("vstatprofiler",
15130 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15131 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
15132 "\n |triangles|points|geomMem|textureMem|frameMem"
15133 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15134 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15136 "\n\t\t: Prints rendering statistics."
15137 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15138 "\n\t\t: else - print all performance counters set previously."
15139 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15140 __FILE__, VStatProfiler, group);
15141 theCommands.Add ("vplace",
15143 "\n\t\t: Places the point (in pixels) at the center of the window",
15144 __FILE__, VPlace, group);
15145 theCommands.Add("vxrotate",
15147 __FILE__,VXRotate,group);
15149 theCommands.Add("vmanipulator",
15150 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15151 "\n tool to create and manage AIS manipulators."
15153 "\n '-attach AISObject' attach manipulator to AISObject"
15154 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
15155 "\n '-adjustSize {0|1}' adjust size when attaching"
15156 "\n '-enableModes {0|1}' enable modes when attaching"
15157 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15158 "\n by default it is displayed in all views of the current viewer"
15159 "\n '-detach' detach manipulator"
15160 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15161 "\n '-transform mouse_x mouse_y' - invoke transformation"
15162 "\n '-stopTransform [abort]' - invoke stop of transformation"
15163 "\n '-move x y z' - move attached object"
15164 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15165 "\n '-scale factor' - scale attached object"
15166 "\n '-autoActivate {0|1}' - set activation on detection"
15167 "\n '-followTranslation {0|1}' - set following translation transform"
15168 "\n '-followRotation {0|1}' - set following rotation transform"
15169 "\n '-followDragging {0|1}' - set following dragging transform"
15170 "\n '-gap value' - set gap between sub-parts"
15171 "\n '-part axis mode {0|1}' - set visual part"
15172 "\n '-parts axis mode {0|1}' - set visual part"
15173 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15174 "\n '-size value' - set size of manipulator"
15175 "\n '-zoomable {0|1}' - set zoom persistence",
15176 __FILE__, VManipulator, group);
15178 theCommands.Add("vselprops",
15179 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
15180 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15181 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
15182 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15183 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
15184 "\n -pickStrategy {first|topmost} : defines picking strategy"
15185 "\n 'first' to pick first acceptable (default)"
15186 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
15187 "\n -pixTol value : sets up pixel tolerance"
15188 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15189 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15190 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
15191 "\n -dispMode dispMode : sets display mode for highlighting"
15192 "\n -layer ZLayer : sets ZLayer for highlighting"
15193 "\n -color {name|r g b} : sets highlight color"
15194 "\n -transp value : sets transparency coefficient for highlight"
15195 "\n -material material : sets highlight material"
15196 "\n -print : prints current state of all mentioned parameters",
15197 __FILE__, VSelectionProperties, group);
15198 theCommands.Add ("vhighlightselected",
15199 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15200 __FILE__, VSelectionProperties, group);
15202 theCommands.Add ("vseldump",
15203 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|entityType|surfNormal}=depth -pickedIndex Index=1"
15204 "\n\t\t: [-xrPose base|head=base]"
15205 "\n\t\t: Generate an image based on detection results:"
15206 "\n\t\t: depth normalized depth values"
15207 "\n\t\t: unnormDepth unnormalized depth values"
15208 "\n\t\t: object color of detected object"
15209 "\n\t\t: owner color of detected owner"
15210 "\n\t\t: selMode color of selection mode"
15211 "\n\t\t: entity color of detected entity"
15212 "\n\t\t: entityType color of detected entity type"
15213 "\n\t\t: surfNormal normal direction values",
15214 __FILE__, VDumpSelectionImage, group);
15216 theCommands.Add ("vviewcube",
15218 "\n\t\t: Displays interactive view manipualtion object."
15219 "\n\t\t: Options: "
15220 "\n\t\t: -reset reset geomertical and visual attributes'"
15221 "\n\t\t: -size Size adapted size of View Cube"
15222 "\n\t\t: -boxSize Size box size"
15223 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
15224 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15225 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15226 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15227 "\n\t\t: -color Color color of View Cube"
15228 "\n\t\t: -boxColor Color box color"
15229 "\n\t\t: -boxSideColor Color box sides color"
15230 "\n\t\t: -boxEdgeColor Color box edges color"
15231 "\n\t\t: -boxCornerColor Color box corner color"
15232 "\n\t\t: -textColor Color color of side text of view cube"
15233 "\n\t\t: -innerColor Color inner box color"
15234 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15235 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
15236 "\n\t\t: -xAxisTextColor Color color of X axis label"
15237 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15238 "\n\t\t: -zAxisTextColor Color color of Z axis label"
15239 "\n\t\t: -font Name font name"
15240 "\n\t\t: -fontHeight Value font height"
15241 "\n\t\t: -boxFacetExtension Value box facet extension"
15242 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15243 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15244 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15245 "\n\t\t: -axesPadding Value padding between box and arrows"
15246 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
15247 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15248 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15249 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
15250 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15251 "\n\t\t: -duration Seconds animation duration in seconds",
15252 __FILE__, VViewCube, group);
15254 theCommands.Add("vcolorconvert" ,
15255 "vcolorconvert {from|to} type C1 C2 C2"
15256 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15257 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15258 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15259 __FILE__,VColorConvert,group);
15260 theCommands.Add("vcolordiff" ,
15261 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15262 __FILE__,VColorDiff,group);
15263 theCommands.Add("vselbvhbuild",
15264 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15265 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15266 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15267 "\n\t\t: -wait waits for building all of BVH",
15268 __FILE__,VSelBvhBuild,group);