0032205: Visualization - implementing new selection scheme in context - replace extra
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands.cxx
CommitLineData
b311480e 1// Created on: 1998-09-01
2// Created by: Robert COUBLANC
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
b8db9379 17#if defined(_WIN32)
18 #include <windows.h>
19#endif
20
49582f9d 21#include <ViewerTest.hxx>
1beb58d7 22
1beb58d7 23#include <AIS_AnimationCamera.hxx>
24#include <AIS_AnimationObject.hxx>
30a1b24e 25#include <AIS_CameraFrustum.hxx>
7a324550 26#include <AIS_ColorScale.hxx>
49582f9d 27#include <AIS_InteractiveContext.hxx>
2daa5d95 28#include <AIS_LightSource.hxx>
0a768f56 29#include <AIS_ListOfInteractive.hxx>
30#include <AIS_ListIteratorOfListOfInteractive.hxx>
49582f9d 31#include <AIS_Manipulator.hxx>
2108d9a2 32#include <AIS_ViewCube.hxx>
49582f9d 33#include <AIS_Shape.hxx>
34#include <Aspect_DisplayConnection.hxx>
8a590580 35#include <Aspect_Grid.hxx>
49582f9d 36#include <Aspect_TypeOfLine.hxx>
37#include <Draw.hxx>
38#include <Draw_Appli.hxx>
39#include <Draw_Interpretor.hxx>
08f8a185 40#include <Draw_ProgressIndicator.hxx>
49582f9d 41#include <gp_Dir.hxx>
42#include <gp_Pln.hxx>
43#include <gp_Pnt.hxx>
61b0191c 44#include <Graphic3d_ArrayOfPolylines.hxx>
49582f9d 45#include <Graphic3d_AspectFillArea3d.hxx>
2bd4c032 46#include <Graphic3d_AspectMarker3d.hxx>
49582f9d 47#include <Graphic3d_ClipPlane.hxx>
077a220c 48#include <Graphic3d_CubeMapPacked.hxx>
49#include <Graphic3d_CubeMapSeparate.hxx>
a79f67f8 50#include <Graphic3d_GraduatedTrihedron.hxx>
b8db9379 51#include <Graphic3d_GraphicDriver.hxx>
52#include <Graphic3d_GraphicDriverFactory.hxx>
49582f9d 53#include <Graphic3d_NameOfTextureEnv.hxx>
54#include <Graphic3d_Texture2Dmanual.hxx>
269294d6 55#include <Graphic3d_TextureEnv.hxx>
56#include <Graphic3d_TextureParams.hxx>
57#include <Graphic3d_TypeOfTextureFilter.hxx>
49582f9d 58#include <Image_AlienPixMap.hxx>
59#include <Image_Diff.hxx>
60#include <Image_VideoRecorder.hxx>
b8db9379 61#include <Message.hxx>
7e785937 62#include <Message_ProgressScope.hxx>
63#include <Message_ProgressRange.hxx>
49582f9d 64#include <NCollection_DataMap.hxx>
18d715bd 65#include <NCollection_List.hxx>
d6fbb2ab 66#include <NCollection_LocalArray.hxx>
18d715bd 67#include <NCollection_Vector.hxx>
8693dfd0 68#include <OSD.hxx>
6a2fb7a1 69#include <OSD_Parallel.hxx>
208e6839 70#include <OSD_Timer.hxx>
4269bd1b 71#include <Prs3d_ShadingAspect.hxx>
0aeb8984 72#include <Prs3d_DatumAspect.hxx>
6262338c 73#include <Prs3d_Drawer.hxx>
61b0191c 74#include <Prs3d_LineAspect.hxx>
fd3f6bd0 75#include <Prs3d_Text.hxx>
76#include <Select3D_SensitivePrimitiveArray.hxx>
49582f9d 77#include <TColStd_HSequenceOfAsciiString.hxx>
78#include <TColStd_SequenceOfInteger.hxx>
79#include <TColStd_HSequenceOfReal.hxx>
80#include <TColgp_Array1OfPnt2d.hxx>
81#include <TColStd_MapOfAsciiString.hxx>
82#include <ViewerTest_AutoUpdater.hxx>
08b7a39f 83#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 84#include <ViewerTest_EventManager.hxx>
85#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
86#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
87#include <ViewerTest_CmdParser.hxx>
88#include <ViewerTest_V3dView.hxx>
89#include <V3d_AmbientLight.hxx>
90#include <V3d_DirectionalLight.hxx>
91#include <V3d_PositionalLight.hxx>
92#include <V3d_SpotLight.hxx>
0aeb8984 93#include <V3d_Trihedron.hxx>
1a96d253 94#include <V3d_Viewer.hxx>
7fd59977 95
293211ae 96#include <tcl.h>
97
692613e5 98#include <cstdlib>
25289ec1 99
58655684 100#if defined(_WIN32)
4fe56619 101 #include <WNT_WClass.hxx>
102 #include <WNT_Window.hxx>
d6fbb2ab 103 #include <WNT_HIDSpaceMouse.hxx>
4fe56619 104#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 105 #include <Cocoa_Window.hxx>
7fd59977 106#else
4fe56619 107 #include <Xw_Window.hxx>
108 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
109 #include <X11/Xutil.h>
110 #include <tk.h>
7fd59977 111#endif
112
7fd59977 113//==============================================================================
114// VIEWER GLOBAL VARIABLES
115//==============================================================================
116
117Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 118Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 119
120Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 121extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 122
58655684 123#if defined(_WIN32)
7fd59977 124static Handle(WNT_Window)& VT_GetWindow() {
125 static Handle(WNT_Window) WNTWin;
126 return WNTWin;
127}
4fe56619 128#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 129static Handle(Cocoa_Window)& VT_GetWindow()
130{
131 static Handle(Cocoa_Window) aWindow;
132 return aWindow;
133}
134extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 135extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
136
7fd59977 137#else
7fd59977 138static Handle(Xw_Window)& VT_GetWindow(){
139 static Handle(Xw_Window) XWWin;
140 return XWWin;
141}
7fd59977 142
143static void VProcessEvents(ClientData,int);
144#endif
145
18d715bd 146static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
147{
148 static Handle(Aspect_DisplayConnection) aDisplayConnection;
149 return aDisplayConnection;
150}
151
152static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
153{
154 GetDisplayConnection() = theDisplayConnection;
155}
156
18d715bd 157NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 158static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 159static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
18d715bd 160
7fd59977 161static void OSWindowSetup();
162
f42753ed 163static struct
164{
165 Quantity_Color FlatColor;
166 Quantity_Color GradientColor1;
167 Quantity_Color GradientColor2;
168 Aspect_GradientFillMethod FillMethod;
169} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
170
7fd59977 171//==============================================================================
172// EVENT GLOBAL VARIABLES
173//==============================================================================
174
1beb58d7 175Standard_Boolean TheIsAnimating = Standard_False;
7fd59977 176
293211ae 177namespace
178{
179
180 //! Checks if some set is a subset of other set
181 //! @tparam TheSuperSet the type of the superset
182 //! @tparam TheSubSet the type of the subset
183 //! @param theSuperSet the superset
184 //! @param theSubSet the subset to be checked
185 //! @return true if the superset includes subset, or false otherwise
186 template <typename TheSuperSet, typename TheSubSet>
187 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
188 {
189 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
190 }
191
192 //! A variable set of keys for command-line options.
193 //! It includes a set of mandatory keys and a set of all possible keys.
194 class CommandOptionKeyVariableSet
195 {
196 public:
197 //! Default constructor
198 CommandOptionKeyVariableSet()
199 {
200 }
201
202 //! Constructor
203 //! @param theMandatoryKeySet the set of the mandatory option keys
204 //! @param theAdditionalKeySet the set of additional options that could be omitted
205 CommandOptionKeyVariableSet (
206 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
207 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
208 : myMandatoryKeySet (theMandatoryKeySet)
209 {
210 std::set_union (theMandatoryKeySet.begin(),
211 theMandatoryKeySet.end(),
212 theAdditionalKeySet.begin(),
213 theAdditionalKeySet.end(),
214 std::inserter (myFullKeySet, myFullKeySet.begin()));
215 }
216
217 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
218 //! and be contained in the full key set)
219 //! @param theCheckedKeySet the set of option keys to be checked
220 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
221 {
222 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
223 }
224
225 private:
226 //! A set of mandatory command-line option keys
227 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
228
229 //! A full set of command-line option keys (includes mandatory and additional option keys)
230 ViewerTest_CommandOptionKeySet myFullKeySet;
231 };
232
233 //! Gets some code by its name
234 //! @tparam TheCode the type of a code to be found
235 //! @param theCodeNameMap the map from code names to codes
236 //! @param theCodeName the name of a code to be found
237 //! @param theCode the code to be found
238 //! @return true if a code is found, or false otherwise
239 template <typename TheCode>
240 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
241 TCollection_AsciiString theCodeName,
242 TheCode& theCode)
243 {
244 theCodeName.LowerCase();
245 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
246 theCodeName);
247 if (aCodeIterator == theCodeNameMap.end())
248 {
249 return false;
250 }
251 theCode = aCodeIterator->second;
252 return true;
253 }
254
255 // Defines possible commands related to background changing
256 enum BackgroundCommand
257 {
077a220c 258 BackgroundCommand_Main, //!< The main command that manages other commands through options
259 BackgroundCommand_Image, //!< Sets an image as a background
260 BackgroundCommand_ImageMode, //!< Changes a background image mode
261 BackgroundCommand_Gradient, //!< Sets a gradient as a background
262 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
263 BackgroundCommand_Color, //!< Fills background with a specified color
264 BackgroundCommand_Default //!< Sets the background default color or gradient
293211ae 265 };
266
267 //! Map from background command names to its codes
268 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
269
270 //! Creates a map from background command names to its codes
271 //! @return a map from background command names to its codes
272 static BackgroundCommandNameMap createBackgroundCommandNameMap()
273 {
274 BackgroundCommandNameMap aBackgroundCommandNameMap;
077a220c 275 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
276 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
277 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
278 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
279 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
280 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
281 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
293211ae 282 return aBackgroundCommandNameMap;
283 }
284
285 //! Gets a background command by its name
286 //! @param theBackgroundCommandName the name of the background command
287 //! @param theBackgroundCommand the background command to be found
288 //! @return true if a background command is found, or false otherwise
289 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
290 BackgroundCommand& theBackgroundCommand)
291 {
292 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
293 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
294 }
295
296 //! Map from background image fill method names to its codes
297 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
298
299 //! Creates a map from background image fill method names to its codes
300 //! @return a map from background image fill method names to its codes
301 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
302 {
303 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
304 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
305 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
306 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
307 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
308 return aBackgroundImageFillMethodNameMap;
309 }
310
311 //! Gets a background image fill method by its name
312 //! @param theBackgroundImageFillMethodName the name of the background image fill method
313 //! @param theBackgroundImageFillMethod the background image fill method to be found
314 //! @return true if a background image fill method is found, or false otherwise
315 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
316 Aspect_FillMethod& theBackgroundImageFillMethod)
317 {
318 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
319 createBackgroundImageFillMethodNameMap();
320 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
321 theBackgroundImageFillMethodName,
322 theBackgroundImageFillMethod);
323 }
324
325 //! Map from background gradient fill method names to its codes
326 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
327
328 //! Creates a map from background gradient fill method names to its codes
329 //! @return a map from background gradient fill method names to its codes
330 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
331 {
332 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
333 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
334 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
335 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
336 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
337 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
338 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
339 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
340 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
341 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
342 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
343 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
344 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
345 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
346 return aBackgroundGradientFillMethodNameMap;
347 }
348
349 //! Gets a gradient fill method by its name
350 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
351 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
352 //! @return true if a gradient fill method is found, or false otherwise
353 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
354 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
355 {
356 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
357 createBackgroundGradientFillMethodNameMap();
358 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
359 theBackgroundGradientFillMethodName,
360 theBackgroundGradientFillMethod);
361 }
362
363 //! Changes the background in accordance with passed command line options
364 class BackgroundChanger
365 {
366 public:
367 //! Constructor. Prepares the command parser
368 BackgroundChanger()
369 {
370 prepareCommandParser();
371 }
372
373 //! Processes the command line and changes the background
374 //! @param theDrawInterpretor the interpreter of the Draw Harness application
375 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
376 //! @param theCommandLineArguments the array of command line arguments
377 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
378 const Standard_Integer theNumberOfCommandLineArguments,
379 const char* const* const theCommandLineArguments)
380 {
381 const char* const aBackgroundCommandName = theCommandLineArguments[0];
382 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
383 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
384 {
385 return false;
386 }
387 addCommandDescription (aBackgroundCommand);
388 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
389 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
390 }
391
392 private:
393 //! The type of functions that are able to set gradient background filling
394 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
395 const Quantity_Color& /* theColor2 */,
396 const Aspect_GradientFillMethod /* theGradientMode */);
397
398 //! The type of functions that are able to fill a background with a specific color
399 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
400
401 //! the command parser used to parse command line options and its arguments
402 ViewerTest_CmdParser myCommandParser;
403
404 //! the option key for the command that sets an image as a background
405 ViewerTest_CommandOptionKey myImageOptionKey;
406
407 //! the option key for the command that sets a background image fill type
408 ViewerTest_CommandOptionKey myImageModeOptionKey;
409
410 //! the option key for the command that sets a gradient filling for the background
411 ViewerTest_CommandOptionKey myGradientOptionKey;
412
413 //! the option key for the command that sets a background gradient filling method
414 ViewerTest_CommandOptionKey myGradientModeOptionKey;
415
416 //! the option key for the command that fills background with a specific color
417 ViewerTest_CommandOptionKey myColorOptionKey;
418
419 //! the option key for the command that sets default background gradient or color
420 ViewerTest_CommandOptionKey myDefaultOptionKey;
421
077a220c 422 //! the option key for the command that sets an environment cubemap as a background
423 ViewerTest_CommandOptionKey myCubeMapOptionKey;
424
425 //! the option key for the command that defines order of tiles in one image packed cubemap
426 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
427
428 //! the option key for the command that sets inversion of Z axis for background cubemap
429 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
430
67312b79 431 //! the option key for the command that allows skip IBL map generation
432 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
433
293211ae 434 //! the variable set of options that are allowed for the old scenario (without any option passed)
435 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
436
077a220c 437 //! the variable set of options that are allowed for setting an environment cubemap as background
438 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
439
293211ae 440 //! the variable set of options that are allowed for setting an image as a background
441 CommandOptionKeyVariableSet myImageOptionVariableSet;
442
443 //! the variable set of options that are allowed for setting a background image fill type
444 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
445
446 //! the variable set of options that are allowed for setting a gradient filling for the background
447 CommandOptionKeyVariableSet myGradientOptionVariableSet;
448
449 //! the variable set of options that are allowed for setting a background gradient filling method
450 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
451
452 //! the variable set of options that are allowed for filling a background with a specific color
453 CommandOptionKeyVariableSet myColorOptionVariableSet;
454
455 //! the variable set of options that are allowed for setting a default background gradient
456 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
457
458 //! the variable set of options that are allowed for setting a default background color
459 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
460
461 //! the variable set of options that are allowed for printing help
462 CommandOptionKeyVariableSet myHelpOptionVariableSet;
463
464 //! Adds options to command parser
465 void addOptionsToCommandParser()
466 {
467 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
468 "filename of image used as background");
469 myImageModeOptionKey = myCommandParser.AddOption (
470 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
471 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
472 "sets background gradient starting and ending colors");
473 myGradientModeOptionKey =
474 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
475 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
476 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
477 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
478 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
077a220c 479
480 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
481 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
482 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
483 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
67312b79 484 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
293211ae 485 }
486
487 //! Creates option sets used to determine if a passed option set is valid or not
488 void createOptionSets()
489 {
490 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
491 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
492 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
493
077a220c 494 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
495 aCubeMapOptionSet.insert (myCubeMapOptionKey);
496 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
497 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
67312b79 498 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
077a220c 499 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
500 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
501
293211ae 502 ViewerTest_CommandOptionKeySet anImageOptionSet;
503 anImageOptionSet.insert (myImageOptionKey);
504 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
505 anImageModeOptionSet.insert (myImageModeOptionKey);
506 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
507 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
508
509 ViewerTest_CommandOptionKeySet aGradientOptionSet;
510 aGradientOptionSet.insert (myGradientOptionKey);
511 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
512 aGradientModeOptionSet.insert (myGradientModeOptionKey);
513 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
514 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
515
516 ViewerTest_CommandOptionKeySet aColorOptionSet;
517 aColorOptionSet.insert (myColorOptionKey);
518 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
519
520 aGradientOptionSet.insert (myDefaultOptionKey);
521 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
522 aColorOptionSet.insert (myDefaultOptionKey);
523 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
524
525 ViewerTest_CommandOptionKeySet aHelpOptionSet;
526 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
527 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
528 }
529
530 //! Prepares the command parser. Adds options and creates option sets used to determine
531 //! if a passed option set is valid or not
532 void prepareCommandParser()
533 {
534 addOptionsToCommandParser();
535 createOptionSets();
536 }
537
538 //! Adds a command description to the command parser
539 //! @param theBackgroundCommand the key of the command which description is added to the command parser
540 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
541 {
542 std::string aDescription;
543 bool isMainCommand = false;
544 switch (theBackgroundCommand)
545 {
546 case BackgroundCommand_Main:
547 aDescription = "Command: vbackground (changes background or some background settings)";
548 isMainCommand = true;
549 break;
550 case BackgroundCommand_Image:
551 aDescription = "Command: vsetbg (loads image as a background)";
552 break;
553 case BackgroundCommand_ImageMode:
554 aDescription = "Command: vsetbgmode (changes background fill type)";
555 break;
556 case BackgroundCommand_Gradient:
557 aDescription = "Command: vsetgradientbg (mounts gradient background)";
558 break;
559 case BackgroundCommand_GradientMode:
560 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
561 break;
562 case BackgroundCommand_Color:
563 aDescription = "Command: vsetcolorbg (sets color background)";
564 break;
565 case BackgroundCommand_Default:
566 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
567 break;
568 default:
569 return;
570 }
571 if (!isMainCommand)
572 {
573 aDescription += "\nThis command is obsolete. Use vbackground instead.";
574 }
575 myCommandParser.SetDescription (aDescription);
576 }
577
578 //! Check if a viewer is needed to be initialized
579 //! @param theBackgroundCommand the key of the command that changes the background
580 //! @return true if processing was successful, or false otherwise
581 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
582 {
583 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
584 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
585 const bool aViewerIsNotNeeded =
586 (theBackgroundCommand == BackgroundCommand_Default)
587 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
588 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
589 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
590 return !aViewerIsNotNeeded;
591 }
592
593 //! Check if a viewer is initialized
594 //! @param theBackgroundCommandName the name of the command that changes the background
595 //! @param theDrawInterpretor the interpreter of the Draw Harness application
596 //! @return true if a viewer is initialized, or false otherwise
597 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
598 Draw_Interpretor& theDrawInterpretor)
599 {
600 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
601 if (anAISContext.IsNull())
602 {
603 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
604 return false;
605 }
606 return true;
607 }
608
609 //! Processes command options
610 //! @param theBackgroundCommandName the name of the command that changes the background
611 //! @param theBackgroundCommand the key of the command that changes the background
612 //! @param theDrawInterpretor the interpreter of the Draw Harness application
613 //! @return true if processing was successful, or false otherwise
614 bool processCommandOptions (const char* const theBackgroundCommandName,
615 const BackgroundCommand theBackgroundCommand,
616 Draw_Interpretor& theDrawInterpretor) const
617 {
618 if (myCommandParser.HasNoOption())
619 {
620 return printHelp (theBackgroundCommandName, theDrawInterpretor);
621 }
622 if (checkViewerIsNeeded (theBackgroundCommand)
623 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
624 {
625 return false;
626 }
627 if (myCommandParser.HasOnlyUnnamedOption())
628 {
629 return processUnnamedOption (theBackgroundCommand);
630 }
631 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
632 }
633
634 //! Processes the unnamed option
635 //! @param theBackgroundCommand the key of the command that changes the background
636 //! @return true if processing was successful, or false otherwise
637 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
638 {
639 switch (theBackgroundCommand)
640 {
641 case BackgroundCommand_Main:
642 return false;
643 case BackgroundCommand_Image:
644 return processImageUnnamedOption();
645 case BackgroundCommand_ImageMode:
646 return processImageModeUnnamedOption();
647 case BackgroundCommand_Gradient:
648 return processGradientUnnamedOption();
649 case BackgroundCommand_GradientMode:
650 return processGradientModeUnnamedOption();
651 case BackgroundCommand_Color:
652 return processColorUnnamedOption();
653 case BackgroundCommand_Default:
654 return processDefaultUnnamedOption();
655 default:
656 return false;
657 }
658 }
659
660 //! Processes the image unnamed option
661 //! @return true if processing was successful, or false otherwise
662 bool processImageUnnamedOption() const
663 {
664 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
665 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
666 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
667 {
668 return false;
669 }
670 std::string anImageFileName;
671 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
672 {
673 return false;
674 }
675 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
676 if (aNumberOfImageUnnamedOptionArguments == 2)
677 {
678 std::string anImageModeString;
679 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
680 {
681 return false;
682 }
683 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
684 {
685 return false;
686 }
687 }
688 setImage (anImageFileName.c_str(), anImageMode);
689 return true;
690 }
691
692 //! Processes the image mode unnamed option
693 //! @return true if processing was successful, or false otherwise
694 bool processImageModeUnnamedOption() const
695 {
696 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
697 }
698
699 //! Processes the gradient unnamed option
700 //! @param theSetGradient the function used to set a background gradient filling
701 //! @return true if processing was successful, or false otherwise
702 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
703 {
704 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
705 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
706 if (aNumberOfGradientUnnamedOptionArguments < 2)
707 {
708 return false;
709 }
710
711 Standard_Integer anArgumentIndex = 0;
712 Quantity_Color aColor1;
713 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
714 {
715 return false;
716 }
717 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
718 {
719 return false;
720 }
721
722 Quantity_Color aColor2;
723 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
724 {
725 return false;
726 }
727 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
728 {
729 return false;
730 }
731
732 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
733 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
734 {
735 std::string anGradientModeString;
736
737 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
738 anArgumentIndex,
739 anGradientModeString))
740 {
741 return false;
742 }
743 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
744 {
745 return false;
746 }
747 ++anArgumentIndex;
748 }
749 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
750 {
751 return false;
752 }
753 theSetGradient (aColor1, aColor2, aGradientMode);
754 return true;
755 }
756
757 //! Processes the gradient mode unnamed option
758 //! @return true if processing was successful, or false otherwise
759 bool processGradientModeUnnamedOption() const
760 {
761 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
762 }
763
764 //! Processes the color unnamed option
765 //! @param theSetColor the function used to set a background color
766 //! @return true if processing was successful, or false otherwise
767 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
768 {
769 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
770 }
771
772 //! Processes the default back unnamed option
773 //! @return true if processing was successful, or false otherwise
774 bool processDefaultUnnamedOption() const
775 {
776 if (processGradientUnnamedOption (setDefaultGradient))
777 {
778 return true;
779 }
780 return processColorUnnamedOption (setDefaultColor);
781 }
782
783 //! Processes named options
784 //! @param theBackgroundCommandName the name of the command that changes the background
785 //! @param theBackgroundCommand the key of the command that changes the background
786 //! @param theDrawInterpretor the interpreter of the Draw Harness application
787 //! @return true if processing was successful, or false otherwise
788 bool processNamedOptions (const char* const theBackgroundCommandName,
789 const BackgroundCommand theBackgroundCommand,
790 Draw_Interpretor& theDrawInterpretor) const
791 {
792 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
793 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
077a220c 794 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
795 {
796 return processCubeMapOptionSet();
797 }
293211ae 798 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
799 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
800 {
801 return processImageOptionSet();
802 }
803 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
804 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
805 {
806 return processImageModeOptionSet();
807 }
808 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
809 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
810 {
811 return processGradientOptionSet();
812 }
813 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
814 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
815 {
816 return processGradientModeOptionSet();
817 }
818 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
819 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
820 {
821 return processColorOptionSet();
822 }
823 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
824 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
825 && (theBackgroundCommand == BackgroundCommand_Default)))
826 {
827 return processDefaultGradientOptionSet();
828 }
829 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
830 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
831 {
832 return processDefaultColorOptionSet();
833 }
834 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
835 {
836 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
837 }
838 return false;
839 }
840
077a220c 841 //! Process the cubemap option set in named and unnamed case.
842 //! @return true if processing was successful, or false otherwise
843 bool processCubeMapOptionSet() const
844 {
845 NCollection_Array1<TCollection_AsciiString> aFilePaths;
846
847 if (!processCubeMapOptions (aFilePaths))
848 {
849 return false;
850 }
851
852 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
853
854 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
855 {
856 if (!processCubeMapOrderOptions (anOrder))
857 {
858 return false;
859 }
860 }
861
862 bool aZIsInverted = false;
863 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
864 {
865 if (!processCubeMapInvertedZOptionSet())
866 {
867 return false;
868 }
869 aZIsInverted = true;
870 }
871
67312b79 872 bool aToGenPBREnv = true;
873 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
874 {
875 if (!processCubeMapDoNotGenPBREnvOptionSet())
876 {
877 return false;
878 }
879 aToGenPBREnv = false;
880 }
881
882 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
077a220c 883 return true;
884 }
885
293211ae 886 //! Processes the image option set
887 //! @return true if processing was successful, or false otherwise
888 bool processImageOptionSet() const
889 {
890 std::string anImageFileName;
891 if (!processImageOption (anImageFileName))
892 {
893 return false;
894 }
895 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
896 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
897 {
898 return false;
899 }
900 setImage (anImageFileName.c_str(), anImageMode);
901 return true;
902 }
903
904 //! Processes the image mode option set
905 //! @return true if processing was successful, or false otherwise
906 bool processImageModeOptionSet() const
907 {
908 return processImageModeOptionSet (myImageModeOptionKey);
909 }
910
911 //! Processes the image mode option set
912 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
913 //! @return true if processing was successful, or false otherwise
914 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
915 {
916 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
917 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
918 {
919 return false;
920 }
921 setImageMode (anImageMode);
922 return true;
923 }
924
925 //! Processes the gradient option set
926 //! @param theSetGradient the function used to set a background gradient filling
927 //! @return true if processing was successful, or false otherwise
928 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
929 {
930 Quantity_Color aColor1;
931 Quantity_Color aColor2;
932 if (!processGradientOption (aColor1, aColor2))
933 {
934 return false;
935 }
936 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
937 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
938 {
939 return false;
940 }
941 theSetGradient (aColor1, aColor2, aGradientMode);
942 return true;
943 }
944
945 //! Processes the gradient mode option set
946 //! @return true if processing was successful, or false otherwise
947 bool processGradientModeOptionSet() const
948 {
949 return processGradientModeOptionSet (myGradientModeOptionKey);
950 }
951
952 //! Processes the gradient mode option set
953 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
954 //! @return true if processing was successful, or false otherwise
955 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
956 {
957 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
958 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
959 {
960 return false;
961 }
962 setGradientMode (aGradientMode);
963 return true;
964 }
965
966 //! Processes the color option set
967 //! @param theSetColor the function used to set a background color
968 //! @return true if processing was successful, or false otherwise
969 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
970 {
971 return processColorOptionSet (myColorOptionKey, theSetColor);
972 }
973
974 //! Processes the default color option set
975 //! @return true if processing was successful, or false otherwise
976 bool processDefaultGradientOptionSet() const
977 {
978 return processGradientOptionSet (setDefaultGradient);
979 }
980
981 //! Processes the default gradient option set
982 //! @return true if processing was successful, or false otherwise
983 bool processDefaultColorOptionSet() const
984 {
985 return processColorOptionSet (setDefaultColor);
986 }
987
988 //! Processes the color option set
989 //! @param theColorOptionKey the key of the option that is interpreted as a color option
990 //! @param theSetColor the function used to set a background color
991 //! @return true if processing was successful, or false otherwise
992 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
993 SetColorFunction* const theSetColor = setColor) const
994 {
995 Quantity_Color aColor;
996 if (!processColorOption (theColorOptionKey, aColor))
997 {
998 return false;
999 }
1000 theSetColor (aColor);
1001 return true;
1002 }
1003
1004 //! Processes the help option set
1005 //! @param theBackgroundCommandName the name of the command that changes the background
1006 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1007 //! @return true if processing was successful, or false otherwise
1008 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1009 {
1010 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1011 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1012 if (aNumberOfHelpOptionArguments != 0)
1013 {
1014 return false;
1015 }
1016 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1017 }
1018
077a220c 1019 //! Processes the cubemap option
1020 //! @param theFilePaths the array of filenames of cubemap sides
1021 //! @return true if processing was successful, or false otherwise
1022 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1023 {
1024 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1025
1026 if (aNumberOfCubeMapOptionArguments != 1
1027 && aNumberOfCubeMapOptionArguments != 6)
1028 {
1029 return false;
1030 }
1031
1032 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1033
1034 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1035 {
1036 std::string aCubeMapFileName;
1037 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1038 {
1039 return false;
1040 }
1041 theFilePaths[i] = aCubeMapFileName.c_str();
1042 }
1043
1044 return true;
1045 }
1046
67312b79 1047 //! Processes the inverted z cubemap option
077a220c 1048 //! @return true if processing was successful, or false otherwise
1049 bool processCubeMapInvertedZOptionSet () const
1050 {
1051 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1052 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1053
1054 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1055 {
1056 return false;
1057 }
1058
1059 return true;
1060 }
1061
67312b79 1062 //! Processes the option allowing to skip IBM maps generation
1063 //! @return true if processing was successful, or false otherwise
1064 bool processCubeMapDoNotGenPBREnvOptionSet() const
1065 {
1066 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1067 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1068
1069 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1070 {
1071 return false;
1072 }
1073
1074 return true;
1075 }
1076
077a220c 1077 //! Processes the tiles order option
1078 //! @param theOrder the array of indexes if cubemap sides in tile grid
1079 //! @return true if processing was successful, or false otherwise
1080 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1081 {
1082 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1083 myCubeMapOrderOptionKey);
1084
1085 if (aNumberOfCubeMapOrderOptionArguments != 6)
1086 {
1087 return false;
1088 }
1089
1090
1091 for (unsigned int i = 0; i < 6; ++i)
1092 {
1093 std::string anOrderItem;
1094 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1095 {
1096 return false;
1097 }
1098
1099 theOrder.Set (Graphic3d_CubeMapSide (i),
1100 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1101 }
1102
1103 return theOrder.IsValid();
1104 }
1105
293211ae 1106 //! Processes the image option
1107 //! @param theImageFileName the filename of the image to be used as a background
1108 //! @return true if processing was successful, or false otherwise
1109 bool processImageOption (std::string& theImageFileName) const
1110 {
1111 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1112 myImageOptionKey);
1113 if (aNumberOfImageOptionArguments != 1)
1114 {
1115 return false;
1116 }
1117 std::string anImageFileName;
1118 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1119 {
1120 return false;
1121 }
1122 theImageFileName = anImageFileName;
1123 return true;
1124 }
1125
1126 //! Processes the image mode option
1127 //! @param theImageMode the fill type used for a background image
1128 //! @return true if processing was successful, or false otherwise
1129 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1130 {
1131 return processImageModeOption (myImageModeOptionKey, theImageMode);
1132 }
1133
1134 //! Processes the image mode option
1135 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1136 //! @param theImageMode the fill type used for a background image
1137 //! @return true if processing was successful, or false otherwise
1138 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1139 Aspect_FillMethod& theImageMode) const
1140 {
1141 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1142 }
1143
1144 //! Processes the gradient option
1145 //! @param theColor1 the gradient starting color
1146 //! @param theColor2 the gradient ending color
1147 //! @return true if processing was successful, or false otherwise
1148 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1149 {
1150 Standard_Integer anArgumentIndex = 0;
1151 Quantity_Color aColor1;
1152 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1153 {
1154 return false;
1155 }
1156 Quantity_Color aColor2;
1157 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1158 {
1159 return false;
1160 }
1161 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1162 myGradientOptionKey);
1163 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1164 {
1165 return false;
1166 }
1167 theColor1 = aColor1;
1168 theColor2 = aColor2;
1169 return true;
1170 }
1171
1172 //! Processes the gradient mode option
1173 //! @param theGradientMode the fill method used for a background gradient filling
1174 //! @return true if processing was successful, or false otherwise
1175 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1176 {
1177 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1178 }
1179
1180 //! Processes the gradient mode option
1181 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1182 //! @param theGradientMode the fill method used for a background gradient filling
1183 //! @return true if processing was successful, or false otherwise
1184 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1185 Aspect_GradientFillMethod& theGradientMode) const
1186 {
1187 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1188 }
1189
1190 //! Processes some mode option
1191 //! @tparam TheMode the type of a mode to be processed
1192 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1193 //! @param theMode a mode to be processed
1194 //! @return true if processing was successful, or false otherwise
1195 template <typename TheMode>
1196 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1197 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1198 TheMode& /* theMode */),
1199 TheMode& theMode) const
1200 {
1201 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1202 theModeOptionKey);
1203 if (aNumberOfModeOptionArguments != 1)
1204 {
1205 return false;
1206 }
1207 std::string aModeString;
1208 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1209 {
1210 return false;
1211 }
1212 TheMode aMode = TheMode();
1213 if (!theGetModeByName (aModeString.c_str(), aMode))
1214 {
1215 return false;
1216 }
1217 theMode = aMode;
1218 return true;
1219 }
1220
1221 //! Processes the color option
1222 //! @param theColor a color used for filling a background
1223 //! @return true if processing was successful, or false otherwise
1224 bool processColorOption (Quantity_Color& theColor) const
1225 {
1226 return processColorOption (myColorOptionKey, theColor);
1227 }
1228
1229 //! Processes the color option
1230 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1231 //! @param theColor a color used for filling a background
1232 //! @return true if processing was successful, or false otherwise
1233 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1234 {
1235 Standard_Integer anArgumentIndex = 0;
1236 Quantity_Color aColor;
1237 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1238 {
1239 return false;
1240 }
1241 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1242 theColorOptionKey);
1243 if (anArgumentIndex != aNumberOfColorOptionArguments)
1244 {
1245 return false;
1246 }
1247 theColor = aColor;
1248 return true;
1249 }
1250
1251 //! Prints helping message
1252 //! @param theBackgroundCommandName the name of the command that changes the background
1253 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1254 //! @return true if printing was successful, or false otherwise
1255 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1256 {
1257 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1258 }
1259
077a220c 1260 //! Sets the cubemap as a background
1261 //! @param theFileNames the array of filenames of packed or multifile cubemap
1262 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1263 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1264 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
67312b79 1265 bool theZIsInverted = false,
1266 bool theToGenPBREnv = true)
077a220c 1267 {
1268 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1269 Handle(Graphic3d_CubeMap) aCubeMap;
1270
1271 if (theFileNames.Size() == 1)
1272 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1273 else
1274 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1275
1276 aCubeMap->SetZInversion (theZIsInverted);
1277
1278 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1279 aCubeMap->GetParams()->SetRepeat(Standard_False);
1280 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1281
67312b79 1282 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
077a220c 1283 }
1284
293211ae 1285 //! Sets the image as a background
1286 //! @param theImageFileName the filename of the image to be used as a background
1287 //! @param theImageMode the fill type used for a background image
1288 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1289 {
1290 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1291 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1292 }
1293
1294 //! Sets the fill type used for a background image
1295 //! @param theImageMode the fill type used for a background image
1296 static void setImageMode (const Aspect_FillMethod theImageMode)
1297 {
1298 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1299 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1300 }
1301
1302 //! Sets the gradient filling for a background
1303 //! @param theColor1 the gradient starting color
1304 //! @param theColor2 the gradient ending color
1305 //! @param theGradientMode the fill method used for a background gradient filling
1306 static void setGradient (const Quantity_Color& theColor1,
1307 const Quantity_Color& theColor2,
1308 const Aspect_GradientFillMethod theGradientMode)
1309 {
1310 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1311 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1312 }
1313
1314 //! Sets the fill method used for a background gradient filling
1315 //! @param theGradientMode the fill method used for a background gradient filling
1316 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1317 {
1318 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1319 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1320 }
1321
1322 //! Sets the color used for filling a background
1323 //! @param theColor the color used for filling a background
1324 static void setColor (const Quantity_Color& theColor)
1325 {
1326 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1327 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1328 aCurrentView->SetBackgroundColor (theColor);
1329 aCurrentView->Update();
1330 }
1331
1332 //! Sets the gradient filling for a background in a default viewer
1333 //! @param theColor1 the gradient starting color
1334 //! @param theColor2 the gradient ending color
1335 //! @param theGradientMode the fill method used for a background gradient filling
1336 static void setDefaultGradient (const Quantity_Color& theColor1,
1337 const Quantity_Color& theColor2,
1338 const Aspect_GradientFillMethod theGradientMode)
1339 {
1340 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1341 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1342 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1343 setDefaultGradient();
1344 }
1345
1346 //! Sets the color used for filling a background in a default viewer
1347 //! @param theColor the color used for filling a background
1348 static void setDefaultColor (const Quantity_Color& theColor)
1349 {
1350 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1351 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1352 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1353 ViewerTest_DefaultBackground.FlatColor = theColor;
1354 setDefaultGradient();
1355 setDefaultColor();
1356 }
1357
1358 //! Sets the gradient filling for a background in a default viewer.
1359 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1360 static void setDefaultGradient()
1361 {
1362 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1363 anInteractiveContextIterator (ViewerTest_myContexts);
1364 anInteractiveContextIterator.More();
1365 anInteractiveContextIterator.Next())
1366 {
1367 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1368 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1369 ViewerTest_DefaultBackground.GradientColor2,
1370 ViewerTest_DefaultBackground.FillMethod);
1371 }
1372 }
1373
1374 //! Sets the color used for filling a background in a default viewer.
1375 //! The color value is taken from ViewerTest_DefaultBackground structure
1376 static void setDefaultColor()
1377 {
1378 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1379 anInteractiveContextIterator (ViewerTest_myContexts);
1380 anInteractiveContextIterator.More();
1381 anInteractiveContextIterator.Next())
1382 {
1383 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1384 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1385 }
1386 }
1387 };
1388
1389} // namespace
b12e1c7b 1390
7fd59977 1391//==============================================================================
1392
57c28b61 1393#ifdef _WIN32
7fd59977 1394static LRESULT WINAPI ViewerWindowProc(
1395 HWND hwnd,
1396 UINT uMsg,
1397 WPARAM wParam,
1398 LPARAM lParam );
1399static LRESULT WINAPI AdvViewerWindowProc(
1400 HWND hwnd,
1401 UINT uMsg,
1402 WPARAM wParam,
1403 LPARAM lParam );
1404#endif
1405
1406
1407//==============================================================================
1408//function : WClass
1409//purpose :
1410//==============================================================================
1411
1bd04b5a 1412const Handle(WNT_WClass)& ViewerTest::WClass()
7fd59977 1413{
1bd04b5a 1414 static Handle(WNT_WClass) theWClass;
58655684 1415#if defined(_WIN32)
4fe56619 1416 if (theWClass.IsNull())
1417 {
7c65581d 1418 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1419 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1420 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1421 }
1422#endif
1423 return theWClass;
1424}
1425
18d715bd 1426//==============================================================================
1427//function : CreateName
1428//purpose : Create numerical name for new object in theMap
1429//==============================================================================
1430template <typename ObjectType>
1431TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1432 const TCollection_AsciiString& theDefaultString)
1433{
1434 if (theObjectMap.IsEmpty())
1435 return theDefaultString + TCollection_AsciiString(1);
1436
1437 Standard_Integer aNextKey = 1;
1438 Standard_Boolean isFound = Standard_False;
1439 while (!isFound)
1440 {
1441 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1442 // Look for objects with default names
1443 if (theObjectMap.IsBound1(aStringKey))
1444 {
1445 aNextKey++;
1446 }
1447 else
1448 isFound = Standard_True;
1449 }
1450
1451 return theDefaultString + TCollection_AsciiString(aNextKey);
1452}
1453
1454//==============================================================================
1455//structure : ViewerTest_Names
1456//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1457//==============================================================================
1458struct ViewerTest_Names
1459{
1460private:
1461 TCollection_AsciiString myDriverName;
1462 TCollection_AsciiString myViewerName;
1463 TCollection_AsciiString myViewName;
1464
1465public:
1466
1467 const TCollection_AsciiString& GetDriverName () const
1468 {
1469 return myDriverName;
1470 }
1471 void SetDriverName (const TCollection_AsciiString& theDriverName)
1472 {
1473 myDriverName = theDriverName;
1474 }
1475 const TCollection_AsciiString& GetViewerName () const
1476 {
1477 return myViewerName;
1478 }
1479 void SetViewerName (const TCollection_AsciiString& theViewerName)
1480 {
1481 myViewerName = theViewerName;
1482 }
1483 const TCollection_AsciiString& GetViewName () const
1484 {
1485 return myViewName;
1486 }
1487 void SetViewName (const TCollection_AsciiString& theViewName)
1488 {
1489 myViewName = theViewName;
1490 }
1491
1492 //===========================================================================
1493 //function : Constructor for ViewerTest_Names
1494 //purpose : Get view, viewer, driver names from custom string
1495 //===========================================================================
1496
1497 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1498 {
1499 TCollection_AsciiString aName(theInputString);
1500 if (theInputString.IsEmpty())
1501 {
1502 // Get current configuration
1503 if (ViewerTest_myDrivers.IsEmpty())
1504 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1505 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1506 else
1507 myDriverName = ViewerTest_myDrivers.Find2
1508 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1509
1510 if(ViewerTest_myContexts.IsEmpty())
1511 {
1512 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1513 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1514 }
1515 else
c48e2889 1516 {
18d715bd 1517 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1518 }
18d715bd 1519
c48e2889 1520 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1521 }
1522 else
1523 {
1524 // There is at least view name
1525 Standard_Integer aParserNumber = 0;
1526 for (Standard_Integer i = 0; i < 3; ++i)
1527 {
1528 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1529 if(aParserPos != -1)
1530 {
1531 aParserNumber++;
1532 aName.Split(aParserPos-1);
1533 }
1534 else
1535 break;
1536 }
1537 if (aParserNumber == 0)
1538 {
1539 // Only view name
1540 if (!ViewerTest::GetAISContext().IsNull())
1541 {
1542 myDriverName = ViewerTest_myDrivers.Find2
1543 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1544 myViewerName = ViewerTest_myContexts.Find2
1545 (ViewerTest::GetAISContext());
1546 }
1547 else
1548 {
1549 // There is no opened contexts here, need to create names for viewer and driver
1550 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1551 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1552
1553 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1554 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1555 }
1556 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1557 }
1558 else if (aParserNumber == 1)
1559 {
1560 // Here is viewerName/viewName
1561 if (!ViewerTest::GetAISContext().IsNull())
1562 myDriverName = ViewerTest_myDrivers.Find2
1563 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1564 else
1565 {
1566 // There is no opened contexts here, need to create name for driver
1567 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1568 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1569 }
1570 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1571
1572 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1573 }
1574 else
1575 {
1576 //Here is driverName/viewerName/viewName
1577 myDriverName = TCollection_AsciiString(aName);
1578
1579 TCollection_AsciiString aViewerName(theInputString);
1580 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1581 myViewerName = TCollection_AsciiString(aViewerName);
1582
1583 myViewName = TCollection_AsciiString(theInputString);
1584 }
1585 }
1586 }
1587};
1588
1589//==============================================================================
1590//function : FindContextByView
1591//purpose : Find AIS_InteractiveContext by View
1592//==============================================================================
1593
1594Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1595{
1596 Handle(AIS_InteractiveContext) anAISContext;
1597
1598 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1599 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1600 {
1601 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1602 return anIter.Key2();
1603 }
1604 return anAISContext;
1605}
1606
18d715bd 1607//==============================================================================
1608//function : IsWindowOverlapped
1609//purpose : Check if theWindow overlapp another view
1610//==============================================================================
1611
1612Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1613 const Standard_Integer thePxTop,
1614 const Standard_Integer thePxRight,
1615 const Standard_Integer thePxBottom,
1616 TCollection_AsciiString& theViewId)
1617{
1618 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1619 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1620 {
1621 Standard_Integer aTop = 0,
1622 aLeft = 0,
1623 aRight = 0,
1624 aBottom = 0;
1625 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1626 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1627 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1628 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1629 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1630 {
1631 theViewId = anIter.Key1();
1632 return Standard_True;
1633 }
1634 }
1635 return Standard_False;
1636}
1637
1638// Workaround: to create and delete non-orthographic views outside ViewerTest
1639void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1640{
1641 ViewerTest_myViews.UnBind1 (theName);
1642}
1643
1644void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1645 const Handle(V3d_View)& theView)
1646{
1647 ViewerTest_myViews.Bind (theName, theView);
1648}
1649
1650TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1651{
1652 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1653}
8693dfd0 1654
7fd59977 1655//==============================================================================
1656//function : ViewerInit
1657//purpose : Create the window viewer and initialize all the global variable
1658//==============================================================================
1659
18d715bd 1660TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1661 const Standard_Integer thePxTop,
1662 const Standard_Integer thePxWidth,
1663 const Standard_Integer thePxHeight,
9e04ccdc 1664 const TCollection_AsciiString& theViewName,
1665 const TCollection_AsciiString& theDisplayName,
72ed0644 1666 const Handle(V3d_View)& theViewToClone,
1667 const Standard_Boolean theIsVirtual)
7fd59977 1668{
8c3c9904 1669 // Default position and dimension of the viewer window.
4fe56619 1670 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1671 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1672 // The position corresponds to the window's client area, thus some
8c3c9904 1673 // gap is added for window frame to be visible.
1674 Standard_Integer aPxLeft = 20;
1675 Standard_Integer aPxTop = 40;
7fd59977 1676 Standard_Integer aPxWidth = 409;
1677 Standard_Integer aPxHeight = 409;
18d715bd 1678 Standard_Boolean toCreateViewer = Standard_False;
72ed0644 1679 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
9e04ccdc 1680 if (!theViewToClone.IsNull())
1681 {
1682 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1683 }
18d715bd 1684
b8db9379 1685 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1686 if (aFactory.IsNull())
1687 {
1688 Draw::GetInterpretor().Eval ("pload OPENGL");
1689 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1690 if (aFactory.IsNull())
1691 {
b8ef513c 1692 Draw::GetInterpretor().Eval ("pload GLES");
1693 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1694 if (aFactory.IsNull())
1695 {
1696 throw Standard_ProgramError("Error: no graphic driver factory found");
1697 }
b8db9379 1698 }
1699 }
1700
1701 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
18d715bd 1702 ViewerTest_Names aViewNames(theViewName);
1703 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
1704 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1705
1706 if (thePxLeft != 0)
1707 aPxLeft = thePxLeft;
1708 if (thePxTop != 0)
1709 aPxTop = thePxTop;
1710 if (thePxWidth != 0)
1711 aPxWidth = thePxWidth;
1712 if (thePxHeight != 0)
7fd59977 1713 aPxHeight = thePxHeight;
4269bd1b 1714
18d715bd 1715 // Get graphic driver (create it or get from another view)
8693dfd0 1716 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1717 if (isNewDriver)
18d715bd 1718 {
1719 // Get connection string
58655684 1720 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 1721 if (!theDisplayName.IsEmpty())
1722 {
1723 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1724 }
18d715bd 1725 else
8693dfd0 1726 {
1727 ::Display* aDispX = NULL;
1728 // create dedicated display connection instead of reusing Tk connection
1729 // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
1730 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1731 Tcl_Interp* aTclInterp = aCommands.Interp();
1732 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1733 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1734 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1735 }
18d715bd 1736 #else
498ce76b 1737 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1738 SetDisplayConnection (new Aspect_DisplayConnection ());
1739 #endif
14cb22a1 1740
b8db9379 1741 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
72ed0644 1742 if (isVirtual)
14cb22a1 1743 {
1744 // don't waste the time waiting for VSync when window is not displayed on the screen
b8db9379 1745 aGraphicDriver->SetVerticalSync (false);
14cb22a1 1746 }
14cb22a1 1747
18d715bd 1748 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1749 toCreateViewer = Standard_True;
1750 }
1751 else
1752 {
b8db9379 1753 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
7fd59977 1754 }
1755
18d715bd 1756 //Dispose the window if input parameters are default
1757 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1758 {
18d715bd 1759 Standard_Integer aTop = 0,
1760 aLeft = 0,
1761 aRight = 0,
1762 aBottom = 0,
1763 aScreenWidth = 0,
1764 aScreenHeight = 0;
1765
1766 // Get screen resolution
1767#if defined(_WIN32) || defined(__WIN32__)
1768 RECT aWindowSize;
1769 GetClientRect(GetDesktopWindow(), &aWindowSize);
1770 aScreenHeight = aWindowSize.bottom;
1771 aScreenWidth = aWindowSize.right;
1772#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1773 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1774#else
1775 Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
1776 aScreenWidth = WidthOfScreen(aScreen);
1777 aScreenHeight = HeightOfScreen(aScreen);
1778#endif
1779
1780 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1781
1782 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1783 {
18d715bd 1784 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1785
1786 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1787 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1788 {
1789 if (aBottom + aPxHeight + 40 > aScreenHeight)
1790 {
1791 aPxLeft = 20;
1792 aPxTop = 40;
1793 break;
1794 }
1795 aPxLeft = 20;
1796 aPxTop = aBottom + 40;
1797 }
1798 else
1799 aPxLeft = aRight + 20;
dc3fe572 1800 }
18d715bd 1801 }
1802
1803 // Get viewer name
1804 TCollection_AsciiString aTitle("3D View - ");
1805 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1806
1807 // Change name of current active window
49582f9d 1808 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
18d715bd 1809 {
49582f9d 1810 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
18d715bd 1811 }
1812
1813 // Create viewer
eb4320f2 1814 Handle(V3d_Viewer) a3DViewer;
18d715bd 1815 // If it's the single view, we first look for empty context
1816 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1817 {
1818 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1819 anIter(ViewerTest_myContexts);
1820 if (anIter.More())
1821 ViewerTest::SetAISContext (anIter.Value());
1822 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1823 }
1824 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1825 {
1826 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1827 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1828 }
eb4320f2 1829 else if (a3DViewer.IsNull())
18d715bd 1830 {
1831 toCreateViewer = Standard_True;
6a24c6de 1832 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1833 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1834 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1835 ViewerTest_DefaultBackground.GradientColor2,
1836 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1837 }
1838
1839 // AIS context setup
1840 if (ViewerTest::GetAISContext().IsNull() ||
1841 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1842 {
e79a94b9 1843 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1844 ViewerTest::SetAISContext (aContext);
1845 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1846 }
1847 else
e79a94b9 1848 {
18d715bd 1849 ViewerTest::ResetEventManager();
e79a94b9 1850 }
18d715bd 1851
1852 // Create window
e79a94b9 1853#if defined(_WIN32)
1bd04b5a 1854 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
72ed0644 1855 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1856 aPxLeft, aPxTop,
1857 aPxWidth, aPxHeight,
1858 Quantity_NOC_BLACK);
d6fbb2ab 1859 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
4fe56619 1860#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e79a94b9 1861 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1862 aPxLeft, aPxTop,
1863 aPxWidth, aPxHeight);
1864 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
7fd59977 1865#else
e79a94b9 1866 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1867 aTitle.ToCString(),
1868 aPxLeft, aPxTop,
1869 aPxWidth, aPxHeight);
7fd59977 1870#endif
72ed0644 1871 VT_GetWindow()->SetVirtual (isVirtual);
7fd59977 1872
d09dda09 1873 // View setup
9e04ccdc 1874 Handle(V3d_View) aView;
1875 if (!theViewToClone.IsNull())
1876 {
2e93433e 1877 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1878 }
1879 else
1880 {
2e93433e 1881 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1882 }
1883
d09dda09 1884 aView->SetWindow (VT_GetWindow());
c3282ec1 1885 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1886
18d715bd 1887 ViewerTest::CurrentView(aView);
1888 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1889
18d715bd 1890 // Setup for X11 or NT
1891 OSWindowSetup();
7fd59977 1892
18d715bd 1893 // Set parameters for V3d_View and V3d_Viewer
1894 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1895 aV3dView->SetComputedMode(Standard_False);
7fd59977 1896
18d715bd 1897 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1898 if (toCreateViewer)
1899 {
7fd59977 1900 a3DViewer->SetDefaultLights();
1901 a3DViewer->SetLightOn();
18d715bd 1902 }
7fd59977 1903
8693dfd0 1904#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1905 if (isNewDriver)
1906 {
1907 ::Display* aDispX = GetDisplayConnection()->GetDisplay();
1908 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1909 }
1910#endif
7fd59977 1911
7fd59977 1912 VT_GetWindow()->Map();
4269bd1b 1913
18d715bd 1914 // Set the handle of created view in the event manager
1915 ViewerTest::ResetEventManager();
1916
4fe56619 1917 ViewerTest::CurrentView()->Redraw();
18d715bd 1918
1919 aView.Nullify();
1920 a3DViewer.Nullify();
18d715bd 1921
1922 return aViewNames.GetViewName();
1923}
1924
4269bd1b 1925//==============================================================================
1926//function : RedrawAllViews
1927//purpose : Redraw all created views
1928//==============================================================================
1929void ViewerTest::RedrawAllViews()
1930{
1931 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1932 for (; aViewIt.More(); aViewIt.Next())
1933 {
1934 const Handle(V3d_View)& aView = aViewIt.Key2();
1935 aView->Redraw();
1936 }
1937}
1938
b8db9379 1939//==============================================================================
1940//function : VDriver
1941//purpose :
1942//==============================================================================
1943static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1944{
1945 if (theArgsNb == 1)
1946 {
1947 theDi << "Registered: ";
1948 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
1949 aFactoryIter.More(); aFactoryIter.Next())
1950 {
1951 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
1952 theDi << aFactory->Name() << " ";
1953 }
1954
1955 theDi << "\n";
1956 theDi << "Default: ";
1957 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
1958 {
1959 theDi << aFactory->Name();
1960 }
1961 else
1962 {
1963 theDi << "NONE";
1964 }
1965 return 0;
1966 }
1967
1968 TCollection_AsciiString aNewActive;
1969 bool toLoad = false;
1970 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
1971 {
1972 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1973 anArgCase.LowerCase();
1974 if (anArgCase == "-list")
1975 {
1976 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
1977 aFactoryIter.More(); aFactoryIter.Next())
1978 {
1979 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
1980 theDi << aFactory->Name() << " ";
1981 }
1982 }
1983 else if ((anArgCase == "-default"
1984 || anArgCase == "-load")
1985 && aNewActive.IsEmpty())
1986 {
1987 toLoad = (anArgCase == "-load");
1988 if (anArgIter + 1 < theArgsNb)
1989 {
1990 aNewActive = theArgVec[++anArgIter];
1991 }
1992 else if (toLoad)
1993 {
1994 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
1995 return 1;
1996 }
1997 else
1998 {
1999 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2000 {
2001 theDi << aFactory->Name();
2002 }
2003 else
2004 {
2005 theDi << "NONE";
2006 }
2007 }
2008 }
2009 else if (aNewActive.IsEmpty())
2010 {
2011 aNewActive = theArgVec[anArgIter];
2012 }
2013 else
2014 {
2015 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
2016 return 1;
2017 }
2018 }
2019
2020 if (!aNewActive.IsEmpty())
2021 {
2022 const TCollection_AsciiString aNameCopy = aNewActive;
2023 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
2024 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
2025 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
2026 {
2027 aNewActive = "tkopengl";
2028 }
b8ef513c 2029 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
2030 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
2031 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
2032 {
2033 aNewActive = "tkopengles";
2034 }
b8db9379 2035 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
2036 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
2037 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
2038 {
2039 aNewActive = "tkd3dhost";
2040 }
2041
2042 if (toLoad)
2043 {
2044 if (aNewActive == "tkopengl")
2045 {
2046 Draw::GetInterpretor().Eval ("pload OPENGL");
2047 }
b8ef513c 2048 else if (aNewActive == "tkopengles")
2049 {
2050 Draw::GetInterpretor().Eval ("pload GLES");
2051 }
b8db9379 2052 else if (aNewActive == "tkd3dhost")
2053 {
2054 Draw::GetInterpretor().Eval ("pload D3DHOST");
2055 }
2056 else
2057 {
2058 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
2059 return 1;
2060 }
2061 }
2062
2063 bool isFound = false;
2064 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2065 aFactoryIter.More(); aFactoryIter.Next())
2066 {
2067 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
2068 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
2069 {
2070 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
2071 isFound = true;
2072 break;
2073 }
2074 }
2075
2076 if (!isFound)
2077 {
2078 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
2079 return 1;
2080 }
2081 }
2082
2083 return 0;
2084}
2085
7fd59977 2086//==============================================================================
2087//function : Vinit
2088//purpose : Create the window viewer and initialize all the global variable
e79a94b9 2089// Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 2090//==============================================================================
2091
18d715bd 2092static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 2093{
e79a94b9 2094 TCollection_AsciiString aViewName, aDisplayName;
2095 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
72ed0644 2096 Standard_Boolean isVirtual = false;
9e04ccdc 2097 Handle(V3d_View) aCopyFrom;
e79a94b9 2098 TCollection_AsciiString aName, aValue;
2e93433e 2099 int is2dMode = -1;
e79a94b9 2100 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 2101 {
e79a94b9 2102 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2103 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 2104 anArgCase.LowerCase();
2105 if (anArgIt + 1 < theArgsNb
2106 && anArgCase == "-name")
2107 {
2108 aViewName = theArgVec[++anArgIt];
2109 }
2110 else if (anArgIt + 1 < theArgsNb
2111 && (anArgCase == "-left"
2112 || anArgCase == "-l"))
2113 {
2114 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2115 }
2116 else if (anArgIt + 1 < theArgsNb
2117 && (anArgCase == "-top"
2118 || anArgCase == "-t"))
2119 {
2120 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2121 }
2122 else if (anArgIt + 1 < theArgsNb
2123 && (anArgCase == "-width"
2124 || anArgCase == "-w"))
2125 {
2126 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2127 }
2128 else if (anArgIt + 1 < theArgsNb
2129 && (anArgCase == "-height"
2130 || anArgCase == "-h"))
18d715bd 2131 {
fd3f6bd0 2132 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2133 }
72ed0644 2134 else if (anArgCase == "-virtual"
2135 || anArgCase == "-offscreen")
2136 {
2137 isVirtual = true;
2138 if (anArgIt + 1 < theArgsNb
2139 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
2140 {
2141 ++anArgIt;
2142 }
2143 }
fd3f6bd0 2144 else if (anArgCase == "-exitonclose")
2145 {
49582f9d 2146 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 2147 if (anArgIt + 1 < theArgsNb
dae2a922 2148 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 2149 {
2150 ++anArgIt;
2151 }
2152 }
2153 else if (anArgCase == "-closeonescape"
2154 || anArgCase == "-closeonesc")
2155 {
49582f9d 2156 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 2157 if (anArgIt + 1 < theArgsNb
dae2a922 2158 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 2159 {
2160 ++anArgIt;
2161 }
2162 }
2e93433e 2163 else if (anArgCase == "-2d_mode"
2164 || anArgCase == "-2dmode"
2165 || anArgCase == "-2d")
2166 {
2167 bool toEnable = true;
2168 if (anArgIt + 1 < theArgsNb
dae2a922 2169 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2e93433e 2170 {
2171 ++anArgIt;
2172 }
2173 is2dMode = toEnable ? 1 : 0;
2174 }
fd3f6bd0 2175 else if (anArgIt + 1 < theArgsNb
2176 && (anArgCase == "-disp"
2177 || anArgCase == "-display"))
2178 {
2179 aDisplayName = theArgVec[++anArgIt];
2180 }
9e04ccdc 2181 else if (!ViewerTest::CurrentView().IsNull()
2182 && aCopyFrom.IsNull()
2183 && (anArgCase == "-copy"
2184 || anArgCase == "-clone"
2185 || anArgCase == "-cloneactive"
2186 || anArgCase == "-cloneactiveview"))
2187 {
2188 aCopyFrom = ViewerTest::CurrentView();
2189 }
fd3f6bd0 2190 // old syntax
2191 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2192 {
2193 aName.LowerCase();
2194 if (aName == "name")
18d715bd 2195 {
2196 aViewName = aValue;
2197 }
fd3f6bd0 2198 else if (aName == "l"
2199 || aName == "left")
e79a94b9 2200 {
18d715bd 2201 aPxLeft = aValue.IntegerValue();
e79a94b9 2202 }
fd3f6bd0 2203 else if (aName == "t"
2204 || aName == "top")
e79a94b9 2205 {
18d715bd 2206 aPxTop = aValue.IntegerValue();
e79a94b9 2207 }
fd3f6bd0 2208 else if (aName == "disp"
2209 || aName == "display")
e79a94b9 2210 {
18d715bd 2211 aDisplayName = aValue;
e79a94b9 2212 }
fd3f6bd0 2213 else if (aName == "w"
2214 || aName == "width")
e79a94b9 2215 {
18d715bd 2216 aPxWidth = aValue.IntegerValue();
e79a94b9 2217 }
fd3f6bd0 2218 else if (aName == "h"
2219 || aName == "height")
e79a94b9 2220 {
18d715bd 2221 aPxHeight = aValue.IntegerValue();
e79a94b9 2222 }
18d715bd 2223 else
2224 {
23fe70ec 2225 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2226 return 1;
18d715bd 2227 }
2228 }
e79a94b9 2229 else if (aViewName.IsEmpty())
2230 {
2231 aViewName = anArg;
2232 }
2233 else
2234 {
23fe70ec 2235 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2236 return 1;
e79a94b9 2237 }
18d715bd 2238 }
2239
fd3f6bd0 2240#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2241 if (!aDisplayName.IsEmpty())
2242 {
2243 aDisplayName.Clear();
23fe70ec 2244 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
fd3f6bd0 2245 }
2246#endif
2247
18d715bd 2248 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2249 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2250 {
e79a94b9 2251 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2252 theDi.Eval (aCommand.ToCString());
2e93433e 2253 if (is2dMode != -1)
2254 {
2255 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2256 }
18d715bd 2257 return 0;
2258 }
2259
2260 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
72ed0644 2261 aViewName, aDisplayName, aCopyFrom, isVirtual);
2e93433e 2262 if (is2dMode != -1)
2263 {
2264 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2265 }
e79a94b9 2266 theDi << aViewId;
7fd59977 2267 return 0;
2268}
2269
1eeef710 2270//! Parse HLR algo type.
2271static Standard_Boolean parseHlrAlgoType (const char* theName,
2272 Prs3d_TypeOfHLR& theType)
2273{
2274 TCollection_AsciiString aName (theName);
2275 aName.LowerCase();
2276 if (aName == "polyalgo")
2277 {
2278 theType = Prs3d_TOH_PolyAlgo;
2279 }
2280 else if (aName == "algo")
2281 {
2282 theType = Prs3d_TOH_Algo;
2283 }
2284 else
2285 {
2286 return Standard_False;
2287 }
2288 return Standard_True;
2289}
2290
0a768f56 2291//==============================================================================
2292//function : VHLR
2293//purpose : hidden lines removal algorithm
2294//==============================================================================
2295
2296static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2297{
1eeef710 2298 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2299 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2300 if (aView.IsNull())
0a768f56 2301 {
23fe70ec 2302 Message::SendFail ("Error: no active viewer");
0a768f56 2303 return 1;
2304 }
2305
1eeef710 2306 Standard_Boolean hasHlrOnArg = Standard_False;
2307 Standard_Boolean hasShowHiddenArg = Standard_False;
2308 Standard_Boolean isHLROn = Standard_False;
2309 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2310 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2311 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2312 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2313 {
1eeef710 2314 TCollection_AsciiString anArg (argv[anArgIter]);
2315 anArg.LowerCase();
2316 if (anUpdateTool.parseRedrawMode (anArg))
2317 {
2318 continue;
2319 }
2320 else if (anArg == "-showhidden"
2321 && anArgIter + 1 < argc
dae2a922 2322 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1eeef710 2323 {
2324 ++anArgIter;
2325 hasShowHiddenArg = Standard_True;
2326 continue;
2327 }
2328 else if ((anArg == "-type"
2329 || anArg == "-algo"
2330 || anArg == "-algotype")
2331 && anArgIter + 1 < argc
2332 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2333 {
2334 ++anArgIter;
2335 continue;
2336 }
2337 else if (!hasHlrOnArg
dae2a922 2338 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1eeef710 2339 {
2340 hasHlrOnArg = Standard_True;
2341 continue;
2342 }
2343 // old syntax
2344 else if (!hasShowHiddenArg
dae2a922 2345 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1eeef710 2346 {
2347 hasShowHiddenArg = Standard_True;
2348 continue;
2349 }
2350 else
2351 {
23fe70ec 2352 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1eeef710 2353 return 1;
2354 }
0a768f56 2355 }
1eeef710 2356 if (!hasHlrOnArg)
0a768f56 2357 {
1eeef710 2358 di << "HLR: " << aView->ComputedMode() << "\n";
2359 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2360 di << "HlrAlgo: ";
2361 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2362 {
2363 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2364 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2365 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2366 }
2367 anUpdateTool.Invalidate();
2368 return 0;
0a768f56 2369 }
2370
1eeef710 2371 Standard_Boolean toRecompute = Standard_False;
2372 if (aTypeOfHLR != Prs3d_TOH_NotSet
2373 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2374 {
1eeef710 2375 toRecompute = Standard_True;
2376 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2377 }
2378 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2379 {
2380 toRecompute = Standard_True;
2381 if (toShowHidden)
e9224045 2382 {
1eeef710 2383 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2384 }
2385 else
2386 {
1eeef710 2387 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2388 }
1eeef710 2389 }
e9224045 2390
1eeef710 2391 // redisplay shapes
2392 if (aView->ComputedMode() && isHLROn && toRecompute)
2393 {
2394 AIS_ListOfInteractive aListOfShapes;
2395 aCtx->DisplayedObjects (aListOfShapes);
2396 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2397 {
1eeef710 2398 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2399 {
1eeef710 2400 aCtx->Redisplay (aShape, Standard_False);
e9224045 2401 }
2402 }
2403 }
0a768f56 2404
1eeef710 2405 aView->SetComputedMode (isHLROn);
0a768f56 2406 return 0;
2407}
2408
2409//==============================================================================
2410//function : VHLRType
2411//purpose : change type of using HLR algorithm
2412//==============================================================================
2413
1eeef710 2414static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2415{
1eeef710 2416 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2417 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2418 if (aView.IsNull())
0a768f56 2419 {
23fe70ec 2420 Message::SendFail ("Error: no active viewer");
0a768f56 2421 return 1;
2422 }
2423
1eeef710 2424 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2425 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2426 AIS_ListOfInteractive aListOfShapes;
2427 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2428 {
1eeef710 2429 TCollection_AsciiString anArg (argv[anArgIter]);
2430 anArg.LowerCase();
2431 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2432 {
1eeef710 2433 continue;
0a768f56 2434 }
1eeef710 2435 else if ((anArg == "-type"
2436 || anArg == "-algo"
2437 || anArg == "-algotype")
2438 && anArgIter + 1 < argc
2439 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2440 {
2441 ++anArgIter;
2442 continue;
2443 }
2444 // old syntax
2445 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2446 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2447 {
2448 continue;
2449 }
2450 else
0a768f56 2451 {
2452 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2453 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2454 if (!aMap.IsBound2 (aName))
2455 {
23fe70ec 2456 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1eeef710 2457 return 1;
0a768f56 2458 }
1eeef710 2459
2460 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2461 if (aShape.IsNull())
2462 {
23fe70ec 2463 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1eeef710 2464 return 1;
2465 }
2466 aListOfShapes.Append (aShape);
2467 continue;
0a768f56 2468 }
1eeef710 2469 }
2470 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2471 {
23fe70ec 2472 Message::SendFail ("Syntax error: wrong number of arguments");
1eeef710 2473 return 1;
2474 }
2475
2476 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2477 if (isGlobal)
2478 {
2479 aCtx->DisplayedObjects (aListOfShapes);
2480 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2481 }
2482
1eeef710 2483 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2484 {
2485 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2486 if (aShape.IsNull())
2487 {
2488 continue;
2489 }
2490
2491 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2492 && aView->ComputedMode();
2493 if (!isGlobal
2494 || aShape->TypeOfHLR() != aTypeOfHLR)
2495 {
2496 aShape->SetTypeOfHLR (aTypeOfHLR);
2497 }
2498 if (toUpdateShape)
2499 {
2500 aCtx->Redisplay (aShape, Standard_False);
2501 }
2502 }
0a768f56 2503 return 0;
2504}
2505
18d715bd 2506//==============================================================================
2507//function : FindViewIdByWindowHandle
2508//purpose : Find theView Id in the map of views by window handle
2509//==============================================================================
49582f9d 2510#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2511TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
18d715bd 2512{
2513 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2514 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2515 {
49582f9d 2516 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
18d715bd 2517 if (aWindowHandle == theWindowHandle)
2518 return anIter.Key1();
2519 }
2520 return TCollection_AsciiString("");
2521}
2522#endif
2523
e084dbbc 2524//! Make the view active
2525void ActivateView (const TCollection_AsciiString& theViewName,
2526 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2527{
2528 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2529 if (aView.IsNull())
18d715bd 2530 {
e084dbbc 2531 return;
2532 }
18d715bd 2533
e084dbbc 2534 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2535 if (!anAISContext.IsNull())
2536 {
49582f9d 2537 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
e084dbbc 2538 {
49582f9d 2539 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
e084dbbc 2540 }
2541
2542 ViewerTest::CurrentView (aView);
2543 ViewerTest::SetAISContext (anAISContext);
49582f9d 2544 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
1eeef710 2545#if defined(_WIN32)
e084dbbc 2546 VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2547#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e084dbbc 2548 VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2549#else
e084dbbc 2550 VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2551#endif
e084dbbc 2552 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2553 if (theToUpdate)
2554 {
18d715bd 2555 ViewerTest::CurrentView()->Redraw();
2556 }
2557 }
2558}
2559
0e93d9e5 2560//==============================================================================
2561//function : RemoveView
2562//purpose :
2563//==============================================================================
2564void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2565 const Standard_Boolean theToRemoveContext)
2566{
2567 if (!ViewerTest_myViews.IsBound2 (theView))
2568 {
2569 return;
2570 }
2571
2572 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2573 RemoveView (aViewName, theToRemoveContext);
2574}
2575
18d715bd 2576//==============================================================================
2577//function : RemoveView
4551e1be 2578//purpose : Close and remove view from display, clear maps if necessary
18d715bd 2579//==============================================================================
2580void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2581{
2582 if (!ViewerTest_myViews.IsBound1(theViewName))
2583 {
23fe70ec 2584 Message::SendFail() << "Wrong view name";
18d715bd 2585 return;
2586 }
2587
2588 // Activate another view if it's active now
2589 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2590 {
2591 if (ViewerTest_myViews.Extent() > 1)
2592 {
2593 TCollection_AsciiString aNewViewName;
c48e2889 2594 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2595 anIter.More(); anIter.Next())
2596 {
18d715bd 2597 if (anIter.Key1() != theViewName)
2598 {
2599 aNewViewName = anIter.Key1();
2600 break;
2601 }
c48e2889 2602 }
2603 ActivateView (aNewViewName);
18d715bd 2604 }
2605 else
2606 {
e084dbbc 2607 VT_GetWindow().Nullify();
2608 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2609 if (isContextRemoved)
2610 {
2611 Handle(AIS_InteractiveContext) anEmptyContext;
2612 ViewerTest::SetAISContext(anEmptyContext);
2613 }
2614 }
2615 }
2616
2617 // Delete view
2618 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2619 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2620 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2621 aRedrawer.Stop (aView->Window());
18d715bd 2622
2623 // Remove view resources
18d715bd 2624 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2625 aView->Window()->Unmap();
18d715bd 2626 aView->Remove();
2627
2628#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2629 XFlush (GetDisplayConnection()->GetDisplay());
2630#endif
2631
2632 // Keep context opened only if the closed view is last to avoid
2633 // unused empty contexts
2634 if (!aCurrentContext.IsNull())
2635 {
2636 // Check if there are more difined views in the viewer
f7fc0c03 2637 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2638 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
18d715bd 2639 {
2640 // Remove driver if there is no viewers that use it
2641 Standard_Boolean isRemoveDriver = Standard_True;
2642 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2643 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2644 {
2645 if (aCurrentContext != anIter.Key2() &&
2646 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2647 {
2648 isRemoveDriver = Standard_False;
2649 break;
2650 }
2651 }
2ec85268 2652
2653 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2654 if(isRemoveDriver)
2655 {
2656 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2657 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 2658 Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
18d715bd 2659 #endif
2660 }
2661
2662 ViewerTest_myContexts.UnBind2(aCurrentContext);
2663 }
2664 }
23fe70ec 2665 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
49582f9d 2666 if (ViewerTest_EventManager::ToExitOnCloseView())
fd3f6bd0 2667 {
2668 Draw_Interprete ("exit");
2669 }
18d715bd 2670}
2671
2672//==============================================================================
2673//function : VClose
2674//purpose : Remove the view defined by its name
2675//==============================================================================
2676
d0cc1cb7 2677static int VClose (Draw_Interpretor& /*theDi*/,
2678 Standard_Integer theArgsNb,
2679 const char** theArgVec)
18d715bd 2680{
18d715bd 2681 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2682 if (theArgsNb > 1)
18d715bd 2683 {
d0cc1cb7 2684 TCollection_AsciiString anArg (theArgVec[1]);
2685 anArg.UpperCase();
2686 if (anArg.IsEqual ("ALL")
2687 || anArg.IsEqual ("*"))
2688 {
2689 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2690 anIter.More(); anIter.Next())
2691 {
2692 aViewList.Append (anIter.Key1());
2693 }
2694 if (aViewList.IsEmpty())
2695 {
2696 std::cout << "No view to close\n";
2697 return 0;
2698 }
2699 }
2700 else
18d715bd 2701 {
d0cc1cb7 2702 ViewerTest_Names aViewName (theArgVec[1]);
2703 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2704 {
23fe70ec 2705 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
d0cc1cb7 2706 return 1;
2707 }
2708 aViewList.Append (aViewName.GetViewName());
18d715bd 2709 }
2710 }
2711 else
2712 {
d0cc1cb7 2713 // close active view
2714 if (ViewerTest::CurrentView().IsNull())
2715 {
23fe70ec 2716 Message::SendFail ("Error: no active view");
d0cc1cb7 2717 return 1;
2718 }
2719 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2720 }
2721
d0cc1cb7 2722 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2723 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2724 anIter.More(); anIter.Next())
2725 {
d0cc1cb7 2726 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2727 }
2728
2729 return 0;
2730}
2731
2732//==============================================================================
2733//function : VActivate
2734//purpose : Activate the view defined by its ID
2735//==============================================================================
2736
2737static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2738{
e084dbbc 2739 if (theArgsNb == 1)
18d715bd 2740 {
2741 theDi.Eval("vviewlist");
2742 return 0;
2743 }
2744
e084dbbc 2745 TCollection_AsciiString aNameString;
2746 Standard_Boolean toUpdate = Standard_True;
2747 Standard_Boolean toActivate = Standard_True;
2748 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2749 {
e084dbbc 2750 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2751 anArg.LowerCase();
2752 if (toUpdate
2753 && anArg == "-noupdate")
2754 {
2755 toUpdate = Standard_False;
2756 }
2757 else if (toActivate
2758 && aNameString.IsEmpty()
2759 && anArg == "none")
2760 {
49582f9d 2761 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
e084dbbc 2762 VT_GetWindow().Nullify();
2763 ViewerTest::CurrentView (Handle(V3d_View)());
2764 ViewerTest::ResetEventManager();
2765 theDi << theArgVec[0] << ": all views are inactive\n";
2766 toActivate = Standard_False;
2767 }
2768 else if (toActivate
2769 && aNameString.IsEmpty())
2770 {
2771 aNameString = theArgVec[anArgIter];
2772 }
2773 else
2774 {
23fe70ec 2775 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
e084dbbc 2776 return 1;
2777 }
18d715bd 2778 }
2779
e084dbbc 2780 if (!toActivate)
2781 {
2782 return 0;
2783 }
2784 else if (aNameString.IsEmpty())
2785 {
23fe70ec 2786 Message::SendFail ("Syntax error: wrong number of arguments");
e084dbbc 2787 return 1;
2788 }
18d715bd 2789
2790 // Check if this view exists in the viewer with the driver
e084dbbc 2791 ViewerTest_Names aViewNames (aNameString);
18d715bd 2792 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2793 {
e084dbbc 2794 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2795 return 1;
2796 }
2797
2798 // Check if it is active already
2799 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2800 {
2801 theDi << theArgVec[0] << ": the view is active already\n";
2802 return 0;
2803 }
2804
e084dbbc 2805 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2806 return 0;
2807}
2808
2809//==============================================================================
2810//function : VViewList
2811//purpose : Print current list of views per viewer and graphic driver ID
2812// shared between viewers
2813//==============================================================================
2814
2815static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2816{
2817 if (theArgsNb > 2)
2818 {
2819 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2820 << "Usage: " << theArgVec[0] << " name";
18d715bd 2821 return 1;
2822 }
2823 if (ViewerTest_myContexts.Size() < 1)
2824 return 0;
2825
18d715bd 2826 Standard_Boolean isTreeView =
29cb310a 2827 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2828
2829 if (isTreeView)
c48e2889 2830 {
18d715bd 2831 theDi << theArgVec[0] <<":\n";
c48e2889 2832 }
18d715bd 2833
c48e2889 2834 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2835 aDriverIter.More(); aDriverIter.Next())
2836 {
2837 if (isTreeView)
2838 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2839
c48e2889 2840 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2841 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2842 {
2843 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2844 {
c48e2889 2845 if (isTreeView)
18d715bd 2846 {
c48e2889 2847 TCollection_AsciiString aContextName(aContextIter.Key1());
2848 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2849 }
18d715bd 2850
c48e2889 2851 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2852 aViewIter.More(); aViewIter.Next())
2853 {
2854 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2855 {
c48e2889 2856 TCollection_AsciiString aViewName(aViewIter.Key1());
2857 if (isTreeView)
18d715bd 2858 {
c48e2889 2859 if (aViewIter.Value() == ViewerTest::CurrentView())
2860 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2861 else
c48e2889 2862 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2863 }
2864 else
2865 {
2866 theDi << aViewName << " ";
18d715bd 2867 }
2868 }
2869 }
2870 }
2871 }
c48e2889 2872 }
18d715bd 2873 return 0;
2874}
2875
7fd59977 2876//==============================================================================
49582f9d 2877//function : GetMousePosition
2878//purpose :
7fd59977 2879//==============================================================================
49582f9d 2880void ViewerTest::GetMousePosition (Standard_Integer& theX,
2881 Standard_Integer& theY)
7fd59977 2882{
49582f9d 2883 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
4fe56619 2884 {
49582f9d 2885 theX = aViewCtrl->LastMousePosition().x();
2886 theY = aViewCtrl->LastMousePosition().y();
4fe56619 2887 }
7fd59977 2888}
2889
44b8f2d6 2890//==============================================================================
fc552d84 2891//function : VViewProj
2892//purpose : Switch view projection
44b8f2d6 2893//==============================================================================
fc552d84 2894static int VViewProj (Draw_Interpretor& ,
2895 Standard_Integer theNbArgs,
2896 const char** theArgVec)
44b8f2d6 2897{
fc552d84 2898 static Standard_Boolean isYup = Standard_False;
2899 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2900 if (aView.IsNull())
44b8f2d6 2901 {
23fe70ec 2902 Message::SendFail ("Error: no active viewer");
44b8f2d6 2903 return 1;
2904 }
2905
fc552d84 2906 TCollection_AsciiString aCmdName (theArgVec[0]);
2907 Standard_Boolean isGeneralCmd = Standard_False;
2908 if (aCmdName == "vfront")
2909 {
2910 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2911 }
2912 else if (aCmdName == "vback")
2913 {
2914 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2915 }
2916 else if (aCmdName == "vtop")
2917 {
2918 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2919 }
2920 else if (aCmdName == "vbottom")
2921 {
2922 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2923 }
2924 else if (aCmdName == "vleft")
2925 {
2926 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2927 }
2928 else if (aCmdName == "vright")
2929 {
2930 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2931 }
2932 else if (aCmdName == "vaxo")
2933 {
2934 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2935 }
2936 else
2937 {
2938 isGeneralCmd = Standard_True;
2939 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2940 {
2941 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2942 anArgCase.LowerCase();
2943 if (anArgCase == "-zup")
2944 {
2945 isYup = Standard_False;
2946 }
2947 else if (anArgCase == "-yup")
2948 {
2949 isYup = Standard_True;
2950 }
2951 else if (anArgCase == "-front"
2952 || anArgCase == "front"
2953 || anArgCase == "-f"
2954 || anArgCase == "f")
2955 {
2956 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2957 }
2958 else if (anArgCase == "-back"
2959 || anArgCase == "back"
2960 || anArgCase == "-b"
2961 || anArgCase == "b")
2962 {
2963 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2964 }
2965 else if (anArgCase == "-top"
2966 || anArgCase == "top"
2967 || anArgCase == "-t"
2968 || anArgCase == "t")
2969 {
2970 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2971 }
2972 else if (anArgCase == "-bottom"
2973 || anArgCase == "bottom"
2974 || anArgCase == "-bot"
2975 || anArgCase == "bot"
2976 || anArgCase == "-b"
2977 || anArgCase == "b")
2978 {
2979 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2980 }
2981 else if (anArgCase == "-left"
2982 || anArgCase == "left"
2983 || anArgCase == "-l"
2984 || anArgCase == "l")
2985 {
2986 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2987 }
2988 else if (anArgCase == "-right"
2989 || anArgCase == "right"
2990 || anArgCase == "-r"
2991 || anArgCase == "r")
2992 {
2993 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2994 }
2995 else if (anArgCase == "-axoleft"
2996 || anArgCase == "-leftaxo"
2997 || anArgCase == "axoleft"
2998 || anArgCase == "leftaxo")
2999 {
3000 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
3001 }
3002 else if (anArgCase == "-axo"
3003 || anArgCase == "axo"
3004 || anArgCase == "-a"
3005 || anArgCase == "a"
3006 || anArgCase == "-axoright"
3007 || anArgCase == "-rightaxo"
3008 || anArgCase == "axoright"
3009 || anArgCase == "rightaxo")
3010 {
3011 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
3012 }
3013 else if (anArgCase == "+x")
3014 {
3015 aView->SetProj (V3d_Xpos, isYup);
3016 }
3017 else if (anArgCase == "-x")
3018 {
3019 aView->SetProj (V3d_Xneg, isYup);
3020 }
3021 else if (anArgCase == "+y")
3022 {
3023 aView->SetProj (V3d_Ypos, isYup);
3024 }
3025 else if (anArgCase == "-y")
3026 {
3027 aView->SetProj (V3d_Yneg, isYup);
3028 }
3029 else if (anArgCase == "+z")
3030 {
3031 aView->SetProj (V3d_Zpos, isYup);
3032 }
3033 else if (anArgCase == "-z")
3034 {
3035 aView->SetProj (V3d_Zneg, isYup);
3036 }
3037 else if (anArgCase == "+x+y+z")
3038 {
3039 aView->SetProj (V3d_XposYposZpos, isYup);
3040 }
3041 else if (anArgCase == "+x+y-z")
3042 {
3043 aView->SetProj (V3d_XposYposZneg, isYup);
3044 }
3045 else if (anArgCase == "+x-y+z")
3046 {
3047 aView->SetProj (V3d_XposYnegZpos, isYup);
3048 }
3049 else if (anArgCase == "+x-y-z")
3050 {
3051 aView->SetProj (V3d_XposYnegZneg, isYup);
3052 }
3053 else if (anArgCase == "-x+y+z")
3054 {
3055 aView->SetProj (V3d_XnegYposZpos, isYup);
3056 }
3057 else if (anArgCase == "-x+y-z")
3058 {
3059 aView->SetProj (V3d_XnegYposZneg, isYup);
3060 }
3061 else if (anArgCase == "-x-y+z")
3062 {
3063 aView->SetProj (V3d_XnegYnegZpos, isYup);
3064 }
3065 else if (anArgCase == "-x-y-z")
3066 {
3067 aView->SetProj (V3d_XnegYnegZneg, isYup);
3068 }
3069 else if (anArgCase == "+x+y")
3070 {
3071 aView->SetProj (V3d_XposYpos, isYup);
3072 }
3073 else if (anArgCase == "+x-y")
3074 {
3075 aView->SetProj (V3d_XposYneg, isYup);
3076 }
3077 else if (anArgCase == "-x+y")
3078 {
3079 aView->SetProj (V3d_XnegYpos, isYup);
3080 }
3081 else if (anArgCase == "-x-y")
3082 {
3083 aView->SetProj (V3d_XnegYneg, isYup);
3084 }
3085 else if (anArgCase == "+x+z")
3086 {
3087 aView->SetProj (V3d_XposZpos, isYup);
3088 }
3089 else if (anArgCase == "+x-z")
3090 {
3091 aView->SetProj (V3d_XposZneg, isYup);
3092 }
3093 else if (anArgCase == "-x+z")
3094 {
3095 aView->SetProj (V3d_XnegZpos, isYup);
3096 }
3097 else if (anArgCase == "-x-z")
3098 {
3099 aView->SetProj (V3d_XnegZneg, isYup);
3100 }
3101 else if (anArgCase == "+y+z")
3102 {
3103 aView->SetProj (V3d_YposZpos, isYup);
3104 }
3105 else if (anArgCase == "+y-z")
3106 {
3107 aView->SetProj (V3d_YposZneg, isYup);
3108 }
3109 else if (anArgCase == "-y+z")
3110 {
3111 aView->SetProj (V3d_YnegZpos, isYup);
3112 }
3113 else if (anArgCase == "-y-z")
3114 {
3115 aView->SetProj (V3d_YnegZneg, isYup);
3116 }
3117 else if (anArgIter + 1 < theNbArgs
3118 && anArgCase == "-frame"
3119 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
3120 {
3121 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
3122 aFrameDef.LowerCase();
3123 gp_Dir aRight, anUp;
3124 if (aFrameDef.Value (2) == aFrameDef.Value (4))
3125 {
23fe70ec 3126 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3127 return 1;
3128 }
44b8f2d6 3129
fc552d84 3130 if (aFrameDef.Value (2) == 'x')
3131 {
3132 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
3133 }
3134 else if (aFrameDef.Value (2) == 'y')
3135 {
3136 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
3137 }
3138 else if (aFrameDef.Value (2) == 'z')
3139 {
3140 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
3141 }
3142 else
3143 {
23fe70ec 3144 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3145 return 1;
3146 }
7fd59977 3147
fc552d84 3148 if (aFrameDef.Value (4) == 'x')
3149 {
3150 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
3151 }
3152 else if (aFrameDef.Value (4) == 'y')
3153 {
3154 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
3155 }
3156 else if (aFrameDef.Value (4) == 'z')
3157 {
3158 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
3159 }
3160 else
3161 {
23fe70ec 3162 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3163 return 1;
3164 }
44b8f2d6 3165
fc552d84 3166 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3167 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3168 const gp_Dir aDir = anUp.Crossed (aRight);
3169 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3170 aCamera->SetDirection (aDir);
3171 aCamera->SetUp (anUp);
3172 aCamera->OrthogonalizeUp();
44b8f2d6 3173
fc552d84 3174 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3175 aView->Update();
3176 }
3177 else
3178 {
23fe70ec 3179 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3180 return 1;
3181 }
3182 }
3183 }
44b8f2d6 3184
fc552d84 3185 if (!isGeneralCmd
3186 && theNbArgs != 1)
3187 {
23fe70ec 3188 Message::SendFail ("Syntax error: wrong number of arguments");
fc552d84 3189 return 1;
3190 }
3191 return 0;
7fd59977 3192}
3193
3194//==============================================================================
3195//function : VHelp
3196//purpose : Dsiplay help on viewer Keyboead and mouse commands
3197//Draw arg : No args
3198//==============================================================================
3199
3200static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3201{
586db386 3202 di << "=========================\n";
3203 di << "F : FitAll\n";
3204 di << "T : TopView\n";
3205 di << "B : BottomView\n";
3206 di << "R : RightView\n";
3207 di << "L : LeftView\n";
d22962e4 3208 di << "Backspace : AxonometricView\n";
586db386 3209
3210 di << "=========================\n";
d22962e4 3211 di << "W, S : Fly forward/backward\n";
3212 di << "A, D : Slide left/right\n";
3213 di << "Q, E : Bank left/right\n";
3214 di << "-, + : Change flying speed\n";
3215 di << "Arrows : look left/right/up/down\n";
3216 di << "Arrows+Shift : slide left/right/up/down\n";
3217
3218 di << "=========================\n";
3219 di << "S + Ctrl : Shading\n";
3220 di << "W + Ctrl : Wireframe\n";
49582f9d 3221 di << "H : HiddenLineRemoval\n";
586db386 3222 di << "U : Unset display mode\n";
3223 di << "Delete : Remove selection from viewer\n";
3224
3225 di << "=========================\n";
3226 di << "Selection mode \n";
3227 di << "0 : Shape\n";
3228 di << "1 : Vertex\n";
3229 di << "2 : Edge\n";
3230 di << "3 : Wire\n";
3231 di << "4 : Face\n";
3232 di << "5 : Shell\n";
3233 di << "6 : Solid\n";
3234 di << "7 : Compound\n";
3235
3236 di << "=========================\n";
49582f9d 3237 di << "< : Hilight next detected\n";
3238 di << "> : Hilight previous detected\n";
7fd59977 3239
3240 return 0;
3241}
3242
57c28b61 3243#ifdef _WIN32
7fd59977 3244
49582f9d 3245static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3246 UINT theMsg,
3247 WPARAM wParam,
3248 LPARAM lParam )
7fd59977 3249{
49582f9d 3250 if (ViewerTest_myViews.IsEmpty())
3251 {
3252 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
3253 }
7fd59977 3254
49582f9d 3255 switch (theMsg)
3256 {
18d715bd 3257 case WM_CLOSE:
49582f9d 3258 {
3259 // Delete view from map of views
3260 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3261 return 0;
3262 }
18d715bd 3263 case WM_ACTIVATE:
49582f9d 3264 {
3265 if (LOWORD(wParam) == WA_CLICKACTIVE
3266 || LOWORD(wParam) == WA_ACTIVE
3267 || ViewerTest::CurrentView().IsNull())
18d715bd 3268 {
3269 // Activate inactive window
49582f9d 3270 if (VT_GetWindow().IsNull()
3271 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
625e1958 3272 {
49582f9d 3273 ActivateView (FindViewIdByWindowHandle (theWinHandle));
625e1958 3274 }
7fd59977 3275 }
7fd59977 3276 break;
49582f9d 3277 }
7fd59977 3278 default:
49582f9d 3279 {
3280 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
7fd59977 3281 }
7fd59977 3282 }
49582f9d 3283 return 0;
7fd59977 3284}
3285
49582f9d 3286static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
3287 UINT theMsg,
3288 WPARAM wParam,
3289 LPARAM lParam)
7fd59977 3290{
f978241f 3291 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3292 if (aView.IsNull())
3293 {
49582f9d 3294 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
f978241f 3295 }
7fd59977 3296
49582f9d 3297 switch (theMsg)
3298 {
7fd59977 3299 case WM_PAINT:
49582f9d 3300 {
3301 PAINTSTRUCT aPaint;
3302 BeginPaint(theWinHandle, &aPaint);
3303 EndPaint (theWinHandle, &aPaint);
3304 ViewerTest::CurrentEventManager()->ProcessExpose();
7fd59977 3305 break;
49582f9d 3306 }
7fd59977 3307 case WM_SIZE:
49582f9d 3308 {
3309 ViewerTest::CurrentEventManager()->ProcessConfigure();
7fd59977 3310 break;
49582f9d 3311 }
f978241f 3312 case WM_MOVE:
3313 case WM_MOVING:
3314 case WM_SIZING:
49582f9d 3315 {
f978241f 3316 switch (aView->RenderingParams().StereoMode)
3317 {
3318 case Graphic3d_StereoMode_RowInterlaced:
3319 case Graphic3d_StereoMode_ColumnInterlaced:
3320 case Graphic3d_StereoMode_ChessBoard:
49582f9d 3321 {
3322 // track window moves to reverse stereo pair
3323 aView->MustBeResized();
3324 aView->Update();
f978241f 3325 break;
49582f9d 3326 }
f978241f 3327 default:
3328 break;
3329 }
3330 break;
49582f9d 3331 }
3332 case WM_KEYUP:
7fd59977 3333 case WM_KEYDOWN:
49582f9d 3334 {
3335 const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
3336 if (aVKey != Aspect_VKey_UNKNOWN)
4fe56619 3337 {
49582f9d 3338 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3339 if (theMsg == WM_KEYDOWN)
f978241f 3340 {
49582f9d 3341 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
f978241f 3342 }
49582f9d 3343 else
f978241f 3344 {
49582f9d 3345 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
f978241f 3346 }
49582f9d 3347 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
7fd59977 3348 }
3349 break;
49582f9d 3350 }
7fd59977 3351 case WM_LBUTTONUP:
3352 case WM_MBUTTONUP:
3353 case WM_RBUTTONUP:
7fd59977 3354 case WM_LBUTTONDOWN:
3355 case WM_MBUTTONDOWN:
3356 case WM_RBUTTONDOWN:
49582f9d 3357 {
3358 const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3359 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3360 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3361 switch (theMsg)
7fd59977 3362 {
49582f9d 3363 case WM_LBUTTONUP:
3364 case WM_LBUTTONDOWN:
3365 aButton = Aspect_VKeyMouse_LeftButton;
3366 break;
3367 case WM_MBUTTONUP:
3368 case WM_MBUTTONDOWN:
3369 aButton = Aspect_VKeyMouse_MiddleButton;
3370 break;
3371 case WM_RBUTTONUP:
3372 case WM_RBUTTONDOWN:
3373 aButton = Aspect_VKeyMouse_RightButton;
3374 break;
7fd59977 3375 }
49582f9d 3376 if (theMsg == WM_LBUTTONDOWN
3377 || theMsg == WM_MBUTTONDOWN
3378 || theMsg == WM_RBUTTONDOWN)
f978241f 3379 {
49582f9d 3380 if (aButton == Aspect_VKeyMouse_LeftButton)
f978241f 3381 {
49582f9d 3382 TheIsAnimating = Standard_False;
f978241f 3383 }
49582f9d 3384
3385 SetFocus (theWinHandle);
3386 SetCapture(theWinHandle);
3387 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
f978241f 3388 }
3389 else
3390 {
49582f9d 3391 ReleaseCapture();
3392 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
f978241f 3393 }
49582f9d 3394 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
f978241f 3395 break;
3396 }
49582f9d 3397 case WM_MOUSEWHEEL:
3398 {
3399 const int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
3400 const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
3401 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3402 Graphic3d_Vec2i aPos (int(short(LOWORD(lParam))), int(short(HIWORD(lParam))));
3403 POINT aCursorPnt = { aPos.x(), aPos.y() };
3404 if (ScreenToClient (theWinHandle, &aCursorPnt))
7fd59977 3405 {
49582f9d 3406 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3407 }
7fd59977 3408
49582f9d 3409 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3410 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3411 break;
3412 }
3413 case WM_MOUSEMOVE:
3414 {
3415 Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3416 Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (wParam);
3417 Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(wParam);
7fd59977 3418
49582f9d 3419 // don't make a slide-show from input events - fetch the actual mouse cursor position
3420 CURSORINFO aCursor;
3421 aCursor.cbSize = sizeof(aCursor);
3422 if (::GetCursorInfo (&aCursor) != FALSE)
3423 {
3424 POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
3425 if (ScreenToClient (theWinHandle, &aCursorPnt))
3426 {
3427 // as we override mouse position, we need overriding also mouse state
3428 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3429 aButtons = WNT_Window::MouseButtonsAsync();
3430 aFlags = WNT_Window::MouseKeyFlagsAsync();
3431 }
3432 }
7fd59977 3433
49582f9d 3434 if (VT_GetWindow().IsNull()
3435 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3436 {
3437 // mouse move events come also for inactive windows
3438 break;
7fd59977 3439 }
7fd59977 3440
49582f9d 3441 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3442 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
3443 break;
3444 }
d6fbb2ab 3445 case WM_INPUT:
3446 {
3447 UINT aSize = 0;
3448 ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
3449 NCollection_LocalArray<BYTE> aRawData (aSize);
3450 if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
3451 {
3452 break;
3453 }
3454
3455 const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
3456 if (aRawInput->header.dwType != RIM_TYPEHID)
3457 {
3458 break;
3459 }
3460
3461 RID_DEVICE_INFO aDevInfo;
3462 aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
3463 UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
3464 if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
3465 || (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
3466 && aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
3467 {
3468 break;
3469 }
3470
3471 WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
3472 if (ViewerTest::CurrentEventManager()->Update3dMouse (aSpaceData)
3473 && !VT_GetWindow().IsNull())
3474 {
3475 VT_GetWindow()->InvalidateContent();
3476 }
3477 break;
3478 }
7fd59977 3479 default:
49582f9d 3480 {
3481 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
7fd59977 3482 }
49582f9d 3483 }
3484 return 0L;
7fd59977 3485}
3486
7fd59977 3487//==============================================================================
3488//function : ViewerMainLoop
3489//purpose : Get a Event on the view and dispatch it
3490//==============================================================================
3491
49582f9d 3492int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
7fd59977 3493{
49582f9d 3494 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3495 if (aViewCtrl.IsNull()
3496 || theNbArgs < 4)
3497 {
3498 return 0;
3499 }
7fd59977 3500
49582f9d 3501 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
7fd59977 3502
49582f9d 3503 std::cout << "Start picking\n";
7fd59977 3504
49582f9d 3505 MSG aMsg;
3506 aMsg.wParam = 1;
3507 while (aViewCtrl->ToPickPoint())
3508 {
3509 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3510 if (GetMessageW (&aMsg, NULL, 0, 0))
3511 {
3512 TranslateMessage (&aMsg);
3513 DispatchMessageW (&aMsg);
7fd59977 3514 }
7fd59977 3515 }
3516
49582f9d 3517 std::cout << "Picking done\n";
3518 return 0;
7fd59977 3519}
3520
4fe56619 3521#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
7fd59977 3522
3523int min( int a, int b )
3524{
3525 if( a<b )
3526 return a;
3527 else
3528 return b;
3529}
3530
3531int max( int a, int b )
3532{
3533 if( a>b )
3534 return a;
3535 else
3536 return b;
3537}
3538
49582f9d 3539int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
4269bd1b 3540{
18d715bd 3541 static XEvent aReport;
49582f9d 3542 const Standard_Boolean toPick = theNbArgs > 0;
3543 if (theNbArgs > 0)
3544 {
3545 if (ViewerTest::CurrentEventManager().IsNull())
3546 {
3547 return 0;
3548 }
3549 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3550 }
3551
8693dfd0 3552 Display* aDisplay = GetDisplayConnection()->GetDisplay();
18d715bd 3553 XNextEvent (aDisplay, &aReport);
7fd59977 3554
18d715bd 3555 // Handle event for the chosen display connection
8693dfd0 3556 switch (aReport.type)
3557 {
3558 case ClientMessage:
3559 {
3560 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3561 {
3562 // Close the window
3563 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3564 return toPick ? 0 : 1;
3565 }
3566 break;
3567 }
3568 case FocusIn:
3569 {
3570 // Activate inactive view
49582f9d 3571 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3572 if (aWindow != aReport.xfocus.window)
3573 {
3574 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3575 }
3576 break;
3577 }
3578 case Expose:
3579 {
49582f9d 3580 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3581 if (anXWindow == aReport.xexpose.window)
3582 {
49582f9d 3583 ViewerTest::CurrentEventManager()->ProcessExpose();
8693dfd0 3584 }
3585
3586 // remove all the ExposureMask and process them at once
3587 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3588 {
3589 if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
18d715bd 3590 {
8693dfd0 3591 break;
18d715bd 3592 }
8693dfd0 3593 }
3594
3595 break;
3596 }
3597 case ConfigureNotify:
3598 {
3599 // remove all the StructureNotifyMask and process them at once
49582f9d 3600 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3601 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3602 {
3603 if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
3604 {
3605 break;
3606 }
3607 }
3608
3609 if (anXWindow == aReport.xconfigure.window)
3610 {
49582f9d 3611 ViewerTest::CurrentEventManager()->ProcessConfigure();
8693dfd0 3612 }
3613 break;
3614 }
3615 case KeyPress:
49582f9d 3616 case KeyRelease:
8693dfd0 3617 {
49582f9d 3618 XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
3619 const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
3620 const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
3621 if (aVKey != Aspect_VKey_UNKNOWN)
8693dfd0 3622 {
49582f9d 3623 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3624 if (aReport.type == KeyPress)
7fd59977 3625 {
49582f9d 3626 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
7fd59977 3627 }
8693dfd0 3628 else
7fd59977 3629 {
49582f9d 3630 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
7fd59977 3631 }
49582f9d 3632 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3633 }
3634 break;
3635 }
49582f9d 3636 case ButtonPress:
8693dfd0 3637 case ButtonRelease:
3638 {
49582f9d 3639 const Graphic3d_Vec2i aPos (aReport.xbutton.x, aReport.xbutton.y);
3640 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3641 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3642 if (aReport.xbutton.button == Button1)
8693dfd0 3643 {
49582f9d 3644 aButton = Aspect_VKeyMouse_LeftButton;
8693dfd0 3645 }
49582f9d 3646 if (aReport.xbutton.button == Button2)
8693dfd0 3647 {
49582f9d 3648 aButton = Aspect_VKeyMouse_MiddleButton;
8693dfd0 3649 }
49582f9d 3650 if (aReport.xbutton.button == Button3)
8693dfd0 3651 {
49582f9d 3652 aButton = Aspect_VKeyMouse_RightButton;
8693dfd0 3653 }
7fd59977 3654
49582f9d 3655 if (aReport.xbutton.state & ControlMask)
8693dfd0 3656 {
49582f9d 3657 aFlags |= Aspect_VKeyFlags_CTRL;
3658 }
3659 if (aReport.xbutton.state & ShiftMask)
3660 {
3661 aFlags |= Aspect_VKeyFlags_SHIFT;
3662 }
3663 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3664 {
3665 aFlags |= Aspect_VKeyFlags_ALT;
8693dfd0 3666 }
7fd59977 3667
49582f9d 3668 if (aReport.xbutton.button == Button4
3669 || aReport.xbutton.button == Button5)
8693dfd0 3670 {
49582f9d 3671 if (aReport.type != ButtonPress)
8693dfd0 3672 {
49582f9d 3673 break;
7fd59977 3674 }
49582f9d 3675
3676 const double aDeltaF = (aReport.xbutton.button == Button4 ? 1.0 : -1.0);
3677 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3678 }
3679 else if (aReport.type == ButtonPress)
3680 {
3681 if (aButton == Aspect_VKeyMouse_LeftButton)
7fd59977 3682 {
49582f9d 3683 TheIsAnimating = Standard_False;
7fd59977 3684 }
49582f9d 3685 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3686 }
3687 else
3688 {
49582f9d 3689 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3690 }
49582f9d 3691 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3692 break;
3693 }
3694 case MotionNotify:
3695 {
49582f9d 3696 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3697 if (anXWindow != aReport.xmotion.window)
3698 {
7fd59977 3699 break;
8693dfd0 3700 }
3701
3702 // remove all the ButtonMotionMask and process them at once
3703 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3704 {
3705 if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
7fd59977 3706 {
8693dfd0 3707 break;
3708 }
3709 }
7fd59977 3710
49582f9d 3711 Graphic3d_Vec2i aPos (aReport.xmotion.x, aReport.xmotion.y);
3712 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
3713 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3714 if ((aReport.xmotion.state & Button1Mask) != 0)
8693dfd0 3715 {
49582f9d 3716 aButtons |= Aspect_VKeyMouse_LeftButton;
3717 }
3718 else if ((aReport.xmotion.state & Button2Mask) != 0)
3719 {
3720 aButtons |= Aspect_VKeyMouse_MiddleButton;
3721 }
3722 else if ((aReport.xmotion.state & Button3Mask) != 0)
3723 {
3724 aButtons |= Aspect_VKeyMouse_RightButton;
3725 }
7fd59977 3726
49582f9d 3727 if (aReport.xmotion.state & ControlMask)
3728 {
3729 aFlags |= Aspect_VKeyFlags_CTRL;
8693dfd0 3730 }
49582f9d 3731 if (aReport.xmotion.state & ShiftMask)
8693dfd0 3732 {
49582f9d 3733 aFlags |= Aspect_VKeyFlags_SHIFT;
8693dfd0 3734 }
49582f9d 3735 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3736 {
3737 aFlags |= Aspect_VKeyFlags_ALT;
3738 }
3739
3740 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3741 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3742 break;
3743 }
3744 }
49582f9d 3745 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
7fd59977 3746}
3747
3748//==============================================================================
3749//function : VProcessEvents
8693dfd0 3750//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3751//==============================================================================
8693dfd0 3752static void VProcessEvents (ClientData theDispX, int)
7fd59977 3753{
8693dfd0 3754 Display* aDispX = (Display* )theDispX;
3755 Handle(Aspect_DisplayConnection) aDispConn;
3756 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3757 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3758 {
8693dfd0 3759 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3760 if (aDispConnTmp->GetDisplay() == aDispX)
3761 {
3762 aDispConn = aDispConnTmp;
3763 break;
3764 }
3765 }
3766 if (aDispConn.IsNull())
3767 {
23fe70ec 3768 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
8693dfd0 3769 return;
4269bd1b 3770 }
8693dfd0 3771
3772 // process new events in queue
3773 SetDisplayConnection (aDispConn);
3774 int aNbRemain = 0;
3775 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3776 {
8693dfd0 3777 const int anEventResult = ViewerMainLoop (0, NULL);
3778 if (anEventResult == 0)
18d715bd 3779 {
8693dfd0 3780 return;
3781 }
3782
3783 aNbRemain = XPending (aDispX);
3784 if (++anEventIter >= aNbEventsMax
3785 || aNbRemain <= 0)
3786 {
3787 break;
18d715bd 3788 }
7fd59977 3789 }
4269bd1b 3790
8693dfd0 3791 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3792 // it is possible that new events will arrive to queue before the end of this callback
3793 // so that either this callback should go into an infinite loop (blocking processing of other events)
3794 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3795 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3796 if (aNbRemain != 0)
3797 {
3798 XEvent aDummyEvent;
3799 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3800 aDummyEvent.type = ClientMessage;
3801 aDummyEvent.xclient.format = 32;
3802 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3803 XFlush (aDispX);
3804 }
4269bd1b 3805
8693dfd0 3806 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3807 {
3808 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3809 }
7fd59977 3810}
3811#endif
3812
3813//==============================================================================
3814//function : OSWindowSetup
3815//purpose : Setup for the X11 window to be able to cath the event
3816//==============================================================================
3817
3818
3819static void OSWindowSetup()
3820{
4fe56619 3821#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 3822 // X11
3823
3824 Window window = VT_GetWindow()->XWindow();
18d715bd 3825 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
3826 Display *aDisplay = GetDisplayConnection()->GetDisplay();
3827 XSynchronize(aDisplay, 1);
7fd59977 3828
3829 // X11 : For keyboard on SUN
3830 XWMHints wmhints;
3831 wmhints.flags = InputHint;
3832 wmhints.input = 1;
3833
18d715bd 3834 XSetWMHints( aDisplay, window, &wmhints);
7fd59977 3835
49582f9d 3836 XSelectInput( aDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask |
7fd59977 3837 ButtonPressMask | ButtonReleaseMask |
3838 StructureNotifyMask |
3839 PointerMotionMask |
3840 Button1MotionMask | Button2MotionMask |
18d715bd 3841 Button3MotionMask | FocusChangeMask
7fd59977 3842 );
18d715bd 3843 Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
3844 XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
7fd59977 3845
18d715bd 3846 XSynchronize(aDisplay, 0);
7fd59977 3847
3848#else
57c28b61 3849 // _WIN32
7fd59977 3850#endif
3851
3852}
3853
7fd59977 3854//==============================================================================
3855//function : VFit
1beb58d7 3856//purpose :
7fd59977 3857//==============================================================================
3858
1beb58d7 3859static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 3860{
1beb58d7 3861 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3862 if (aView.IsNull())
b586500b 3863 {
23fe70ec 3864 Message::SendFail ("Error: no active viewer");
1beb58d7 3865 return 1;
b586500b 3866 }
3867
1beb58d7 3868 Standard_Boolean toFit = Standard_True;
3869 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3870 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 3871 {
1beb58d7 3872 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 3873 anArg.LowerCase();
1beb58d7 3874 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 3875 {
1beb58d7 3876 continue;
3877 }
3878 else if (anArg == "-selected")
3879 {
3880 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3881 toFit = Standard_False;
3882 }
3883 else
3884 {
23fe70ec 3885 Message::SendFail() << "Syntax error at '" << anArg << "'";
b586500b 3886 }
3887 }
3888
1beb58d7 3889 if (toFit)
3890 {
3891 aView->FitAll (0.01, Standard_False);
7fd59977 3892 }
3893 return 0;
3894}
3895
6262a303 3896//=======================================================================
3897//function : VFitArea
3898//purpose : Fit view to show area located between two points
3899// : given in world 2D or 3D coordinates.
3900//=======================================================================
3901static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3902{
3903 Handle(V3d_View) aView = ViewerTest::CurrentView();
3904 if (aView.IsNull())
3905 {
23fe70ec 3906 Message::SendFail ("Error: No active viewer");
6262a303 3907 return 1;
3908 }
3909
3910 // Parse arguments.
3911 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3912 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3913
3914 if (theArgNb == 5)
3915 {
3916 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3917 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3918 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3919 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3920 }
3921 else if (theArgNb == 7)
3922 {
3923 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3924 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3925 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3926 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3927 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3928 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3929 }
3930 else
3931 {
23fe70ec 3932 Message::SendFail ("Syntax error: Invalid number of arguments");
6262a303 3933 theDI.PrintHelp(theArgVec[0]);
3934 return 1;
3935 }
3936
3937 // Convert model coordinates to view space
3938 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3939 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3940 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3941
3942 // Determine fit area
3943 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3944 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3945
3946 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3947
3948 if (aDiagonal < Precision::Confusion())
3949 {
23fe70ec 3950 Message::SendFail ("Error: view area is too small");
6262a303 3951 return 1;
3952 }
3953
3954 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3955 return 0;
3956}
3957
7fd59977 3958//==============================================================================
3959//function : VZFit
3960//purpose : ZFitall, no DRAW arguments
3961//Draw arg : No args
3962//==============================================================================
197ac94e 3963static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 3964{
197ac94e 3965 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3966
3967 if (aCurrentView.IsNull())
3968 {
23fe70ec 3969 Message::SendFail ("Error: no active viewer");
197ac94e 3970 return 1;
3971 }
3972
3973 if (theArgsNb == 1)
3974 {
c357e426 3975 aCurrentView->ZFitAll();
197ac94e 3976 aCurrentView->Redraw();
3977 return 0;
3978 }
3979
3980 Standard_Real aScale = 1.0;
3981
3982 if (theArgsNb >= 2)
3983 {
3984 aScale = Draw::Atoi (theArgVec[1]);
3985 }
3986
c357e426 3987 aCurrentView->ZFitAll (aScale);
197ac94e 3988 aCurrentView->Redraw();
7fd59977 3989
197ac94e 3990 return 0;
3991}
7fd59977 3992
197ac94e 3993//==============================================================================
3994//function : VRepaint
3995//purpose :
3996//==============================================================================
56689b27 3997static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 3998{
56689b27 3999 Handle(V3d_View) aView = ViewerTest::CurrentView();
4000 if (aView.IsNull())
4001 {
23fe70ec 4002 Message::SendFail ("Error: no active viewer");
56689b27 4003 return 1;
4004 }
4005
4006 Standard_Boolean isImmediateUpdate = Standard_False;
4007 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4008 {
4009 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4010 anArg.LowerCase();
8693dfd0 4011 if (anArg == "-immediate"
4012 || anArg == "-imm")
56689b27 4013 {
4014 isImmediateUpdate = Standard_True;
4015 if (anArgIter + 1 < theArgNb
dae2a922 4016 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
56689b27 4017 {
4018 ++anArgIter;
4019 }
4020 }
8693dfd0 4021 else if (anArg == "-continuous"
4022 || anArg == "-cont"
4023 || anArg == "-fps"
4024 || anArg == "-framerate")
4025 {
4026 Standard_Real aFps = -1.0;
4027 if (anArgIter + 1 < theArgNb
d45edf24 4028 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
8693dfd0 4029 {
4030 aFps = Draw::Atof (theArgVec[++anArgIter]);
4031 }
4032
4033 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
4034 if (Abs (aFps) >= 1.0)
4035 {
4036 aRedrawer.Start (aView->Window(), aFps);
4037 }
4038 else
4039 {
4040 aRedrawer.Stop();
4041 }
4042 }
56689b27 4043 else
4044 {
23fe70ec 4045 Message::SendFail() << "Syntax error at '" << anArg << "'";
8693dfd0 4046 return 1;
56689b27 4047 }
4048 }
4049
4050 if (isImmediateUpdate)
4051 {
4052 aView->RedrawImmediate();
4053 }
4054 else
4055 {
4056 aView->Redraw();
4057 }
4058 return 0;
7fd59977 4059}
4060
7fd59977 4061//==============================================================================
4062//function : VClear
4063//purpose : Remove all the object from the viewer
4064//Draw arg : No args
4065//==============================================================================
4066
4067static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
4068{
4069 Handle(V3d_View) V = ViewerTest::CurrentView();
4070 if(!V.IsNull())
4071 ViewerTest::Clear();
4072 return 0;
4073}
4074
4075//==============================================================================
4076//function : VPick
4077//purpose :
4078//==============================================================================
4079
49582f9d 4080static int VPick (Draw_Interpretor& ,
4081 Standard_Integer theNbArgs,
4082 const char** theArgVec)
4083{
4084 if (ViewerTest::CurrentView().IsNull())
4085 {
4086 return 1;
4087 }
7fd59977 4088
49582f9d 4089 if (theNbArgs < 4)
4090 {
23fe70ec 4091 Message::SendFail ("Syntax error: wrong number of arguments");
49582f9d 4092 return 1;
4093 }
7fd59977 4094
49582f9d 4095 while (ViewerMainLoop (theNbArgs, theArgVec))
4096 {
4097 //
4098 }
7fd59977 4099
49582f9d 4100 return 0;
7fd59977 4101}
4102
293211ae 4103namespace
7fd59977 4104{
7fd59977 4105
293211ae 4106 //! Changes the background
4107 //! @param theDrawInterpretor the interpreter of the Draw Harness application
4108 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
4109 //! @param theCommandLineArguments the array of command line arguments
4110 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
4111 static int vbackground (Draw_Interpretor& theDrawInterpretor,
4112 const Standard_Integer theNumberOfCommandLineArguments,
4113 const char** const theCommandLineArguments)
7fd59977 4114 {
293211ae 4115 if (theNumberOfCommandLineArguments < 1)
7fd59977 4116 {
293211ae 4117 return TCL_ERROR;
7fd59977 4118 }
293211ae 4119 BackgroundChanger aBackgroundChanger;
4120 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
4121 theNumberOfCommandLineArguments,
4122 theCommandLineArguments))
f8b2ed36 4123 {
293211ae 4124 theDrawInterpretor << "Wrong command arguments.\n"
4125 "Type 'help "
4126 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
4127 return TCL_ERROR;
f8b2ed36 4128 }
293211ae 4129 return TCL_OK;
f8b2ed36 4130 }
4131
293211ae 4132} // namespace
f42753ed 4133
7fd59977 4134//==============================================================================
4135//function : VScale
4136//purpose : View Scaling
4137//==============================================================================
4138
4139static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4140{
4141 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4142 if ( V3dView.IsNull() ) return 1;
4143
4144 if ( argc != 4 ) {
586db386 4145 di << argv[0] << "Invalid number of arguments\n";
7fd59977 4146 return 1;
4147 }
91322f44 4148 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 4149 return 0;
4150}
4151//==============================================================================
536d98e2 4152//function : VZBuffTrihedron
4153//purpose :
7fd59977 4154//==============================================================================
4155
536d98e2 4156static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
4157 Standard_Integer theArgNb,
4158 const char** theArgVec)
7fd59977 4159{
536d98e2 4160 Handle(V3d_View) aView = ViewerTest::CurrentView();
4161 if (aView.IsNull())
4162 {
23fe70ec 4163 Message::SendFail ("Error: no active viewer");
536d98e2 4164 return 1;
4165 }
7fd59977 4166
536d98e2 4167 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 4168
536d98e2 4169 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
4170 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
0aeb8984 4171 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
4172 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
4173 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
536d98e2 4174 Quantity_Color anArrowColorX = Quantity_NOC_RED;
4175 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
4176 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
4177 Standard_Real aScale = 0.1;
4178 Standard_Real aSizeRatio = 0.8;
4179 Standard_Real anArrowDiam = 0.05;
4180 Standard_Integer aNbFacets = 12;
4181 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 4182 {
536d98e2 4183 Standard_CString anArg = theArgVec[anArgIter];
4184 TCollection_AsciiString aFlag (anArg);
4185 aFlag.LowerCase();
4186 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 4187 {
536d98e2 4188 continue;
4189 }
4190 else if (aFlag == "-on")
7c8a8fcc 4191 {
536d98e2 4192 continue;
4193 }
4194 else if (aFlag == "-off")
7c8a8fcc 4195 {
536d98e2 4196 aView->TriedronErase();
4197 return 0;
4198 }
4199 else if (aFlag == "-pos"
4200 || aFlag == "-position"
4201 || aFlag == "-corner")
7c8a8fcc 4202 {
536d98e2 4203 if (++anArgIter >= theArgNb)
4204 {
23fe70ec 4205 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4206 return 1;
4207 }
4208
4209 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
4210 aPosName.LowerCase();
4211 if (aPosName == "center")
4212 {
4213 aPosition = Aspect_TOTP_CENTER;
4214 }
4215 else if (aPosName == "left_lower"
4216 || aPosName == "lower_left"
4217 || aPosName == "leftlower"
4218 || aPosName == "lowerleft")
4219 {
4220 aPosition = Aspect_TOTP_LEFT_LOWER;
4221 }
4222 else if (aPosName == "left_upper"
4223 || aPosName == "upper_left"
4224 || aPosName == "leftupper"
4225 || aPosName == "upperleft")
4226 {
4227 aPosition = Aspect_TOTP_LEFT_UPPER;
4228 }
4229 else if (aPosName == "right_lower"
4230 || aPosName == "lower_right"
4231 || aPosName == "rightlower"
4232 || aPosName == "lowerright")
4233 {
4234 aPosition = Aspect_TOTP_RIGHT_LOWER;
4235 }
4236 else if (aPosName == "right_upper"
4237 || aPosName == "upper_right"
4238 || aPosName == "rightupper"
4239 || aPosName == "upperright")
4240 {
4241 aPosition = Aspect_TOTP_RIGHT_UPPER;
4242 }
4243 else
4244 {
23fe70ec 4245 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
536d98e2 4246 return 1;
4247 }
4248 }
4249 else if (aFlag == "-type")
7c8a8fcc 4250 {
536d98e2 4251 if (++anArgIter >= theArgNb)
4252 {
23fe70ec 4253 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4254 return 1;
4255 }
4256
4257 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
4258 aTypeName.LowerCase();
4259 if (aTypeName == "wireframe"
4260 || aTypeName == "wire")
4261 {
4262 aVisType = V3d_WIREFRAME;
4263 }
4264 else if (aTypeName == "zbuffer"
4265 || aTypeName == "shaded")
4266 {
4267 aVisType = V3d_ZBUFFER;
4268 }
4269 else
4270 {
23fe70ec 4271 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
536d98e2 4272 }
4273 }
4274 else if (aFlag == "-scale")
7c8a8fcc 4275 {
536d98e2 4276 if (++anArgIter >= theArgNb)
4277 {
23fe70ec 4278 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4279 return 1;
4280 }
4281
4282 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 4283 }
536d98e2 4284 else if (aFlag == "-size"
4285 || aFlag == "-sizeratio")
4286 {
4287 if (++anArgIter >= theArgNb)
4288 {
23fe70ec 4289 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4290 return 1;
4291 }
7c8a8fcc 4292
536d98e2 4293 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
4294 }
4295 else if (aFlag == "-arrowdiam"
4296 || aFlag == "-arrowdiameter")
4297 {
4298 if (++anArgIter >= theArgNb)
4299 {
23fe70ec 4300 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4301 return 1;
4302 }
7c8a8fcc 4303
536d98e2 4304 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
4305 }
4306 else if (aFlag == "-nbfacets")
4307 {
4308 if (++anArgIter >= theArgNb)
4309 {
23fe70ec 4310 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4311 return 1;
4312 }
7c8a8fcc 4313
536d98e2 4314 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
4315 }
4316 else if (aFlag == "-colorlabel"
0aeb8984 4317 || aFlag == "-colorlabels"
4318 || aFlag == "-colorlabelx"
4319 || aFlag == "-colorlabely"
4320 || aFlag == "-colorlabelz"
4321 || aFlag == "-colorarrowx"
4322 || aFlag == "-colorarrowy"
4323 || aFlag == "-colorarrowz")
7c8a8fcc 4324 {
0aeb8984 4325 Quantity_Color aColor;
dae2a922 4326 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4327 theArgVec + anArgIter + 1,
0aeb8984 4328 aColor);
536d98e2 4329 if (aNbParsed == 0)
4330 {
23fe70ec 4331 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4332 return 1;
4333 }
0aeb8984 4334
4335 if (aFlag == "-colorarrowx")
536d98e2 4336 {
0aeb8984 4337 anArrowColorX = aColor;
536d98e2 4338 }
0aeb8984 4339 else if (aFlag == "-colorarrowy")
536d98e2 4340 {
0aeb8984 4341 anArrowColorY = aColor;
536d98e2 4342 }
0aeb8984 4343 else if (aFlag == "-colorarrowz")
536d98e2 4344 {
0aeb8984 4345 anArrowColorZ = aColor;
4346 }
4347 else if (aFlag == "-colorlabelx")
4348 {
4349 aLabelsColorX = aColor;
4350 }
4351 else if (aFlag == "-colorlabely")
4352 {
4353 aLabelsColorY = aColor;
4354 }
4355 else if (aFlag == "-colorlabelz")
4356 {
4357 aLabelsColorZ = aColor;
4358 }
4359 else
4360 {
4361 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
536d98e2 4362 }
4363 anArgIter += aNbParsed;
4364 }
4365 else
4366 {
23fe70ec 4367 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
7c8a8fcc 4368 return 1;
4369 }
7c8a8fcc 4370 }
4371
0aeb8984 4372 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
4373 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
4374 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
4375 aTrihedron->SetSizeRatio (aSizeRatio);
4376 aTrihedron->SetNbFacets (aNbFacets);
4377 aTrihedron->SetArrowDiameter(anArrowDiam);
4378 aTrihedron->SetScale (aScale);
4379 aTrihedron->SetPosition (aPosition);
4380 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
4381 aTrihedron->Display (aView);
4382
c357e426 4383 aView->ZFitAll();
7fd59977 4384 return 0;
4385}
4386
4387//==============================================================================
4388//function : VRotate
4389//purpose : Camera Rotating
4390//==============================================================================
4391
4af098ba 4392static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4393{
4394 Handle(V3d_View) aView = ViewerTest::CurrentView();
4395 if (aView.IsNull())
4396 {
23fe70ec 4397 Message::SendFail ("Error: no active viewer");
7fd59977 4398 return 1;
4399 }
4400
4af098ba 4401 Standard_Boolean hasFlags = Standard_False;
4402 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4403 {
4404 Standard_CString anArg (theArgVec[anArgIter]);
4405 TCollection_AsciiString aFlag (anArg);
4406 aFlag.LowerCase();
4407 if (aFlag == "-mousestart"
4408 || aFlag == "-mousefrom")
4409 {
4410 hasFlags = Standard_True;
4411 if (anArgIter + 2 >= theArgNb)
4412 {
23fe70ec 4413 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4414 return 1;
4415 }
4416
4417 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4418 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4419 aView->StartRotation (anX, anY);
4420 }
4421 else if (aFlag == "-mousemove")
4422 {
4423 hasFlags = Standard_True;
4424 if (anArgIter + 2 >= theArgNb)
4425 {
23fe70ec 4426 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4427 return 1;
4428 }
4429
4430 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4431 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4432 aView->Rotation (anX, anY);
4433 }
4434 else if (theArgNb != 4
4435 && theArgNb != 7)
4436 {
23fe70ec 4437 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4438 return 1;
4439 }
4440 }
4441
4442 if (hasFlags)
4443 {
7fd59977 4444 return 0;
4af098ba 4445 }
4446 else if (theArgNb == 4)
4447 {
4448 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4449 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4450 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4451 aView->Rotate (anAX, anAY, anAZ);
4452 return 0;
4453 }
4454 else if (theArgNb == 7)
4455 {
4456 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4457 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4458 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4459
4460 Standard_Real anX = Draw::Atof (theArgVec[4]);
4461 Standard_Real anY = Draw::Atof (theArgVec[5]);
4462 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4463
4464 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4465 return 0;
7fd59977 4466 }
4af098ba 4467
23fe70ec 4468 Message::SendFail ("Error: Invalid number of arguments");
4af098ba 4469 return 1;
7fd59977 4470}
4471
4472//==============================================================================
4473//function : VZoom
4474//purpose : View zoom in / out (relative to current zoom)
4475//==============================================================================
4476
4477static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4478 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4479 if ( V3dView.IsNull() ) {
4480 return 1;
4481 }
4482
4483 if ( argc == 2 ) {
91322f44 4484 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4485 if ( coef <= 0.0 ) {
586db386 4486 di << argv[1] << "Invalid value\n";
7fd59977 4487 return 1;
4488 }
91322f44 4489 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4490 return 0;
4491 } else {
586db386 4492 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4493 return 1;
4494 }
4495}
4496
4497//==============================================================================
4498//function : VPan
4499//purpose : View panning (in pixels)
4500//==============================================================================
4501
4502static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4503 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4504 if ( V3dView.IsNull() ) return 1;
4505
4506 if ( argc == 3 ) {
91322f44 4507 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4508 return 0;
4509 } else {
586db386 4510 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4511 return 1;
4512 }
4513}
4514
49e1a5c7 4515//==============================================================================
4516//function : VPlace
4517//purpose : Place the point (in pixels) at the center of the window
4518//==============================================================================
4519static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4520{
4521 Handle(V3d_View) aView = ViewerTest::CurrentView();
4522 if (aView.IsNull())
4523 {
23fe70ec 4524 Message::SendFail ("Error: no active viewer");
49e1a5c7 4525 return 1;
4526 }
4527
4528 if (theArgNb != 3)
4529 {
23fe70ec 4530 Message::SendFail ("Syntax error: wrong number of arguments");
49e1a5c7 4531 return 1;
4532 }
4533
4534 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4535
4536 return 0;
4537}
7fd59977 4538
71215351 4539static int VColorScale (Draw_Interpretor& theDI,
4540 Standard_Integer theArgNb,
4541 const char** theArgVec)
4542{
7fd59977 4543 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4544 Handle(V3d_View) aView = ViewerTest::CurrentView();
4545 if (aContext.IsNull())
4546 {
23fe70ec 4547 Message::SendFail ("Error: no active viewer");
71215351 4548 return 1;
7fd59977 4549 }
24a88697 4550 if (theArgNb <= 1)
4551 {
23fe70ec 4552 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
24a88697 4553 return 1;
4554 }
7fd59977 4555
4b3d6eb1 4556 Handle(AIS_ColorScale) aColorScale;
7a324550 4557 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4558 {
4b3d6eb1 4559 // find existing object
4560 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4561 if (aColorScale.IsNull())
7a324550 4562 {
23fe70ec 4563 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
7a324550 4564 return 1;
4565 }
4566 }
71215351 4567
7a324550 4568 if (theArgNb <= 2)
4569 {
4b3d6eb1 4570 if (aColorScale.IsNull())
4571 {
23fe70ec 4572 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4b3d6eb1 4573 return 1;
4574 }
4575
7a324550 4576 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4577 << "Min range: " << aColorScale->GetMin() << "\n"
4578 << "Max range: " << aColorScale->GetMax() << "\n"
4579 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4580 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4581 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4582 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4583 << "Label position: ";
4b3d6eb1 4584 switch (aColorScale->GetLabelPosition())
71215351 4585 {
4586 case Aspect_TOCSP_NONE:
4587 theDI << "None\n";
4588 break;
4589 case Aspect_TOCSP_LEFT:
4590 theDI << "Left\n";
4591 break;
4592 case Aspect_TOCSP_RIGHT:
4593 theDI << "Right\n";
4594 break;
4595 case Aspect_TOCSP_CENTER:
4596 theDI << "Center\n";
4597 break;
4598 }
4599 return 0;
4600 }
71215351 4601
4b3d6eb1 4602 if (aColorScale.IsNull())
4603 {
4604 aColorScale = new AIS_ColorScale();
4605 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4606 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4607 }
4608
4609 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4610 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4611 {
4612 Standard_CString anArg = theArgVec[anArgIter];
4613 TCollection_AsciiString aFlag (anArg);
4614 aFlag.LowerCase();
4615 if (anUpdateTool.parseRedrawMode (aFlag))
4616 {
4617 continue;
4618 }
4619 else if (aFlag == "-range")
4620 {
4621 if (anArgIter + 3 >= theArgNb)
4622 {
23fe70ec 4623 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
71215351 4624 return 1;
4625 }
4626
4b3d6eb1 4627 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4628 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4629 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
d45edf24 4630 if (!aRangeMin.IsRealValue (Standard_True)
4631 || !aRangeMax.IsRealValue (Standard_True))
71215351 4632 {
23fe70ec 4633 Message::SendFail ("Syntax error: the range values should be real");
71215351 4634 return 1;
4635 }
4b3d6eb1 4636 else if (!aNbIntervals.IsIntegerValue())
71215351 4637 {
23fe70ec 4638 Message::SendFail ("Syntax error: the number of intervals should be integer");
71215351 4639 return 1;
4640 }
4641
4b3d6eb1 4642 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4643 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4644 }
4645 else if (aFlag == "-font")
4646 {
4647 if (anArgIter + 1 >= theArgNb)
4648 {
23fe70ec 4649 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4650 return 1;
4651 }
51740958 4652 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4653 if (!aFontArg.IsIntegerValue())
71215351 4654 {
23fe70ec 4655 Message::SendFail ("Syntax error: HeightFont value should be integer");
71215351 4656 return 1;
4657 }
4658
4b3d6eb1 4659 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4660 anArgIter += 1;
4661 }
4662 else if (aFlag == "-textpos")
4663 {
4664 if (anArgIter + 1 >= theArgNb)
4665 {
23fe70ec 4666 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4667 return 1;
4668 }
4b3d6eb1 4669
51740958 4670 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4671 aTextPosArg.LowerCase();
4b3d6eb1 4672 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4673 if (aTextPosArg == "none")
71215351 4674 {
4675 aLabPosition = Aspect_TOCSP_NONE;
4676 }
51740958 4677 else if (aTextPosArg == "left")
71215351 4678 {
4679 aLabPosition = Aspect_TOCSP_LEFT;
4680 }
51740958 4681 else if (aTextPosArg == "right")
71215351 4682 {
4683 aLabPosition = Aspect_TOCSP_RIGHT;
4684 }
51740958 4685 else if (aTextPosArg == "center")
71215351 4686 {
4687 aLabPosition = Aspect_TOCSP_CENTER;
4688 }
4689 else
4690 {
23fe70ec 4691 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
71215351 4692 return 1;
4693 }
4b3d6eb1 4694 aColorScale->SetLabelPosition (aLabPosition);
71215351 4695 }
24a88697 4696 else if (aFlag == "-logarithmic"
4697 || aFlag == "-log")
4698 {
4699 if (anArgIter + 1 >= theArgNb)
4700 {
23fe70ec 4701 Message::SendFail() << "Synta error at argument '" << anArg << "'";
24a88697 4702 return 1;
4703 }
4b3d6eb1 4704
24a88697 4705 Standard_Boolean IsLog;
dae2a922 4706 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
24a88697 4707 {
23fe70ec 4708 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
24a88697 4709 return 1;
4710 }
4b3d6eb1 4711 aColorScale->SetLogarithmic (IsLog);
4712 }
4713 else if (aFlag == "-huerange"
4714 || aFlag == "-hue")
4715 {
4716 if (anArgIter + 2 >= theArgNb)
4717 {
23fe70ec 4718 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4719 return 1;
4720 }
4721
4722 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4723 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4724 aColorScale->SetHueRange (aHueMin, aHueMax);
4725 }
4726 else if (aFlag == "-colorrange")
4727 {
4728 Quantity_Color aColorMin, aColorMax;
dae2a922 4729 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4730 theArgVec + (anArgIter + 1),
4731 aColorMin);
4b3d6eb1 4732 anArgIter += aNbParsed1;
dae2a922 4733 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4734 theArgVec + (anArgIter + 1),
4735 aColorMax);
4b3d6eb1 4736 anArgIter += aNbParsed2;
4737 if (aNbParsed1 == 0
4738 || aNbParsed2 == 0)
4739 {
23fe70ec 4740 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4b3d6eb1 4741 return 1;
4742 }
4743
4744 aColorScale->SetColorRange (aColorMin, aColorMax);
4745 }
4746 else if (aFlag == "-reversed"
4747 || aFlag == "-inverted"
4748 || aFlag == "-topdown"
4749 || aFlag == "-bottomup")
4750 {
4751 Standard_Boolean toEnable = Standard_True;
4752 if (anArgIter + 1 < theArgNb
dae2a922 4753 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4754 {
4755 ++anArgIter;
4756 }
4757 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4758 }
4759 else if (aFlag == "-smooth"
4760 || aFlag == "-smoothtransition")
4761 {
4762 Standard_Boolean toEnable = Standard_True;
4763 if (anArgIter + 1 < theArgNb
dae2a922 4764 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4765 {
4766 ++anArgIter;
4767 }
4768 aColorScale->SetSmoothTransition (toEnable);
24a88697 4769 }
71215351 4770 else if (aFlag == "-xy")
4771 {
4772 if (anArgIter + 2 >= theArgNb)
4773 {
23fe70ec 4774 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4775 return 1;
4776 }
4777
4b3d6eb1 4778 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4779 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4780 if (!anX.IsIntegerValue()
4781 || !anY.IsIntegerValue())
71215351 4782 {
23fe70ec 4783 Message::SendFail ("Syntax error: coordinates should be integer values");
71215351 4784 return 1;
4785 }
4786
4b3d6eb1 4787 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4788 }
4789 else if (aFlag == "-width"
4b3d6eb1 4790 || aFlag == "-w"
4791 || aFlag == "-breadth")
b4b2ecca 4792 {
4793 if (anArgIter + 1 >= theArgNb)
4794 {
23fe70ec 4795 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4796 return 1;
4797 }
4798
4b3d6eb1 4799 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4800 if (!aBreadth.IsIntegerValue())
b4b2ecca 4801 {
23fe70ec 4802 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4803 return 1;
4804 }
4b3d6eb1 4805 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4806 }
4807 else if (aFlag == "-height"
4808 || aFlag == "-h")
4809 {
4810 if (anArgIter + 1 >= theArgNb)
4811 {
23fe70ec 4812 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4813 return 1;
4814 }
4815
4b3d6eb1 4816 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4817 if (!aHeight.IsIntegerValue())
b4b2ecca 4818 {
23fe70ec 4819 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4820 return 1;
4821 }
4b3d6eb1 4822 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4823 }
4824 else if (aFlag == "-color")
4825 {
4b3d6eb1 4826 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4827 {
23fe70ec 4828 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
71215351 4829 return 1;
4830 }
4b3d6eb1 4831 else if (anArgIter + 2 >= theArgNb)
71215351 4832 {
23fe70ec 4833 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4834 return 1;
71215351 4835 }
4836
4b3d6eb1 4837 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 4838 if (!anInd.IsIntegerValue())
4839 {
23fe70ec 4840 Message::SendFail ("Syntax error: Index value should be integer");
71215351 4841 return 1;
4842 }
4b3d6eb1 4843 const Standard_Integer anIndex = anInd.IntegerValue();
4844 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 4845 {
23fe70ec 4846 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
71215351 4847 return 1;
4848 }
4849
4b3d6eb1 4850 Quantity_Color aColor;
dae2a922 4851 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4852 theArgVec + (anArgIter + 1),
4853 aColor);
4b3d6eb1 4854 if (aNbParsed == 0)
71215351 4855 {
23fe70ec 4856 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
71215351 4857 return 1;
4858 }
4b3d6eb1 4859 aColorScale->SetIntervalColor (aColor, anIndex);
4860 aColorScale->SetColorType (Aspect_TOCSD_USER);
4861 anArgIter += aNbParsed;
71215351 4862 }
4863 else if (aFlag == "-label")
4864 {
4b3d6eb1 4865 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4866 {
23fe70ec 4867 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
71215351 4868 return 1;
4869 }
4870 else if (anArgIter + 2 >= theArgNb)
4871 {
23fe70ec 4872 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4873 return 1;
4874 }
4875
4876 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 4877 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 4878 {
23fe70ec 4879 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
71215351 4880 return 1;
4881 }
4882
94f16a89 4883 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4b3d6eb1 4884 aColorScale->SetLabel (aText, anIndex);
4885 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4886 anArgIter += 2;
4887 }
4b3d6eb1 4888 else if (aFlag == "-labelat"
4889 || aFlag == "-labat"
4890 || aFlag == "-labelatborder"
4891 || aFlag == "-labatborder"
4892 || aFlag == "-labelatcenter"
4893 || aFlag == "-labatcenter")
71215351 4894 {
4b3d6eb1 4895 Standard_Boolean toEnable = Standard_True;
4896 if (aFlag == "-labelat"
4897 || aFlag == "-labat")
71215351 4898 {
4b3d6eb1 4899 Standard_Integer aLabAtBorder = -1;
4900 if (++anArgIter >= theArgNb)
71215351 4901 {
4b3d6eb1 4902 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4903 anAtBorder.LowerCase();
4904 if (anAtBorder == "border")
71215351 4905 {
4b3d6eb1 4906 aLabAtBorder = 1;
71215351 4907 }
4b3d6eb1 4908 else if (anAtBorder == "center")
71215351 4909 {
4b3d6eb1 4910 aLabAtBorder = 0;
71215351 4911 }
71215351 4912 }
4b3d6eb1 4913 if (aLabAtBorder == -1)
4914 {
23fe70ec 4915 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4916 return 1;
4917 }
4918 toEnable = (aLabAtBorder == 1);
4919 }
4920 else if (anArgIter + 1 < theArgNb
dae2a922 4921 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4922 {
4923 ++anArgIter;
71215351 4924 }
4b3d6eb1 4925 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4926 || aFlag == "-labatcenter"
4927 ? !toEnable
4928 : toEnable);
4929 }
4930 else if (aFlag == "-colors")
4931 {
4932 Aspect_SequenceOfColor aSeq;
4933 for (;;)
4934 {
4935 Quantity_Color aColor;
dae2a922 4936 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4937 theArgVec + (anArgIter + 1),
4938 aColor);
4b3d6eb1 4939 if (aNbParsed == 0)
4940 {
4941 break;
4942 }
4943 anArgIter += aNbParsed;
4944 aSeq.Append (aColor);
4945 }
4946 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 4947 {
23fe70ec 4948 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4949 << aColorScale->GetNumberOfIntervals() << " intervals";
71215351 4950 return 1;
4951 }
4952
4b3d6eb1 4953 aColorScale->SetColors (aSeq);
4954 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 4955 }
14b741b0 4956 else if (aFlag == "-uniform")
4957 {
4958 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4959 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4960 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4961 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4962 aColorScale->SetColorType (Aspect_TOCSD_USER);
4963 }
4b3d6eb1 4964 else if (aFlag == "-labels"
4965 || aFlag == "-freelabels")
71215351 4966 {
4b3d6eb1 4967 if (anArgIter + 1 >= theArgNb)
4968 {
23fe70ec 4969 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4970 return 1;
4971 }
4972
4973 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4974 ? aColorScale->GetNumberOfIntervals() + 1
4975 : aColorScale->GetNumberOfIntervals();
4976 if (aFlag == "-freelabels")
4977 {
4978 ++anArgIter;
4979 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4980 }
4981 if (anArgIter + aNbLabels >= theArgNb)
71215351 4982 {
23fe70ec 4983 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
71215351 4984 return 1;
4985 }
4986
4987 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 4988 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 4989 {
94f16a89 4990 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
71215351 4991 }
4b3d6eb1 4992 aColorScale->SetLabels (aSeq);
4993 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4994 }
4995 else if (aFlag == "-title")
4996 {
4997 if (anArgIter + 1 >= theArgNb)
4998 {
23fe70ec 4999 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 5000 return 1;
5001 }
5002
5003 Standard_Boolean isTwoArgs = Standard_False;
5004 if (anArgIter + 2 < theArgNb)
5005 {
5006 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
5007 aSecondArg.LowerCase();
4b3d6eb1 5008 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 5009 if (aSecondArg == "none")
5010 {
4b3d6eb1 5011 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 5012 isTwoArgs = Standard_True;
5013 }
5014 else if (aSecondArg == "left")
5015 {
4b3d6eb1 5016 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 5017 isTwoArgs = Standard_True;
5018 }
5019 else if (aSecondArg == "right")
5020 {
4b3d6eb1 5021 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 5022 isTwoArgs = Standard_True;
5023 }
5024 else if (aSecondArg == "center")
5025 {
4b3d6eb1 5026 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 5027 isTwoArgs = Standard_True;
5028 }
4b3d6eb1 5029 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 5030 }
5031
94f16a89 5032 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
5033 aColorScale->SetTitle (aTitle);
71215351 5034 if (isTwoArgs)
5035 {
5036 anArgIter += 1;
5037 }
5038 anArgIter += 1;
5039 }
5040 else if (aFlag == "-demoversion"
5041 || aFlag == "-demo")
5042 {
4b3d6eb1 5043 aColorScale->SetPosition (0, 0);
5044 aColorScale->SetTextHeight (16);
5045 aColorScale->SetRange (0.0, 100.0);
5046 aColorScale->SetNumberOfIntervals (10);
5047 aColorScale->SetBreadth (0);
5048 aColorScale->SetHeight (0);
5049 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
5050 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
5051 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 5052 }
d5514578 5053 else if (aFlag == "-findcolor")
5054 {
5055 if (anArgIter + 1 >= theArgNb)
5056 {
23fe70ec 5057 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
d5514578 5058 return 1;
5059 }
5060
5061 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
5062
d45edf24 5063 if (!anArg1.IsRealValue (Standard_True))
d5514578 5064 {
23fe70ec 5065 Message::SendFail ("Syntax error: the value should be real");
d5514578 5066 return 1;
5067 }
5068
5069 Quantity_Color aColor;
4b3d6eb1 5070 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 5071 theDI << Quantity_Color::StringName (aColor.Name());
5072 return 0;
5073 }
71215351 5074 else
5075 {
23fe70ec 5076 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
71215351 5077 return 1;
5078 }
5079 }
4b3d6eb1 5080
5081 Standard_Integer aWinWidth = 0, aWinHeight = 0;
5082 aView->Window()->Size (aWinWidth, aWinHeight);
5083 if (aColorScale->GetBreadth() == 0)
b4b2ecca 5084 {
4b3d6eb1 5085 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 5086 }
4b3d6eb1 5087 if (aColorScale->GetHeight() == 0)
5088 {
5089 aColorScale->SetHeight (aWinHeight);
5090 }
5091 aColorScale->SetToUpdate();
5092 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 5093 return 0;
5094}
5095
5096//==============================================================================
5097//function : VGraduatedTrihedron
a79f67f8 5098//purpose : Displays or hides a graduated trihedron
7fd59977 5099//==============================================================================
a79f67f8 5100static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
5101 Quantity_Color& theColor)
13a22457 5102{
a79f67f8 5103 Quantity_NameOfColor aColorName;
5104 TCollection_AsciiString aVal = theValue;
5105 aVal.UpperCase();
5106 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 5107 {
a79f67f8 5108 return Standard_False;
13a22457 5109 }
a79f67f8 5110 theColor = Quantity_Color (aColorName);
5111 return Standard_True;
13a22457
S
5112}
5113
a79f67f8 5114static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 5115{
a79f67f8 5116 if (theArgNum < 2)
13a22457 5117 {
23fe70ec 5118 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
5119 << theArgs[0] <<"' for more information";
5120 return 1;
13a22457 5121 }
7fd59977 5122
a79f67f8 5123 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
5124 TCollection_AsciiString aParseKey;
5125 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
5126 {
5127 TCollection_AsciiString anArg (theArgs [anArgIt]);
5128
d45edf24 5129 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
a79f67f8 5130 {
5131 aParseKey = anArg;
5132 aParseKey.Remove (1);
5133 aParseKey.LowerCase();
5134 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
5135 continue;
5136 }
13a22457 5137
a79f67f8 5138 if (aParseKey.IsEmpty())
5139 {
5140 continue;
5141 }
5142
5143 aMapOfArgs(aParseKey)->Append (anArg);
5144 }
5145
5146 // Check parameters
5147 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
5148 aMapIt.More(); aMapIt.Next())
7fd59977 5149 {
a79f67f8 5150 const TCollection_AsciiString& aKey = aMapIt.Key();
5151 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
5152
5153 // Bool key, without arguments
5154 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
5155 && anArgs->IsEmpty())
5156 {
5157 continue;
5158 }
5159
5160 // One argument
5161 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
5162 && anArgs->Length() == 1)
5163 {
5164 continue;
5165 }
5166
5167 // On/off arguments
5168 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
5169 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 5170 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
5171 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 5172 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
5173 {
5174 continue;
5175 }
5176
5177 // One string argument
5178 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
5179 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
d45edf24 5180 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
a79f67f8 5181 {
5182 continue;
5183 }
5184
5185 // One integer argument
5186 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
5187 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
5188 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
5189 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
5190 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
5191 {
5192 continue;
5193 }
5194
5195 // One real argument
5196 if ( aKey.IsEqual ("arrowlength")
d45edf24 5197 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
a79f67f8 5198 {
5199 continue;
5200 }
5201
5202 // Two string arguments
5203 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
d45edf24 5204 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
13a22457 5205 {
a79f67f8 5206 continue;
13a22457 5207 }
a79f67f8 5208
5209 TCollection_AsciiString aLowerKey;
5210 aLowerKey = "-";
5211 aLowerKey += aKey;
5212 aLowerKey.LowerCase();
23fe70ec 5213 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
5214 << "Type help for more information";
a79f67f8 5215 return 1;
7fd59977 5216 }
5217
a79f67f8 5218 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5219 if (anAISContext.IsNull())
5220 {
23fe70ec 5221 Message::SendFail ("Error: no active viewer");
a79f67f8 5222 return 1;
5223 }
7fd59977 5224
a79f67f8 5225 Standard_Boolean toDisplay = Standard_True;
5226 Quantity_Color aColor;
5227 Graphic3d_GraduatedTrihedron aTrihedronData;
5228 // Process parameters
5229 Handle(TColStd_HSequenceOfAsciiString) aValues;
5230 if (aMapOfArgs.Find ("off", aValues))
7fd59977 5231 {
a79f67f8 5232 toDisplay = Standard_False;
5233 }
13a22457 5234
a79f67f8 5235 // AXES NAMES
5236 if (aMapOfArgs.Find ("xname", aValues))
5237 {
5238 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
5239 }
5240 if (aMapOfArgs.Find ("yname", aValues))
5241 {
5242 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
5243 }
5244 if (aMapOfArgs.Find ("zname", aValues))
5245 {
5246 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
5247 }
5248 if (aMapOfArgs.Find ("xdrawname", aValues))
5249 {
536d98e2 5250 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5251 }
5252 if (aMapOfArgs.Find ("ydrawname", aValues))
5253 {
536d98e2 5254 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5255 }
5256 if (aMapOfArgs.Find ("zdrawname", aValues))
5257 {
536d98e2 5258 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5259 }
5260 if (aMapOfArgs.Find ("xnameoffset", aValues))
5261 {
5262 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5263 }
5264 if (aMapOfArgs.Find ("ynameoffset", aValues))
5265 {
5266 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5267 }
5268 if (aMapOfArgs.Find ("znameoffset", aValues))
5269 {
5270 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5271 }
13a22457 5272
a79f67f8 5273 // COLORS
5274 if (aMapOfArgs.Find ("xnamecolor", aValues))
5275 {
5276 if (!GetColor (aValues->Value(1), aColor))
13a22457 5277 {
23fe70ec 5278 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
a79f67f8 5279 return 1;
13a22457 5280 }
a79f67f8 5281 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
5282 }
5283 if (aMapOfArgs.Find ("ynamecolor", aValues))
5284 {
5285 if (!GetColor (aValues->Value(1), aColor))
13a22457 5286 {
23fe70ec 5287 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
a79f67f8 5288 return 1;
5289 }
5290 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
5291 }
5292 if (aMapOfArgs.Find ("znamecolor", aValues))
5293 {
5294 if (!GetColor (aValues->Value(1), aColor))
5295 {
23fe70ec 5296 Message::SendFail ("Syntax error: -znamecolor wrong color name");
a79f67f8 5297 return 1;
5298 }
5299 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
5300 }
5301 if (aMapOfArgs.Find ("xcolor", aValues))
5302 {
5303 if (!GetColor (aValues->Value(1), aColor))
5304 {
23fe70ec 5305 Message::SendFail ("Syntax error: -xcolor wrong color name");
a79f67f8 5306 return 1;
5307 }
5308 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
5309 }
5310 if (aMapOfArgs.Find ("ycolor", aValues))
5311 {
5312 if (!GetColor (aValues->Value(1), aColor))
5313 {
23fe70ec 5314 Message::SendFail ("Syntax error: -ycolor wrong color name");
a79f67f8 5315 return 1;
5316 }
5317 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
5318 }
5319 if (aMapOfArgs.Find ("zcolor", aValues))
5320 {
5321 if (!GetColor (aValues->Value(1), aColor))
5322 {
23fe70ec 5323 Message::SendFail ("Syntax error: -zcolor wrong color name");
a79f67f8 5324 return 1;
5325 }
5326 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
5327 }
5328
5329 // TICKMARKS
5330 if (aMapOfArgs.Find ("xticks", aValues))
5331 {
536d98e2 5332 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5333 }
5334 if (aMapOfArgs.Find ("yticks", aValues))
5335 {
536d98e2 5336 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5337 }
5338 if (aMapOfArgs.Find ("zticks", aValues))
5339 {
536d98e2 5340 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5341 }
5342 if (aMapOfArgs.Find ("xticklength", aValues))
5343 {
536d98e2 5344 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5345 }
5346 if (aMapOfArgs.Find ("yticklength", aValues))
5347 {
536d98e2 5348 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5349 }
5350 if (aMapOfArgs.Find ("zticklength", aValues))
5351 {
536d98e2 5352 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5353 }
5354 if (aMapOfArgs.Find ("xdrawticks", aValues))
5355 {
536d98e2 5356 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5357 }
5358 if (aMapOfArgs.Find ("ydrawticks", aValues))
5359 {
536d98e2 5360 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5361 }
5362 if (aMapOfArgs.Find ("zdrawticks", aValues))
5363 {
536d98e2 5364 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5365 }
5366
5367 // VALUES
5368 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5369 {
536d98e2 5370 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5371 }
5372 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5373 {
536d98e2 5374 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5375 }
5376 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5377 {
536d98e2 5378 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5379 }
5380 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5381 {
5382 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5383 }
5384 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5385 {
5386 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5387 }
5388 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5389 {
5390 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5391 }
5392
5393 // ARROWS
5394 if (aMapOfArgs.Find ("arrowlength", aValues))
5395 {
536d98e2 5396 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5397 }
5398
5399 // FONTS
5400 if (aMapOfArgs.Find ("namefont", aValues))
5401 {
5402 aTrihedronData.SetNamesFont (aValues->Value(1));
5403 }
5404 if (aMapOfArgs.Find ("valuesfont", aValues))
5405 {
5406 aTrihedronData.SetValuesFont (aValues->Value(1));
5407 }
5408
536d98e2 5409 if (aMapOfArgs.Find ("drawgrid", aValues))
5410 {
5411 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5412 }
5413 if (aMapOfArgs.Find ("drawaxes", aValues))
5414 {
5415 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5416 }
5417
a79f67f8 5418 // The final step: display of erase trihedron
5419 if (toDisplay)
5420 {
5421 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5422 }
7fd59977 5423 else
a79f67f8 5424 {
5425 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5426 }
7fd59977 5427
5428 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5429 ViewerTest::CurrentView()->Redraw();
13a22457 5430
7fd59977 5431 return 0;
5432}
5433
3bffef55 5434//==============================================================================
5435//function : VTile
5436//purpose :
5437//==============================================================================
5438static int VTile (Draw_Interpretor& theDI,
5439 Standard_Integer theArgNb,
5440 const char** theArgVec)
5441{
5442 Handle(V3d_View) aView = ViewerTest::CurrentView();
5443 if (aView.IsNull())
5444 {
23fe70ec 5445 Message::SendFail ("Error: no active viewer");
3bffef55 5446 return 1;
5447 }
5448
5449 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5450 if (theArgNb < 2)
5451 {
5452 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5453 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5454 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5455 return 0;
5456 }
5457
5458 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5459 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5460 {
5461 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5462 anArg.LowerCase();
5463 if (anArg == "-lowerleft"
5464 || anArg == "-upperleft")
5465 {
5466 if (anArgIter + 3 < theArgNb)
5467 {
23fe70ec 5468 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5469 return 1;
5470 }
5471 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5472 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5473 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5474 }
5475 else if (anArg == "-total"
5476 || anArg == "-totalsize"
5477 || anArg == "-viewsize")
5478 {
5479 if (anArgIter + 3 < theArgNb)
5480 {
23fe70ec 5481 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5482 return 1;
5483 }
5484 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5485 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5486 if (aTile.TotalSize.x() < 1
5487 || aTile.TotalSize.y() < 1)
5488 {
23fe70ec 5489 Message::SendFail ("Error: total size is incorrect");
3bffef55 5490 return 1;
5491 }
5492 }
5493 else if (anArg == "-tilesize")
5494 {
5495 if (anArgIter + 3 < theArgNb)
5496 {
23fe70ec 5497 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5498 return 1;
5499 }
5500
5501 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5502 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5503 if (aTile.TileSize.x() < 1
5504 || aTile.TileSize.y() < 1)
5505 {
23fe70ec 5506 Message::SendFail ("Error: tile size is incorrect");
3bffef55 5507 return 1;
5508 }
5509 }
5510 else if (anArg == "-unset")
5511 {
5512 aView->Camera()->SetTile (Graphic3d_CameraTile());
5513 aView->Redraw();
5514 return 0;
5515 }
5516 }
5517
5518 if (aTile.TileSize.x() < 1
5519 || aTile.TileSize.y() < 1)
5520 {
23fe70ec 5521 Message::SendFail ("Error: tile size is undefined");
3bffef55 5522 return 1;
5523 }
5524 else if (aTile.TotalSize.x() < 1
5525 || aTile.TotalSize.y() < 1)
5526 {
23fe70ec 5527 Message::SendFail ("Error: total size is undefined");
3bffef55 5528 return 1;
5529 }
5530
5531 aView->Camera()->SetTile (aTile);
5532 aView->Redraw();
5533 return 0;
5534}
5535
7c3ef2f7 5536//! Format ZLayer ID.
5537inline const char* formZLayerId (const Standard_Integer theLayerId)
5538{
5539 switch (theLayerId)
5540 {
5541 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5542 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5543 case Graphic3d_ZLayerId_Top: return "[TOP]";
5544 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5545 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5546 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5547 }
5548 return "";
5549}
5550
5551//! Print the ZLayer information.
5552inline void printZLayerInfo (Draw_Interpretor& theDI,
5553 const Graphic3d_ZLayerSettings& theLayer)
5554{
5555 if (!theLayer.Name().IsEmpty())
5556 {
5557 theDI << " Name: " << theLayer.Name() << "\n";
5558 }
5559 if (theLayer.IsImmediate())
5560 {
5561 theDI << " Immediate: TRUE\n";
5562 }
5563 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5564 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5565 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5566 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5567 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5568 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5569 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5570 {
5571 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5572 }
5573}
5574
59f45b7c 5575//==============================================================================
5576//function : VZLayer
5577//purpose : Test z layer operations for v3d viewer
5578//==============================================================================
7c3ef2f7 5579static int VZLayer (Draw_Interpretor& theDI,
5580 Standard_Integer theArgNb,
5581 const char** theArgVec)
59f45b7c 5582{
7c3ef2f7 5583 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5584 if (aContextAIS.IsNull())
5585 {
23fe70ec 5586 Message::SendFail ("Error: no active viewer");
59f45b7c 5587 return 1;
5588 }
5589
5590 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5591 if (theArgNb < 2)
59f45b7c 5592 {
7c3ef2f7 5593 TColStd_SequenceOfInteger aLayers;
5594 aViewer->GetAllZLayers (aLayers);
5595 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5596 {
5597 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5598 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5599 printZLayerInfo (theDI, aSettings);
5600 }
95bdefb2 5601 return 0;
59f45b7c 5602 }
5603
7c3ef2f7 5604 Standard_Integer anArgIter = 1;
5605 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5606 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5607 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5608 {
7c3ef2f7 5609 ++anArgIter;
5610 }
59f45b7c 5611
7c3ef2f7 5612 {
55c8f0f7
BB
5613 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5614 if (aFirstArg.IsIntegerValue())
c5751993 5615 {
7c3ef2f7 5616 ++anArgIter;
55c8f0f7 5617 aLayerId = aFirstArg.IntegerValue();
c5751993 5618 }
7c3ef2f7 5619 else
c5751993 5620 {
55c8f0f7 5621 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5622 {
55c8f0f7 5623 ++anArgIter;
7c3ef2f7 5624 }
c5751993 5625 }
7c3ef2f7 5626 }
c5751993 5627
1c728f2d 5628 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
7c3ef2f7 5629 for (; anArgIter < theArgNb; ++anArgIter)
5630 {
5631 // perform operation
5632 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5633 anArg.LowerCase();
5634 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5635 {
7c3ef2f7 5636 //
c5751993 5637 }
7c3ef2f7 5638 else if (anArg == "-add"
5639 || anArg == "add")
c5751993 5640 {
7c3ef2f7 5641 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5642 if (!aViewer->AddZLayer (aLayerId))
5643 {
23fe70ec 5644 Message::SendFail ("Error: can not add a new z layer");
7c3ef2f7 5645 return 0;
5646 }
5647
5648 theDI << aLayerId;
c5751993 5649 }
1c728f2d 5650 else if (anArg == "-insertbefore"
5651 && anArgIter + 1 < theArgNb
5652 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5653 {
5654 ++anArgIter;
5655 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5656 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5657 {
23fe70ec 5658 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5659 return 0;
5660 }
5661
5662 theDI << aLayerId;
5663 }
5664 else if (anArg == "-insertafter"
5665 && anArgIter + 1 < theArgNb
5666 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5667 {
5668 ++anArgIter;
5669 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5670 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5671 {
23fe70ec 5672 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5673 return 0;
5674 }
5675
5676 theDI << aLayerId;
5677 }
7c3ef2f7 5678 else if (anArg == "-del"
5679 || anArg == "-delete"
5680 || anArg == "del")
c5751993 5681 {
7c3ef2f7 5682 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5683 {
5684 if (++anArgIter >= theArgNb)
5685 {
23fe70ec 5686 Message::SendFail ("Syntax error: id of z layer to remove is missing");
7c3ef2f7 5687 return 1;
5688 }
5689
5690 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5691 }
5692
5693 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5694 || aLayerId == Graphic3d_ZLayerId_Default
5695 || aLayerId == Graphic3d_ZLayerId_Top
5696 || aLayerId == Graphic3d_ZLayerId_Topmost
5697 || aLayerId == Graphic3d_ZLayerId_TopOSD
5698 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5699 {
23fe70ec 5700 Message::SendFail ("Syntax error: standard Z layer can not be removed");
7c3ef2f7 5701 return 1;
5702 }
5703
5704 // move all object displayed in removing layer to default layer
5705 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5706 anObjIter.More(); anObjIter.Next())
5707 {
8f521168 5708 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5709 if (aPrs.IsNull()
5710 || aPrs->ZLayer() != aLayerId)
5711 {
5712 continue;
5713 }
5714 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5715 }
5716
5717 if (!aViewer->RemoveZLayer (aLayerId))
5718 {
23fe70ec 5719 Message::SendFail ("Z layer can not be removed");
7c3ef2f7 5720 }
5721 else
5722 {
5723 theDI << aLayerId << " ";
5724 }
c5751993 5725 }
7c3ef2f7 5726 else if (anArg == "-get"
5727 || anArg == "get")
c5751993 5728 {
7c3ef2f7 5729 TColStd_SequenceOfInteger aLayers;
5730 aViewer->GetAllZLayers (aLayers);
5731 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5732 {
5733 theDI << aLayeriter.Value() << " ";
5734 }
5735
5736 theDI << "\n";
c5751993 5737 }
7c3ef2f7 5738 else if (anArg == "-name")
c5751993 5739 {
7c3ef2f7 5740 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5741 {
23fe70ec 5742 Message::SendFail ("Syntax error: id of Z layer is missing");
c5751993 5743 return 1;
5744 }
5745
7c3ef2f7 5746 if (++anArgIter >= theArgNb)
5747 {
23fe70ec 5748 Message::SendFail ("Syntax error: name is missing");
7c3ef2f7 5749 return 1;
5750 }
c5751993 5751
7c3ef2f7 5752 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5753 aSettings.SetName (theArgVec[anArgIter]);
5754 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5755 }
7c3ef2f7 5756 else if (anArg == "-origin")
c5751993 5757 {
7c3ef2f7 5758 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5759 {
23fe70ec 5760 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5761 return 1;
5762 }
5763
5764 if (anArgIter + 2 >= theArgNb)
5765 {
23fe70ec 5766 Message::SendFail ("Syntax error: origin coordinates are missing");
7c3ef2f7 5767 return 1;
5768 }
5769
5770 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5771 gp_XYZ anOrigin;
5772 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5773 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5774 anOrigin.SetZ (0.0);
5775 if (anArgIter + 3 < theArgNb)
5776 {
5777 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5778 anArgIter += 3;
5779 }
5780 else
5781 {
5782 anArgIter += 2;
5783 }
5784 aSettings.SetOrigin (anOrigin);
5785 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5786 }
4ecf34cc 5787 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5788 && anArgIter + 1 < theArgNb
5789 && (anArg == "-cullingdistance"
5790 || anArg == "-cullingdist"
5791 || anArg == "-culldistance"
5792 || anArg == "-culldist"
5793 || anArg == "-distcull"
5794 || anArg == "-distculling"
5795 || anArg == "-distanceculling"))
5796 {
5797 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5798 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5799 aSettings.SetCullingDistance (aDist);
5800 aViewer->SetZLayerSettings (aLayerId, aSettings);
5801 }
5802 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5803 && anArgIter + 1 < theArgNb
5804 && (anArg == "-cullingsize"
5805 || anArg == "-cullsize"
5806 || anArg == "-sizecull"
5807 || anArg == "-sizeculling"))
5808 {
5809 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5810 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5811 aSettings.SetCullingSize (aSize);
5812 aViewer->SetZLayerSettings (aLayerId, aSettings);
5813 }
7c3ef2f7 5814 else if (anArg == "-settings"
5815 || anArg == "settings")
c5751993 5816 {
7c3ef2f7 5817 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5818 {
5819 if (++anArgIter >= theArgNb)
5820 {
23fe70ec 5821 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5822 return 1;
5823 }
5824
5825 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5826 }
5827
5828 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5829 printZLayerInfo (theDI, aSettings);
c5751993 5830 }
7c3ef2f7 5831 else if (anArg == "-enable"
5832 || anArg == "enable"
5833 || anArg == "-disable"
5834 || anArg == "disable")
83da37b1 5835 {
7c3ef2f7 5836 const Standard_Boolean toEnable = anArg == "-enable"
5837 || anArg == "enable";
5838 if (++anArgIter >= theArgNb)
5839 {
23fe70ec 5840 Message::SendFail ("Syntax error: option name is missing");
7c3ef2f7 5841 return 1;
5842 }
c5751993 5843
7c3ef2f7 5844 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5845 aSubOp.LowerCase();
5846 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5847 {
5848 if (++anArgIter >= theArgNb)
5849 {
23fe70ec 5850 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5851 return 1;
5852 }
c5751993 5853
7c3ef2f7 5854 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5855 }
c5751993 5856
7c3ef2f7 5857 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5858 if (aSubOp == "depthtest"
5859 || aSubOp == "test")
5860 {
5861 aSettings.SetEnableDepthTest (toEnable);
5862 }
5863 else if (aSubOp == "depthwrite"
5864 || aSubOp == "write")
5865 {
5866 aSettings.SetEnableDepthWrite (toEnable);
5867 }
5868 else if (aSubOp == "depthclear"
5869 || aSubOp == "clear")
5870 {
5871 aSettings.SetClearDepth (toEnable);
5872 }
5873 else if (aSubOp == "depthoffset"
5874 || aSubOp == "offset")
5875 {
5876 Graphic3d_PolygonOffset aParams;
5877 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5878 if (toEnable)
5879 {
5880 if (anArgIter + 2 >= theArgNb)
5881 {
23fe70ec 5882 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
7c3ef2f7 5883 return 1;
5884 }
c5751993 5885
7c3ef2f7 5886 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5887 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5888 }
5889 aSettings.SetPolygonOffset (aParams);
5890 }
5891 else if (aSubOp == "positiveoffset"
5892 || aSubOp == "poffset")
5893 {
5894 if (toEnable)
5895 {
5896 aSettings.SetDepthOffsetPositive();
5897 }
5898 else
5899 {
5900 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5901 }
5902 }
5903 else if (aSubOp == "negativeoffset"
5904 || aSubOp == "noffset")
5905 {
5906 if (toEnable)
5907 {
5908 aSettings.SetDepthOffsetNegative();
5909 }
5910 else
5911 {
5912 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5913 }
5914 }
5915 else if (aSubOp == "textureenv")
5916 {
5917 aSettings.SetEnvironmentTexture (toEnable);
5918 }
1c728f2d 5919 else if (aSubOp == "raytracing")
5920 {
5921 aSettings.SetRaytracable (toEnable);
5922 }
7c3ef2f7 5923
5924 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5925 }
7c3ef2f7 5926 else
83da37b1 5927 {
23fe70ec 5928 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
7c3ef2f7 5929 return 1;
83da37b1 5930 }
59f45b7c 5931 }
5932
5933 return 0;
5934}
5935
c357e426 5936// The interactive presentation of 2d layer item
5937// for "vlayerline" command it provides a presentation of
5938// line with user-defined linewidth, linetype and transparency.
61b0191c 5939class V3d_LineItem : public AIS_InteractiveObject
20637bd2 5940{
5941public:
5942 // CASCADE RTTI
92efcf78 5943 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 5944
20637bd2 5945 // constructor
5946 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5947 Standard_Real X2, Standard_Real Y2,
20637bd2 5948 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5949 Standard_Real theWidth = 0.5,
5950 Standard_Real theTransp = 1.0);
5951
decbff0d 5952private:
61b0191c 5953
decbff0d 5954 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5955 const Handle(Prs3d_Presentation)& thePrs,
5956 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 5957
decbff0d 5958 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5959 const Standard_Integer ) Standard_OVERRIDE
79104795 5960 {}
20637bd2 5961
5962private:
5963
5964 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 5965 Aspect_TypeOfLine myType;
20637bd2 5966 Standard_Real myWidth;
20637bd2 5967};
5968
20637bd2 5969// default constructor for line item
4fe56619 5970V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 5971 Standard_Real X2, Standard_Real Y2,
20637bd2 5972 Aspect_TypeOfLine theType,
5973 Standard_Real theWidth,
5974 Standard_Real theTransp) :
61b0191c 5975 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5976 myType(theType), myWidth(theWidth)
20637bd2 5977{
61b0191c 5978 SetTransparency (1-theTransp);
20637bd2 5979}
5980
5981// render line
decbff0d 5982void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
61b0191c 5983 const Handle(Prs3d_Presentation)& thePresentation,
decbff0d 5984 const Standard_Integer )
20637bd2 5985{
61b0191c 5986 thePresentation->Clear();
ba00aab7 5987 Quantity_Color aColor (Quantity_NOC_RED);
61b0191c 5988 Standard_Integer aWidth, aHeight;
5989 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
d6c48921 5990 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
61b0191c 5991 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5992 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5993 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5994 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5995 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5996 aGroup->AddPrimitiveArray (aPrim);
20637bd2 5997}
5998
5999//=============================================================================
6000//function : VLayerLine
6001//purpose : Draws line in the v3d view layer with given attributes: linetype,
6002// : linewidth, transparency coefficient
6003//============================================================================
6004static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
6005{
6006 // get the active view
6007 Handle(V3d_View) aView = ViewerTest::CurrentView();
6008 if (aView.IsNull())
6009 {
6010 di << "Call vinit before!\n";
6011 return 1;
6012 }
6013 else if (argc < 5)
6014 {
6015 di << "Use: " << argv[0];
6016 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
6017 di << " linetype : { 0 | 1 | 2 | 3 } \n";
6018 di << " 0 - solid \n";
6019 di << " 1 - dashed \n";
6020 di << " 2 - dot \n";
6021 di << " 3 - dashdot\n";
6022 di << " transparency : { 0.0 - 1.0 } \n";
6023 di << " 0.0 - transparent\n";
6024 di << " 1.0 - visible \n";
6025 return 1;
6026 }
6027
61b0191c 6028 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 6029 // get the input params
91322f44 6030 Standard_Real X1 = Draw::Atof(argv[1]);
6031 Standard_Real Y1 = Draw::Atof(argv[2]);
6032 Standard_Real X2 = Draw::Atof(argv[3]);
6033 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 6034
3a4a3962 6035 Standard_Real aWidth = 0.5;
6036 Standard_Real aTransparency = 1.0;
20637bd2 6037
6038 // has width
6039 if (argc > 5)
91322f44 6040 aWidth = Draw::Atof(argv[5]);
20637bd2 6041
3a4a3962 6042 // select appropriate line type
6043 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
6044 if (argc > 6
6045 && !ViewerTest::ParseLineType (argv[6], aLineType))
6046 {
23fe70ec 6047 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
3a4a3962 6048 return 1;
6049 }
20637bd2 6050
6051 // has transparency
6052 if (argc > 7)
6053 {
91322f44 6054 aTransparency = Draw::Atof(argv[7]);
4fe56619 6055 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 6056 aTransparency = 1.0;
6057 }
6058
61b0191c 6059 static Handle (V3d_LineItem) aLine;
6060 if (!aLine.IsNull())
25289ec1 6061 {
0577ae8c 6062 aContext->Erase (aLine, Standard_False);
25289ec1 6063 }
61b0191c 6064 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
6065 aLineType, aWidth,
6066 aTransparency);
25289ec1 6067
778cd667 6068 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 6069 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
6070 aLine->SetToUpdate();
6071 aContext->Display (aLine, Standard_True);
25289ec1 6072
6073 return 0;
6074}
6075
61b0191c 6076
2bd4c032 6077//==============================================================================
6078//function : VGrid
6079//purpose :
6080//==============================================================================
6081
35e08fe8 6082static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 6083 Standard_Integer theArgNb,
6084 const char** theArgVec)
6085{
2bd4c032 6086 Handle(V3d_View) aView = ViewerTest::CurrentView();
6087 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6088 if (aView.IsNull() || aViewer.IsNull())
6089 {
23fe70ec 6090 Message::SendFail ("Error: no active viewer");
2bd4c032 6091 return 1;
6092 }
6093
6094 Aspect_GridType aType = aViewer->GridType();
6095 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 6096 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
6097 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
6098 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 6099 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 6100 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 6101 {
79931835 6102 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6103 anArg.LowerCase();
6104 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 6105 {
6106 continue;
6107 }
79931835 6108 else if (anArgIter + 1 < theArgNb
6109 && anArg == "-type")
6110 {
6111 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6112 anArgNext.LowerCase();
6113 if (anArgNext == "r"
6114 || anArgNext == "rect"
6115 || anArgNext == "rectangular")
6116 {
6117 aType = Aspect_GT_Rectangular;
6118 }
6119 else if (anArgNext == "c"
6120 || anArgNext == "circ"
6121 || anArgNext == "circular")
6122 {
6123 aType = Aspect_GT_Circular;
6124 }
6125 else
6126 {
23fe70ec 6127 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 6128 return 1;
6129 }
6130 }
6131 else if (anArgIter + 1 < theArgNb
6132 && anArg == "-mode")
6133 {
6134 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6135 anArgNext.LowerCase();
6136 if (anArgNext == "l"
6137 || anArgNext == "line"
6138 || anArgNext == "lines")
6139 {
6140 aMode = Aspect_GDM_Lines;
6141 }
6142 else if (anArgNext == "p"
6143 || anArgNext == "point"
6144 || anArgNext == "points")
6145 {
6146 aMode = Aspect_GDM_Points;
6147 }
6148 else
6149 {
23fe70ec 6150 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 6151 return 1;
6152 }
6153 }
6154 else if (anArgIter + 2 < theArgNb
6155 && (anArg == "-origin"
6156 || anArg == "-orig"))
6157 {
6158 hasOrigin = true;
6159 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6160 Draw::Atof (theArgVec[anArgIter + 2]));
6161 anArgIter += 2;
6162 }
6163 else if (anArgIter + 2 < theArgNb
6164 && anArg == "-step")
6165 {
6166 hasStep = true;
6167 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6168 Draw::Atof (theArgVec[anArgIter + 2]));
6169 if (aNewStepXY.x() <= 0.0
6170 || aNewStepXY.y() <= 0.0)
6171 {
23fe70ec 6172 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 6173 return 1;
6174 }
6175 anArgIter += 2;
6176 }
6177 else if (anArgIter + 1 < theArgNb
6178 && (anArg == "-angle"
6179 || anArg == "-rotangle"
6180 || anArg == "-rotationangle"))
6181 {
6182 hasRotAngle = true;
6183 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
6184 }
6185 else if (anArgIter + 1 < theArgNb
6186 && (anArg == "-zoffset"
6187 || anArg == "-dz"))
6188 {
6189 hasZOffset = true;
6190 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
6191 }
6192 else if (anArgIter + 1 < theArgNb
6193 && anArg == "-radius")
6194 {
6195 hasSize = true;
6196 ++anArgIter;
6197 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
6198 if (aNewStepXY.x() <= 0.0)
6199 {
23fe70ec 6200 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
79931835 6201 return 1;
6202 }
6203 }
6204 else if (anArgIter + 2 < theArgNb
6205 && anArg == "-size")
6206 {
6207 hasSize = true;
6208 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6209 Draw::Atof (theArgVec[anArgIter + 2]));
6210 if (aNewStepXY.x() <= 0.0
6211 || aNewStepXY.y() <= 0.0)
6212 {
23fe70ec 6213 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 6214 return 1;
6215 }
6216 anArgIter += 2;
6217 }
6218 else if (anArg == "r"
6219 || anArg == "rect"
6220 || anArg == "rectangular")
2bd4c032 6221 {
6222 aType = Aspect_GT_Rectangular;
6223 }
79931835 6224 else if (anArg == "c"
6225 || anArg == "circ"
6226 || anArg == "circular")
2bd4c032 6227 {
6228 aType = Aspect_GT_Circular;
6229 }
79931835 6230 else if (anArg == "l"
6231 || anArg == "line"
6232 || anArg == "lines")
2bd4c032 6233 {
6234 aMode = Aspect_GDM_Lines;
6235 }
79931835 6236 else if (anArg == "p"
6237 || anArg == "point"
6238 || anArg == "points")
2bd4c032 6239 {
6240 aMode = Aspect_GDM_Points;
6241 }
79931835 6242 else if (anArgIter + 1 >= theArgNb
6243 && anArg == "off")
2bd4c032 6244 {
6245 aViewer->DeactivateGrid();
6246 return 0;
6247 }
6248 else
6249 {
23fe70ec 6250 Message::SendFail() << "Syntax error at '" << anArg << "'";
79931835 6251 return 1;
2bd4c032 6252 }
6253 }
6254
2bd4c032 6255 if (aType == Aspect_GT_Rectangular)
6256 {
79931835 6257 Graphic3d_Vec2d anOrigXY, aStepXY;
6258 Standard_Real aRotAngle = 0.0;
6259 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6260 if (hasOrigin)
6261 {
6262 anOrigXY = aNewOriginXY;
6263 }
6264 if (hasStep)
6265 {
6266 aStepXY = aNewStepXY;
6267 }
6268 if (hasRotAngle)
6269 {
6270 aRotAngle = aNewRotAngle;
6271 }
6272 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6273 if (hasSize || hasZOffset)
2bd4c032 6274 {
79931835 6275 Graphic3d_Vec3d aSize;
6276 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6277 if (hasSize)
6278 {
6279 aSize.x() = aNewSizeXY.x();
6280 aSize.y() = aNewSizeXY.y();
6281 }
6282 if (hasZOffset)
6283 {
6284 aSize.z() = aNewZOffset;
6285 }
6286 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 6287 }
2bd4c032 6288 }
6289 else if (aType == Aspect_GT_Circular)
6290 {
79931835 6291 Graphic3d_Vec2d anOrigXY;
ee2be2a8 6292 Standard_Real aRadiusStep;
2bd4c032 6293 Standard_Integer aDivisionNumber;
79931835 6294 Standard_Real aRotAngle = 0.0;
6295 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6296 if (hasOrigin)
6297 {
6298 anOrigXY = aNewOriginXY;
6299 }
6300 if (hasStep)
6301 {
6302 aRadiusStep = aNewStepXY[0];
6303 aDivisionNumber = (int )aNewStepXY[1];
6304 if (aDivisionNumber < 1)
6305 {
23fe70ec 6306 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
79931835 6307 return 1;
6308 }
6309 }
6310 if (hasRotAngle)
2bd4c032 6311 {
79931835 6312 aRotAngle = aNewRotAngle;
2bd4c032 6313 }
6314
79931835 6315 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6316 if (hasSize || hasZOffset)
6317 {
6318 Standard_Real aRadius = 0.0, aZOffset = 0.0;
6319 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
6320 if (hasSize)
6321 {
6322 aRadius = aNewSizeXY.x();
6323 if (aNewSizeXY.y() != 0.0)
6324 {
23fe70ec 6325 Message::SendFail ("Syntax error: circular size should be specified as radius");
79931835 6326 return 1;
6327 }
6328 }
6329 if (hasZOffset)
6330 {
6331 aZOffset = aNewZOffset;
6332 }
6333 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6334 }
2bd4c032 6335 }
79931835 6336 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6337 return 0;
6338}
6339
c40b7d58 6340//==============================================================================
6341//function : VPriviledgedPlane
6342//purpose :
6343//==============================================================================
6344
6345static int VPriviledgedPlane (Draw_Interpretor& theDI,
6346 Standard_Integer theArgNb,
6347 const char** theArgVec)
6348{
6349 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6350 {
23fe70ec 6351 Message::SendFail ("Error: wrong number of arguments! See usage:");
c40b7d58 6352 theDI.PrintHelp (theArgVec[0]);
6353 return 1;
6354 }
6355
6356 // get the active viewer
6357 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6358 if (aViewer.IsNull())
6359 {
23fe70ec 6360 Message::SendFail ("Error: no active viewer");
c40b7d58 6361 return 1;
6362 }
6363
6364 if (theArgNb == 1)
6365 {
6366 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6367 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6368 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6369 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6370 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6371 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6372 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6373 return 0;
6374 }
6375
6376 Standard_Integer anArgIdx = 1;
6377 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6378 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6379 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6380 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6381 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6382 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6383
6384 gp_Ax3 aPriviledgedPlane;
6385 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6386 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6387 if (theArgNb > 7)
6388 {
6389 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6390 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6391 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6392 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6393 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6394 }
6395 else
6396 {
6397 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6398 }
6399
6400 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6401
6402 return 0;
6403}
6404
f25b82d6 6405//==============================================================================
6406//function : VConvert
6407//purpose :
6408//==============================================================================
6409
6410static int VConvert (Draw_Interpretor& theDI,
6411 Standard_Integer theArgNb,
6412 const char** theArgVec)
6413{
6414 // get the active view
6415 Handle(V3d_View) aView = ViewerTest::CurrentView();
6416 if (aView.IsNull())
6417 {
23fe70ec 6418 Message::SendFail ("Error: no active viewer");
f25b82d6 6419 return 1;
6420 }
6421
6422 enum { Model, Ray, View, Window, Grid } aMode = Model;
6423
6424 // access coordinate arguments
6425 TColStd_SequenceOfReal aCoord;
6426 Standard_Integer anArgIdx = 1;
6427 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6428 {
6429 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
d45edf24 6430 if (!anArg.IsRealValue (Standard_True))
f25b82d6 6431 {
6432 break;
6433 }
6434 aCoord.Append (anArg.RealValue());
6435 }
6436
6437 // non-numeric argument too early
6438 if (aCoord.IsEmpty())
6439 {
23fe70ec 6440 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6441 theDI.PrintHelp (theArgVec[0]);
6442 return 1;
6443 }
6444
6445 // collect all other arguments and options
6446 for (; anArgIdx < theArgNb; ++anArgIdx)
6447 {
6448 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6449 anArg.LowerCase();
6450 if (anArg == "window") aMode = Window;
6451 else if (anArg == "view") aMode = View;
6452 else if (anArg == "grid") aMode = Grid;
6453 else if (anArg == "ray") aMode = Ray;
6454 else
6455 {
23fe70ec 6456 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
f25b82d6 6457 theDI.PrintHelp (theArgVec[0]);
6458 return 1;
6459 }
6460 }
6461
6462 // complete input checks
6463 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6464 (aCoord.Length() == 2 && theArgNb > 4) ||
6465 (aCoord.Length() == 3 && theArgNb > 5))
6466 {
23fe70ec 6467 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6468 theDI.PrintHelp (theArgVec[0]);
6469 return 1;
6470 }
6471
6472 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6473 Standard_Integer aXYp[2] = {0, 0};
6474
6475 // convert one-dimensional coordinate
6476 if (aCoord.Length() == 1)
6477 {
6478 switch (aMode)
6479 {
ee2be2a8 6480 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6481 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6482 default:
23fe70ec 6483 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6484 theDI.PrintHelp (theArgVec[0]);
6485 return 1;
6486 }
6487 }
6488
6489 // convert 2D coordinates from projection or view reference space
6490 if (aCoord.Length() == 2)
6491 {
6492 switch (aMode)
6493 {
6494 case Model :
6495 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6496 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6497 return 0;
6498
6499 case View :
6500 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6501 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6502 return 0;
6503
6504 case Window :
ee2be2a8 6505 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6506 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6507 return 0;
6508
6509 case Grid :
6510 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6511 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6512 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6513 return 0;
6514
6515 case Ray :
6516 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6517 (Standard_Integer) aCoord (2),
6518 aXYZ[0], aXYZ[1], aXYZ[2],
6519 aXYZ[3], aXYZ[4], aXYZ[5]);
6520 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6521 return 0;
6522
6523 default:
23fe70ec 6524 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6525 theDI.PrintHelp (theArgVec[0]);
6526 return 1;
6527 }
6528 }
6529
6530 // convert 3D coordinates from view reference space
6531 else if (aCoord.Length() == 3)
6532 {
6533 switch (aMode)
6534 {
6535 case Window :
6536 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6537 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6538 return 0;
6539
6540 case Grid :
6541 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6542 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6543 return 0;
6544
6545 default:
23fe70ec 6546 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6547 theDI.PrintHelp (theArgVec[0]);
6548 return 1;
6549 }
6550 }
6551
6552 return 0;
6553}
6554
208e6839 6555//==============================================================================
6556//function : VFps
6557//purpose :
6558//==============================================================================
6559
6560static int VFps (Draw_Interpretor& theDI,
6561 Standard_Integer theArgNb,
6562 const char** theArgVec)
6563{
6564 // get the active view
6565 Handle(V3d_View) aView = ViewerTest::CurrentView();
6566 if (aView.IsNull())
6567 {
23fe70ec 6568 Message::SendFail ("Error: no active viewer");
208e6839 6569 return 1;
6570 }
6571
e084dbbc 6572 Standard_Integer aFramesNb = -1;
6573 Standard_Real aDuration = -1.0;
6574 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6575 {
e084dbbc 6576 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6577 anArg.LowerCase();
6578 if (aDuration < 0.0
6579 && anArgIter + 1 < theArgNb
6580 && (anArg == "-duration"
6581 || anArg == "-dur"
6582 || anArg == "-time"))
6583 {
6584 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6585 }
6586 else if (aFramesNb < 0
6587 && anArg.IsIntegerValue())
6588 {
6589 aFramesNb = anArg.IntegerValue();
6590 if (aFramesNb <= 0)
6591 {
23fe70ec 6592 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6593 return 1;
6594 }
6595 }
6596 else
6597 {
23fe70ec 6598 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6599 return 1;
6600 }
6601 }
6602 if (aFramesNb < 0 && aDuration < 0.0)
6603 {
6604 aFramesNb = 100;
208e6839 6605 }
6606
6607 // the time is meaningless for first call
6608 // due to async OpenGl rendering
6609 aView->Redraw();
6610
6611 // redraw view in loop to estimate average values
6612 OSD_Timer aTimer;
6613 aTimer.Start();
e084dbbc 6614 Standard_Integer aFrameIter = 1;
6615 for (;; ++aFrameIter)
208e6839 6616 {
6617 aView->Redraw();
e084dbbc 6618 if ((aFramesNb > 0
6619 && aFrameIter >= aFramesNb)
6620 || (aDuration > 0.0
6621 && aTimer.ElapsedTime() >= aDuration))
6622 {
6623 break;
6624 }
208e6839 6625 }
6626 aTimer.Stop();
6627 Standard_Real aCpu;
6628 const Standard_Real aTime = aTimer.ElapsedTime();
6629 aTimer.OSD_Chronometer::Show (aCpu);
6630
e084dbbc 6631 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6632 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6633
6634 // return statistics
6635 theDI << "FPS: " << aFpsAver << "\n"
6636 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6637
8c820969 6638 // compute additional statistics in ray-tracing mode
e084dbbc 6639 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6640 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6641 {
e084dbbc 6642 Graphic3d_Vec2i aWinSize (0, 0);
6643 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6644
6645 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6646 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6647 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6648 }
6649
208e6839 6650 return 0;
6651}
6652
a577aaab 6653
f0430952 6654//==============================================================================
6655//function : VMemGpu
6656//purpose :
6657//==============================================================================
6658
6659static int VMemGpu (Draw_Interpretor& theDI,
6660 Standard_Integer theArgNb,
6661 const char** theArgVec)
6662{
6663 // get the context
6664 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6665 if (aContextAIS.IsNull())
6666 {
23fe70ec 6667 Message::SendFail ("Error: no active viewer");
f0430952 6668 return 1;
6669 }
6670
dc3fe572 6671 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 6672 if (aDriver.IsNull())
6673 {
23fe70ec 6674 Message::SendFail ("Error: graphic driver not available");
f0430952 6675 return 1;
6676 }
6677
6678 Standard_Size aFreeBytes = 0;
6679 TCollection_AsciiString anInfo;
6680 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
6681 {
23fe70ec 6682 Message::SendFail ("Error: information not available");
f0430952 6683 return 1;
6684 }
6685
6686 if (theArgNb > 1 && *theArgVec[1] == 'f')
6687 {
6688 theDI << Standard_Real (aFreeBytes);
6689 }
6690 else
6691 {
6692 theDI << anInfo;
6693 }
6694
6695 return 0;
6696}
6697
85e096c3 6698// ==============================================================================
6699// function : VReadPixel
6700// purpose :
6701// ==============================================================================
6702static int VReadPixel (Draw_Interpretor& theDI,
6703 Standard_Integer theArgNb,
6704 const char** theArgVec)
6705{
6706 // get the active view
6707 Handle(V3d_View) aView = ViewerTest::CurrentView();
6708 if (aView.IsNull())
6709 {
23fe70ec 6710 Message::SendFail ("Error: no active viewer");
85e096c3 6711 return 1;
6712 }
6713 else if (theArgNb < 3)
6714 {
23fe70ec 6715 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
6716 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
85e096c3 6717 return 1;
6718 }
6719
dc858f4c 6720 Image_Format aFormat = Image_Format_RGBA;
6721 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 6722
85e096c3 6723 Standard_Integer aWidth, aHeight;
6724 aView->Window()->Size (aWidth, aHeight);
91322f44 6725 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
6726 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 6727 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
6728 {
23fe70ec 6729 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
85e096c3 6730 return 1;
6731 }
6732
ba00aab7 6733 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
85e096c3 6734 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
6735 {
dc858f4c 6736 TCollection_AsciiString aParam (theArgVec[anIter]);
6737 aParam.LowerCase();
55c8f0f7 6738 if (aParam == "-rgb"
ba00aab7 6739 || aParam == "rgb"
6740 || aParam == "-srgb"
6741 || aParam == "srgb")
85e096c3 6742 {
dc858f4c 6743 aFormat = Image_Format_RGB;
692613e5 6744 aBufferType = Graphic3d_BT_RGB;
ba00aab7 6745 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
85e096c3 6746 }
55c8f0f7
BB
6747 else if (aParam == "-hls"
6748 || aParam == "hls")
85e096c3 6749 {
dc858f4c 6750 aFormat = Image_Format_RGB;
692613e5 6751 aBufferType = Graphic3d_BT_RGB;
85e096c3 6752 toShowHls = Standard_True;
6753 }
55c8f0f7
BB
6754 else if (aParam == "-rgbf"
6755 || aParam == "rgbf")
85e096c3 6756 {
dc858f4c 6757 aFormat = Image_Format_RGBF;
692613e5 6758 aBufferType = Graphic3d_BT_RGB;
85e096c3 6759 }
55c8f0f7 6760 else if (aParam == "-rgba"
ba00aab7 6761 || aParam == "rgba"
6762 || aParam == "-srgba"
6763 || aParam == "srgba")
85e096c3 6764 {
dc858f4c 6765 aFormat = Image_Format_RGBA;
692613e5 6766 aBufferType = Graphic3d_BT_RGBA;
ba00aab7 6767 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
85e096c3 6768 }
55c8f0f7
BB
6769 else if (aParam == "-rgbaf"
6770 || aParam == "rgbaf")
85e096c3 6771 {
dc858f4c 6772 aFormat = Image_Format_RGBAF;
692613e5 6773 aBufferType = Graphic3d_BT_RGBA;
85e096c3 6774 }
55c8f0f7
BB
6775 else if (aParam == "-depth"
6776 || aParam == "depth")
85e096c3 6777 {
dc858f4c 6778 aFormat = Image_Format_GrayF;
692613e5 6779 aBufferType = Graphic3d_BT_Depth;
85e096c3 6780 }
55c8f0f7
BB
6781 else if (aParam == "-name"
6782 || aParam == "name")
85e096c3 6783 {
6784 toShowName = Standard_True;
6785 }
9196ea9d 6786 else if (aParam == "-hex"
6787 || aParam == "hex")
6788 {
6789 toShowHex = Standard_True;
6790 }
55c8f0f7
BB
6791 else
6792 {
23fe70ec 6793 Message::SendFail() << "Syntax error at '" << aParam << "'";
9196ea9d 6794 return 1;
55c8f0f7 6795 }
85e096c3 6796 }
6797
692613e5 6798 Image_PixMap anImage;
6799 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
6800 {
23fe70ec 6801 Message::SendFail ("Error: image allocation failed");
692613e5 6802 return 1;
6803 }
6804 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 6805 {
23fe70ec 6806 Message::SendFail ("Error: image dump failed");
85e096c3 6807 return 1;
6808 }
6809
68beaa3c 6810 // redirect possible warning messages that could have been added by ToPixMap
6811 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
6812 // contaminate result of the command
6813 Standard_CString aWarnLog = theDI.Result();
6814 if (aWarnLog != NULL && aWarnLog[0] != '\0')
6815 {
6816 std::cout << aWarnLog << std::endl;
6817 }
6818 theDI.Reset();
6819
ba00aab7 6820 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
85e096c3 6821 if (toShowName)
6822 {
692613e5 6823 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 6824 {
e958a649 6825 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 6826 }
6827 else
6828 {
e958a649 6829 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 6830 }
6831 }
9196ea9d 6832 else if (toShowHex)
6833 {
6834 if (aBufferType == Graphic3d_BT_RGBA)
6835 {
6836 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
6837 }
6838 else
6839 {
6840 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
6841 }
6842 }
85e096c3 6843 else
6844 {
6845 switch (aBufferType)
6846 {
6847 default:
692613e5 6848 case Graphic3d_BT_RGB:
85e096c3 6849 {
6850 if (toShowHls)
6851 {
e958a649 6852 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 6853 }
ba00aab7 6854 else if (toShow_sRGB)
6855 {
6856 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
6857 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
6858 }
85e096c3 6859 else
6860 {
e958a649 6861 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 6862 }
6863 break;
6864 }
692613e5 6865 case Graphic3d_BT_RGBA:
85e096c3 6866 {
ba00aab7 6867 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
6868 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
85e096c3 6869 break;
6870 }
692613e5 6871 case Graphic3d_BT_Depth:
85e096c3 6872 {
e958a649 6873 theDI << aColor.GetRGB().Red();
85e096c3 6874 break;
6875 }
6876 }
6877 }
6878
6879 return 0;
6880}
6881
fd3f6bd0 6882//! Auxiliary presentation for an image plane.
6883class ViewerTest_ImagePrs : public AIS_InteractiveObject
6884{
6885public:
6886 //! Main constructor.
6887 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
6888 const Standard_Real theWidth,
6889 const Standard_Real theHeight,
6890 const TCollection_AsciiString& theLabel)
6891 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
6892 {
6893 SetDisplayMode (0);
6894 SetHilightMode (1);
6895 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
6896 {
6897 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6898 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
6899 Graphic3d_MaterialAspect aMat;
6900 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
61168418 6901 aMat.SetAmbientColor (Quantity_NOC_BLACK);
6902 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
6903 aMat.SetSpecularColor (Quantity_NOC_BLACK);
6904 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
fd3f6bd0 6905 aFillAspect->SetFrontMaterial (aMat);
6906 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
6907 aFillAspect->SetTextureMapOn();
6908 }
6909 {
6910 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
6911 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
6912 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
6913 myDrawer->SetTextAspect (aTextAspect);
6914 }
6915 {
6916 const gp_Dir aNorm (0.0, 0.0, 1.0);
6917 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
6918 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
6919 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
6920 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
6921 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
6922 myTris->AddEdge (1);
6923 myTris->AddEdge (2);
6924 myTris->AddEdge (3);
6925 myTris->AddEdge (3);
6926 myTris->AddEdge (2);
6927 myTris->AddEdge (4);
6928
6929 myRect = new Graphic3d_ArrayOfPolylines (4);
6930 myRect->AddVertex (myTris->Vertice (1));
6931 myRect->AddVertex (myTris->Vertice (3));
6932 myRect->AddVertex (myTris->Vertice (4));
6933 myRect->AddVertex (myTris->Vertice (2));
6934 }
6935 }
6936
6937 //! Returns TRUE for accepted display modes.
6938 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
6939
6940 //! Compute presentation.
decbff0d 6941 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
6942 const Handle(Prs3d_Presentation)& thePrs,
6943 const Standard_Integer theMode) Standard_OVERRIDE
fd3f6bd0 6944 {
6945 switch (theMode)
6946 {
6947 case 0:
6948 {
6949 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6950 aGroup->AddPrimitiveArray (myTris);
6951 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6952 aGroup->AddPrimitiveArray (myRect);
6953 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6954 return;
6955 }
6956 case 1:
6957 {
6958 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6959 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6960 aGroup->AddPrimitiveArray (myRect);
6961 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6962 return;
6963 }
6964 }
6965 }
6966
6967 //! Compute selection.
6968 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6969 {
6970 if (theMode == 0)
6971 {
6972 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6973 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6974 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6975 theSel->Add (aSensitive);
6976 }
6977 }
6978
6979private:
6980 Handle(Graphic3d_ArrayOfTriangles) myTris;
6981 Handle(Graphic3d_ArrayOfPolylines) myRect;
6982 TCollection_AsciiString myLabel;
6983 Standard_Real myWidth;
6984 Standard_Real myHeight;
6985};
6986
692613e5 6987//==============================================================================
6988//function : VDiffImage
6989//purpose : The draw-command compares two images.
6990//==============================================================================
6991
6992static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6993{
fd3f6bd0 6994 if (theArgNb < 3)
692613e5 6995 {
23fe70ec 6996 Message::SendFail ("Syntax error: not enough arguments");
692613e5 6997 return 1;
6998 }
6999
fd3f6bd0 7000 Standard_Integer anArgIter = 1;
7001 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
7002 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
7003 TCollection_AsciiString aDiffImagePath;
7004 Standard_Real aTolColor = -1.0;
7005 Standard_Integer toBlackWhite = -1;
7006 Standard_Integer isBorderFilterOn = -1;
7007 Standard_Boolean isOldSyntax = Standard_False;
7008 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
7009 for (; anArgIter < theArgNb; ++anArgIter)
7010 {
7011 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7012 anArg.LowerCase();
7013 if (anArgIter + 1 < theArgNb
7014 && (anArg == "-toleranceofcolor"
7015 || anArg == "-tolerancecolor"
7016 || anArg == "-tolerance"
7017 || anArg == "-toler"))
7018 {
7019 aTolColor = Atof (theArgVec[++anArgIter]);
7020 if (aTolColor < 0.0 || aTolColor > 1.0)
7021 {
23fe70ec 7022 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7023 return 1;
7024 }
7025 }
7026 else if (anArg == "-blackwhite")
7027 {
7028 Standard_Boolean toEnable = Standard_True;
7029 if (anArgIter + 1 < theArgNb
dae2a922 7030 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7031 {
7032 ++anArgIter;
7033 }
7034 toBlackWhite = toEnable ? 1 : 0;
7035 }
7036 else if (anArg == "-borderfilter")
7037 {
7038 Standard_Boolean toEnable = Standard_True;
7039 if (anArgIter + 1 < theArgNb
dae2a922 7040 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7041 {
7042 ++anArgIter;
7043 }
7044 isBorderFilterOn = toEnable ? 1 : 0;
7045 }
7046 else if (anArg == "-exitonclose")
7047 {
49582f9d 7048 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 7049 if (anArgIter + 1 < theArgNb
dae2a922 7050 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 7051 {
7052 ++anArgIter;
7053 }
7054 }
7055 else if (anArg == "-closeonescape"
7056 || anArg == "-closeonesc")
7057 {
49582f9d 7058 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 7059 if (anArgIter + 1 < theArgNb
dae2a922 7060 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 7061 {
7062 ++anArgIter;
7063 }
7064 }
7065 else if (anArgIter + 3 < theArgNb
7066 && anArg == "-display")
7067 {
7068 aViewName = theArgVec[++anArgIter];
7069 aPrsNameRef = theArgVec[++anArgIter];
7070 aPrsNameNew = theArgVec[++anArgIter];
7071 if (anArgIter + 1 < theArgNb
7072 && *theArgVec[anArgIter + 1] != '-')
7073 {
7074 aPrsNameDiff = theArgVec[++anArgIter];
7075 }
7076 }
7077 else if (aTolColor < 0.0
d45edf24 7078 && anArg.IsRealValue (Standard_True))
fd3f6bd0 7079 {
7080 isOldSyntax = Standard_True;
7081 aTolColor = anArg.RealValue();
7082 if (aTolColor < 0.0 || aTolColor > 1.0)
7083 {
23fe70ec 7084 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7085 return 1;
7086 }
7087 }
7088 else if (isOldSyntax
7089 && toBlackWhite == -1
7090 && (anArg == "0" || anArg == "1"))
7091 {
7092 toBlackWhite = anArg == "1" ? 1 : 0;
7093 }
7094 else if (isOldSyntax
7095 && isBorderFilterOn == -1
7096 && (anArg == "0" || anArg == "1"))
7097 {
7098 isBorderFilterOn = anArg == "1" ? 1 : 0;
7099 }
7100 else if (aDiffImagePath.IsEmpty())
7101 {
7102 aDiffImagePath = theArgVec[anArgIter];
7103 }
7104 else
7105 {
23fe70ec 7106 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fd3f6bd0 7107 return 1;
7108 }
7109 }
692613e5 7110
fd3f6bd0 7111 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
7112 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
7113 if (!anImgRef->Load (anImgPathRef))
7114 {
23fe70ec 7115 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
fd3f6bd0 7116 return 1;
7117 }
7118 if (!anImgNew->Load (anImgPathNew))
7119 {
23fe70ec 7120 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
fd3f6bd0 7121 return 1;
7122 }
692613e5 7123
7124 // compare the images
7125 Image_Diff aComparer;
fd3f6bd0 7126 Standard_Integer aDiffColorsNb = -1;
7127 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 7128 {
fd3f6bd0 7129 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
7130 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
7131 aDiffColorsNb = aComparer.Compare();
7132 theDI << aDiffColorsNb << "\n";
692613e5 7133 }
7134
692613e5 7135 // save image of difference
fd3f6bd0 7136 Handle(Image_AlienPixMap) aDiff;
7137 if (aDiffColorsNb > 0
7138 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
7139 {
7140 aDiff = new Image_AlienPixMap();
7141 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
7142 {
23fe70ec 7143 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
fd3f6bd0 7144 return 1;
7145 }
7146 aComparer.SaveDiffImage (*aDiff);
7147 if (!aDiffImagePath.IsEmpty()
7148 && !aDiff->Save (aDiffImagePath))
7149 {
23fe70ec 7150 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
fd3f6bd0 7151 return 1;
7152 }
7153 }
7154
7155 if (aViewName.IsEmpty())
7156 {
7157 return 0;
7158 }
7159
7160 ViewerTest_Names aViewNames (aViewName);
7161 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
7162 {
7163 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
7164 theDI.Eval (aCommand.ToCString());
7165 }
7166
7167 Standard_Integer aPxLeft = 0;
7168 Standard_Integer aPxTop = 0;
7169 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
7170 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
7171 ? int(anImgRef->SizeY() * 2)
7172 : int(anImgRef->SizeY());
7173 TCollection_AsciiString aDisplayName;
9e04ccdc 7174 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
7175 aViewName, aDisplayName);
fd3f6bd0 7176
7177 Standard_Real aRatio = anImgRef->Ratio();
7178 Standard_Real aSizeX = 1.0;
7179 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 7180 {
fd3f6bd0 7181 OSD_Path aPath (anImgPathRef);
7182 TCollection_AsciiString aLabelRef;
7183 if (!aPath.Name().IsEmpty())
7184 {
7185 aLabelRef = aPath.Name() + aPath.Extension();
7186 }
7187 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
7188
7189 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
7190 gp_Trsf aTrsfRef;
7191 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
7192 anImgRefPrs->SetLocalTransformation (aTrsfRef);
7193 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 7194 }
fd3f6bd0 7195 {
7196 OSD_Path aPath (anImgPathNew);
7197 TCollection_AsciiString aLabelNew;
7198 if (!aPath.Name().IsEmpty())
7199 {
7200 aLabelNew = aPath.Name() + aPath.Extension();
7201 }
7202 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 7203
fd3f6bd0 7204 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
7205 gp_Trsf aTrsfRef;
7206 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
7207 anImgNewPrs->SetLocalTransformation (aTrsfRef);
7208 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
7209 }
7210 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
7211 if (!aDiff.IsNull())
7212 {
7213 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
7214 gp_Trsf aTrsfDiff;
7215 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
7216 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
7217 }
7218 if (!aPrsNameDiff.IsEmpty())
7219 {
7220 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
7221 }
7222 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
7223 ViewerTest::CurrentView()->FitAll();
692613e5 7224 return 0;
7225}
7226
4754e164 7227//=======================================================================
7228//function : VSelect
7229//purpose : Emulates different types of selection by mouse:
7230// 1) single click selection
7231// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
7232// 3) selection with polygon having corners at
dc3fe572 7233// pixel positions (x1,y1),...,(xn,yn)
4754e164 7234// 4) any of these selections with shift button pressed
7235//=======================================================================
49582f9d 7236static Standard_Integer VSelect (Draw_Interpretor& ,
7237 Standard_Integer theNbArgs,
7238 const char** theArgVec)
4754e164 7239{
49582f9d 7240 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
7241 if (aCtx.IsNull())
4754e164 7242 {
23fe70ec 7243 Message::SendFail ("Error: no active viewer");
4754e164 7244 return 1;
7245 }
2157d6ac 7246
49582f9d 7247 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
75cf8250 7248 bool toAllowOverlap = false;
7249 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
49582f9d 7250 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2157d6ac 7251 {
49582f9d 7252 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7253 anArg.LowerCase();
7254 if (anArg == "-allowoverlap")
7255 {
7256 toAllowOverlap = true;
7257 if (anArgIter + 1 < theNbArgs
dae2a922 7258 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
49582f9d 7259 {
7260 ++anArgIter;
7261 }
7262 }
e3d4b879 7263 else if (anArg == "-replace")
7264 {
7265 aSelScheme = AIS_SelectionScheme_Replace;
7266 }
e76471b5 7267 else if (anArg == "-replaceextra")
7268 {
7269 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
7270 }
e3d4b879 7271 else if (anArg == "-xor"
7272 || anArg == "-shift")
7273 {
7274 aSelScheme = AIS_SelectionScheme_XOR;
7275 }
7276 else if (anArg == "-add")
7277 {
7278 aSelScheme = AIS_SelectionScheme_Add;
7279 }
7280 else if (anArg == "-remove")
7281 {
7282 aSelScheme = AIS_SelectionScheme_Remove;
7283 }
49582f9d 7284 else if (anArgIter + 1 < theNbArgs
7285 && anArg.IsIntegerValue()
7286 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
2157d6ac 7287 {
49582f9d 7288 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
7289 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
7290 }
7291 else if (anArgIter + 1 == theNbArgs
7292 && anArg.IsIntegerValue())
7293 {
75cf8250 7294 if (anArg.IntegerValue() == 1)
7295 {
7296 aSelScheme = AIS_SelectionScheme_XOR;
7297 }
49582f9d 7298 }
7299 else
7300 {
23fe70ec 7301 Message::SendFail() << "Syntax error at '" << anArg << "'";
2157d6ac 7302 return 1;
7303 }
49582f9d 7304 }
a24a7821 7305
49582f9d 7306 if (toAllowOverlap)
7307 {
7308 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
2157d6ac 7309 }
7310
4754e164 7311 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
49582f9d 7312 if (aPnts.IsEmpty())
4754e164 7313 {
75cf8250 7314 aCtx->SelectDetected (aSelScheme);
49582f9d 7315 aCtx->CurrentViewer()->Invalidate();
4754e164 7316 }
49582f9d 7317 else if (aPnts.Length() == 2)
4754e164 7318 {
49582f9d 7319 if (toAllowOverlap
7320 && aPnts.First().y() < aPnts.Last().y())
7321 {
7322 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7323 }
7324 else if (!toAllowOverlap
7325 && aPnts.First().y() > aPnts.Last().y())
7326 {
7327 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7328 }
e3d4b879 7329
7330 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7331 }
7332 else
7333 {
e3d4b879 7334 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7335 }
49582f9d 7336 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
4754e164 7337 return 0;
7338}
7339
7340//=======================================================================
7341//function : VMoveTo
dc3fe572 7342//purpose : Emulates cursor movement to defined pixel position
4754e164 7343//=======================================================================
1e756cb9 7344static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7345 Standard_Integer theNbArgs,
7346 const char** theArgVec)
4754e164 7347{
8a590580 7348 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7349 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7350 if (aContext.IsNull())
4754e164 7351 {
23fe70ec 7352 Message::SendFail ("Error: no active viewer");
4754e164 7353 return 1;
7354 }
7355
8a590580 7356 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7357 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7358 {
8a590580 7359 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7360 anArgStr.LowerCase();
7361 if (anArgStr == "-reset"
7362 || anArgStr == "-clear")
7363 {
7364 if (anArgIter + 1 < theNbArgs)
7365 {
23fe70ec 7366 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
8a590580 7367 return 1;
7368 }
7369
5634c81a 7370 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
8a590580 7371 && aContext->CurrentViewer()->GridEcho();
7372 if (toEchoGrid)
7373 {
7374 aContext->CurrentViewer()->HideGridEcho (aView);
7375 }
7376 if (aContext->ClearDetected() || toEchoGrid)
7377 {
7378 aContext->CurrentViewer()->RedrawImmediate();
7379 }
7380 return 0;
7381 }
7382 else if (aMousePos.x() == IntegerLast()
7383 && anArgStr.IsIntegerValue())
7384 {
7385 aMousePos.x() = anArgStr.IntegerValue();
7386 }
7387 else if (aMousePos.y() == IntegerLast()
7388 && anArgStr.IsIntegerValue())
7389 {
7390 aMousePos.y() = anArgStr.IntegerValue();
7391 }
7392 else
7393 {
23fe70ec 7394 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8a590580 7395 return 1;
7396 }
7397 }
7398
7399 if (aMousePos.x() == IntegerLast()
7400 || aMousePos.y() == IntegerLast())
7401 {
23fe70ec 7402 Message::SendFail ("Syntax error: wrong number of arguments");
4754e164 7403 return 1;
7404 }
8a590580 7405
49582f9d 7406 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7407 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7408 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7409
1e756cb9 7410 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7411 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7412 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7413 {
7414 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7415 {
7416 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7417 break;
7418 }
7419 }
7420 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7421 return 0;
7422}
7423
1beb58d7 7424namespace
7425{
7426 //! Global map storing all animations registered in ViewerTest.
7427 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7428
7429 //! The animation calling the Draw Harness command.
7430 class ViewerTest_AnimationProc : public AIS_Animation
7431 {
7432 public:
7433
7434 //! Main constructor.
7435 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7436 Draw_Interpretor* theDI,
7437 const TCollection_AsciiString& theCommand)
7438 : AIS_Animation (theAnimationName),
7439 myDrawInter(theDI),
7440 myCommand (theCommand)
7441 {
7442 //
7443 }
7444
7445 protected:
7446
7447 //! Evaluate the command.
7448 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7449 {
7450 TCollection_AsciiString aCmd = myCommand;
7451 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7452 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7453 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7454 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7455 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7456 myDrawInter->Eval (aCmd.ToCString());
7457 }
7458
7459 //! Find the keyword in the command and replace it with value.
7460 //! @return the position of the keyword to pass value
7461 void replace (TCollection_AsciiString& theCmd,
7462 const TCollection_AsciiString& theKey,
7463 const TCollection_AsciiString& theVal)
7464 {
7465 TCollection_AsciiString aCmd (theCmd);
7466 aCmd.LowerCase();
7467 const Standard_Integer aPos = aCmd.Search (theKey);
7468 if (aPos == -1)
7469 {
7470 return;
7471 }
7472
7473 TCollection_AsciiString aPart1, aPart2;
7474 Standard_Integer aPart1To = aPos - 1;
7475 if (aPart1To >= 1
7476 && aPart1To <= theCmd.Length())
7477 {
7478 aPart1 = theCmd.SubString (1, aPart1To);
7479 }
7480
7481 Standard_Integer aPart2From = aPos + theKey.Length();
7482 if (aPart2From >= 1
7483 && aPart2From <= theCmd.Length())
7484 {
7485 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7486 }
7487
7488 theCmd = aPart1 + theVal + aPart2;
7489 }
7490
7491 protected:
7492
7493 Draw_Interpretor* myDrawInter;
7494 TCollection_AsciiString myCommand;
7495
7496 };
7497
7498 //! Replace the animation with the new one.
7499 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7500 Handle(AIS_Animation)& theAnimation,
7501 const Handle(AIS_Animation)& theAnimationNew)
7502 {
7503 theAnimationNew->CopyFrom (theAnimation);
7504 if (!theParentAnimation.IsNull())
7505 {
7506 theParentAnimation->Replace (theAnimation, theAnimationNew);
7507 }
7508 else
7509 {
7510 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7511 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7512 }
7513 theAnimation = theAnimationNew;
7514 }
7515
7516 //! Parse the point.
7517 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7518 {
7519 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
d45edf24 7520 if (!anXYZ[0].IsRealValue (Standard_True)
7521 || !anXYZ[1].IsRealValue (Standard_True)
7522 || !anXYZ[2].IsRealValue (Standard_True))
1beb58d7 7523 {
7524 return Standard_False;
7525 }
7526
7527 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7528 return Standard_True;
7529 }
7530
7531 //! Parse the quaternion.
7532 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7533 {
7534 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
d45edf24 7535 if (!anXYZW[0].IsRealValue (Standard_True)
7536 || !anXYZW[1].IsRealValue (Standard_True)
7537 || !anXYZW[2].IsRealValue (Standard_True)
7538 || !anXYZW[3].IsRealValue (Standard_True))
1beb58d7 7539 {
7540 return Standard_False;
7541 }
7542
7543 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7544 return Standard_True;
7545 }
7546
08f8a185 7547 //! Auxiliary class for flipping image upside-down.
7548 class ImageFlipper
7549 {
7550 public:
7551
7552 //! Empty constructor.
7553 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7554
7555 //! Perform flipping.
7556 Standard_Boolean FlipY (Image_PixMap& theImage)
7557 {
7558 if (theImage.IsEmpty()
7559 || theImage.SizeX() == 0
7560 || theImage.SizeY() == 0)
7561 {
7562 return Standard_False;
7563 }
7564
7565 const Standard_Size aRowSize = theImage.SizeRowBytes();
7566 if (myTmp.Size() < aRowSize
7567 && !myTmp.Allocate (aRowSize))
7568 {
7569 return Standard_False;
7570 }
7571
7572 // for odd height middle row should be left as is
7573 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7574 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7575 {
7576 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7577 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7578 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7579 memcpy (aTop, aBot, aRowSize);
7580 memcpy (aBot, myTmp.Data(), aRowSize);
7581 }
7582 return Standard_True;
7583 }
7584
7585 private:
7586 NCollection_Buffer myTmp;
7587 };
7588
1beb58d7 7589}
7590
197ac94e 7591//=================================================================================================
4754e164 7592//function : VViewParams
dc3fe572 7593//purpose : Gets or sets AIS View characteristics
197ac94e 7594//=================================================================================================
7595static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7596{
1beb58d7 7597 Handle(V3d_View) aView = ViewerTest::CurrentView();
7598 if (aView.IsNull())
4754e164 7599 {
23fe70ec 7600 Message::SendFail ("Error: no active viewer");
4754e164 7601 return 1;
7602 }
197ac94e 7603
1beb58d7 7604 Standard_Boolean toSetProj = Standard_False;
7605 Standard_Boolean toSetUp = Standard_False;
7606 Standard_Boolean toSetAt = Standard_False;
7607 Standard_Boolean toSetEye = Standard_False;
7608 Standard_Boolean toSetScale = Standard_False;
7609 Standard_Boolean toSetSize = Standard_False;
7610 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7611 Standard_Real aViewScale = aView->Scale();
7612 Standard_Real aViewSize = 1.0;
1beb58d7 7613 Graphic3d_Vec2i aCenter2d;
7614 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7615 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7616 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7617 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7618 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
197ac94e 7619 if (theArgsNb == 1)
4754e164 7620 {
197ac94e 7621 // print all of the available view parameters
1beb58d7 7622 char aText[4096];
7623 Sprintf (aText,
7624 "Scale: %g\n"
7625 "Proj: %12g %12g %12g\n"
7626 "Up: %12g %12g %12g\n"
7627 "At: %12g %12g %12g\n"
7628 "Eye: %12g %12g %12g\n",
7629 aViewScale,
7630 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7631 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7632 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7633 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7634 theDi << aText;
197ac94e 7635 return 0;
4754e164 7636 }
197ac94e 7637
1beb58d7 7638 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7639 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7640 {
1beb58d7 7641 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7642 anArg.LowerCase();
7643 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7644 {
197ac94e 7645 continue;
7646 }
1beb58d7 7647 else if (anArg == "-cmd"
7648 || anArg == "-command"
7649 || anArg == "-args")
7650 {
7651 char aText[4096];
7652 Sprintf (aText,
7653 "-scale %g "
7654 "-proj %g %g %g "
7655 "-up %g %g %g "
7656 "-at %g %g %g\n",
7657 aViewScale,
7658 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7659 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7660 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7661 theDi << aText;
7662 }
7663 else if (anArg == "-scale"
7664 || anArg == "-size")
7665 {
7666 if (anArgIter + 1 < theArgsNb
7667 && *theArgVec[anArgIter + 1] != '-')
7668 {
7669 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
d45edf24 7670 if (aValueArg.IsRealValue (Standard_True))
1beb58d7 7671 {
7672 ++anArgIter;
7673 if (anArg == "-scale")
7674 {
7675 toSetScale = Standard_True;
7676 aViewScale = aValueArg.RealValue();
7677 }
7678 else if (anArg == "-size")
7679 {
7680 toSetSize = Standard_True;
7681 aViewSize = aValueArg.RealValue();
7682 }
7683 continue;
7684 }
7685 }
7686 if (anArg == "-scale")
7687 {
7688 theDi << "Scale: " << aView->Scale() << "\n";
7689 }
7690 else if (anArg == "-size")
7691 {
7692 Graphic3d_Vec2d aSizeXY;
7693 aView->Size (aSizeXY.x(), aSizeXY.y());
7694 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7695 }
7696 }
7697 else if (anArg == "-eye"
7698 || anArg == "-at"
7699 || anArg == "-up"
7700 || anArg == "-proj")
7701 {
7702 if (anArgIter + 3 < theArgsNb)
7703 {
7704 gp_XYZ anXYZ;
7705 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7706 {
7707 anArgIter += 3;
7708 if (anArg == "-eye")
7709 {
7710 toSetEye = Standard_True;
7711 aViewEye = anXYZ;
7712 }
7713 else if (anArg == "-at")
7714 {
7715 toSetAt = Standard_True;
7716 aViewAt = anXYZ;
7717 }
7718 else if (anArg == "-up")
7719 {
7720 toSetUp = Standard_True;
7721 aViewUp = anXYZ;
7722 }
7723 else if (anArg == "-proj")
7724 {
7725 toSetProj = Standard_True;
7726 aViewProj = anXYZ;
7727 }
7728 continue;
7729 }
7730 }
197ac94e 7731
1beb58d7 7732 if (anArg == "-eye")
7733 {
7734 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7735 }
7736 else if (anArg == "-at")
7737 {
7738 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7739 }
7740 else if (anArg == "-up")
7741 {
7742 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7743 }
7744 else if (anArg == "-proj")
7745 {
7746 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7747 }
7748 }
7749 else if (anArg == "-center")
3dfe95cd 7750 {
1beb58d7 7751 if (anArgIter + 2 < theArgsNb)
7752 {
7753 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7754 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7755 if (anX.IsIntegerValue()
7756 && anY.IsIntegerValue())
7757 {
7758 toSetCenter2d = Standard_True;
7759 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7760 }
7761 }
7762 }
7763 else
7764 {
23fe70ec 7765 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 7766 return 1;
7767 }
1beb58d7 7768 }
3dfe95cd 7769
1beb58d7 7770 // change view parameters in proper order
7771 if (toSetScale)
7772 {
7773 aView->SetScale (aViewScale);
7774 }
7775 if (toSetSize)
7776 {
7777 aView->SetSize (aViewSize);
7778 }
7779 if (toSetEye)
7780 {
7781 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7782 }
7783 if (toSetAt)
7784 {
7785 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7786 }
7787 if (toSetProj)
7788 {
7789 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7790 }
7791 if (toSetUp)
7792 {
7793 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7794 }
7795 if (toSetCenter2d)
7796 {
7797 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 7798 }
7799
1beb58d7 7800 return 0;
7801}
197ac94e 7802
2e93433e 7803//==============================================================================
7804//function : V2DMode
7805//purpose :
7806//==============================================================================
7807static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7808{
7809 bool is2dMode = true;
7810 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7811 if (aV3dView.IsNull())
7812 {
23fe70ec 7813 Message::SendFail ("Error: no active viewer");
2e93433e 7814 return 1;
7815 }
7816 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7817 {
7818 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7819 TCollection_AsciiString anArgCase = anArg;
7820 anArgCase.LowerCase();
7821 if (anArgIt + 1 < theArgsNb
7822 && anArgCase == "-name")
7823 {
7824 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7825 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7826 if (!ViewerTest_myViews.IsBound1 (aViewName))
7827 {
23fe70ec 7828 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 7829 return 1;
7830 }
7831 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7832 }
7833 else if (anArgCase == "-mode")
7834 {
7835 if (anArgIt + 1 < theArgsNb
dae2a922 7836 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 7837 {
7838 ++anArgIt;
7839 }
7840 }
dae2a922 7841 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 7842 {
7843 //
7844 }
7845 else
7846 {
23fe70ec 7847 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 7848 return 1;
7849 }
7850 }
7851
7852 aV3dView->SetView2DMode (is2dMode);
7853 return 0;
7854}
7855
1beb58d7 7856//==============================================================================
7857//function : VAnimation
7858//purpose :
7859//==============================================================================
7860static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7861 Standard_Integer theArgNb,
7862 const char** theArgVec)
7863{
7864 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7865 if (theArgNb < 2)
4754e164 7866 {
1beb58d7 7867 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7868 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7869 {
7870 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7871 }
1beb58d7 7872 return 0;
7873 }
7874 if (aCtx.IsNull())
7875 {
23fe70ec 7876 Message::SendFail ("Error: no active viewer");
1beb58d7 7877 return 1;
4754e164 7878 }
197ac94e 7879
1beb58d7 7880 Standard_Integer anArgIter = 1;
7881 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7882 if (aNameArg.IsEmpty())
7883 {
23fe70ec 7884 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7885 return 1;
7886 }
7887
7888 TCollection_AsciiString aNameArgLower = aNameArg;
7889 aNameArgLower.LowerCase();
7890 if (aNameArgLower == "-reset"
7891 || aNameArgLower == "-clear")
7892 {
7893 ViewerTest_AnimationTimelineMap.Clear();
7894 return 0;
7895 }
7896 else if (aNameArg.Value (1) == '-')
7897 {
23fe70ec 7898 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 7899 return 1;
7900 }
197ac94e 7901
1beb58d7 7902 const char* aNameSplitter = "/";
7903 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7904 if (aSplitPos == -1)
197ac94e 7905 {
1beb58d7 7906 aNameSplitter = ".";
7907 aSplitPos = aNameArg.Search (aNameSplitter);
7908 }
7909
7910 // find existing or create a new animation by specified name within syntax "parent.child".
7911 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7912 for (; !aNameArg.IsEmpty();)
7913 {
7914 TCollection_AsciiString aNameParent;
7915 if (aSplitPos != -1)
197ac94e 7916 {
1beb58d7 7917 if (aSplitPos == aNameArg.Length())
7918 {
23fe70ec 7919 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7920 return 1;
7921 }
7922
7923 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7924 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7925
7926 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 7927 }
7928 else
7929 {
1beb58d7 7930 aNameParent = aNameArg;
7931 aNameArg.Clear();
197ac94e 7932 }
1beb58d7 7933
7934 if (anAnimation.IsNull())
3dfe95cd 7935 {
1beb58d7 7936 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7937 {
7938 anAnimation = new AIS_Animation (aNameParent);
7939 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7940 }
7941 aRootAnimation = anAnimation;
3dfe95cd 7942 }
7943 else
7944 {
1beb58d7 7945 aParentAnimation = anAnimation;
7946 anAnimation = aParentAnimation->Find (aNameParent);
7947 if (anAnimation.IsNull())
7948 {
7949 anAnimation = new AIS_Animation (aNameParent);
7950 aParentAnimation->Add (anAnimation);
7951 }
3dfe95cd 7952 }
7953 }
1beb58d7 7954
7955 if (anArgIter >= theArgNb)
197ac94e 7956 {
1beb58d7 7957 // just print the list of children
7958 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 7959 {
1beb58d7 7960 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7961 }
1beb58d7 7962 return 0;
197ac94e 7963 }
1beb58d7 7964
bf7b2ceb 7965 // animation parameters
1beb58d7 7966 Standard_Boolean toPlay = Standard_False;
7967 Standard_Real aPlaySpeed = 1.0;
7968 Standard_Real aPlayStartTime = anAnimation->StartPts();
7969 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 7970 Standard_Boolean isFreeCamera = Standard_False;
7971 Standard_Boolean isLockLoop = Standard_False;
08f8a185 7972
7973 // video recording parameters
7974 TCollection_AsciiString aRecFile;
7975 Image_VideoParams aRecParams;
7976
1beb58d7 7977 Handle(V3d_View) aView = ViewerTest::CurrentView();
7978 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 7979 {
1beb58d7 7980 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7981 anArg.LowerCase();
bf7b2ceb 7982 // general options
1beb58d7 7983 if (anArg == "-reset"
7984 || anArg == "-clear")
197ac94e 7985 {
1beb58d7 7986 anAnimation->Clear();
7987 }
7988 else if (anArg == "-remove"
7989 || anArg == "-del"
7990 || anArg == "-delete")
7991 {
7992 if (!aParentAnimation.IsNull())
7993 {
7994 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7995 }
7996 else
7997 {
7998 aParentAnimation->Remove (anAnimation);
7999 }
8000 }
bf7b2ceb 8001 // playback options
1beb58d7 8002 else if (anArg == "-play")
8003 {
8004 toPlay = Standard_True;
8005 if (++anArgIter < theArgNb)
8006 {
8007 if (*theArgVec[anArgIter] == '-')
8008 {
8009 --anArgIter;
8010 continue;
8011 }
8012 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
8013
8014 if (++anArgIter < theArgNb)
8015 {
8016 if (*theArgVec[anArgIter] == '-')
8017 {
8018 --anArgIter;
8019 continue;
8020 }
8021 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8022 }
8023 }
8024 }
8025 else if (anArg == "-resume")
8026 {
8027 toPlay = Standard_True;
8028 aPlayStartTime = anAnimation->ElapsedTime();
8029 if (++anArgIter < theArgNb)
8030 {
8031 if (*theArgVec[anArgIter] == '-')
8032 {
8033 --anArgIter;
8034 continue;
8035 }
8036
8037 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8038 }
8039 }
8040 else if (anArg == "-playspeed"
8041 || anArg == "-speed")
8042 {
8043 if (++anArgIter >= theArgNb)
8044 {
23fe70ec 8045 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 8046 return 1;
8047 }
8048 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8049 }
8050 else if (anArg == "-lock"
8051 || anArg == "-lockloop"
8052 || anArg == "-playlockloop")
8053 {
8054 isLockLoop = Standard_True;
8055 }
8056 else if (anArg == "-freecamera"
8057 || anArg == "-playfreecamera"
8058 || anArg == "-freelook")
8059 {
8060 isFreeCamera = Standard_True;
8061 }
08f8a185 8062 // video recodring options
8063 else if (anArg == "-rec"
8064 || anArg == "-record")
8065 {
8066 if (++anArgIter >= theArgNb)
8067 {
23fe70ec 8068 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8069 return 1;
8070 }
8071
8072 aRecFile = theArgVec[anArgIter];
8073 if (aRecParams.FpsNum <= 0)
8074 {
8075 aRecParams.FpsNum = 24;
8076 }
8077
8078 if (anArgIter + 2 < theArgNb
8079 && *theArgVec[anArgIter + 1] != '-'
8080 && *theArgVec[anArgIter + 2] != '-')
8081 {
8082 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8083 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8084 if (aWidthArg .IsIntegerValue()
8085 && aHeightArg.IsIntegerValue())
8086 {
8087 aRecParams.Width = aWidthArg .IntegerValue();
8088 aRecParams.Height = aHeightArg.IntegerValue();
8089 anArgIter += 2;
8090 }
8091 }
8092 }
1beb58d7 8093 else if (anArg == "-fps")
8094 {
8095 if (++anArgIter >= theArgNb)
8096 {
23fe70ec 8097 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8098 return 1;
8099 }
bf7b2ceb 8100
8101 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8102 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8103 if (aSplitIndex == 0)
8104 {
08f8a185 8105 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 8106 }
8107 else
8108 {
8109 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8110 aFpsArg.Split (aFpsArg.Length() - 1);
8111 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 8112 aRecParams.FpsNum = aNumStr.IntegerValue();
8113 aRecParams.FpsDen = aDenStr.IntegerValue();
8114 if (aRecParams.FpsDen < 1)
bf7b2ceb 8115 {
23fe70ec 8116 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 8117 return 1;
8118 }
8119 }
1beb58d7 8120 }
08f8a185 8121 else if (anArg == "-format")
8122 {
8123 if (++anArgIter >= theArgNb)
8124 {
23fe70ec 8125 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8126 return 1;
8127 }
8128 aRecParams.Format = theArgVec[anArgIter];
8129 }
8130 else if (anArg == "-pix_fmt"
8131 || anArg == "-pixfmt"
8132 || anArg == "-pixelformat")
8133 {
8134 if (++anArgIter >= theArgNb)
8135 {
23fe70ec 8136 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8137 return 1;
8138 }
8139 aRecParams.PixelFormat = theArgVec[anArgIter];
8140 }
8141 else if (anArg == "-codec"
8142 || anArg == "-vcodec"
8143 || anArg == "-videocodec")
8144 {
8145 if (++anArgIter >= theArgNb)
8146 {
23fe70ec 8147 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8148 return 1;
8149 }
8150 aRecParams.VideoCodec = theArgVec[anArgIter];
8151 }
8152 else if (anArg == "-crf"
8153 || anArg == "-preset"
8154 || anArg == "-qp")
8155 {
8156 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8157 if (++anArgIter >= theArgNb)
8158 {
23fe70ec 8159 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8160 return 1;
8161 }
8162
8163 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8164 }
bf7b2ceb 8165 // animation definition options
1beb58d7 8166 else if (anArg == "-start"
8167 || anArg == "-starttime"
8168 || anArg == "-startpts")
8169 {
8170 if (++anArgIter >= theArgNb)
8171 {
23fe70ec 8172 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8173 return 1;
8174 }
8175
8176 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8177 aRootAnimation->UpdateTotalDuration();
8178 }
8179 else if (anArg == "-end"
8180 || anArg == "-endtime"
8181 || anArg == "-endpts")
8182 {
8183 if (++anArgIter >= theArgNb)
8184 {
23fe70ec 8185 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8186 return 1;
8187 }
8188
8189 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8190 aRootAnimation->UpdateTotalDuration();
8191 }
8192 else if (anArg == "-dur"
8193 || anArg == "-duration")
8194 {
8195 if (++anArgIter >= theArgNb)
8196 {
23fe70ec 8197 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8198 return 1;
8199 }
8200
8201 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8202 aRootAnimation->UpdateTotalDuration();
8203 }
8204 else if (anArg == "-command"
8205 || anArg == "-cmd"
8206 || anArg == "-invoke"
8207 || anArg == "-eval"
8208 || anArg == "-proc")
8209 {
8210 if (++anArgIter >= theArgNb)
8211 {
23fe70ec 8212 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8213 return 1;
8214 }
8215
8216 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8217 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8218 }
8219 else if (anArg == "-objecttrsf"
8220 || anArg == "-objectransformation"
8221 || anArg == "-objtransformation"
8222 || anArg == "-objtrsf"
8223 || anArg == "-object"
8224 || anArg == "-obj")
8225 {
8226 if (++anArgIter >= theArgNb)
8227 {
23fe70ec 8228 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8229 return 1;
8230 }
8231
8232 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8233 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8234 Handle(AIS_InteractiveObject) anObject;
8235 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8236 {
23fe70ec 8237 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8238 return 1;
8239 }
8240
1beb58d7 8241 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8242 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8243 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8244 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8245 Standard_Boolean isTrsfSet = Standard_False;
8246 Standard_Integer aTrsfArgIter = anArgIter + 1;
8247 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8248 {
8249 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8250 aTrsfArg.LowerCase();
8251 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8252 if (aTrsfArg.StartsWith ("-rotation")
8253 || aTrsfArg.StartsWith ("-rot"))
8254 {
8255 isTrsfSet = Standard_True;
8256 if (aTrsfArgIter + 4 >= theArgNb
8257 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8258 {
23fe70ec 8259 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8260 return 1;
8261 }
8262 aTrsfArgIter += 4;
8263 }
8264 else if (aTrsfArg.StartsWith ("-location")
8265 || aTrsfArg.StartsWith ("-loc"))
8266 {
8267 isTrsfSet = Standard_True;
8268 if (aTrsfArgIter + 3 >= theArgNb
8269 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8270 {
23fe70ec 8271 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8272 return 1;
8273 }
8274 aTrsfArgIter += 3;
8275 }
8276 else if (aTrsfArg.StartsWith ("-scale"))
8277 {
8278 isTrsfSet = Standard_True;
8279 if (++aTrsfArgIter >= theArgNb)
8280 {
23fe70ec 8281 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8282 return 1;
8283 }
8284
8285 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
d45edf24 8286 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8287 {
23fe70ec 8288 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8289 return 1;
8290 }
8291 aScales[anIndex] = aScaleStr.RealValue();
8292 }
8293 else
8294 {
8295 anArgIter = aTrsfArgIter - 1;
8296 break;
8297 }
8298 }
8299 if (!isTrsfSet)
8300 {
23fe70ec 8301 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8302 return 1;
8303 }
8304 else if (aTrsfArgIter >= theArgNb)
8305 {
8306 anArgIter = theArgNb;
8307 }
8308
8309 aTrsfs[0].SetRotation (aRotQuats[0]);
8310 aTrsfs[1].SetRotation (aRotQuats[1]);
8311 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8312 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8313 aTrsfs[0].SetScaleFactor (aScales[0]);
8314 aTrsfs[1].SetScaleFactor (aScales[1]);
8315
8316 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8317 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8318 }
8319 else if (anArg == "-viewtrsf"
8320 || anArg == "-view")
8321 {
8322 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8323 if (aCamAnimation.IsNull())
8324 {
8325 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8326 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8327 }
8328
8329 Handle(Graphic3d_Camera) aCams[2] =
8330 {
8331 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8332 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8333 };
8334
8335 Standard_Boolean isTrsfSet = Standard_False;
8336 Standard_Integer aViewArgIter = anArgIter + 1;
8337 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8338 {
8339 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8340 aViewArg.LowerCase();
8341 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8342 if (aViewArg.StartsWith ("-scale"))
8343 {
8344 isTrsfSet = Standard_True;
8345 if (++aViewArgIter >= theArgNb)
8346 {
23fe70ec 8347 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8348 return 1;
8349 }
8350
8351 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
d45edf24 8352 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8353 {
23fe70ec 8354 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8355 return 1;
8356 }
8357 Standard_Real aScale = aScaleStr.RealValue();
8358 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8359 aCams[anIndex]->SetScale (aScale);
8360 }
8361 else if (aViewArg.StartsWith ("-eye")
8362 || aViewArg.StartsWith ("-center")
8363 || aViewArg.StartsWith ("-at")
8364 || aViewArg.StartsWith ("-up"))
8365 {
8366 isTrsfSet = Standard_True;
8367 gp_XYZ anXYZ;
8368 if (aViewArgIter + 3 >= theArgNb
8369 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8370 {
23fe70ec 8371 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8372 return 1;
8373 }
8374 aViewArgIter += 3;
8375
8376 if (aViewArg.StartsWith ("-eye"))
8377 {
8378 aCams[anIndex]->SetEye (anXYZ);
8379 }
8380 else if (aViewArg.StartsWith ("-center")
8381 || aViewArg.StartsWith ("-at"))
8382 {
8383 aCams[anIndex]->SetCenter (anXYZ);
8384 }
8385 else if (aViewArg.StartsWith ("-up"))
8386 {
8387 aCams[anIndex]->SetUp (anXYZ);
8388 }
8389 }
8390 else
8391 {
8392 anArgIter = aViewArgIter - 1;
8393 break;
8394 }
8395 }
8396 if (!isTrsfSet)
8397 {
23fe70ec 8398 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8399 return 1;
8400 }
8401 else if (aViewArgIter >= theArgNb)
8402 {
8403 anArgIter = theArgNb;
8404 }
8405
8406 aCamAnimation->SetCameraStart(aCams[0]);
8407 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8408 }
8409 else
8410 {
23fe70ec 8411 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8412 return 1;
197ac94e 8413 }
8414 }
1beb58d7 8415
08f8a185 8416 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8417 {
1beb58d7 8418 return 0;
8419 }
8420
8421 // Start animation timeline and process frame updating.
8422 TheIsAnimating = Standard_True;
8423 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8424 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8425 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8426 if (isFreeCamera)
8427 {
8428 aView->Camera()->Copy (aCameraBack);
8429 }
8430
8431 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8432 if (aRecParams.FpsNum <= 0)
1beb58d7 8433 {
8434 while (!anAnimation->IsStopped())
197ac94e 8435 {
1beb58d7 8436 aCameraBack->Copy (aView->Camera());
8437 const Standard_Real aPts = anAnimation->UpdateTimer();
8438 if (isFreeCamera)
8439 {
8440 aView->Camera()->Copy (aCameraBack);
8441 }
8442
8443 if (aPts >= anUpperPts)
8444 {
8445 anAnimation->Pause();
8446 break;
8447 }
8448
8449 if (aView->IsInvalidated())
8450 {
8451 aView->Redraw();
8452 }
8453 else
8454 {
8455 aView->RedrawImmediate();
8456 }
8457
8458 if (!isLockLoop)
8459 {
8460 // handle user events
8461 theDI.Eval ("after 1 set waiter 1");
8462 theDI.Eval ("vwait waiter");
8463 }
8464 if (!TheIsAnimating)
8465 {
8466 anAnimation->Pause();
8467 theDI << aPts;
8468 break;
8469 }
8470 }
8471
8472 if (aView->IsInvalidated())
8473 {
8474 aView->Redraw();
197ac94e 8475 }
8476 else
8477 {
1beb58d7 8478 aView->RedrawImmediate();
197ac94e 8479 }
8480 }
1beb58d7 8481 else
197ac94e 8482 {
bf7b2ceb 8483 OSD_Timer aPerfTimer;
8484 aPerfTimer.Start();
1beb58d7 8485
08f8a185 8486 Handle(Image_VideoRecorder) aRecorder;
8487 ImageFlipper aFlipper;
8488 Handle(Draw_ProgressIndicator) aProgress;
8489 if (!aRecFile.IsEmpty())
8490 {
8491 if (aRecParams.Width <= 0
8492 || aRecParams.Height <= 0)
8493 {
8494 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8495 }
8496
8497 aRecorder = new Image_VideoRecorder();
8498 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8499 {
23fe70ec 8500 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8501 return 0;
8502 }
8503
8504 aProgress = new Draw_ProgressIndicator (theDI, 1);
8505 }
8506
1beb58d7 8507 // Manage frame-rated animation here
8508 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8509 int64_t aNbFrames = 0;
7e785937 8510 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8511 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8512 Standard_Integer aSecondsProgress = 0;
7e785937 8513 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8514 {
08f8a185 8515 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8516 aPts = aPlayStartTime + aRecPts;
8517 ++aNbFrames;
1beb58d7 8518 if (!anAnimation->Update (aPts))
8519 {
8520 break;
8521 }
8522
08f8a185 8523 if (!aRecorder.IsNull())
8524 {
8525 V3d_ImageDumpOptions aDumpParams;
8526 aDumpParams.Width = aRecParams.Width;
8527 aDumpParams.Height = aRecParams.Height;
8528 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8529 aDumpParams.StereoOptions = V3d_SDO_MONO;
8530 aDumpParams.ToAdjustAspect = Standard_True;
8531 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8532 {
23fe70ec 8533 Message::SendFail ("Error: view dump is failed");
08f8a185 8534 return 0;
8535 }
8536 aFlipper.FlipY (aRecorder->ChangeFrame());
8537 if (!aRecorder->PushFrame())
8538 {
8539 return 0;
8540 }
8541 }
8542 else
8543 {
8544 aView->Redraw();
8545 }
8546
8547 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8548 {
7e785937 8549 aPS.Next();
08f8a185 8550 ++aSecondsProgress;
8551 }
197ac94e 8552 }
bf7b2ceb 8553
8554 aPerfTimer.Stop();
1beb58d7 8555 anAnimation->Stop();
bf7b2ceb 8556 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8557 theDI << "Average FPS: " << aRecFps << "\n"
8558 << "Nb. Frames: " << Standard_Real(aNbFrames);
8559
8560 aView->Redraw();
197ac94e 8561 }
8562
1beb58d7 8563 aView->SetImmediateUpdate (wasImmediateUpdate);
8564 TheIsAnimating = Standard_False;
4754e164 8565 return 0;
8566}
8567
1beb58d7 8568
4754e164 8569//=======================================================================
8570//function : VChangeSelected
dc3fe572 8571//purpose : Adds the shape to selection or remove one from it
4754e164 8572//=======================================================================
8573static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8574 Standard_Integer argc,
8575 const char ** argv)
8576{
8577 if(argc != 2)
8578 {
8579 di<<"Usage : " << argv[0] << " shape \n";
8580 return 1;
8581 }
8582 //get AIS_Shape:
4754e164 8583 TCollection_AsciiString aName(argv[1]);
8584 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8585 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8586 || anAISObject.IsNull())
4754e164 8587 {
8588 di<<"Use 'vdisplay' before";
8589 return 1;
8590 }
4754e164 8591
8f521168 8592 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8593 return 0;
8594}
8595
4754e164 8596//=======================================================================
8597//function : VNbSelected
dc3fe572 8598//purpose : Returns number of selected objects
4754e164 8599//=======================================================================
8600static Standard_Integer VNbSelected (Draw_Interpretor& di,
8601 Standard_Integer argc,
8602 const char ** argv)
8603{
8604 if(argc != 1)
8605 {
8606 di << "Usage : " << argv[0] << "\n";
8607 return 1;
8608 }
8609 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8610 if(aContext.IsNull())
8611 {
8612 di << "use 'vinit' command before " << argv[0] << "\n";
8613 return 1;
8614 }
8615 di << aContext->NbSelected() << "\n";
8616 return 0;
8617}
8618
4754e164 8619//=======================================================================
8620//function : VSetViewSize
8621//purpose :
8622//=======================================================================
8623static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8624 Standard_Integer argc,
8625 const char ** argv)
8626{
8627 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8628 if(aContext.IsNull())
8629 {
8630 di << "use 'vinit' command before " << argv[0] << "\n";
8631 return 1;
8632 }
8633 if(argc != 2)
8634 {
8635 di<<"Usage : " << argv[0] << " Size\n";
8636 return 1;
8637 }
6b62b2da 8638 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8639 if (aSize <= 0.)
8640 {
8641 di<<"Bad Size value : " << aSize << "\n";
8642 return 1;
8643 }
8644
8645 Handle(V3d_View) aView = ViewerTest::CurrentView();
8646 aView->SetSize(aSize);
8647 return 0;
8648}
8649
8650//=======================================================================
8651//function : VMoveView
8652//purpose :
8653//=======================================================================
8654static Standard_Integer VMoveView (Draw_Interpretor& di,
8655 Standard_Integer argc,
8656 const char ** argv)
8657{
8658 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8659 if(aContext.IsNull())
8660 {
8661 di << "use 'vinit' command before " << argv[0] << "\n";
8662 return 1;
8663 }
8664 if(argc < 4 || argc > 5)
8665 {
8666 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8667 return 1;
8668 }
6b62b2da 8669 Standard_Real Dx = Draw::Atof (argv[1]);
8670 Standard_Real Dy = Draw::Atof (argv[2]);
8671 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8672 Standard_Boolean aStart = Standard_True;
8673 if (argc == 5)
8674 {
6b62b2da 8675 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8676 }
8677
8678 Handle(V3d_View) aView = ViewerTest::CurrentView();
8679 aView->Move(Dx,Dy,Dz,aStart);
8680 return 0;
8681}
8682
8683//=======================================================================
8684//function : VTranslateView
8685//purpose :
8686//=======================================================================
8687static Standard_Integer VTranslateView (Draw_Interpretor& di,
8688 Standard_Integer argc,
8689 const char ** argv)
8690{
8691 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8692 if(aContext.IsNull())
8693 {
8694 di << "use 'vinit' command before " << argv[0] << "\n";
8695 return 1;
8696 }
8697 if(argc < 4 || argc > 5)
8698 {
8699 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8700 return 1;
8701 }
6b62b2da 8702 Standard_Real Dx = Draw::Atof (argv[1]);
8703 Standard_Real Dy = Draw::Atof (argv[2]);
8704 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8705 Standard_Boolean aStart = Standard_True;
dc3fe572 8706 if (argc == 5)
4754e164 8707 {
6b62b2da 8708 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8709 }
8710
8711 Handle(V3d_View) aView = ViewerTest::CurrentView();
8712 aView->Translate(Dx,Dy,Dz,aStart);
8713 return 0;
8714}
8715
8716//=======================================================================
8717//function : VTurnView
8718//purpose :
8719//=======================================================================
8720static Standard_Integer VTurnView (Draw_Interpretor& di,
8721 Standard_Integer argc,
8722 const char ** argv)
8723{
8724 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8725 if(aContext.IsNull()) {
8726 di << "use 'vinit' command before " << argv[0] << "\n";
8727 return 1;
8728 }
8729 if(argc < 4 || argc > 5){
8730 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8731 return 1;
8732 }
6b62b2da 8733 Standard_Real Ax = Draw::Atof (argv[1]);
8734 Standard_Real Ay = Draw::Atof (argv[2]);
8735 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 8736 Standard_Boolean aStart = Standard_True;
dc3fe572 8737 if (argc == 5)
4754e164 8738 {
6b62b2da 8739 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8740 }
8741
8742 Handle(V3d_View) aView = ViewerTest::CurrentView();
8743 aView->Turn(Ax,Ay,Az,aStart);
8744 return 0;
8745}
8746
269294d6 8747//==============================================================================
8748//function : VTextureEnv
8749//purpose : ENables or disables environment mapping
8750//==============================================================================
8751class OCC_TextureEnv : public Graphic3d_TextureEnv
8752{
8753public:
8754 OCC_TextureEnv(const Standard_CString FileName);
8755 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8756 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8757 const Standard_Boolean theModulateFlag,
8758 const Graphic3d_TypeOfTextureFilter theFilter,
8759 const Standard_ShortReal theXScale,
8760 const Standard_ShortReal theYScale,
8761 const Standard_ShortReal theXShift,
8762 const Standard_ShortReal theYShift,
8763 const Standard_ShortReal theAngle);
68858c7d 8764 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 8765};
a3f6f591 8766DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 8767
269294d6 8768OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8769 : Graphic3d_TextureEnv(theFileName)
8770{
8771}
8772
8773OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8774 : Graphic3d_TextureEnv(theTexId)
8775{
8776}
8777
8778void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8779 const Standard_Boolean theModulateFlag,
8780 const Graphic3d_TypeOfTextureFilter theFilter,
8781 const Standard_ShortReal theXScale,
8782 const Standard_ShortReal theYScale,
8783 const Standard_ShortReal theXShift,
8784 const Standard_ShortReal theYShift,
8785 const Standard_ShortReal theAngle)
8786{
8787 myParams->SetRepeat (theRepeatFlag);
8788 myParams->SetModulate (theModulateFlag);
8789 myParams->SetFilter (theFilter);
8790 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8791 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8792 myParams->SetRotation (theAngle);
8793}
8794
35e08fe8 8795static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 8796{
8797 // get the active view
8798 Handle(V3d_View) aView = ViewerTest::CurrentView();
8799 if (aView.IsNull())
8800 {
23fe70ec 8801 Message::SendFail ("Error: no active viewer");
269294d6 8802 return 1;
8803 }
8804
8805 // Checking the input arguments
8806 Standard_Boolean anEnableFlag = Standard_False;
8807 Standard_Boolean isOk = theArgNb >= 2;
8808 if (isOk)
8809 {
8810 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8811 anEnableFlag = anEnableOpt.IsEqual("on");
8812 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8813 }
8814 if (anEnableFlag)
8815 {
8816 isOk = (theArgNb == 3 || theArgNb == 11);
8817 if (isOk)
8818 {
8819 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8820 isOk = (!aTextureOpt.IsIntegerValue() ||
8821 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8822
8823 if (isOk && theArgNb == 11)
8824 {
8825 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8826 aModulateOpt(theArgVec[4]),
8827 aFilterOpt (theArgVec[5]),
8828 aSScaleOpt (theArgVec[6]),
8829 aTScaleOpt (theArgVec[7]),
8830 aSTransOpt (theArgVec[8]),
8831 aTTransOpt (theArgVec[9]),
8832 anAngleOpt (theArgVec[10]);
8833 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8834 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8835 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
d45edf24 8836 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8837 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8838 anAngleOpt.IsRealValue (Standard_True));
269294d6 8839 }
8840 }
8841 }
8842
8843 if (!isOk)
8844 {
23fe70ec 8845 Message::SendFail() << "Usage:\n"
8846 << theArgVec[0] << " off\n"
8847 << 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]";
269294d6 8848 return 1;
8849 }
8850
8851 if (anEnableFlag)
8852 {
8853 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8854 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8855 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8856 new OCC_TextureEnv(theArgVec[2]);
8857
8858 if (theArgNb == 11)
8859 {
8860 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8861 aTexEnv->SetTextureParameters(
8862 aRepeatOpt. IsEqual("repeat"),
8863 aModulateOpt.IsEqual("modulate"),
8864 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8865 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8866 Graphic3d_TOTF_TRILINEAR,
8867 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8868 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8869 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8870 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8871 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8872 );
8873 }
8874 aView->SetTextureEnv(aTexEnv);
269294d6 8875 }
8876 else // Disabling environment mapping
8877 {
269294d6 8878 Handle(Graphic3d_TextureEnv) aTexture;
8879 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8880 }
8881
8882 aView->Redraw();
8883 return 0;
8884}
8885
3e05329c 8886namespace
8887{
8888 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8889
8890 //! Remove registered clipping plane from all views and objects.
8891 static void removePlane (MapOfPlanes& theRegPlanes,
8892 const TCollection_AsciiString& theName)
8893 {
8894 Handle(Graphic3d_ClipPlane) aClipPlane;
8895 if (!theRegPlanes.Find (theName, aClipPlane))
8896 {
23fe70ec 8897 Message::SendWarning ("Warning: no such plane");
3e05329c 8898 return;
8899 }
8900
8901 theRegPlanes.UnBind (theName);
8902 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8903 anIObjIt.More(); anIObjIt.Next())
8904 {
8f521168 8905 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 8906 aPrs->RemoveClipPlane (aClipPlane);
8907 }
8908
8909 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8910 aViewIt.More(); aViewIt.Next())
8911 {
8912 const Handle(V3d_View)& aView = aViewIt.Key2();
8913 aView->RemoveClipPlane(aClipPlane);
8914 }
8915
8916 ViewerTest::RedrawAllViews();
8917 }
8918}
8919
4269bd1b 8920//===============================================================================================
8921//function : VClipPlane
8922//purpose :
8923//===============================================================================================
8924static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8925{
8926 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 8927 static MapOfPlanes aRegPlanes;
8928
8929 if (theArgsNb < 2)
8930 {
3e05329c 8931 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8932 {
8933 theDi << aPlaneIter.Key() << " ";
8934 }
8935 return 0;
4269bd1b 8936 }
8937
8938 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 8939 aCommand.LowerCase();
8940 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8941 if (anActiveView.IsNull())
8942 {
23fe70ec 8943 Message::SendFail ("Error: no active viewer");
3e05329c 8944 return 1;
8945 }
4269bd1b 8946
8947 // print maximum number of planes for current viewer
3e05329c 8948 if (aCommand == "-maxplanes"
8949 || aCommand == "maxplanes")
4269bd1b 8950 {
3e05329c 8951 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8952 << " plane slots provided by driver.\n";
4269bd1b 8953 return 0;
8954 }
8955
8956 // create / delete plane instance
3e05329c 8957 if (aCommand == "-create"
8958 || aCommand == "create"
8959 || aCommand == "-delete"
8960 || aCommand == "delete"
8961 || aCommand == "-clone"
8962 || aCommand == "clone")
4269bd1b 8963 {
8964 if (theArgsNb < 3)
8965 {
23fe70ec 8966 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 8967 return 1;
8968 }
8969
3e05329c 8970 Standard_Boolean toCreate = aCommand == "-create"
8971 || aCommand == "create";
8972 Standard_Boolean toClone = aCommand == "-clone"
8973 || aCommand == "clone";
8974 Standard_Boolean toDelete = aCommand == "-delete"
8975 || aCommand == "delete";
4269bd1b 8976 TCollection_AsciiString aPlane (theArgVec[2]);
8977
8978 if (toCreate)
8979 {
8980 if (aRegPlanes.IsBound (aPlane))
8981 {
3e05329c 8982 std::cout << "Warning: existing plane has been overridden.\n";
8983 toDelete = true;
8984 }
8985 else
8986 {
8987 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8988 return 0;
4269bd1b 8989 }
4269bd1b 8990 }
8991 else if (toClone) // toClone
8992 {
8993 if (!aRegPlanes.IsBound (aPlane))
8994 {
23fe70ec 8995 Message::SendFail ("Error: no such plane");
4269bd1b 8996 return 1;
8997 }
3e05329c 8998 else if (theArgsNb < 4)
4269bd1b 8999 {
23fe70ec 9000 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 9001 return 1;
9002 }
9003
9004 TCollection_AsciiString aClone (theArgVec[3]);
9005 if (aRegPlanes.IsBound (aClone))
9006 {
23fe70ec 9007 Message::SendFail ("Error: plane name is in use");
4269bd1b 9008 return 1;
9009 }
9010
9011 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
9012
9013 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 9014 return 0;
4269bd1b 9015 }
4269bd1b 9016
3e05329c 9017 if (toDelete)
9018 {
9019 if (aPlane == "ALL"
9020 || aPlane == "all"
9021 || aPlane == "*")
4269bd1b 9022 {
3e05329c 9023 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
9024 {
9025 aPlane = aPlaneIter.Key();
9026 removePlane (aRegPlanes, aPlane);
9027 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
9028 }
4269bd1b 9029 }
3e05329c 9030 else
4269bd1b 9031 {
3e05329c 9032 removePlane (aRegPlanes, aPlane);
4269bd1b 9033 }
4269bd1b 9034 }
9035
3e05329c 9036 if (toCreate)
9037 {
9038 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9039 }
4269bd1b 9040 return 0;
9041 }
9042
9043 // set / unset plane command
3e05329c 9044 if (aCommand == "set"
9045 || aCommand == "unset")
4269bd1b 9046 {
3e05329c 9047 if (theArgsNb < 5)
4269bd1b 9048 {
23fe70ec 9049 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9050 return 1;
9051 }
9052
3e05329c 9053 // redirect to new syntax
9054 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
9055 anArgVec.SetValue (1, theArgVec[0]);
9056 anArgVec.SetValue (2, theArgVec[2]);
9057 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
9058 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 9059 {
3e05329c 9060 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 9061 }
9062
3e05329c 9063 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 9064 }
9065
9066 // change plane command
3e05329c 9067 TCollection_AsciiString aPlaneName;
9068 Handle(Graphic3d_ClipPlane) aClipPlane;
9069 Standard_Integer anArgIter = 0;
9070 if (aCommand == "-change"
9071 || aCommand == "change")
4269bd1b 9072 {
3e05329c 9073 // old syntax support
9074 if (theArgsNb < 3)
4269bd1b 9075 {
23fe70ec 9076 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9077 return 1;
9078 }
9079
3e05329c 9080 anArgIter = 3;
9081 aPlaneName = theArgVec[2];
9082 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 9083 {
23fe70ec 9084 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 9085 return 1;
9086 }
3e05329c 9087 }
9088 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9089 {
9090 anArgIter = 2;
9091 aPlaneName = theArgVec[1];
9092 }
9093 else
9094 {
9095 anArgIter = 2;
9096 aPlaneName = theArgVec[1];
9097 aClipPlane = new Graphic3d_ClipPlane();
9098 aRegPlanes.Bind (aPlaneName, aClipPlane);
9099 theDi << "Created new plane " << aPlaneName << ".\n";
9100 }
4269bd1b 9101
3e05329c 9102 if (theArgsNb - anArgIter < 1)
9103 {
23fe70ec 9104 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9105 return 1;
9106 }
4269bd1b 9107
3e05329c 9108 for (; anArgIter < theArgsNb; ++anArgIter)
9109 {
9110 const char** aChangeArgs = theArgVec + anArgIter;
9111 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9112 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9113 aChangeArg.LowerCase();
4269bd1b 9114
3e05329c 9115 Standard_Boolean toEnable = Standard_True;
dae2a922 9116 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 9117 {
3e05329c 9118 aClipPlane->SetOn (toEnable);
4269bd1b 9119 }
25c35042 9120 else if (aChangeArg.StartsWith ("-equation")
9121 || aChangeArg.StartsWith ("equation"))
4269bd1b 9122 {
3e05329c 9123 if (aNbChangeArgs < 5)
4269bd1b 9124 {
23fe70ec 9125 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9126 return 1;
9127 }
9128
25c35042 9129 Standard_Integer aSubIndex = 1;
9130 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9131 if (aPrefixLen < aChangeArg.Length())
9132 {
9133 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9134 if (!aSubStr.IsIntegerValue()
9135 || aSubStr.IntegerValue() <= 0)
9136 {
23fe70ec 9137 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9138 return 1;
9139 }
9140 aSubIndex = aSubStr.IntegerValue();
9141 }
9142
9143 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9144 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9145 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9146 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9147 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9148 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9149 {
9150 if (aSubPln->ChainNextPlane().IsNull())
9151 {
9152 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9153 }
9154 aSubPln = aSubPln->ChainNextPlane();
9155 }
9156 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9157 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9158 anArgIter += 4;
4269bd1b 9159 }
25c35042 9160 else if ((aChangeArg == "-boxinterior"
9161 || aChangeArg == "-boxint"
9162 || aChangeArg == "-box")
9163 && aNbChangeArgs >= 7)
9164 {
9165 Graphic3d_BndBox3d aBndBox;
9166 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9167 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9168 anArgIter += 6;
9169
9170 Standard_Integer aNbSubPlanes = 6;
9171 const Graphic3d_Vec3d aDirArray[6] =
9172 {
9173 Graphic3d_Vec3d (-1, 0, 0),
9174 Graphic3d_Vec3d ( 1, 0, 0),
9175 Graphic3d_Vec3d ( 0,-1, 0),
9176 Graphic3d_Vec3d ( 0, 1, 0),
9177 Graphic3d_Vec3d ( 0, 0,-1),
9178 Graphic3d_Vec3d ( 0, 0, 1),
9179 };
9180 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9181 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9182 {
9183 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9184 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9185 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9186 if (aSubPlaneIter + 1 == aNbSubPlanes)
9187 {
9188 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9189 }
9190 else
9191 {
9192 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9193 }
9194 aSubPln = aSubPln->ChainNextPlane();
9195 }
9196 }
3e05329c 9197 else if (aChangeArg == "-capping"
9198 || aChangeArg == "capping")
4269bd1b 9199 {
3e05329c 9200 if (aNbChangeArgs < 2)
4269bd1b 9201 {
23fe70ec 9202 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9203 return 1;
9204 }
9205
dae2a922 9206 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9207 {
3e05329c 9208 aClipPlane->SetCapping (toEnable);
9209 anArgIter += 1;
9210 }
9211 else
9212 {
9213 // just skip otherwise (old syntax)
9214 }
9215 }
9216 else if (aChangeArg == "-useobjectmaterial"
9217 || aChangeArg == "-useobjectmat"
9218 || aChangeArg == "-useobjmat"
9219 || aChangeArg == "-useobjmaterial")
9220 {
9221 if (aNbChangeArgs < 2)
9222 {
23fe70ec 9223 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9224 return 1;
9225 }
9226
dae2a922 9227 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9228 {
3e05329c 9229 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9230 anArgIter += 1;
4269bd1b 9231 }
3e05329c 9232 }
9233 else if (aChangeArg == "-useobjecttexture"
9234 || aChangeArg == "-useobjecttex"
9235 || aChangeArg == "-useobjtexture"
9236 || aChangeArg == "-useobjtex")
9237 {
9238 if (aNbChangeArgs < 2)
4269bd1b 9239 {
23fe70ec 9240 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9241 return 1;
9242 }
4269bd1b 9243
dae2a922 9244 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9245 {
9246 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9247 anArgIter += 1;
9248 }
9249 }
9250 else if (aChangeArg == "-useobjectshader"
9251 || aChangeArg == "-useobjshader")
9252 {
9253 if (aNbChangeArgs < 2)
9254 {
23fe70ec 9255 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9256 return 1;
9257 }
4269bd1b 9258
dae2a922 9259 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9260 {
9261 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9262 anArgIter += 1;
4269bd1b 9263 }
3e05329c 9264 }
9265 else if (aChangeArg == "-color"
9266 || aChangeArg == "color")
9267 {
9268 Quantity_Color aColor;
dae2a922 9269 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9270 aChangeArgs + 1,
9271 aColor);
3e05329c 9272 if (aNbParsed == 0)
4269bd1b 9273 {
23fe70ec 9274 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9275 return 1;
9276 }
61168418 9277 aClipPlane->SetCappingColor (aColor);
3e05329c 9278 anArgIter += aNbParsed;
9279 }
61168418 9280 else if (aNbChangeArgs >= 1
9281 && (aChangeArg == "-material"
9282 || aChangeArg == "material"))
9283 {
9284 ++anArgIter;
9285 Graphic3d_NameOfMaterial aMatName;
9286 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9287 {
23fe70ec 9288 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9289 return 1;
9290 }
9291 aClipPlane->SetCappingMaterial (aMatName);
9292 }
1b661a81 9293 else if ((aChangeArg == "-transparency"
9294 || aChangeArg == "-transp")
9295 && aNbChangeArgs >= 2)
9296 {
9297 TCollection_AsciiString aValStr (aChangeArgs[1]);
9298 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
d45edf24 9299 if (aValStr.IsRealValue (Standard_True))
1b661a81 9300 {
9301 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9302 aMat.SetTransparency ((float )aValStr.RealValue());
9303 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9304 aClipPlane->SetCappingMaterial (aMat);
9305 }
9306 else
9307 {
9308 aValStr.LowerCase();
9309 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9310 if (aValStr == "opaque")
9311 {
9312 aMode = Graphic3d_AlphaMode_Opaque;
9313 }
9314 else if (aValStr == "mask")
9315 {
9316 aMode = Graphic3d_AlphaMode_Mask;
9317 }
9318 else if (aValStr == "blend")
9319 {
9320 aMode = Graphic3d_AlphaMode_Blend;
9321 }
33425a46 9322 else if (aValStr == "maskblend"
9323 || aValStr == "blendmask")
9324 {
9325 aMode = Graphic3d_AlphaMode_MaskBlend;
9326 }
1b661a81 9327 else if (aValStr == "blendauto")
9328 {
9329 aMode = Graphic3d_AlphaMode_BlendAuto;
9330 }
9331 else
9332 {
23fe70ec 9333 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9334 return 1;
9335 }
9336 anAspect->SetAlphaMode (aMode);
9337 aClipPlane->SetCappingAspect (anAspect);
9338 }
9339 anArgIter += 1;
9340 }
3e05329c 9341 else if (aChangeArg == "-texname"
9342 || aChangeArg == "texname")
9343 {
9344 if (aNbChangeArgs < 2)
9345 {
23fe70ec 9346 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9347 return 1;
9348 }
4269bd1b 9349
3e05329c 9350 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9351 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9352 if (!aTexture->IsDone())
9353 {
9354 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9355 }
3e05329c 9356 else
4269bd1b 9357 {
3e05329c 9358 aTexture->EnableModulate();
9359 aTexture->EnableRepeat();
9360 aClipPlane->SetCappingTexture (aTexture);
9361 }
9362 anArgIter += 1;
9363 }
9364 else if (aChangeArg == "-texscale"
9365 || aChangeArg == "texscale")
9366 {
9367 if (aClipPlane->CappingTexture().IsNull())
9368 {
23fe70ec 9369 Message::SendFail ("Error: no texture is set");
3e05329c 9370 return 1;
9371 }
4269bd1b 9372
3e05329c 9373 if (aNbChangeArgs < 3)
9374 {
23fe70ec 9375 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9376 return 1;
9377 }
4269bd1b 9378
3e05329c 9379 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9380 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9381 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9382 anArgIter += 2;
9383 }
9384 else if (aChangeArg == "-texorigin"
9385 || aChangeArg == "texorigin") // texture origin
9386 {
9387 if (aClipPlane->CappingTexture().IsNull())
9388 {
23fe70ec 9389 Message::SendFail ("Error: no texture is set");
3e05329c 9390 return 1;
9391 }
4269bd1b 9392
3e05329c 9393 if (aNbChangeArgs < 3)
9394 {
23fe70ec 9395 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9396 return 1;
4269bd1b 9397 }
3e05329c 9398
9399 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9400 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9401
9402 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9403 anArgIter += 2;
9404 }
9405 else if (aChangeArg == "-texrotate"
9406 || aChangeArg == "texrotate") // texture rotation
9407 {
9408 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9409 {
23fe70ec 9410 Message::SendFail ("Error: no texture is set");
3e05329c 9411 return 1;
9412 }
4269bd1b 9413
3e05329c 9414 if (aNbChangeArgs < 2)
9415 {
23fe70ec 9416 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9417 return 1;
9418 }
4269bd1b 9419
3e05329c 9420 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9421 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9422 anArgIter += 1;
9423 }
9424 else if (aChangeArg == "-hatch"
9425 || aChangeArg == "hatch")
9426 {
9427 if (aNbChangeArgs < 2)
9428 {
23fe70ec 9429 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9430 return 1;
9431 }
4269bd1b 9432
3e05329c 9433 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9434 aHatchStr.LowerCase();
9435 if (aHatchStr == "on")
9436 {
9437 aClipPlane->SetCappingHatchOn();
9438 }
9439 else if (aHatchStr == "off")
9440 {
9441 aClipPlane->SetCappingHatchOff();
4269bd1b 9442 }
3e05329c 9443 else
4269bd1b 9444 {
3e05329c 9445 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9446 }
9447 anArgIter += 1;
9448 }
9449 else if (aChangeArg == "-delete"
9450 || aChangeArg == "delete")
9451 {
9452 removePlane (aRegPlanes, aPlaneName);
9453 return 0;
9454 }
9455 else if (aChangeArg == "-set"
32ca7711 9456 || aChangeArg == "-unset"
9457 || aChangeArg == "-setoverrideglobal")
3e05329c 9458 {
9459 // set / unset plane command
32ca7711 9460 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9461 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9462 Standard_Integer anIt = 1;
9463 for (; anIt < aNbChangeArgs; ++anIt)
9464 {
9465 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9466 if (anEntityName.IsEmpty()
9467 || anEntityName.Value (1) == '-')
4269bd1b 9468 {
3e05329c 9469 break;
4269bd1b 9470 }
32ca7711 9471 else if (!toOverrideGlobal
9472 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9473 {
3e05329c 9474 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9475 if (toSet)
9476 {
9477 aView->AddClipPlane (aClipPlane);
9478 }
9479 else
9480 {
9481 aView->RemoveClipPlane (aClipPlane);
9482 }
9483 continue;
4269bd1b 9484 }
3e05329c 9485 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9486 {
8f521168 9487 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9488 if (toSet)
9489 {
9490 aIObj->AddClipPlane (aClipPlane);
9491 }
9492 else
9493 {
9494 aIObj->RemoveClipPlane (aClipPlane);
9495 }
32ca7711 9496 if (!aIObj->ClipPlanes().IsNull())
9497 {
9498 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9499 }
4269bd1b 9500 }
3e05329c 9501 else
4269bd1b 9502 {
23fe70ec 9503 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9504 return 1;
4269bd1b 9505 }
3e05329c 9506 }
9507
9508 if (anIt == 1)
9509 {
9510 // apply to active view
9511 if (toSet)
4269bd1b 9512 {
3e05329c 9513 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9514 }
9515 else
9516 {
3e05329c 9517 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9518 }
9519 }
3e05329c 9520 else
9521 {
9522 anArgIter = anArgIter + anIt - 1;
9523 }
9524 }
9525 else
9526 {
23fe70ec 9527 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9528 return 1;
4269bd1b 9529 }
4269bd1b 9530 }
9531
3e05329c 9532 ViewerTest::RedrawAllViews();
9533 return 0;
4269bd1b 9534}
9535
b5ac8292 9536//===============================================================================================
9537//function : VZRange
9538//purpose :
9539//===============================================================================================
9540static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9541{
197ac94e 9542 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9543
9544 if (aCurrentView.IsNull())
b5ac8292 9545 {
23fe70ec 9546 Message::SendFail ("Error: no active viewer");
b5ac8292 9547 return 1;
9548 }
9549
197ac94e 9550 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9551
9552 if (theArgsNb < 2)
9553 {
9554 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9555 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9556 return 0;
9557 }
9558
9559 if (theArgsNb == 3)
9560 {
6b62b2da 9561 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9562 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9563
9564 if (aNewZNear >= aNewZFar)
9565 {
23fe70ec 9566 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9567 return 1;
9568 }
9569
9570 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9571 {
23fe70ec 9572 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9573 return 1;
9574 }
9575
9576 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9577 }
9578 else
9579 {
23fe70ec 9580 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9581 return 1;
9582 }
9583
197ac94e 9584 aCurrentView->Redraw();
9585
b5ac8292 9586 return 0;
9587}
9588
9589//===============================================================================================
9590//function : VAutoZFit
9591//purpose :
9592//===============================================================================================
9593static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9594{
197ac94e 9595 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9596
9597 if (aCurrentView.IsNull())
b5ac8292 9598 {
23fe70ec 9599 Message::SendFail ("Error: no active viewer");
b5ac8292 9600 return 1;
9601 }
9602
c357e426 9603 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9604
9605 if (theArgsNb > 3)
b5ac8292 9606 {
23fe70ec 9607 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9608 return 1;
b5ac8292 9609 }
9610
197ac94e 9611 if (theArgsNb < 2)
b5ac8292 9612 {
586db386 9613 theDi << "Auto z-fit mode: \n"
c357e426 9614 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9615 << "Scale: " << aScale << "\n";
9616 return 0;
b5ac8292 9617 }
197ac94e 9618
9619 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9620
9621 if (theArgsNb >= 3)
b5ac8292 9622 {
197ac94e 9623 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9624 }
9625
c357e426 9626 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9627 aCurrentView->Redraw();
b5ac8292 9628 return 0;
9629}
9630
6b62b2da 9631//! Auxiliary function to print projection type
9632inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9633{
9634 switch (theProjType)
9635 {
9636 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9637 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9638 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9639 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9640 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9641 }
9642 return "UNKNOWN";
9643}
9644
b5ac8292 9645//===============================================================================================
6b62b2da 9646//function : VCamera
b5ac8292 9647//purpose :
9648//===============================================================================================
6b62b2da 9649static int VCamera (Draw_Interpretor& theDI,
9650 Standard_Integer theArgsNb,
9651 const char** theArgVec)
b5ac8292 9652{
6b62b2da 9653 Handle(V3d_View) aView = ViewerTest::CurrentView();
9654 if (aView.IsNull())
b5ac8292 9655 {
23fe70ec 9656 Message::SendFail ("Error: no active viewer");
b5ac8292 9657 return 1;
9658 }
9659
6b62b2da 9660 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9661 if (theArgsNb < 2)
b5ac8292 9662 {
6b62b2da 9663 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9664 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 9665 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9666 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 9667 theDI << "Distance: " << aCamera->Distance() << "\n";
9668 theDI << "IOD: " << aCamera->IOD() << "\n";
9669 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9670 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9671 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
9672 return 0;
b5ac8292 9673 }
9674
30a1b24e 9675 TCollection_AsciiString aPrsName;
6b62b2da 9676 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 9677 {
6b62b2da 9678 Standard_CString anArg = theArgVec[anArgIter];
9679 TCollection_AsciiString anArgCase (anArg);
9680 anArgCase.LowerCase();
9681 if (anArgCase == "-proj"
9682 || anArgCase == "-projection"
9683 || anArgCase == "-projtype"
9684 || anArgCase == "-projectiontype")
9685 {
9686 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9687 }
9688 else if (anArgCase == "-ortho"
9689 || anArgCase == "-orthographic")
b5ac8292 9690 {
9691 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 9692 }
9693 else if (anArgCase == "-persp"
9694 || anArgCase == "-perspective"
9695 || anArgCase == "-perspmono"
9696 || anArgCase == "-perspectivemono"
9697 || anArgCase == "-mono")
b5ac8292 9698 {
9699 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9700 }
6b62b2da 9701 else if (anArgCase == "-stereo"
9702 || anArgCase == "-stereoscopic"
9703 || anArgCase == "-perspstereo"
9704 || anArgCase == "-perspectivestereo")
9705 {
9706 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9707 }
9708 else if (anArgCase == "-left"
9709 || anArgCase == "-lefteye"
9710 || anArgCase == "-monoleft"
9711 || anArgCase == "-monolefteye"
9712 || anArgCase == "-perpsleft"
9713 || anArgCase == "-perpslefteye")
b5ac8292 9714 {
9715 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9716 }
6b62b2da 9717 else if (anArgCase == "-right"
9718 || anArgCase == "-righteye"
9719 || anArgCase == "-monoright"
9720 || anArgCase == "-monorighteye"
9721 || anArgCase == "-perpsright")
b5ac8292 9722 {
9723 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9724 }
6b62b2da 9725 else if (anArgCase == "-dist"
9726 || anArgCase == "-distance")
b5ac8292 9727 {
6b62b2da 9728 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9729 if (anArgValue != NULL
9730 && *anArgValue != '-')
9731 {
9732 ++anArgIter;
9733 aCamera->SetDistance (Draw::Atof (anArgValue));
9734 continue;
9735 }
9736 theDI << aCamera->Distance() << " ";
b5ac8292 9737 }
6b62b2da 9738 else if (anArgCase == "-iod")
b5ac8292 9739 {
6b62b2da 9740 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9741 if (anArgValue != NULL
9742 && *anArgValue != '-')
9743 {
9744 ++anArgIter;
9745 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9746 continue;
9747 }
9748 theDI << aCamera->IOD() << " ";
b5ac8292 9749 }
6b62b2da 9750 else if (anArgCase == "-iodtype")
b5ac8292 9751 {
6b62b2da 9752 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9753 TCollection_AsciiString anValueCase (anArgValue);
9754 anValueCase.LowerCase();
9755 if (anValueCase == "abs"
9756 || anValueCase == "absolute")
9757 {
9758 ++anArgIter;
9759 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9760 continue;
9761 }
9762 else if (anValueCase == "rel"
9763 || anValueCase == "relative")
9764 {
9765 ++anArgIter;
9766 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9767 continue;
9768 }
9769 else if (*anArgValue != '-')
9770 {
23fe70ec 9771 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 9772 return 1;
9773 }
9774 switch (aCamera->GetIODType())
9775 {
9776 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9777 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9778 }
b5ac8292 9779 }
6b62b2da 9780 else if (anArgCase == "-zfocus")
b5ac8292 9781 {
6b62b2da 9782 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9783 if (anArgValue != NULL
9784 && *anArgValue != '-')
9785 {
9786 ++anArgIter;
9787 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9788 continue;
9789 }
9790 theDI << aCamera->ZFocus() << " ";
b5ac8292 9791 }
6b62b2da 9792 else if (anArgCase == "-zfocustype")
b5ac8292 9793 {
6b62b2da 9794 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9795 TCollection_AsciiString anValueCase (anArgValue);
9796 anValueCase.LowerCase();
9797 if (anValueCase == "abs"
9798 || anValueCase == "absolute")
9799 {
9800 ++anArgIter;
9801 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9802 continue;
9803 }
9804 else if (anValueCase == "rel"
9805 || anValueCase == "relative")
9806 {
9807 ++anArgIter;
9808 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9809 continue;
9810 }
9811 else if (*anArgValue != '-')
9812 {
23fe70ec 9813 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 9814 return 1;
9815 }
9816 switch (aCamera->ZFocusType())
9817 {
9818 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9819 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9820 }
9821 }
b40cdc2b 9822 else if (anArgCase == "-lockzup"
9823 || anArgCase == "-turntable")
9824 {
9825 bool toLockUp = true;
9826 if (++anArgIter < theArgsNb
dae2a922 9827 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 9828 {
9829 --anArgIter;
9830 }
9831 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9832 }
6b62b2da 9833 else if (anArgCase == "-fov"
b40cdc2b 9834 || anArgCase == "-fovy"
9835 || anArgCase == "-fovx"
9836 || anArgCase == "-fov2d")
b5ac8292 9837 {
6b62b2da 9838 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9839 if (anArgValue != NULL
9840 && *anArgValue != '-')
9841 {
9842 ++anArgIter;
b40cdc2b 9843 if (anArgCase == "-fov2d")
9844 {
9845 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9846 }
9847 else if (anArgCase == "-fovx")
9848 {
9849 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9850 }
9851 else
9852 {
9853 aCamera->SetFOVy (Draw::Atof (anArgValue));
9854 }
6b62b2da 9855 continue;
9856 }
b40cdc2b 9857 if (anArgCase == "-fov2d")
9858 {
9859 theDI << aCamera->FOV2d() << " ";
9860 }
9861 else if (anArgCase == "-fovx")
9862 {
9863 theDI << aCamera->FOVx() << " ";
9864 }
9865 else
9866 {
9867 theDI << aCamera->FOVy() << " ";
9868 }
9869 }
9870 else if (anArgIter + 1 < theArgsNb
9871 && anArgCase == "-xrpose")
9872 {
9873 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9874 anXRArg.LowerCase();
9875 if (anXRArg == "base")
9876 {
9877 aCamera = aView->View()->BaseXRCamera();
9878 }
9879 else if (anXRArg == "head")
9880 {
9881 aCamera = aView->View()->PosedXRCamera();
9882 }
9883 else
9884 {
9885 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9886 return 1;
9887 }
9888 if (aCamera.IsNull())
9889 {
9890 Message::SendFail() << "Error: undefined XR pose";
9891 return 0;
9892 }
9893 if (aView->AutoZFitMode())
9894 {
9895 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9896 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9897 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9898 }
b5ac8292 9899 }
30a1b24e 9900 else if (aPrsName.IsEmpty()
9901 && !anArgCase.StartsWith ("-"))
9902 {
9903 aPrsName = anArg;
9904 }
b5ac8292 9905 else
9906 {
23fe70ec 9907 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 9908 return 1;
9909 }
9910 }
b5ac8292 9911
30a1b24e 9912 if (aPrsName.IsEmpty()
9913 || theArgsNb > 2)
9914 {
30a1b24e 9915 aView->Redraw();
9916 }
9917
9918 if (!aPrsName.IsEmpty())
9919 {
9920 Handle(AIS_CameraFrustum) aCameraFrustum;
9921 if (GetMapOfAIS().IsBound2 (aPrsName))
9922 {
9923 // find existing object
9924 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9925 if (aCameraFrustum.IsNull())
9926 {
23fe70ec 9927 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 9928 return 1;
9929 }
9930 }
9931
9932 if (aCameraFrustum.IsNull())
9933 {
9934 aCameraFrustum = new AIS_CameraFrustum();
9935 }
9936 else
9937 {
9938 // not include displayed object of old camera frustum in the new one.
9939 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9940 aView->ZFitAll();
9941 }
b40cdc2b 9942 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 9943
9944 ViewerTest::Display (aPrsName, aCameraFrustum);
9945 }
b5ac8292 9946
9947 return 0;
9948}
9949
f978241f 9950//! Parse stereo output mode
9951inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9952 Graphic3d_StereoMode& theMode)
9953{
9954 TCollection_AsciiString aFlag (theArg);
9955 aFlag.LowerCase();
9956 if (aFlag == "quadbuffer")
9957 {
9958 theMode = Graphic3d_StereoMode_QuadBuffer;
9959 }
9960 else if (aFlag == "anaglyph")
9961 {
9962 theMode = Graphic3d_StereoMode_Anaglyph;
9963 }
9964 else if (aFlag == "row"
9965 || aFlag == "rowinterlaced")
9966 {
9967 theMode = Graphic3d_StereoMode_RowInterlaced;
9968 }
9969 else if (aFlag == "col"
9970 || aFlag == "colinterlaced"
9971 || aFlag == "columninterlaced")
9972 {
9973 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9974 }
9975 else if (aFlag == "chess"
9976 || aFlag == "chessboard")
9977 {
9978 theMode = Graphic3d_StereoMode_ChessBoard;
9979 }
9980 else if (aFlag == "sbs"
9981 || aFlag == "sidebyside")
9982 {
9983 theMode = Graphic3d_StereoMode_SideBySide;
9984 }
9985 else if (aFlag == "ou"
9986 || aFlag == "overunder")
9987 {
9988 theMode = Graphic3d_StereoMode_OverUnder;
9989 }
9990 else if (aFlag == "pageflip"
9991 || aFlag == "softpageflip")
9992 {
9993 theMode = Graphic3d_StereoMode_SoftPageFlip;
9994 }
b40cdc2b 9995 else if (aFlag == "openvr"
9996 || aFlag == "vr")
9997 {
9998 theMode = Graphic3d_StereoMode_OpenVR;
9999 }
f978241f 10000 else
10001 {
10002 return Standard_False;
10003 }
10004 return Standard_True;
10005}
10006
10007//! Parse anaglyph filter
10008inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
10009 Graphic3d_RenderingParams::Anaglyph& theFilter)
10010{
10011 TCollection_AsciiString aFlag (theArg);
10012 aFlag.LowerCase();
10013 if (aFlag == "redcyansimple")
10014 {
10015 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10016 }
10017 else if (aFlag == "redcyan"
10018 || aFlag == "redcyanoptimized")
10019 {
10020 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
10021 }
10022 else if (aFlag == "yellowbluesimple")
10023 {
10024 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
10025 }
10026 else if (aFlag == "yellowblue"
10027 || aFlag == "yellowblueoptimized")
10028 {
10029 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
10030 }
10031 else if (aFlag == "greenmagenta"
10032 || aFlag == "greenmagentasimple")
10033 {
10034 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
10035 }
10036 else
10037 {
10038 return Standard_False;
10039 }
10040 return Standard_True;
10041}
10042
b5ac8292 10043//==============================================================================
10044//function : VStereo
10045//purpose :
10046//==============================================================================
10047
10048static int VStereo (Draw_Interpretor& theDI,
10049 Standard_Integer theArgNb,
10050 const char** theArgVec)
10051{
f978241f 10052 Handle(V3d_View) aView = ViewerTest::CurrentView();
b8db9379 10053 if (aView.IsNull())
b5ac8292 10054 {
b8db9379 10055 Message::SendFail ("Error: no active viewer");
10056 return 0;
10057 }
b5ac8292 10058
b8db9379 10059 Handle(Graphic3d_Camera) aCamera = aView->Camera();
10060 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
10061 if (theArgNb < 2)
10062 {
10063 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
b5ac8292 10064 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 10065 if (isActive)
10066 {
10067 TCollection_AsciiString aMode;
10068 switch (aView->RenderingParams().StereoMode)
10069 {
10070 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10071 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10072 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10073 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10074 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10075 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10076 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 10077 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 10078 case Graphic3d_StereoMode_Anaglyph :
10079 aMode = "anaglyph";
10080 switch (aView->RenderingParams().AnaglyphFilter)
10081 {
10082 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10083 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10084 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10085 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10086 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10087 default: break;
10088 }
10089 default: break;
10090 }
10091 theDI << "Mode " << aMode << "\n";
10092 }
b5ac8292 10093 return 0;
10094 }
10095
b8db9379 10096 Graphic3d_StereoMode aMode = aParams->StereoMode;
f978241f 10097 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10098 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10099 {
10100 Standard_CString anArg = theArgVec[anArgIter];
10101 TCollection_AsciiString aFlag (anArg);
10102 aFlag.LowerCase();
10103 if (anUpdateTool.parseRedrawMode (aFlag))
10104 {
10105 continue;
10106 }
10107 else if (aFlag == "0"
10108 || aFlag == "off")
10109 {
10110 if (++anArgIter < theArgNb)
10111 {
23fe70ec 10112 Message::SendFail ("Error: wrong number of arguments");
f978241f 10113 return 1;
10114 }
10115
b8db9379 10116 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
f978241f 10117 {
10118 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10119 }
f978241f 10120 return 0;
10121 }
10122 else if (aFlag == "1"
10123 || aFlag == "on")
10124 {
10125 if (++anArgIter < theArgNb)
10126 {
23fe70ec 10127 Message::SendFail ("Error: wrong number of arguments");
f978241f 10128 return 1;
10129 }
10130
b8db9379 10131 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 10132 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10133 {
10134 return 0;
10135 }
f978241f 10136 }
10137 else if (aFlag == "-reverse"
10138 || aFlag == "-reversed"
10139 || aFlag == "-swap")
10140 {
10141 Standard_Boolean toEnable = Standard_True;
10142 if (++anArgIter < theArgNb
dae2a922 10143 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10144 {
10145 --anArgIter;
10146 }
10147 aParams->ToReverseStereo = toEnable;
10148 }
10149 else if (aFlag == "-noreverse"
10150 || aFlag == "-noswap")
10151 {
10152 Standard_Boolean toDisable = Standard_True;
10153 if (++anArgIter < theArgNb
dae2a922 10154 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10155 {
10156 --anArgIter;
10157 }
10158 aParams->ToReverseStereo = !toDisable;
10159 }
10160 else if (aFlag == "-mode"
10161 || aFlag == "-stereomode")
10162 {
10163 if (++anArgIter >= theArgNb
10164 || !parseStereoMode (theArgVec[anArgIter], aMode))
10165 {
23fe70ec 10166 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10167 return 1;
10168 }
10169
10170 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10171 {
b8db9379 10172 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10173 }
10174 }
10175 else if (aFlag == "-anaglyph"
10176 || aFlag == "-anaglyphfilter")
10177 {
10178 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10179 if (++anArgIter >= theArgNb
10180 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10181 {
23fe70ec 10182 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10183 return 1;
10184 }
10185
10186 aMode = Graphic3d_StereoMode_Anaglyph;
10187 aParams->AnaglyphFilter = aFilter;
10188 }
10189 else if (parseStereoMode (anArg, aMode)) // short syntax
10190 {
10191 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10192 {
b8db9379 10193 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10194 }
10195 }
b40cdc2b 10196 else if (anArgIter + 1 < theArgNb
10197 && aFlag == "-hmdfov2d")
10198 {
10199 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10200 if (aParams->HmdFov2d < 10.0f
10201 || aParams->HmdFov2d > 180.0f)
10202 {
10203 Message::SendFail() << "Error: FOV is out of range";
10204 return 1;
10205 }
10206 }
10207 else if (aFlag == "-mirror"
10208 || aFlag == "-mirrorcomposer")
10209 {
10210 Standard_Boolean toEnable = Standard_True;
10211 if (++anArgIter < theArgNb
dae2a922 10212 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10213 {
10214 --anArgIter;
10215 }
10216 aParams->ToMirrorComposer = toEnable;
10217 }
10218 else if (anArgIter + 1 < theArgNb
10219 && (aFlag == "-unitfactor"
10220 || aFlag == "-unitscale"))
10221 {
10222 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10223 }
f978241f 10224 else
10225 {
23fe70ec 10226 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10227 return 1;
10228 }
10229 }
10230
b8db9379 10231 aParams->StereoMode = aMode;
10232 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10233 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
f978241f 10234 {
b8db9379 10235 // initiate implicit continuous rendering
10236 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
f978241f 10237 }
b5ac8292 10238 return 0;
10239}
10240
392ac980 10241//===============================================================================================
10242//function : VDefaults
10243//purpose :
10244//===============================================================================================
10245static int VDefaults (Draw_Interpretor& theDi,
10246 Standard_Integer theArgsNb,
10247 const char** theArgVec)
10248{
10249 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10250 if (aCtx.IsNull())
10251 {
23fe70ec 10252 Message::SendFail ("Error: no active viewer");
392ac980 10253 return 1;
10254 }
10255
10256 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10257 if (theArgsNb < 2)
10258 {
10259 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10260 {
10261 theDi << "DeflType: relative\n"
10262 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10263 }
10264 else
10265 {
10266 theDi << "DeflType: absolute\n"
10267 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10268 }
67441d0c 10269 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10270 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10271 return 0;
10272 }
10273
10274 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10275 {
10276 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10277 anArg.UpperCase();
10278 if (anArg == "-ABSDEFL"
10279 || anArg == "-ABSOLUTEDEFLECTION"
10280 || anArg == "-DEFL"
10281 || anArg == "-DEFLECTION")
392ac980 10282 {
4c513386 10283 if (++anArgIter >= theArgsNb)
10284 {
23fe70ec 10285 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10286 return 1;
10287 }
392ac980 10288 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10289 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10290 }
4c513386 10291 else if (anArg == "-RELDEFL"
10292 || anArg == "-RELATIVEDEFLECTION"
10293 || anArg == "-DEVCOEFF"
10294 || anArg == "-DEVIATIONCOEFF"
10295 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10296 {
4c513386 10297 if (++anArgIter >= theArgsNb)
10298 {
23fe70ec 10299 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10300 return 1;
10301 }
392ac980 10302 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10303 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10304 }
4c513386 10305 else if (anArg == "-ANGDEFL"
10306 || anArg == "-ANGULARDEFL"
10307 || anArg == "-ANGULARDEFLECTION")
392ac980 10308 {
4c513386 10309 if (++anArgIter >= theArgsNb)
10310 {
23fe70ec 10311 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10312 return 1;
10313 }
67441d0c 10314 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10315 }
385c43e7 10316 else if (anArg == "-AUTOTR"
10317 || anArg == "-AUTOTRIANG"
10318 || anArg == "-AUTOTRIANGULATION")
4c513386 10319 {
14c7f553 10320 ++anArgIter;
10321 bool toTurnOn = true;
10322 if (anArgIter >= theArgsNb
dae2a922 10323 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10324 {
23fe70ec 10325 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10326 return 1;
10327 }
14c7f553 10328 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10329 }
10330 else
10331 {
23fe70ec 10332 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10333 return 1;
392ac980 10334 }
10335 }
10336
10337 return 0;
10338}
10339
12381341 10340//! Auxiliary method
10341inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10342 const Graphic3d_ZLayerId theLayer,
12381341 10343 const Standard_Boolean theIsGlobal)
10344{
10345 if (theLightNew.IsNull())
10346 {
10347 return;
10348 }
10349
992ed6b3 10350 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10351 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10352 {
992ed6b3 10353 aViewer->AddLight (theLightNew);
10354 if (theIsGlobal)
10355 {
10356 aViewer->SetLightOn (theLightNew);
10357 }
10358 else
10359 {
10360 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10361 }
12381341 10362 }
10363 else
10364 {
992ed6b3 10365 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10366 if (aSettings.Lights().IsNull())
10367 {
10368 aSettings.SetLights (new Graphic3d_LightSet());
10369 }
10370 aSettings.Lights()->Add (theLightNew);
10371 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10372 }
10373}
10374
10375//! Auxiliary method
10376inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10377{
10378 TCollection_AsciiString anArgNextCase (theArgNext);
10379 anArgNextCase.UpperCase();
10380 if (anArgNextCase.Length() > 5
10381 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10382 {
10383 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10384 }
10385 else
10386 {
10387 return theArgNext.IntegerValue();
10388 }
10389}
10390
2daa5d95 10391static Handle(AIS_LightSource) findLightPrs (const Handle(V3d_Light)& theLight,
10392 const bool theToShowErrors = true)
10393{
10394 if (theLight.IsNull())
10395 {
10396 if (theToShowErrors)
10397 {
10398 Message::SendFail() << "Syntax error: no active light source to find presentation";
10399 }
10400 return Handle(AIS_LightSource)();
10401 }
10402
10403 Handle(AIS_InteractiveObject) anObject;
10404 GetMapOfAIS().Find2 (theLight->Name(), anObject);
10405 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (anObject);
10406 if (aLightSource.IsNull())
10407 {
10408 if (theToShowErrors)
10409 {
10410 Message::SendFail() << "Syntax error: could not find '" << theLight->Name() << "' AIS object";
10411 }
10412 }
10413 return aLightSource;
10414}
10415
12381341 10416//===============================================================================================
10417//function : VLight
10418//purpose :
10419//===============================================================================================
10420static int VLight (Draw_Interpretor& theDi,
10421 Standard_Integer theArgsNb,
10422 const char** theArgVec)
10423{
10424 Handle(V3d_View) aView = ViewerTest::CurrentView();
10425 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10426 if (aView.IsNull()
10427 || aViewer.IsNull())
10428 {
23fe70ec 10429 Message::SendFail ("Error: no active viewer");
12381341 10430 return 1;
10431 }
10432
ee2be2a8 10433 Standard_Real anXYZ[3] = {};
10434 Standard_Real anAtten[2] = {};
12381341 10435 if (theArgsNb < 2)
10436 {
10437 // print lights info
10438 Standard_Integer aLightId = 0;
6a24c6de 10439 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10440 {
6a24c6de 10441 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10442 const Quantity_Color aColor = aLight->Color();
992ed6b3 10443 theDi << "Light #" << aLightId
10444 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10445 << " [" << aLight->GetId() << "]" << "\n";
12381341 10446 switch (aLight->Type())
10447 {
10448 case V3d_AMBIENT:
10449 {
189f85a3 10450 theDi << " Type: Ambient\n";
10451 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10452 break;
10453 }
10454 case V3d_DIRECTIONAL:
10455 {
189f85a3 10456 theDi << " Type: Directional\n";
10457 theDi << " Intensity: " << aLight->Intensity() << "\n";
10458 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10459 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10460 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10461 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10462 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10463 break;
10464 }
10465 case V3d_POSITIONAL:
10466 {
189f85a3 10467 theDi << " Type: Positional\n";
10468 theDi << " Intensity: " << aLight->Intensity() << "\n";
10469 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10470 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10471 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10472 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10473 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10474 aLight->Attenuation (anAtten[0], anAtten[1]);
10475 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
88b312d3 10476 theDi << " Range: " << aLight->Range() << "\n";
12381341 10477 break;
10478 }
10479 case V3d_SPOT:
10480 {
189f85a3 10481 theDi << " Type: Spot\n";
10482 theDi << " Intensity: " << aLight->Intensity() << "\n";
10483 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10484 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10485 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10486 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10487 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10488 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10489 aLight->Attenuation (anAtten[0], anAtten[1]);
10490 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10491 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10492 theDi << " Exponent: " << aLight->Concentration() << "\n";
88b312d3 10493 theDi << " Range: " << aLight->Range() << "\n";
12381341 10494 break;
10495 }
10496 default:
10497 {
189f85a3 10498 theDi << " Type: UNKNOWN\n";
12381341 10499 break;
10500 }
10501 }
992ed6b3 10502 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10503 }
10504 }
10505
2daa5d95 10506 Handle(V3d_Light) aLightNew, aLightOld;
992ed6b3 10507 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10508 Standard_Boolean isGlobal = Standard_True;
10509 Standard_Boolean toCreate = Standard_False;
761d8807 10510 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10511 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10512 {
992ed6b3 10513 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10514
10515 TCollection_AsciiString aName, aValue;
10516 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10517 TCollection_AsciiString anArgCase (anArg);
10518 anArgCase.UpperCase();
761d8807 10519 if (anUpdateTool.parseRedrawMode (anArg))
10520 {
10521 continue;
10522 }
10523
12381341 10524 if (anArgCase.IsEqual ("NEW")
10525 || anArgCase.IsEqual ("ADD")
992ed6b3 10526 || anArgCase.IsEqual ("CREATE")
10527 || anArgCase.IsEqual ("-NEW")
10528 || anArgCase.IsEqual ("-ADD")
10529 || anArgCase.IsEqual ("-CREATE"))
12381341 10530 {
10531 toCreate = Standard_True;
10532 }
992ed6b3 10533 else if (anArgCase.IsEqual ("-LAYER")
10534 || anArgCase.IsEqual ("-ZLAYER"))
10535 {
10536 if (++anArgIt >= theArgsNb)
10537 {
23fe70ec 10538 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10539 return 1;
10540 }
10541
10542 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10543 aValStr.LowerCase();
10544 if (aValStr == "default"
10545 || aValStr == "def")
10546 {
10547 aLayer = Graphic3d_ZLayerId_Default;
10548 }
10549 else if (aValStr == "top")
10550 {
10551 aLayer = Graphic3d_ZLayerId_Top;
10552 }
10553 else if (aValStr == "topmost")
10554 {
10555 aLayer = Graphic3d_ZLayerId_Topmost;
10556 }
10557 else if (aValStr == "toposd"
10558 || aValStr == "osd")
10559 {
10560 aLayer = Graphic3d_ZLayerId_TopOSD;
10561 }
10562 else if (aValStr == "botosd"
10563 || aValStr == "bottom")
10564 {
10565 aLayer = Graphic3d_ZLayerId_BotOSD;
10566 }
10567 else if (aValStr.IsIntegerValue())
10568 {
10569 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10570 }
10571 else
10572 {
23fe70ec 10573 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10574 return 1;
10575 }
10576 }
12381341 10577 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10578 || anArgCase.IsEqual ("GLOBAL")
10579 || anArgCase.IsEqual ("-GLOB")
10580 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10581 {
10582 isGlobal = Standard_True;
10583 }
10584 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10585 || anArgCase.IsEqual ("LOCAL")
10586 || anArgCase.IsEqual ("-LOC")
10587 || anArgCase.IsEqual ("-LOCAL"))
12381341 10588 {
10589 isGlobal = Standard_False;
10590 }
4fe9ad57 10591 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10592 || anArgCase.IsEqual ("DEFAULTS")
10593 || anArgCase.IsEqual ("-DEF")
10594 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10595 {
10596 toCreate = Standard_False;
10597 aViewer->SetDefaultLights();
10598 }
10599 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10600 || anArgCase.IsEqual ("CLEAR")
10601 || anArgCase.IsEqual ("-CLR")
10602 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10603 {
10604 toCreate = Standard_False;
992ed6b3 10605
10606 TColStd_SequenceOfInteger aLayers;
10607 aViewer->GetAllZLayers (aLayers);
10608 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10609 {
992ed6b3 10610 if (aLayeriter.Value() == aLayer
10611 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10612 {
10613 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10614 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10615 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10616 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10617 {
10618 break;
10619 }
10620 }
10621 }
10622
10623 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10624 {
2daa5d95 10625 ViewerTest_DoubleMapOfInteractiveAndName aMap = GetMapOfAIS();
992ed6b3 10626 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10627 {
10628 Handle(V3d_Light) aLight = aLightIter.Value();
2daa5d95 10629 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLight, false))
10630 {
10631 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10632 GetMapOfAIS().UnBind2 (aLight->Name());
10633 }
992ed6b3 10634 aViewer->DelLight (aLight);
10635 aLightIter = aView->ActiveLightIterator();
10636 }
4fe9ad57 10637 }
10638 }
12381341 10639 else if (anArgCase.IsEqual ("AMB")
10640 || anArgCase.IsEqual ("AMBIENT")
10641 || anArgCase.IsEqual ("AMBLIGHT"))
10642 {
12381341 10643 if (!toCreate)
10644 {
23fe70ec 10645 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10646 return 1;
10647 }
992ed6b3 10648
10649 addLight (aLightNew, aLayer, isGlobal);
12381341 10650 toCreate = Standard_False;
992ed6b3 10651 aLightNew = new V3d_AmbientLight();
12381341 10652 }
10653 else if (anArgCase.IsEqual ("DIRECTIONAL")
10654 || anArgCase.IsEqual ("DIRLIGHT"))
10655 {
12381341 10656 if (!toCreate)
10657 {
23fe70ec 10658 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10659 return 1;
10660 }
992ed6b3 10661
10662 addLight (aLightNew, aLayer, isGlobal);
12381341 10663 toCreate = Standard_False;
992ed6b3 10664 aLightNew = new V3d_DirectionalLight();
12381341 10665 }
10666 else if (anArgCase.IsEqual ("SPOT")
10667 || anArgCase.IsEqual ("SPOTLIGHT"))
10668 {
12381341 10669 if (!toCreate)
10670 {
23fe70ec 10671 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10672 return 1;
10673 }
992ed6b3 10674
10675 addLight (aLightNew, aLayer, isGlobal);
12381341 10676 toCreate = Standard_False;
992ed6b3 10677 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10678 }
10679 else if (anArgCase.IsEqual ("POSLIGHT")
10680 || anArgCase.IsEqual ("POSITIONAL"))
10681 {
12381341 10682 if (!toCreate)
10683 {
23fe70ec 10684 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10685 return 1;
10686 }
992ed6b3 10687
10688 addLight (aLightNew, aLayer, isGlobal);
12381341 10689 toCreate = Standard_False;
992ed6b3 10690 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10691 }
992ed6b3 10692 else if (anArgCase.IsEqual ("CHANGE")
10693 || anArgCase.IsEqual ("-CHANGE"))
12381341 10694 {
12381341 10695 if (++anArgIt >= theArgsNb)
10696 {
23fe70ec 10697 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10698 return 1;
10699 }
10700
992ed6b3 10701 addLight (aLightNew, aLayer, isGlobal);
10702 aLightNew.Nullify();
12381341 10703 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
10704 Standard_Integer aLightIt = 0;
6a24c6de 10705 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10706 {
10707 if (aLightIt == aLightId)
10708 {
6a24c6de 10709 aLightOld = aLightIter.Value();
12381341 10710 break;
10711 }
10712 }
10713
10714 if (aLightOld.IsNull())
10715 {
23fe70ec 10716 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
12381341 10717 return 1;
10718 }
10719 }
2daa5d95 10720 else if (anArgCase == "-DISPLAY"
10721 || anArgCase == "-DISP"
10722 || anArgCase == "-PRESENTATION"
10723 || anArgCase == "-PRS")
10724 {
10725 if (aLightCurr.IsNull())
10726 {
10727 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10728 return 1;
10729 }
10730
10731 TCollection_AsciiString aLightName = aLightCurr->Name();
10732 if (++anArgIt > theArgsNb
10733 && aLightName.IsEmpty())
10734 {
10735 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10736 return 1;
10737 }
10738 if (anArgIt < theArgsNb)
10739 {
10740 if (theArgVec[anArgIt][0] != '-')
10741 {
10742 aLightName = theArgVec[anArgIt];
10743 aLightCurr->SetName (aLightName);
10744 }
10745 else
10746 {
10747 --anArgIt;
10748 }
10749 }
10750 if (aLightName.IsEmpty())
10751 {
10752 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10753 return 1;
10754 }
10755 ViewerTest::Display (aLightName, new AIS_LightSource (aLightCurr), false);
10756 }
10757 else if (anArgCase == "DEL"
10758 || anArgCase == "DELETE"
10759 || anArgCase == "-DEL"
10760 || anArgCase == "-DELETE"
10761 || anArgCase == "-REMOVE")
12381341 10762 {
10763 Handle(V3d_Light) aLightDel;
10764 if (++anArgIt >= theArgsNb)
10765 {
23fe70ec 10766 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10767 return 1;
10768 }
10769
10770 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
10771 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
10772 Standard_Integer aLightIt = 0;
6a24c6de 10773 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10774 {
6a24c6de 10775 aLightDel = aLightIter.Value();
12381341 10776 if (aLightIt == aLightDelId)
10777 {
10778 break;
10779 }
10780 }
992ed6b3 10781 if (aLightDel.IsNull())
10782 {
10783 continue;
10784 }
10785
10786 TColStd_SequenceOfInteger aLayers;
10787 aViewer->GetAllZLayers (aLayers);
10788 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10789 {
10790 if (aLayeriter.Value() == aLayer
10791 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10792 {
10793 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10794 if (!aSettings.Lights().IsNull())
10795 {
10796 aSettings.Lights()->Remove (aLightDel);
10797 if (aSettings.Lights()->IsEmpty())
10798 {
10799 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10800 }
10801 }
10802 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10803 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10804 {
10805 break;
10806 }
10807 }
10808 }
10809
10810 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10811 {
2daa5d95 10812 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLightDel, false))
10813 {
10814 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10815 GetMapOfAIS().UnBind2 (aLightDel->Name());
10816 }
12381341 10817 aViewer->DelLight (aLightDel);
10818 }
10819 }
10820 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 10821 || anArgCase.IsEqual ("COLOUR")
10822 || anArgCase.IsEqual ("-COLOR")
10823 || anArgCase.IsEqual ("-COLOUR"))
12381341 10824 {
dae2a922 10825 Quantity_Color aColor;
10826 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10827 theArgVec + anArgIt + 1,
10828 aColor);
10829 anArgIt += aNbParsed;
10830 if (aNbParsed == 0
992ed6b3 10831 || aLightCurr.IsNull())
12381341 10832 {
23fe70ec 10833 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10834 return 1;
10835 }
992ed6b3 10836 aLightCurr->SetColor (aColor);
12381341 10837 }
2daa5d95 10838 else if (anArgCase == "POS"
10839 || anArgCase == "POSITION"
10840 || anArgCase == "-POS"
10841 || anArgCase == "-POSITION"
10842 || anArgCase == "-PRSPOSITION"
10843 || anArgCase == "-PRSPOS")
12381341 10844 {
2daa5d95 10845 gp_XYZ aPosXYZ;
992ed6b3 10846 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10847 || !parseXYZ (theArgVec + anArgIt + 1, aPosXYZ)
10848 || aLightCurr.IsNull())
12381341 10849 {
23fe70ec 10850 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10851 return 1;
10852 }
10853
2daa5d95 10854 anArgIt += 3;
10855 if (anArgCase == "-PRSPOSITION"
10856 || anArgCase == "-PRSPOS")
10857 {
10858 aLightCurr->SetDisplayPosition (aPosXYZ);
10859 }
10860 else
10861 {
10862 if (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10863 && aLightCurr->Type() != Graphic3d_TOLS_SPOT)
10864 {
10865 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10866 return 1;
10867 }
10868
10869 aLightCurr->SetPosition (aPosXYZ);
10870 }
12381341 10871 }
10872 else if (anArgCase.IsEqual ("DIR")
992ed6b3 10873 || anArgCase.IsEqual ("DIRECTION")
10874 || anArgCase.IsEqual ("-DIR")
10875 || anArgCase.IsEqual ("-DIRECTION"))
12381341 10876 {
2daa5d95 10877 gp_XYZ aDirXYZ;
992ed6b3 10878 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10879 || !parseXYZ (theArgVec + anArgIt + 1, aDirXYZ)
992ed6b3 10880 || aLightCurr.IsNull()
10881 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
10882 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10883 {
23fe70ec 10884 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10885 return 1;
10886 }
10887
2daa5d95 10888 anArgIt += 3;
10889 aLightCurr->SetDirection (gp_Dir (aDirXYZ));
12381341 10890 }
189f85a3 10891 else if (anArgCase.IsEqual ("SM")
992ed6b3 10892 || anArgCase.IsEqual ("SMOOTHNESS")
10893 || anArgCase.IsEqual ("-SM")
10894 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 10895 {
992ed6b3 10896 if (++anArgIt >= theArgsNb
10897 || aLightCurr.IsNull())
189f85a3 10898 {
23fe70ec 10899 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10900 return 1;
10901 }
10902
992ed6b3 10903 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10904 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 10905 {
10906 aLightCurr->SetIntensity (1.f);
10907 }
992ed6b3 10908 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 10909 {
10910 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10911 }
10912 else
10913 {
10914 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
10915 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10916 }
10917
992ed6b3 10918 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 10919 {
992ed6b3 10920 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 10921 }
992ed6b3 10922 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 10923 {
992ed6b3 10924 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 10925 }
10926 }
10927 else if (anArgCase.IsEqual ("INT")
992ed6b3 10928 || anArgCase.IsEqual ("INTENSITY")
10929 || anArgCase.IsEqual ("-INT")
10930 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 10931 {
992ed6b3 10932 if (++anArgIt >= theArgsNb
10933 || aLightCurr.IsNull())
189f85a3 10934 {
23fe70ec 10935 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10936 return 1;
10937 }
10938
992ed6b3 10939 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10940 aLightCurr->SetIntensity (aIntensity);
189f85a3 10941 }
4fe9ad57 10942 else if (anArgCase.IsEqual ("ANG")
992ed6b3 10943 || anArgCase.IsEqual ("ANGLE")
10944 || anArgCase.IsEqual ("-ANG")
10945 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 10946 {
992ed6b3 10947 if (++anArgIt >= theArgsNb
10948 || aLightCurr.IsNull()
10949 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 10950 {
23fe70ec 10951 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4fe9ad57 10952 return 1;
10953 }
992ed6b3 10954 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
2daa5d95 10955 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10956 aLightCurr->SetAngle (anAngle);
4fe9ad57 10957 }
12381341 10958 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 10959 || anArgCase.IsEqual ("CONSTATTENUATION")
10960 || anArgCase.IsEqual ("-CONSTATTEN")
10961 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 10962 {
992ed6b3 10963 if (++anArgIt >= theArgsNb
10964 || aLightCurr.IsNull()
10965 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10966 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10967 {
23fe70ec 10968 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10969 return 1;
10970 }
10971
992ed6b3 10972 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10973 anAtten[0] = Atof (theArgVec[anArgIt]);
10974 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10975 }
10976 else if (anArgCase.IsEqual ("LINATTEN")
10977 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 10978 || anArgCase.IsEqual ("LINEARATTENUATION")
10979 || anArgCase.IsEqual ("-LINATTEN")
10980 || anArgCase.IsEqual ("-LINEARATTEN")
10981 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 10982 {
992ed6b3 10983 if (++anArgIt >= theArgsNb
10984 || aLightCurr.IsNull()
10985 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10986 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10987 {
23fe70ec 10988 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10989 return 1;
10990 }
10991
992ed6b3 10992 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10993 anAtten[1] = Atof (theArgVec[anArgIt]);
10994 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10995 }
10996 else if (anArgCase.IsEqual ("EXP")
10997 || anArgCase.IsEqual ("EXPONENT")
10998 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 10999 || anArgCase.IsEqual ("SPOTEXPONENT")
11000 || anArgCase.IsEqual ("-EXP")
11001 || anArgCase.IsEqual ("-EXPONENT")
11002 || anArgCase.IsEqual ("-SPOTEXP")
11003 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 11004 {
992ed6b3 11005 if (++anArgIt >= theArgsNb
11006 || aLightCurr.IsNull()
11007 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 11008 {
23fe70ec 11009 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11010 return 1;
11011 }
11012
992ed6b3 11013 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 11014 }
88b312d3 11015 else if (anArgCase.IsEqual("RANGE")
11016 || anArgCase.IsEqual("-RANGE"))
11017 {
11018 if (++anArgIt >= theArgsNb
11019 || aLightCurr.IsNull()
11020 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
11021 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
11022 {
23fe70ec 11023 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
88b312d3 11024 return 1;
11025 }
2daa5d95 11026 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
11027 aLightCurr->SetRange (aRange);
88b312d3 11028 }
12381341 11029 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 11030 || anArgCase.IsEqual ("HEADLIGHT")
11031 || anArgCase.IsEqual ("-HEAD")
11032 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 11033 {
992ed6b3 11034 if (aLightCurr.IsNull()
11035 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 11036 {
23fe70ec 11037 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11038 return 1;
11039 }
11040
992ed6b3 11041 Standard_Boolean isHeadLight = Standard_True;
11042 if (anArgIt + 1 < theArgsNb
dae2a922 11043 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 11044 {
992ed6b3 11045 ++anArgIt;
12381341 11046 }
992ed6b3 11047 aLightCurr->SetHeadlight (isHeadLight);
12381341 11048 }
2daa5d95 11049 else if (anArgCase.IsEqual ("NAME")
11050 || anArgCase.IsEqual ("-NAME"))
11051 {
11052 if ((anArgIt + 1) >= theArgsNb
11053 || aLightCurr.IsNull())
11054 {
11055 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11056 return 1;
11057 }
11058 aName = theArgVec[++anArgIt];
11059 aLightCurr->SetName (aName);
11060 }
11061 else if (anArgCase == "-SHOWZOOMABLE"
11062 || anArgCase == "-PRSZOOMABLE"
11063 || anArgCase == "-ZOOMABLE")
11064 {
11065 if (aLightCurr.IsNull())
11066 {
11067 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11068 return 1;
11069 }
11070
11071 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11072 {
11073 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11074 aLightSource->SetZoomable (isZoomable);
11075 }
11076 else
11077 {
11078 return 1;
11079 }
11080 }
11081 else if (anArgCase == "-SHOWNAME"
11082 || anArgCase == "-PRSNAME")
11083 {
11084 if (aLightCurr.IsNull())
11085 {
11086 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11087 return 1;
11088 }
11089
11090 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11091 {
11092 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11093 aLightSource->SetDisplayName (toDisplay);
11094 }
11095 else
11096 {
11097 return 1;
11098 }
11099 }
11100 else if (anArgCase == "-SHOWRANGE"
11101 || anArgCase == "-PRSRANGE")
11102 {
11103 if (aLightCurr.IsNull()
11104 || (aLightCurr->Type() != Graphic3d_TOLS_SPOT
11105 && aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL))
11106 {
11107 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11108 return 1;
11109 }
11110
11111 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11112 {
11113 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11114 aLightSource->SetDisplayRange (toDisplay);
11115 }
11116 else
11117 {
11118 return 1;
11119 }
11120 }
11121 else if (anArgCase == "-SHOWSIZE"
11122 || anArgCase == "-PRSSIZE")
11123 {
11124 Standard_Real aSize = 0.0;
11125 if ((anArgIt + 1) >= theArgsNb
11126 || !Draw::ParseReal (theArgVec[anArgIt + 1], aSize)
11127 || aSize <= 0.0)
11128 {
11129 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11130 return 1;
11131 }
11132
11133 ++anArgIt;
11134 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11135 {
11136 aLightSource->SetSize (aSize);
11137 }
11138 else
11139 {
11140 return 1;
11141 }
11142 }
d84e8669 11143 else if (anArgCase.IsEqual ("-CASTSHADOW")
11144 || anArgCase.IsEqual ("-CASTSHADOWS")
11145 || anArgCase.IsEqual ("-SHADOWS"))
11146 {
11147 if (aLightCurr.IsNull()
11148 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
11149 {
11150 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11151 return 1;
11152 }
11153
11154 bool toCastShadows = true;
11155 if (anArgIt + 1 < theArgsNb
11156 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
11157 {
11158 ++anArgIt;
11159 }
11160 aLightCurr->SetCastShadows (toCastShadows);
11161 }
12381341 11162 else
11163 {
23fe70ec 11164 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
12381341 11165 }
11166 }
11167
992ed6b3 11168 addLight (aLightNew, aLayer, isGlobal);
2daa5d95 11169
11170 struct LightPrsSort
11171 {
11172 bool operator() (const Handle(AIS_LightSource)& theLeft,
11173 const Handle(AIS_LightSource)& theRight)
11174 {
11175 return theLeft->Light()->GetId() < theRight->Light()->GetId();
11176 }
11177 };
11178
11179 AIS_ListOfInteractive aPrsList;
11180 ViewerTest::GetAISContext()->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
11181 if (!aPrsList.IsEmpty())
11182 {
11183 // update light source presentations
11184 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
11185 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
11186 {
11187 if (Handle(AIS_LightSource) aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
11188 {
11189 aLightPrsVec.push_back (aLightPrs);
11190 }
11191 }
11192
11193 // sort objects by id as AIS_InteractiveContext stores them in unordered map
11194 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
11195
11196 Standard_Integer aTopStack = 0;
11197 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
11198 {
11199 Handle(AIS_LightSource) aLightPrs = *aPrsIter;
11200 if (!aLightPrs->TransformPersistence().IsNull()
11201 && aLightPrs->TransformPersistence()->IsTrihedronOr2d())
11202 {
11203 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs->Size();
11204 aLightPrs->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
11205 aTopStack += aPrsSize + aPrsSize / 2;
11206 }
11207 ViewerTest::GetAISContext()->Redisplay (aLightPrs, false);
11208 ViewerTest::GetAISContext()->SetTransformPersistence (aLightPrs, aLightPrs->TransformPersistence());
11209 }
11210 }
12381341 11211 return 0;
11212}
11213
67312b79 11214//===============================================================================================
11215//function : VPBREnvironment
11216//purpose :
11217//===============================================================================================
11218static int VPBREnvironment (Draw_Interpretor&,
11219 Standard_Integer theArgsNb,
11220 const char** theArgVec)
11221{
11222 if (theArgsNb > 2)
11223 {
23fe70ec 11224 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11225 return 1;
11226 }
11227
11228 Handle(V3d_View) aView = ViewerTest::CurrentView();
11229 if (aView.IsNull())
11230 {
23fe70ec 11231 Message::SendFail ("Error: no active viewer");
67312b79 11232 return 1;
11233 }
11234
11235 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11236 anArg.LowerCase();
11237
11238 if (anArg == "-generate"
11239 || anArg == "-gen")
11240 {
11241 aView->GeneratePBREnvironment (Standard_True);
11242 }
11243 else if (anArg == "-clear")
11244 {
11245 aView->ClearPBREnvironment (Standard_True);
11246 }
11247 else
11248 {
23fe70ec 11249 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11250 return 1;
11251 }
11252
11253 return 0;
11254}
11255
15669413 11256//! Read Graphic3d_RenderingParams::PerfCounters flag.
11257static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11258 Standard_Boolean& theToReset,
11259 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11260 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11261{
11262 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11263 TCollection_AsciiString aVal = theValue;
11264 Standard_Boolean toReverse = Standard_False;
11265 if (aVal == "none")
11266 {
11267 theToReset = Standard_True;
11268 return Standard_True;
11269 }
11270 else if (aVal.StartsWith ("-"))
11271 {
11272 toReverse = Standard_True;
11273 aVal = aVal.SubString (2, aVal.Length());
11274 }
11275 else if (aVal.StartsWith ("no"))
11276 {
11277 toReverse = Standard_True;
11278 aVal = aVal.SubString (3, aVal.Length());
11279 }
11280 else if (aVal.StartsWith ("+"))
11281 {
11282 aVal = aVal.SubString (2, aVal.Length());
11283 }
11284 else
11285 {
11286 theToReset = Standard_True;
11287 }
11288
11289 if ( aVal == "fps"
11290 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11291 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11292 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11293 else if (aVal == "structs"
11294 || aVal == "structures"
11295 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11296 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11297 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11298 else if (aVal == "tris"
11299 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11300 else if (aVal == "pnts"
11301 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11302 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11303 else if (aVal == "mem"
11304 || aVal == "gpumem"
11305 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11306 else if (aVal == "skipimmediate"
11307 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11308 else if (aVal == "frametime"
11309 || aVal == "frametimers"
11310 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11311 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11312 else if (aVal == "extended"
11313 || aVal == "verbose"
11314 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11315 else if (aVal == "full"
11316 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11317 else
11318 {
11319 return Standard_False;
11320 }
11321
11322 if (toReverse)
11323 {
11324 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11325 }
11326 else
11327 {
11328 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11329 }
11330 return Standard_True;
11331}
11332
11333//! Read Graphic3d_RenderingParams::PerfCounters flags.
11334static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11335 Graphic3d_RenderingParams::PerfCounters& theFlags)
11336{
11337 TCollection_AsciiString aValue = theValue;
11338 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11339 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11340 Standard_Boolean toReset = Standard_False;
11341 for (;;)
11342 {
11343 Standard_Integer aSplitPos = aValue.Search ("|");
11344 if (aSplitPos <= 0)
11345 {
11346 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11347 {
11348 return Standard_False;
11349 }
11350 if (toReset)
11351 {
11352 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11353 }
11354 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11355 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11356 return Standard_True;
11357 }
11358
11359 if (aSplitPos > 1)
11360 {
11361 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11362 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11363 {
11364 return Standard_False;
11365 }
11366 }
11367 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11368 }
11369}
11370
e276548b 11371//=======================================================================
bc8c79bb 11372//function : VRenderParams
11373//purpose : Enables/disables rendering features
e276548b 11374//=======================================================================
11375
bc8c79bb 11376static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11377 Standard_Integer theArgNb,
11378 const char** theArgVec)
e276548b 11379{
7ae4a307 11380 Handle(V3d_View) aView = ViewerTest::CurrentView();
11381 if (aView.IsNull())
e276548b 11382 {
23fe70ec 11383 Message::SendFail ("Error: no active viewer");
e276548b 11384 return 1;
11385 }
bc8c79bb 11386
11387 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11388 TCollection_AsciiString aCmdName (theArgVec[0]);
11389 aCmdName.LowerCase();
11390 if (aCmdName == "vraytrace")
11391 {
11392 if (theArgNb == 1)
11393 {
11394 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11395 return 0;
11396 }
11397 else if (theArgNb == 2)
11398 {
11399 TCollection_AsciiString aValue (theArgVec[1]);
11400 aValue.LowerCase();
11401 if (aValue == "on"
11402 || aValue == "1")
11403 {
11404 aParams.Method = Graphic3d_RM_RAYTRACING;
11405 aView->Redraw();
11406 return 0;
11407 }
11408 else if (aValue == "off"
11409 || aValue == "0")
11410 {
11411 aParams.Method = Graphic3d_RM_RASTERIZATION;
11412 aView->Redraw();
11413 return 0;
11414 }
11415 else
11416 {
23fe70ec 11417 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11418 return 1;
11419 }
11420 }
11421 else
11422 {
23fe70ec 11423 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11424 return 1;
11425 }
11426 }
bc8c79bb 11427
11428 if (theArgNb < 2)
e276548b 11429 {
bc8c79bb 11430 theDI << "renderMode: ";
11431 switch (aParams.Method)
11432 {
11433 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11434 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11435 }
11436 theDI << "\n";
a1073ae2 11437 theDI << "transparency: ";
11438 switch (aParams.TransparencyMethod)
11439 {
11440 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11441 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11442 << TCollection_AsciiString (aParams.OitDepthFactor); break;
78c4e836 11443 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11444 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
a1073ae2 11445 }
11446 theDI << "\n";
b4327ba8 11447 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11448 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11449 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11450 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11451 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
d84e8669 11452 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11453 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
b4327ba8 11454 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11455 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11456 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11457 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11458 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11459 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11460 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11461 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11462 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11463 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11464 theDI << "shadingModel: ";
11465 switch (aView->ShadingModel())
11466 {
67312b79 11467 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11468 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11469 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11470 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11471 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11472 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11473 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11474 }
37f80e16 11475 theDI << "\n";
15669413 11476 {
11477 theDI << "perfCounters:";
11478 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11479 {
11480 theDI << " fps";
11481 }
11482 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11483 {
11484 theDI << " cpu";
11485 }
11486 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11487 {
11488 theDI << " structs";
11489 }
11490 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11491 {
11492 theDI << " groups";
11493 }
11494 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11495 {
11496 theDI << " arrays";
11497 }
11498 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11499 {
11500 theDI << " tris";
11501 }
b9f43ad1 11502 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11503 {
11504 theDI << " lines";
11505 }
15669413 11506 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11507 {
11508 theDI << " pnts";
11509 }
11510 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11511 {
11512 theDI << " gpumem";
11513 }
5e30547b 11514 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11515 {
11516 theDI << " frameTime";
11517 }
11518 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11519 {
11520 theDI << " skipimmediate";
11521 }
15669413 11522 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11523 {
11524 theDI << " none";
11525 }
11526 theDI << "\n";
11527 }
f88457e6 11528 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11529 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11530 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11531 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11532 "noUpdate") << "\n";
8625ef7e 11533 theDI << "\n";
bc8c79bb 11534 return 0;
e276548b 11535 }
11536
4c7a3fae 11537 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11538 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11539 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11540 {
bc8c79bb 11541 Standard_CString anArg (theArgVec[anArgIter]);
11542 TCollection_AsciiString aFlag (anArg);
11543 aFlag.LowerCase();
8625ef7e 11544 if (anUpdateTool.parseRedrawMode (aFlag))
11545 {
11546 continue;
11547 }
11548 else if (aFlag == "-echo"
11549 || aFlag == "-print")
e276548b 11550 {
bc8c79bb 11551 toPrint = Standard_True;
8625ef7e 11552 anUpdateTool.Invalidate();
e276548b 11553 }
4c7a3fae 11554 else if (aFlag == "-reset")
11555 {
11556 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11557 }
11558 else if (aFlag == "-sync"
11559 && (anArgIter + 1 < theArgNb))
11560 {
11561 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11562 aSyncFlag.LowerCase();
11563 if (aSyncFlag == "default"
11564 || aSyncFlag == "defaults"
11565 || aSyncFlag == "viewer")
11566 {
11567 toSyncDefaults = true;
11568 }
11569 else if (aSyncFlag == "allviews"
11570 || aSyncFlag == "views")
11571 {
11572 toSyncAllViews = true;
11573 }
11574 else
11575 {
11576 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11577 return 1;
11578 }
11579 }
bc8c79bb 11580 else if (aFlag == "-mode"
11581 || aFlag == "-rendermode"
11582 || aFlag == "-render_mode")
e276548b 11583 {
bc8c79bb 11584 if (toPrint)
11585 {
11586 switch (aParams.Method)
11587 {
11588 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11589 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11590 }
11591 continue;
11592 }
e276548b 11593 else
bc8c79bb 11594 {
23fe70ec 11595 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11596 return 1;
11597 }
11598 }
11599 else if (aFlag == "-ray"
11600 || aFlag == "-raytrace")
11601 {
11602 if (toPrint)
11603 {
11604 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11605 continue;
11606 }
11607
4c7a3fae 11608 bool isRayTrace = true;
11609 if (anArgIter + 1 < theArgNb
dae2a922 11610 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11611 {
11612 ++anArgIter;
11613 }
11614 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11615 }
bc8c79bb 11616 else if (aFlag == "-rast"
11617 || aFlag == "-raster"
11618 || aFlag == "-rasterization")
e276548b 11619 {
bc8c79bb 11620 if (toPrint)
11621 {
11622 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11623 continue;
11624 }
11625
4c7a3fae 11626 bool isRaster = true;
11627 if (anArgIter + 1 < theArgNb
dae2a922 11628 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11629 {
11630 ++anArgIter;
11631 }
11632 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11633 }
3c4b62a4 11634 else if (aFlag == "-msaa")
11635 {
11636 if (toPrint)
11637 {
11638 theDI << aParams.NbMsaaSamples << " ";
11639 continue;
11640 }
11641 else if (++anArgIter >= theArgNb)
11642 {
23fe70ec 11643 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11644 return 1;
11645 }
11646
11647 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11648 if (aNbSamples < 0)
11649 {
23fe70ec 11650 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 11651 return 1;
11652 }
11653 else
11654 {
11655 aParams.NbMsaaSamples = aNbSamples;
11656 }
11657 }
2a332745 11658 else if (aFlag == "-linefeather"
11659 || aFlag == "-edgefeather"
11660 || aFlag == "-feather")
11661 {
11662 if (toPrint)
11663 {
11664 theDI << " " << aParams.LineFeather << " ";
11665 continue;
11666 }
11667 else if (++anArgIter >= theArgNb)
11668 {
23fe70ec 11669 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 11670 return 1;
11671 }
11672
11673 TCollection_AsciiString aParam = theArgVec[anArgIter];
11674 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11675 if (aFeather <= 0.0f)
11676 {
23fe70ec 11677 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 11678 return 1;
11679 }
11680 aParams.LineFeather = aFeather;
11681 }
a1073ae2 11682 else if (aFlag == "-oit")
11683 {
11684 if (toPrint)
11685 {
11686 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11687 {
11688 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11689 }
78c4e836 11690 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11691 {
11692 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11693 }
a1073ae2 11694 else
11695 {
11696 theDI << "off" << " ";
11697 }
11698 continue;
11699 }
11700 else if (++anArgIter >= theArgNb)
11701 {
23fe70ec 11702 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11703 return 1;
11704 }
11705
11706 TCollection_AsciiString aParam = theArgVec[anArgIter];
11707 aParam.LowerCase();
78c4e836 11708 if (aParam == "peeling"
11709 || aParam == "peel")
11710 {
11711 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11712 if (anArgIter + 1 < theArgNb
11713 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11714 {
11715 ++anArgIter;
11716 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11717 if (aNbLayers < 2)
11718 {
11719 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11720 return 1;
11721 }
11722 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11723 }
11724 }
11725 else if (aParam == "weighted"
11726 || aParam == "weight")
11727 {
11728 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11729 if (anArgIter + 1 < theArgNb
11730 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11731 {
11732 ++anArgIter;
11733 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11734 if (aWeight < 0.f || aWeight > 1.f)
11735 {
11736 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11737 return 1;
11738 }
11739 aParams.OitDepthFactor = aWeight;
11740 }
11741 }
11742 else if (aParam.IsRealValue())
a1073ae2 11743 {
11744 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11745 if (aWeight < 0.f || aWeight > 1.f)
11746 {
23fe70ec 11747 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 11748 return 1;
11749 }
11750
11751 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11752 aParams.OitDepthFactor = aWeight;
11753 }
11754 else if (aParam == "off")
11755 {
11756 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11757 }
11758 else
11759 {
23fe70ec 11760 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11761 return 1;
11762 }
11763 }
d37aef5c 11764 else if (aFlag == "-fonthinting"
11765 || aFlag == "-fonthint")
11766 {
11767 if (toPrint)
11768 {
11769 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11770 {
11771 theDI << "normal" << " ";
11772 }
11773 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11774 {
11775 theDI << "light" << " ";
11776 }
11777 else
11778 {
11779 theDI << "off" << " ";
11780 }
11781 continue;
11782 }
11783 else if (anArgIter + 1 >= theArgNb)
11784 {
11785 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11786 return 1;
11787 }
11788
11789 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11790 aHintStyle.LowerCase();
11791 if (aHintStyle == "normal"
11792 || aHintStyle == "on"
11793 || aHintStyle == "1")
11794 {
11795 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11796 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11797 }
11798 else if (aHintStyle == "light")
11799 {
11800 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11801 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11802 }
11803 else if (aHintStyle == "no"
11804 || aHintStyle == "off"
11805 || aHintStyle == "0")
11806 {
11807 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11808 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11809 }
11810 else
11811 {
11812 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11813 return 1;
11814 }
11815 }
11816 else if (aFlag == "-fontautohinting"
11817 || aFlag == "-fontautohint")
11818 {
11819 if (toPrint)
11820 {
11821 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11822 {
11823 theDI << "force" << " ";
11824 }
11825 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11826 {
11827 theDI << "disallow" << " ";
11828 }
11829 else
11830 {
11831 theDI << "auto" << " ";
11832 }
11833 continue;
11834 }
11835 else if (anArgIter + 1 >= theArgNb)
11836 {
11837 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11838 return 1;
11839 }
11840
11841 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11842 aHintStyle.LowerCase();
11843 if (aHintStyle == "force")
11844 {
11845 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11846 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11847 }
11848 else if (aHintStyle == "disallow"
11849 || aHintStyle == "no")
11850 {
11851 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11852 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11853 }
11854 else if (aHintStyle == "auto")
11855 {
11856 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11857 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11858 }
11859 else
11860 {
11861 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11862 return 1;
11863 }
11864 }
f88457e6 11865 else if (aFlag == "-depthprepass")
11866 {
11867 if (toPrint)
11868 {
11869 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11870 continue;
11871 }
11872 aParams.ToEnableDepthPrepass = Standard_True;
11873 if (anArgIter + 1 < theArgNb
dae2a922 11874 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 11875 {
11876 ++anArgIter;
11877 }
11878 }
c40eb6b9 11879 else if (aFlag == "-samplealphatocoverage"
11880 || aFlag == "-alphatocoverage")
11881 {
11882 if (toPrint)
11883 {
11884 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11885 continue;
11886 }
11887 aParams.ToEnableAlphaToCoverage = Standard_True;
11888 if (anArgIter + 1 < theArgNb
dae2a922 11889 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 11890 {
11891 ++anArgIter;
11892 }
11893 }
56689b27 11894 else if (aFlag == "-rendscale"
11895 || aFlag == "-renderscale"
11896 || aFlag == "-renderresolutionscale")
11897 {
11898 if (toPrint)
11899 {
11900 theDI << aParams.RenderResolutionScale << " ";
11901 continue;
11902 }
11903 else if (++anArgIter >= theArgNb)
11904 {
23fe70ec 11905 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 11906 return 1;
11907 }
11908
11909 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11910 if (aScale < 0.01)
11911 {
23fe70ec 11912 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 11913 return 1;
11914 }
11915 else
11916 {
11917 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11918 }
11919 }
bc8c79bb 11920 else if (aFlag == "-raydepth"
11921 || aFlag == "-ray_depth")
11922 {
11923 if (toPrint)
11924 {
11925 theDI << aParams.RaytracingDepth << " ";
11926 continue;
11927 }
11928 else if (++anArgIter >= theArgNb)
11929 {
23fe70ec 11930 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11931 return 1;
11932 }
11933
11934 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 11935
11936 // We allow RaytracingDepth be more than 10 in case of GI enabled
11937 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 11938 {
23fe70ec 11939 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 11940 return 1;
11941 }
e276548b 11942 else
bc8c79bb 11943 {
11944 aParams.RaytracingDepth = aDepth;
11945 }
11946 }
11947 else if (aFlag == "-shad"
11948 || aFlag == "-shadows")
11949 {
11950 if (toPrint)
11951 {
11952 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11953 continue;
11954 }
11955
11956 Standard_Boolean toEnable = Standard_True;
11957 if (++anArgIter < theArgNb
dae2a922 11958 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11959 {
11960 --anArgIter;
11961 }
11962 aParams.IsShadowEnabled = toEnable;
11963 }
d84e8669 11964 else if (aFlag == "-shadowmapresolution"
11965 || aFlag == "-shadowmap")
11966 {
11967 if (toPrint)
11968 {
11969 theDI << aParams.ShadowMapResolution << " ";
11970 continue;
11971 }
11972 else if (++anArgIter >= theArgNb)
11973 {
11974 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11975 return 1;
11976 }
11977
11978 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11979 }
11980 else if (aFlag == "-shadowmapbias")
11981 {
11982 if (toPrint)
11983 {
11984 theDI << aParams.ShadowMapBias << " ";
11985 continue;
11986 }
11987 else if (++anArgIter >= theArgNb)
11988 {
11989 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11990 return 1;
11991 }
11992
11993 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11994 }
bc8c79bb 11995 else if (aFlag == "-refl"
11996 || aFlag == "-reflections")
11997 {
11998 if (toPrint)
11999 {
12000 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
12001 continue;
12002 }
12003
12004 Standard_Boolean toEnable = Standard_True;
12005 if (++anArgIter < theArgNb
dae2a922 12006 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12007 {
12008 --anArgIter;
12009 }
12010 aParams.IsReflectionEnabled = toEnable;
12011 }
12012 else if (aFlag == "-fsaa")
12013 {
12014 if (toPrint)
12015 {
12016 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
12017 continue;
12018 }
12019
12020 Standard_Boolean toEnable = Standard_True;
12021 if (++anArgIter < theArgNb
dae2a922 12022 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12023 {
12024 --anArgIter;
12025 }
12026 aParams.IsAntialiasingEnabled = toEnable;
12027 }
12028 else if (aFlag == "-gleam")
12029 {
12030 if (toPrint)
12031 {
12032 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
12033 continue;
12034 }
12035
12036 Standard_Boolean toEnable = Standard_True;
12037 if (++anArgIter < theArgNb
dae2a922 12038 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12039 {
12040 --anArgIter;
12041 }
12042 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 12043 }
189f85a3 12044 else if (aFlag == "-gi")
12045 {
12046 if (toPrint)
12047 {
12048 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
12049 continue;
12050 }
12051
12052 Standard_Boolean toEnable = Standard_True;
12053 if (++anArgIter < theArgNb
dae2a922 12054 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12055 {
12056 --anArgIter;
12057 }
12058 aParams.IsGlobalIlluminationEnabled = toEnable;
12059 if (!toEnable)
12060 {
12061 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
12062 }
12063 }
8c820969 12064 else if (aFlag == "-blockedrng"
12065 || aFlag == "-brng")
12066 {
12067 if (toPrint)
12068 {
12069 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
12070 continue;
12071 }
12072
12073 Standard_Boolean toEnable = Standard_True;
12074 if (++anArgIter < theArgNb
dae2a922 12075 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 12076 {
12077 --anArgIter;
12078 }
12079 aParams.CoherentPathTracingMode = toEnable;
12080 }
b09447ed 12081 else if (aFlag == "-maxrad")
12082 {
12083 if (toPrint)
12084 {
12085 theDI << aParams.RadianceClampingValue << " ";
12086 continue;
12087 }
12088 else if (++anArgIter >= theArgNb)
12089 {
23fe70ec 12090 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 12091 return 1;
12092 }
12093
12094 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
d45edf24 12095 if (!aMaxRadStr.IsRealValue (Standard_True))
b09447ed 12096 {
23fe70ec 12097 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 12098 return 1;
12099 }
12100
12101 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
12102 if (aMaxRadiance <= 0.0)
12103 {
23fe70ec 12104 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 12105 return 1;
12106 }
12107 else
12108 {
12109 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
12110 }
12111 }
3a9b5dc8 12112 else if (aFlag == "-iss")
12113 {
12114 if (toPrint)
12115 {
12116 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
12117 continue;
12118 }
12119
12120 Standard_Boolean toEnable = Standard_True;
12121 if (++anArgIter < theArgNb
dae2a922 12122 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12123 {
12124 --anArgIter;
12125 }
12126 aParams.AdaptiveScreenSampling = toEnable;
12127 }
e084dbbc 12128 else if (aFlag == "-issatomic")
12129 {
12130 if (toPrint)
12131 {
12132 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12133 continue;
12134 }
12135
12136 Standard_Boolean toEnable = Standard_True;
12137 if (++anArgIter < theArgNb
dae2a922 12138 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 12139 {
12140 --anArgIter;
12141 }
12142 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12143 }
3a9b5dc8 12144 else if (aFlag == "-issd")
12145 {
12146 if (toPrint)
12147 {
12148 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12149 continue;
12150 }
12151
12152 Standard_Boolean toEnable = Standard_True;
12153 if (++anArgIter < theArgNb
dae2a922 12154 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12155 {
12156 --anArgIter;
12157 }
12158 aParams.ShowSamplingTiles = toEnable;
12159 }
66d1cdc6 12160 else if (aFlag == "-tilesize")
12161 {
12162 if (toPrint)
12163 {
12164 theDI << aParams.RayTracingTileSize << " ";
12165 continue;
12166 }
12167 else if (++anArgIter >= theArgNb)
12168 {
23fe70ec 12169 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 12170 return 1;
12171 }
12172
12173 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12174 if (aTileSize < 1)
12175 {
23fe70ec 12176 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 12177 return 1;
12178 }
12179 aParams.RayTracingTileSize = aTileSize;
12180 }
4eaaf9d8 12181 else if (aFlag == "-nbtiles")
12182 {
12183 if (toPrint)
12184 {
12185 theDI << aParams.NbRayTracingTiles << " ";
12186 continue;
12187 }
12188 else if (++anArgIter >= theArgNb)
12189 {
23fe70ec 12190 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 12191 return 1;
12192 }
12193
12194 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12195 if (aNbTiles < -1)
4eaaf9d8 12196 {
23fe70ec 12197 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 12198 return 1;
12199 }
66d1cdc6 12200 else if (aNbTiles > 0
12201 && (aNbTiles < 64
12202 || aNbTiles > 1024))
4eaaf9d8 12203 {
23fe70ec 12204 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 12205 }
66d1cdc6 12206 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 12207 }
189f85a3 12208 else if (aFlag == "-env")
12209 {
12210 if (toPrint)
12211 {
12212 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12213 continue;
12214 }
12215
12216 Standard_Boolean toEnable = Standard_True;
12217 if (++anArgIter < theArgNb
dae2a922 12218 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12219 {
12220 --anArgIter;
12221 }
12222 aParams.UseEnvironmentMapBackground = toEnable;
12223 }
78607702 12224 else if (aFlag == "-ignorenormalmap")
12225 {
12226 if (toPrint)
12227 {
12228 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12229 continue;
12230 }
12231
12232 Standard_Boolean toEnable = Standard_True;
12233 if (++anArgIter < theArgNb
dae2a922 12234 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12235 {
12236 --anArgIter;
12237 }
12238 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12239 }
b4327ba8 12240 else if (aFlag == "-twoside")
12241 {
12242 if (toPrint)
12243 {
12244 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12245 continue;
12246 }
12247
12248 Standard_Boolean toEnable = Standard_True;
12249 if (++anArgIter < theArgNb
dae2a922 12250 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12251 {
12252 --anArgIter;
12253 }
12254 aParams.TwoSidedBsdfModels = toEnable;
12255 }
8625ef7e 12256 else if (aFlag == "-shademodel"
12257 || aFlag == "-shadingmodel"
12258 || aFlag == "-shading")
12259 {
12260 if (toPrint)
12261 {
12262 switch (aView->ShadingModel())
12263 {
67312b79 12264 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12265 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12266 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12267 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12268 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12269 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12270 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12271 }
12272 continue;
12273 }
12274
12275 if (++anArgIter >= theArgNb)
12276 {
23fe70ec 12277 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12278 }
12279
dc89236f 12280 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12281 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12282 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12283 {
dc89236f 12284 aView->SetShadingModel (aModel);
8625ef7e 12285 }
12286 else
12287 {
23fe70ec 12288 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12289 return 1;
12290 }
12291 }
67312b79 12292 else if (aFlag == "-pbrenvpow2size"
12293 || aFlag == "-pbrenvp2s"
12294 || aFlag == "-pep2s")
12295 {
12296 if (++anArgIter >= theArgNb)
12297 {
23fe70ec 12298 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12299 return 1;
12300 }
12301
12302 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12303 if (aPbrEnvPow2Size < 1)
12304 {
23fe70ec 12305 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12306 return 1;
12307 }
12308 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12309 }
12310 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12311 || aFlag == "-pbrenvspecmapnblevels"
12312 || aFlag == "-pbrenvspecmaplevels"
12313 || aFlag == "-pbrenvsmln"
12314 || aFlag == "-pesmln")
12315 {
12316 if (++anArgIter >= theArgNb)
12317 {
23fe70ec 12318 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12319 return 1;
12320 }
12321
12322 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12323 if (aPbrEnvSpecMapNbLevels < 2)
12324 {
23fe70ec 12325 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12326 return 1;
12327 }
12328 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12329 }
12330 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12331 || aFlag == "-pbrenvbakingdiffsamples"
12332 || aFlag == "-pbrenvbdsn")
12333 {
12334 if (++anArgIter >= theArgNb)
12335 {
23fe70ec 12336 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12337 return 1;
12338 }
12339
12340 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12341 if (aPbrEnvBakingDiffNbSamples < 1)
12342 {
4551e1be 12343 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12344 return 1;
12345 }
12346 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12347 }
12348 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12349 || aFlag == "-pbrenvbakingspecsamples"
12350 || aFlag == "-pbrenvbssn")
12351 {
12352 if (++anArgIter >= theArgNb)
12353 {
23fe70ec 12354 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12355 return 1;
12356 }
12357
12358 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12359 if (aPbrEnvBakingSpecNbSamples < 1)
12360 {
4551e1be 12361 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12362 return 1;
12363 }
12364 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12365 }
12366 else if (aFlag == "-pbrenvbakingprobability"
12367 || aFlag == "-pbrenvbp")
12368 {
12369 if (++anArgIter >= theArgNb)
12370 {
23fe70ec 12371 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12372 return 1;
12373 }
12374 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12375 if (aPbrEnvBakingProbability < 0.f
12376 || aPbrEnvBakingProbability > 1.f)
12377 {
4551e1be 12378 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
67312b79 12379 return 1;
12380 }
12381 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12382 }
4b1c8733 12383 else if (aFlag == "-resolution")
12384 {
12385 if (++anArgIter >= theArgNb)
12386 {
23fe70ec 12387 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12388 return 1;
12389 }
12390
12391 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12392 if (aResolution.IsIntegerValue())
12393 {
12394 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12395 }
12396 else
12397 {
23fe70ec 12398 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12399 return 1;
12400 }
12401 }
d877e610 12402 else if (aFlag == "-rebuildglsl"
12403 || aFlag == "-rebuild")
12404 {
12405 if (toPrint)
12406 {
12407 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12408 continue;
12409 }
12410
12411 Standard_Boolean toEnable = Standard_True;
12412 if (++anArgIter < theArgNb
dae2a922 12413 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12414 {
12415 --anArgIter;
12416 }
12417 aParams.RebuildRayTracingShaders = toEnable;
12418 }
b27ab03d 12419 else if (aFlag == "-focal")
12420 {
12421 if (++anArgIter >= theArgNb)
12422 {
23fe70ec 12423 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12424 return 1;
12425 }
12426
12427 TCollection_AsciiString aParam (theArgVec[anArgIter]);
d45edf24 12428 if (aParam.IsRealValue (Standard_True))
b27ab03d 12429 {
12430 float aFocalDist = static_cast<float> (aParam.RealValue());
12431 if (aFocalDist < 0)
12432 {
23fe70ec 12433 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12434 return 1;
12435 }
12436 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12437 }
12438 else
12439 {
23fe70ec 12440 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12441 return 1;
12442 }
12443 }
12444 else if (aFlag == "-aperture")
12445 {
12446 if (++anArgIter >= theArgNb)
12447 {
23fe70ec 12448 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12449 return 1;
12450 }
12451
12452 TCollection_AsciiString aParam(theArgVec[anArgIter]);
d45edf24 12453 if (aParam.IsRealValue (Standard_True))
b27ab03d 12454 {
12455 float aApertureSize = static_cast<float> (aParam.RealValue());
12456 if (aApertureSize < 0)
12457 {
23fe70ec 12458 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12459 return 1;
12460 }
12461 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12462 }
12463 else
12464 {
23fe70ec 12465 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12466 return 1;
12467 }
12468 }
eb85ed36 12469 else if (aFlag == "-exposure")
12470 {
12471 if (++anArgIter >= theArgNb)
12472 {
23fe70ec 12473 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12474 return 1;
12475 }
12476
12477 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
d45edf24 12478 if (anExposure.IsRealValue (Standard_True))
eb85ed36 12479 {
12480 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12481 }
12482 else
12483 {
23fe70ec 12484 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12485 return 1;
12486 }
12487 }
12488 else if (aFlag == "-whitepoint")
12489 {
12490 if (++anArgIter >= theArgNb)
12491 {
23fe70ec 12492 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12493 return 1;
12494 }
12495
12496 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
d45edf24 12497 if (aWhitePoint.IsRealValue (Standard_True))
eb85ed36 12498 {
12499 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12500 }
12501 else
12502 {
23fe70ec 12503 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12504 return 1;
12505 }
12506 }
12507 else if (aFlag == "-tonemapping")
12508 {
12509 if (++anArgIter >= theArgNb)
12510 {
23fe70ec 12511 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12512 return 1;
12513 }
12514
12515 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12516 aMode.LowerCase();
12517
12518 if (aMode == "disabled")
12519 {
12520 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12521 }
12522 else if (aMode == "filmic")
12523 {
12524 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12525 }
12526 else
12527 {
23fe70ec 12528 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12529 return 1;
12530 }
12531 }
15669413 12532 else if (aFlag == "-performancestats"
12533 || aFlag == "-performancecounters"
12534 || aFlag == "-perfstats"
12535 || aFlag == "-perfcounters"
12536 || aFlag == "-stats")
12537 {
12538 if (++anArgIter >= theArgNb)
12539 {
23fe70ec 12540 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12541 return 1;
12542 }
12543
12544 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12545 aFlagsStr.LowerCase();
12546 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12547 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12548 {
23fe70ec 12549 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12550 return 1;
12551 }
12552 aView->ChangeRenderingParams().CollectedStats = aFlags;
12553 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12554 }
12555 else if (aFlag == "-perfupdateinterval"
12556 || aFlag == "-statsupdateinterval")
12557 {
12558 if (++anArgIter >= theArgNb)
12559 {
23fe70ec 12560 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12561 return 1;
12562 }
12563 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12564 }
5e30547b 12565 else if (aFlag == "-perfchart"
12566 || aFlag == "-statschart")
12567 {
12568 if (++anArgIter >= theArgNb)
12569 {
23fe70ec 12570 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12571 return 1;
12572 }
12573 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12574 }
12575 else if (aFlag == "-perfchartmax"
12576 || aFlag == "-statschartmax")
12577 {
12578 if (++anArgIter >= theArgNb)
12579 {
23fe70ec 12580 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12581 return 1;
12582 }
12583 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12584 }
0e3025bc 12585 else if (aFlag == "-frustumculling"
12586 || aFlag == "-culling")
12587 {
12588 if (toPrint)
12589 {
12590 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12591 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12592 "noUpdate") << " ";
12593 continue;
12594 }
12595
12596 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12597 if (++anArgIter < theArgNb)
12598 {
12599 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12600 aStateStr.LowerCase();
12601 bool toEnable = true;
dae2a922 12602 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12603 {
12604 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12605 }
12606 else if (aStateStr == "noupdate"
12607 || aStateStr == "freeze")
12608 {
12609 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12610 }
12611 else
12612 {
12613 --anArgIter;
12614 }
12615 }
12616 aParams.FrustumCullingState = aState;
12617 }
e276548b 12618 else
12619 {
23fe70ec 12620 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12621 return 1;
e276548b 12622 }
12623 }
189f85a3 12624
4c7a3fae 12625 // set current view parameters as defaults
12626 if (toSyncDefaults)
12627 {
12628 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12629 }
12630 if (toSyncAllViews)
12631 {
12632 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12633 {
12634 aViewIter.Value()->ChangeRenderingParams() = aParams;
12635 }
12636 }
189f85a3 12637 return 0;
12638}
12639
79b544e6 12640//=======================================================================
12641//function : searchInfo
12642//purpose :
12643//=======================================================================
12644inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12645 const TCollection_AsciiString& theKey)
12646{
12647 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12648 {
12649 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12650 {
12651 return anIter.Value();
12652 }
12653 }
12654 return TCollection_AsciiString();
12655}
12656
12657//=======================================================================
12658//function : VStatProfiler
12659//purpose :
12660//=======================================================================
12661static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12662 Standard_Integer theArgNb,
12663 const char** theArgVec)
12664{
12665 Handle(V3d_View) aView = ViewerTest::CurrentView();
12666 if (aView.IsNull())
12667 {
23fe70ec 12668 Message::SendFail ("Error: no active viewer");
79b544e6 12669 return 1;
12670 }
12671
12672 Standard_Boolean toRedraw = Standard_True;
12673 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12674 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12675 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12676 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12677 {
12678 Standard_CString anArg (theArgVec[anArgIter]);
12679 TCollection_AsciiString aFlag (anArg);
12680 aFlag.LowerCase();
12681 if (aFlag == "-noredraw")
12682 {
12683 toRedraw = Standard_False;
12684 }
12685 else
12686 {
12687 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12688 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12689 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12690 else if (aFlag == "alllayers"
12691 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12692 else if (aFlag == "allstructs"
a2803f37 12693 || aFlag == "allstructures"
12694 || aFlag == "structs"
12695 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12696 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12697 else if (aFlag == "allarrays"
12698 || aFlag == "fillarrays"
12699 || aFlag == "linearrays"
12700 || aFlag == "pointarrays"
12701 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12702 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12703 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12704 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12705 else if (aFlag == "geommem"
12706 || aFlag == "texturemem"
12707 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12708 else if (aFlag == "elapsedframe"
12709 || aFlag == "cpuframeaverage"
12710 || aFlag == "cpupickingaverage"
12711 || aFlag == "cpucullingaverage"
12712 || aFlag == "cpudynaverage"
12713 || aFlag == "cpuframemax"
12714 || aFlag == "cpupickingmax"
12715 || aFlag == "cpucullingmax"
12716 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12717 else
12718 {
23fe70ec 12719 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12720 continue;
12721 }
12722
12723 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12724 }
12725 }
12726
12727 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12728 {
12729 aView->ChangeRenderingParams().CollectedStats =
12730 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12731
12732 if (toRedraw)
12733 {
12734 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12735 aView->Redraw();
12736 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12737 }
12738
12739 TColStd_IndexedDataMapOfStringString aDict;
12740 aView->StatisticInformation (aDict);
12741
12742 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12743
12744 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12745 {
12746 Standard_CString anArg(theArgVec[anArgIter]);
12747 TCollection_AsciiString aFlag(anArg);
12748 aFlag.LowerCase();
12749 if (aFlag == "fps")
12750 {
12751 theDI << searchInfo (aDict, "FPS") << " ";
12752 }
12753 else if (aFlag == "cpu")
12754 {
12755 theDI << searchInfo (aDict, "CPU FPS") << " ";
12756 }
12757 else if (aFlag == "alllayers")
12758 {
12759 theDI << searchInfo (aDict, "Layers") << " ";
12760 }
12761 else if (aFlag == "layers")
12762 {
12763 theDI << searchInfo (aDict, "Rendered layers") << " ";
12764 }
a2803f37 12765 else if (aFlag == "allstructs"
12766 || aFlag == "allstructures")
79b544e6 12767 {
12768 theDI << searchInfo (aDict, "Structs") << " ";
12769 }
a2803f37 12770 else if (aFlag == "structs"
12771 || aFlag == "structures")
79b544e6 12772 {
a2803f37 12773 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12774 if (aRend.IsEmpty()) // all structures rendered
12775 {
12776 aRend = searchInfo (aDict, "Structs");
12777 }
12778 theDI << aRend << " ";
79b544e6 12779 }
12780 else if (aFlag == "groups")
12781 {
12782 theDI << searchInfo (aDict, "Rendered groups") << " ";
12783 }
12784 else if (aFlag == "allarrays")
12785 {
12786 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12787 }
12788 else if (aFlag == "fillarrays")
12789 {
12790 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12791 }
12792 else if (aFlag == "linearrays")
12793 {
12794 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12795 }
12796 else if (aFlag == "pointarrays")
12797 {
12798 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12799 }
12800 else if (aFlag == "textarrays")
12801 {
12802 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12803 }
12804 else if (aFlag == "triangles")
12805 {
12806 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12807 }
12808 else if (aFlag == "points")
12809 {
12810 theDI << searchInfo (aDict, "Rendered points") << " ";
12811 }
12812 else if (aFlag == "geommem")
12813 {
12814 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12815 }
12816 else if (aFlag == "texturemem")
12817 {
12818 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12819 }
12820 else if (aFlag == "framemem")
12821 {
12822 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12823 }
12824 else if (aFlag == "elapsedframe")
12825 {
12826 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12827 }
12828 else if (aFlag == "cpuframe_average")
12829 {
12830 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12831 }
12832 else if (aFlag == "cpupicking_average")
12833 {
12834 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12835 }
12836 else if (aFlag == "cpuculling_average")
12837 {
12838 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12839 }
12840 else if (aFlag == "cpudyn_average")
12841 {
12842 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12843 }
12844 else if (aFlag == "cpuframe_max")
12845 {
12846 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12847 }
12848 else if (aFlag == "cpupicking_max")
12849 {
12850 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12851 }
12852 else if (aFlag == "cpuculling_max")
12853 {
12854 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12855 }
12856 else if (aFlag == "cpudyn_max")
12857 {
12858 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12859 }
12860 }
12861 }
12862 else
12863 {
12864 if (toRedraw)
12865 {
12866 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12867 aView->Redraw();
12868 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12869 }
12870 theDI << "Statistic info:\n" << aView->StatisticInformation();
12871 }
12872 return 0;
12873}
12874
0717ddc1 12875//=======================================================================
12876//function : VXRotate
12877//purpose :
12878//=======================================================================
12879static Standard_Integer VXRotate (Draw_Interpretor& di,
12880 Standard_Integer argc,
12881 const char ** argv)
12882{
12883 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12884 if (aContext.IsNull())
12885 {
586db386 12886 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12887 return 1;
12888 }
8693dfd0 12889
0717ddc1 12890 if (argc != 3)
12891 {
586db386 12892 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12893 return 1;
12894 }
12895
12896 TCollection_AsciiString aName (argv[1]);
12897 Standard_Real anAngle = Draw::Atof (argv[2]);
12898
12899 // find object
12900 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12901 Handle(AIS_InteractiveObject) anIObj;
8f521168 12902 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12903 {
586db386 12904 di << "Use 'vdisplay' before\n";
0717ddc1 12905 return 1;
12906 }
0717ddc1 12907
8f521168 12908 gp_Trsf aTransform;
12909 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12910 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12911
8f521168 12912 aContext->SetLocation (anIObj, aTransform);
12913 aContext->UpdateCurrentViewer();
0717ddc1 12914 return 0;
12915}
12916
ff6122e0 12917namespace
12918{
12919 //! Structure for setting AIS_Manipulator::SetPart() property.
12920 struct ManipAxisModeOnOff
12921 {
12922 Standard_Integer Axis;
12923 AIS_ManipulatorMode Mode;
12924 Standard_Boolean ToEnable;
12925
12926 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12927 };
12928
12929 enum ManipAjustPosition
12930 {
12931 ManipAjustPosition_Off,
12932 ManipAjustPosition_Center,
12933 ManipAjustPosition_Location,
12934 ManipAjustPosition_ShapeLocation,
12935 };
12936}
12937
625e1958 12938//===============================================================================================
12939//function : VManipulator
12940//purpose :
12941//===============================================================================================
12942static int VManipulator (Draw_Interpretor& theDi,
12943 Standard_Integer theArgsNb,
12944 const char** theArgVec)
12945{
bbf3fcde 12946 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 12947 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 12948 if (aCurrentView.IsNull()
625e1958 12949 || aViewer.IsNull())
12950 {
23fe70ec 12951 Message::SendFail ("Error: no active viewer");
625e1958 12952 return 1;
12953 }
12954
12955 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12956 Standard_Integer anArgIter = 1;
ff6122e0 12957 Handle(AIS_Manipulator) aManipulator;
12958 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12959 TCollection_AsciiString aName;
12960 // parameters
12961 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12962 Standard_Real aGap = -1.0, aSize = -1.0;
12963 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12964 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12965 //
12966 bool toDetach = false;
12967 AIS_Manipulator::OptionsForAttach anAttachOptions;
12968 Handle(AIS_InteractiveObject) anAttachObject;
12969 Handle(V3d_View) aViewAffinity;
12970 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12971 //
12972 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12973 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12974 Standard_Integer toStopMouseTransform = -1;
12975 // explicit transformation
12976 gp_Trsf aTrsf;
12977 gp_XYZ aTmpXYZ;
12978 Standard_Real aTmpReal = 0.0;
12979 gp_XYZ aRotPnt, aRotAxis;
625e1958 12980 for (; anArgIter < theArgsNb; ++anArgIter)
12981 {
ff6122e0 12982 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12983 anArg.LowerCase();
12984 if (anUpdateTool.parseRedrawMode (anArg))
12985 {
12986 continue;
12987 }
12988 else if (anArg == "-help")
12989 {
12990 theDi.PrintHelp (theArgVec[0]);
12991 return 0;
12992 }
12993 //
12994 else if (anArg == "-autoactivate"
12995 || anArg == "-noautoactivate")
12996 {
12997 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12998 }
12999 else if (anArg == "-followtranslation"
13000 || anArg == "-nofollowtranslation")
13001 {
13002 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13003 }
13004 else if (anArg == "-followrotation"
13005 || anArg == "-nofollowrotation")
13006 {
13007 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13008 }
13009 else if (anArg == "-followdragging"
13010 || anArg == "-nofollowdragging")
13011 {
13012 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13013 }
13014 else if (anArg == "-gap"
13015 && anArgIter + 1 < theArgsNb
13016 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
13017 && aGap >= 0.0)
13018 {
13019 ++anArgIter;
13020 }
13021 else if (anArg == "-size"
13022 && anArgIter + 1 < theArgsNb
13023 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
13024 && aSize > 0.0)
13025 {
13026 ++anArgIter;
13027 }
13028 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
13029 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
13030 {
13031 ManipAxisModeOnOff aPart;
13032 Standard_Integer aMode = 0;
13033 if (anArg == "-part")
13034 {
13035 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
13036 || aPart.Axis < 0 || aPart.Axis > 3)
13037 {
13038 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
13039 return 1;
13040 }
13041 }
13042 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
13043 || aMode < 1 || aMode > 4)
13044 {
13045 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
13046 return 1;
13047 }
13048 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
13049 {
13050 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
13051 return 1;
13052 }
13053 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
13054 aParts.Append (aPart);
13055 }
13056 else if (anArg == "-pos"
13057 && anArgIter + 3 < theArgsNb
13058 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
13059 {
13060 anArgIter += 3;
13061 if (anArgIter + 3 < theArgsNb
13062 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
13063 && aVDir.Modulus() > Precision::Confusion())
13064 {
13065 anArgIter += 3;
13066 }
13067 if (anArgIter + 3 < theArgsNb
13068 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
13069 && anXDir.Modulus() > Precision::Confusion())
13070 {
13071 anArgIter += 3;
13072 }
13073 }
13074 else if (anArg == "-zoomable"
13075 || anArg == "-notzoomable")
13076 {
13077 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13078 }
13079 //
13080 else if (anArg == "-adjustposition"
13081 || anArg == "-noadjustposition")
13082 {
13083 anAttachPos = ManipAjustPosition_Center;
13084 if (anArgIter + 1 < theArgsNb)
13085 {
13086 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
13087 aPosName.LowerCase();
13088 if (aPosName == "0")
13089 {
13090 anAttachPos = ManipAjustPosition_Off;
13091 }
13092 else if (aPosName == "1"
13093 || aPosName == "center")
13094 {
13095 anAttachPos = ManipAjustPosition_Center;
13096 }
13097 else if (aPosName == "transformation"
13098 || aPosName == "trsf"
13099 || aPosName == "location"
13100 || aPosName == "loc")
13101 {
13102 anAttachPos = ManipAjustPosition_Location;
13103 }
13104 else if (aPosName == "shapelocation"
13105 || aPosName == "shapeloc")
13106 {
13107 anAttachPos = ManipAjustPosition_ShapeLocation;
13108 }
13109 else
13110 {
13111 --anArgIter;
13112 }
13113 }
13114 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
13115 }
13116 else if (anArg == "-adjustsize"
13117 || anArg == "-noadjustsize")
13118 {
13119 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13120 }
13121 else if (anArg == "-enablemodes"
13122 || anArg == "-enablemodes")
13123 {
13124 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13125 }
13126 //
13127 else if (anArg == "-starttransform"
13128 && anArgIter + 2 < theArgsNb
13129 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
13130 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
13131 {
13132 anArgIter += 2;
13133 }
13134 else if (anArg == "-transform"
13135 && anArgIter + 2 < theArgsNb
13136 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
13137 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
13138 {
13139 anArgIter += 2;
13140 }
13141 else if (anArg == "-stoptransform")
13142 {
13143 toStopMouseTransform = 1;
13144 if (anArgIter + 1 < theArgsNb
13145 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
13146 {
13147 ++anArgIter;
13148 toStopMouseTransform = 0;
13149 }
13150 }
13151 //
13152 else if (anArg == "-move"
13153 && anArgIter + 3 < theArgsNb
13154 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
13155 {
13156 anArgIter += 3;
13157 aTrsf.SetTranslationPart (aTmpXYZ);
13158 }
13159 else if (anArg == "-scale"
13160 && anArgIter + 1 < theArgsNb
13161 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
13162 {
13163 ++anArgIter;
13164 aTrsf.SetScale (gp_Pnt(), aTmpReal);
13165 }
13166 else if (anArg == "-rotate"
13167 && anArgIter + 7 < theArgsNb
13168 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
13169 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
13170 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
13171 {
13172 anArgIter += 7;
13173 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
13174 }
13175 //
13176 else if (anArg == "-detach")
13177 {
13178 toDetach = true;
13179 }
13180 else if (anArg == "-attach"
13181 && anArgIter + 1 < theArgsNb)
13182 {
13183 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
13184 if (!aMapAIS.Find2 (anObjName, anAttachObject))
13185 {
13186 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
13187 return 1;
13188 }
625e1958 13189
ff6122e0 13190 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
13191 {
13192 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13193 if (!aManip.IsNull()
13194 && aManip->IsAttached()
13195 && aManip->Object() == anAttachObject)
13196 {
13197 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
13198 return 1;
13199 }
13200 }
13201 }
13202 else if (anArg == "-view"
13203 && anArgIter + 1 < theArgsNb
13204 && aViewAffinity.IsNull())
13205 {
13206 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
13207 if (aViewString == "active")
13208 {
13209 aViewAffinity = ViewerTest::CurrentView();
13210 }
13211 else // Check view name
13212 {
13213 ViewerTest_Names aViewNames (aViewString);
13214 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13215 {
13216 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13217 return 1;
13218 }
13219 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13220 if (aViewAffinity.IsNull())
13221 {
13222 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13223 return 1;
13224 }
13225 }
13226 }
13227 else if (aName.IsEmpty())
13228 {
13229 aName = theArgVec[anArgIter];
13230 if (!aMapAIS.IsBound2 (aName))
13231 {
13232 aManipulator = new AIS_Manipulator();
13233 aManipulator->SetModeActivationOnDetection (true);
13234 aMapAIS.Bind (aManipulator, aName);
13235 }
13236 else
13237 {
13238 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13239 if (aManipulator.IsNull())
13240 {
13241 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13242 return 1;
13243 }
13244 }
13245 }
13246 else
13247 {
13248 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13249 }
625e1958 13250 }
13251
625e1958 13252 if (aName.IsEmpty())
13253 {
23fe70ec 13254 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 13255 return 1;
13256 }
ff6122e0 13257 if (!toDetach
13258 && aManipulator.IsNull())
625e1958 13259 {
8b037fe4 13260 aManipulator = new AIS_Manipulator();
49582f9d 13261 aManipulator->SetModeActivationOnDetection (true);
625e1958 13262 aMapAIS.Bind (aManipulator, aName);
13263 }
625e1958 13264
13265 // -----------------------------------------
13266 // change properties of manipulator instance
13267 // -----------------------------------------
13268
ff6122e0 13269 if (toAutoActivate != -1)
625e1958 13270 {
ff6122e0 13271 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
625e1958 13272 }
ff6122e0 13273 if (toFollowTranslation != -1)
625e1958 13274 {
ff6122e0 13275 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
625e1958 13276 }
ff6122e0 13277 if (toFollowRotation != -1)
625e1958 13278 {
ff6122e0 13279 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
625e1958 13280 }
ff6122e0 13281 if (toFollowDragging != -1)
f522ce50 13282 {
ff6122e0 13283 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
f522ce50 13284 }
ff6122e0 13285 if (aGap >= 0.0f)
625e1958 13286 {
ff6122e0 13287 aManipulator->SetGap ((float )aGap);
625e1958 13288 }
ff6122e0 13289
13290 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
625e1958 13291 {
ff6122e0 13292 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13293 if (aPart.Axis == -1)
625e1958 13294 {
ff6122e0 13295 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
625e1958 13296 }
ff6122e0 13297 else
84b904bc 13298 {
ff6122e0 13299 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
84b904bc 13300 }
84b904bc 13301 }
625e1958 13302
ff6122e0 13303 if (aSize > 0.0)
625e1958 13304 {
ff6122e0 13305 aManipulator->SetSize ((float )aSize);
625e1958 13306 }
ff6122e0 13307 if (isZoomable != -1)
625e1958 13308 {
ff6122e0 13309 aManipulator->SetZoomPersistence (isZoomable == 0);
625e1958 13310
13311 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13312 {
13313 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13314 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13315 }
13316 }
13317
ff6122e0 13318 // ----------------------------------
13319 // detach existing manipulator object
13320 // ----------------------------------
13321
13322 if (toDetach)
13323 {
13324 aManipulator->Detach();
13325 aMapAIS.UnBind2 (aName);
13326 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13327 }
13328
625e1958 13329 // ---------------------------------------------------
13330 // attach, detach or access manipulator from an object
13331 // ---------------------------------------------------
13332
ff6122e0 13333 if (!anAttachObject.IsNull())
625e1958 13334 {
ff6122e0 13335 aManipulator->Attach (anAttachObject, anAttachOptions);
13336 }
13337 if (!aViewAffinity.IsNull())
13338 {
13339 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
8b037fe4 13340 anIter.More(); anIter.Next())
625e1958 13341 {
ff6122e0 13342 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
625e1958 13343 }
ff6122e0 13344 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13345 }
625e1958 13346
ff6122e0 13347 if (anAttachPos != ManipAjustPosition_Off
13348 && aManipulator->IsAttached()
13349 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13350 {
13351 gp_Ax2 aPosition = gp::XOY();
13352 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13353 switch (anAttachPos)
bbf3fcde 13354 {
ff6122e0 13355 case ManipAjustPosition_Off:
bbf3fcde 13356 {
ff6122e0 13357 break;
bbf3fcde 13358 }
ff6122e0 13359 case ManipAjustPosition_Location:
bbf3fcde 13360 {
ff6122e0 13361 aPosition = gp::XOY().Transformed (aBaseTrsf);
13362 break;
bbf3fcde 13363 }
ff6122e0 13364 case ManipAjustPosition_ShapeLocation:
bbf3fcde 13365 {
ff6122e0 13366 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
bbf3fcde 13367 {
ff6122e0 13368 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
bbf3fcde 13369 }
ff6122e0 13370 else
bbf3fcde 13371 {
ff6122e0 13372 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
bbf3fcde 13373 return 1;
13374 }
ff6122e0 13375 break;
bbf3fcde 13376 }
ff6122e0 13377 case ManipAjustPosition_Center:
bbf3fcde 13378 {
ff6122e0 13379 Bnd_Box aBox;
13380 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13381 {
13382 Bnd_Box anObjBox;
13383 anObjIter.Value()->BoundingBox (anObjBox);
13384 aBox.Add (anObjBox);
13385 }
13386 aBox = aBox.FinitePart();
13387 if (!aBox.IsVoid())
13388 {
13389 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13390 aPosition.SetLocation (aCenter);
13391 }
13392 break;
bbf3fcde 13393 }
bbf3fcde 13394 }
ff6122e0 13395 aManipulator->SetPosition (aPosition);
13396 }
13397 if (!Precision::IsInfinite (aLocation.X()))
13398 {
13399 if (aVDir.Modulus() <= Precision::Confusion())
13400 {
13401 aVDir = aManipulator->Position().Direction().XYZ();
13402 }
13403 if (anXDir.Modulus() <= Precision::Confusion())
13404 {
13405 anXDir = aManipulator->Position().XDirection().XYZ();
13406 }
13407 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
625e1958 13408 }
13409
13410 // --------------------------------------
13411 // apply transformation using manipulator
13412 // --------------------------------------
13413
ff6122e0 13414 if (aMousePosFrom.x() != IntegerLast())
625e1958 13415 {
ff6122e0 13416 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
625e1958 13417 }
ff6122e0 13418 if (aMousePosTo.x() != IntegerLast())
625e1958 13419 {
ff6122e0 13420 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
625e1958 13421 }
ff6122e0 13422 if (toStopMouseTransform != -1)
625e1958 13423 {
ff6122e0 13424 aManipulator->StopTransform (toStopMouseTransform == 1);
625e1958 13425 }
13426
ff6122e0 13427 if (aTrsf.Form() != gp_Identity)
625e1958 13428 {
ff6122e0 13429 aManipulator->Transform (aTrsf);
625e1958 13430 }
13431
ff6122e0 13432 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
625e1958 13433 {
ff6122e0 13434 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
625e1958 13435 }
625e1958 13436 return 0;
13437}
13438
8e5fb5ea 13439//===============================================================================================
13440//function : VSelectionProperties
13441//purpose :
13442//===============================================================================================
13443static int VSelectionProperties (Draw_Interpretor& theDi,
13444 Standard_Integer theArgsNb,
13445 const char** theArgVec)
13446{
13447 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13448 if (aCtx.IsNull())
13449 {
23fe70ec 13450 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13451 return 1;
13452 }
13453
be3d8cbc 13454 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13455 {
13456 // handle obsolete alias
13457 bool toEnable = true;
13458 if (theArgsNb < 2)
13459 {
13460 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13461 return 0;
13462 }
13463 else if (theArgsNb != 2
dae2a922 13464 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13465 {
23fe70ec 13466 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13467 return 1;
13468 }
13469 if (toEnable != aCtx->ToHilightSelected())
13470 {
13471 aCtx->ClearDetected();
13472 aCtx->SetToHilightSelected (toEnable);
13473 }
13474 return 0;
13475 }
13476
f838dac4 13477 Standard_Boolean toPrint = theArgsNb == 1;
13478 Standard_Boolean toRedraw = Standard_False;
13479 Standard_Integer anArgIter = 1;
13480 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13481 if (anArgIter < theArgsNb)
13482 {
13483 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13484 anArgFirst.LowerCase();
13485 ++anArgIter;
13486 if (anArgFirst == "dynhighlight"
13487 || anArgFirst == "dynhilight"
13488 || anArgFirst == "dynamichighlight"
13489 || anArgFirst == "dynamichilight")
13490 {
13491 aType = Prs3d_TypeOfHighlight_Dynamic;
13492 }
13493 else if (anArgFirst == "localdynhighlight"
13494 || anArgFirst == "localdynhilight"
13495 || anArgFirst == "localdynamichighlight"
13496 || anArgFirst == "localdynamichilight")
13497 {
13498 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13499 }
13500 else if (anArgFirst == "selhighlight"
13501 || anArgFirst == "selhilight"
13502 || anArgFirst == "selectedhighlight"
13503 || anArgFirst == "selectedhilight")
13504 {
13505 aType = Prs3d_TypeOfHighlight_Selected;
13506 }
13507 else if (anArgFirst == "localselhighlight"
13508 || anArgFirst == "localselhilight"
13509 || anArgFirst == "localselectedhighlight"
13510 || anArgFirst == "localselectedhilight")
13511 {
13512 aType = Prs3d_TypeOfHighlight_LocalSelected;
13513 }
13514 else
13515 {
13516 --anArgIter;
13517 }
13518 }
13519 for (; anArgIter < theArgsNb; ++anArgIter)
13520 {
13521 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13522 anArg.LowerCase();
13523 if (anArg == "-help")
13524 {
13525 theDi.PrintHelp (theArgVec[0]);
13526 return 0;
13527 }
13528 else if (anArg == "-print")
13529 {
13530 toPrint = Standard_True;
13531 }
13532 else if (anArg == "-autoactivate")
13533 {
13534 Standard_Boolean toEnable = Standard_True;
13535 if (anArgIter + 1 < theArgsNb
dae2a922 13536 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13537 {
13538 ++anArgIter;
13539 }
13540 aCtx->SetAutoActivateSelection (toEnable);
13541 }
be3d8cbc 13542 else if (anArg == "-automatichighlight"
13543 || anArg == "-automatichilight"
13544 || anArg == "-autohighlight"
13545 || anArg == "-autohilight")
13546 {
13547 Standard_Boolean toEnable = Standard_True;
13548 if (anArgIter + 1 < theArgsNb
dae2a922 13549 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13550 {
13551 ++anArgIter;
13552 }
13553 aCtx->ClearSelected (false);
13554 aCtx->ClearDetected();
13555 aCtx->SetAutomaticHilight (toEnable);
13556 toRedraw = true;
13557 }
13558 else if (anArg == "-highlightselected"
13559 || anArg == "-hilightselected")
13560 {
13561 Standard_Boolean toEnable = Standard_True;
13562 if (anArgIter + 1 < theArgsNb
dae2a922 13563 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13564 {
13565 ++anArgIter;
13566 }
13567 aCtx->ClearDetected();
13568 aCtx->SetToHilightSelected (toEnable);
13569 toRedraw = true;
13570 }
14c4193d 13571 else if (anArg == "-pickstrategy"
13572 || anArg == "-pickingstrategy")
13573 {
13574 if (++anArgIter >= theArgsNb)
13575 {
23fe70ec 13576 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13577 return 1;
13578 }
13579
13580 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13581 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13582 aVal.LowerCase();
13583 if (aVal == "first"
13584 || aVal == "firstaccepted"
13585 || aVal == "firstacceptable")
13586 {
13587 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13588 }
13589 else if (aVal == "topmost"
13590 || aVal == "onlyTopmost")
13591 {
13592 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13593 }
13594 else
13595 {
23fe70ec 13596 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13597 return 1;
13598 }
13599
13600 aCtx->SetPickingStrategy (aStrategy);
13601 }
f838dac4 13602 else if (anArg == "-pixtol"
13603 && anArgIter + 1 < theArgsNb)
13604 {
13605 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13606 }
8c36926a 13607 else if (anArg == "-preferclosest")
13608 {
13609 bool toPreferClosest = true;
13610 if (anArgIter + 1 < theArgsNb
13611 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13612 {
13613 ++anArgIter;
13614 }
13615 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13616 }
13617 else if ((anArg == "-depthtol"
13618 || anArg == "-depthtolerance")
13619 && anArgIter + 1 < theArgsNb)
13620 {
13621 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13622 aTolType.LowerCase();
13623 if (aTolType == "uniform")
13624 {
13625 if (anArgIter + 1 >= theArgsNb)
13626 {
13627 Message::SendFail() << "Syntax error: wrong number of arguments";
13628 return 1;
13629 }
13630 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13631 Draw::Atof (theArgVec[++anArgIter]));
13632 }
13633 else if (aTolType == "uniformpx")
13634 {
13635 if (anArgIter + 1 >= theArgsNb)
13636 {
13637 Message::SendFail() << "Syntax error: wrong number of arguments";
13638 return 1;
13639 }
13640 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13641 Draw::Atof (theArgVec[++anArgIter]));
13642 }
13643 else if (aTolType == "sensfactor")
13644 {
13645 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13646 }
13647 else
13648 {
13649 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13650 return 1;
13651 }
13652 }
f838dac4 13653 else if ((anArg == "-mode"
13654 || anArg == "-dispmode")
13655 && anArgIter + 1 < theArgsNb)
13656 {
13657 if (aType == Prs3d_TypeOfHighlight_None)
13658 {
23fe70ec 13659 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13660 return 1;
13661 }
8e5fb5ea 13662
f838dac4 13663 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13664 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13665 aStyle->SetDisplayMode (aDispMode);
13666 toRedraw = Standard_True;
13667 }
13668 else if (anArg == "-layer"
13669 && anArgIter + 1 < theArgsNb)
13670 {
13671 if (aType == Prs3d_TypeOfHighlight_None)
13672 {
23fe70ec 13673 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13674 return 1;
13675 }
8e5fb5ea 13676
55c8f0f7
BB
13677 ++anArgIter;
13678 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13679 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13680 {
23fe70ec 13681 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13682 return 1;
f838dac4 13683 }
8e5fb5ea 13684
f838dac4 13685 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13686 aStyle->SetZLayer (aNewLayer);
13687 toRedraw = Standard_True;
13688 }
13689 else if (anArg == "-hicolor"
13690 || anArg == "-selcolor"
13691 || anArg == "-color")
13692 {
13693 if (anArg.StartsWith ("-hi"))
13694 {
13695 aType = Prs3d_TypeOfHighlight_Dynamic;
13696 }
13697 else if (anArg.StartsWith ("-sel"))
13698 {
13699 aType = Prs3d_TypeOfHighlight_Selected;
13700 }
13701 else if (aType == Prs3d_TypeOfHighlight_None)
13702 {
23fe70ec 13703 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13704 return 1;
13705 }
8e5fb5ea 13706
f838dac4 13707 Quantity_Color aColor;
dae2a922 13708 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13709 theArgVec + anArgIter + 1,
13710 aColor);
f838dac4 13711 if (aNbParsed == 0)
13712 {
23fe70ec 13713 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13714 return 1;
13715 }
13716 anArgIter += aNbParsed;
8e5fb5ea 13717
f838dac4 13718 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13719 aStyle->SetColor (aColor);
13720 toRedraw = Standard_True;
13721 }
13722 else if ((anArg == "-transp"
13723 || anArg == "-transparency"
13724 || anArg == "-hitransp"
13725 || anArg == "-seltransp"
13726 || anArg == "-hitransplocal"
13727 || anArg == "-seltransplocal")
13728 && anArgIter + 1 < theArgsNb)
13729 {
13730 if (anArg.StartsWith ("-hi"))
13731 {
13732 aType = Prs3d_TypeOfHighlight_Dynamic;
13733 }
13734 else if (anArg.StartsWith ("-sel"))
13735 {
13736 aType = Prs3d_TypeOfHighlight_Selected;
13737 }
13738 else if (aType == Prs3d_TypeOfHighlight_None)
13739 {
23fe70ec 13740 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13741 return 1;
13742 }
8e5fb5ea 13743
f838dac4 13744 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13745 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13746 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13747 toRedraw = Standard_True;
13748 }
13749 else if ((anArg == "-mat"
13750 || anArg == "-material")
13751 && anArgIter + 1 < theArgsNb)
13752 {
13753 if (aType == Prs3d_TypeOfHighlight_None)
13754 {
23fe70ec 13755 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13756 return 1;
13757 }
8e5fb5ea 13758
f838dac4 13759 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13760 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 13761 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 13762 {
13763 ++anArgIter;
13764 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13765 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13766 Graphic3d_MaterialAspect aMat (aMatName);
13767 aMat.SetColor (aStyle->Color());
13768 aMat.SetTransparency (aStyle->Transparency());
13769 anAspect->SetFrontMaterial (aMat);
13770 anAspect->SetInteriorColor (aStyle->Color());
13771 aStyle->SetBasicFillAreaAspect (anAspect);
13772 }
13773 else
13774 {
13775 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13776 }
13777 toRedraw = Standard_True;
13778 }
13779 else
13780 {
23fe70ec 13781 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 13782 return 1;
f838dac4 13783 }
8e5fb5ea 13784 }
13785
f838dac4 13786 if (toPrint)
8e5fb5ea 13787 {
f838dac4 13788 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13789 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13790 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13791 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13792 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13793 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13794 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13795 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13796 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13797 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13798 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13799 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13800 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13801 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13802 }
13803
13804 if (aCtx->NbSelected() != 0 && toRedraw)
13805 {
13806 aCtx->HilightSelected (Standard_True);
13807 }
13808
13809 return 0;
13810}
13811
decdee7d 13812//===============================================================================================
13813//function : VDumpSelectionImage
13814//purpose :
13815//===============================================================================================
13816static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13817 Standard_Integer theArgsNb,
13818 const char** theArgVec)
13819{
13820 if (theArgsNb < 2)
13821 {
23fe70ec 13822 Message::SendFail() << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'";
decdee7d 13823 return 1;
13824 }
13825
13826 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 13827 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 13828 if (aContext.IsNull())
13829 {
23fe70ec 13830 Message::SendFail ("Error: no active viewer");
decdee7d 13831 return 1;
13832 }
13833
13834 TCollection_AsciiString aFile;
13835 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 13836 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 13837 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13838 Standard_Integer aPickedIndex = 1;
13839 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13840 {
13841 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13842 aParam.LowerCase();
13843 if (aParam == "-type")
13844 {
13845 if (++anArgIter >= theArgsNb)
13846 {
23fe70ec 13847 Message::SendFail ("Syntax error: wrong number parameters of flag '-depth'");
decdee7d 13848 return 1;
13849 }
13850
13851 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13852 aValue.LowerCase();
13853 if (aValue == "depth"
13854 || aValue == "normdepth"
13855 || aValue == "normalizeddepth")
13856 {
13857 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13858 anImgFormat = Image_Format_GrayF;
decdee7d 13859 }
13860 if (aValue == "depthinverted"
13861 || aValue == "normdepthinverted"
13862 || aValue == "normalizeddepthinverted"
13863 || aValue == "inverted")
13864 {
13865 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13866 anImgFormat = Image_Format_GrayF;
decdee7d 13867 }
13868 else if (aValue == "unnormdepth"
13869 || aValue == "unnormalizeddepth")
13870 {
13871 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13872 anImgFormat = Image_Format_GrayF;
decdee7d 13873 }
13874 else if (aValue == "objectcolor"
13875 || aValue == "object"
13876 || aValue == "color")
13877 {
13878 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13879 }
13880 else if (aValue == "entitycolor"
13881 || aValue == "entity")
13882 {
13883 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13884 }
13885 else if (aValue == "ownercolor"
13886 || aValue == "owner")
13887 {
13888 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13889 }
13890 else if (aValue == "selectionmodecolor"
13891 || aValue == "selectionmode"
13892 || aValue == "selmodecolor"
13893 || aValue == "selmode")
13894 {
13895 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13896 }
13897 }
13898 else if (aParam == "-picked"
13899 || aParam == "-pickeddepth"
13900 || aParam == "-pickedindex")
13901 {
13902 if (++anArgIter >= theArgsNb)
13903 {
23fe70ec 13904 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 13905 return 1;
13906 }
13907
13908 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13909 }
b40cdc2b 13910 else if (anArgIter + 1 < theArgsNb
13911 && aParam == "-xrpose")
13912 {
13913 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13914 anXRArg.LowerCase();
13915 if (anXRArg == "base")
13916 {
13917 aCustomCam = aView->View()->BaseXRCamera();
13918 }
13919 else if (anXRArg == "head")
13920 {
13921 aCustomCam = aView->View()->PosedXRCamera();
13922 }
13923 else
13924 {
13925 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13926 return 1;
13927 }
13928 if (aCustomCam.IsNull())
13929 {
13930 Message::SendFail() << "Error: undefined XR pose";
13931 return 0;
13932 }
13933 }
decdee7d 13934 else if (aFile.IsEmpty())
13935 {
13936 aFile = theArgVec[anArgIter];
13937 }
13938 else
13939 {
23fe70ec 13940 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 13941 return 1;
13942 }
13943 }
13944 if (aFile.IsEmpty())
13945 {
23fe70ec 13946 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 13947 return 1;
13948 }
13949
decdee7d 13950 Standard_Integer aWidth = 0, aHeight = 0;
13951 aView->Window()->Size (aWidth, aHeight);
13952
13953 Image_AlienPixMap aPixMap;
13954 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13955 {
23fe70ec 13956 Message::SendFail ("Error: can't allocate image");
decdee7d 13957 return 1;
13958 }
b40cdc2b 13959
13960 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13961 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13962 if (!aCustomCam.IsNull())
13963 {
13964 aView->SetCamera (aCustomCam);
13965 }
decdee7d 13966 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13967 {
23fe70ec 13968 Message::SendFail ("Error: can't generate selection image");
decdee7d 13969 return 1;
13970 }
b40cdc2b 13971 if (!aCustomCam.IsNull())
13972 {
13973 aView->SetCamera (aCamBack);
13974 }
13975 aView->SetImmediateUpdate (wasImmUpdate);
13976
decdee7d 13977 if (!aPixMap.Save (aFile))
13978 {
23fe70ec 13979 Message::SendFail ("Error: can't save selection image");
decdee7d 13980 return 0;
13981 }
13982 return 0;
13983}
13984
2108d9a2 13985//===============================================================================================
13986//function : VViewCube
13987//purpose :
13988//===============================================================================================
13989static int VViewCube (Draw_Interpretor& ,
13990 Standard_Integer theNbArgs,
13991 const char** theArgVec)
13992{
13993 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13994 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13995 if (aContext.IsNull() || aView.IsNull())
13996 {
23fe70ec 13997 Message::SendFail ("Error: no active viewer");
2108d9a2 13998 return 1;
13999 }
14000 else if (theNbArgs < 2)
14001 {
23fe70ec 14002 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 14003 return 1;
14004 }
14005
14006 Handle(AIS_ViewCube) aViewCube;
14007 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
14008 Quantity_Color aColorRgb;
14009 TCollection_AsciiString aName;
14010 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14011 {
14012 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14013 anArg.LowerCase();
14014 if (anUpdateTool.parseRedrawMode (anArg))
14015 {
14016 //
14017 }
14018 else if (aViewCube.IsNull())
14019 {
14020 aName = theArgVec[anArgIter];
14021 if (aName.StartsWith ("-"))
14022 {
23fe70ec 14023 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 14024 return 1;
14025 }
14026 Handle(AIS_InteractiveObject) aPrs;
14027 GetMapOfAIS().Find2 (aName, aPrs);
14028 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
14029 if (aViewCube.IsNull())
14030 {
14031 aViewCube = new AIS_ViewCube();
14032 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
14033 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
14034 aViewCube->SetFixedAnimationLoop (false);
14035 }
14036 }
14037 else if (anArg == "-reset")
14038 {
14039 aViewCube->ResetStyles();
14040 }
14041 else if (anArg == "-color"
14042 || anArg == "-boxcolor"
14043 || anArg == "-boxsidecolor"
14044 || anArg == "-sidecolor"
14045 || anArg == "-boxedgecolor"
14046 || anArg == "-edgecolor"
14047 || anArg == "-boxcornercolor"
14048 || anArg == "-cornercolor"
14049 || anArg == "-innercolor"
0aeb8984 14050 || anArg == "-textcolor"
14051 || anArg == "-xaxistextcolor"
14052 || anArg == "-yaxistextcolor"
14053 || anArg == "-zaxistextcolor")
2108d9a2 14054 {
dae2a922 14055 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
14056 theArgVec + anArgIter + 1,
14057 aColorRgb);
2108d9a2 14058 if (aNbParsed == 0)
14059 {
23fe70ec 14060 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 14061 return 1;
14062 }
14063 anArgIter += aNbParsed;
14064 if (anArg == "-boxcolor")
14065 {
14066 aViewCube->SetBoxColor (aColorRgb);
14067 }
14068 else if (anArg == "-boxsidecolor"
14069 || anArg == "-sidecolor")
14070 {
14071 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
14072 aViewCube->SynchronizeAspects();
14073 }
14074 else if (anArg == "-boxedgecolor"
14075 || anArg == "-edgecolor")
14076 {
14077 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
14078 aViewCube->SynchronizeAspects();
14079 }
14080 else if (anArg == "-boxcornercolor"
14081 || anArg == "-cornercolor")
14082 {
14083 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
14084 aViewCube->SynchronizeAspects();
14085 }
14086 else if (anArg == "-innercolor")
14087 {
14088 aViewCube->SetInnerColor (aColorRgb);
14089 }
14090 else if (anArg == "-textcolor")
14091 {
14092 aViewCube->SetTextColor (aColorRgb);
14093 }
0aeb8984 14094 else if (anArg == "-xaxistextcolor"
14095 || anArg == "-yaxistextcolor"
14096 || anArg == "-zaxistextcolor")
14097 {
14098 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
14099 ? Prs3d_DatumParts_XAxis
14100 : (anArg.Value (2) == 'y'
14101 ? Prs3d_DatumParts_YAxis
14102 : Prs3d_DatumParts_ZAxis);
14103 aViewCube->Attributes()->SetOwnDatumAspects();
14104 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
14105 }
2108d9a2 14106 else
14107 {
14108 aViewCube->SetColor (aColorRgb);
14109 }
14110 }
14111 else if (anArgIter + 1 < theNbArgs
14112 && (anArg == "-transparency"
14113 || anArg == "-boxtransparency"))
14114 {
14115 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
14116 if (aValue < 0.0 || aValue > 1.0)
14117 {
23fe70ec 14118 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 14119 return 1;
14120 }
14121
14122 if (anArg == "-boxtransparency")
14123 {
14124 aViewCube->SetBoxTransparency (aValue);
14125 }
14126 else
14127 {
14128 aViewCube->SetTransparency (aValue);
14129 }
14130 }
14131 else if (anArg == "-axes"
14132 || anArg == "-edges"
14133 || anArg == "-vertices"
14134 || anArg == "-vertexes"
14135 || anArg == "-fixedanimation")
14136 {
14137 bool toShow = true;
14138 if (anArgIter + 1 < theNbArgs
dae2a922 14139 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 14140 {
14141 ++anArgIter;
14142 }
14143 if (anArg == "-fixedanimation")
14144 {
14145 aViewCube->SetFixedAnimationLoop (toShow);
14146 }
14147 else if (anArg == "-axes")
14148 {
14149 aViewCube->SetDrawAxes (toShow);
14150 }
14151 else if (anArg == "-edges")
14152 {
14153 aViewCube->SetDrawEdges (toShow);
14154 }
14155 else
14156 {
14157 aViewCube->SetDrawVertices (toShow);
14158 }
14159 }
14160 else if (anArg == "-yup"
14161 || anArg == "-zup")
14162 {
14163 bool isOn = true;
14164 if (anArgIter + 1 < theNbArgs
dae2a922 14165 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 14166 {
14167 ++anArgIter;
14168 }
14169 if (anArg == "-yup")
14170 {
14171 aViewCube->SetYup (isOn);
14172 }
14173 else
14174 {
14175 aViewCube->SetYup (!isOn);
14176 }
14177 }
14178 else if (anArgIter + 1 < theNbArgs
14179 && anArg == "-font")
14180 {
14181 aViewCube->SetFont (theArgVec[++anArgIter]);
14182 }
14183 else if (anArgIter + 1 < theNbArgs
14184 && anArg == "-fontheight")
14185 {
14186 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
14187 }
14188 else if (anArgIter + 1 < theNbArgs
14189 && (anArg == "-size"
14190 || anArg == "-boxsize"))
14191 {
14192 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
14193 anArg != "-boxsize");
14194 }
14195 else if (anArgIter + 1 < theNbArgs
14196 && (anArg == "-boxfacet"
14197 || anArg == "-boxfacetextension"
14198 || anArg == "-facetextension"
14199 || anArg == "-extension"))
14200 {
14201 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
14202 }
14203 else if (anArgIter + 1 < theNbArgs
14204 && (anArg == "-boxedgegap"
14205 || anArg == "-edgegap"))
14206 {
14207 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
14208 }
14209 else if (anArgIter + 1 < theNbArgs
14210 && (anArg == "-boxedgeminsize"
14211 || anArg == "-edgeminsize"))
14212 {
14213 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14214 }
14215 else if (anArgIter + 1 < theNbArgs
14216 && (anArg == "-boxcornerminsize"
14217 || anArg == "-cornerminsize"))
14218 {
14219 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14220 }
14221 else if (anArgIter + 1 < theNbArgs
14222 && anArg == "-axespadding")
14223 {
14224 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14225 }
14226 else if (anArgIter + 1 < theNbArgs
14227 && anArg == "-roundradius")
14228 {
14229 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14230 }
14231 else if (anArgIter + 1 < theNbArgs
14232 && anArg == "-duration")
14233 {
14234 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14235 }
6466cc9e 14236 else if (anArgIter + 1 < theNbArgs
14237 && anArg == "-axesradius")
14238 {
14239 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14240 }
14241 else if (anArgIter + 1 < theNbArgs
14242 && anArg == "-axesconeradius")
14243 {
14244 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14245 }
14246 else if (anArgIter + 1 < theNbArgs
14247 && anArg == "-axessphereradius")
14248 {
14249 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14250 }
2108d9a2 14251 else
14252 {
23fe70ec 14253 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 14254 return 1;
14255 }
14256 }
14257 if (aViewCube.IsNull())
14258 {
23fe70ec 14259 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 14260 return 1;
14261 }
14262
14263 ViewerTest::Display (aName, aViewCube, false);
14264 return 0;
14265}
14266
14b741b0 14267//===============================================================================================
14268//function : VColorConvert
14269//purpose :
14270//===============================================================================================
14271static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14272{
14273 if (theNbArgs != 6)
14274 {
14275 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14276 return 1;
14277 }
14278
14279 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14280 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14281 {
14282 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14283 return 1;
14284 }
14285
14286 const char* aTypeStr = theArgVec[2];
14287 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14288 if (! strcasecmp (aTypeStr, "srgb"))
14289 {
14290 aType = Quantity_TOC_sRGB;
14291 }
14292 else if (! strcasecmp (aTypeStr, "hls"))
14293 {
14294 aType = Quantity_TOC_HLS;
14295 }
14296 else if (! strcasecmp (aTypeStr, "lab"))
14297 {
14298 aType = Quantity_TOC_CIELab;
14299 }
14300 else if (! strcasecmp (aTypeStr, "lch"))
14301 {
14302 aType = Quantity_TOC_CIELch;
14303 }
14304 else
14305 {
14306 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14307 return 1;
14308 }
14309
14310 double aC1 = Draw::Atof (theArgVec[3]);
14311 double aC2 = Draw::Atof (theArgVec[4]);
14312 double aC3 = Draw::Atof (theArgVec[5]);
14313
14314 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14315 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14316
14317 // print values with 6 decimal digits
14318 char buffer[1024];
14319 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14320 theDI << buffer;
14321
14322 return 0;
14323}
14324
14325//===============================================================================================
14326//function : VColorDiff
14327//purpose :
14328//===============================================================================================
14329static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14330{
14331 if (theNbArgs != 7)
14332 {
14333 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14334 return 1;
14335 }
14336
14337 double aR1 = Draw::Atof (theArgVec[1]);
14338 double aG1 = Draw::Atof (theArgVec[2]);
14339 double aB1 = Draw::Atof (theArgVec[3]);
14340 double aR2 = Draw::Atof (theArgVec[4]);
14341 double aG2 = Draw::Atof (theArgVec[5]);
14342 double aB2 = Draw::Atof (theArgVec[6]);
14343
14344 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14345 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14346
14347 theDI << aColor1.DeltaE2000 (aColor2);
14348
14349 return 0;
14350}
14351
6a2fb7a1 14352//===============================================================================================
4551e1be 14353//function : VSelBvhBuild
6a2fb7a1 14354//purpose :
14355//===============================================================================================
14356static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14357{
14358 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14359 if (aCtx.IsNull())
14360 {
14361 Message::SendFail ("Error: no active viewer");
14362 return 1;
14363 }
14364
14365 if (theNbArgs < 2)
14366 {
14367 Message::SendFail ("Error: command syntax is incorrect, see help");
14368 return 1;
14369 }
14370
14371 Standard_Integer toEnable = -1;
14372 Standard_Integer aThreadsNb = -1;
14373 Standard_Boolean toWait = Standard_False;
14374
14375 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14376 {
14377 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14378 anArg.LowerCase();
14379
14380 if (anArg == "-nbthreads"
14381 && anArgIter + 1 < theNbArgs)
14382 {
14383 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14384 if (aThreadsNb < 1)
14385 {
14386 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14387 }
14388 }
14389 else if (anArg == "-wait")
14390 {
14391 toWait = Standard_True;
14392 }
14393 else if (toEnable == -1)
14394 {
14395 Standard_Boolean toEnableValue = Standard_True;
14396 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14397 {
14398 toEnable = toEnableValue ? 1 : 0;
14399 }
14400 else
14401 {
14402 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14403 return 1;
14404 }
14405 }
14406 else
14407 {
14408 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14409 return 1;
14410 }
14411 }
14412
14413 if (aThreadsNb == -1)
14414 {
14415 aThreadsNb = 1;
14416 }
14417 if (toEnable != -1)
14418 {
14419 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14420 }
14421 if (toWait)
14422 {
14423 aCtx->MainSelector()->WaitForBVHBuild();
14424 }
14425
14426 return 0;
14427}
14428
a6049685 14429//=======================================================================
14430//function : ViewerTest_ExitProc
14431//purpose :
14432//=======================================================================
14433static void ViewerTest_ExitProc (ClientData )
14434{
14435 NCollection_List<TCollection_AsciiString> aViewList;
14436 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14437 anIter.More(); anIter.Next())
14438 {
14439 aViewList.Append (anIter.Key1());
14440 }
14441
14442 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14443 anIter.More(); anIter.Next())
14444 {
14445 ViewerTest::RemoveView (anIter.Value(), true);
14446 }
14447}
14448
7fd59977 14449//=======================================================================
14450//function : ViewerCommands
14451//purpose :
14452//=======================================================================
14453
14454void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14455{
a6049685 14456 static bool TheIsInitialized = false;
14457 if (TheIsInitialized)
14458 {
14459 return;
14460 }
14461
14462 TheIsInitialized = true;
14463 // define destruction callback to destroy views in a well-defined order
14464 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
7fd59977 14465
14466 const char *group = "ZeViewer";
b8db9379 14467 theCommands.Add("vdriver",
14468 "vdriver [-list] [-default DriverName] [-load DriverName]"
14469 "\n\t\t: Manages active graphic driver factory."
14470 "\n\t\t: Prints current active driver when called without arguments."
14471 "\n\t\t: Makes specified driver active when ActiveName argument is specified."
14472 "\n\t\t: -list print registered factories"
14473 "\n\t\t: -default define which factory should be used by default (to be used by next vinit call)"
14474 "\n\t\t: -load try loading factory plugin and set it as default one",
14475 __FILE__, VDriver, group);
18d715bd 14476 theCommands.Add("vinit",
fd3f6bd0 14477 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
72ed0644 14478 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
fd3f6bd0 14479 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14480 "\n\t\t: [-display displayName]"
14481 #endif
14482 "\n\t\t: Creates new View window with specified name viewName."
14483 "\n\t\t: By default the new view is created in the viewer and in"
14484 "\n\t\t: graphic driver shared with active view."
14485 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14486 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14487 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
14488#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14489 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14490 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14491#endif
fd3f6bd0 14492 "\n\t\t: -left, -top pixel position of left top corner of the window."
4551e1be 14493 "\n\t\t: -width, -height width and height of window respectively."
72ed0644 14494 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
fd3f6bd0 14495 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14496 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
72ed0644 14497 "\n\t\t: -virtual create an offscreen window within interactive session"
2e93433e 14498 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14499 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14500 __FILE__,VInit,group);
18d715bd 14501 theCommands.Add("vclose" ,
d0cc1cb7 14502 "[view_id [keep_context=0|1]]\n"
18d715bd 14503 "or vclose ALL - to remove all created views\n"
14504 " - removes view(viewer window) defined by its view_id.\n"
14505 " - keep_context: by default 0; if 1 and the last view is deleted"
14506 " the current context is not removed.",
14507 __FILE__,VClose,group);
14508 theCommands.Add("vactivate" ,
e084dbbc 14509 "vactivate view_id [-noUpdate]"
18d715bd 14510 " - activates view(viewer window) defined by its view_id",
14511 __FILE__,VActivate,group);
14512 theCommands.Add("vviewlist",
14513 "vviewlist [format={tree, long}]"
14514 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14515 " - format: format of result output, if tree the output is a tree view;"
14516 "otherwise it's a list of full view names. By default format = tree",
14517 __FILE__,VViewList,group);
7fd59977 14518 theCommands.Add("vhelp" ,
14519 "vhelp : display help on the viewer commands",
14520 __FILE__,VHelp,group);
fc552d84 14521 theCommands.Add("vviewproj",
14522 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14523 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14524 "\n\t\t: Setup view direction"
14525 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14526 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14527 "\n\t\t: for example '+Z' will show front of the model,"
14528 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14529 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14530 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14531 __FILE__,VViewProj,group);
7fd59977 14532 theCommands.Add("vtop" ,
27af3052 14533 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14534 __FILE__,VViewProj,group);
44b8f2d6 14535 theCommands.Add("vbottom" ,
27af3052 14536 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14537 __FILE__,VViewProj,group);
44b8f2d6 14538 theCommands.Add("vleft" ,
27af3052 14539 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14540 __FILE__,VViewProj,group);
44b8f2d6 14541 theCommands.Add("vright" ,
27af3052 14542 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14543 __FILE__,VViewProj,group);
7fd59977 14544 theCommands.Add("vaxo" ,
27af3052 14545 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14546 __FILE__,VViewProj,group);
44b8f2d6 14547 theCommands.Add("vfront" ,
27af3052 14548 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14549 __FILE__,VViewProj,group);
44b8f2d6 14550 theCommands.Add("vback" ,
27af3052 14551 "vback : Back view. Orientation -X+Z" ,
fc552d84 14552 __FILE__,VViewProj,group);
7fd59977 14553 theCommands.Add("vpick" ,
14554 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14555 VPick,group);
1beb58d7 14556 theCommands.Add("vfit",
14557 "vfit or <F> [-selected] [-noupdate]"
b586500b 14558 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14559 __FILE__,VFit,group);
6262a303 14560 theCommands.Add ("vfitarea",
14561 "vfitarea x1 y1 x2 y2"
14562 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14563 "\n\t\t: Fit view to show area located between two points"
14564 "\n\t\t: given in world 2D or 3D corrdinates.",
14565 __FILE__, VFitArea, group);
197ac94e 14566 theCommands.Add ("vzfit", "vzfit [scale]\n"
14567 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14568 " \"scale\" - specifies factor to scale computed z range.\n",
14569 __FILE__, VZFit, group);
7fd59977 14570 theCommands.Add("vrepaint",
8693dfd0 14571 "vrepaint [-immediate] [-continuous FPS]"
14572 "\n\t\t: force redraw of active View"
14573 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14574 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14575 "\n\t\t: 0 means no continuous rendering,"
14576 "\n\t\t: -1 means non-stop redraws,"
14577 "\n\t\t: >0 specifies target framerate,",
7fd59977 14578 __FILE__,VRepaint,group);
14579 theCommands.Add("vclear",
faea8b40 14580 "vclear : vclear"
14581 "\n\t\t: remove all the object from the viewer",
7fd59977 14582 __FILE__,VClear,group);
293211ae 14583 theCommands.Add (
14584 "vbackground",
14585 "Changes background or some background settings.\n"
14586 "\n"
14587 "Usage:\n"
14588 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14589 " vbackground -imageMode FillType\n"
14590 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14591 " vbackground -gradientMode FillMethod\n"
077a220c 14592 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14593 " vbackground -color Color\n"
14594 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14595 " vbackground -default -color Color\n"
14596 " vbackground -help\n"
14597 "\n"
14598 "Options:\n"
14599 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14600 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14601 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14602 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
4551e1be 14603 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
077a220c 14604 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14605 " -order (-o): defines order of tiles in one image cubemap\n"
14606 " (has no effect in case of multi image cubemaps)\n"
293211ae 14607 " -color (-col): sets background color\n"
14608 " -default (-def): sets background default gradient or color\n"
14609 " -help (-h): outputs short help message\n"
14610 "\n"
14611 "Arguments:\n"
077a220c 14612 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14613 " or reals within the range [0.0, 1.0]\n"
077a220c 14614 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14615 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14616 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14617 "CORNER4\n"
077a220c 14618 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14619 " ImageFile: a name of the file with the image used as a background\n"
14620 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14621 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14622 __FILE__,
14623 vbackground,
14624 group);
14625 theCommands.Add ("vsetbg",
14626 "Loads image as background."
14627 "\n\t\t: vsetbg ImageFile [FillType]"
14628 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14629 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14630 __FILE__,
14631 vbackground,
14632 group);
14633 theCommands.Add ("vsetbgmode",
14634 "Changes background image fill type."
14635 "\n\t\t: vsetbgmode [-imageMode] FillType"
14636 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14637 __FILE__,
14638 vbackground,
14639 group);
14640 theCommands.Add ("vsetgradientbg",
14641 "Mounts gradient background."
14642 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14643 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14644 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14645 __FILE__,
14646 vbackground,
14647 group);
14648 theCommands.Add ("vsetgrbgmode",
14649 "Changes gradient background fill method."
14650 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14651 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14652 __FILE__,
14653 vbackground,
14654 group);
14655 theCommands.Add ("vsetcolorbg",
14656 "Sets background color."
14657 "\n\t\t: vsetcolorbg [-color] Color."
14658 "\n\t\t: Alias for 'vbackground -color Color'.",
14659 __FILE__,
14660 vbackground,
14661 group);
14662 theCommands.Add ("vsetdefaultbg",
14663 "Sets default viewer background fill color (flat/gradient)."
14664 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14665 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14666 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14667 "\n\t\t: vsetdefaultbg [-color] Color"
14668 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14669 __FILE__,
14670 vbackground,
14671 group);
7fd59977 14672 theCommands.Add("vscale",
14673 "vscale : vscale X Y Z",
14674 __FILE__,VScale,group);
14675 theCommands.Add("vzbufftrihedron",
536d98e2 14676 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14677 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14678 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14679 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14680 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
0aeb8984 14681 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
536d98e2 14682 "\n\t\t: Displays a trihedron",
14683 __FILE__,VZBuffTrihedron,group);
7fd59977 14684 theCommands.Add("vrotate",
4af098ba 14685 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14686 "\n : Option -mouseStart starts rotation according to the mouse position"
14687 "\n : Option -mouseMove continues rotation with angle computed"
14688 "\n : from last and new mouse position."
14689 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14690 __FILE__,VRotate,group);
14691 theCommands.Add("vzoom",
14692 "vzoom : vzoom coef",
14693 __FILE__,VZoom,group);
14694 theCommands.Add("vpan",
14695 "vpan : vpan dx dy",
14696 __FILE__,VPan,group);
7fd59977 14697 theCommands.Add("vcolorscale",
4b3d6eb1 14698 "vcolorscale name [-noupdate|-update] [-demo]"
14699 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14700 "\n\t\t: [-font HeightFont=20]"
14701 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14702 "\n\t\t: [-smoothTransition {on|off}=off]"
14703 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14704 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14705 "\n\t\t: [-textpos {left|right|center|none}=right]"
14706 "\n\t\t: [-labelAtBorder {on|off}=on]"
14707 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14708 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14709 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14710 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14711 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14712 "\n\t\t: -demo - displays a color scale with demonstratio values"
14713 "\n\t\t: -colors - set colors for all intervals"
14714 "\n\t\t: -color - set color for specific interval"
14b741b0 14715 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14716 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14717 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14718 "\n\t\t: at border means the value inbetween neighbor intervals,"
14719 "\n\t\t: at center means the center value within current interval"
14720 "\n\t\t: -labels - set labels for all intervals"
14721 "\n\t\t: -freeLabels - same as -labels but does not require"
14722 "\n\t\t: matching the number of intervals"
14723 "\n\t\t: -label - set label for specific interval"
14724 "\n\t\t: -title - set title"
14725 "\n\t\t: -reversed - setup smooth color transition between intervals"
14726 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14727 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14728 __FILE__, VColorScale, group);
7fd59977 14729 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14730 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14731 "\t[-namefont Name] [-valuesfont Name]\n"
14732 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14733 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14734 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14735 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14736 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14737 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14738 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14739 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14740 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14741 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14742 " - Displays or erases graduated trihedron"
14743 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14744 " - namefont - font of axes names. Default: Arial\n"
14745 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14746 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14747 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14748 " - valuesfont - font of axes values. Default: Arial\n"
14749 " - xcolor, ycolor, zcolor - color of axis and values\n"
14750 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14751 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14752 __FILE__,VGraduatedTrihedron,group);
3bffef55 14753 theCommands.Add("vtile" ,
14754 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14755 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14756 "\n\t\t: -totalSize the size of virtual bigger viewport"
14757 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14758 "\n\t\t: -lowerLeft tile offset as lower left corner"
14759 "\n\t\t: -upperLeft tile offset as upper left corner",
14760 __FILE__, VTile, group);
59f45b7c 14761 theCommands.Add("vzlayer",
7c3ef2f7 14762 "vzlayer [layerId]"
1c728f2d 14763 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14764 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14765 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14766 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14767 "\n\t\t: ZLayer list management:"
14768 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14769 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14770 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14771 "\n\t\t: -delete delete z layer"
14772 "\n\t\t: -get print sequence of z layers"
14773 "\n\t\t: -settings print status of z layer settings"
14774 "\n\t\t: -disable disables given setting"
14775 "\n\t\t: -enable enables given setting",
59f45b7c 14776 __FILE__,VZLayer,group);
20637bd2 14777 theCommands.Add("vlayerline",
14778 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14779 __FILE__,VLayerLine,group);
79931835 14780 theCommands.Add("vgrid",
14781 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14782 "\n\t\t: [-step X Y] [-size DX DY]"
14783 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 14784 __FILE__, VGrid, group);
c40b7d58 14785 theCommands.Add ("vpriviledgedplane",
14786 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14787 "\n\t\t: Ox, Oy, Oz - plane origin"
14788 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14789 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14790 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14791 __FILE__, VPriviledgedPlane, group);
f25b82d6 14792 theCommands.Add ("vconvert",
14793 "vconvert v [Mode={window|view}]"
14794 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14795 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14796 "\n\t\t: window - convert to window coordinates, pixels"
14797 "\n\t\t: view - convert to view projection plane"
14798 "\n\t\t: grid - convert to model coordinates, given on grid"
4551e1be 14799 "\n\t\t: ray - convert projection ray to model coordinates"
f25b82d6 14800 "\n\t\t: - vconvert v window : convert view to window;"
14801 "\n\t\t: - vconvert v view : convert window to view;"
14802 "\n\t\t: - vconvert x y window : convert view to window;"
14803 "\n\t\t: - vconvert x y view : convert window to view;"
14804 "\n\t\t: - vconvert x y : convert window to model;"
14805 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14806 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14807 "\n\t\t: - vconvert x y z window : convert model to window;"
14808 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14809 "\n\t\t: Converts the given coordinates to window/view/model space.",
14810 __FILE__, VConvert, group);
208e6839 14811 theCommands.Add ("vfps",
e084dbbc 14812 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 14813 __FILE__, VFps, group);
b5ac8292 14814 theCommands.Add ("vstereo",
f978241f 14815 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 14816 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 14817 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 14818 "\n\t\t: Control stereo output mode."
14819 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14820 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14821 "\n\t\t: Available modes for -mode:"
f978241f 14822 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14823 "\n\t\t: requires driver support."
14824 "\n\t\t: Should be called BEFORE vinit!"
14825 "\n\t\t: anaglyph - Anaglyph glasses"
14826 "\n\t\t: rowInterlaced - row-interlaced display"
14827 "\n\t\t: columnInterlaced - column-interlaced display"
14828 "\n\t\t: chessBoard - chess-board output"
14829 "\n\t\t: sideBySide - horizontal pair"
14830 "\n\t\t: overUnder - vertical pair"
b40cdc2b 14831 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 14832 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14833 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14834 "\n\t\t: greenMagentaSimple",
b5ac8292 14835 __FILE__, VStereo, group);
f0430952 14836 theCommands.Add ("vmemgpu",
14837 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14838 " with f option returns free memory in bytes",
14839 __FILE__, VMemGpu, group);
85e096c3 14840 theCommands.Add ("vreadpixel",
ba00aab7 14841 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 14842 " : Read pixel value for active view",
14843 __FILE__, VReadPixel, group);
692613e5 14844 theCommands.Add("diffimage",
fd3f6bd0 14845 "diffimage imageFile1 imageFile2 [diffImageFile]"
14846 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14847 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14848 "\n\t\t: Compare two images by content and generate difference image."
14849 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14850 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 14851 __FILE__, VDiffImage, group);
4754e164 14852 theCommands.Add ("vselect",
e76471b5 14853 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-replaceextra|-xor|-add|-remove]\n"
4754e164 14854 "- emulates different types of selection:\n"
14855 "- 1) single click selection\n"
14856 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14857 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 14858 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14859 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14860 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14861 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
e76471b5 14862 "- 5) selection scheme replace, replaceextra, xor, add or remove (replace by default)",
4754e164 14863 __FILE__, VSelect, group);
14864 theCommands.Add ("vmoveto",
8a590580 14865 "vmoveto [x y] [-reset]"
14866 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14867 "\n\t\t: -reset resets current highlighting",
4754e164 14868 __FILE__, VMoveTo, group);
1beb58d7 14869 theCommands.Add ("vviewparams",
14870 "vviewparams [-args] [-scale [s]]"
14871 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14872 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14873 "\n\t\t: Manage current view parameters or prints all"
14874 "\n\t\t: current values when called without argument."
14875 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14876 "\n\t\t: -eye [x y z] prints or sets eye location"
14877 "\n\t\t: -at [x y z] prints or sets center of look"
14878 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14879 "\n\t\t: -proj [x y z] prints or sets direction of look"
14880 "\n\t\t: -center x y sets location of center of the screen in pixels"
14881 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14882 "\n\t\t: or changes the size of its maximum dimension"
14883 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 14884 __FILE__, VViewParams, group);
1beb58d7 14885
2e93433e 14886 theCommands.Add("v2dmode",
14887 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14888 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14889 "\n\t\t: mode - switches On/Off rotation mode"
14890 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14891 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14892 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14893 "\n\t\t: View camera position might be changed only by commands.",
14894 __FILE__, V2DMode, group);
14895
1beb58d7 14896 theCommands.Add("vanimation", "Alias for vanim",
14897 __FILE__, VAnimation, group);
14898
14899 theCommands.Add("vanim",
14900 "List existing animations:"
14901 "\n\t\t: vanim"
14902 "\n\t\t: Animation playback:"
14903 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14904 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14905 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14906 "\n\t\t: -freeLook skip camera animations"
14907 "\n\t\t: -lockLoop disable any interactions"
14908 "\n\t\t:"
14909 "\n\t\t: Animation definition:"
14910 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14911 "\n\t\t: [start TimeSec] [duration TimeSec]"
14912 "\n\t\t:"
14913 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14914 "\n\t\t: specifies nested animations."
14915 "\n\t\t: There is no syntax to explicitly add new animation,"
14916 "\n\t\t: and all non-existing animations within the name will be"
14917 "\n\t\t: implicitly created on first use (including parents)."
14918 "\n\t\t:"
14919 "\n\t\t: Each animation might define the SINGLE action (see below),"
14920 "\n\t\t: like camera transition, object transformation or custom callback."
14921 "\n\t\t: Child animations can be used for defining concurrent actions."
14922 "\n\t\t:"
14923 "\n\t\t: Camera animation:"
14924 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14925 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14926 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14927 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14928 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14929 "\n\t\t: -atX camera Center positions pair"
14930 "\n\t\t: -upX camera Up directions pair"
14931 "\n\t\t: -scaleX camera Scale factors pair"
14932 "\n\t\t: Object animation:"
14933 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14934 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14935 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14936 "\n\t\t: -locX object Location points pair (translation)"
14937 "\n\t\t: -rotX object Orientations pair (quaternions)"
14938 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14939 "\n\t\t: Custom callback:"
14940 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14941 "\n\t\t: %Pts overall animation presentation timestamp"
14942 "\n\t\t: %LocalPts local animation timestamp"
14943 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 14944 "\n\t\t:"
14945 "\n\t\t: Video recording:"
14946 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14947 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14948 "\n\t\t: [-crf Value] [-preset Preset]"
14949 "\n\t\t: -fps video framerate"
14950 "\n\t\t: -format file format, container (matroska, etc.)"
14951 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14952 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14953 "\n\t\t: -crf constant rate factor (specific to codec)"
14954 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 14955 __FILE__, VAnimation, group);
14956
4754e164 14957 theCommands.Add("vchangeselected",
dc3fe572 14958 "vchangeselected shape"
4754e164 14959 "- adds to shape to selection or remove one from it",
14960 __FILE__, VChangeSelected, group);
4754e164 14961 theCommands.Add ("vnbselected",
faea8b40 14962 "vnbselected"
14963 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14964 theCommands.Add ("vcamera",
30a1b24e 14965 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14966 "\n\t\t: [-persp]"
14967 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14968 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14969 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14970 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 14971 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14972 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 14973 "\n\t\t: Manages camera parameters."
4551e1be 14974 "\n\t\t: Displays frustum when presentation name PrsName is specified."
6b62b2da 14975 "\n\t\t: Prints current value when option called without argument."
14976 "\n\t\t: Orthographic camera:"
14977 "\n\t\t: -ortho activate orthographic projection"
14978 "\n\t\t: Perspective camera:"
14979 "\n\t\t: -persp activate perspective projection (mono)"
14980 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 14981 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 14982 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 14983 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 14984 "\n\t\t: Stereoscopic camera:"
14985 "\n\t\t: -stereo perspective projection (stereo)"
14986 "\n\t\t: -leftEye perspective projection (left eye)"
14987 "\n\t\t: -rightEye perspective projection (right eye)"
14988 "\n\t\t: -iod intraocular distance value"
14989 "\n\t\t: -iodType distance type, absolute or relative"
14990 "\n\t\t: -zfocus stereographic focus value"
14991 "\n\t\t: -zfocusType focus type, absolute or relative",
14992 __FILE__, VCamera, group);
b5ac8292 14993 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14994 "- vautozfit [on={1|0}] [scale]\n"
14995 " Prints or changes parameters of automatic z-fit mode:\n"
14996 " \"on\" - turns automatic z-fit on or off\n"
14997 " \"scale\" - specifies factor to scale computed z range.\n",
14998 __FILE__, VAutoZFit, group);
b5ac8292 14999 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
15000 " vzrange - without parameters shows current values\n"
15001 " vzrange [znear] [zfar] - applies provided values to view",
15002 __FILE__,VZRange, group);
4754e164 15003 theCommands.Add("vsetviewsize",
15004 "vsetviewsize size",
15005 __FILE__,VSetViewSize,group);
15006 theCommands.Add("vmoveview",
15007 "vmoveview Dx Dy Dz [Start = 1|0]",
15008 __FILE__,VMoveView,group);
15009 theCommands.Add("vtranslateview",
15010 "vtranslateview Dx Dy Dz [Start = 1|0)]",
15011 __FILE__,VTranslateView,group);
15012 theCommands.Add("vturnview",
15013 "vturnview Ax Ay Az [Start = 1|0]",
15014 __FILE__,VTurnView,group);
269294d6 15015 theCommands.Add("vtextureenv",
15016 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
15017 "or user-defined file and optionally applying texture mapping parameters\n"
15018 " Usage:\n"
15019 " vtextureenv off - disables environment mapping\n"
15020 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
15021 " std_texture = (0..7)\n"
15022 " rep = {clamp|repeat}\n"
15023 " mod = {decal|modulate}\n"
15024 " flt = {nearest|bilinear|trilinear}\n"
15025 " ss, st - scale factors for s and t texture coordinates\n"
15026 " ts, tt - translation for s and t texture coordinates\n"
15027 " rot - texture rotation angle in degrees",
15028 __FILE__, VTextureEnv, group);
1eeef710 15029 theCommands.Add("vhlr",
15030 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
15031 "\n\t\t: Hidden Line Removal algorithm."
15032 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
15033 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 15034 __FILE__,VHLR,group);
1eeef710 15035 theCommands.Add("vhlrtype",
15036 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
15037 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
15038 "\n\t\t: 'algo' - exact HLR algorithm is applied"
15039 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
15040 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 15041 __FILE__,VHLRType,group);
3e05329c 15042 theCommands.Add("vclipplane",
15043 "vclipplane planeName [{0|1}]"
25c35042 15044 "\n\t\t: [-equation1 A B C D]"
15045 "\n\t\t: [-equation2 A B C D]"
15046 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 15047 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 15048 "\n\t\t: [-maxPlanes]"
15049 "\n\t\t: [-capping {0|1}]"
1b661a81 15050 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 15051 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
15052 "\n\t\t: [-texRotate Angle]"
15053 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
15054 "\n\t\t: [-useObjShader {0|1}]"
15055 "\n\t\t: Clipping planes management:"
15056 "\n\t\t: -maxPlanes print plane limit for view"
15057 "\n\t\t: -delete delete plane with given name"
15058 "\n\t\t: {off|on|0|1} turn clipping on/off"
15059 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
15060 "\n\t\t: applied to active View when list is omitted"
15061 "\n\t\t: -equation A B C D change plane equation"
15062 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
15063 "\n\t\t: Capping options:"
15064 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
15065 "\n\t\t: -color R G B set capping color"
1b661a81 15066 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 15067 "\n\t\t: -texName Texture set capping texture"
15068 "\n\t\t: -texScale SX SY set capping tex scale"
15069 "\n\t\t: -texOrigin TX TY set capping tex origin"
15070 "\n\t\t: -texRotate Angle set capping tex rotation"
15071 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
15072 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
15073 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
15074 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
15075 __FILE__, VClipPlane, group);
392ac980 15076 theCommands.Add("vdefaults",
4c513386 15077 "vdefaults [-absDefl value]"
15078 "\n\t\t: [-devCoeff value]"
15079 "\n\t\t: [-angDefl value]"
15080 "\n\t\t: [-autoTriang {off/on | 0/1}]"
15081 , __FILE__, VDefaults, group);
12381341 15082 theCommands.Add("vlight",
816d03ee 15083 "tool to manage light sources, without arguments shows list of lights."
15084 "\n Main commands: "
992ed6b3 15085 "\n '-clear' to clear lights"
2daa5d95 15086 "\n '-{def}aults' to load default lights"
992ed6b3 15087 "\n '-add' <type> to add any light source"
816d03ee 15088 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
15089 "\n 'change' <lightId> to edit light source with specified lightId"
15090 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 15091 "\n -layer Id"
15092 "\n -{pos}ition X Y Z"
15093 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
15094 "\n -color colorName"
15095 "\n -{head}light 0|1"
d84e8669 15096 "\n -castShadows 0|1"
992ed6b3 15097 "\n -{sm}oothness value"
15098 "\n -{int}ensity value"
15099 "\n -{constAtten}uation value"
15100 "\n -{linearAtten}uation value"
15101 "\n -angle angleDeg"
15102 "\n -{spotexp}onent value"
88b312d3 15103 "\n -range value"
992ed6b3 15104 "\n -local|-global"
2daa5d95 15105 "\n -name value"
15106 "\n -display nameOfLight (display light source with specified nameOfLight or its name)"
15107 "\n -showName {1|0} show/hide the name of light source; 1 by default"
15108 "\n -showRange {1|0} show/hide the range of spot/positional light source; 1 by default"
15109 "\n -prsZoomable {1|0} make light presentation zoomable/non-zoomable"
15110 "\n -prsSize {Value} set light presentation size"
15111 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
992ed6b3 15112 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 15113 __FILE__, VLight, group);
67312b79 15114 theCommands.Add("vpbrenv",
15115 "vpbrenv -clear|-generate"
15116 "\n\t\t: Clears or generates PBR environment map of active view."
15117 "\n\t\t: -clear clears PBR environment (fills by white color)"
15118 "\n\t\t: -generate generates PBR environment from current background cubemap",
15119 __FILE__, VPBREnvironment, group);
6b62b2da 15120 theCommands.Add("vraytrace",
15121 "vraytrace [0|1]"
189f85a3 15122 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 15123 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
15124 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
15125 __FILE__, VRenderParams, group);
bc8c79bb 15126 theCommands.Add("vrenderparams",
4c7a3fae 15127 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
15128 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
15129 "\n\t\t: Common parameters:"
15130 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
d37aef5c 15131 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1]"
15132 "\n\t\t: [-resolution value=72] [-fontHinting {off|normal|light}=off]"
15133 "\n\t\t: [-fontAutoHinting {auto|force|disallow}=auto]"
4c7a3fae 15134 "\n\t\t: [-oit {off|0.0-1.0}=off]"
d84e8669 15135 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
4c7a3fae 15136 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
15137 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
15138 "\n\t\t: [-sync {default|views}] [-reset]"
15139 "\n\t\t: -raster Disables GPU ray-tracing."
15140 "\n\t\t: -shadingModel Controls shading model."
15141 "\n\t\t: -msaa Specifies number of samples for MSAA."
15142 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
15143 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
d37aef5c 15144 "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens."
15145 "\n\t\t: -fontAutoHinting Manages font autohinting."
4c7a3fae 15146 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
15147 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
15148 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
15149 "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result,"
15150 "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)."
d84e8669 15151 "\n\t\t: -shadows Enables/disables shadows rendering."
15152 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
15153 "\n\t\t: -shadowMapBias Shadow map bias."
4c7a3fae 15154 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
15155 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
15156 "\n\t\t: sets state to check structures culled previously."
15157 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
15158 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
15159 "\n\t\t: Diagnostic output (on-screen overlay):"
15160 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
15161 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
15162 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
15163 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
15164 "\n\t\t: -perfUpdateInterval Performance counters update interval."
15165 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
15166 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
15167 "\n\t\t: Ray-Tracing options:"
d84e8669 15168 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
4c7a3fae 15169 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
15170 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
15171 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
15172 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
15173 "\n\t\t: [-maxRad {value>0}=30.0]"
15174 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15175 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15176 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15177 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
4c7a3fae 15178 "\n\t\t: -reflections Enables/disables specular reflections."
15179 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15180 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15181 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15182 "\n\t\t: -env Enables/disables environment map background."
15183 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15184 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15185 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15186 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15187 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15188 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15189 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15190 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15191 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15192 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15193 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15194 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15195 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15196 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15197 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15198 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15199 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15200 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15201 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15202 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15203 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15204 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15205 "\n\t\t: Debug options:"
15206 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15207 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15208 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15209 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 15210 __FILE__, VRenderParams, group);
79b544e6 15211 theCommands.Add("vstatprofiler",
15212 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15213 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 15214 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 15215 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15216 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15217 "\n [-noredraw]"
15218 "\n\t\t: Prints rendering statistics."
15219 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15220 "\n\t\t: else - print all performance counters set previously."
15221 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15222 __FILE__, VStatProfiler, group);
49e1a5c7 15223 theCommands.Add ("vplace",
15224 "vplace dx dy"
15225 "\n\t\t: Places the point (in pixels) at the center of the window",
15226 __FILE__, VPlace, group);
0717ddc1 15227 theCommands.Add("vxrotate",
15228 "vxrotate",
15229 __FILE__,VXRotate,group);
15230
625e1958 15231 theCommands.Add("vmanipulator",
15232 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15233 "\n tool to create and manage AIS manipulators."
15234 "\n Options: "
15235 "\n '-attach AISObject' attach manipulator to AISObject"
ff6122e0 15236 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
625e1958 15237 "\n '-adjustSize {0|1}' adjust size when attaching"
15238 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 15239 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15240 "\n by default it is displayed in all views of the current viewer"
625e1958 15241 "\n '-detach' detach manipulator"
15242 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15243 "\n '-transform mouse_x mouse_y' - invoke transformation"
15244 "\n '-stopTransform [abort]' - invoke stop of transformation"
15245 "\n '-move x y z' - move attached object"
15246 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15247 "\n '-scale factor' - scale attached object"
15248 "\n '-autoActivate {0|1}' - set activation on detection"
15249 "\n '-followTranslation {0|1}' - set following translation transform"
15250 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 15251 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 15252 "\n '-gap value' - set gap between sub-parts"
15253 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 15254 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 15255 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15256 "\n '-size value' - set size of manipulator"
15257 "\n '-zoomable {0|1}' - set zoom persistence",
15258 __FILE__, VManipulator, group);
15259
8e5fb5ea 15260 theCommands.Add("vselprops",
f838dac4 15261 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 15262 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15263 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 15264 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15265 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 15266 "\n -pickStrategy {first|topmost} : defines picking strategy"
15267 "\n 'first' to pick first acceptable (default)"
15268 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 15269 "\n -pixTol value : sets up pixel tolerance"
8c36926a 15270 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15271 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15272 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 15273 "\n -dispMode dispMode : sets display mode for highlighting"
15274 "\n -layer ZLayer : sets ZLayer for highlighting"
15275 "\n -color {name|r g b} : sets highlight color"
15276 "\n -transp value : sets transparency coefficient for highlight"
15277 "\n -material material : sets highlight material"
8e5fb5ea 15278 "\n -print : prints current state of all mentioned parameters",
15279 __FILE__, VSelectionProperties, group);
be3d8cbc 15280 theCommands.Add ("vhighlightselected",
15281 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15282 __FILE__, VSelectionProperties, group);
8e5fb5ea 15283
decdee7d 15284 theCommands.Add ("vseldump",
15285 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
b40cdc2b 15286 "\n\t\t: [-xrPose base|head=base]"
decdee7d 15287 "\n\t\t: Generate an image based on detection results:"
15288 "\n\t\t: depth normalized depth values"
15289 "\n\t\t: unnormDepth unnormalized depth values"
15290 "\n\t\t: object color of detected object"
15291 "\n\t\t: owner color of detected owner"
15292 "\n\t\t: selMode color of selection mode"
15293 "\n\t\t: entity color of etected entity",
15294 __FILE__, VDumpSelectionImage, group);
293211ae 15295
2108d9a2 15296 theCommands.Add ("vviewcube",
15297 "vviewcube name"
15298 "\n\t\t: Displays interactive view manipualtion object."
15299 "\n\t\t: Options: "
15300 "\n\t\t: -reset reset geomertical and visual attributes'"
15301 "\n\t\t: -size Size adapted size of View Cube"
15302 "\n\t\t: -boxSize Size box size"
0aeb8984 15303 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
2108d9a2 15304 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15305 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15306 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15307 "\n\t\t: -color Color color of View Cube"
15308 "\n\t\t: -boxColor Color box color"
15309 "\n\t\t: -boxSideColor Color box sides color"
15310 "\n\t\t: -boxEdgeColor Color box edges color"
15311 "\n\t\t: -boxCornerColor Color box corner color"
15312 "\n\t\t: -textColor Color color of side text of view cube"
15313 "\n\t\t: -innerColor Color inner box color"
15314 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15315 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
0aeb8984 15316 "\n\t\t: -xAxisTextColor Color color of X axis label"
15317 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15318 "\n\t\t: -zAxisTextColor Color color of Z axis label"
2108d9a2 15319 "\n\t\t: -font Name font name"
15320 "\n\t\t: -fontHeight Value font height"
15321 "\n\t\t: -boxFacetExtension Value box facet extension"
15322 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15323 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15324 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15325 "\n\t\t: -axesPadding Value padding between box and arrows"
15326 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15327 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15328 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15329 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15330 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15331 "\n\t\t: -duration Seconds animation duration in seconds",
15332 __FILE__, VViewCube, group);
15333
14b741b0 15334 theCommands.Add("vcolorconvert" ,
15335 "vcolorconvert {from|to} type C1 C2 C2"
15336 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15337 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15338 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15339 __FILE__,VColorConvert,group);
15340 theCommands.Add("vcolordiff" ,
15341 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15342 __FILE__,VColorDiff,group);
6a2fb7a1 15343 theCommands.Add("vselbvhbuild",
15344 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15345 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15346 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15347 "\n\t\t: -wait waits for building all of BVH",
15348 __FILE__,VSelBvhBuild,group);
2108d9a2 15349}