0032433: Visualization, TKService - introduce Wasm_Window implementing Aspect_Window...
[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>
0461e7fd 25#include <AIS_Axis.hxx>
30a1b24e 26#include <AIS_CameraFrustum.hxx>
7a324550 27#include <AIS_ColorScale.hxx>
49582f9d 28#include <AIS_InteractiveContext.hxx>
2daa5d95 29#include <AIS_LightSource.hxx>
0a768f56 30#include <AIS_ListOfInteractive.hxx>
31#include <AIS_ListIteratorOfListOfInteractive.hxx>
49582f9d 32#include <AIS_Manipulator.hxx>
2108d9a2 33#include <AIS_ViewCube.hxx>
49582f9d 34#include <AIS_Shape.hxx>
0461e7fd 35#include <AIS_Point.hxx>
49582f9d 36#include <Aspect_DisplayConnection.hxx>
8a590580 37#include <Aspect_Grid.hxx>
49582f9d 38#include <Aspect_TypeOfLine.hxx>
39#include <Draw.hxx>
40#include <Draw_Appli.hxx>
41#include <Draw_Interpretor.hxx>
08f8a185 42#include <Draw_ProgressIndicator.hxx>
49582f9d 43#include <gp_Dir.hxx>
44#include <gp_Pln.hxx>
45#include <gp_Pnt.hxx>
0461e7fd 46#include <Geom_Axis2Placement.hxx>
47#include <Geom_CartesianPoint.hxx>
61b0191c 48#include <Graphic3d_ArrayOfPolylines.hxx>
49582f9d 49#include <Graphic3d_AspectFillArea3d.hxx>
2bd4c032 50#include <Graphic3d_AspectMarker3d.hxx>
49582f9d 51#include <Graphic3d_ClipPlane.hxx>
077a220c 52#include <Graphic3d_CubeMapPacked.hxx>
53#include <Graphic3d_CubeMapSeparate.hxx>
a79f67f8 54#include <Graphic3d_GraduatedTrihedron.hxx>
b8db9379 55#include <Graphic3d_GraphicDriver.hxx>
56#include <Graphic3d_GraphicDriverFactory.hxx>
49582f9d 57#include <Graphic3d_NameOfTextureEnv.hxx>
58#include <Graphic3d_Texture2Dmanual.hxx>
269294d6 59#include <Graphic3d_TextureEnv.hxx>
60#include <Graphic3d_TextureParams.hxx>
61#include <Graphic3d_TypeOfTextureFilter.hxx>
49582f9d 62#include <Image_AlienPixMap.hxx>
63#include <Image_Diff.hxx>
64#include <Image_VideoRecorder.hxx>
b8db9379 65#include <Message.hxx>
7e785937 66#include <Message_ProgressScope.hxx>
67#include <Message_ProgressRange.hxx>
49582f9d 68#include <NCollection_DataMap.hxx>
18d715bd 69#include <NCollection_List.hxx>
d6fbb2ab 70#include <NCollection_LocalArray.hxx>
18d715bd 71#include <NCollection_Vector.hxx>
8693dfd0 72#include <OSD.hxx>
6a2fb7a1 73#include <OSD_Parallel.hxx>
208e6839 74#include <OSD_Timer.hxx>
4269bd1b 75#include <Prs3d_ShadingAspect.hxx>
0aeb8984 76#include <Prs3d_DatumAspect.hxx>
6262338c 77#include <Prs3d_Drawer.hxx>
61b0191c 78#include <Prs3d_LineAspect.hxx>
fd3f6bd0 79#include <Prs3d_Text.hxx>
80#include <Select3D_SensitivePrimitiveArray.hxx>
49582f9d 81#include <TColStd_HSequenceOfAsciiString.hxx>
82#include <TColStd_SequenceOfInteger.hxx>
83#include <TColStd_HSequenceOfReal.hxx>
84#include <TColgp_Array1OfPnt2d.hxx>
85#include <TColStd_MapOfAsciiString.hxx>
86#include <ViewerTest_AutoUpdater.hxx>
08b7a39f 87#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 88#include <ViewerTest_EventManager.hxx>
89#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
90#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
91#include <ViewerTest_CmdParser.hxx>
92#include <ViewerTest_V3dView.hxx>
93#include <V3d_AmbientLight.hxx>
94#include <V3d_DirectionalLight.hxx>
95#include <V3d_PositionalLight.hxx>
96#include <V3d_SpotLight.hxx>
0aeb8984 97#include <V3d_Trihedron.hxx>
1a96d253 98#include <V3d_Viewer.hxx>
0461e7fd 99#include <UnitsAPI.hxx>
7fd59977 100
293211ae 101#include <tcl.h>
102
692613e5 103#include <cstdlib>
25289ec1 104
58655684 105#if defined(_WIN32)
4fe56619 106 #include <WNT_WClass.hxx>
107 #include <WNT_Window.hxx>
d6fbb2ab 108 #include <WNT_HIDSpaceMouse.hxx>
b69e576a 109#elif defined(HAVE_XLIB)
4fe56619 110 #include <Xw_Window.hxx>
b69e576a 111 #include <X11/Xlib.h>
4fe56619 112 #include <X11/Xutil.h>
b69e576a 113#elif defined(__APPLE__)
114 #include <Cocoa_Window.hxx>
f9ab9f7f 115#elif defined(__EMSCRIPTEN__)
116 #include <Wasm_Window.hxx>
117 #include <emscripten/emscripten.h>
b69e576a 118#else
119 #include <Aspect_NeutralWindow.hxx>
7fd59977 120#endif
121
7fd59977 122//==============================================================================
123// VIEWER GLOBAL VARIABLES
124//==============================================================================
125
126Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 127Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 128
129Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 130extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 131
58655684 132#if defined(_WIN32)
b69e576a 133typedef WNT_Window ViewerTest_Window;
134#elif defined(HAVE_XLIB)
135typedef Xw_Window ViewerTest_Window;
136static void VProcessEvents(ClientData,int);
137#elif defined(__APPLE__)
138typedef Cocoa_Window ViewerTest_Window;
4fe56619 139extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 140extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
f9ab9f7f 141#elif defined(__EMSCRIPTEN__)
142typedef Wasm_Window ViewerTest_Window;
7fd59977 143#else
b69e576a 144typedef Aspect_NeutralWindow ViewerTest_Window;
7fd59977 145#endif
146
f9ab9f7f 147#if defined(__EMSCRIPTEN__)
148//! Return DOM id of default WebGL canvas from Module.canvas.
149EM_JS(char*, occJSModuleCanvasId, (), {
150 const aCanvasId = Module.canvas.id;
151 const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
152 const aStrPtr = Module._malloc (aNbBytes);
153 stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
154 return aStrPtr;
155});
156
157//! Return DOM id of default WebGL canvas from Module.canvas.
158static TCollection_AsciiString getModuleCanvasId()
159{
160 char* aRawId = occJSModuleCanvasId();
161 TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
162 free (aRawId);
163 return anId;
164}
165#endif
166
b69e576a 167static Handle(ViewerTest_Window)& VT_GetWindow()
168{
169 static Handle(ViewerTest_Window) aWindow;
170 return aWindow;
171}
172
18d715bd 173static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
174{
175 static Handle(Aspect_DisplayConnection) aDisplayConnection;
176 return aDisplayConnection;
177}
178
179static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
180{
181 GetDisplayConnection() = theDisplayConnection;
182}
183
18d715bd 184NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 185static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 186static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
18d715bd 187
f42753ed 188static struct
189{
190 Quantity_Color FlatColor;
191 Quantity_Color GradientColor1;
192 Quantity_Color GradientColor2;
193 Aspect_GradientFillMethod FillMethod;
194} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
195
7fd59977 196//==============================================================================
197// EVENT GLOBAL VARIABLES
198//==============================================================================
199
1beb58d7 200Standard_Boolean TheIsAnimating = Standard_False;
7fd59977 201
293211ae 202namespace
203{
204
205 //! Checks if some set is a subset of other set
206 //! @tparam TheSuperSet the type of the superset
207 //! @tparam TheSubSet the type of the subset
208 //! @param theSuperSet the superset
209 //! @param theSubSet the subset to be checked
210 //! @return true if the superset includes subset, or false otherwise
211 template <typename TheSuperSet, typename TheSubSet>
212 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
213 {
214 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
215 }
216
217 //! A variable set of keys for command-line options.
218 //! It includes a set of mandatory keys and a set of all possible keys.
219 class CommandOptionKeyVariableSet
220 {
221 public:
222 //! Default constructor
223 CommandOptionKeyVariableSet()
224 {
225 }
226
227 //! Constructor
228 //! @param theMandatoryKeySet the set of the mandatory option keys
229 //! @param theAdditionalKeySet the set of additional options that could be omitted
230 CommandOptionKeyVariableSet (
231 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
232 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
233 : myMandatoryKeySet (theMandatoryKeySet)
234 {
235 std::set_union (theMandatoryKeySet.begin(),
236 theMandatoryKeySet.end(),
237 theAdditionalKeySet.begin(),
238 theAdditionalKeySet.end(),
239 std::inserter (myFullKeySet, myFullKeySet.begin()));
240 }
241
242 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
243 //! and be contained in the full key set)
244 //! @param theCheckedKeySet the set of option keys to be checked
245 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
246 {
247 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
248 }
249
250 private:
251 //! A set of mandatory command-line option keys
252 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
253
254 //! A full set of command-line option keys (includes mandatory and additional option keys)
255 ViewerTest_CommandOptionKeySet myFullKeySet;
256 };
257
258 //! Gets some code by its name
259 //! @tparam TheCode the type of a code to be found
260 //! @param theCodeNameMap the map from code names to codes
261 //! @param theCodeName the name of a code to be found
262 //! @param theCode the code to be found
263 //! @return true if a code is found, or false otherwise
264 template <typename TheCode>
265 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
266 TCollection_AsciiString theCodeName,
267 TheCode& theCode)
268 {
269 theCodeName.LowerCase();
270 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
271 theCodeName);
272 if (aCodeIterator == theCodeNameMap.end())
273 {
274 return false;
275 }
276 theCode = aCodeIterator->second;
277 return true;
278 }
279
280 // Defines possible commands related to background changing
281 enum BackgroundCommand
282 {
077a220c 283 BackgroundCommand_Main, //!< The main command that manages other commands through options
284 BackgroundCommand_Image, //!< Sets an image as a background
285 BackgroundCommand_ImageMode, //!< Changes a background image mode
286 BackgroundCommand_Gradient, //!< Sets a gradient as a background
287 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
288 BackgroundCommand_Color, //!< Fills background with a specified color
289 BackgroundCommand_Default //!< Sets the background default color or gradient
293211ae 290 };
291
292 //! Map from background command names to its codes
293 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
294
295 //! Creates a map from background command names to its codes
296 //! @return a map from background command names to its codes
297 static BackgroundCommandNameMap createBackgroundCommandNameMap()
298 {
299 BackgroundCommandNameMap aBackgroundCommandNameMap;
077a220c 300 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
301 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
302 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
303 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
304 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
305 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
306 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
293211ae 307 return aBackgroundCommandNameMap;
308 }
309
310 //! Gets a background command by its name
311 //! @param theBackgroundCommandName the name of the background command
312 //! @param theBackgroundCommand the background command to be found
313 //! @return true if a background command is found, or false otherwise
314 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
315 BackgroundCommand& theBackgroundCommand)
316 {
317 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
318 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
319 }
320
321 //! Map from background image fill method names to its codes
322 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
323
324 //! Creates a map from background image fill method names to its codes
325 //! @return a map from background image fill method names to its codes
326 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
327 {
328 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
329 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
330 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
331 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
332 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
333 return aBackgroundImageFillMethodNameMap;
334 }
335
336 //! Gets a background image fill method by its name
337 //! @param theBackgroundImageFillMethodName the name of the background image fill method
338 //! @param theBackgroundImageFillMethod the background image fill method to be found
339 //! @return true if a background image fill method is found, or false otherwise
340 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
341 Aspect_FillMethod& theBackgroundImageFillMethod)
342 {
343 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
344 createBackgroundImageFillMethodNameMap();
345 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
346 theBackgroundImageFillMethodName,
347 theBackgroundImageFillMethod);
348 }
349
350 //! Map from background gradient fill method names to its codes
351 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
352
353 //! Creates a map from background gradient fill method names to its codes
354 //! @return a map from background gradient fill method names to its codes
355 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
356 {
357 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
358 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
359 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
360 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
361 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
362 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
363 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
364 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
365 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
366 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
367 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
368 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
369 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
370 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
371 return aBackgroundGradientFillMethodNameMap;
372 }
373
374 //! Gets a gradient fill method by its name
375 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
376 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
377 //! @return true if a gradient fill method is found, or false otherwise
378 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
379 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
380 {
381 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
382 createBackgroundGradientFillMethodNameMap();
383 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
384 theBackgroundGradientFillMethodName,
385 theBackgroundGradientFillMethod);
386 }
387
388 //! Changes the background in accordance with passed command line options
389 class BackgroundChanger
390 {
391 public:
392 //! Constructor. Prepares the command parser
393 BackgroundChanger()
394 {
395 prepareCommandParser();
396 }
397
398 //! Processes the command line and changes the background
399 //! @param theDrawInterpretor the interpreter of the Draw Harness application
400 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
401 //! @param theCommandLineArguments the array of command line arguments
402 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
403 const Standard_Integer theNumberOfCommandLineArguments,
404 const char* const* const theCommandLineArguments)
405 {
406 const char* const aBackgroundCommandName = theCommandLineArguments[0];
407 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
408 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
409 {
410 return false;
411 }
412 addCommandDescription (aBackgroundCommand);
413 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
414 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
415 }
416
417 private:
418 //! The type of functions that are able to set gradient background filling
419 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
420 const Quantity_Color& /* theColor2 */,
421 const Aspect_GradientFillMethod /* theGradientMode */);
422
423 //! The type of functions that are able to fill a background with a specific color
424 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
425
426 //! the command parser used to parse command line options and its arguments
427 ViewerTest_CmdParser myCommandParser;
428
429 //! the option key for the command that sets an image as a background
430 ViewerTest_CommandOptionKey myImageOptionKey;
431
432 //! the option key for the command that sets a background image fill type
433 ViewerTest_CommandOptionKey myImageModeOptionKey;
434
435 //! the option key for the command that sets a gradient filling for the background
436 ViewerTest_CommandOptionKey myGradientOptionKey;
437
438 //! the option key for the command that sets a background gradient filling method
439 ViewerTest_CommandOptionKey myGradientModeOptionKey;
440
441 //! the option key for the command that fills background with a specific color
442 ViewerTest_CommandOptionKey myColorOptionKey;
443
444 //! the option key for the command that sets default background gradient or color
445 ViewerTest_CommandOptionKey myDefaultOptionKey;
446
077a220c 447 //! the option key for the command that sets an environment cubemap as a background
448 ViewerTest_CommandOptionKey myCubeMapOptionKey;
449
450 //! the option key for the command that defines order of tiles in one image packed cubemap
451 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
452
453 //! the option key for the command that sets inversion of Z axis for background cubemap
454 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
455
67312b79 456 //! the option key for the command that allows skip IBL map generation
457 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
458
293211ae 459 //! the variable set of options that are allowed for the old scenario (without any option passed)
460 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
461
077a220c 462 //! the variable set of options that are allowed for setting an environment cubemap as background
463 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
464
293211ae 465 //! the variable set of options that are allowed for setting an image as a background
466 CommandOptionKeyVariableSet myImageOptionVariableSet;
467
468 //! the variable set of options that are allowed for setting a background image fill type
469 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
470
471 //! the variable set of options that are allowed for setting a gradient filling for the background
472 CommandOptionKeyVariableSet myGradientOptionVariableSet;
473
474 //! the variable set of options that are allowed for setting a background gradient filling method
475 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
476
477 //! the variable set of options that are allowed for filling a background with a specific color
478 CommandOptionKeyVariableSet myColorOptionVariableSet;
479
480 //! the variable set of options that are allowed for setting a default background gradient
481 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
482
483 //! the variable set of options that are allowed for setting a default background color
484 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
485
486 //! the variable set of options that are allowed for printing help
487 CommandOptionKeyVariableSet myHelpOptionVariableSet;
488
489 //! Adds options to command parser
490 void addOptionsToCommandParser()
491 {
492 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
493 "filename of image used as background");
494 myImageModeOptionKey = myCommandParser.AddOption (
495 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
496 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
497 "sets background gradient starting and ending colors");
498 myGradientModeOptionKey =
499 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
500 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
501 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
502 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
503 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
077a220c 504
505 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
506 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
507 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
508 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
67312b79 509 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
293211ae 510 }
511
512 //! Creates option sets used to determine if a passed option set is valid or not
513 void createOptionSets()
514 {
515 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
516 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
517 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
518
077a220c 519 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
520 aCubeMapOptionSet.insert (myCubeMapOptionKey);
521 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
522 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
67312b79 523 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
077a220c 524 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
525 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
526
293211ae 527 ViewerTest_CommandOptionKeySet anImageOptionSet;
528 anImageOptionSet.insert (myImageOptionKey);
529 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
530 anImageModeOptionSet.insert (myImageModeOptionKey);
531 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
532 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
533
534 ViewerTest_CommandOptionKeySet aGradientOptionSet;
535 aGradientOptionSet.insert (myGradientOptionKey);
536 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
537 aGradientModeOptionSet.insert (myGradientModeOptionKey);
538 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
539 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
540
541 ViewerTest_CommandOptionKeySet aColorOptionSet;
542 aColorOptionSet.insert (myColorOptionKey);
543 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
544
545 aGradientOptionSet.insert (myDefaultOptionKey);
546 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
547 aColorOptionSet.insert (myDefaultOptionKey);
548 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
549
550 ViewerTest_CommandOptionKeySet aHelpOptionSet;
551 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
552 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
553 }
554
555 //! Prepares the command parser. Adds options and creates option sets used to determine
556 //! if a passed option set is valid or not
557 void prepareCommandParser()
558 {
559 addOptionsToCommandParser();
560 createOptionSets();
561 }
562
563 //! Adds a command description to the command parser
564 //! @param theBackgroundCommand the key of the command which description is added to the command parser
565 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
566 {
567 std::string aDescription;
568 bool isMainCommand = false;
569 switch (theBackgroundCommand)
570 {
571 case BackgroundCommand_Main:
572 aDescription = "Command: vbackground (changes background or some background settings)";
573 isMainCommand = true;
574 break;
575 case BackgroundCommand_Image:
576 aDescription = "Command: vsetbg (loads image as a background)";
577 break;
578 case BackgroundCommand_ImageMode:
579 aDescription = "Command: vsetbgmode (changes background fill type)";
580 break;
581 case BackgroundCommand_Gradient:
582 aDescription = "Command: vsetgradientbg (mounts gradient background)";
583 break;
584 case BackgroundCommand_GradientMode:
585 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
586 break;
587 case BackgroundCommand_Color:
588 aDescription = "Command: vsetcolorbg (sets color background)";
589 break;
590 case BackgroundCommand_Default:
591 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
592 break;
593 default:
594 return;
595 }
596 if (!isMainCommand)
597 {
598 aDescription += "\nThis command is obsolete. Use vbackground instead.";
599 }
600 myCommandParser.SetDescription (aDescription);
601 }
602
603 //! Check if a viewer is needed to be initialized
604 //! @param theBackgroundCommand the key of the command that changes the background
605 //! @return true if processing was successful, or false otherwise
606 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
607 {
608 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
609 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
610 const bool aViewerIsNotNeeded =
611 (theBackgroundCommand == BackgroundCommand_Default)
612 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
613 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
614 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
615 return !aViewerIsNotNeeded;
616 }
617
618 //! Check if a viewer is initialized
619 //! @param theBackgroundCommandName the name of the command that changes the background
620 //! @param theDrawInterpretor the interpreter of the Draw Harness application
621 //! @return true if a viewer is initialized, or false otherwise
622 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
623 Draw_Interpretor& theDrawInterpretor)
624 {
625 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
626 if (anAISContext.IsNull())
627 {
628 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
629 return false;
630 }
631 return true;
632 }
633
634 //! Processes command options
635 //! @param theBackgroundCommandName the name of the command that changes the background
636 //! @param theBackgroundCommand the key of the command that changes the background
637 //! @param theDrawInterpretor the interpreter of the Draw Harness application
638 //! @return true if processing was successful, or false otherwise
639 bool processCommandOptions (const char* const theBackgroundCommandName,
640 const BackgroundCommand theBackgroundCommand,
641 Draw_Interpretor& theDrawInterpretor) const
642 {
643 if (myCommandParser.HasNoOption())
644 {
645 return printHelp (theBackgroundCommandName, theDrawInterpretor);
646 }
647 if (checkViewerIsNeeded (theBackgroundCommand)
648 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
649 {
650 return false;
651 }
652 if (myCommandParser.HasOnlyUnnamedOption())
653 {
654 return processUnnamedOption (theBackgroundCommand);
655 }
656 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
657 }
658
659 //! Processes the unnamed option
660 //! @param theBackgroundCommand the key of the command that changes the background
661 //! @return true if processing was successful, or false otherwise
662 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
663 {
664 switch (theBackgroundCommand)
665 {
666 case BackgroundCommand_Main:
667 return false;
668 case BackgroundCommand_Image:
669 return processImageUnnamedOption();
670 case BackgroundCommand_ImageMode:
671 return processImageModeUnnamedOption();
672 case BackgroundCommand_Gradient:
673 return processGradientUnnamedOption();
674 case BackgroundCommand_GradientMode:
675 return processGradientModeUnnamedOption();
676 case BackgroundCommand_Color:
677 return processColorUnnamedOption();
678 case BackgroundCommand_Default:
679 return processDefaultUnnamedOption();
680 default:
681 return false;
682 }
683 }
684
685 //! Processes the image unnamed option
686 //! @return true if processing was successful, or false otherwise
687 bool processImageUnnamedOption() const
688 {
689 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
690 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
691 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
692 {
693 return false;
694 }
695 std::string anImageFileName;
696 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
697 {
698 return false;
699 }
700 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
701 if (aNumberOfImageUnnamedOptionArguments == 2)
702 {
703 std::string anImageModeString;
704 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
705 {
706 return false;
707 }
708 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
709 {
710 return false;
711 }
712 }
713 setImage (anImageFileName.c_str(), anImageMode);
714 return true;
715 }
716
717 //! Processes the image mode unnamed option
718 //! @return true if processing was successful, or false otherwise
719 bool processImageModeUnnamedOption() const
720 {
721 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
722 }
723
724 //! Processes the gradient unnamed option
725 //! @param theSetGradient the function used to set a background gradient filling
726 //! @return true if processing was successful, or false otherwise
727 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
728 {
729 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
730 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
731 if (aNumberOfGradientUnnamedOptionArguments < 2)
732 {
733 return false;
734 }
735
736 Standard_Integer anArgumentIndex = 0;
737 Quantity_Color aColor1;
738 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
739 {
740 return false;
741 }
742 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
743 {
744 return false;
745 }
746
747 Quantity_Color aColor2;
748 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
749 {
750 return false;
751 }
752 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
753 {
754 return false;
755 }
756
757 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
758 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
759 {
760 std::string anGradientModeString;
761
762 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
763 anArgumentIndex,
764 anGradientModeString))
765 {
766 return false;
767 }
768 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
769 {
770 return false;
771 }
772 ++anArgumentIndex;
773 }
774 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
775 {
776 return false;
777 }
778 theSetGradient (aColor1, aColor2, aGradientMode);
779 return true;
780 }
781
782 //! Processes the gradient mode unnamed option
783 //! @return true if processing was successful, or false otherwise
784 bool processGradientModeUnnamedOption() const
785 {
786 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
787 }
788
789 //! Processes the color unnamed option
790 //! @param theSetColor the function used to set a background color
791 //! @return true if processing was successful, or false otherwise
792 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
793 {
794 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
795 }
796
797 //! Processes the default back unnamed option
798 //! @return true if processing was successful, or false otherwise
799 bool processDefaultUnnamedOption() const
800 {
801 if (processGradientUnnamedOption (setDefaultGradient))
802 {
803 return true;
804 }
805 return processColorUnnamedOption (setDefaultColor);
806 }
807
808 //! Processes named options
809 //! @param theBackgroundCommandName the name of the command that changes the background
810 //! @param theBackgroundCommand the key of the command that changes the background
811 //! @param theDrawInterpretor the interpreter of the Draw Harness application
812 //! @return true if processing was successful, or false otherwise
813 bool processNamedOptions (const char* const theBackgroundCommandName,
814 const BackgroundCommand theBackgroundCommand,
815 Draw_Interpretor& theDrawInterpretor) const
816 {
817 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
818 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
077a220c 819 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
820 {
821 return processCubeMapOptionSet();
822 }
293211ae 823 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
824 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
825 {
826 return processImageOptionSet();
827 }
828 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
829 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
830 {
831 return processImageModeOptionSet();
832 }
833 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
834 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
835 {
836 return processGradientOptionSet();
837 }
838 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
839 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
840 {
841 return processGradientModeOptionSet();
842 }
843 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
844 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
845 {
846 return processColorOptionSet();
847 }
848 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
849 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
850 && (theBackgroundCommand == BackgroundCommand_Default)))
851 {
852 return processDefaultGradientOptionSet();
853 }
854 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
855 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
856 {
857 return processDefaultColorOptionSet();
858 }
859 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
860 {
861 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
862 }
863 return false;
864 }
865
077a220c 866 //! Process the cubemap option set in named and unnamed case.
867 //! @return true if processing was successful, or false otherwise
868 bool processCubeMapOptionSet() const
869 {
870 NCollection_Array1<TCollection_AsciiString> aFilePaths;
871
872 if (!processCubeMapOptions (aFilePaths))
873 {
874 return false;
875 }
876
877 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
878
879 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
880 {
881 if (!processCubeMapOrderOptions (anOrder))
882 {
883 return false;
884 }
885 }
886
887 bool aZIsInverted = false;
888 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
889 {
890 if (!processCubeMapInvertedZOptionSet())
891 {
892 return false;
893 }
894 aZIsInverted = true;
895 }
896
67312b79 897 bool aToGenPBREnv = true;
898 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
899 {
900 if (!processCubeMapDoNotGenPBREnvOptionSet())
901 {
902 return false;
903 }
904 aToGenPBREnv = false;
905 }
906
907 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
077a220c 908 return true;
909 }
910
293211ae 911 //! Processes the image option set
912 //! @return true if processing was successful, or false otherwise
913 bool processImageOptionSet() const
914 {
915 std::string anImageFileName;
916 if (!processImageOption (anImageFileName))
917 {
918 return false;
919 }
920 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
921 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
922 {
923 return false;
924 }
925 setImage (anImageFileName.c_str(), anImageMode);
926 return true;
927 }
928
929 //! Processes the image mode option set
930 //! @return true if processing was successful, or false otherwise
931 bool processImageModeOptionSet() const
932 {
933 return processImageModeOptionSet (myImageModeOptionKey);
934 }
935
936 //! Processes the image mode option set
937 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
938 //! @return true if processing was successful, or false otherwise
939 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
940 {
941 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
942 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
943 {
944 return false;
945 }
946 setImageMode (anImageMode);
947 return true;
948 }
949
950 //! Processes the gradient option set
951 //! @param theSetGradient the function used to set a background gradient filling
952 //! @return true if processing was successful, or false otherwise
953 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
954 {
955 Quantity_Color aColor1;
956 Quantity_Color aColor2;
957 if (!processGradientOption (aColor1, aColor2))
958 {
959 return false;
960 }
961 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
962 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
963 {
964 return false;
965 }
966 theSetGradient (aColor1, aColor2, aGradientMode);
967 return true;
968 }
969
970 //! Processes the gradient mode option set
971 //! @return true if processing was successful, or false otherwise
972 bool processGradientModeOptionSet() const
973 {
974 return processGradientModeOptionSet (myGradientModeOptionKey);
975 }
976
977 //! Processes the gradient mode option set
978 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
979 //! @return true if processing was successful, or false otherwise
980 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
981 {
982 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
983 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
984 {
985 return false;
986 }
987 setGradientMode (aGradientMode);
988 return true;
989 }
990
991 //! Processes the color option set
992 //! @param theSetColor the function used to set a background color
993 //! @return true if processing was successful, or false otherwise
994 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
995 {
996 return processColorOptionSet (myColorOptionKey, theSetColor);
997 }
998
999 //! Processes the default color option set
1000 //! @return true if processing was successful, or false otherwise
1001 bool processDefaultGradientOptionSet() const
1002 {
1003 return processGradientOptionSet (setDefaultGradient);
1004 }
1005
1006 //! Processes the default gradient option set
1007 //! @return true if processing was successful, or false otherwise
1008 bool processDefaultColorOptionSet() const
1009 {
1010 return processColorOptionSet (setDefaultColor);
1011 }
1012
1013 //! Processes the color option set
1014 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1015 //! @param theSetColor the function used to set a background color
1016 //! @return true if processing was successful, or false otherwise
1017 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
1018 SetColorFunction* const theSetColor = setColor) const
1019 {
1020 Quantity_Color aColor;
1021 if (!processColorOption (theColorOptionKey, aColor))
1022 {
1023 return false;
1024 }
1025 theSetColor (aColor);
1026 return true;
1027 }
1028
1029 //! Processes the help option set
1030 //! @param theBackgroundCommandName the name of the command that changes the background
1031 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1032 //! @return true if processing was successful, or false otherwise
1033 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1034 {
1035 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1036 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1037 if (aNumberOfHelpOptionArguments != 0)
1038 {
1039 return false;
1040 }
1041 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1042 }
1043
077a220c 1044 //! Processes the cubemap option
1045 //! @param theFilePaths the array of filenames of cubemap sides
1046 //! @return true if processing was successful, or false otherwise
1047 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1048 {
1049 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1050
1051 if (aNumberOfCubeMapOptionArguments != 1
1052 && aNumberOfCubeMapOptionArguments != 6)
1053 {
1054 return false;
1055 }
1056
1057 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1058
1059 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1060 {
1061 std::string aCubeMapFileName;
1062 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1063 {
1064 return false;
1065 }
1066 theFilePaths[i] = aCubeMapFileName.c_str();
1067 }
1068
1069 return true;
1070 }
1071
67312b79 1072 //! Processes the inverted z cubemap option
077a220c 1073 //! @return true if processing was successful, or false otherwise
1074 bool processCubeMapInvertedZOptionSet () const
1075 {
1076 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1077 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1078
1079 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1080 {
1081 return false;
1082 }
1083
1084 return true;
1085 }
1086
67312b79 1087 //! Processes the option allowing to skip IBM maps generation
1088 //! @return true if processing was successful, or false otherwise
1089 bool processCubeMapDoNotGenPBREnvOptionSet() const
1090 {
1091 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1092 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1093
1094 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1095 {
1096 return false;
1097 }
1098
1099 return true;
1100 }
1101
077a220c 1102 //! Processes the tiles order option
1103 //! @param theOrder the array of indexes if cubemap sides in tile grid
1104 //! @return true if processing was successful, or false otherwise
1105 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1106 {
1107 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1108 myCubeMapOrderOptionKey);
1109
1110 if (aNumberOfCubeMapOrderOptionArguments != 6)
1111 {
1112 return false;
1113 }
1114
1115
1116 for (unsigned int i = 0; i < 6; ++i)
1117 {
1118 std::string anOrderItem;
1119 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1120 {
1121 return false;
1122 }
1123
1124 theOrder.Set (Graphic3d_CubeMapSide (i),
1125 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1126 }
1127
1128 return theOrder.IsValid();
1129 }
1130
293211ae 1131 //! Processes the image option
1132 //! @param theImageFileName the filename of the image to be used as a background
1133 //! @return true if processing was successful, or false otherwise
1134 bool processImageOption (std::string& theImageFileName) const
1135 {
1136 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1137 myImageOptionKey);
1138 if (aNumberOfImageOptionArguments != 1)
1139 {
1140 return false;
1141 }
1142 std::string anImageFileName;
1143 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1144 {
1145 return false;
1146 }
1147 theImageFileName = anImageFileName;
1148 return true;
1149 }
1150
1151 //! Processes the image mode option
1152 //! @param theImageMode the fill type used for a background image
1153 //! @return true if processing was successful, or false otherwise
1154 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1155 {
1156 return processImageModeOption (myImageModeOptionKey, theImageMode);
1157 }
1158
1159 //! Processes the image mode option
1160 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1161 //! @param theImageMode the fill type used for a background image
1162 //! @return true if processing was successful, or false otherwise
1163 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1164 Aspect_FillMethod& theImageMode) const
1165 {
1166 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1167 }
1168
1169 //! Processes the gradient option
1170 //! @param theColor1 the gradient starting color
1171 //! @param theColor2 the gradient ending color
1172 //! @return true if processing was successful, or false otherwise
1173 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1174 {
1175 Standard_Integer anArgumentIndex = 0;
1176 Quantity_Color aColor1;
1177 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1178 {
1179 return false;
1180 }
1181 Quantity_Color aColor2;
1182 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1183 {
1184 return false;
1185 }
1186 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1187 myGradientOptionKey);
1188 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1189 {
1190 return false;
1191 }
1192 theColor1 = aColor1;
1193 theColor2 = aColor2;
1194 return true;
1195 }
1196
1197 //! Processes the gradient mode option
1198 //! @param theGradientMode the fill method used for a background gradient filling
1199 //! @return true if processing was successful, or false otherwise
1200 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1201 {
1202 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1203 }
1204
1205 //! Processes the gradient mode option
1206 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1207 //! @param theGradientMode the fill method used for a background gradient filling
1208 //! @return true if processing was successful, or false otherwise
1209 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1210 Aspect_GradientFillMethod& theGradientMode) const
1211 {
1212 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1213 }
1214
1215 //! Processes some mode option
1216 //! @tparam TheMode the type of a mode to be processed
1217 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1218 //! @param theMode a mode to be processed
1219 //! @return true if processing was successful, or false otherwise
1220 template <typename TheMode>
1221 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1222 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1223 TheMode& /* theMode */),
1224 TheMode& theMode) const
1225 {
1226 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1227 theModeOptionKey);
1228 if (aNumberOfModeOptionArguments != 1)
1229 {
1230 return false;
1231 }
1232 std::string aModeString;
1233 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1234 {
1235 return false;
1236 }
1237 TheMode aMode = TheMode();
1238 if (!theGetModeByName (aModeString.c_str(), aMode))
1239 {
1240 return false;
1241 }
1242 theMode = aMode;
1243 return true;
1244 }
1245
1246 //! Processes the color option
1247 //! @param theColor a color used for filling a background
1248 //! @return true if processing was successful, or false otherwise
1249 bool processColorOption (Quantity_Color& theColor) const
1250 {
1251 return processColorOption (myColorOptionKey, theColor);
1252 }
1253
1254 //! Processes the color option
1255 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1256 //! @param theColor a color used for filling a background
1257 //! @return true if processing was successful, or false otherwise
1258 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1259 {
1260 Standard_Integer anArgumentIndex = 0;
1261 Quantity_Color aColor;
1262 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1263 {
1264 return false;
1265 }
1266 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1267 theColorOptionKey);
1268 if (anArgumentIndex != aNumberOfColorOptionArguments)
1269 {
1270 return false;
1271 }
1272 theColor = aColor;
1273 return true;
1274 }
1275
1276 //! Prints helping message
1277 //! @param theBackgroundCommandName the name of the command that changes the background
1278 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1279 //! @return true if printing was successful, or false otherwise
1280 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1281 {
1282 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1283 }
1284
077a220c 1285 //! Sets the cubemap as a background
1286 //! @param theFileNames the array of filenames of packed or multifile cubemap
1287 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1288 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1289 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
67312b79 1290 bool theZIsInverted = false,
1291 bool theToGenPBREnv = true)
077a220c 1292 {
1293 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1294 Handle(Graphic3d_CubeMap) aCubeMap;
1295
1296 if (theFileNames.Size() == 1)
1297 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1298 else
1299 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1300
1301 aCubeMap->SetZInversion (theZIsInverted);
1302
1303 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1304 aCubeMap->GetParams()->SetRepeat(Standard_False);
1305 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1306
67312b79 1307 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
077a220c 1308 }
1309
293211ae 1310 //! Sets the image as a background
1311 //! @param theImageFileName the filename of the image to be used as a background
1312 //! @param theImageMode the fill type used for a background image
1313 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1314 {
1315 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1316 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1317 }
1318
1319 //! Sets the fill type used for a background image
1320 //! @param theImageMode the fill type used for a background image
1321 static void setImageMode (const Aspect_FillMethod theImageMode)
1322 {
1323 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1324 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1325 }
1326
1327 //! Sets the gradient filling for a background
1328 //! @param theColor1 the gradient starting color
1329 //! @param theColor2 the gradient ending color
1330 //! @param theGradientMode the fill method used for a background gradient filling
1331 static void setGradient (const Quantity_Color& theColor1,
1332 const Quantity_Color& theColor2,
1333 const Aspect_GradientFillMethod theGradientMode)
1334 {
1335 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1336 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1337 }
1338
1339 //! Sets the fill method used for a background gradient filling
1340 //! @param theGradientMode the fill method used for a background gradient filling
1341 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1342 {
1343 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1344 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1345 }
1346
1347 //! Sets the color used for filling a background
1348 //! @param theColor the color used for filling a background
1349 static void setColor (const Quantity_Color& theColor)
1350 {
1351 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1352 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1353 aCurrentView->SetBackgroundColor (theColor);
1354 aCurrentView->Update();
1355 }
1356
1357 //! Sets the gradient filling for a background in a default viewer
1358 //! @param theColor1 the gradient starting color
1359 //! @param theColor2 the gradient ending color
1360 //! @param theGradientMode the fill method used for a background gradient filling
1361 static void setDefaultGradient (const Quantity_Color& theColor1,
1362 const Quantity_Color& theColor2,
1363 const Aspect_GradientFillMethod theGradientMode)
1364 {
1365 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1366 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1367 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1368 setDefaultGradient();
1369 }
1370
1371 //! Sets the color used for filling a background in a default viewer
1372 //! @param theColor the color used for filling a background
1373 static void setDefaultColor (const Quantity_Color& theColor)
1374 {
1375 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1376 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1377 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1378 ViewerTest_DefaultBackground.FlatColor = theColor;
1379 setDefaultGradient();
1380 setDefaultColor();
1381 }
1382
1383 //! Sets the gradient filling for a background in a default viewer.
1384 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1385 static void setDefaultGradient()
1386 {
1387 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1388 anInteractiveContextIterator (ViewerTest_myContexts);
1389 anInteractiveContextIterator.More();
1390 anInteractiveContextIterator.Next())
1391 {
1392 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1393 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1394 ViewerTest_DefaultBackground.GradientColor2,
1395 ViewerTest_DefaultBackground.FillMethod);
1396 }
1397 }
1398
1399 //! Sets the color used for filling a background in a default viewer.
1400 //! The color value is taken from ViewerTest_DefaultBackground structure
1401 static void setDefaultColor()
1402 {
1403 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1404 anInteractiveContextIterator (ViewerTest_myContexts);
1405 anInteractiveContextIterator.More();
1406 anInteractiveContextIterator.Next())
1407 {
1408 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1409 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1410 }
1411 }
1412 };
1413
1414} // namespace
b12e1c7b 1415
7fd59977 1416//==============================================================================
1417
57c28b61 1418#ifdef _WIN32
e8e157df 1419static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
7fd59977 1420#endif
1421
7fd59977 1422//==============================================================================
1423//function : WClass
1424//purpose :
1425//==============================================================================
1426
1bd04b5a 1427const Handle(WNT_WClass)& ViewerTest::WClass()
7fd59977 1428{
1bd04b5a 1429 static Handle(WNT_WClass) theWClass;
58655684 1430#if defined(_WIN32)
4fe56619 1431 if (theWClass.IsNull())
1432 {
7c65581d 1433 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1434 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1435 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1436 }
1437#endif
1438 return theWClass;
1439}
1440
18d715bd 1441//==============================================================================
1442//function : CreateName
1443//purpose : Create numerical name for new object in theMap
1444//==============================================================================
1445template <typename ObjectType>
1446TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1447 const TCollection_AsciiString& theDefaultString)
1448{
1449 if (theObjectMap.IsEmpty())
1450 return theDefaultString + TCollection_AsciiString(1);
1451
1452 Standard_Integer aNextKey = 1;
1453 Standard_Boolean isFound = Standard_False;
1454 while (!isFound)
1455 {
1456 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1457 // Look for objects with default names
1458 if (theObjectMap.IsBound1(aStringKey))
1459 {
1460 aNextKey++;
1461 }
1462 else
1463 isFound = Standard_True;
1464 }
1465
1466 return theDefaultString + TCollection_AsciiString(aNextKey);
1467}
1468
1469//==============================================================================
1470//structure : ViewerTest_Names
1471//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1472//==============================================================================
1473struct ViewerTest_Names
1474{
1475private:
1476 TCollection_AsciiString myDriverName;
1477 TCollection_AsciiString myViewerName;
1478 TCollection_AsciiString myViewName;
1479
1480public:
1481
1482 const TCollection_AsciiString& GetDriverName () const
1483 {
1484 return myDriverName;
1485 }
1486 void SetDriverName (const TCollection_AsciiString& theDriverName)
1487 {
1488 myDriverName = theDriverName;
1489 }
1490 const TCollection_AsciiString& GetViewerName () const
1491 {
1492 return myViewerName;
1493 }
1494 void SetViewerName (const TCollection_AsciiString& theViewerName)
1495 {
1496 myViewerName = theViewerName;
1497 }
1498 const TCollection_AsciiString& GetViewName () const
1499 {
1500 return myViewName;
1501 }
1502 void SetViewName (const TCollection_AsciiString& theViewName)
1503 {
1504 myViewName = theViewName;
1505 }
1506
1507 //===========================================================================
1508 //function : Constructor for ViewerTest_Names
1509 //purpose : Get view, viewer, driver names from custom string
1510 //===========================================================================
1511
1512 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1513 {
1514 TCollection_AsciiString aName(theInputString);
1515 if (theInputString.IsEmpty())
1516 {
1517 // Get current configuration
1518 if (ViewerTest_myDrivers.IsEmpty())
1519 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1520 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1521 else
1522 myDriverName = ViewerTest_myDrivers.Find2
1523 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1524
1525 if(ViewerTest_myContexts.IsEmpty())
1526 {
1527 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1528 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1529 }
1530 else
c48e2889 1531 {
18d715bd 1532 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1533 }
18d715bd 1534
c48e2889 1535 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1536 }
1537 else
1538 {
1539 // There is at least view name
1540 Standard_Integer aParserNumber = 0;
1541 for (Standard_Integer i = 0; i < 3; ++i)
1542 {
1543 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1544 if(aParserPos != -1)
1545 {
1546 aParserNumber++;
1547 aName.Split(aParserPos-1);
1548 }
1549 else
1550 break;
1551 }
1552 if (aParserNumber == 0)
1553 {
1554 // Only view name
1555 if (!ViewerTest::GetAISContext().IsNull())
1556 {
1557 myDriverName = ViewerTest_myDrivers.Find2
1558 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1559 myViewerName = ViewerTest_myContexts.Find2
1560 (ViewerTest::GetAISContext());
1561 }
1562 else
1563 {
1564 // There is no opened contexts here, need to create names for viewer and driver
1565 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1566 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1567
1568 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1569 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1570 }
1571 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1572 }
1573 else if (aParserNumber == 1)
1574 {
1575 // Here is viewerName/viewName
1576 if (!ViewerTest::GetAISContext().IsNull())
1577 myDriverName = ViewerTest_myDrivers.Find2
1578 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1579 else
1580 {
1581 // There is no opened contexts here, need to create name for driver
1582 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1583 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1584 }
1585 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1586
1587 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1588 }
1589 else
1590 {
1591 //Here is driverName/viewerName/viewName
1592 myDriverName = TCollection_AsciiString(aName);
1593
1594 TCollection_AsciiString aViewerName(theInputString);
1595 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1596 myViewerName = TCollection_AsciiString(aViewerName);
1597
1598 myViewName = TCollection_AsciiString(theInputString);
1599 }
1600 }
1601 }
1602};
1603
1604//==============================================================================
1605//function : FindContextByView
1606//purpose : Find AIS_InteractiveContext by View
1607//==============================================================================
1608
1609Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1610{
1611 Handle(AIS_InteractiveContext) anAISContext;
1612
1613 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1614 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1615 {
1616 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1617 return anIter.Key2();
1618 }
1619 return anAISContext;
1620}
1621
18d715bd 1622//==============================================================================
1623//function : IsWindowOverlapped
1624//purpose : Check if theWindow overlapp another view
1625//==============================================================================
1626
1627Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1628 const Standard_Integer thePxTop,
1629 const Standard_Integer thePxRight,
1630 const Standard_Integer thePxBottom,
1631 TCollection_AsciiString& theViewId)
1632{
1633 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1634 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1635 {
1636 Standard_Integer aTop = 0,
1637 aLeft = 0,
1638 aRight = 0,
1639 aBottom = 0;
1640 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1641 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1642 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1643 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1644 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1645 {
1646 theViewId = anIter.Key1();
1647 return Standard_True;
1648 }
1649 }
1650 return Standard_False;
1651}
1652
1653// Workaround: to create and delete non-orthographic views outside ViewerTest
1654void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1655{
1656 ViewerTest_myViews.UnBind1 (theName);
1657}
1658
1659void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1660 const Handle(V3d_View)& theView)
1661{
1662 ViewerTest_myViews.Bind (theName, theView);
1663}
1664
1665TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1666{
1667 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1668}
8693dfd0 1669
7fd59977 1670//==============================================================================
1671//function : ViewerInit
1672//purpose : Create the window viewer and initialize all the global variable
1673//==============================================================================
1674
18d715bd 1675TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1676 const Standard_Integer thePxTop,
1677 const Standard_Integer thePxWidth,
1678 const Standard_Integer thePxHeight,
9e04ccdc 1679 const TCollection_AsciiString& theViewName,
1680 const TCollection_AsciiString& theDisplayName,
72ed0644 1681 const Handle(V3d_View)& theViewToClone,
1682 const Standard_Boolean theIsVirtual)
7fd59977 1683{
8c3c9904 1684 // Default position and dimension of the viewer window.
4fe56619 1685 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1686 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1687 // The position corresponds to the window's client area, thus some
8c3c9904 1688 // gap is added for window frame to be visible.
f9ab9f7f 1689 Standard_Integer aPxLeft = 20, aPxTop = 40;
1690 Standard_Integer aPxWidth = 409, aPxHeight = 409;
1691 Standard_Boolean isDefViewSize = Standard_True;
18d715bd 1692 Standard_Boolean toCreateViewer = Standard_False;
72ed0644 1693 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
9e04ccdc 1694 if (!theViewToClone.IsNull())
1695 {
1696 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
f9ab9f7f 1697 isDefViewSize = Standard_False;
1698 #if !defined(__EMSCRIPTEN__)
1699 (void )isDefViewSize;
1700 #endif
9e04ccdc 1701 }
18d715bd 1702
b8db9379 1703 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1704 if (aFactory.IsNull())
1705 {
1706 Draw::GetInterpretor().Eval ("pload OPENGL");
1707 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1708 if (aFactory.IsNull())
1709 {
b8ef513c 1710 Draw::GetInterpretor().Eval ("pload GLES");
1711 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1712 if (aFactory.IsNull())
1713 {
1714 throw Standard_ProgramError("Error: no graphic driver factory found");
1715 }
b8db9379 1716 }
1717 }
1718
1719 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
18d715bd 1720 ViewerTest_Names aViewNames(theViewName);
f9ab9f7f 1721 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1722 {
18d715bd 1723 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
f9ab9f7f 1724 }
18d715bd 1725
1726 if (thePxLeft != 0)
f9ab9f7f 1727 {
18d715bd 1728 aPxLeft = thePxLeft;
f9ab9f7f 1729 }
18d715bd 1730 if (thePxTop != 0)
f9ab9f7f 1731 {
18d715bd 1732 aPxTop = thePxTop;
f9ab9f7f 1733 }
18d715bd 1734 if (thePxWidth != 0)
f9ab9f7f 1735 {
1736 isDefViewSize = Standard_False;
18d715bd 1737 aPxWidth = thePxWidth;
f9ab9f7f 1738 }
18d715bd 1739 if (thePxHeight != 0)
f9ab9f7f 1740 {
1741 isDefViewSize = Standard_False;
7fd59977 1742 aPxHeight = thePxHeight;
f9ab9f7f 1743 }
4269bd1b 1744
18d715bd 1745 // Get graphic driver (create it or get from another view)
8693dfd0 1746 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1747 if (isNewDriver)
18d715bd 1748 {
1749 // Get connection string
b69e576a 1750 #if defined(HAVE_XLIB)
8693dfd0 1751 if (!theDisplayName.IsEmpty())
1752 {
1753 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1754 }
18d715bd 1755 else
8693dfd0 1756 {
b69e576a 1757 Aspect_XDisplay* aDispX = NULL;
8693dfd0 1758 // create dedicated display connection instead of reusing Tk connection
b69e576a 1759 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
8693dfd0 1760 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1761 Tcl_Interp* aTclInterp = aCommands.Interp();
1762 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1763 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1764 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1765 }
18d715bd 1766 #else
498ce76b 1767 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1768 SetDisplayConnection (new Aspect_DisplayConnection ());
1769 #endif
14cb22a1 1770
b8db9379 1771 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
72ed0644 1772 if (isVirtual)
14cb22a1 1773 {
1774 // don't waste the time waiting for VSync when window is not displayed on the screen
b8db9379 1775 aGraphicDriver->SetVerticalSync (false);
14cb22a1 1776 }
14cb22a1 1777
18d715bd 1778 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1779 toCreateViewer = Standard_True;
1780 }
1781 else
1782 {
b8db9379 1783 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
7fd59977 1784 }
1785
18d715bd 1786 //Dispose the window if input parameters are default
1787 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1788 {
18d715bd 1789 Standard_Integer aTop = 0,
1790 aLeft = 0,
1791 aRight = 0,
1792 aBottom = 0,
1793 aScreenWidth = 0,
1794 aScreenHeight = 0;
1795
1796 // Get screen resolution
b69e576a 1797#if defined(_WIN32)
18d715bd 1798 RECT aWindowSize;
1799 GetClientRect(GetDesktopWindow(), &aWindowSize);
1800 aScreenHeight = aWindowSize.bottom;
1801 aScreenWidth = aWindowSize.right;
b69e576a 1802#elif defined(HAVE_XLIB)
1803 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
1804 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
1805 aScreenWidth = WidthOfScreen(aScreen);
1806 aScreenHeight = HeightOfScreen(aScreen);
1807#elif defined(__APPLE__)
18d715bd 1808 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1809#else
b69e576a 1810 // not implemented
18d715bd 1811#endif
1812
1813 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1814
1815 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1816 {
18d715bd 1817 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1818
1819 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1820 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1821 {
1822 if (aBottom + aPxHeight + 40 > aScreenHeight)
1823 {
1824 aPxLeft = 20;
1825 aPxTop = 40;
1826 break;
1827 }
1828 aPxLeft = 20;
1829 aPxTop = aBottom + 40;
1830 }
1831 else
1832 aPxLeft = aRight + 20;
dc3fe572 1833 }
18d715bd 1834 }
1835
1836 // Get viewer name
1837 TCollection_AsciiString aTitle("3D View - ");
1838 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1839
1840 // Change name of current active window
49582f9d 1841 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
18d715bd 1842 {
49582f9d 1843 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
18d715bd 1844 }
1845
1846 // Create viewer
eb4320f2 1847 Handle(V3d_Viewer) a3DViewer;
18d715bd 1848 // If it's the single view, we first look for empty context
1849 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1850 {
1851 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1852 anIter(ViewerTest_myContexts);
1853 if (anIter.More())
1854 ViewerTest::SetAISContext (anIter.Value());
1855 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1856 }
1857 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1858 {
1859 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1860 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1861 }
eb4320f2 1862 else if (a3DViewer.IsNull())
18d715bd 1863 {
1864 toCreateViewer = Standard_True;
6a24c6de 1865 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1866 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1867 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1868 ViewerTest_DefaultBackground.GradientColor2,
1869 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1870 }
1871
1872 // AIS context setup
1873 if (ViewerTest::GetAISContext().IsNull() ||
1874 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1875 {
e79a94b9 1876 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1877 ViewerTest::SetAISContext (aContext);
1878 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1879 }
1880 else
e79a94b9 1881 {
18d715bd 1882 ViewerTest::ResetEventManager();
e79a94b9 1883 }
18d715bd 1884
1885 // Create window
e79a94b9 1886#if defined(_WIN32)
1bd04b5a 1887 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
72ed0644 1888 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1889 aPxLeft, aPxTop,
1890 aPxWidth, aPxHeight,
1891 Quantity_NOC_BLACK);
d6fbb2ab 1892 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
b69e576a 1893#elif defined(HAVE_XLIB)
1894 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1895 aTitle.ToCString(),
1896 aPxLeft, aPxTop,
1897 aPxWidth, aPxHeight);
1898#elif defined(__APPLE__)
e79a94b9 1899 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1900 aPxLeft, aPxTop,
1901 aPxWidth, aPxHeight);
1902 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
f9ab9f7f 1903#elif defined(__EMSCRIPTEN__)
1904 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
1905 // the code should be revised for handling multiple canvas elements (which is technically also possible)
1906 TCollection_AsciiString aCanvasId = getModuleCanvasId();
1907 if (!aCanvasId.IsEmpty())
1908 {
1909 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
1910 }
1911
1912 VT_GetWindow() = new Wasm_Window (aCanvasId);
1913 Graphic3d_Vec2i aRealSize;
1914 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
1915 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
1916 {
1917 // Wasm_Window wraps an existing HTML element without creating a new one.
1918 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
1919 // but resize canvas if vinit has been called with explicitly specified dimensions.
1920 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxWidth, aPxHeight));
1921 }
7fd59977 1922#else
b69e576a 1923 // not implemented
1924 VT_GetWindow() = new Aspect_NeutralWindow();
1925 VT_GetWindow()->SetSize (aPxWidth, aPxHeight);
7fd59977 1926#endif
72ed0644 1927 VT_GetWindow()->SetVirtual (isVirtual);
7fd59977 1928
d09dda09 1929 // View setup
9e04ccdc 1930 Handle(V3d_View) aView;
1931 if (!theViewToClone.IsNull())
1932 {
2e93433e 1933 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1934 }
1935 else
1936 {
2e93433e 1937 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1938 }
1939
d09dda09 1940 aView->SetWindow (VT_GetWindow());
c3282ec1 1941 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1942
18d715bd 1943 ViewerTest::CurrentView(aView);
1944 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1945
18d715bd 1946 // Setup for X11 or NT
f9ab9f7f 1947 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1948 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
7fd59977 1949
18d715bd 1950 // Set parameters for V3d_View and V3d_Viewer
1951 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1952 aV3dView->SetComputedMode(Standard_False);
7fd59977 1953
18d715bd 1954 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1955 if (toCreateViewer)
1956 {
7fd59977 1957 a3DViewer->SetDefaultLights();
1958 a3DViewer->SetLightOn();
18d715bd 1959 }
7fd59977 1960
b69e576a 1961#if defined(HAVE_XLIB)
8693dfd0 1962 if (isNewDriver)
1963 {
b69e576a 1964 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
8693dfd0 1965 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1966 }
1967#endif
7fd59977 1968
7fd59977 1969 VT_GetWindow()->Map();
4269bd1b 1970
18d715bd 1971 // Set the handle of created view in the event manager
1972 ViewerTest::ResetEventManager();
1973
4fe56619 1974 ViewerTest::CurrentView()->Redraw();
18d715bd 1975
1976 aView.Nullify();
1977 a3DViewer.Nullify();
18d715bd 1978
1979 return aViewNames.GetViewName();
1980}
1981
4269bd1b 1982//==============================================================================
1983//function : RedrawAllViews
1984//purpose : Redraw all created views
1985//==============================================================================
1986void ViewerTest::RedrawAllViews()
1987{
1988 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1989 for (; aViewIt.More(); aViewIt.Next())
1990 {
1991 const Handle(V3d_View)& aView = aViewIt.Key2();
1992 aView->Redraw();
1993 }
1994}
1995
b8db9379 1996//==============================================================================
1997//function : VDriver
1998//purpose :
1999//==============================================================================
2000static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2001{
2002 if (theArgsNb == 1)
2003 {
2004 theDi << "Registered: ";
2005 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2006 aFactoryIter.More(); aFactoryIter.Next())
2007 {
2008 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2009 theDi << aFactory->Name() << " ";
2010 }
2011
2012 theDi << "\n";
2013 theDi << "Default: ";
2014 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2015 {
2016 theDi << aFactory->Name();
2017 }
2018 else
2019 {
2020 theDi << "NONE";
2021 }
2022 return 0;
2023 }
2024
2025 TCollection_AsciiString aNewActive;
2026 bool toLoad = false;
2027 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
2028 {
2029 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2030 anArgCase.LowerCase();
2031 if (anArgCase == "-list")
2032 {
2033 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2034 aFactoryIter.More(); aFactoryIter.Next())
2035 {
2036 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2037 theDi << aFactory->Name() << " ";
2038 }
2039 }
2040 else if ((anArgCase == "-default"
2041 || anArgCase == "-load")
2042 && aNewActive.IsEmpty())
2043 {
2044 toLoad = (anArgCase == "-load");
2045 if (anArgIter + 1 < theArgsNb)
2046 {
2047 aNewActive = theArgVec[++anArgIter];
2048 }
2049 else if (toLoad)
2050 {
2051 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
2052 return 1;
2053 }
2054 else
2055 {
2056 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2057 {
2058 theDi << aFactory->Name();
2059 }
2060 else
2061 {
2062 theDi << "NONE";
2063 }
2064 }
2065 }
2066 else if (aNewActive.IsEmpty())
2067 {
2068 aNewActive = theArgVec[anArgIter];
2069 }
2070 else
2071 {
2072 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
2073 return 1;
2074 }
2075 }
2076
2077 if (!aNewActive.IsEmpty())
2078 {
2079 const TCollection_AsciiString aNameCopy = aNewActive;
2080 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
2081 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
2082 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
2083 {
2084 aNewActive = "tkopengl";
2085 }
b8ef513c 2086 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
2087 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
2088 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
2089 {
2090 aNewActive = "tkopengles";
2091 }
b8db9379 2092 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
2093 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
2094 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
2095 {
2096 aNewActive = "tkd3dhost";
2097 }
2098
2099 if (toLoad)
2100 {
2101 if (aNewActive == "tkopengl")
2102 {
2103 Draw::GetInterpretor().Eval ("pload OPENGL");
2104 }
b8ef513c 2105 else if (aNewActive == "tkopengles")
2106 {
2107 Draw::GetInterpretor().Eval ("pload GLES");
2108 }
b8db9379 2109 else if (aNewActive == "tkd3dhost")
2110 {
2111 Draw::GetInterpretor().Eval ("pload D3DHOST");
2112 }
2113 else
2114 {
2115 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
2116 return 1;
2117 }
2118 }
2119
2120 bool isFound = false;
2121 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2122 aFactoryIter.More(); aFactoryIter.Next())
2123 {
2124 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
2125 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
2126 {
2127 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
2128 isFound = true;
2129 break;
2130 }
2131 }
2132
2133 if (!isFound)
2134 {
2135 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
2136 return 1;
2137 }
2138 }
2139
2140 return 0;
2141}
2142
7fd59977 2143//==============================================================================
2144//function : Vinit
2145//purpose : Create the window viewer and initialize all the global variable
87b68a0f 2146// Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 2147//==============================================================================
18d715bd 2148static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 2149{
e79a94b9 2150 TCollection_AsciiString aViewName, aDisplayName;
2151 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
72ed0644 2152 Standard_Boolean isVirtual = false;
9e04ccdc 2153 Handle(V3d_View) aCopyFrom;
e79a94b9 2154 TCollection_AsciiString aName, aValue;
2e93433e 2155 int is2dMode = -1;
e79a94b9 2156 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 2157 {
e79a94b9 2158 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2159 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 2160 anArgCase.LowerCase();
2161 if (anArgIt + 1 < theArgsNb
2162 && anArgCase == "-name")
2163 {
2164 aViewName = theArgVec[++anArgIt];
2165 }
2166 else if (anArgIt + 1 < theArgsNb
2167 && (anArgCase == "-left"
2168 || anArgCase == "-l"))
2169 {
2170 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2171 }
2172 else if (anArgIt + 1 < theArgsNb
2173 && (anArgCase == "-top"
2174 || anArgCase == "-t"))
2175 {
2176 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2177 }
2178 else if (anArgIt + 1 < theArgsNb
2179 && (anArgCase == "-width"
2180 || anArgCase == "-w"))
2181 {
2182 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2183 }
2184 else if (anArgIt + 1 < theArgsNb
2185 && (anArgCase == "-height"
2186 || anArgCase == "-h"))
18d715bd 2187 {
fd3f6bd0 2188 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2189 }
72ed0644 2190 else if (anArgCase == "-virtual"
2191 || anArgCase == "-offscreen")
2192 {
2193 isVirtual = true;
2194 if (anArgIt + 1 < theArgsNb
2195 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
2196 {
2197 ++anArgIt;
2198 }
2199 }
fd3f6bd0 2200 else if (anArgCase == "-exitonclose")
2201 {
49582f9d 2202 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 2203 if (anArgIt + 1 < theArgsNb
dae2a922 2204 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 2205 {
2206 ++anArgIt;
2207 }
2208 }
2209 else if (anArgCase == "-closeonescape"
2210 || anArgCase == "-closeonesc")
2211 {
49582f9d 2212 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 2213 if (anArgIt + 1 < theArgsNb
dae2a922 2214 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 2215 {
2216 ++anArgIt;
2217 }
2218 }
2e93433e 2219 else if (anArgCase == "-2d_mode"
2220 || anArgCase == "-2dmode"
2221 || anArgCase == "-2d")
2222 {
2223 bool toEnable = true;
2224 if (anArgIt + 1 < theArgsNb
dae2a922 2225 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2e93433e 2226 {
2227 ++anArgIt;
2228 }
2229 is2dMode = toEnable ? 1 : 0;
2230 }
fd3f6bd0 2231 else if (anArgIt + 1 < theArgsNb
2232 && (anArgCase == "-disp"
2233 || anArgCase == "-display"))
2234 {
2235 aDisplayName = theArgVec[++anArgIt];
2236 }
9e04ccdc 2237 else if (!ViewerTest::CurrentView().IsNull()
2238 && aCopyFrom.IsNull()
2239 && (anArgCase == "-copy"
2240 || anArgCase == "-clone"
2241 || anArgCase == "-cloneactive"
2242 || anArgCase == "-cloneactiveview"))
2243 {
2244 aCopyFrom = ViewerTest::CurrentView();
2245 }
fd3f6bd0 2246 // old syntax
2247 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2248 {
2249 aName.LowerCase();
2250 if (aName == "name")
18d715bd 2251 {
2252 aViewName = aValue;
2253 }
fd3f6bd0 2254 else if (aName == "l"
2255 || aName == "left")
e79a94b9 2256 {
18d715bd 2257 aPxLeft = aValue.IntegerValue();
e79a94b9 2258 }
fd3f6bd0 2259 else if (aName == "t"
2260 || aName == "top")
e79a94b9 2261 {
18d715bd 2262 aPxTop = aValue.IntegerValue();
e79a94b9 2263 }
fd3f6bd0 2264 else if (aName == "disp"
2265 || aName == "display")
e79a94b9 2266 {
18d715bd 2267 aDisplayName = aValue;
e79a94b9 2268 }
fd3f6bd0 2269 else if (aName == "w"
2270 || aName == "width")
e79a94b9 2271 {
18d715bd 2272 aPxWidth = aValue.IntegerValue();
e79a94b9 2273 }
fd3f6bd0 2274 else if (aName == "h"
2275 || aName == "height")
e79a94b9 2276 {
18d715bd 2277 aPxHeight = aValue.IntegerValue();
e79a94b9 2278 }
18d715bd 2279 else
2280 {
23fe70ec 2281 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2282 return 1;
18d715bd 2283 }
2284 }
e79a94b9 2285 else if (aViewName.IsEmpty())
2286 {
2287 aViewName = anArg;
2288 }
2289 else
2290 {
23fe70ec 2291 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2292 return 1;
e79a94b9 2293 }
18d715bd 2294 }
2295
b69e576a 2296#if !defined(HAVE_XLIB)
fd3f6bd0 2297 if (!aDisplayName.IsEmpty())
2298 {
2299 aDisplayName.Clear();
23fe70ec 2300 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
fd3f6bd0 2301 }
2302#endif
2303
18d715bd 2304 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2305 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2306 {
e79a94b9 2307 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2308 theDi.Eval (aCommand.ToCString());
2e93433e 2309 if (is2dMode != -1)
2310 {
2311 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2312 }
18d715bd 2313 return 0;
2314 }
2315
2316 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
72ed0644 2317 aViewName, aDisplayName, aCopyFrom, isVirtual);
2e93433e 2318 if (is2dMode != -1)
2319 {
2320 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2321 }
e79a94b9 2322 theDi << aViewId;
7fd59977 2323 return 0;
2324}
2325
1eeef710 2326//! Parse HLR algo type.
2327static Standard_Boolean parseHlrAlgoType (const char* theName,
2328 Prs3d_TypeOfHLR& theType)
2329{
2330 TCollection_AsciiString aName (theName);
2331 aName.LowerCase();
2332 if (aName == "polyalgo")
2333 {
2334 theType = Prs3d_TOH_PolyAlgo;
2335 }
2336 else if (aName == "algo")
2337 {
2338 theType = Prs3d_TOH_Algo;
2339 }
2340 else
2341 {
2342 return Standard_False;
2343 }
2344 return Standard_True;
2345}
2346
0a768f56 2347//==============================================================================
2348//function : VHLR
2349//purpose : hidden lines removal algorithm
2350//==============================================================================
2351
2352static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2353{
1eeef710 2354 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2355 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2356 if (aView.IsNull())
0a768f56 2357 {
23fe70ec 2358 Message::SendFail ("Error: no active viewer");
0a768f56 2359 return 1;
2360 }
2361
1eeef710 2362 Standard_Boolean hasHlrOnArg = Standard_False;
2363 Standard_Boolean hasShowHiddenArg = Standard_False;
2364 Standard_Boolean isHLROn = Standard_False;
2365 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2366 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2367 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2368 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2369 {
1eeef710 2370 TCollection_AsciiString anArg (argv[anArgIter]);
2371 anArg.LowerCase();
2372 if (anUpdateTool.parseRedrawMode (anArg))
2373 {
2374 continue;
2375 }
2376 else if (anArg == "-showhidden"
2377 && anArgIter + 1 < argc
dae2a922 2378 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1eeef710 2379 {
2380 ++anArgIter;
2381 hasShowHiddenArg = Standard_True;
2382 continue;
2383 }
2384 else if ((anArg == "-type"
2385 || anArg == "-algo"
2386 || anArg == "-algotype")
2387 && anArgIter + 1 < argc
2388 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2389 {
2390 ++anArgIter;
2391 continue;
2392 }
2393 else if (!hasHlrOnArg
dae2a922 2394 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1eeef710 2395 {
2396 hasHlrOnArg = Standard_True;
2397 continue;
2398 }
2399 // old syntax
2400 else if (!hasShowHiddenArg
dae2a922 2401 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1eeef710 2402 {
2403 hasShowHiddenArg = Standard_True;
2404 continue;
2405 }
2406 else
2407 {
23fe70ec 2408 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1eeef710 2409 return 1;
2410 }
0a768f56 2411 }
1eeef710 2412 if (!hasHlrOnArg)
0a768f56 2413 {
1eeef710 2414 di << "HLR: " << aView->ComputedMode() << "\n";
2415 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2416 di << "HlrAlgo: ";
2417 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2418 {
2419 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2420 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2421 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2422 }
2423 anUpdateTool.Invalidate();
2424 return 0;
0a768f56 2425 }
2426
1eeef710 2427 Standard_Boolean toRecompute = Standard_False;
2428 if (aTypeOfHLR != Prs3d_TOH_NotSet
2429 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2430 {
1eeef710 2431 toRecompute = Standard_True;
2432 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2433 }
2434 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2435 {
2436 toRecompute = Standard_True;
2437 if (toShowHidden)
e9224045 2438 {
1eeef710 2439 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2440 }
2441 else
2442 {
1eeef710 2443 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2444 }
1eeef710 2445 }
e9224045 2446
1eeef710 2447 // redisplay shapes
2448 if (aView->ComputedMode() && isHLROn && toRecompute)
2449 {
2450 AIS_ListOfInteractive aListOfShapes;
2451 aCtx->DisplayedObjects (aListOfShapes);
2452 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2453 {
1eeef710 2454 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2455 {
1eeef710 2456 aCtx->Redisplay (aShape, Standard_False);
e9224045 2457 }
2458 }
2459 }
0a768f56 2460
1eeef710 2461 aView->SetComputedMode (isHLROn);
0a768f56 2462 return 0;
2463}
2464
2465//==============================================================================
2466//function : VHLRType
2467//purpose : change type of using HLR algorithm
2468//==============================================================================
2469
1eeef710 2470static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2471{
1eeef710 2472 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2473 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2474 if (aView.IsNull())
0a768f56 2475 {
23fe70ec 2476 Message::SendFail ("Error: no active viewer");
0a768f56 2477 return 1;
2478 }
2479
1eeef710 2480 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2481 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2482 AIS_ListOfInteractive aListOfShapes;
2483 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2484 {
1eeef710 2485 TCollection_AsciiString anArg (argv[anArgIter]);
2486 anArg.LowerCase();
2487 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2488 {
1eeef710 2489 continue;
0a768f56 2490 }
1eeef710 2491 else if ((anArg == "-type"
2492 || anArg == "-algo"
2493 || anArg == "-algotype")
2494 && anArgIter + 1 < argc
2495 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2496 {
2497 ++anArgIter;
2498 continue;
2499 }
2500 // old syntax
2501 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2502 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2503 {
2504 continue;
2505 }
2506 else
0a768f56 2507 {
2508 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2509 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2510 if (!aMap.IsBound2 (aName))
2511 {
23fe70ec 2512 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1eeef710 2513 return 1;
0a768f56 2514 }
1eeef710 2515
2516 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2517 if (aShape.IsNull())
2518 {
23fe70ec 2519 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1eeef710 2520 return 1;
2521 }
2522 aListOfShapes.Append (aShape);
2523 continue;
0a768f56 2524 }
1eeef710 2525 }
2526 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2527 {
23fe70ec 2528 Message::SendFail ("Syntax error: wrong number of arguments");
1eeef710 2529 return 1;
2530 }
2531
2532 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2533 if (isGlobal)
2534 {
2535 aCtx->DisplayedObjects (aListOfShapes);
2536 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2537 }
2538
1eeef710 2539 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2540 {
2541 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2542 if (aShape.IsNull())
2543 {
2544 continue;
2545 }
2546
2547 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2548 && aView->ComputedMode();
2549 if (!isGlobal
2550 || aShape->TypeOfHLR() != aTypeOfHLR)
2551 {
2552 aShape->SetTypeOfHLR (aTypeOfHLR);
2553 }
2554 if (toUpdateShape)
2555 {
2556 aCtx->Redisplay (aShape, Standard_False);
2557 }
2558 }
0a768f56 2559 return 0;
2560}
2561
18d715bd 2562//==============================================================================
2563//function : FindViewIdByWindowHandle
2564//purpose : Find theView Id in the map of views by window handle
2565//==============================================================================
b69e576a 2566#if defined(_WIN32) || defined(HAVE_XLIB)
2567static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
18d715bd 2568{
2569 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2570 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2571 {
49582f9d 2572 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
18d715bd 2573 if (aWindowHandle == theWindowHandle)
2574 return anIter.Key1();
2575 }
2576 return TCollection_AsciiString("");
2577}
2578#endif
2579
e084dbbc 2580//! Make the view active
2581void ActivateView (const TCollection_AsciiString& theViewName,
2582 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2583{
2584 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2585 if (aView.IsNull())
18d715bd 2586 {
e084dbbc 2587 return;
2588 }
18d715bd 2589
e084dbbc 2590 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2591 if (!anAISContext.IsNull())
2592 {
49582f9d 2593 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
e084dbbc 2594 {
49582f9d 2595 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
e084dbbc 2596 }
2597
2598 ViewerTest::CurrentView (aView);
2599 ViewerTest::SetAISContext (anAISContext);
49582f9d 2600 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
f9ab9f7f 2601 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(ViewerTest::CurrentView()->Window());
e084dbbc 2602 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2603 if (theToUpdate)
2604 {
18d715bd 2605 ViewerTest::CurrentView()->Redraw();
2606 }
2607 }
2608}
2609
0e93d9e5 2610//==============================================================================
2611//function : RemoveView
2612//purpose :
2613//==============================================================================
2614void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2615 const Standard_Boolean theToRemoveContext)
2616{
2617 if (!ViewerTest_myViews.IsBound2 (theView))
2618 {
2619 return;
2620 }
2621
2622 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2623 RemoveView (aViewName, theToRemoveContext);
2624}
2625
18d715bd 2626//==============================================================================
2627//function : RemoveView
4551e1be 2628//purpose : Close and remove view from display, clear maps if necessary
18d715bd 2629//==============================================================================
2630void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2631{
2632 if (!ViewerTest_myViews.IsBound1(theViewName))
2633 {
23fe70ec 2634 Message::SendFail() << "Wrong view name";
18d715bd 2635 return;
2636 }
2637
2638 // Activate another view if it's active now
2639 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2640 {
2641 if (ViewerTest_myViews.Extent() > 1)
2642 {
2643 TCollection_AsciiString aNewViewName;
c48e2889 2644 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2645 anIter.More(); anIter.Next())
2646 {
18d715bd 2647 if (anIter.Key1() != theViewName)
2648 {
2649 aNewViewName = anIter.Key1();
2650 break;
2651 }
c48e2889 2652 }
2653 ActivateView (aNewViewName);
18d715bd 2654 }
2655 else
2656 {
e084dbbc 2657 VT_GetWindow().Nullify();
2658 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2659 if (isContextRemoved)
2660 {
2661 Handle(AIS_InteractiveContext) anEmptyContext;
2662 ViewerTest::SetAISContext(anEmptyContext);
2663 }
2664 }
2665 }
2666
2667 // Delete view
2668 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2669 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2670 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2671 aRedrawer.Stop (aView->Window());
18d715bd 2672
2673 // Remove view resources
18d715bd 2674 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2675 aView->Window()->Unmap();
18d715bd 2676 aView->Remove();
2677
b69e576a 2678#if defined(HAVE_XLIB)
2679 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
18d715bd 2680#endif
2681
2682 // Keep context opened only if the closed view is last to avoid
2683 // unused empty contexts
2684 if (!aCurrentContext.IsNull())
2685 {
2686 // Check if there are more difined views in the viewer
f7fc0c03 2687 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2688 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
18d715bd 2689 {
2690 // Remove driver if there is no viewers that use it
2691 Standard_Boolean isRemoveDriver = Standard_True;
2692 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2693 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2694 {
2695 if (aCurrentContext != anIter.Key2() &&
2696 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2697 {
2698 isRemoveDriver = Standard_False;
2699 break;
2700 }
2701 }
2ec85268 2702
2703 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2704 if(isRemoveDriver)
2705 {
2706 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
b69e576a 2707 #if defined(HAVE_XLIB)
2708 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
18d715bd 2709 #endif
2710 }
2711
2712 ViewerTest_myContexts.UnBind2(aCurrentContext);
2713 }
2714 }
23fe70ec 2715 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
49582f9d 2716 if (ViewerTest_EventManager::ToExitOnCloseView())
fd3f6bd0 2717 {
2718 Draw_Interprete ("exit");
2719 }
18d715bd 2720}
2721
2722//==============================================================================
2723//function : VClose
2724//purpose : Remove the view defined by its name
2725//==============================================================================
2726
d0cc1cb7 2727static int VClose (Draw_Interpretor& /*theDi*/,
2728 Standard_Integer theArgsNb,
2729 const char** theArgVec)
18d715bd 2730{
18d715bd 2731 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2732 if (theArgsNb > 1)
18d715bd 2733 {
d0cc1cb7 2734 TCollection_AsciiString anArg (theArgVec[1]);
2735 anArg.UpperCase();
2736 if (anArg.IsEqual ("ALL")
2737 || anArg.IsEqual ("*"))
2738 {
2739 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2740 anIter.More(); anIter.Next())
2741 {
2742 aViewList.Append (anIter.Key1());
2743 }
2744 if (aViewList.IsEmpty())
2745 {
2746 std::cout << "No view to close\n";
2747 return 0;
2748 }
2749 }
2750 else
18d715bd 2751 {
d0cc1cb7 2752 ViewerTest_Names aViewName (theArgVec[1]);
2753 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2754 {
23fe70ec 2755 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
d0cc1cb7 2756 return 1;
2757 }
2758 aViewList.Append (aViewName.GetViewName());
18d715bd 2759 }
2760 }
2761 else
2762 {
d0cc1cb7 2763 // close active view
2764 if (ViewerTest::CurrentView().IsNull())
2765 {
23fe70ec 2766 Message::SendFail ("Error: no active view");
d0cc1cb7 2767 return 1;
2768 }
2769 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2770 }
2771
d0cc1cb7 2772 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2773 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2774 anIter.More(); anIter.Next())
2775 {
d0cc1cb7 2776 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2777 }
2778
2779 return 0;
2780}
2781
2782//==============================================================================
2783//function : VActivate
2784//purpose : Activate the view defined by its ID
2785//==============================================================================
2786
2787static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2788{
e084dbbc 2789 if (theArgsNb == 1)
18d715bd 2790 {
2791 theDi.Eval("vviewlist");
2792 return 0;
2793 }
2794
e084dbbc 2795 TCollection_AsciiString aNameString;
2796 Standard_Boolean toUpdate = Standard_True;
2797 Standard_Boolean toActivate = Standard_True;
2798 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2799 {
e084dbbc 2800 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2801 anArg.LowerCase();
2802 if (toUpdate
2803 && anArg == "-noupdate")
2804 {
2805 toUpdate = Standard_False;
2806 }
2807 else if (toActivate
2808 && aNameString.IsEmpty()
2809 && anArg == "none")
2810 {
49582f9d 2811 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
e084dbbc 2812 VT_GetWindow().Nullify();
2813 ViewerTest::CurrentView (Handle(V3d_View)());
2814 ViewerTest::ResetEventManager();
2815 theDi << theArgVec[0] << ": all views are inactive\n";
2816 toActivate = Standard_False;
2817 }
2818 else if (toActivate
2819 && aNameString.IsEmpty())
2820 {
2821 aNameString = theArgVec[anArgIter];
2822 }
2823 else
2824 {
23fe70ec 2825 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
e084dbbc 2826 return 1;
2827 }
18d715bd 2828 }
2829
e084dbbc 2830 if (!toActivate)
2831 {
2832 return 0;
2833 }
2834 else if (aNameString.IsEmpty())
2835 {
23fe70ec 2836 Message::SendFail ("Syntax error: wrong number of arguments");
e084dbbc 2837 return 1;
2838 }
18d715bd 2839
2840 // Check if this view exists in the viewer with the driver
e084dbbc 2841 ViewerTest_Names aViewNames (aNameString);
18d715bd 2842 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2843 {
e084dbbc 2844 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2845 return 1;
2846 }
2847
2848 // Check if it is active already
2849 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2850 {
2851 theDi << theArgVec[0] << ": the view is active already\n";
2852 return 0;
2853 }
2854
e084dbbc 2855 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2856 return 0;
2857}
2858
2859//==============================================================================
2860//function : VViewList
2861//purpose : Print current list of views per viewer and graphic driver ID
2862// shared between viewers
2863//==============================================================================
2864
2865static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2866{
2867 if (theArgsNb > 2)
2868 {
2869 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2870 << "Usage: " << theArgVec[0] << " name";
18d715bd 2871 return 1;
2872 }
2873 if (ViewerTest_myContexts.Size() < 1)
2874 return 0;
2875
18d715bd 2876 Standard_Boolean isTreeView =
29cb310a 2877 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2878
2879 if (isTreeView)
c48e2889 2880 {
18d715bd 2881 theDi << theArgVec[0] <<":\n";
c48e2889 2882 }
18d715bd 2883
c48e2889 2884 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2885 aDriverIter.More(); aDriverIter.Next())
2886 {
2887 if (isTreeView)
2888 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2889
c48e2889 2890 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2891 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2892 {
2893 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2894 {
c48e2889 2895 if (isTreeView)
18d715bd 2896 {
c48e2889 2897 TCollection_AsciiString aContextName(aContextIter.Key1());
2898 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2899 }
18d715bd 2900
c48e2889 2901 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2902 aViewIter.More(); aViewIter.Next())
2903 {
2904 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2905 {
c48e2889 2906 TCollection_AsciiString aViewName(aViewIter.Key1());
2907 if (isTreeView)
18d715bd 2908 {
c48e2889 2909 if (aViewIter.Value() == ViewerTest::CurrentView())
2910 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2911 else
c48e2889 2912 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2913 }
2914 else
2915 {
2916 theDi << aViewName << " ";
18d715bd 2917 }
2918 }
2919 }
2920 }
2921 }
c48e2889 2922 }
18d715bd 2923 return 0;
2924}
2925
7fd59977 2926//==============================================================================
49582f9d 2927//function : GetMousePosition
2928//purpose :
7fd59977 2929//==============================================================================
49582f9d 2930void ViewerTest::GetMousePosition (Standard_Integer& theX,
2931 Standard_Integer& theY)
7fd59977 2932{
49582f9d 2933 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
4fe56619 2934 {
49582f9d 2935 theX = aViewCtrl->LastMousePosition().x();
2936 theY = aViewCtrl->LastMousePosition().y();
4fe56619 2937 }
7fd59977 2938}
2939
44b8f2d6 2940//==============================================================================
fc552d84 2941//function : VViewProj
2942//purpose : Switch view projection
44b8f2d6 2943//==============================================================================
fc552d84 2944static int VViewProj (Draw_Interpretor& ,
2945 Standard_Integer theNbArgs,
2946 const char** theArgVec)
44b8f2d6 2947{
fc552d84 2948 static Standard_Boolean isYup = Standard_False;
2949 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2950 if (aView.IsNull())
44b8f2d6 2951 {
23fe70ec 2952 Message::SendFail ("Error: no active viewer");
44b8f2d6 2953 return 1;
2954 }
2955
fc552d84 2956 TCollection_AsciiString aCmdName (theArgVec[0]);
2957 Standard_Boolean isGeneralCmd = Standard_False;
2958 if (aCmdName == "vfront")
2959 {
2960 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2961 }
2962 else if (aCmdName == "vback")
2963 {
2964 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2965 }
2966 else if (aCmdName == "vtop")
2967 {
2968 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2969 }
2970 else if (aCmdName == "vbottom")
2971 {
2972 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2973 }
2974 else if (aCmdName == "vleft")
2975 {
2976 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2977 }
2978 else if (aCmdName == "vright")
2979 {
2980 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2981 }
2982 else if (aCmdName == "vaxo")
2983 {
2984 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2985 }
2986 else
2987 {
2988 isGeneralCmd = Standard_True;
2989 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2990 {
2991 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2992 anArgCase.LowerCase();
2993 if (anArgCase == "-zup")
2994 {
2995 isYup = Standard_False;
2996 }
2997 else if (anArgCase == "-yup")
2998 {
2999 isYup = Standard_True;
3000 }
3001 else if (anArgCase == "-front"
3002 || anArgCase == "front"
3003 || anArgCase == "-f"
3004 || anArgCase == "f")
3005 {
3006 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
3007 }
3008 else if (anArgCase == "-back"
3009 || anArgCase == "back"
3010 || anArgCase == "-b"
3011 || anArgCase == "b")
3012 {
3013 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
3014 }
3015 else if (anArgCase == "-top"
3016 || anArgCase == "top"
3017 || anArgCase == "-t"
3018 || anArgCase == "t")
3019 {
3020 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
3021 }
3022 else if (anArgCase == "-bottom"
3023 || anArgCase == "bottom"
3024 || anArgCase == "-bot"
3025 || anArgCase == "bot"
3026 || anArgCase == "-b"
3027 || anArgCase == "b")
3028 {
3029 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
3030 }
3031 else if (anArgCase == "-left"
3032 || anArgCase == "left"
3033 || anArgCase == "-l"
3034 || anArgCase == "l")
3035 {
3036 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
3037 }
3038 else if (anArgCase == "-right"
3039 || anArgCase == "right"
3040 || anArgCase == "-r"
3041 || anArgCase == "r")
3042 {
3043 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
3044 }
3045 else if (anArgCase == "-axoleft"
3046 || anArgCase == "-leftaxo"
3047 || anArgCase == "axoleft"
3048 || anArgCase == "leftaxo")
3049 {
3050 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
3051 }
3052 else if (anArgCase == "-axo"
3053 || anArgCase == "axo"
3054 || anArgCase == "-a"
3055 || anArgCase == "a"
3056 || anArgCase == "-axoright"
3057 || anArgCase == "-rightaxo"
3058 || anArgCase == "axoright"
3059 || anArgCase == "rightaxo")
3060 {
3061 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
3062 }
3063 else if (anArgCase == "+x")
3064 {
3065 aView->SetProj (V3d_Xpos, isYup);
3066 }
3067 else if (anArgCase == "-x")
3068 {
3069 aView->SetProj (V3d_Xneg, isYup);
3070 }
3071 else if (anArgCase == "+y")
3072 {
3073 aView->SetProj (V3d_Ypos, isYup);
3074 }
3075 else if (anArgCase == "-y")
3076 {
3077 aView->SetProj (V3d_Yneg, isYup);
3078 }
3079 else if (anArgCase == "+z")
3080 {
3081 aView->SetProj (V3d_Zpos, isYup);
3082 }
3083 else if (anArgCase == "-z")
3084 {
3085 aView->SetProj (V3d_Zneg, isYup);
3086 }
3087 else if (anArgCase == "+x+y+z")
3088 {
3089 aView->SetProj (V3d_XposYposZpos, isYup);
3090 }
3091 else if (anArgCase == "+x+y-z")
3092 {
3093 aView->SetProj (V3d_XposYposZneg, isYup);
3094 }
3095 else if (anArgCase == "+x-y+z")
3096 {
3097 aView->SetProj (V3d_XposYnegZpos, isYup);
3098 }
3099 else if (anArgCase == "+x-y-z")
3100 {
3101 aView->SetProj (V3d_XposYnegZneg, isYup);
3102 }
3103 else if (anArgCase == "-x+y+z")
3104 {
3105 aView->SetProj (V3d_XnegYposZpos, isYup);
3106 }
3107 else if (anArgCase == "-x+y-z")
3108 {
3109 aView->SetProj (V3d_XnegYposZneg, isYup);
3110 }
3111 else if (anArgCase == "-x-y+z")
3112 {
3113 aView->SetProj (V3d_XnegYnegZpos, isYup);
3114 }
3115 else if (anArgCase == "-x-y-z")
3116 {
3117 aView->SetProj (V3d_XnegYnegZneg, isYup);
3118 }
3119 else if (anArgCase == "+x+y")
3120 {
3121 aView->SetProj (V3d_XposYpos, isYup);
3122 }
3123 else if (anArgCase == "+x-y")
3124 {
3125 aView->SetProj (V3d_XposYneg, isYup);
3126 }
3127 else if (anArgCase == "-x+y")
3128 {
3129 aView->SetProj (V3d_XnegYpos, isYup);
3130 }
3131 else if (anArgCase == "-x-y")
3132 {
3133 aView->SetProj (V3d_XnegYneg, isYup);
3134 }
3135 else if (anArgCase == "+x+z")
3136 {
3137 aView->SetProj (V3d_XposZpos, isYup);
3138 }
3139 else if (anArgCase == "+x-z")
3140 {
3141 aView->SetProj (V3d_XposZneg, isYup);
3142 }
3143 else if (anArgCase == "-x+z")
3144 {
3145 aView->SetProj (V3d_XnegZpos, isYup);
3146 }
3147 else if (anArgCase == "-x-z")
3148 {
3149 aView->SetProj (V3d_XnegZneg, isYup);
3150 }
3151 else if (anArgCase == "+y+z")
3152 {
3153 aView->SetProj (V3d_YposZpos, isYup);
3154 }
3155 else if (anArgCase == "+y-z")
3156 {
3157 aView->SetProj (V3d_YposZneg, isYup);
3158 }
3159 else if (anArgCase == "-y+z")
3160 {
3161 aView->SetProj (V3d_YnegZpos, isYup);
3162 }
3163 else if (anArgCase == "-y-z")
3164 {
3165 aView->SetProj (V3d_YnegZneg, isYup);
3166 }
3167 else if (anArgIter + 1 < theNbArgs
3168 && anArgCase == "-frame"
3169 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
3170 {
3171 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
3172 aFrameDef.LowerCase();
3173 gp_Dir aRight, anUp;
3174 if (aFrameDef.Value (2) == aFrameDef.Value (4))
3175 {
23fe70ec 3176 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3177 return 1;
3178 }
44b8f2d6 3179
fc552d84 3180 if (aFrameDef.Value (2) == 'x')
3181 {
3182 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
3183 }
3184 else if (aFrameDef.Value (2) == 'y')
3185 {
3186 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
3187 }
3188 else if (aFrameDef.Value (2) == 'z')
3189 {
3190 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
3191 }
3192 else
3193 {
23fe70ec 3194 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3195 return 1;
3196 }
7fd59977 3197
fc552d84 3198 if (aFrameDef.Value (4) == 'x')
3199 {
3200 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
3201 }
3202 else if (aFrameDef.Value (4) == 'y')
3203 {
3204 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
3205 }
3206 else if (aFrameDef.Value (4) == 'z')
3207 {
3208 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
3209 }
3210 else
3211 {
23fe70ec 3212 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3213 return 1;
3214 }
44b8f2d6 3215
fc552d84 3216 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3217 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3218 const gp_Dir aDir = anUp.Crossed (aRight);
3219 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3220 aCamera->SetDirection (aDir);
3221 aCamera->SetUp (anUp);
3222 aCamera->OrthogonalizeUp();
44b8f2d6 3223
fc552d84 3224 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3225 aView->Update();
3226 }
3227 else
3228 {
23fe70ec 3229 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3230 return 1;
3231 }
3232 }
3233 }
44b8f2d6 3234
fc552d84 3235 if (!isGeneralCmd
3236 && theNbArgs != 1)
3237 {
23fe70ec 3238 Message::SendFail ("Syntax error: wrong number of arguments");
fc552d84 3239 return 1;
3240 }
3241 return 0;
7fd59977 3242}
3243
3244//==============================================================================
3245//function : VHelp
3246//purpose : Dsiplay help on viewer Keyboead and mouse commands
3247//Draw arg : No args
3248//==============================================================================
3249
3250static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3251{
586db386 3252 di << "=========================\n";
3253 di << "F : FitAll\n";
3254 di << "T : TopView\n";
3255 di << "B : BottomView\n";
3256 di << "R : RightView\n";
3257 di << "L : LeftView\n";
d22962e4 3258 di << "Backspace : AxonometricView\n";
586db386 3259
3260 di << "=========================\n";
d22962e4 3261 di << "W, S : Fly forward/backward\n";
3262 di << "A, D : Slide left/right\n";
3263 di << "Q, E : Bank left/right\n";
3264 di << "-, + : Change flying speed\n";
3265 di << "Arrows : look left/right/up/down\n";
3266 di << "Arrows+Shift : slide left/right/up/down\n";
3267
3268 di << "=========================\n";
3269 di << "S + Ctrl : Shading\n";
3270 di << "W + Ctrl : Wireframe\n";
49582f9d 3271 di << "H : HiddenLineRemoval\n";
586db386 3272 di << "U : Unset display mode\n";
3273 di << "Delete : Remove selection from viewer\n";
3274
3275 di << "=========================\n";
3276 di << "Selection mode \n";
3277 di << "0 : Shape\n";
3278 di << "1 : Vertex\n";
3279 di << "2 : Edge\n";
3280 di << "3 : Wire\n";
3281 di << "4 : Face\n";
3282 di << "5 : Shell\n";
3283 di << "6 : Solid\n";
3284 di << "7 : Compound\n";
3285
3286 di << "=========================\n";
49582f9d 3287 di << "< : Hilight next detected\n";
3288 di << "> : Hilight previous detected\n";
7fd59977 3289
3290 return 0;
3291}
3292
57c28b61 3293#ifdef _WIN32
7fd59977 3294
49582f9d 3295static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3296 UINT theMsg,
3297 WPARAM wParam,
3298 LPARAM lParam )
7fd59977 3299{
49582f9d 3300 if (ViewerTest_myViews.IsEmpty())
3301 {
e8e157df 3302 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
49582f9d 3303 }
7fd59977 3304
49582f9d 3305 switch (theMsg)
3306 {
18d715bd 3307 case WM_CLOSE:
49582f9d 3308 {
3309 // Delete view from map of views
3310 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3311 return 0;
3312 }
18d715bd 3313 case WM_ACTIVATE:
49582f9d 3314 {
3315 if (LOWORD(wParam) == WA_CLICKACTIVE
3316 || LOWORD(wParam) == WA_ACTIVE
3317 || ViewerTest::CurrentView().IsNull())
18d715bd 3318 {
3319 // Activate inactive window
49582f9d 3320 if (VT_GetWindow().IsNull()
3321 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
625e1958 3322 {
49582f9d 3323 ActivateView (FindViewIdByWindowHandle (theWinHandle));
625e1958 3324 }
7fd59977 3325 }
e8e157df 3326 return 0;
49582f9d 3327 }
7fd59977 3328 case WM_LBUTTONDOWN:
49582f9d 3329 {
e8e157df 3330 TheIsAnimating = Standard_False;
f978241f 3331 }
e8e157df 3332 Standard_FALLTHROUGH
3333 default:
49582f9d 3334 {
e8e157df 3335 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3336 if (!aView.IsNull()
3337 && !VT_GetWindow().IsNull())
49582f9d 3338 {
e8e157df 3339 MSG aMsg = {};
3340 aMsg.hwnd = theWinHandle;
3341 aMsg.message = theMsg;
3342 aMsg.wParam = wParam;
3343 aMsg.lParam = lParam;
3344 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
49582f9d 3345 {
e8e157df 3346 return 0;
49582f9d 3347 }
3348 }
7fd59977 3349 }
49582f9d 3350 }
e8e157df 3351 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
7fd59977 3352}
3353
7fd59977 3354//==============================================================================
3355//function : ViewerMainLoop
3356//purpose : Get a Event on the view and dispatch it
3357//==============================================================================
3358
49582f9d 3359int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
7fd59977 3360{
49582f9d 3361 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3362 if (aViewCtrl.IsNull()
3363 || theNbArgs < 4)
3364 {
3365 return 0;
3366 }
7fd59977 3367
49582f9d 3368 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
7fd59977 3369
49582f9d 3370 std::cout << "Start picking\n";
7fd59977 3371
49582f9d 3372 MSG aMsg;
3373 aMsg.wParam = 1;
3374 while (aViewCtrl->ToPickPoint())
3375 {
3376 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3377 if (GetMessageW (&aMsg, NULL, 0, 0))
3378 {
3379 TranslateMessage (&aMsg);
3380 DispatchMessageW (&aMsg);
7fd59977 3381 }
7fd59977 3382 }
3383
49582f9d 3384 std::cout << "Picking done\n";
3385 return 0;
7fd59977 3386}
3387
b69e576a 3388#elif defined(HAVE_XLIB)
7fd59977 3389
49582f9d 3390int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
4269bd1b 3391{
18d715bd 3392 static XEvent aReport;
49582f9d 3393 const Standard_Boolean toPick = theNbArgs > 0;
3394 if (theNbArgs > 0)
3395 {
3396 if (ViewerTest::CurrentEventManager().IsNull())
3397 {
3398 return 0;
3399 }
3400 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3401 }
3402
b69e576a 3403 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
18d715bd 3404 XNextEvent (aDisplay, &aReport);
7fd59977 3405
18d715bd 3406 // Handle event for the chosen display connection
8693dfd0 3407 switch (aReport.type)
3408 {
3409 case ClientMessage:
3410 {
3411 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3412 {
3413 // Close the window
3414 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3415 return toPick ? 0 : 1;
3416 }
3417 break;
3418 }
3419 case FocusIn:
3420 {
3421 // Activate inactive view
49582f9d 3422 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3423 if (aWindow != aReport.xfocus.window)
3424 {
3425 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3426 }
3427 break;
3428 }
49582f9d 3429 case ButtonPress:
8693dfd0 3430 {
49582f9d 3431 if (aReport.xbutton.button == Button1)
8693dfd0 3432 {
e8e157df 3433 TheIsAnimating = Standard_False;
49582f9d 3434 }
8693dfd0 3435 }
e8e157df 3436 Standard_FALLTHROUGH
3437 default:
8693dfd0 3438 {
e8e157df 3439 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3440 if (!aView.IsNull()
3441 && !VT_GetWindow().IsNull())
8693dfd0 3442 {
e8e157df 3443 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
49582f9d 3444 }
8693dfd0 3445 break;
3446 }
3447 }
49582f9d 3448 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
7fd59977 3449}
3450
3451//==============================================================================
3452//function : VProcessEvents
8693dfd0 3453//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3454//==============================================================================
8693dfd0 3455static void VProcessEvents (ClientData theDispX, int)
7fd59977 3456{
8693dfd0 3457 Display* aDispX = (Display* )theDispX;
3458 Handle(Aspect_DisplayConnection) aDispConn;
3459 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3460 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3461 {
8693dfd0 3462 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
b69e576a 3463 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
8693dfd0 3464 {
3465 aDispConn = aDispConnTmp;
3466 break;
3467 }
3468 }
3469 if (aDispConn.IsNull())
3470 {
23fe70ec 3471 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
8693dfd0 3472 return;
4269bd1b 3473 }
8693dfd0 3474
3475 // process new events in queue
3476 SetDisplayConnection (aDispConn);
3477 int aNbRemain = 0;
3478 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3479 {
8693dfd0 3480 const int anEventResult = ViewerMainLoop (0, NULL);
3481 if (anEventResult == 0)
18d715bd 3482 {
8693dfd0 3483 return;
3484 }
3485
3486 aNbRemain = XPending (aDispX);
3487 if (++anEventIter >= aNbEventsMax
3488 || aNbRemain <= 0)
3489 {
3490 break;
18d715bd 3491 }
7fd59977 3492 }
4269bd1b 3493
8693dfd0 3494 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3495 // it is possible that new events will arrive to queue before the end of this callback
3496 // so that either this callback should go into an infinite loop (blocking processing of other events)
3497 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3498 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3499 if (aNbRemain != 0)
3500 {
3501 XEvent aDummyEvent;
3502 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3503 aDummyEvent.type = ClientMessage;
3504 aDummyEvent.xclient.format = 32;
3505 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3506 XFlush (aDispX);
3507 }
4269bd1b 3508
8693dfd0 3509 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3510 {
3511 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3512 }
7fd59977 3513}
b69e576a 3514#elif !defined(__APPLE__)
3515// =======================================================================
3516// function : ViewerMainLoop
3517// purpose :
3518// =======================================================================
3519int ViewerMainLoop (Standard_Integer , const char** )
3520{
3521 // unused
3522 return 0;
3523}
7fd59977 3524#endif
3525
7fd59977 3526//==============================================================================
3527//function : VFit
1beb58d7 3528//purpose :
7fd59977 3529//==============================================================================
3530
1beb58d7 3531static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 3532{
1beb58d7 3533 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3534 if (aView.IsNull())
b586500b 3535 {
23fe70ec 3536 Message::SendFail ("Error: no active viewer");
1beb58d7 3537 return 1;
b586500b 3538 }
3539
1beb58d7 3540 Standard_Boolean toFit = Standard_True;
3541 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3542 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 3543 {
1beb58d7 3544 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 3545 anArg.LowerCase();
1beb58d7 3546 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 3547 {
1beb58d7 3548 continue;
3549 }
3550 else if (anArg == "-selected")
3551 {
3552 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3553 toFit = Standard_False;
3554 }
3555 else
3556 {
23fe70ec 3557 Message::SendFail() << "Syntax error at '" << anArg << "'";
b586500b 3558 }
3559 }
3560
1beb58d7 3561 if (toFit)
3562 {
3563 aView->FitAll (0.01, Standard_False);
7fd59977 3564 }
3565 return 0;
3566}
3567
6262a303 3568//=======================================================================
3569//function : VFitArea
3570//purpose : Fit view to show area located between two points
3571// : given in world 2D or 3D coordinates.
3572//=======================================================================
3573static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3574{
3575 Handle(V3d_View) aView = ViewerTest::CurrentView();
3576 if (aView.IsNull())
3577 {
23fe70ec 3578 Message::SendFail ("Error: No active viewer");
6262a303 3579 return 1;
3580 }
3581
3582 // Parse arguments.
3583 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3584 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3585
3586 if (theArgNb == 5)
3587 {
3588 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3589 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3590 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3591 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3592 }
3593 else if (theArgNb == 7)
3594 {
3595 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3596 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3597 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3598 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3599 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3600 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3601 }
3602 else
3603 {
23fe70ec 3604 Message::SendFail ("Syntax error: Invalid number of arguments");
6262a303 3605 theDI.PrintHelp(theArgVec[0]);
3606 return 1;
3607 }
3608
3609 // Convert model coordinates to view space
3610 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3611 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3612 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3613
3614 // Determine fit area
3615 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3616 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3617
3618 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3619
3620 if (aDiagonal < Precision::Confusion())
3621 {
23fe70ec 3622 Message::SendFail ("Error: view area is too small");
6262a303 3623 return 1;
3624 }
3625
3626 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3627 return 0;
3628}
3629
7fd59977 3630//==============================================================================
3631//function : VZFit
3632//purpose : ZFitall, no DRAW arguments
3633//Draw arg : No args
3634//==============================================================================
197ac94e 3635static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 3636{
197ac94e 3637 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3638
3639 if (aCurrentView.IsNull())
3640 {
23fe70ec 3641 Message::SendFail ("Error: no active viewer");
197ac94e 3642 return 1;
3643 }
3644
3645 if (theArgsNb == 1)
3646 {
c357e426 3647 aCurrentView->ZFitAll();
197ac94e 3648 aCurrentView->Redraw();
3649 return 0;
3650 }
3651
3652 Standard_Real aScale = 1.0;
3653
3654 if (theArgsNb >= 2)
3655 {
3656 aScale = Draw::Atoi (theArgVec[1]);
3657 }
3658
c357e426 3659 aCurrentView->ZFitAll (aScale);
197ac94e 3660 aCurrentView->Redraw();
7fd59977 3661
197ac94e 3662 return 0;
3663}
7fd59977 3664
197ac94e 3665//==============================================================================
3666//function : VRepaint
3667//purpose :
3668//==============================================================================
56689b27 3669static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 3670{
56689b27 3671 Handle(V3d_View) aView = ViewerTest::CurrentView();
3672 if (aView.IsNull())
3673 {
23fe70ec 3674 Message::SendFail ("Error: no active viewer");
56689b27 3675 return 1;
3676 }
3677
3678 Standard_Boolean isImmediateUpdate = Standard_False;
3679 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3680 {
3681 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3682 anArg.LowerCase();
8693dfd0 3683 if (anArg == "-immediate"
3684 || anArg == "-imm")
56689b27 3685 {
3686 isImmediateUpdate = Standard_True;
3687 if (anArgIter + 1 < theArgNb
dae2a922 3688 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
56689b27 3689 {
3690 ++anArgIter;
3691 }
3692 }
8693dfd0 3693 else if (anArg == "-continuous"
3694 || anArg == "-cont"
3695 || anArg == "-fps"
3696 || anArg == "-framerate")
3697 {
3698 Standard_Real aFps = -1.0;
3699 if (anArgIter + 1 < theArgNb
d45edf24 3700 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
8693dfd0 3701 {
3702 aFps = Draw::Atof (theArgVec[++anArgIter]);
3703 }
3704
3705 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3706 if (Abs (aFps) >= 1.0)
3707 {
3708 aRedrawer.Start (aView->Window(), aFps);
3709 }
3710 else
3711 {
3712 aRedrawer.Stop();
3713 }
3714 }
56689b27 3715 else
3716 {
23fe70ec 3717 Message::SendFail() << "Syntax error at '" << anArg << "'";
8693dfd0 3718 return 1;
56689b27 3719 }
3720 }
3721
3722 if (isImmediateUpdate)
3723 {
3724 aView->RedrawImmediate();
3725 }
3726 else
3727 {
3728 aView->Redraw();
3729 }
3730 return 0;
7fd59977 3731}
3732
7fd59977 3733//==============================================================================
3734//function : VClear
3735//purpose : Remove all the object from the viewer
3736//Draw arg : No args
3737//==============================================================================
3738
3739static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3740{
3741 Handle(V3d_View) V = ViewerTest::CurrentView();
3742 if(!V.IsNull())
3743 ViewerTest::Clear();
3744 return 0;
3745}
3746
3747//==============================================================================
3748//function : VPick
3749//purpose :
3750//==============================================================================
3751
49582f9d 3752static int VPick (Draw_Interpretor& ,
3753 Standard_Integer theNbArgs,
3754 const char** theArgVec)
3755{
3756 if (ViewerTest::CurrentView().IsNull())
3757 {
3758 return 1;
3759 }
7fd59977 3760
49582f9d 3761 if (theNbArgs < 4)
3762 {
23fe70ec 3763 Message::SendFail ("Syntax error: wrong number of arguments");
49582f9d 3764 return 1;
3765 }
7fd59977 3766
49582f9d 3767 while (ViewerMainLoop (theNbArgs, theArgVec))
3768 {
3769 //
3770 }
7fd59977 3771
49582f9d 3772 return 0;
7fd59977 3773}
3774
293211ae 3775namespace
7fd59977 3776{
7fd59977 3777
293211ae 3778 //! Changes the background
3779 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3780 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3781 //! @param theCommandLineArguments the array of command line arguments
3782 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3783 static int vbackground (Draw_Interpretor& theDrawInterpretor,
3784 const Standard_Integer theNumberOfCommandLineArguments,
3785 const char** const theCommandLineArguments)
7fd59977 3786 {
293211ae 3787 if (theNumberOfCommandLineArguments < 1)
7fd59977 3788 {
293211ae 3789 return TCL_ERROR;
7fd59977 3790 }
293211ae 3791 BackgroundChanger aBackgroundChanger;
3792 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
3793 theNumberOfCommandLineArguments,
3794 theCommandLineArguments))
f8b2ed36 3795 {
293211ae 3796 theDrawInterpretor << "Wrong command arguments.\n"
3797 "Type 'help "
3798 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
3799 return TCL_ERROR;
f8b2ed36 3800 }
293211ae 3801 return TCL_OK;
f8b2ed36 3802 }
3803
293211ae 3804} // namespace
f42753ed 3805
7fd59977 3806//==============================================================================
3807//function : VScale
3808//purpose : View Scaling
3809//==============================================================================
3810
3811static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3812{
3813 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3814 if ( V3dView.IsNull() ) return 1;
3815
3816 if ( argc != 4 ) {
586db386 3817 di << argv[0] << "Invalid number of arguments\n";
7fd59977 3818 return 1;
3819 }
91322f44 3820 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 3821 return 0;
3822}
3823//==============================================================================
536d98e2 3824//function : VZBuffTrihedron
3825//purpose :
7fd59977 3826//==============================================================================
3827
536d98e2 3828static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3829 Standard_Integer theArgNb,
3830 const char** theArgVec)
7fd59977 3831{
536d98e2 3832 Handle(V3d_View) aView = ViewerTest::CurrentView();
3833 if (aView.IsNull())
3834 {
23fe70ec 3835 Message::SendFail ("Error: no active viewer");
536d98e2 3836 return 1;
3837 }
7fd59977 3838
536d98e2 3839 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 3840
536d98e2 3841 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3842 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
0aeb8984 3843 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3844 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3845 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
536d98e2 3846 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3847 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3848 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3849 Standard_Real aScale = 0.1;
3850 Standard_Real aSizeRatio = 0.8;
3851 Standard_Real anArrowDiam = 0.05;
3852 Standard_Integer aNbFacets = 12;
3853 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 3854 {
536d98e2 3855 Standard_CString anArg = theArgVec[anArgIter];
3856 TCollection_AsciiString aFlag (anArg);
3857 aFlag.LowerCase();
3858 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 3859 {
536d98e2 3860 continue;
3861 }
3862 else if (aFlag == "-on")
7c8a8fcc 3863 {
536d98e2 3864 continue;
3865 }
3866 else if (aFlag == "-off")
7c8a8fcc 3867 {
536d98e2 3868 aView->TriedronErase();
3869 return 0;
3870 }
3871 else if (aFlag == "-pos"
3872 || aFlag == "-position"
3873 || aFlag == "-corner")
7c8a8fcc 3874 {
536d98e2 3875 if (++anArgIter >= theArgNb)
3876 {
23fe70ec 3877 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3878 return 1;
3879 }
3880
3881 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3882 aPosName.LowerCase();
3883 if (aPosName == "center")
3884 {
3885 aPosition = Aspect_TOTP_CENTER;
3886 }
3887 else if (aPosName == "left_lower"
3888 || aPosName == "lower_left"
3889 || aPosName == "leftlower"
3890 || aPosName == "lowerleft")
3891 {
3892 aPosition = Aspect_TOTP_LEFT_LOWER;
3893 }
3894 else if (aPosName == "left_upper"
3895 || aPosName == "upper_left"
3896 || aPosName == "leftupper"
3897 || aPosName == "upperleft")
3898 {
3899 aPosition = Aspect_TOTP_LEFT_UPPER;
3900 }
3901 else if (aPosName == "right_lower"
3902 || aPosName == "lower_right"
3903 || aPosName == "rightlower"
3904 || aPosName == "lowerright")
3905 {
3906 aPosition = Aspect_TOTP_RIGHT_LOWER;
3907 }
3908 else if (aPosName == "right_upper"
3909 || aPosName == "upper_right"
3910 || aPosName == "rightupper"
3911 || aPosName == "upperright")
3912 {
3913 aPosition = Aspect_TOTP_RIGHT_UPPER;
3914 }
3915 else
3916 {
23fe70ec 3917 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
536d98e2 3918 return 1;
3919 }
3920 }
3921 else if (aFlag == "-type")
7c8a8fcc 3922 {
536d98e2 3923 if (++anArgIter >= theArgNb)
3924 {
23fe70ec 3925 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3926 return 1;
3927 }
3928
3929 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3930 aTypeName.LowerCase();
3931 if (aTypeName == "wireframe"
3932 || aTypeName == "wire")
3933 {
3934 aVisType = V3d_WIREFRAME;
3935 }
3936 else if (aTypeName == "zbuffer"
3937 || aTypeName == "shaded")
3938 {
3939 aVisType = V3d_ZBUFFER;
3940 }
3941 else
3942 {
23fe70ec 3943 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
536d98e2 3944 }
3945 }
3946 else if (aFlag == "-scale")
7c8a8fcc 3947 {
536d98e2 3948 if (++anArgIter >= theArgNb)
3949 {
23fe70ec 3950 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3951 return 1;
3952 }
3953
3954 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 3955 }
536d98e2 3956 else if (aFlag == "-size"
3957 || aFlag == "-sizeratio")
3958 {
3959 if (++anArgIter >= theArgNb)
3960 {
23fe70ec 3961 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3962 return 1;
3963 }
7c8a8fcc 3964
536d98e2 3965 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3966 }
3967 else if (aFlag == "-arrowdiam"
3968 || aFlag == "-arrowdiameter")
3969 {
3970 if (++anArgIter >= theArgNb)
3971 {
23fe70ec 3972 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3973 return 1;
3974 }
7c8a8fcc 3975
536d98e2 3976 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3977 }
3978 else if (aFlag == "-nbfacets")
3979 {
3980 if (++anArgIter >= theArgNb)
3981 {
23fe70ec 3982 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3983 return 1;
3984 }
7c8a8fcc 3985
536d98e2 3986 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3987 }
3988 else if (aFlag == "-colorlabel"
0aeb8984 3989 || aFlag == "-colorlabels"
3990 || aFlag == "-colorlabelx"
3991 || aFlag == "-colorlabely"
3992 || aFlag == "-colorlabelz"
3993 || aFlag == "-colorarrowx"
3994 || aFlag == "-colorarrowy"
3995 || aFlag == "-colorarrowz")
7c8a8fcc 3996 {
0aeb8984 3997 Quantity_Color aColor;
dae2a922 3998 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3999 theArgVec + anArgIter + 1,
0aeb8984 4000 aColor);
536d98e2 4001 if (aNbParsed == 0)
4002 {
23fe70ec 4003 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4004 return 1;
4005 }
0aeb8984 4006
4007 if (aFlag == "-colorarrowx")
536d98e2 4008 {
0aeb8984 4009 anArrowColorX = aColor;
536d98e2 4010 }
0aeb8984 4011 else if (aFlag == "-colorarrowy")
536d98e2 4012 {
0aeb8984 4013 anArrowColorY = aColor;
536d98e2 4014 }
0aeb8984 4015 else if (aFlag == "-colorarrowz")
536d98e2 4016 {
0aeb8984 4017 anArrowColorZ = aColor;
4018 }
4019 else if (aFlag == "-colorlabelx")
4020 {
4021 aLabelsColorX = aColor;
4022 }
4023 else if (aFlag == "-colorlabely")
4024 {
4025 aLabelsColorY = aColor;
4026 }
4027 else if (aFlag == "-colorlabelz")
4028 {
4029 aLabelsColorZ = aColor;
4030 }
4031 else
4032 {
4033 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
536d98e2 4034 }
4035 anArgIter += aNbParsed;
4036 }
4037 else
4038 {
23fe70ec 4039 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
7c8a8fcc 4040 return 1;
4041 }
7c8a8fcc 4042 }
4043
0aeb8984 4044 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
4045 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
4046 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
4047 aTrihedron->SetSizeRatio (aSizeRatio);
4048 aTrihedron->SetNbFacets (aNbFacets);
4049 aTrihedron->SetArrowDiameter(anArrowDiam);
4050 aTrihedron->SetScale (aScale);
4051 aTrihedron->SetPosition (aPosition);
4052 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
4053 aTrihedron->Display (aView);
4054
c357e426 4055 aView->ZFitAll();
7fd59977 4056 return 0;
4057}
4058
4059//==============================================================================
4060//function : VRotate
4061//purpose : Camera Rotating
4062//==============================================================================
4063
4af098ba 4064static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4065{
4066 Handle(V3d_View) aView = ViewerTest::CurrentView();
4067 if (aView.IsNull())
4068 {
23fe70ec 4069 Message::SendFail ("Error: no active viewer");
7fd59977 4070 return 1;
4071 }
4072
4af098ba 4073 Standard_Boolean hasFlags = Standard_False;
4074 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4075 {
4076 Standard_CString anArg (theArgVec[anArgIter]);
4077 TCollection_AsciiString aFlag (anArg);
4078 aFlag.LowerCase();
4079 if (aFlag == "-mousestart"
4080 || aFlag == "-mousefrom")
4081 {
4082 hasFlags = Standard_True;
4083 if (anArgIter + 2 >= theArgNb)
4084 {
23fe70ec 4085 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4086 return 1;
4087 }
4088
4089 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4090 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4091 aView->StartRotation (anX, anY);
4092 }
4093 else if (aFlag == "-mousemove")
4094 {
4095 hasFlags = Standard_True;
4096 if (anArgIter + 2 >= theArgNb)
4097 {
23fe70ec 4098 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4099 return 1;
4100 }
4101
4102 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4103 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4104 aView->Rotation (anX, anY);
4105 }
4106 else if (theArgNb != 4
4107 && theArgNb != 7)
4108 {
23fe70ec 4109 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4110 return 1;
4111 }
4112 }
4113
4114 if (hasFlags)
4115 {
7fd59977 4116 return 0;
4af098ba 4117 }
4118 else if (theArgNb == 4)
4119 {
4120 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4121 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4122 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4123 aView->Rotate (anAX, anAY, anAZ);
4124 return 0;
4125 }
4126 else if (theArgNb == 7)
4127 {
4128 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4129 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4130 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4131
4132 Standard_Real anX = Draw::Atof (theArgVec[4]);
4133 Standard_Real anY = Draw::Atof (theArgVec[5]);
4134 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4135
4136 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4137 return 0;
7fd59977 4138 }
4af098ba 4139
23fe70ec 4140 Message::SendFail ("Error: Invalid number of arguments");
4af098ba 4141 return 1;
7fd59977 4142}
4143
4144//==============================================================================
4145//function : VZoom
4146//purpose : View zoom in / out (relative to current zoom)
4147//==============================================================================
4148
4149static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4150 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4151 if ( V3dView.IsNull() ) {
4152 return 1;
4153 }
4154
4155 if ( argc == 2 ) {
91322f44 4156 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4157 if ( coef <= 0.0 ) {
586db386 4158 di << argv[1] << "Invalid value\n";
7fd59977 4159 return 1;
4160 }
91322f44 4161 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4162 return 0;
4163 } else {
586db386 4164 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4165 return 1;
4166 }
4167}
4168
4169//==============================================================================
4170//function : VPan
4171//purpose : View panning (in pixels)
4172//==============================================================================
4173
4174static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4175 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4176 if ( V3dView.IsNull() ) return 1;
4177
4178 if ( argc == 3 ) {
91322f44 4179 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4180 return 0;
4181 } else {
586db386 4182 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4183 return 1;
4184 }
4185}
4186
49e1a5c7 4187//==============================================================================
4188//function : VPlace
4189//purpose : Place the point (in pixels) at the center of the window
4190//==============================================================================
4191static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4192{
4193 Handle(V3d_View) aView = ViewerTest::CurrentView();
4194 if (aView.IsNull())
4195 {
23fe70ec 4196 Message::SendFail ("Error: no active viewer");
49e1a5c7 4197 return 1;
4198 }
4199
4200 if (theArgNb != 3)
4201 {
23fe70ec 4202 Message::SendFail ("Syntax error: wrong number of arguments");
49e1a5c7 4203 return 1;
4204 }
4205
4206 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4207
4208 return 0;
4209}
7fd59977 4210
71215351 4211static int VColorScale (Draw_Interpretor& theDI,
4212 Standard_Integer theArgNb,
4213 const char** theArgVec)
4214{
7fd59977 4215 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4216 Handle(V3d_View) aView = ViewerTest::CurrentView();
4217 if (aContext.IsNull())
4218 {
23fe70ec 4219 Message::SendFail ("Error: no active viewer");
71215351 4220 return 1;
7fd59977 4221 }
24a88697 4222 if (theArgNb <= 1)
4223 {
23fe70ec 4224 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
24a88697 4225 return 1;
4226 }
7fd59977 4227
4b3d6eb1 4228 Handle(AIS_ColorScale) aColorScale;
7a324550 4229 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4230 {
4b3d6eb1 4231 // find existing object
4232 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4233 if (aColorScale.IsNull())
7a324550 4234 {
23fe70ec 4235 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
7a324550 4236 return 1;
4237 }
4238 }
71215351 4239
7a324550 4240 if (theArgNb <= 2)
4241 {
4b3d6eb1 4242 if (aColorScale.IsNull())
4243 {
23fe70ec 4244 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4b3d6eb1 4245 return 1;
4246 }
4247
7a324550 4248 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4249 << "Min range: " << aColorScale->GetMin() << "\n"
4250 << "Max range: " << aColorScale->GetMax() << "\n"
4251 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4252 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4253 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4254 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4255 << "Label position: ";
4b3d6eb1 4256 switch (aColorScale->GetLabelPosition())
71215351 4257 {
4258 case Aspect_TOCSP_NONE:
4259 theDI << "None\n";
4260 break;
4261 case Aspect_TOCSP_LEFT:
4262 theDI << "Left\n";
4263 break;
4264 case Aspect_TOCSP_RIGHT:
4265 theDI << "Right\n";
4266 break;
4267 case Aspect_TOCSP_CENTER:
4268 theDI << "Center\n";
4269 break;
4270 }
4271 return 0;
4272 }
71215351 4273
4b3d6eb1 4274 if (aColorScale.IsNull())
4275 {
4276 aColorScale = new AIS_ColorScale();
4277 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4278 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4279 }
4280
4281 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4282 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4283 {
4284 Standard_CString anArg = theArgVec[anArgIter];
4285 TCollection_AsciiString aFlag (anArg);
4286 aFlag.LowerCase();
4287 if (anUpdateTool.parseRedrawMode (aFlag))
4288 {
4289 continue;
4290 }
4291 else if (aFlag == "-range")
4292 {
4293 if (anArgIter + 3 >= theArgNb)
4294 {
23fe70ec 4295 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
71215351 4296 return 1;
4297 }
4298
4b3d6eb1 4299 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4300 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4301 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
d45edf24 4302 if (!aRangeMin.IsRealValue (Standard_True)
4303 || !aRangeMax.IsRealValue (Standard_True))
71215351 4304 {
23fe70ec 4305 Message::SendFail ("Syntax error: the range values should be real");
71215351 4306 return 1;
4307 }
4b3d6eb1 4308 else if (!aNbIntervals.IsIntegerValue())
71215351 4309 {
23fe70ec 4310 Message::SendFail ("Syntax error: the number of intervals should be integer");
71215351 4311 return 1;
4312 }
4313
4b3d6eb1 4314 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4315 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4316 }
4317 else if (aFlag == "-font")
4318 {
4319 if (anArgIter + 1 >= theArgNb)
4320 {
23fe70ec 4321 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4322 return 1;
4323 }
51740958 4324 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4325 if (!aFontArg.IsIntegerValue())
71215351 4326 {
23fe70ec 4327 Message::SendFail ("Syntax error: HeightFont value should be integer");
71215351 4328 return 1;
4329 }
4330
4b3d6eb1 4331 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4332 anArgIter += 1;
4333 }
4334 else if (aFlag == "-textpos")
4335 {
4336 if (anArgIter + 1 >= theArgNb)
4337 {
23fe70ec 4338 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4339 return 1;
4340 }
4b3d6eb1 4341
51740958 4342 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4343 aTextPosArg.LowerCase();
4b3d6eb1 4344 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4345 if (aTextPosArg == "none")
71215351 4346 {
4347 aLabPosition = Aspect_TOCSP_NONE;
4348 }
51740958 4349 else if (aTextPosArg == "left")
71215351 4350 {
4351 aLabPosition = Aspect_TOCSP_LEFT;
4352 }
51740958 4353 else if (aTextPosArg == "right")
71215351 4354 {
4355 aLabPosition = Aspect_TOCSP_RIGHT;
4356 }
51740958 4357 else if (aTextPosArg == "center")
71215351 4358 {
4359 aLabPosition = Aspect_TOCSP_CENTER;
4360 }
4361 else
4362 {
23fe70ec 4363 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
71215351 4364 return 1;
4365 }
4b3d6eb1 4366 aColorScale->SetLabelPosition (aLabPosition);
71215351 4367 }
24a88697 4368 else if (aFlag == "-logarithmic"
4369 || aFlag == "-log")
4370 {
4371 if (anArgIter + 1 >= theArgNb)
4372 {
23fe70ec 4373 Message::SendFail() << "Synta error at argument '" << anArg << "'";
24a88697 4374 return 1;
4375 }
4b3d6eb1 4376
24a88697 4377 Standard_Boolean IsLog;
dae2a922 4378 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
24a88697 4379 {
23fe70ec 4380 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
24a88697 4381 return 1;
4382 }
4b3d6eb1 4383 aColorScale->SetLogarithmic (IsLog);
4384 }
4385 else if (aFlag == "-huerange"
4386 || aFlag == "-hue")
4387 {
4388 if (anArgIter + 2 >= theArgNb)
4389 {
23fe70ec 4390 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4391 return 1;
4392 }
4393
4394 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4395 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4396 aColorScale->SetHueRange (aHueMin, aHueMax);
4397 }
4398 else if (aFlag == "-colorrange")
4399 {
4400 Quantity_Color aColorMin, aColorMax;
dae2a922 4401 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4402 theArgVec + (anArgIter + 1),
4403 aColorMin);
4b3d6eb1 4404 anArgIter += aNbParsed1;
dae2a922 4405 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4406 theArgVec + (anArgIter + 1),
4407 aColorMax);
4b3d6eb1 4408 anArgIter += aNbParsed2;
4409 if (aNbParsed1 == 0
4410 || aNbParsed2 == 0)
4411 {
23fe70ec 4412 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4b3d6eb1 4413 return 1;
4414 }
4415
4416 aColorScale->SetColorRange (aColorMin, aColorMax);
4417 }
4418 else if (aFlag == "-reversed"
4419 || aFlag == "-inverted"
4420 || aFlag == "-topdown"
4421 || aFlag == "-bottomup")
4422 {
4423 Standard_Boolean toEnable = Standard_True;
4424 if (anArgIter + 1 < theArgNb
dae2a922 4425 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4426 {
4427 ++anArgIter;
4428 }
4429 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4430 }
4431 else if (aFlag == "-smooth"
4432 || aFlag == "-smoothtransition")
4433 {
4434 Standard_Boolean toEnable = Standard_True;
4435 if (anArgIter + 1 < theArgNb
dae2a922 4436 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4437 {
4438 ++anArgIter;
4439 }
4440 aColorScale->SetSmoothTransition (toEnable);
24a88697 4441 }
71215351 4442 else if (aFlag == "-xy")
4443 {
4444 if (anArgIter + 2 >= theArgNb)
4445 {
23fe70ec 4446 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4447 return 1;
4448 }
4449
4b3d6eb1 4450 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4451 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4452 if (!anX.IsIntegerValue()
4453 || !anY.IsIntegerValue())
71215351 4454 {
23fe70ec 4455 Message::SendFail ("Syntax error: coordinates should be integer values");
71215351 4456 return 1;
4457 }
4458
4b3d6eb1 4459 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4460 }
4461 else if (aFlag == "-width"
4b3d6eb1 4462 || aFlag == "-w"
4463 || aFlag == "-breadth")
b4b2ecca 4464 {
4465 if (anArgIter + 1 >= theArgNb)
4466 {
23fe70ec 4467 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4468 return 1;
4469 }
4470
4b3d6eb1 4471 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4472 if (!aBreadth.IsIntegerValue())
b4b2ecca 4473 {
23fe70ec 4474 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4475 return 1;
4476 }
4b3d6eb1 4477 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4478 }
4479 else if (aFlag == "-height"
4480 || aFlag == "-h")
4481 {
4482 if (anArgIter + 1 >= theArgNb)
4483 {
23fe70ec 4484 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4485 return 1;
4486 }
4487
4b3d6eb1 4488 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4489 if (!aHeight.IsIntegerValue())
b4b2ecca 4490 {
23fe70ec 4491 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4492 return 1;
4493 }
4b3d6eb1 4494 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4495 }
4496 else if (aFlag == "-color")
4497 {
4b3d6eb1 4498 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4499 {
23fe70ec 4500 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
71215351 4501 return 1;
4502 }
4b3d6eb1 4503 else if (anArgIter + 2 >= theArgNb)
71215351 4504 {
23fe70ec 4505 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4506 return 1;
71215351 4507 }
4508
4b3d6eb1 4509 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 4510 if (!anInd.IsIntegerValue())
4511 {
23fe70ec 4512 Message::SendFail ("Syntax error: Index value should be integer");
71215351 4513 return 1;
4514 }
4b3d6eb1 4515 const Standard_Integer anIndex = anInd.IntegerValue();
4516 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 4517 {
23fe70ec 4518 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
71215351 4519 return 1;
4520 }
4521
4b3d6eb1 4522 Quantity_Color aColor;
dae2a922 4523 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4524 theArgVec + (anArgIter + 1),
4525 aColor);
4b3d6eb1 4526 if (aNbParsed == 0)
71215351 4527 {
23fe70ec 4528 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
71215351 4529 return 1;
4530 }
4b3d6eb1 4531 aColorScale->SetIntervalColor (aColor, anIndex);
4532 aColorScale->SetColorType (Aspect_TOCSD_USER);
4533 anArgIter += aNbParsed;
71215351 4534 }
4535 else if (aFlag == "-label")
4536 {
4b3d6eb1 4537 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4538 {
23fe70ec 4539 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
71215351 4540 return 1;
4541 }
4542 else if (anArgIter + 2 >= theArgNb)
4543 {
23fe70ec 4544 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4545 return 1;
4546 }
4547
4548 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 4549 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 4550 {
23fe70ec 4551 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
71215351 4552 return 1;
4553 }
4554
94f16a89 4555 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4b3d6eb1 4556 aColorScale->SetLabel (aText, anIndex);
4557 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4558 anArgIter += 2;
4559 }
4b3d6eb1 4560 else if (aFlag == "-labelat"
4561 || aFlag == "-labat"
4562 || aFlag == "-labelatborder"
4563 || aFlag == "-labatborder"
4564 || aFlag == "-labelatcenter"
4565 || aFlag == "-labatcenter")
71215351 4566 {
4b3d6eb1 4567 Standard_Boolean toEnable = Standard_True;
4568 if (aFlag == "-labelat"
4569 || aFlag == "-labat")
71215351 4570 {
4b3d6eb1 4571 Standard_Integer aLabAtBorder = -1;
4572 if (++anArgIter >= theArgNb)
71215351 4573 {
4b3d6eb1 4574 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4575 anAtBorder.LowerCase();
4576 if (anAtBorder == "border")
71215351 4577 {
4b3d6eb1 4578 aLabAtBorder = 1;
71215351 4579 }
4b3d6eb1 4580 else if (anAtBorder == "center")
71215351 4581 {
4b3d6eb1 4582 aLabAtBorder = 0;
71215351 4583 }
71215351 4584 }
4b3d6eb1 4585 if (aLabAtBorder == -1)
4586 {
23fe70ec 4587 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4588 return 1;
4589 }
4590 toEnable = (aLabAtBorder == 1);
4591 }
4592 else if (anArgIter + 1 < theArgNb
dae2a922 4593 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4594 {
4595 ++anArgIter;
71215351 4596 }
4b3d6eb1 4597 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4598 || aFlag == "-labatcenter"
4599 ? !toEnable
4600 : toEnable);
4601 }
4602 else if (aFlag == "-colors")
4603 {
4604 Aspect_SequenceOfColor aSeq;
4605 for (;;)
4606 {
4607 Quantity_Color aColor;
dae2a922 4608 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4609 theArgVec + (anArgIter + 1),
4610 aColor);
4b3d6eb1 4611 if (aNbParsed == 0)
4612 {
4613 break;
4614 }
4615 anArgIter += aNbParsed;
4616 aSeq.Append (aColor);
4617 }
4618 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 4619 {
23fe70ec 4620 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4621 << aColorScale->GetNumberOfIntervals() << " intervals";
71215351 4622 return 1;
4623 }
4624
4b3d6eb1 4625 aColorScale->SetColors (aSeq);
4626 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 4627 }
14b741b0 4628 else if (aFlag == "-uniform")
4629 {
4630 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4631 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4632 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4633 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4634 aColorScale->SetColorType (Aspect_TOCSD_USER);
4635 }
4b3d6eb1 4636 else if (aFlag == "-labels"
4637 || aFlag == "-freelabels")
71215351 4638 {
4b3d6eb1 4639 if (anArgIter + 1 >= theArgNb)
4640 {
23fe70ec 4641 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4642 return 1;
4643 }
4644
4645 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4646 ? aColorScale->GetNumberOfIntervals() + 1
4647 : aColorScale->GetNumberOfIntervals();
4648 if (aFlag == "-freelabels")
4649 {
4650 ++anArgIter;
4651 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4652 }
4653 if (anArgIter + aNbLabels >= theArgNb)
71215351 4654 {
23fe70ec 4655 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
71215351 4656 return 1;
4657 }
4658
4659 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 4660 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 4661 {
94f16a89 4662 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
71215351 4663 }
4b3d6eb1 4664 aColorScale->SetLabels (aSeq);
4665 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4666 }
4667 else if (aFlag == "-title")
4668 {
4669 if (anArgIter + 1 >= theArgNb)
4670 {
23fe70ec 4671 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4672 return 1;
4673 }
4674
4675 Standard_Boolean isTwoArgs = Standard_False;
4676 if (anArgIter + 2 < theArgNb)
4677 {
4678 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4679 aSecondArg.LowerCase();
4b3d6eb1 4680 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 4681 if (aSecondArg == "none")
4682 {
4b3d6eb1 4683 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 4684 isTwoArgs = Standard_True;
4685 }
4686 else if (aSecondArg == "left")
4687 {
4b3d6eb1 4688 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 4689 isTwoArgs = Standard_True;
4690 }
4691 else if (aSecondArg == "right")
4692 {
4b3d6eb1 4693 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 4694 isTwoArgs = Standard_True;
4695 }
4696 else if (aSecondArg == "center")
4697 {
4b3d6eb1 4698 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 4699 isTwoArgs = Standard_True;
4700 }
4b3d6eb1 4701 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 4702 }
4703
94f16a89 4704 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4705 aColorScale->SetTitle (aTitle);
71215351 4706 if (isTwoArgs)
4707 {
4708 anArgIter += 1;
4709 }
4710 anArgIter += 1;
4711 }
4712 else if (aFlag == "-demoversion"
4713 || aFlag == "-demo")
4714 {
4b3d6eb1 4715 aColorScale->SetPosition (0, 0);
4716 aColorScale->SetTextHeight (16);
4717 aColorScale->SetRange (0.0, 100.0);
4718 aColorScale->SetNumberOfIntervals (10);
4719 aColorScale->SetBreadth (0);
4720 aColorScale->SetHeight (0);
4721 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4722 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4723 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 4724 }
d5514578 4725 else if (aFlag == "-findcolor")
4726 {
4727 if (anArgIter + 1 >= theArgNb)
4728 {
23fe70ec 4729 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
d5514578 4730 return 1;
4731 }
4732
4733 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4734
d45edf24 4735 if (!anArg1.IsRealValue (Standard_True))
d5514578 4736 {
23fe70ec 4737 Message::SendFail ("Syntax error: the value should be real");
d5514578 4738 return 1;
4739 }
4740
4741 Quantity_Color aColor;
4b3d6eb1 4742 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 4743 theDI << Quantity_Color::StringName (aColor.Name());
4744 return 0;
4745 }
71215351 4746 else
4747 {
23fe70ec 4748 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
71215351 4749 return 1;
4750 }
4751 }
4b3d6eb1 4752
4753 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4754 aView->Window()->Size (aWinWidth, aWinHeight);
4755 if (aColorScale->GetBreadth() == 0)
b4b2ecca 4756 {
4b3d6eb1 4757 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 4758 }
4b3d6eb1 4759 if (aColorScale->GetHeight() == 0)
4760 {
4761 aColorScale->SetHeight (aWinHeight);
4762 }
4763 aColorScale->SetToUpdate();
4764 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 4765 return 0;
4766}
4767
4768//==============================================================================
4769//function : VGraduatedTrihedron
a79f67f8 4770//purpose : Displays or hides a graduated trihedron
7fd59977 4771//==============================================================================
a79f67f8 4772static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4773 Quantity_Color& theColor)
13a22457 4774{
a79f67f8 4775 Quantity_NameOfColor aColorName;
4776 TCollection_AsciiString aVal = theValue;
4777 aVal.UpperCase();
4778 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 4779 {
a79f67f8 4780 return Standard_False;
13a22457 4781 }
a79f67f8 4782 theColor = Quantity_Color (aColorName);
4783 return Standard_True;
13a22457
S
4784}
4785
a79f67f8 4786static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 4787{
a79f67f8 4788 if (theArgNum < 2)
13a22457 4789 {
23fe70ec 4790 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4791 << theArgs[0] <<"' for more information";
4792 return 1;
13a22457 4793 }
7fd59977 4794
a79f67f8 4795 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4796 TCollection_AsciiString aParseKey;
4797 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4798 {
4799 TCollection_AsciiString anArg (theArgs [anArgIt]);
4800
d45edf24 4801 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
a79f67f8 4802 {
4803 aParseKey = anArg;
4804 aParseKey.Remove (1);
4805 aParseKey.LowerCase();
4806 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4807 continue;
4808 }
13a22457 4809
a79f67f8 4810 if (aParseKey.IsEmpty())
4811 {
4812 continue;
4813 }
4814
4815 aMapOfArgs(aParseKey)->Append (anArg);
4816 }
4817
4818 // Check parameters
4819 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4820 aMapIt.More(); aMapIt.Next())
7fd59977 4821 {
a79f67f8 4822 const TCollection_AsciiString& aKey = aMapIt.Key();
4823 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4824
4825 // Bool key, without arguments
4826 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4827 && anArgs->IsEmpty())
4828 {
4829 continue;
4830 }
4831
4832 // One argument
4833 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4834 && anArgs->Length() == 1)
4835 {
4836 continue;
4837 }
4838
4839 // On/off arguments
4840 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4841 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 4842 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4843 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 4844 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4845 {
4846 continue;
4847 }
4848
4849 // One string argument
4850 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4851 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
d45edf24 4852 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
a79f67f8 4853 {
4854 continue;
4855 }
4856
4857 // One integer argument
4858 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4859 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4860 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4861 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4862 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4863 {
4864 continue;
4865 }
4866
4867 // One real argument
4868 if ( aKey.IsEqual ("arrowlength")
d45edf24 4869 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
a79f67f8 4870 {
4871 continue;
4872 }
4873
4874 // Two string arguments
4875 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
d45edf24 4876 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
13a22457 4877 {
a79f67f8 4878 continue;
13a22457 4879 }
a79f67f8 4880
4881 TCollection_AsciiString aLowerKey;
4882 aLowerKey = "-";
4883 aLowerKey += aKey;
4884 aLowerKey.LowerCase();
23fe70ec 4885 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4886 << "Type help for more information";
a79f67f8 4887 return 1;
7fd59977 4888 }
4889
a79f67f8 4890 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4891 if (anAISContext.IsNull())
4892 {
23fe70ec 4893 Message::SendFail ("Error: no active viewer");
a79f67f8 4894 return 1;
4895 }
7fd59977 4896
a79f67f8 4897 Standard_Boolean toDisplay = Standard_True;
4898 Quantity_Color aColor;
4899 Graphic3d_GraduatedTrihedron aTrihedronData;
4900 // Process parameters
4901 Handle(TColStd_HSequenceOfAsciiString) aValues;
4902 if (aMapOfArgs.Find ("off", aValues))
7fd59977 4903 {
a79f67f8 4904 toDisplay = Standard_False;
4905 }
13a22457 4906
a79f67f8 4907 // AXES NAMES
4908 if (aMapOfArgs.Find ("xname", aValues))
4909 {
4910 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4911 }
4912 if (aMapOfArgs.Find ("yname", aValues))
4913 {
4914 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4915 }
4916 if (aMapOfArgs.Find ("zname", aValues))
4917 {
4918 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4919 }
4920 if (aMapOfArgs.Find ("xdrawname", aValues))
4921 {
536d98e2 4922 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4923 }
4924 if (aMapOfArgs.Find ("ydrawname", aValues))
4925 {
536d98e2 4926 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4927 }
4928 if (aMapOfArgs.Find ("zdrawname", aValues))
4929 {
536d98e2 4930 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4931 }
4932 if (aMapOfArgs.Find ("xnameoffset", aValues))
4933 {
4934 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4935 }
4936 if (aMapOfArgs.Find ("ynameoffset", aValues))
4937 {
4938 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4939 }
4940 if (aMapOfArgs.Find ("znameoffset", aValues))
4941 {
4942 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4943 }
13a22457 4944
a79f67f8 4945 // COLORS
4946 if (aMapOfArgs.Find ("xnamecolor", aValues))
4947 {
4948 if (!GetColor (aValues->Value(1), aColor))
13a22457 4949 {
23fe70ec 4950 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
a79f67f8 4951 return 1;
13a22457 4952 }
a79f67f8 4953 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4954 }
4955 if (aMapOfArgs.Find ("ynamecolor", aValues))
4956 {
4957 if (!GetColor (aValues->Value(1), aColor))
13a22457 4958 {
23fe70ec 4959 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
a79f67f8 4960 return 1;
4961 }
4962 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4963 }
4964 if (aMapOfArgs.Find ("znamecolor", aValues))
4965 {
4966 if (!GetColor (aValues->Value(1), aColor))
4967 {
23fe70ec 4968 Message::SendFail ("Syntax error: -znamecolor wrong color name");
a79f67f8 4969 return 1;
4970 }
4971 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4972 }
4973 if (aMapOfArgs.Find ("xcolor", aValues))
4974 {
4975 if (!GetColor (aValues->Value(1), aColor))
4976 {
23fe70ec 4977 Message::SendFail ("Syntax error: -xcolor wrong color name");
a79f67f8 4978 return 1;
4979 }
4980 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4981 }
4982 if (aMapOfArgs.Find ("ycolor", aValues))
4983 {
4984 if (!GetColor (aValues->Value(1), aColor))
4985 {
23fe70ec 4986 Message::SendFail ("Syntax error: -ycolor wrong color name");
a79f67f8 4987 return 1;
4988 }
4989 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4990 }
4991 if (aMapOfArgs.Find ("zcolor", aValues))
4992 {
4993 if (!GetColor (aValues->Value(1), aColor))
4994 {
23fe70ec 4995 Message::SendFail ("Syntax error: -zcolor wrong color name");
a79f67f8 4996 return 1;
4997 }
4998 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4999 }
5000
5001 // TICKMARKS
5002 if (aMapOfArgs.Find ("xticks", aValues))
5003 {
536d98e2 5004 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5005 }
5006 if (aMapOfArgs.Find ("yticks", aValues))
5007 {
536d98e2 5008 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5009 }
5010 if (aMapOfArgs.Find ("zticks", aValues))
5011 {
536d98e2 5012 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5013 }
5014 if (aMapOfArgs.Find ("xticklength", aValues))
5015 {
536d98e2 5016 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5017 }
5018 if (aMapOfArgs.Find ("yticklength", aValues))
5019 {
536d98e2 5020 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5021 }
5022 if (aMapOfArgs.Find ("zticklength", aValues))
5023 {
536d98e2 5024 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5025 }
5026 if (aMapOfArgs.Find ("xdrawticks", aValues))
5027 {
536d98e2 5028 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5029 }
5030 if (aMapOfArgs.Find ("ydrawticks", aValues))
5031 {
536d98e2 5032 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5033 }
5034 if (aMapOfArgs.Find ("zdrawticks", aValues))
5035 {
536d98e2 5036 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5037 }
5038
5039 // VALUES
5040 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5041 {
536d98e2 5042 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5043 }
5044 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5045 {
536d98e2 5046 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5047 }
5048 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5049 {
536d98e2 5050 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5051 }
5052 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5053 {
5054 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5055 }
5056 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5057 {
5058 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5059 }
5060 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5061 {
5062 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5063 }
5064
5065 // ARROWS
5066 if (aMapOfArgs.Find ("arrowlength", aValues))
5067 {
536d98e2 5068 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5069 }
5070
5071 // FONTS
5072 if (aMapOfArgs.Find ("namefont", aValues))
5073 {
5074 aTrihedronData.SetNamesFont (aValues->Value(1));
5075 }
5076 if (aMapOfArgs.Find ("valuesfont", aValues))
5077 {
5078 aTrihedronData.SetValuesFont (aValues->Value(1));
5079 }
5080
536d98e2 5081 if (aMapOfArgs.Find ("drawgrid", aValues))
5082 {
5083 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5084 }
5085 if (aMapOfArgs.Find ("drawaxes", aValues))
5086 {
5087 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5088 }
5089
a79f67f8 5090 // The final step: display of erase trihedron
5091 if (toDisplay)
5092 {
5093 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5094 }
7fd59977 5095 else
a79f67f8 5096 {
5097 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5098 }
7fd59977 5099
5100 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5101 ViewerTest::CurrentView()->Redraw();
13a22457 5102
7fd59977 5103 return 0;
5104}
5105
3bffef55 5106//==============================================================================
5107//function : VTile
5108//purpose :
5109//==============================================================================
5110static int VTile (Draw_Interpretor& theDI,
5111 Standard_Integer theArgNb,
5112 const char** theArgVec)
5113{
5114 Handle(V3d_View) aView = ViewerTest::CurrentView();
5115 if (aView.IsNull())
5116 {
23fe70ec 5117 Message::SendFail ("Error: no active viewer");
3bffef55 5118 return 1;
5119 }
5120
5121 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5122 if (theArgNb < 2)
5123 {
5124 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5125 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5126 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5127 return 0;
5128 }
5129
5130 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5131 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5132 {
5133 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5134 anArg.LowerCase();
5135 if (anArg == "-lowerleft"
5136 || anArg == "-upperleft")
5137 {
5138 if (anArgIter + 3 < theArgNb)
5139 {
23fe70ec 5140 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5141 return 1;
5142 }
5143 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5144 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5145 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5146 }
5147 else if (anArg == "-total"
5148 || anArg == "-totalsize"
5149 || anArg == "-viewsize")
5150 {
5151 if (anArgIter + 3 < theArgNb)
5152 {
23fe70ec 5153 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5154 return 1;
5155 }
5156 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5157 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5158 if (aTile.TotalSize.x() < 1
5159 || aTile.TotalSize.y() < 1)
5160 {
23fe70ec 5161 Message::SendFail ("Error: total size is incorrect");
3bffef55 5162 return 1;
5163 }
5164 }
5165 else if (anArg == "-tilesize")
5166 {
5167 if (anArgIter + 3 < theArgNb)
5168 {
23fe70ec 5169 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5170 return 1;
5171 }
5172
5173 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5174 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5175 if (aTile.TileSize.x() < 1
5176 || aTile.TileSize.y() < 1)
5177 {
23fe70ec 5178 Message::SendFail ("Error: tile size is incorrect");
3bffef55 5179 return 1;
5180 }
5181 }
5182 else if (anArg == "-unset")
5183 {
5184 aView->Camera()->SetTile (Graphic3d_CameraTile());
5185 aView->Redraw();
5186 return 0;
5187 }
5188 }
5189
5190 if (aTile.TileSize.x() < 1
5191 || aTile.TileSize.y() < 1)
5192 {
23fe70ec 5193 Message::SendFail ("Error: tile size is undefined");
3bffef55 5194 return 1;
5195 }
5196 else if (aTile.TotalSize.x() < 1
5197 || aTile.TotalSize.y() < 1)
5198 {
23fe70ec 5199 Message::SendFail ("Error: total size is undefined");
3bffef55 5200 return 1;
5201 }
5202
5203 aView->Camera()->SetTile (aTile);
5204 aView->Redraw();
5205 return 0;
5206}
5207
7c3ef2f7 5208//! Format ZLayer ID.
5209inline const char* formZLayerId (const Standard_Integer theLayerId)
5210{
5211 switch (theLayerId)
5212 {
5213 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5214 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5215 case Graphic3d_ZLayerId_Top: return "[TOP]";
5216 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5217 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5218 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5219 }
5220 return "";
5221}
5222
5223//! Print the ZLayer information.
5224inline void printZLayerInfo (Draw_Interpretor& theDI,
5225 const Graphic3d_ZLayerSettings& theLayer)
5226{
5227 if (!theLayer.Name().IsEmpty())
5228 {
5229 theDI << " Name: " << theLayer.Name() << "\n";
5230 }
5231 if (theLayer.IsImmediate())
5232 {
5233 theDI << " Immediate: TRUE\n";
5234 }
5235 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5236 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5237 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5238 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5239 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5240 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5241 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5242 {
5243 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5244 }
5245}
5246
59f45b7c 5247//==============================================================================
5248//function : VZLayer
5249//purpose : Test z layer operations for v3d viewer
5250//==============================================================================
7c3ef2f7 5251static int VZLayer (Draw_Interpretor& theDI,
5252 Standard_Integer theArgNb,
5253 const char** theArgVec)
59f45b7c 5254{
7c3ef2f7 5255 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5256 if (aContextAIS.IsNull())
5257 {
23fe70ec 5258 Message::SendFail ("Error: no active viewer");
59f45b7c 5259 return 1;
5260 }
5261
5262 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5263 if (theArgNb < 2)
59f45b7c 5264 {
7c3ef2f7 5265 TColStd_SequenceOfInteger aLayers;
5266 aViewer->GetAllZLayers (aLayers);
5267 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5268 {
5269 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5270 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5271 printZLayerInfo (theDI, aSettings);
5272 }
95bdefb2 5273 return 0;
59f45b7c 5274 }
5275
7c3ef2f7 5276 Standard_Integer anArgIter = 1;
5277 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5278 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5279 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5280 {
7c3ef2f7 5281 ++anArgIter;
5282 }
59f45b7c 5283
7c3ef2f7 5284 {
55c8f0f7
BB
5285 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5286 if (aFirstArg.IsIntegerValue())
c5751993 5287 {
7c3ef2f7 5288 ++anArgIter;
55c8f0f7 5289 aLayerId = aFirstArg.IntegerValue();
c5751993 5290 }
7c3ef2f7 5291 else
c5751993 5292 {
55c8f0f7 5293 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5294 {
55c8f0f7 5295 ++anArgIter;
7c3ef2f7 5296 }
c5751993 5297 }
7c3ef2f7 5298 }
c5751993 5299
1c728f2d 5300 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
7c3ef2f7 5301 for (; anArgIter < theArgNb; ++anArgIter)
5302 {
5303 // perform operation
5304 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5305 anArg.LowerCase();
5306 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5307 {
7c3ef2f7 5308 //
c5751993 5309 }
7c3ef2f7 5310 else if (anArg == "-add"
5311 || anArg == "add")
c5751993 5312 {
7c3ef2f7 5313 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5314 if (!aViewer->AddZLayer (aLayerId))
5315 {
23fe70ec 5316 Message::SendFail ("Error: can not add a new z layer");
7c3ef2f7 5317 return 0;
5318 }
5319
5320 theDI << aLayerId;
c5751993 5321 }
1c728f2d 5322 else if (anArg == "-insertbefore"
5323 && anArgIter + 1 < theArgNb
5324 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5325 {
5326 ++anArgIter;
5327 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5328 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5329 {
23fe70ec 5330 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5331 return 0;
5332 }
5333
5334 theDI << aLayerId;
5335 }
5336 else if (anArg == "-insertafter"
5337 && anArgIter + 1 < theArgNb
5338 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5339 {
5340 ++anArgIter;
5341 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5342 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5343 {
23fe70ec 5344 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5345 return 0;
5346 }
5347
5348 theDI << aLayerId;
5349 }
7c3ef2f7 5350 else if (anArg == "-del"
5351 || anArg == "-delete"
5352 || anArg == "del")
c5751993 5353 {
7c3ef2f7 5354 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5355 {
5356 if (++anArgIter >= theArgNb)
5357 {
23fe70ec 5358 Message::SendFail ("Syntax error: id of z layer to remove is missing");
7c3ef2f7 5359 return 1;
5360 }
5361
5362 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5363 }
5364
5365 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5366 || aLayerId == Graphic3d_ZLayerId_Default
5367 || aLayerId == Graphic3d_ZLayerId_Top
5368 || aLayerId == Graphic3d_ZLayerId_Topmost
5369 || aLayerId == Graphic3d_ZLayerId_TopOSD
5370 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5371 {
23fe70ec 5372 Message::SendFail ("Syntax error: standard Z layer can not be removed");
7c3ef2f7 5373 return 1;
5374 }
5375
5376 // move all object displayed in removing layer to default layer
5377 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5378 anObjIter.More(); anObjIter.Next())
5379 {
8f521168 5380 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5381 if (aPrs.IsNull()
5382 || aPrs->ZLayer() != aLayerId)
5383 {
5384 continue;
5385 }
5386 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5387 }
5388
5389 if (!aViewer->RemoveZLayer (aLayerId))
5390 {
23fe70ec 5391 Message::SendFail ("Z layer can not be removed");
7c3ef2f7 5392 }
5393 else
5394 {
5395 theDI << aLayerId << " ";
5396 }
c5751993 5397 }
7c3ef2f7 5398 else if (anArg == "-get"
5399 || anArg == "get")
c5751993 5400 {
7c3ef2f7 5401 TColStd_SequenceOfInteger aLayers;
5402 aViewer->GetAllZLayers (aLayers);
5403 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5404 {
5405 theDI << aLayeriter.Value() << " ";
5406 }
5407
5408 theDI << "\n";
c5751993 5409 }
7c3ef2f7 5410 else if (anArg == "-name")
c5751993 5411 {
7c3ef2f7 5412 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5413 {
23fe70ec 5414 Message::SendFail ("Syntax error: id of Z layer is missing");
c5751993 5415 return 1;
5416 }
5417
7c3ef2f7 5418 if (++anArgIter >= theArgNb)
5419 {
23fe70ec 5420 Message::SendFail ("Syntax error: name is missing");
7c3ef2f7 5421 return 1;
5422 }
c5751993 5423
7c3ef2f7 5424 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5425 aSettings.SetName (theArgVec[anArgIter]);
5426 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5427 }
7c3ef2f7 5428 else if (anArg == "-origin")
c5751993 5429 {
7c3ef2f7 5430 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5431 {
23fe70ec 5432 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5433 return 1;
5434 }
5435
5436 if (anArgIter + 2 >= theArgNb)
5437 {
23fe70ec 5438 Message::SendFail ("Syntax error: origin coordinates are missing");
7c3ef2f7 5439 return 1;
5440 }
5441
5442 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5443 gp_XYZ anOrigin;
5444 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5445 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5446 anOrigin.SetZ (0.0);
5447 if (anArgIter + 3 < theArgNb)
5448 {
5449 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5450 anArgIter += 3;
5451 }
5452 else
5453 {
5454 anArgIter += 2;
5455 }
5456 aSettings.SetOrigin (anOrigin);
5457 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5458 }
4ecf34cc 5459 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5460 && anArgIter + 1 < theArgNb
5461 && (anArg == "-cullingdistance"
5462 || anArg == "-cullingdist"
5463 || anArg == "-culldistance"
5464 || anArg == "-culldist"
5465 || anArg == "-distcull"
5466 || anArg == "-distculling"
5467 || anArg == "-distanceculling"))
5468 {
5469 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5470 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5471 aSettings.SetCullingDistance (aDist);
5472 aViewer->SetZLayerSettings (aLayerId, aSettings);
5473 }
5474 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5475 && anArgIter + 1 < theArgNb
5476 && (anArg == "-cullingsize"
5477 || anArg == "-cullsize"
5478 || anArg == "-sizecull"
5479 || anArg == "-sizeculling"))
5480 {
5481 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5482 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5483 aSettings.SetCullingSize (aSize);
5484 aViewer->SetZLayerSettings (aLayerId, aSettings);
5485 }
7c3ef2f7 5486 else if (anArg == "-settings"
5487 || anArg == "settings")
c5751993 5488 {
7c3ef2f7 5489 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5490 {
5491 if (++anArgIter >= theArgNb)
5492 {
23fe70ec 5493 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5494 return 1;
5495 }
5496
5497 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5498 }
5499
5500 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5501 printZLayerInfo (theDI, aSettings);
c5751993 5502 }
7c3ef2f7 5503 else if (anArg == "-enable"
5504 || anArg == "enable"
5505 || anArg == "-disable"
5506 || anArg == "disable")
83da37b1 5507 {
7c3ef2f7 5508 const Standard_Boolean toEnable = anArg == "-enable"
5509 || anArg == "enable";
5510 if (++anArgIter >= theArgNb)
5511 {
23fe70ec 5512 Message::SendFail ("Syntax error: option name is missing");
7c3ef2f7 5513 return 1;
5514 }
c5751993 5515
7c3ef2f7 5516 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5517 aSubOp.LowerCase();
5518 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5519 {
5520 if (++anArgIter >= theArgNb)
5521 {
23fe70ec 5522 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5523 return 1;
5524 }
c5751993 5525
7c3ef2f7 5526 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5527 }
c5751993 5528
7c3ef2f7 5529 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5530 if (aSubOp == "depthtest"
5531 || aSubOp == "test")
5532 {
5533 aSettings.SetEnableDepthTest (toEnable);
5534 }
5535 else if (aSubOp == "depthwrite"
5536 || aSubOp == "write")
5537 {
5538 aSettings.SetEnableDepthWrite (toEnable);
5539 }
5540 else if (aSubOp == "depthclear"
5541 || aSubOp == "clear")
5542 {
5543 aSettings.SetClearDepth (toEnable);
5544 }
5545 else if (aSubOp == "depthoffset"
5546 || aSubOp == "offset")
5547 {
5548 Graphic3d_PolygonOffset aParams;
5549 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5550 if (toEnable)
5551 {
5552 if (anArgIter + 2 >= theArgNb)
5553 {
23fe70ec 5554 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
7c3ef2f7 5555 return 1;
5556 }
c5751993 5557
7c3ef2f7 5558 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5559 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5560 }
5561 aSettings.SetPolygonOffset (aParams);
5562 }
5563 else if (aSubOp == "positiveoffset"
5564 || aSubOp == "poffset")
5565 {
5566 if (toEnable)
5567 {
5568 aSettings.SetDepthOffsetPositive();
5569 }
5570 else
5571 {
5572 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5573 }
5574 }
5575 else if (aSubOp == "negativeoffset"
5576 || aSubOp == "noffset")
5577 {
5578 if (toEnable)
5579 {
5580 aSettings.SetDepthOffsetNegative();
5581 }
5582 else
5583 {
5584 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5585 }
5586 }
5587 else if (aSubOp == "textureenv")
5588 {
5589 aSettings.SetEnvironmentTexture (toEnable);
5590 }
1c728f2d 5591 else if (aSubOp == "raytracing")
5592 {
5593 aSettings.SetRaytracable (toEnable);
5594 }
7c3ef2f7 5595
5596 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5597 }
7c3ef2f7 5598 else
83da37b1 5599 {
23fe70ec 5600 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
7c3ef2f7 5601 return 1;
83da37b1 5602 }
59f45b7c 5603 }
5604
5605 return 0;
5606}
5607
c357e426 5608// The interactive presentation of 2d layer item
5609// for "vlayerline" command it provides a presentation of
5610// line with user-defined linewidth, linetype and transparency.
61b0191c 5611class V3d_LineItem : public AIS_InteractiveObject
20637bd2 5612{
5613public:
5614 // CASCADE RTTI
92efcf78 5615 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 5616
20637bd2 5617 // constructor
5618 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5619 Standard_Real X2, Standard_Real Y2,
20637bd2 5620 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5621 Standard_Real theWidth = 0.5,
5622 Standard_Real theTransp = 1.0);
5623
decbff0d 5624private:
61b0191c 5625
decbff0d 5626 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5627 const Handle(Prs3d_Presentation)& thePrs,
5628 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 5629
decbff0d 5630 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5631 const Standard_Integer ) Standard_OVERRIDE
79104795 5632 {}
20637bd2 5633
5634private:
5635
5636 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 5637 Aspect_TypeOfLine myType;
20637bd2 5638 Standard_Real myWidth;
20637bd2 5639};
5640
20637bd2 5641// default constructor for line item
4fe56619 5642V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 5643 Standard_Real X2, Standard_Real Y2,
20637bd2 5644 Aspect_TypeOfLine theType,
5645 Standard_Real theWidth,
5646 Standard_Real theTransp) :
61b0191c 5647 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5648 myType(theType), myWidth(theWidth)
20637bd2 5649{
61b0191c 5650 SetTransparency (1-theTransp);
20637bd2 5651}
5652
5653// render line
decbff0d 5654void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
61b0191c 5655 const Handle(Prs3d_Presentation)& thePresentation,
decbff0d 5656 const Standard_Integer )
20637bd2 5657{
61b0191c 5658 thePresentation->Clear();
ba00aab7 5659 Quantity_Color aColor (Quantity_NOC_RED);
61b0191c 5660 Standard_Integer aWidth, aHeight;
5661 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
d6c48921 5662 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
61b0191c 5663 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5664 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5665 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5666 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5667 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5668 aGroup->AddPrimitiveArray (aPrim);
20637bd2 5669}
5670
5671//=============================================================================
5672//function : VLayerLine
5673//purpose : Draws line in the v3d view layer with given attributes: linetype,
5674// : linewidth, transparency coefficient
5675//============================================================================
5676static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5677{
5678 // get the active view
5679 Handle(V3d_View) aView = ViewerTest::CurrentView();
5680 if (aView.IsNull())
5681 {
5682 di << "Call vinit before!\n";
5683 return 1;
5684 }
5685 else if (argc < 5)
5686 {
5687 di << "Use: " << argv[0];
5688 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5689 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5690 di << " 0 - solid \n";
5691 di << " 1 - dashed \n";
5692 di << " 2 - dot \n";
5693 di << " 3 - dashdot\n";
5694 di << " transparency : { 0.0 - 1.0 } \n";
5695 di << " 0.0 - transparent\n";
5696 di << " 1.0 - visible \n";
5697 return 1;
5698 }
5699
61b0191c 5700 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 5701 // get the input params
91322f44 5702 Standard_Real X1 = Draw::Atof(argv[1]);
5703 Standard_Real Y1 = Draw::Atof(argv[2]);
5704 Standard_Real X2 = Draw::Atof(argv[3]);
5705 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 5706
3a4a3962 5707 Standard_Real aWidth = 0.5;
5708 Standard_Real aTransparency = 1.0;
20637bd2 5709
5710 // has width
5711 if (argc > 5)
91322f44 5712 aWidth = Draw::Atof(argv[5]);
20637bd2 5713
3a4a3962 5714 // select appropriate line type
5715 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5716 if (argc > 6
5717 && !ViewerTest::ParseLineType (argv[6], aLineType))
5718 {
23fe70ec 5719 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
3a4a3962 5720 return 1;
5721 }
20637bd2 5722
5723 // has transparency
5724 if (argc > 7)
5725 {
91322f44 5726 aTransparency = Draw::Atof(argv[7]);
4fe56619 5727 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 5728 aTransparency = 1.0;
5729 }
5730
61b0191c 5731 static Handle (V3d_LineItem) aLine;
5732 if (!aLine.IsNull())
25289ec1 5733 {
0577ae8c 5734 aContext->Erase (aLine, Standard_False);
25289ec1 5735 }
61b0191c 5736 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5737 aLineType, aWidth,
5738 aTransparency);
25289ec1 5739
778cd667 5740 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 5741 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5742 aLine->SetToUpdate();
5743 aContext->Display (aLine, Standard_True);
25289ec1 5744
5745 return 0;
5746}
5747
61b0191c 5748
2bd4c032 5749//==============================================================================
5750//function : VGrid
5751//purpose :
5752//==============================================================================
5753
35e08fe8 5754static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 5755 Standard_Integer theArgNb,
5756 const char** theArgVec)
5757{
2bd4c032 5758 Handle(V3d_View) aView = ViewerTest::CurrentView();
5759 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5760 if (aView.IsNull() || aViewer.IsNull())
5761 {
23fe70ec 5762 Message::SendFail ("Error: no active viewer");
2bd4c032 5763 return 1;
5764 }
5765
5766 Aspect_GridType aType = aViewer->GridType();
5767 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 5768 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5769 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5770 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 5771 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 5772 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 5773 {
79931835 5774 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5775 anArg.LowerCase();
5776 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 5777 {
5778 continue;
5779 }
79931835 5780 else if (anArgIter + 1 < theArgNb
5781 && anArg == "-type")
5782 {
5783 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5784 anArgNext.LowerCase();
5785 if (anArgNext == "r"
5786 || anArgNext == "rect"
5787 || anArgNext == "rectangular")
5788 {
5789 aType = Aspect_GT_Rectangular;
5790 }
5791 else if (anArgNext == "c"
5792 || anArgNext == "circ"
5793 || anArgNext == "circular")
5794 {
5795 aType = Aspect_GT_Circular;
5796 }
5797 else
5798 {
23fe70ec 5799 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5800 return 1;
5801 }
5802 }
5803 else if (anArgIter + 1 < theArgNb
5804 && anArg == "-mode")
5805 {
5806 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5807 anArgNext.LowerCase();
5808 if (anArgNext == "l"
5809 || anArgNext == "line"
5810 || anArgNext == "lines")
5811 {
5812 aMode = Aspect_GDM_Lines;
5813 }
5814 else if (anArgNext == "p"
5815 || anArgNext == "point"
5816 || anArgNext == "points")
5817 {
5818 aMode = Aspect_GDM_Points;
5819 }
5820 else
5821 {
23fe70ec 5822 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5823 return 1;
5824 }
5825 }
5826 else if (anArgIter + 2 < theArgNb
5827 && (anArg == "-origin"
5828 || anArg == "-orig"))
5829 {
5830 hasOrigin = true;
5831 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5832 Draw::Atof (theArgVec[anArgIter + 2]));
5833 anArgIter += 2;
5834 }
5835 else if (anArgIter + 2 < theArgNb
5836 && anArg == "-step")
5837 {
5838 hasStep = true;
5839 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5840 Draw::Atof (theArgVec[anArgIter + 2]));
5841 if (aNewStepXY.x() <= 0.0
5842 || aNewStepXY.y() <= 0.0)
5843 {
23fe70ec 5844 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 5845 return 1;
5846 }
5847 anArgIter += 2;
5848 }
5849 else if (anArgIter + 1 < theArgNb
5850 && (anArg == "-angle"
5851 || anArg == "-rotangle"
5852 || anArg == "-rotationangle"))
5853 {
5854 hasRotAngle = true;
5855 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5856 }
5857 else if (anArgIter + 1 < theArgNb
5858 && (anArg == "-zoffset"
5859 || anArg == "-dz"))
5860 {
5861 hasZOffset = true;
5862 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5863 }
5864 else if (anArgIter + 1 < theArgNb
5865 && anArg == "-radius")
5866 {
5867 hasSize = true;
5868 ++anArgIter;
5869 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5870 if (aNewStepXY.x() <= 0.0)
5871 {
23fe70ec 5872 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
79931835 5873 return 1;
5874 }
5875 }
5876 else if (anArgIter + 2 < theArgNb
5877 && anArg == "-size")
5878 {
5879 hasSize = true;
5880 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5881 Draw::Atof (theArgVec[anArgIter + 2]));
5882 if (aNewStepXY.x() <= 0.0
5883 || aNewStepXY.y() <= 0.0)
5884 {
23fe70ec 5885 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 5886 return 1;
5887 }
5888 anArgIter += 2;
5889 }
5890 else if (anArg == "r"
5891 || anArg == "rect"
5892 || anArg == "rectangular")
2bd4c032 5893 {
5894 aType = Aspect_GT_Rectangular;
5895 }
79931835 5896 else if (anArg == "c"
5897 || anArg == "circ"
5898 || anArg == "circular")
2bd4c032 5899 {
5900 aType = Aspect_GT_Circular;
5901 }
79931835 5902 else if (anArg == "l"
5903 || anArg == "line"
5904 || anArg == "lines")
2bd4c032 5905 {
5906 aMode = Aspect_GDM_Lines;
5907 }
79931835 5908 else if (anArg == "p"
5909 || anArg == "point"
5910 || anArg == "points")
2bd4c032 5911 {
5912 aMode = Aspect_GDM_Points;
5913 }
79931835 5914 else if (anArgIter + 1 >= theArgNb
5915 && anArg == "off")
2bd4c032 5916 {
5917 aViewer->DeactivateGrid();
5918 return 0;
5919 }
5920 else
5921 {
23fe70ec 5922 Message::SendFail() << "Syntax error at '" << anArg << "'";
79931835 5923 return 1;
2bd4c032 5924 }
5925 }
5926
2bd4c032 5927 if (aType == Aspect_GT_Rectangular)
5928 {
79931835 5929 Graphic3d_Vec2d anOrigXY, aStepXY;
5930 Standard_Real aRotAngle = 0.0;
5931 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5932 if (hasOrigin)
5933 {
5934 anOrigXY = aNewOriginXY;
5935 }
5936 if (hasStep)
5937 {
5938 aStepXY = aNewStepXY;
5939 }
5940 if (hasRotAngle)
5941 {
5942 aRotAngle = aNewRotAngle;
5943 }
5944 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5945 if (hasSize || hasZOffset)
2bd4c032 5946 {
79931835 5947 Graphic3d_Vec3d aSize;
5948 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5949 if (hasSize)
5950 {
5951 aSize.x() = aNewSizeXY.x();
5952 aSize.y() = aNewSizeXY.y();
5953 }
5954 if (hasZOffset)
5955 {
5956 aSize.z() = aNewZOffset;
5957 }
5958 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 5959 }
2bd4c032 5960 }
5961 else if (aType == Aspect_GT_Circular)
5962 {
79931835 5963 Graphic3d_Vec2d anOrigXY;
ee2be2a8 5964 Standard_Real aRadiusStep;
2bd4c032 5965 Standard_Integer aDivisionNumber;
79931835 5966 Standard_Real aRotAngle = 0.0;
5967 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5968 if (hasOrigin)
5969 {
5970 anOrigXY = aNewOriginXY;
5971 }
5972 if (hasStep)
5973 {
5974 aRadiusStep = aNewStepXY[0];
5975 aDivisionNumber = (int )aNewStepXY[1];
5976 if (aDivisionNumber < 1)
5977 {
23fe70ec 5978 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
79931835 5979 return 1;
5980 }
5981 }
5982 if (hasRotAngle)
2bd4c032 5983 {
79931835 5984 aRotAngle = aNewRotAngle;
2bd4c032 5985 }
5986
79931835 5987 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5988 if (hasSize || hasZOffset)
5989 {
5990 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5991 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5992 if (hasSize)
5993 {
5994 aRadius = aNewSizeXY.x();
5995 if (aNewSizeXY.y() != 0.0)
5996 {
23fe70ec 5997 Message::SendFail ("Syntax error: circular size should be specified as radius");
79931835 5998 return 1;
5999 }
6000 }
6001 if (hasZOffset)
6002 {
6003 aZOffset = aNewZOffset;
6004 }
6005 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6006 }
2bd4c032 6007 }
79931835 6008 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6009 return 0;
6010}
6011
c40b7d58 6012//==============================================================================
6013//function : VPriviledgedPlane
6014//purpose :
6015//==============================================================================
6016
6017static int VPriviledgedPlane (Draw_Interpretor& theDI,
6018 Standard_Integer theArgNb,
6019 const char** theArgVec)
6020{
6021 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6022 {
23fe70ec 6023 Message::SendFail ("Error: wrong number of arguments! See usage:");
c40b7d58 6024 theDI.PrintHelp (theArgVec[0]);
6025 return 1;
6026 }
6027
6028 // get the active viewer
6029 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6030 if (aViewer.IsNull())
6031 {
23fe70ec 6032 Message::SendFail ("Error: no active viewer");
c40b7d58 6033 return 1;
6034 }
6035
6036 if (theArgNb == 1)
6037 {
6038 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6039 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6040 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6041 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6042 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6043 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6044 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6045 return 0;
6046 }
6047
6048 Standard_Integer anArgIdx = 1;
6049 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6050 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6051 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6052 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6053 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6054 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6055
6056 gp_Ax3 aPriviledgedPlane;
6057 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6058 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6059 if (theArgNb > 7)
6060 {
6061 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6062 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6063 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6064 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6065 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6066 }
6067 else
6068 {
6069 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6070 }
6071
6072 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6073
6074 return 0;
6075}
6076
f25b82d6 6077//==============================================================================
6078//function : VConvert
6079//purpose :
6080//==============================================================================
6081
6082static int VConvert (Draw_Interpretor& theDI,
6083 Standard_Integer theArgNb,
6084 const char** theArgVec)
6085{
6086 // get the active view
6087 Handle(V3d_View) aView = ViewerTest::CurrentView();
6088 if (aView.IsNull())
6089 {
23fe70ec 6090 Message::SendFail ("Error: no active viewer");
f25b82d6 6091 return 1;
6092 }
6093
6094 enum { Model, Ray, View, Window, Grid } aMode = Model;
6095
6096 // access coordinate arguments
6097 TColStd_SequenceOfReal aCoord;
6098 Standard_Integer anArgIdx = 1;
6099 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6100 {
6101 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
d45edf24 6102 if (!anArg.IsRealValue (Standard_True))
f25b82d6 6103 {
6104 break;
6105 }
6106 aCoord.Append (anArg.RealValue());
6107 }
6108
6109 // non-numeric argument too early
6110 if (aCoord.IsEmpty())
6111 {
23fe70ec 6112 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6113 theDI.PrintHelp (theArgVec[0]);
6114 return 1;
6115 }
6116
6117 // collect all other arguments and options
6118 for (; anArgIdx < theArgNb; ++anArgIdx)
6119 {
6120 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6121 anArg.LowerCase();
6122 if (anArg == "window") aMode = Window;
6123 else if (anArg == "view") aMode = View;
6124 else if (anArg == "grid") aMode = Grid;
6125 else if (anArg == "ray") aMode = Ray;
6126 else
6127 {
23fe70ec 6128 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
f25b82d6 6129 theDI.PrintHelp (theArgVec[0]);
6130 return 1;
6131 }
6132 }
6133
6134 // complete input checks
6135 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6136 (aCoord.Length() == 2 && theArgNb > 4) ||
6137 (aCoord.Length() == 3 && theArgNb > 5))
6138 {
23fe70ec 6139 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6140 theDI.PrintHelp (theArgVec[0]);
6141 return 1;
6142 }
6143
6144 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6145 Standard_Integer aXYp[2] = {0, 0};
6146
6147 // convert one-dimensional coordinate
6148 if (aCoord.Length() == 1)
6149 {
6150 switch (aMode)
6151 {
ee2be2a8 6152 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6153 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6154 default:
23fe70ec 6155 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6156 theDI.PrintHelp (theArgVec[0]);
6157 return 1;
6158 }
6159 }
6160
6161 // convert 2D coordinates from projection or view reference space
6162 if (aCoord.Length() == 2)
6163 {
6164 switch (aMode)
6165 {
6166 case Model :
6167 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6168 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6169 return 0;
6170
6171 case View :
6172 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6173 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6174 return 0;
6175
6176 case Window :
ee2be2a8 6177 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6178 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6179 return 0;
6180
6181 case Grid :
6182 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6183 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6184 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6185 return 0;
6186
6187 case Ray :
6188 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6189 (Standard_Integer) aCoord (2),
6190 aXYZ[0], aXYZ[1], aXYZ[2],
6191 aXYZ[3], aXYZ[4], aXYZ[5]);
6192 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6193 return 0;
6194
6195 default:
23fe70ec 6196 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6197 theDI.PrintHelp (theArgVec[0]);
6198 return 1;
6199 }
6200 }
6201
6202 // convert 3D coordinates from view reference space
6203 else if (aCoord.Length() == 3)
6204 {
6205 switch (aMode)
6206 {
6207 case Window :
6208 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6209 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6210 return 0;
6211
6212 case Grid :
6213 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6214 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6215 return 0;
6216
6217 default:
23fe70ec 6218 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6219 theDI.PrintHelp (theArgVec[0]);
6220 return 1;
6221 }
6222 }
6223
6224 return 0;
6225}
6226
208e6839 6227//==============================================================================
6228//function : VFps
6229//purpose :
6230//==============================================================================
6231
6232static int VFps (Draw_Interpretor& theDI,
6233 Standard_Integer theArgNb,
6234 const char** theArgVec)
6235{
6236 // get the active view
6237 Handle(V3d_View) aView = ViewerTest::CurrentView();
6238 if (aView.IsNull())
6239 {
23fe70ec 6240 Message::SendFail ("Error: no active viewer");
208e6839 6241 return 1;
6242 }
6243
e084dbbc 6244 Standard_Integer aFramesNb = -1;
6245 Standard_Real aDuration = -1.0;
6246 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6247 {
e084dbbc 6248 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6249 anArg.LowerCase();
6250 if (aDuration < 0.0
6251 && anArgIter + 1 < theArgNb
6252 && (anArg == "-duration"
6253 || anArg == "-dur"
6254 || anArg == "-time"))
6255 {
6256 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6257 }
6258 else if (aFramesNb < 0
6259 && anArg.IsIntegerValue())
6260 {
6261 aFramesNb = anArg.IntegerValue();
6262 if (aFramesNb <= 0)
6263 {
23fe70ec 6264 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6265 return 1;
6266 }
6267 }
6268 else
6269 {
23fe70ec 6270 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6271 return 1;
6272 }
6273 }
6274 if (aFramesNb < 0 && aDuration < 0.0)
6275 {
6276 aFramesNb = 100;
208e6839 6277 }
6278
6279 // the time is meaningless for first call
6280 // due to async OpenGl rendering
6281 aView->Redraw();
6282
6283 // redraw view in loop to estimate average values
6284 OSD_Timer aTimer;
6285 aTimer.Start();
e084dbbc 6286 Standard_Integer aFrameIter = 1;
6287 for (;; ++aFrameIter)
208e6839 6288 {
6289 aView->Redraw();
e084dbbc 6290 if ((aFramesNb > 0
6291 && aFrameIter >= aFramesNb)
6292 || (aDuration > 0.0
6293 && aTimer.ElapsedTime() >= aDuration))
6294 {
6295 break;
6296 }
208e6839 6297 }
6298 aTimer.Stop();
6299 Standard_Real aCpu;
6300 const Standard_Real aTime = aTimer.ElapsedTime();
6301 aTimer.OSD_Chronometer::Show (aCpu);
6302
e084dbbc 6303 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6304 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6305
6306 // return statistics
6307 theDI << "FPS: " << aFpsAver << "\n"
6308 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6309
8c820969 6310 // compute additional statistics in ray-tracing mode
e084dbbc 6311 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6312 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6313 {
e084dbbc 6314 Graphic3d_Vec2i aWinSize (0, 0);
6315 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6316
6317 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6318 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6319 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6320 }
6321
208e6839 6322 return 0;
6323}
6324
a577aaab 6325
f0430952 6326//==============================================================================
6327//function : VMemGpu
6328//purpose :
6329//==============================================================================
6330
6331static int VMemGpu (Draw_Interpretor& theDI,
6332 Standard_Integer theArgNb,
6333 const char** theArgVec)
6334{
6335 // get the context
6336 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6337 if (aContextAIS.IsNull())
6338 {
23fe70ec 6339 Message::SendFail ("Error: no active viewer");
f0430952 6340 return 1;
6341 }
6342
dc3fe572 6343 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 6344 if (aDriver.IsNull())
6345 {
23fe70ec 6346 Message::SendFail ("Error: graphic driver not available");
f0430952 6347 return 1;
6348 }
6349
6350 Standard_Size aFreeBytes = 0;
6351 TCollection_AsciiString anInfo;
6352 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
6353 {
23fe70ec 6354 Message::SendFail ("Error: information not available");
f0430952 6355 return 1;
6356 }
6357
6358 if (theArgNb > 1 && *theArgVec[1] == 'f')
6359 {
6360 theDI << Standard_Real (aFreeBytes);
6361 }
6362 else
6363 {
6364 theDI << anInfo;
6365 }
6366
6367 return 0;
6368}
6369
85e096c3 6370// ==============================================================================
6371// function : VReadPixel
6372// purpose :
6373// ==============================================================================
6374static int VReadPixel (Draw_Interpretor& theDI,
6375 Standard_Integer theArgNb,
6376 const char** theArgVec)
6377{
6378 // get the active view
6379 Handle(V3d_View) aView = ViewerTest::CurrentView();
6380 if (aView.IsNull())
6381 {
23fe70ec 6382 Message::SendFail ("Error: no active viewer");
85e096c3 6383 return 1;
6384 }
6385 else if (theArgNb < 3)
6386 {
23fe70ec 6387 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
6388 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
85e096c3 6389 return 1;
6390 }
6391
dc858f4c 6392 Image_Format aFormat = Image_Format_RGBA;
6393 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 6394
85e096c3 6395 Standard_Integer aWidth, aHeight;
6396 aView->Window()->Size (aWidth, aHeight);
91322f44 6397 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
6398 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 6399 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
6400 {
23fe70ec 6401 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
85e096c3 6402 return 1;
6403 }
6404
ba00aab7 6405 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
85e096c3 6406 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
6407 {
dc858f4c 6408 TCollection_AsciiString aParam (theArgVec[anIter]);
6409 aParam.LowerCase();
55c8f0f7 6410 if (aParam == "-rgb"
ba00aab7 6411 || aParam == "rgb"
6412 || aParam == "-srgb"
6413 || aParam == "srgb")
85e096c3 6414 {
dc858f4c 6415 aFormat = Image_Format_RGB;
692613e5 6416 aBufferType = Graphic3d_BT_RGB;
ba00aab7 6417 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
85e096c3 6418 }
55c8f0f7
BB
6419 else if (aParam == "-hls"
6420 || aParam == "hls")
85e096c3 6421 {
dc858f4c 6422 aFormat = Image_Format_RGB;
692613e5 6423 aBufferType = Graphic3d_BT_RGB;
85e096c3 6424 toShowHls = Standard_True;
6425 }
55c8f0f7
BB
6426 else if (aParam == "-rgbf"
6427 || aParam == "rgbf")
85e096c3 6428 {
dc858f4c 6429 aFormat = Image_Format_RGBF;
692613e5 6430 aBufferType = Graphic3d_BT_RGB;
85e096c3 6431 }
55c8f0f7 6432 else if (aParam == "-rgba"
ba00aab7 6433 || aParam == "rgba"
6434 || aParam == "-srgba"
6435 || aParam == "srgba")
85e096c3 6436 {
dc858f4c 6437 aFormat = Image_Format_RGBA;
692613e5 6438 aBufferType = Graphic3d_BT_RGBA;
ba00aab7 6439 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
85e096c3 6440 }
55c8f0f7
BB
6441 else if (aParam == "-rgbaf"
6442 || aParam == "rgbaf")
85e096c3 6443 {
dc858f4c 6444 aFormat = Image_Format_RGBAF;
692613e5 6445 aBufferType = Graphic3d_BT_RGBA;
85e096c3 6446 }
55c8f0f7
BB
6447 else if (aParam == "-depth"
6448 || aParam == "depth")
85e096c3 6449 {
dc858f4c 6450 aFormat = Image_Format_GrayF;
692613e5 6451 aBufferType = Graphic3d_BT_Depth;
85e096c3 6452 }
55c8f0f7
BB
6453 else if (aParam == "-name"
6454 || aParam == "name")
85e096c3 6455 {
6456 toShowName = Standard_True;
6457 }
9196ea9d 6458 else if (aParam == "-hex"
6459 || aParam == "hex")
6460 {
6461 toShowHex = Standard_True;
6462 }
55c8f0f7
BB
6463 else
6464 {
23fe70ec 6465 Message::SendFail() << "Syntax error at '" << aParam << "'";
9196ea9d 6466 return 1;
55c8f0f7 6467 }
85e096c3 6468 }
6469
692613e5 6470 Image_PixMap anImage;
6471 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
6472 {
23fe70ec 6473 Message::SendFail ("Error: image allocation failed");
692613e5 6474 return 1;
6475 }
6476 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 6477 {
23fe70ec 6478 Message::SendFail ("Error: image dump failed");
85e096c3 6479 return 1;
6480 }
6481
68beaa3c 6482 // redirect possible warning messages that could have been added by ToPixMap
6483 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
6484 // contaminate result of the command
6485 Standard_CString aWarnLog = theDI.Result();
6486 if (aWarnLog != NULL && aWarnLog[0] != '\0')
6487 {
6488 std::cout << aWarnLog << std::endl;
6489 }
6490 theDI.Reset();
6491
ba00aab7 6492 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
85e096c3 6493 if (toShowName)
6494 {
692613e5 6495 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 6496 {
e958a649 6497 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 6498 }
6499 else
6500 {
e958a649 6501 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 6502 }
6503 }
9196ea9d 6504 else if (toShowHex)
6505 {
6506 if (aBufferType == Graphic3d_BT_RGBA)
6507 {
6508 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
6509 }
6510 else
6511 {
6512 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
6513 }
6514 }
85e096c3 6515 else
6516 {
6517 switch (aBufferType)
6518 {
6519 default:
692613e5 6520 case Graphic3d_BT_RGB:
85e096c3 6521 {
6522 if (toShowHls)
6523 {
e958a649 6524 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 6525 }
ba00aab7 6526 else if (toShow_sRGB)
6527 {
6528 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
6529 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
6530 }
85e096c3 6531 else
6532 {
e958a649 6533 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 6534 }
6535 break;
6536 }
692613e5 6537 case Graphic3d_BT_RGBA:
85e096c3 6538 {
ba00aab7 6539 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
6540 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
85e096c3 6541 break;
6542 }
692613e5 6543 case Graphic3d_BT_Depth:
85e096c3 6544 {
e958a649 6545 theDI << aColor.GetRGB().Red();
85e096c3 6546 break;
6547 }
6548 }
6549 }
6550
6551 return 0;
6552}
6553
fd3f6bd0 6554//! Auxiliary presentation for an image plane.
6555class ViewerTest_ImagePrs : public AIS_InteractiveObject
6556{
6557public:
6558 //! Main constructor.
6559 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
6560 const Standard_Real theWidth,
6561 const Standard_Real theHeight,
6562 const TCollection_AsciiString& theLabel)
6563 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
6564 {
6565 SetDisplayMode (0);
6566 SetHilightMode (1);
6567 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
6568 {
6569 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6570 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
6571 Graphic3d_MaterialAspect aMat;
6572 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
61168418 6573 aMat.SetAmbientColor (Quantity_NOC_BLACK);
6574 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
6575 aMat.SetSpecularColor (Quantity_NOC_BLACK);
6576 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
fd3f6bd0 6577 aFillAspect->SetFrontMaterial (aMat);
6578 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
6579 aFillAspect->SetTextureMapOn();
6580 }
6581 {
6582 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
6583 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
6584 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
6585 myDrawer->SetTextAspect (aTextAspect);
6586 }
6587 {
6588 const gp_Dir aNorm (0.0, 0.0, 1.0);
6589 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
6590 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
6591 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
6592 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
6593 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
6594 myTris->AddEdge (1);
6595 myTris->AddEdge (2);
6596 myTris->AddEdge (3);
6597 myTris->AddEdge (3);
6598 myTris->AddEdge (2);
6599 myTris->AddEdge (4);
6600
6601 myRect = new Graphic3d_ArrayOfPolylines (4);
6602 myRect->AddVertex (myTris->Vertice (1));
6603 myRect->AddVertex (myTris->Vertice (3));
6604 myRect->AddVertex (myTris->Vertice (4));
6605 myRect->AddVertex (myTris->Vertice (2));
6606 }
6607 }
6608
6609 //! Returns TRUE for accepted display modes.
6610 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
6611
6612 //! Compute presentation.
decbff0d 6613 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
6614 const Handle(Prs3d_Presentation)& thePrs,
6615 const Standard_Integer theMode) Standard_OVERRIDE
fd3f6bd0 6616 {
6617 switch (theMode)
6618 {
6619 case 0:
6620 {
6621 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6622 aGroup->AddPrimitiveArray (myTris);
6623 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6624 aGroup->AddPrimitiveArray (myRect);
6625 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6626 return;
6627 }
6628 case 1:
6629 {
6630 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6631 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6632 aGroup->AddPrimitiveArray (myRect);
6633 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6634 return;
6635 }
6636 }
6637 }
6638
6639 //! Compute selection.
6640 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6641 {
6642 if (theMode == 0)
6643 {
6644 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6645 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6646 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6647 theSel->Add (aSensitive);
6648 }
6649 }
6650
6651private:
6652 Handle(Graphic3d_ArrayOfTriangles) myTris;
6653 Handle(Graphic3d_ArrayOfPolylines) myRect;
6654 TCollection_AsciiString myLabel;
6655 Standard_Real myWidth;
6656 Standard_Real myHeight;
6657};
6658
692613e5 6659//==============================================================================
6660//function : VDiffImage
6661//purpose : The draw-command compares two images.
6662//==============================================================================
6663
6664static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6665{
fd3f6bd0 6666 if (theArgNb < 3)
692613e5 6667 {
23fe70ec 6668 Message::SendFail ("Syntax error: not enough arguments");
692613e5 6669 return 1;
6670 }
6671
fd3f6bd0 6672 Standard_Integer anArgIter = 1;
6673 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
6674 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
6675 TCollection_AsciiString aDiffImagePath;
6676 Standard_Real aTolColor = -1.0;
6677 Standard_Integer toBlackWhite = -1;
6678 Standard_Integer isBorderFilterOn = -1;
6679 Standard_Boolean isOldSyntax = Standard_False;
6680 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
6681 for (; anArgIter < theArgNb; ++anArgIter)
6682 {
6683 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6684 anArg.LowerCase();
6685 if (anArgIter + 1 < theArgNb
6686 && (anArg == "-toleranceofcolor"
6687 || anArg == "-tolerancecolor"
6688 || anArg == "-tolerance"
6689 || anArg == "-toler"))
6690 {
6691 aTolColor = Atof (theArgVec[++anArgIter]);
6692 if (aTolColor < 0.0 || aTolColor > 1.0)
6693 {
23fe70ec 6694 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 6695 return 1;
6696 }
6697 }
6698 else if (anArg == "-blackwhite")
6699 {
6700 Standard_Boolean toEnable = Standard_True;
6701 if (anArgIter + 1 < theArgNb
dae2a922 6702 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 6703 {
6704 ++anArgIter;
6705 }
6706 toBlackWhite = toEnable ? 1 : 0;
6707 }
6708 else if (anArg == "-borderfilter")
6709 {
6710 Standard_Boolean toEnable = Standard_True;
6711 if (anArgIter + 1 < theArgNb
dae2a922 6712 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 6713 {
6714 ++anArgIter;
6715 }
6716 isBorderFilterOn = toEnable ? 1 : 0;
6717 }
6718 else if (anArg == "-exitonclose")
6719 {
49582f9d 6720 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 6721 if (anArgIter + 1 < theArgNb
dae2a922 6722 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 6723 {
6724 ++anArgIter;
6725 }
6726 }
6727 else if (anArg == "-closeonescape"
6728 || anArg == "-closeonesc")
6729 {
49582f9d 6730 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 6731 if (anArgIter + 1 < theArgNb
dae2a922 6732 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 6733 {
6734 ++anArgIter;
6735 }
6736 }
6737 else if (anArgIter + 3 < theArgNb
6738 && anArg == "-display")
6739 {
6740 aViewName = theArgVec[++anArgIter];
6741 aPrsNameRef = theArgVec[++anArgIter];
6742 aPrsNameNew = theArgVec[++anArgIter];
6743 if (anArgIter + 1 < theArgNb
6744 && *theArgVec[anArgIter + 1] != '-')
6745 {
6746 aPrsNameDiff = theArgVec[++anArgIter];
6747 }
6748 }
6749 else if (aTolColor < 0.0
d45edf24 6750 && anArg.IsRealValue (Standard_True))
fd3f6bd0 6751 {
6752 isOldSyntax = Standard_True;
6753 aTolColor = anArg.RealValue();
6754 if (aTolColor < 0.0 || aTolColor > 1.0)
6755 {
23fe70ec 6756 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 6757 return 1;
6758 }
6759 }
6760 else if (isOldSyntax
6761 && toBlackWhite == -1
6762 && (anArg == "0" || anArg == "1"))
6763 {
6764 toBlackWhite = anArg == "1" ? 1 : 0;
6765 }
6766 else if (isOldSyntax
6767 && isBorderFilterOn == -1
6768 && (anArg == "0" || anArg == "1"))
6769 {
6770 isBorderFilterOn = anArg == "1" ? 1 : 0;
6771 }
6772 else if (aDiffImagePath.IsEmpty())
6773 {
6774 aDiffImagePath = theArgVec[anArgIter];
6775 }
6776 else
6777 {
23fe70ec 6778 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fd3f6bd0 6779 return 1;
6780 }
6781 }
692613e5 6782
fd3f6bd0 6783 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6784 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6785 if (!anImgRef->Load (anImgPathRef))
6786 {
23fe70ec 6787 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
fd3f6bd0 6788 return 1;
6789 }
6790 if (!anImgNew->Load (anImgPathNew))
6791 {
23fe70ec 6792 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
fd3f6bd0 6793 return 1;
6794 }
692613e5 6795
6796 // compare the images
6797 Image_Diff aComparer;
fd3f6bd0 6798 Standard_Integer aDiffColorsNb = -1;
6799 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 6800 {
fd3f6bd0 6801 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6802 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6803 aDiffColorsNb = aComparer.Compare();
6804 theDI << aDiffColorsNb << "\n";
692613e5 6805 }
6806
692613e5 6807 // save image of difference
fd3f6bd0 6808 Handle(Image_AlienPixMap) aDiff;
6809 if (aDiffColorsNb > 0
6810 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6811 {
6812 aDiff = new Image_AlienPixMap();
6813 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6814 {
23fe70ec 6815 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
fd3f6bd0 6816 return 1;
6817 }
6818 aComparer.SaveDiffImage (*aDiff);
6819 if (!aDiffImagePath.IsEmpty()
6820 && !aDiff->Save (aDiffImagePath))
6821 {
23fe70ec 6822 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
fd3f6bd0 6823 return 1;
6824 }
6825 }
6826
6827 if (aViewName.IsEmpty())
6828 {
6829 return 0;
6830 }
6831
6832 ViewerTest_Names aViewNames (aViewName);
6833 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6834 {
6835 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6836 theDI.Eval (aCommand.ToCString());
6837 }
6838
6839 Standard_Integer aPxLeft = 0;
6840 Standard_Integer aPxTop = 0;
6841 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
6842 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6843 ? int(anImgRef->SizeY() * 2)
6844 : int(anImgRef->SizeY());
6845 TCollection_AsciiString aDisplayName;
9e04ccdc 6846 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
6847 aViewName, aDisplayName);
fd3f6bd0 6848
6849 Standard_Real aRatio = anImgRef->Ratio();
6850 Standard_Real aSizeX = 1.0;
6851 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 6852 {
fd3f6bd0 6853 OSD_Path aPath (anImgPathRef);
6854 TCollection_AsciiString aLabelRef;
6855 if (!aPath.Name().IsEmpty())
6856 {
6857 aLabelRef = aPath.Name() + aPath.Extension();
6858 }
6859 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6860
6861 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6862 gp_Trsf aTrsfRef;
6863 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6864 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6865 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 6866 }
fd3f6bd0 6867 {
6868 OSD_Path aPath (anImgPathNew);
6869 TCollection_AsciiString aLabelNew;
6870 if (!aPath.Name().IsEmpty())
6871 {
6872 aLabelNew = aPath.Name() + aPath.Extension();
6873 }
6874 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 6875
fd3f6bd0 6876 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6877 gp_Trsf aTrsfRef;
6878 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6879 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6880 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6881 }
6882 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6883 if (!aDiff.IsNull())
6884 {
6885 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6886 gp_Trsf aTrsfDiff;
6887 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6888 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6889 }
6890 if (!aPrsNameDiff.IsEmpty())
6891 {
6892 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6893 }
6894 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6895 ViewerTest::CurrentView()->FitAll();
692613e5 6896 return 0;
6897}
6898
4754e164 6899//=======================================================================
6900//function : VSelect
6901//purpose : Emulates different types of selection by mouse:
6902// 1) single click selection
6903// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6904// 3) selection with polygon having corners at
dc3fe572 6905// pixel positions (x1,y1),...,(xn,yn)
4754e164 6906// 4) any of these selections with shift button pressed
6907//=======================================================================
49582f9d 6908static Standard_Integer VSelect (Draw_Interpretor& ,
6909 Standard_Integer theNbArgs,
6910 const char** theArgVec)
4754e164 6911{
49582f9d 6912 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6913 if (aCtx.IsNull())
4754e164 6914 {
23fe70ec 6915 Message::SendFail ("Error: no active viewer");
4754e164 6916 return 1;
6917 }
2157d6ac 6918
49582f9d 6919 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
75cf8250 6920 bool toAllowOverlap = false;
6921 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
49582f9d 6922 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2157d6ac 6923 {
49582f9d 6924 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6925 anArg.LowerCase();
6926 if (anArg == "-allowoverlap")
6927 {
6928 toAllowOverlap = true;
6929 if (anArgIter + 1 < theNbArgs
dae2a922 6930 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
49582f9d 6931 {
6932 ++anArgIter;
6933 }
6934 }
e3d4b879 6935 else if (anArg == "-replace")
6936 {
6937 aSelScheme = AIS_SelectionScheme_Replace;
6938 }
e76471b5 6939 else if (anArg == "-replaceextra")
6940 {
6941 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6942 }
e3d4b879 6943 else if (anArg == "-xor"
6944 || anArg == "-shift")
6945 {
6946 aSelScheme = AIS_SelectionScheme_XOR;
6947 }
6948 else if (anArg == "-add")
6949 {
6950 aSelScheme = AIS_SelectionScheme_Add;
6951 }
6952 else if (anArg == "-remove")
6953 {
6954 aSelScheme = AIS_SelectionScheme_Remove;
6955 }
49582f9d 6956 else if (anArgIter + 1 < theNbArgs
6957 && anArg.IsIntegerValue()
6958 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
2157d6ac 6959 {
49582f9d 6960 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6961 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6962 }
6963 else if (anArgIter + 1 == theNbArgs
6964 && anArg.IsIntegerValue())
6965 {
75cf8250 6966 if (anArg.IntegerValue() == 1)
6967 {
6968 aSelScheme = AIS_SelectionScheme_XOR;
6969 }
49582f9d 6970 }
6971 else
6972 {
23fe70ec 6973 Message::SendFail() << "Syntax error at '" << anArg << "'";
2157d6ac 6974 return 1;
6975 }
49582f9d 6976 }
a24a7821 6977
49582f9d 6978 if (toAllowOverlap)
6979 {
6980 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
2157d6ac 6981 }
6982
4754e164 6983 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
49582f9d 6984 if (aPnts.IsEmpty())
4754e164 6985 {
75cf8250 6986 aCtx->SelectDetected (aSelScheme);
49582f9d 6987 aCtx->CurrentViewer()->Invalidate();
4754e164 6988 }
49582f9d 6989 else if (aPnts.Length() == 2)
4754e164 6990 {
49582f9d 6991 if (toAllowOverlap
6992 && aPnts.First().y() < aPnts.Last().y())
6993 {
6994 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6995 }
6996 else if (!toAllowOverlap
6997 && aPnts.First().y() > aPnts.Last().y())
6998 {
6999 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7000 }
e3d4b879 7001
7002 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7003 }
7004 else
7005 {
e3d4b879 7006 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7007 }
49582f9d 7008 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
4754e164 7009 return 0;
7010}
7011
7012//=======================================================================
7013//function : VMoveTo
dc3fe572 7014//purpose : Emulates cursor movement to defined pixel position
4754e164 7015//=======================================================================
1e756cb9 7016static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7017 Standard_Integer theNbArgs,
7018 const char** theArgVec)
4754e164 7019{
8a590580 7020 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7021 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7022 if (aContext.IsNull())
4754e164 7023 {
23fe70ec 7024 Message::SendFail ("Error: no active viewer");
4754e164 7025 return 1;
7026 }
7027
8a590580 7028 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7029 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7030 {
8a590580 7031 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7032 anArgStr.LowerCase();
7033 if (anArgStr == "-reset"
7034 || anArgStr == "-clear")
7035 {
7036 if (anArgIter + 1 < theNbArgs)
7037 {
23fe70ec 7038 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
8a590580 7039 return 1;
7040 }
7041
5634c81a 7042 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
8a590580 7043 && aContext->CurrentViewer()->GridEcho();
7044 if (toEchoGrid)
7045 {
7046 aContext->CurrentViewer()->HideGridEcho (aView);
7047 }
7048 if (aContext->ClearDetected() || toEchoGrid)
7049 {
7050 aContext->CurrentViewer()->RedrawImmediate();
7051 }
7052 return 0;
7053 }
7054 else if (aMousePos.x() == IntegerLast()
7055 && anArgStr.IsIntegerValue())
7056 {
7057 aMousePos.x() = anArgStr.IntegerValue();
7058 }
7059 else if (aMousePos.y() == IntegerLast()
7060 && anArgStr.IsIntegerValue())
7061 {
7062 aMousePos.y() = anArgStr.IntegerValue();
7063 }
7064 else
7065 {
23fe70ec 7066 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8a590580 7067 return 1;
7068 }
7069 }
7070
7071 if (aMousePos.x() == IntegerLast()
7072 || aMousePos.y() == IntegerLast())
7073 {
23fe70ec 7074 Message::SendFail ("Syntax error: wrong number of arguments");
4754e164 7075 return 1;
7076 }
8a590580 7077
49582f9d 7078 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7079 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7080 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7081
1e756cb9 7082 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7083 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7084 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7085 {
7086 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7087 {
7088 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7089 break;
7090 }
7091 }
7092 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7093 return 0;
7094}
7095
0461e7fd 7096//=======================================================================
7097//function : VSelectByAxis
7098//purpose :
7099//=======================================================================
7100static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
7101 Standard_Integer theNbArgs,
7102 const char** theArgVec)
7103{
7104 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7105 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7106 if (aContext.IsNull())
7107 {
7108 Message::SendFail ("Error: no active viewer");
7109 return 1;
7110 }
7111
7112 TCollection_AsciiString aName;
7113 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
7114 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
7115 Standard_Boolean isOnlyTop = true;
7116 Standard_Boolean toShowNormal = false;
7117 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7118 {
7119 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7120 anArgStr.LowerCase();
7121 if (anArgStr == "-display")
7122 {
7123 if (anArgIter + 1 >= theNbArgs)
7124 {
7125 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
7126 return 1;
7127 }
7128 aName = theArgVec[++anArgIter];
7129 }
7130 else if (anArgStr == "-onlytop")
7131 {
7132 isOnlyTop = true;
7133 if (anArgIter + 1 < theNbArgs
7134 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
7135 {
7136 ++anArgIter;
7137 }
7138 }
7139 else if (anArgStr == "-shownormal")
7140 {
7141 toShowNormal = true;
7142 if (anArgIter + 1 < theNbArgs
7143 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
7144 {
7145 ++anArgIter;
7146 }
7147 }
7148 else if (Precision::IsInfinite(anAxisLocation.X())
7149 && anArgStr.IsRealValue())
7150 {
7151 anAxisLocation.SetX (anArgStr.RealValue());
7152 }
7153 else if (Precision::IsInfinite(anAxisLocation.Y())
7154 && anArgStr.IsRealValue())
7155 {
7156 anAxisLocation.SetY (anArgStr.RealValue());
7157 }
7158 else if (Precision::IsInfinite(anAxisLocation.Z())
7159 && anArgStr.IsRealValue())
7160 {
7161 anAxisLocation.SetZ (anArgStr.RealValue());
7162 }
7163 else if (Precision::IsInfinite(anAxisDirection.X())
7164 && anArgStr.IsRealValue())
7165 {
7166 anAxisDirection.SetX (anArgStr.RealValue());
7167 }
7168 else if (Precision::IsInfinite(anAxisDirection.Y())
7169 && anArgStr.IsRealValue())
7170 {
7171 anAxisDirection.SetY (anArgStr.RealValue());
7172 }
7173 else if (Precision::IsInfinite(anAxisDirection.Z())
7174 && anArgStr.IsRealValue())
7175 {
7176 anAxisDirection.SetZ (anArgStr.RealValue());
7177 }
7178 else
7179 {
7180 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7181 return 1;
7182 }
7183 }
7184
7185 if (Precision::IsInfinite (anAxisLocation.X()) ||
7186 Precision::IsInfinite (anAxisLocation.Y()) ||
7187 Precision::IsInfinite (anAxisLocation.Z()) ||
7188 Precision::IsInfinite (anAxisDirection.X()) ||
7189 Precision::IsInfinite (anAxisDirection.Y()) ||
7190 Precision::IsInfinite (anAxisDirection.Z()))
7191 {
7192 Message::SendFail() << "Invalid axis location and direction";
7193 return 1;
7194 }
7195
7196 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
7197 gp_Pnt aTopPnt;
7198 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
7199 {
7200 theDI << "There are no any intersections with this axis.";
7201 return 0;
7202 }
7203 NCollection_Sequence<gp_Pnt> aPoints;
7204 NCollection_Sequence<Graphic3d_Vec3> aNormals;
7205 NCollection_Sequence<Standard_Real> aNormalLengths;
7206 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
7207 {
7208 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
7209 aPoints.Append (aPickedData.Point);
7210 aNormals.Append (aPickedData.Normal);
7211 Standard_Real aNormalLength = 1.0;
7212 if (!aPickedData.Entity.IsNull())
7213 {
7214 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
7215 }
7216 aNormalLengths.Append (aNormalLength);
7217 }
7218 if (!aName.IsEmpty())
7219 {
7220 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
7221 aContext->SetAutoActivateSelection (false);
7222
7223 // Display axis
7224 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
7225 Handle(Geom_Axis2Placement) anAx2Axis =
7226 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
7227 Handle(AIS_Axis) anAISAxis = new AIS_Axis (anAx2Axis, AIS_TOAX_ZAxis);
7228 const Handle(Prs3d_Drawer)& anAxisDrawer = anAISAxis->Attributes();
7229 anAxisDrawer->SetOwnDatumAspects();
7230 Standard_Real aLength = UnitsAPI::AnyToLS (250000., "mm");
7231 anAxisDrawer->DatumAspect()->SetAxisLength (aLength, aLength, aLength);
7232 anAxisDrawer->DatumAspect()->SetDrawLabels (false);
7233 anAxisDrawer->DatumAspect()->SetDrawArrows (true);
7234 anAISAxis->SetColor (Quantity_NOC_GREEN);
7235 anAISAxis->SetAxis2Placement (anAx2Axis, AIS_TOAX_ZAxis); // This is workaround to update axis length
7236 ViewerTest::Display (TCollection_AsciiString(aName) + "_axis", anAISAxis, false);
7237
7238 // Display axis start point
7239 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
7240 anAISStartPnt->SetMarker (Aspect_TOM_O);
7241 anAISStartPnt->SetColor (anAxisColor);
7242 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
7243
7244 Standard_Integer anIndex = 0;
7245 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
7246 {
7247 const gp_Pnt& aPoint = aPntIter.Value();
7248
7249 // Display normals in intersection points
7250 if (toShowNormal)
7251 {
7252 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
7253 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
7254 if (aNormal.SquareModulus() > ShortRealEpsilon())
7255 {
7256 Handle(Geom_Axis2Placement) anAx2Normal =
7257 new Geom_Axis2Placement(gp_Ax2(aPoint, gp_Dir((Standard_Real )aNormal.x(), (Standard_Real )aNormal.y(), (Standard_Real )aNormal.z())));
7258 Handle(AIS_Axis) anAISNormal = new AIS_Axis (anAx2Normal, AIS_TOAX_ZAxis);
7259 const Handle(Prs3d_Drawer)& aNormalDrawer = anAISNormal->Attributes();
7260 aNormalDrawer->SetOwnDatumAspects();
7261 aNormalDrawer->DatumAspect()->SetAxisLength (aNormalLength, aNormalLength, aNormalLength);
7262 aNormalDrawer->DatumAspect()->SetDrawLabels (false);
7263 aNormalDrawer->DatumAspect()->SetDrawArrows (true);
7264 anAISNormal->SetColor (Quantity_NOC_BLUE);
7265 anAISNormal->SetAxis2Placement (anAx2Normal, AIS_TOAX_ZAxis); // This is workaround to update axis length
7266 anAISNormal->SetInfiniteState (false);
7267 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
7268 }
7269 }
7270
7271 // Display intersection points
7272 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
7273 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
7274 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
7275 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
7276 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
7277 }
7278
7279 aContext->SetAutoActivateSelection (wasAuto);
7280 }
7281
7282 Standard_Integer anIndex = 0;
7283 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
7284 {
7285 const gp_Pnt& aPnt = anIter.Value();
7286 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
7287 }
7288 return 0;
7289}
7290
1beb58d7 7291namespace
7292{
7293 //! Global map storing all animations registered in ViewerTest.
7294 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7295
7296 //! The animation calling the Draw Harness command.
7297 class ViewerTest_AnimationProc : public AIS_Animation
7298 {
7299 public:
7300
7301 //! Main constructor.
7302 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7303 Draw_Interpretor* theDI,
7304 const TCollection_AsciiString& theCommand)
7305 : AIS_Animation (theAnimationName),
7306 myDrawInter(theDI),
7307 myCommand (theCommand)
7308 {
7309 //
7310 }
7311
7312 protected:
7313
7314 //! Evaluate the command.
7315 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7316 {
7317 TCollection_AsciiString aCmd = myCommand;
7318 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7319 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7320 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7321 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7322 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7323 myDrawInter->Eval (aCmd.ToCString());
7324 }
7325
7326 //! Find the keyword in the command and replace it with value.
7327 //! @return the position of the keyword to pass value
7328 void replace (TCollection_AsciiString& theCmd,
7329 const TCollection_AsciiString& theKey,
7330 const TCollection_AsciiString& theVal)
7331 {
7332 TCollection_AsciiString aCmd (theCmd);
7333 aCmd.LowerCase();
7334 const Standard_Integer aPos = aCmd.Search (theKey);
7335 if (aPos == -1)
7336 {
7337 return;
7338 }
7339
7340 TCollection_AsciiString aPart1, aPart2;
7341 Standard_Integer aPart1To = aPos - 1;
7342 if (aPart1To >= 1
7343 && aPart1To <= theCmd.Length())
7344 {
7345 aPart1 = theCmd.SubString (1, aPart1To);
7346 }
7347
7348 Standard_Integer aPart2From = aPos + theKey.Length();
7349 if (aPart2From >= 1
7350 && aPart2From <= theCmd.Length())
7351 {
7352 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7353 }
7354
7355 theCmd = aPart1 + theVal + aPart2;
7356 }
7357
7358 protected:
7359
7360 Draw_Interpretor* myDrawInter;
7361 TCollection_AsciiString myCommand;
7362
7363 };
7364
7365 //! Replace the animation with the new one.
7366 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7367 Handle(AIS_Animation)& theAnimation,
7368 const Handle(AIS_Animation)& theAnimationNew)
7369 {
7370 theAnimationNew->CopyFrom (theAnimation);
7371 if (!theParentAnimation.IsNull())
7372 {
7373 theParentAnimation->Replace (theAnimation, theAnimationNew);
7374 }
7375 else
7376 {
7377 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7378 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7379 }
7380 theAnimation = theAnimationNew;
7381 }
7382
7383 //! Parse the point.
7384 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7385 {
7386 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
d45edf24 7387 if (!anXYZ[0].IsRealValue (Standard_True)
7388 || !anXYZ[1].IsRealValue (Standard_True)
7389 || !anXYZ[2].IsRealValue (Standard_True))
1beb58d7 7390 {
7391 return Standard_False;
7392 }
7393
7394 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7395 return Standard_True;
7396 }
7397
7398 //! Parse the quaternion.
7399 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7400 {
7401 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
d45edf24 7402 if (!anXYZW[0].IsRealValue (Standard_True)
7403 || !anXYZW[1].IsRealValue (Standard_True)
7404 || !anXYZW[2].IsRealValue (Standard_True)
7405 || !anXYZW[3].IsRealValue (Standard_True))
1beb58d7 7406 {
7407 return Standard_False;
7408 }
7409
7410 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7411 return Standard_True;
7412 }
7413
08f8a185 7414 //! Auxiliary class for flipping image upside-down.
7415 class ImageFlipper
7416 {
7417 public:
7418
7419 //! Empty constructor.
7420 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7421
7422 //! Perform flipping.
7423 Standard_Boolean FlipY (Image_PixMap& theImage)
7424 {
7425 if (theImage.IsEmpty()
7426 || theImage.SizeX() == 0
7427 || theImage.SizeY() == 0)
7428 {
7429 return Standard_False;
7430 }
7431
7432 const Standard_Size aRowSize = theImage.SizeRowBytes();
7433 if (myTmp.Size() < aRowSize
7434 && !myTmp.Allocate (aRowSize))
7435 {
7436 return Standard_False;
7437 }
7438
7439 // for odd height middle row should be left as is
7440 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7441 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7442 {
7443 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7444 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7445 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7446 memcpy (aTop, aBot, aRowSize);
7447 memcpy (aBot, myTmp.Data(), aRowSize);
7448 }
7449 return Standard_True;
7450 }
7451
7452 private:
7453 NCollection_Buffer myTmp;
7454 };
7455
1beb58d7 7456}
7457
197ac94e 7458//=================================================================================================
4754e164 7459//function : VViewParams
dc3fe572 7460//purpose : Gets or sets AIS View characteristics
197ac94e 7461//=================================================================================================
7462static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7463{
1beb58d7 7464 Handle(V3d_View) aView = ViewerTest::CurrentView();
7465 if (aView.IsNull())
4754e164 7466 {
23fe70ec 7467 Message::SendFail ("Error: no active viewer");
4754e164 7468 return 1;
7469 }
197ac94e 7470
1beb58d7 7471 Standard_Boolean toSetProj = Standard_False;
7472 Standard_Boolean toSetUp = Standard_False;
7473 Standard_Boolean toSetAt = Standard_False;
7474 Standard_Boolean toSetEye = Standard_False;
7475 Standard_Boolean toSetScale = Standard_False;
7476 Standard_Boolean toSetSize = Standard_False;
7477 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7478 Standard_Real aViewScale = aView->Scale();
7479 Standard_Real aViewSize = 1.0;
1beb58d7 7480 Graphic3d_Vec2i aCenter2d;
7481 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7482 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7483 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7484 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7485 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
197ac94e 7486 if (theArgsNb == 1)
4754e164 7487 {
197ac94e 7488 // print all of the available view parameters
1beb58d7 7489 char aText[4096];
7490 Sprintf (aText,
7491 "Scale: %g\n"
7492 "Proj: %12g %12g %12g\n"
7493 "Up: %12g %12g %12g\n"
7494 "At: %12g %12g %12g\n"
7495 "Eye: %12g %12g %12g\n",
7496 aViewScale,
7497 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7498 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7499 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7500 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7501 theDi << aText;
197ac94e 7502 return 0;
4754e164 7503 }
197ac94e 7504
1beb58d7 7505 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7506 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7507 {
1beb58d7 7508 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7509 anArg.LowerCase();
7510 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7511 {
197ac94e 7512 continue;
7513 }
1beb58d7 7514 else if (anArg == "-cmd"
7515 || anArg == "-command"
7516 || anArg == "-args")
7517 {
7518 char aText[4096];
7519 Sprintf (aText,
7520 "-scale %g "
7521 "-proj %g %g %g "
7522 "-up %g %g %g "
7523 "-at %g %g %g\n",
7524 aViewScale,
7525 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7526 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7527 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7528 theDi << aText;
7529 }
7530 else if (anArg == "-scale"
7531 || anArg == "-size")
7532 {
7533 if (anArgIter + 1 < theArgsNb
7534 && *theArgVec[anArgIter + 1] != '-')
7535 {
7536 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
d45edf24 7537 if (aValueArg.IsRealValue (Standard_True))
1beb58d7 7538 {
7539 ++anArgIter;
7540 if (anArg == "-scale")
7541 {
7542 toSetScale = Standard_True;
7543 aViewScale = aValueArg.RealValue();
7544 }
7545 else if (anArg == "-size")
7546 {
7547 toSetSize = Standard_True;
7548 aViewSize = aValueArg.RealValue();
7549 }
7550 continue;
7551 }
7552 }
7553 if (anArg == "-scale")
7554 {
7555 theDi << "Scale: " << aView->Scale() << "\n";
7556 }
7557 else if (anArg == "-size")
7558 {
7559 Graphic3d_Vec2d aSizeXY;
7560 aView->Size (aSizeXY.x(), aSizeXY.y());
7561 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7562 }
7563 }
7564 else if (anArg == "-eye"
7565 || anArg == "-at"
7566 || anArg == "-up"
7567 || anArg == "-proj")
7568 {
7569 if (anArgIter + 3 < theArgsNb)
7570 {
7571 gp_XYZ anXYZ;
7572 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7573 {
7574 anArgIter += 3;
7575 if (anArg == "-eye")
7576 {
7577 toSetEye = Standard_True;
7578 aViewEye = anXYZ;
7579 }
7580 else if (anArg == "-at")
7581 {
7582 toSetAt = Standard_True;
7583 aViewAt = anXYZ;
7584 }
7585 else if (anArg == "-up")
7586 {
7587 toSetUp = Standard_True;
7588 aViewUp = anXYZ;
7589 }
7590 else if (anArg == "-proj")
7591 {
7592 toSetProj = Standard_True;
7593 aViewProj = anXYZ;
7594 }
7595 continue;
7596 }
7597 }
197ac94e 7598
1beb58d7 7599 if (anArg == "-eye")
7600 {
7601 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7602 }
7603 else if (anArg == "-at")
7604 {
7605 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7606 }
7607 else if (anArg == "-up")
7608 {
7609 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7610 }
7611 else if (anArg == "-proj")
7612 {
7613 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7614 }
7615 }
7616 else if (anArg == "-center")
3dfe95cd 7617 {
1beb58d7 7618 if (anArgIter + 2 < theArgsNb)
7619 {
7620 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7621 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7622 if (anX.IsIntegerValue()
7623 && anY.IsIntegerValue())
7624 {
7625 toSetCenter2d = Standard_True;
7626 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7627 }
7628 }
7629 }
7630 else
7631 {
23fe70ec 7632 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 7633 return 1;
7634 }
1beb58d7 7635 }
3dfe95cd 7636
1beb58d7 7637 // change view parameters in proper order
7638 if (toSetScale)
7639 {
7640 aView->SetScale (aViewScale);
7641 }
7642 if (toSetSize)
7643 {
7644 aView->SetSize (aViewSize);
7645 }
7646 if (toSetEye)
7647 {
7648 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7649 }
7650 if (toSetAt)
7651 {
7652 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7653 }
7654 if (toSetProj)
7655 {
7656 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7657 }
7658 if (toSetUp)
7659 {
7660 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7661 }
7662 if (toSetCenter2d)
7663 {
7664 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 7665 }
7666
1beb58d7 7667 return 0;
7668}
197ac94e 7669
2e93433e 7670//==============================================================================
7671//function : V2DMode
7672//purpose :
7673//==============================================================================
7674static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7675{
7676 bool is2dMode = true;
7677 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7678 if (aV3dView.IsNull())
7679 {
23fe70ec 7680 Message::SendFail ("Error: no active viewer");
2e93433e 7681 return 1;
7682 }
7683 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7684 {
7685 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7686 TCollection_AsciiString anArgCase = anArg;
7687 anArgCase.LowerCase();
7688 if (anArgIt + 1 < theArgsNb
7689 && anArgCase == "-name")
7690 {
7691 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7692 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7693 if (!ViewerTest_myViews.IsBound1 (aViewName))
7694 {
23fe70ec 7695 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 7696 return 1;
7697 }
7698 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7699 }
7700 else if (anArgCase == "-mode")
7701 {
7702 if (anArgIt + 1 < theArgsNb
dae2a922 7703 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 7704 {
7705 ++anArgIt;
7706 }
7707 }
dae2a922 7708 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 7709 {
7710 //
7711 }
7712 else
7713 {
23fe70ec 7714 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 7715 return 1;
7716 }
7717 }
7718
7719 aV3dView->SetView2DMode (is2dMode);
7720 return 0;
7721}
7722
1beb58d7 7723//==============================================================================
7724//function : VAnimation
7725//purpose :
7726//==============================================================================
7727static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7728 Standard_Integer theArgNb,
7729 const char** theArgVec)
7730{
7731 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7732 if (theArgNb < 2)
4754e164 7733 {
1beb58d7 7734 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7735 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7736 {
7737 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7738 }
1beb58d7 7739 return 0;
7740 }
7741 if (aCtx.IsNull())
7742 {
23fe70ec 7743 Message::SendFail ("Error: no active viewer");
1beb58d7 7744 return 1;
4754e164 7745 }
197ac94e 7746
1beb58d7 7747 Standard_Integer anArgIter = 1;
7748 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7749 if (aNameArg.IsEmpty())
7750 {
23fe70ec 7751 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7752 return 1;
7753 }
7754
7755 TCollection_AsciiString aNameArgLower = aNameArg;
7756 aNameArgLower.LowerCase();
7757 if (aNameArgLower == "-reset"
7758 || aNameArgLower == "-clear")
7759 {
7760 ViewerTest_AnimationTimelineMap.Clear();
7761 return 0;
7762 }
7763 else if (aNameArg.Value (1) == '-')
7764 {
23fe70ec 7765 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 7766 return 1;
7767 }
197ac94e 7768
1beb58d7 7769 const char* aNameSplitter = "/";
7770 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7771 if (aSplitPos == -1)
197ac94e 7772 {
1beb58d7 7773 aNameSplitter = ".";
7774 aSplitPos = aNameArg.Search (aNameSplitter);
7775 }
7776
7777 // find existing or create a new animation by specified name within syntax "parent.child".
7778 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7779 for (; !aNameArg.IsEmpty();)
7780 {
7781 TCollection_AsciiString aNameParent;
7782 if (aSplitPos != -1)
197ac94e 7783 {
1beb58d7 7784 if (aSplitPos == aNameArg.Length())
7785 {
23fe70ec 7786 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7787 return 1;
7788 }
7789
7790 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7791 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7792
7793 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 7794 }
7795 else
7796 {
1beb58d7 7797 aNameParent = aNameArg;
7798 aNameArg.Clear();
197ac94e 7799 }
1beb58d7 7800
7801 if (anAnimation.IsNull())
3dfe95cd 7802 {
1beb58d7 7803 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7804 {
7805 anAnimation = new AIS_Animation (aNameParent);
7806 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7807 }
7808 aRootAnimation = anAnimation;
3dfe95cd 7809 }
7810 else
7811 {
1beb58d7 7812 aParentAnimation = anAnimation;
7813 anAnimation = aParentAnimation->Find (aNameParent);
7814 if (anAnimation.IsNull())
7815 {
7816 anAnimation = new AIS_Animation (aNameParent);
7817 aParentAnimation->Add (anAnimation);
7818 }
3dfe95cd 7819 }
7820 }
1beb58d7 7821
7822 if (anArgIter >= theArgNb)
197ac94e 7823 {
1beb58d7 7824 // just print the list of children
7825 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 7826 {
1beb58d7 7827 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7828 }
1beb58d7 7829 return 0;
197ac94e 7830 }
1beb58d7 7831
bf7b2ceb 7832 // animation parameters
1beb58d7 7833 Standard_Boolean toPlay = Standard_False;
7834 Standard_Real aPlaySpeed = 1.0;
7835 Standard_Real aPlayStartTime = anAnimation->StartPts();
7836 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 7837 Standard_Boolean isFreeCamera = Standard_False;
7838 Standard_Boolean isLockLoop = Standard_False;
08f8a185 7839
7840 // video recording parameters
7841 TCollection_AsciiString aRecFile;
7842 Image_VideoParams aRecParams;
7843
1beb58d7 7844 Handle(V3d_View) aView = ViewerTest::CurrentView();
7845 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 7846 {
1beb58d7 7847 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7848 anArg.LowerCase();
bf7b2ceb 7849 // general options
1beb58d7 7850 if (anArg == "-reset"
7851 || anArg == "-clear")
197ac94e 7852 {
1beb58d7 7853 anAnimation->Clear();
7854 }
7855 else if (anArg == "-remove"
7856 || anArg == "-del"
7857 || anArg == "-delete")
7858 {
7859 if (!aParentAnimation.IsNull())
7860 {
7861 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7862 }
7863 else
7864 {
7865 aParentAnimation->Remove (anAnimation);
7866 }
7867 }
bf7b2ceb 7868 // playback options
1beb58d7 7869 else if (anArg == "-play")
7870 {
7871 toPlay = Standard_True;
7872 if (++anArgIter < theArgNb)
7873 {
7874 if (*theArgVec[anArgIter] == '-')
7875 {
7876 --anArgIter;
7877 continue;
7878 }
7879 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7880
7881 if (++anArgIter < theArgNb)
7882 {
7883 if (*theArgVec[anArgIter] == '-')
7884 {
7885 --anArgIter;
7886 continue;
7887 }
7888 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7889 }
7890 }
7891 }
7892 else if (anArg == "-resume")
7893 {
7894 toPlay = Standard_True;
7895 aPlayStartTime = anAnimation->ElapsedTime();
7896 if (++anArgIter < theArgNb)
7897 {
7898 if (*theArgVec[anArgIter] == '-')
7899 {
7900 --anArgIter;
7901 continue;
7902 }
7903
7904 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7905 }
7906 }
7907 else if (anArg == "-playspeed"
7908 || anArg == "-speed")
7909 {
7910 if (++anArgIter >= theArgNb)
7911 {
23fe70ec 7912 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 7913 return 1;
7914 }
7915 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7916 }
7917 else if (anArg == "-lock"
7918 || anArg == "-lockloop"
7919 || anArg == "-playlockloop")
7920 {
7921 isLockLoop = Standard_True;
7922 }
7923 else if (anArg == "-freecamera"
7924 || anArg == "-playfreecamera"
7925 || anArg == "-freelook")
7926 {
7927 isFreeCamera = Standard_True;
7928 }
08f8a185 7929 // video recodring options
7930 else if (anArg == "-rec"
7931 || anArg == "-record")
7932 {
7933 if (++anArgIter >= theArgNb)
7934 {
23fe70ec 7935 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 7936 return 1;
7937 }
7938
7939 aRecFile = theArgVec[anArgIter];
7940 if (aRecParams.FpsNum <= 0)
7941 {
7942 aRecParams.FpsNum = 24;
7943 }
7944
7945 if (anArgIter + 2 < theArgNb
7946 && *theArgVec[anArgIter + 1] != '-'
7947 && *theArgVec[anArgIter + 2] != '-')
7948 {
7949 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7950 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7951 if (aWidthArg .IsIntegerValue()
7952 && aHeightArg.IsIntegerValue())
7953 {
7954 aRecParams.Width = aWidthArg .IntegerValue();
7955 aRecParams.Height = aHeightArg.IntegerValue();
7956 anArgIter += 2;
7957 }
7958 }
7959 }
1beb58d7 7960 else if (anArg == "-fps")
7961 {
7962 if (++anArgIter >= theArgNb)
7963 {
23fe70ec 7964 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 7965 return 1;
7966 }
bf7b2ceb 7967
7968 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7969 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7970 if (aSplitIndex == 0)
7971 {
08f8a185 7972 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 7973 }
7974 else
7975 {
7976 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7977 aFpsArg.Split (aFpsArg.Length() - 1);
7978 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 7979 aRecParams.FpsNum = aNumStr.IntegerValue();
7980 aRecParams.FpsDen = aDenStr.IntegerValue();
7981 if (aRecParams.FpsDen < 1)
bf7b2ceb 7982 {
23fe70ec 7983 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 7984 return 1;
7985 }
7986 }
1beb58d7 7987 }
08f8a185 7988 else if (anArg == "-format")
7989 {
7990 if (++anArgIter >= theArgNb)
7991 {
23fe70ec 7992 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 7993 return 1;
7994 }
7995 aRecParams.Format = theArgVec[anArgIter];
7996 }
7997 else if (anArg == "-pix_fmt"
7998 || anArg == "-pixfmt"
7999 || anArg == "-pixelformat")
8000 {
8001 if (++anArgIter >= theArgNb)
8002 {
23fe70ec 8003 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8004 return 1;
8005 }
8006 aRecParams.PixelFormat = theArgVec[anArgIter];
8007 }
8008 else if (anArg == "-codec"
8009 || anArg == "-vcodec"
8010 || anArg == "-videocodec")
8011 {
8012 if (++anArgIter >= theArgNb)
8013 {
23fe70ec 8014 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8015 return 1;
8016 }
8017 aRecParams.VideoCodec = theArgVec[anArgIter];
8018 }
8019 else if (anArg == "-crf"
8020 || anArg == "-preset"
8021 || anArg == "-qp")
8022 {
8023 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8024 if (++anArgIter >= theArgNb)
8025 {
23fe70ec 8026 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8027 return 1;
8028 }
8029
8030 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8031 }
bf7b2ceb 8032 // animation definition options
1beb58d7 8033 else if (anArg == "-start"
8034 || anArg == "-starttime"
8035 || anArg == "-startpts")
8036 {
8037 if (++anArgIter >= theArgNb)
8038 {
23fe70ec 8039 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8040 return 1;
8041 }
8042
8043 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8044 aRootAnimation->UpdateTotalDuration();
8045 }
8046 else if (anArg == "-end"
8047 || anArg == "-endtime"
8048 || anArg == "-endpts")
8049 {
8050 if (++anArgIter >= theArgNb)
8051 {
23fe70ec 8052 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8053 return 1;
8054 }
8055
8056 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8057 aRootAnimation->UpdateTotalDuration();
8058 }
8059 else if (anArg == "-dur"
8060 || anArg == "-duration")
8061 {
8062 if (++anArgIter >= theArgNb)
8063 {
23fe70ec 8064 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8065 return 1;
8066 }
8067
8068 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8069 aRootAnimation->UpdateTotalDuration();
8070 }
8071 else if (anArg == "-command"
8072 || anArg == "-cmd"
8073 || anArg == "-invoke"
8074 || anArg == "-eval"
8075 || anArg == "-proc")
8076 {
8077 if (++anArgIter >= theArgNb)
8078 {
23fe70ec 8079 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8080 return 1;
8081 }
8082
8083 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8084 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8085 }
8086 else if (anArg == "-objecttrsf"
8087 || anArg == "-objectransformation"
8088 || anArg == "-objtransformation"
8089 || anArg == "-objtrsf"
8090 || anArg == "-object"
8091 || anArg == "-obj")
8092 {
8093 if (++anArgIter >= theArgNb)
8094 {
23fe70ec 8095 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8096 return 1;
8097 }
8098
8099 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8100 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8101 Handle(AIS_InteractiveObject) anObject;
8102 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8103 {
23fe70ec 8104 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8105 return 1;
8106 }
8107
1beb58d7 8108 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8109 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8110 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8111 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8112 Standard_Boolean isTrsfSet = Standard_False;
8113 Standard_Integer aTrsfArgIter = anArgIter + 1;
8114 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8115 {
8116 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8117 aTrsfArg.LowerCase();
8118 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8119 if (aTrsfArg.StartsWith ("-rotation")
8120 || aTrsfArg.StartsWith ("-rot"))
8121 {
8122 isTrsfSet = Standard_True;
8123 if (aTrsfArgIter + 4 >= theArgNb
8124 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8125 {
23fe70ec 8126 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8127 return 1;
8128 }
8129 aTrsfArgIter += 4;
8130 }
8131 else if (aTrsfArg.StartsWith ("-location")
8132 || aTrsfArg.StartsWith ("-loc"))
8133 {
8134 isTrsfSet = Standard_True;
8135 if (aTrsfArgIter + 3 >= theArgNb
8136 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8137 {
23fe70ec 8138 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8139 return 1;
8140 }
8141 aTrsfArgIter += 3;
8142 }
8143 else if (aTrsfArg.StartsWith ("-scale"))
8144 {
8145 isTrsfSet = Standard_True;
8146 if (++aTrsfArgIter >= theArgNb)
8147 {
23fe70ec 8148 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8149 return 1;
8150 }
8151
8152 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
d45edf24 8153 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8154 {
23fe70ec 8155 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8156 return 1;
8157 }
8158 aScales[anIndex] = aScaleStr.RealValue();
8159 }
8160 else
8161 {
8162 anArgIter = aTrsfArgIter - 1;
8163 break;
8164 }
8165 }
8166 if (!isTrsfSet)
8167 {
23fe70ec 8168 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8169 return 1;
8170 }
8171 else if (aTrsfArgIter >= theArgNb)
8172 {
8173 anArgIter = theArgNb;
8174 }
8175
8176 aTrsfs[0].SetRotation (aRotQuats[0]);
8177 aTrsfs[1].SetRotation (aRotQuats[1]);
8178 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8179 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8180 aTrsfs[0].SetScaleFactor (aScales[0]);
8181 aTrsfs[1].SetScaleFactor (aScales[1]);
8182
8183 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8184 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8185 }
8186 else if (anArg == "-viewtrsf"
8187 || anArg == "-view")
8188 {
8189 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8190 if (aCamAnimation.IsNull())
8191 {
8192 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8193 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8194 }
8195
8196 Handle(Graphic3d_Camera) aCams[2] =
8197 {
8198 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8199 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8200 };
8201
8202 Standard_Boolean isTrsfSet = Standard_False;
8203 Standard_Integer aViewArgIter = anArgIter + 1;
8204 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8205 {
8206 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8207 aViewArg.LowerCase();
8208 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8209 if (aViewArg.StartsWith ("-scale"))
8210 {
8211 isTrsfSet = Standard_True;
8212 if (++aViewArgIter >= theArgNb)
8213 {
23fe70ec 8214 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8215 return 1;
8216 }
8217
8218 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
d45edf24 8219 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8220 {
23fe70ec 8221 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8222 return 1;
8223 }
8224 Standard_Real aScale = aScaleStr.RealValue();
8225 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8226 aCams[anIndex]->SetScale (aScale);
8227 }
8228 else if (aViewArg.StartsWith ("-eye")
8229 || aViewArg.StartsWith ("-center")
8230 || aViewArg.StartsWith ("-at")
8231 || aViewArg.StartsWith ("-up"))
8232 {
8233 isTrsfSet = Standard_True;
8234 gp_XYZ anXYZ;
8235 if (aViewArgIter + 3 >= theArgNb
8236 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8237 {
23fe70ec 8238 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8239 return 1;
8240 }
8241 aViewArgIter += 3;
8242
8243 if (aViewArg.StartsWith ("-eye"))
8244 {
8245 aCams[anIndex]->SetEye (anXYZ);
8246 }
8247 else if (aViewArg.StartsWith ("-center")
8248 || aViewArg.StartsWith ("-at"))
8249 {
8250 aCams[anIndex]->SetCenter (anXYZ);
8251 }
8252 else if (aViewArg.StartsWith ("-up"))
8253 {
8254 aCams[anIndex]->SetUp (anXYZ);
8255 }
8256 }
8257 else
8258 {
8259 anArgIter = aViewArgIter - 1;
8260 break;
8261 }
8262 }
8263 if (!isTrsfSet)
8264 {
23fe70ec 8265 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8266 return 1;
8267 }
8268 else if (aViewArgIter >= theArgNb)
8269 {
8270 anArgIter = theArgNb;
8271 }
8272
8273 aCamAnimation->SetCameraStart(aCams[0]);
8274 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8275 }
8276 else
8277 {
23fe70ec 8278 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8279 return 1;
197ac94e 8280 }
8281 }
1beb58d7 8282
08f8a185 8283 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8284 {
1beb58d7 8285 return 0;
8286 }
8287
8288 // Start animation timeline and process frame updating.
8289 TheIsAnimating = Standard_True;
8290 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8291 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8292 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8293 if (isFreeCamera)
8294 {
8295 aView->Camera()->Copy (aCameraBack);
8296 }
8297
8298 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8299 if (aRecParams.FpsNum <= 0)
1beb58d7 8300 {
8301 while (!anAnimation->IsStopped())
197ac94e 8302 {
1beb58d7 8303 aCameraBack->Copy (aView->Camera());
8304 const Standard_Real aPts = anAnimation->UpdateTimer();
8305 if (isFreeCamera)
8306 {
8307 aView->Camera()->Copy (aCameraBack);
8308 }
8309
8310 if (aPts >= anUpperPts)
8311 {
8312 anAnimation->Pause();
8313 break;
8314 }
8315
8316 if (aView->IsInvalidated())
8317 {
8318 aView->Redraw();
8319 }
8320 else
8321 {
8322 aView->RedrawImmediate();
8323 }
8324
8325 if (!isLockLoop)
8326 {
8327 // handle user events
8328 theDI.Eval ("after 1 set waiter 1");
8329 theDI.Eval ("vwait waiter");
8330 }
8331 if (!TheIsAnimating)
8332 {
8333 anAnimation->Pause();
8334 theDI << aPts;
8335 break;
8336 }
8337 }
8338
8339 if (aView->IsInvalidated())
8340 {
8341 aView->Redraw();
197ac94e 8342 }
8343 else
8344 {
1beb58d7 8345 aView->RedrawImmediate();
197ac94e 8346 }
8347 }
1beb58d7 8348 else
197ac94e 8349 {
bf7b2ceb 8350 OSD_Timer aPerfTimer;
8351 aPerfTimer.Start();
1beb58d7 8352
08f8a185 8353 Handle(Image_VideoRecorder) aRecorder;
8354 ImageFlipper aFlipper;
8355 Handle(Draw_ProgressIndicator) aProgress;
8356 if (!aRecFile.IsEmpty())
8357 {
8358 if (aRecParams.Width <= 0
8359 || aRecParams.Height <= 0)
8360 {
8361 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8362 }
8363
8364 aRecorder = new Image_VideoRecorder();
8365 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8366 {
23fe70ec 8367 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8368 return 0;
8369 }
8370
8371 aProgress = new Draw_ProgressIndicator (theDI, 1);
8372 }
8373
1beb58d7 8374 // Manage frame-rated animation here
8375 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8376 int64_t aNbFrames = 0;
7e785937 8377 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8378 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8379 Standard_Integer aSecondsProgress = 0;
7e785937 8380 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8381 {
08f8a185 8382 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8383 aPts = aPlayStartTime + aRecPts;
8384 ++aNbFrames;
1beb58d7 8385 if (!anAnimation->Update (aPts))
8386 {
8387 break;
8388 }
8389
08f8a185 8390 if (!aRecorder.IsNull())
8391 {
8392 V3d_ImageDumpOptions aDumpParams;
8393 aDumpParams.Width = aRecParams.Width;
8394 aDumpParams.Height = aRecParams.Height;
8395 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8396 aDumpParams.StereoOptions = V3d_SDO_MONO;
8397 aDumpParams.ToAdjustAspect = Standard_True;
8398 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8399 {
23fe70ec 8400 Message::SendFail ("Error: view dump is failed");
08f8a185 8401 return 0;
8402 }
8403 aFlipper.FlipY (aRecorder->ChangeFrame());
8404 if (!aRecorder->PushFrame())
8405 {
8406 return 0;
8407 }
8408 }
8409 else
8410 {
8411 aView->Redraw();
8412 }
8413
8414 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8415 {
7e785937 8416 aPS.Next();
08f8a185 8417 ++aSecondsProgress;
8418 }
197ac94e 8419 }
bf7b2ceb 8420
8421 aPerfTimer.Stop();
1beb58d7 8422 anAnimation->Stop();
bf7b2ceb 8423 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8424 theDI << "Average FPS: " << aRecFps << "\n"
8425 << "Nb. Frames: " << Standard_Real(aNbFrames);
8426
8427 aView->Redraw();
197ac94e 8428 }
8429
1beb58d7 8430 aView->SetImmediateUpdate (wasImmediateUpdate);
8431 TheIsAnimating = Standard_False;
4754e164 8432 return 0;
8433}
8434
1beb58d7 8435
4754e164 8436//=======================================================================
8437//function : VChangeSelected
dc3fe572 8438//purpose : Adds the shape to selection or remove one from it
4754e164 8439//=======================================================================
8440static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8441 Standard_Integer argc,
8442 const char ** argv)
8443{
8444 if(argc != 2)
8445 {
8446 di<<"Usage : " << argv[0] << " shape \n";
8447 return 1;
8448 }
8449 //get AIS_Shape:
4754e164 8450 TCollection_AsciiString aName(argv[1]);
8451 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8452 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8453 || anAISObject.IsNull())
4754e164 8454 {
8455 di<<"Use 'vdisplay' before";
8456 return 1;
8457 }
4754e164 8458
8f521168 8459 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8460 return 0;
8461}
8462
4754e164 8463//=======================================================================
8464//function : VNbSelected
dc3fe572 8465//purpose : Returns number of selected objects
4754e164 8466//=======================================================================
8467static Standard_Integer VNbSelected (Draw_Interpretor& di,
8468 Standard_Integer argc,
8469 const char ** argv)
8470{
8471 if(argc != 1)
8472 {
8473 di << "Usage : " << argv[0] << "\n";
8474 return 1;
8475 }
8476 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8477 if(aContext.IsNull())
8478 {
8479 di << "use 'vinit' command before " << argv[0] << "\n";
8480 return 1;
8481 }
8482 di << aContext->NbSelected() << "\n";
8483 return 0;
8484}
8485
4754e164 8486//=======================================================================
8487//function : VSetViewSize
8488//purpose :
8489//=======================================================================
8490static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8491 Standard_Integer argc,
8492 const char ** argv)
8493{
8494 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8495 if(aContext.IsNull())
8496 {
8497 di << "use 'vinit' command before " << argv[0] << "\n";
8498 return 1;
8499 }
8500 if(argc != 2)
8501 {
8502 di<<"Usage : " << argv[0] << " Size\n";
8503 return 1;
8504 }
6b62b2da 8505 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8506 if (aSize <= 0.)
8507 {
8508 di<<"Bad Size value : " << aSize << "\n";
8509 return 1;
8510 }
8511
8512 Handle(V3d_View) aView = ViewerTest::CurrentView();
8513 aView->SetSize(aSize);
8514 return 0;
8515}
8516
8517//=======================================================================
8518//function : VMoveView
8519//purpose :
8520//=======================================================================
8521static Standard_Integer VMoveView (Draw_Interpretor& di,
8522 Standard_Integer argc,
8523 const char ** argv)
8524{
8525 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8526 if(aContext.IsNull())
8527 {
8528 di << "use 'vinit' command before " << argv[0] << "\n";
8529 return 1;
8530 }
8531 if(argc < 4 || argc > 5)
8532 {
8533 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8534 return 1;
8535 }
6b62b2da 8536 Standard_Real Dx = Draw::Atof (argv[1]);
8537 Standard_Real Dy = Draw::Atof (argv[2]);
8538 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8539 Standard_Boolean aStart = Standard_True;
8540 if (argc == 5)
8541 {
6b62b2da 8542 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8543 }
8544
8545 Handle(V3d_View) aView = ViewerTest::CurrentView();
8546 aView->Move(Dx,Dy,Dz,aStart);
8547 return 0;
8548}
8549
8550//=======================================================================
8551//function : VTranslateView
8552//purpose :
8553//=======================================================================
8554static Standard_Integer VTranslateView (Draw_Interpretor& di,
8555 Standard_Integer argc,
8556 const char ** argv)
8557{
8558 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8559 if(aContext.IsNull())
8560 {
8561 di << "use 'vinit' command before " << argv[0] << "\n";
8562 return 1;
8563 }
8564 if(argc < 4 || argc > 5)
8565 {
8566 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8567 return 1;
8568 }
6b62b2da 8569 Standard_Real Dx = Draw::Atof (argv[1]);
8570 Standard_Real Dy = Draw::Atof (argv[2]);
8571 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8572 Standard_Boolean aStart = Standard_True;
dc3fe572 8573 if (argc == 5)
4754e164 8574 {
6b62b2da 8575 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8576 }
8577
8578 Handle(V3d_View) aView = ViewerTest::CurrentView();
8579 aView->Translate(Dx,Dy,Dz,aStart);
8580 return 0;
8581}
8582
8583//=======================================================================
8584//function : VTurnView
8585//purpose :
8586//=======================================================================
8587static Standard_Integer VTurnView (Draw_Interpretor& di,
8588 Standard_Integer argc,
8589 const char ** argv)
8590{
8591 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8592 if(aContext.IsNull()) {
8593 di << "use 'vinit' command before " << argv[0] << "\n";
8594 return 1;
8595 }
8596 if(argc < 4 || argc > 5){
8597 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8598 return 1;
8599 }
6b62b2da 8600 Standard_Real Ax = Draw::Atof (argv[1]);
8601 Standard_Real Ay = Draw::Atof (argv[2]);
8602 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 8603 Standard_Boolean aStart = Standard_True;
dc3fe572 8604 if (argc == 5)
4754e164 8605 {
6b62b2da 8606 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8607 }
8608
8609 Handle(V3d_View) aView = ViewerTest::CurrentView();
8610 aView->Turn(Ax,Ay,Az,aStart);
8611 return 0;
8612}
8613
269294d6 8614//==============================================================================
8615//function : VTextureEnv
8616//purpose : ENables or disables environment mapping
8617//==============================================================================
8618class OCC_TextureEnv : public Graphic3d_TextureEnv
8619{
8620public:
8621 OCC_TextureEnv(const Standard_CString FileName);
8622 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8623 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8624 const Standard_Boolean theModulateFlag,
8625 const Graphic3d_TypeOfTextureFilter theFilter,
8626 const Standard_ShortReal theXScale,
8627 const Standard_ShortReal theYScale,
8628 const Standard_ShortReal theXShift,
8629 const Standard_ShortReal theYShift,
8630 const Standard_ShortReal theAngle);
68858c7d 8631 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 8632};
a3f6f591 8633DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 8634
269294d6 8635OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8636 : Graphic3d_TextureEnv(theFileName)
8637{
8638}
8639
8640OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8641 : Graphic3d_TextureEnv(theTexId)
8642{
8643}
8644
8645void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8646 const Standard_Boolean theModulateFlag,
8647 const Graphic3d_TypeOfTextureFilter theFilter,
8648 const Standard_ShortReal theXScale,
8649 const Standard_ShortReal theYScale,
8650 const Standard_ShortReal theXShift,
8651 const Standard_ShortReal theYShift,
8652 const Standard_ShortReal theAngle)
8653{
8654 myParams->SetRepeat (theRepeatFlag);
8655 myParams->SetModulate (theModulateFlag);
8656 myParams->SetFilter (theFilter);
8657 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8658 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8659 myParams->SetRotation (theAngle);
8660}
8661
35e08fe8 8662static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 8663{
8664 // get the active view
8665 Handle(V3d_View) aView = ViewerTest::CurrentView();
8666 if (aView.IsNull())
8667 {
23fe70ec 8668 Message::SendFail ("Error: no active viewer");
269294d6 8669 return 1;
8670 }
8671
8672 // Checking the input arguments
8673 Standard_Boolean anEnableFlag = Standard_False;
8674 Standard_Boolean isOk = theArgNb >= 2;
8675 if (isOk)
8676 {
8677 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8678 anEnableFlag = anEnableOpt.IsEqual("on");
8679 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8680 }
8681 if (anEnableFlag)
8682 {
8683 isOk = (theArgNb == 3 || theArgNb == 11);
8684 if (isOk)
8685 {
8686 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8687 isOk = (!aTextureOpt.IsIntegerValue() ||
8688 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8689
8690 if (isOk && theArgNb == 11)
8691 {
8692 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8693 aModulateOpt(theArgVec[4]),
8694 aFilterOpt (theArgVec[5]),
8695 aSScaleOpt (theArgVec[6]),
8696 aTScaleOpt (theArgVec[7]),
8697 aSTransOpt (theArgVec[8]),
8698 aTTransOpt (theArgVec[9]),
8699 anAngleOpt (theArgVec[10]);
8700 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8701 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8702 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
d45edf24 8703 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8704 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8705 anAngleOpt.IsRealValue (Standard_True));
269294d6 8706 }
8707 }
8708 }
8709
8710 if (!isOk)
8711 {
23fe70ec 8712 Message::SendFail() << "Usage:\n"
8713 << theArgVec[0] << " off\n"
8714 << 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 8715 return 1;
8716 }
8717
8718 if (anEnableFlag)
8719 {
8720 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8721 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8722 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8723 new OCC_TextureEnv(theArgVec[2]);
8724
8725 if (theArgNb == 11)
8726 {
8727 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8728 aTexEnv->SetTextureParameters(
8729 aRepeatOpt. IsEqual("repeat"),
8730 aModulateOpt.IsEqual("modulate"),
8731 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8732 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8733 Graphic3d_TOTF_TRILINEAR,
8734 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8735 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8736 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8737 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8738 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8739 );
8740 }
8741 aView->SetTextureEnv(aTexEnv);
269294d6 8742 }
8743 else // Disabling environment mapping
8744 {
269294d6 8745 Handle(Graphic3d_TextureEnv) aTexture;
8746 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8747 }
8748
8749 aView->Redraw();
8750 return 0;
8751}
8752
3e05329c 8753namespace
8754{
8755 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8756
8757 //! Remove registered clipping plane from all views and objects.
8758 static void removePlane (MapOfPlanes& theRegPlanes,
8759 const TCollection_AsciiString& theName)
8760 {
8761 Handle(Graphic3d_ClipPlane) aClipPlane;
8762 if (!theRegPlanes.Find (theName, aClipPlane))
8763 {
23fe70ec 8764 Message::SendWarning ("Warning: no such plane");
3e05329c 8765 return;
8766 }
8767
8768 theRegPlanes.UnBind (theName);
8769 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8770 anIObjIt.More(); anIObjIt.Next())
8771 {
8f521168 8772 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 8773 aPrs->RemoveClipPlane (aClipPlane);
8774 }
8775
8776 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8777 aViewIt.More(); aViewIt.Next())
8778 {
8779 const Handle(V3d_View)& aView = aViewIt.Key2();
8780 aView->RemoveClipPlane(aClipPlane);
8781 }
8782
8783 ViewerTest::RedrawAllViews();
8784 }
8785}
8786
4269bd1b 8787//===============================================================================================
8788//function : VClipPlane
8789//purpose :
8790//===============================================================================================
8791static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8792{
8793 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 8794 static MapOfPlanes aRegPlanes;
8795
8796 if (theArgsNb < 2)
8797 {
3e05329c 8798 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8799 {
8800 theDi << aPlaneIter.Key() << " ";
8801 }
8802 return 0;
4269bd1b 8803 }
8804
8805 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 8806 aCommand.LowerCase();
8807 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8808 if (anActiveView.IsNull())
8809 {
23fe70ec 8810 Message::SendFail ("Error: no active viewer");
3e05329c 8811 return 1;
8812 }
4269bd1b 8813
8814 // print maximum number of planes for current viewer
3e05329c 8815 if (aCommand == "-maxplanes"
8816 || aCommand == "maxplanes")
4269bd1b 8817 {
3e05329c 8818 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8819 << " plane slots provided by driver.\n";
4269bd1b 8820 return 0;
8821 }
8822
8823 // create / delete plane instance
3e05329c 8824 if (aCommand == "-create"
8825 || aCommand == "create"
8826 || aCommand == "-delete"
8827 || aCommand == "delete"
8828 || aCommand == "-clone"
8829 || aCommand == "clone")
4269bd1b 8830 {
8831 if (theArgsNb < 3)
8832 {
23fe70ec 8833 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 8834 return 1;
8835 }
8836
3e05329c 8837 Standard_Boolean toCreate = aCommand == "-create"
8838 || aCommand == "create";
8839 Standard_Boolean toClone = aCommand == "-clone"
8840 || aCommand == "clone";
8841 Standard_Boolean toDelete = aCommand == "-delete"
8842 || aCommand == "delete";
4269bd1b 8843 TCollection_AsciiString aPlane (theArgVec[2]);
8844
8845 if (toCreate)
8846 {
8847 if (aRegPlanes.IsBound (aPlane))
8848 {
3e05329c 8849 std::cout << "Warning: existing plane has been overridden.\n";
8850 toDelete = true;
8851 }
8852 else
8853 {
8854 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8855 return 0;
4269bd1b 8856 }
4269bd1b 8857 }
8858 else if (toClone) // toClone
8859 {
8860 if (!aRegPlanes.IsBound (aPlane))
8861 {
23fe70ec 8862 Message::SendFail ("Error: no such plane");
4269bd1b 8863 return 1;
8864 }
3e05329c 8865 else if (theArgsNb < 4)
4269bd1b 8866 {
23fe70ec 8867 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 8868 return 1;
8869 }
8870
8871 TCollection_AsciiString aClone (theArgVec[3]);
8872 if (aRegPlanes.IsBound (aClone))
8873 {
23fe70ec 8874 Message::SendFail ("Error: plane name is in use");
4269bd1b 8875 return 1;
8876 }
8877
8878 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8879
8880 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 8881 return 0;
4269bd1b 8882 }
4269bd1b 8883
3e05329c 8884 if (toDelete)
8885 {
8886 if (aPlane == "ALL"
8887 || aPlane == "all"
8888 || aPlane == "*")
4269bd1b 8889 {
3e05329c 8890 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8891 {
8892 aPlane = aPlaneIter.Key();
8893 removePlane (aRegPlanes, aPlane);
8894 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8895 }
4269bd1b 8896 }
3e05329c 8897 else
4269bd1b 8898 {
3e05329c 8899 removePlane (aRegPlanes, aPlane);
4269bd1b 8900 }
4269bd1b 8901 }
8902
3e05329c 8903 if (toCreate)
8904 {
8905 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8906 }
4269bd1b 8907 return 0;
8908 }
8909
8910 // set / unset plane command
3e05329c 8911 if (aCommand == "set"
8912 || aCommand == "unset")
4269bd1b 8913 {
3e05329c 8914 if (theArgsNb < 5)
4269bd1b 8915 {
23fe70ec 8916 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8917 return 1;
8918 }
8919
3e05329c 8920 // redirect to new syntax
8921 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8922 anArgVec.SetValue (1, theArgVec[0]);
8923 anArgVec.SetValue (2, theArgVec[2]);
8924 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8925 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 8926 {
3e05329c 8927 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 8928 }
8929
3e05329c 8930 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 8931 }
8932
8933 // change plane command
3e05329c 8934 TCollection_AsciiString aPlaneName;
8935 Handle(Graphic3d_ClipPlane) aClipPlane;
8936 Standard_Integer anArgIter = 0;
8937 if (aCommand == "-change"
8938 || aCommand == "change")
4269bd1b 8939 {
3e05329c 8940 // old syntax support
8941 if (theArgsNb < 3)
4269bd1b 8942 {
23fe70ec 8943 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8944 return 1;
8945 }
8946
3e05329c 8947 anArgIter = 3;
8948 aPlaneName = theArgVec[2];
8949 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 8950 {
23fe70ec 8951 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 8952 return 1;
8953 }
3e05329c 8954 }
8955 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8956 {
8957 anArgIter = 2;
8958 aPlaneName = theArgVec[1];
8959 }
8960 else
8961 {
8962 anArgIter = 2;
8963 aPlaneName = theArgVec[1];
8964 aClipPlane = new Graphic3d_ClipPlane();
8965 aRegPlanes.Bind (aPlaneName, aClipPlane);
8966 theDi << "Created new plane " << aPlaneName << ".\n";
8967 }
4269bd1b 8968
3e05329c 8969 if (theArgsNb - anArgIter < 1)
8970 {
23fe70ec 8971 Message::SendFail ("Syntax error: need more arguments");
3e05329c 8972 return 1;
8973 }
4269bd1b 8974
3e05329c 8975 for (; anArgIter < theArgsNb; ++anArgIter)
8976 {
8977 const char** aChangeArgs = theArgVec + anArgIter;
8978 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8979 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
8980 aChangeArg.LowerCase();
4269bd1b 8981
3e05329c 8982 Standard_Boolean toEnable = Standard_True;
dae2a922 8983 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 8984 {
3e05329c 8985 aClipPlane->SetOn (toEnable);
4269bd1b 8986 }
25c35042 8987 else if (aChangeArg.StartsWith ("-equation")
8988 || aChangeArg.StartsWith ("equation"))
4269bd1b 8989 {
3e05329c 8990 if (aNbChangeArgs < 5)
4269bd1b 8991 {
23fe70ec 8992 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8993 return 1;
8994 }
8995
25c35042 8996 Standard_Integer aSubIndex = 1;
8997 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
8998 if (aPrefixLen < aChangeArg.Length())
8999 {
9000 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9001 if (!aSubStr.IsIntegerValue()
9002 || aSubStr.IntegerValue() <= 0)
9003 {
23fe70ec 9004 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9005 return 1;
9006 }
9007 aSubIndex = aSubStr.IntegerValue();
9008 }
9009
9010 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9011 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9012 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9013 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9014 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9015 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9016 {
9017 if (aSubPln->ChainNextPlane().IsNull())
9018 {
9019 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9020 }
9021 aSubPln = aSubPln->ChainNextPlane();
9022 }
9023 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9024 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9025 anArgIter += 4;
4269bd1b 9026 }
25c35042 9027 else if ((aChangeArg == "-boxinterior"
9028 || aChangeArg == "-boxint"
9029 || aChangeArg == "-box")
9030 && aNbChangeArgs >= 7)
9031 {
9032 Graphic3d_BndBox3d aBndBox;
9033 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9034 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9035 anArgIter += 6;
9036
9037 Standard_Integer aNbSubPlanes = 6;
9038 const Graphic3d_Vec3d aDirArray[6] =
9039 {
9040 Graphic3d_Vec3d (-1, 0, 0),
9041 Graphic3d_Vec3d ( 1, 0, 0),
9042 Graphic3d_Vec3d ( 0,-1, 0),
9043 Graphic3d_Vec3d ( 0, 1, 0),
9044 Graphic3d_Vec3d ( 0, 0,-1),
9045 Graphic3d_Vec3d ( 0, 0, 1),
9046 };
9047 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9048 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9049 {
9050 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9051 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9052 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9053 if (aSubPlaneIter + 1 == aNbSubPlanes)
9054 {
9055 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9056 }
9057 else
9058 {
9059 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9060 }
9061 aSubPln = aSubPln->ChainNextPlane();
9062 }
9063 }
3e05329c 9064 else if (aChangeArg == "-capping"
9065 || aChangeArg == "capping")
4269bd1b 9066 {
3e05329c 9067 if (aNbChangeArgs < 2)
4269bd1b 9068 {
23fe70ec 9069 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9070 return 1;
9071 }
9072
dae2a922 9073 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9074 {
3e05329c 9075 aClipPlane->SetCapping (toEnable);
9076 anArgIter += 1;
9077 }
9078 else
9079 {
9080 // just skip otherwise (old syntax)
9081 }
9082 }
9083 else if (aChangeArg == "-useobjectmaterial"
9084 || aChangeArg == "-useobjectmat"
9085 || aChangeArg == "-useobjmat"
9086 || aChangeArg == "-useobjmaterial")
9087 {
9088 if (aNbChangeArgs < 2)
9089 {
23fe70ec 9090 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9091 return 1;
9092 }
9093
dae2a922 9094 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9095 {
3e05329c 9096 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9097 anArgIter += 1;
4269bd1b 9098 }
3e05329c 9099 }
9100 else if (aChangeArg == "-useobjecttexture"
9101 || aChangeArg == "-useobjecttex"
9102 || aChangeArg == "-useobjtexture"
9103 || aChangeArg == "-useobjtex")
9104 {
9105 if (aNbChangeArgs < 2)
4269bd1b 9106 {
23fe70ec 9107 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9108 return 1;
9109 }
4269bd1b 9110
dae2a922 9111 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9112 {
9113 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9114 anArgIter += 1;
9115 }
9116 }
9117 else if (aChangeArg == "-useobjectshader"
9118 || aChangeArg == "-useobjshader")
9119 {
9120 if (aNbChangeArgs < 2)
9121 {
23fe70ec 9122 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9123 return 1;
9124 }
4269bd1b 9125
dae2a922 9126 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9127 {
9128 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9129 anArgIter += 1;
4269bd1b 9130 }
3e05329c 9131 }
9132 else if (aChangeArg == "-color"
9133 || aChangeArg == "color")
9134 {
9135 Quantity_Color aColor;
dae2a922 9136 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9137 aChangeArgs + 1,
9138 aColor);
3e05329c 9139 if (aNbParsed == 0)
4269bd1b 9140 {
23fe70ec 9141 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9142 return 1;
9143 }
61168418 9144 aClipPlane->SetCappingColor (aColor);
3e05329c 9145 anArgIter += aNbParsed;
9146 }
61168418 9147 else if (aNbChangeArgs >= 1
9148 && (aChangeArg == "-material"
9149 || aChangeArg == "material"))
9150 {
9151 ++anArgIter;
9152 Graphic3d_NameOfMaterial aMatName;
9153 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9154 {
23fe70ec 9155 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9156 return 1;
9157 }
9158 aClipPlane->SetCappingMaterial (aMatName);
9159 }
1b661a81 9160 else if ((aChangeArg == "-transparency"
9161 || aChangeArg == "-transp")
9162 && aNbChangeArgs >= 2)
9163 {
9164 TCollection_AsciiString aValStr (aChangeArgs[1]);
9165 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
d45edf24 9166 if (aValStr.IsRealValue (Standard_True))
1b661a81 9167 {
9168 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9169 aMat.SetTransparency ((float )aValStr.RealValue());
9170 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9171 aClipPlane->SetCappingMaterial (aMat);
9172 }
9173 else
9174 {
9175 aValStr.LowerCase();
9176 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9177 if (aValStr == "opaque")
9178 {
9179 aMode = Graphic3d_AlphaMode_Opaque;
9180 }
9181 else if (aValStr == "mask")
9182 {
9183 aMode = Graphic3d_AlphaMode_Mask;
9184 }
9185 else if (aValStr == "blend")
9186 {
9187 aMode = Graphic3d_AlphaMode_Blend;
9188 }
33425a46 9189 else if (aValStr == "maskblend"
9190 || aValStr == "blendmask")
9191 {
9192 aMode = Graphic3d_AlphaMode_MaskBlend;
9193 }
1b661a81 9194 else if (aValStr == "blendauto")
9195 {
9196 aMode = Graphic3d_AlphaMode_BlendAuto;
9197 }
9198 else
9199 {
23fe70ec 9200 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9201 return 1;
9202 }
9203 anAspect->SetAlphaMode (aMode);
9204 aClipPlane->SetCappingAspect (anAspect);
9205 }
9206 anArgIter += 1;
9207 }
3e05329c 9208 else if (aChangeArg == "-texname"
9209 || aChangeArg == "texname")
9210 {
9211 if (aNbChangeArgs < 2)
9212 {
23fe70ec 9213 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9214 return 1;
9215 }
4269bd1b 9216
3e05329c 9217 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9218 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9219 if (!aTexture->IsDone())
9220 {
9221 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9222 }
3e05329c 9223 else
4269bd1b 9224 {
3e05329c 9225 aTexture->EnableModulate();
9226 aTexture->EnableRepeat();
9227 aClipPlane->SetCappingTexture (aTexture);
9228 }
9229 anArgIter += 1;
9230 }
9231 else if (aChangeArg == "-texscale"
9232 || aChangeArg == "texscale")
9233 {
9234 if (aClipPlane->CappingTexture().IsNull())
9235 {
23fe70ec 9236 Message::SendFail ("Error: no texture is set");
3e05329c 9237 return 1;
9238 }
4269bd1b 9239
3e05329c 9240 if (aNbChangeArgs < 3)
9241 {
23fe70ec 9242 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9243 return 1;
9244 }
4269bd1b 9245
3e05329c 9246 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9247 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9248 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9249 anArgIter += 2;
9250 }
9251 else if (aChangeArg == "-texorigin"
9252 || aChangeArg == "texorigin") // texture origin
9253 {
9254 if (aClipPlane->CappingTexture().IsNull())
9255 {
23fe70ec 9256 Message::SendFail ("Error: no texture is set");
3e05329c 9257 return 1;
9258 }
4269bd1b 9259
3e05329c 9260 if (aNbChangeArgs < 3)
9261 {
23fe70ec 9262 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9263 return 1;
4269bd1b 9264 }
3e05329c 9265
9266 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9267 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9268
9269 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9270 anArgIter += 2;
9271 }
9272 else if (aChangeArg == "-texrotate"
9273 || aChangeArg == "texrotate") // texture rotation
9274 {
9275 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9276 {
23fe70ec 9277 Message::SendFail ("Error: no texture is set");
3e05329c 9278 return 1;
9279 }
4269bd1b 9280
3e05329c 9281 if (aNbChangeArgs < 2)
9282 {
23fe70ec 9283 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9284 return 1;
9285 }
4269bd1b 9286
3e05329c 9287 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9288 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9289 anArgIter += 1;
9290 }
9291 else if (aChangeArg == "-hatch"
9292 || aChangeArg == "hatch")
9293 {
9294 if (aNbChangeArgs < 2)
9295 {
23fe70ec 9296 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9297 return 1;
9298 }
4269bd1b 9299
3e05329c 9300 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9301 aHatchStr.LowerCase();
9302 if (aHatchStr == "on")
9303 {
9304 aClipPlane->SetCappingHatchOn();
9305 }
9306 else if (aHatchStr == "off")
9307 {
9308 aClipPlane->SetCappingHatchOff();
4269bd1b 9309 }
3e05329c 9310 else
4269bd1b 9311 {
3e05329c 9312 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9313 }
9314 anArgIter += 1;
9315 }
9316 else if (aChangeArg == "-delete"
9317 || aChangeArg == "delete")
9318 {
9319 removePlane (aRegPlanes, aPlaneName);
9320 return 0;
9321 }
9322 else if (aChangeArg == "-set"
32ca7711 9323 || aChangeArg == "-unset"
9324 || aChangeArg == "-setoverrideglobal")
3e05329c 9325 {
9326 // set / unset plane command
32ca7711 9327 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9328 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9329 Standard_Integer anIt = 1;
9330 for (; anIt < aNbChangeArgs; ++anIt)
9331 {
9332 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9333 if (anEntityName.IsEmpty()
9334 || anEntityName.Value (1) == '-')
4269bd1b 9335 {
3e05329c 9336 break;
4269bd1b 9337 }
32ca7711 9338 else if (!toOverrideGlobal
9339 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9340 {
3e05329c 9341 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9342 if (toSet)
9343 {
9344 aView->AddClipPlane (aClipPlane);
9345 }
9346 else
9347 {
9348 aView->RemoveClipPlane (aClipPlane);
9349 }
9350 continue;
4269bd1b 9351 }
3e05329c 9352 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9353 {
8f521168 9354 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9355 if (toSet)
9356 {
9357 aIObj->AddClipPlane (aClipPlane);
9358 }
9359 else
9360 {
9361 aIObj->RemoveClipPlane (aClipPlane);
9362 }
32ca7711 9363 if (!aIObj->ClipPlanes().IsNull())
9364 {
9365 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9366 }
4269bd1b 9367 }
3e05329c 9368 else
4269bd1b 9369 {
23fe70ec 9370 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9371 return 1;
4269bd1b 9372 }
3e05329c 9373 }
9374
9375 if (anIt == 1)
9376 {
9377 // apply to active view
9378 if (toSet)
4269bd1b 9379 {
3e05329c 9380 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9381 }
9382 else
9383 {
3e05329c 9384 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9385 }
9386 }
3e05329c 9387 else
9388 {
9389 anArgIter = anArgIter + anIt - 1;
9390 }
9391 }
9392 else
9393 {
23fe70ec 9394 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9395 return 1;
4269bd1b 9396 }
4269bd1b 9397 }
9398
3e05329c 9399 ViewerTest::RedrawAllViews();
9400 return 0;
4269bd1b 9401}
9402
b5ac8292 9403//===============================================================================================
9404//function : VZRange
9405//purpose :
9406//===============================================================================================
9407static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9408{
197ac94e 9409 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9410
9411 if (aCurrentView.IsNull())
b5ac8292 9412 {
23fe70ec 9413 Message::SendFail ("Error: no active viewer");
b5ac8292 9414 return 1;
9415 }
9416
197ac94e 9417 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9418
9419 if (theArgsNb < 2)
9420 {
9421 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9422 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9423 return 0;
9424 }
9425
9426 if (theArgsNb == 3)
9427 {
6b62b2da 9428 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9429 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9430
9431 if (aNewZNear >= aNewZFar)
9432 {
23fe70ec 9433 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9434 return 1;
9435 }
9436
9437 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9438 {
23fe70ec 9439 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9440 return 1;
9441 }
9442
9443 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9444 }
9445 else
9446 {
23fe70ec 9447 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9448 return 1;
9449 }
9450
197ac94e 9451 aCurrentView->Redraw();
9452
b5ac8292 9453 return 0;
9454}
9455
9456//===============================================================================================
9457//function : VAutoZFit
9458//purpose :
9459//===============================================================================================
9460static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9461{
197ac94e 9462 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9463
9464 if (aCurrentView.IsNull())
b5ac8292 9465 {
23fe70ec 9466 Message::SendFail ("Error: no active viewer");
b5ac8292 9467 return 1;
9468 }
9469
c357e426 9470 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9471
9472 if (theArgsNb > 3)
b5ac8292 9473 {
23fe70ec 9474 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9475 return 1;
b5ac8292 9476 }
9477
197ac94e 9478 if (theArgsNb < 2)
b5ac8292 9479 {
586db386 9480 theDi << "Auto z-fit mode: \n"
c357e426 9481 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9482 << "Scale: " << aScale << "\n";
9483 return 0;
b5ac8292 9484 }
197ac94e 9485
9486 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9487
9488 if (theArgsNb >= 3)
b5ac8292 9489 {
197ac94e 9490 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9491 }
9492
c357e426 9493 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9494 aCurrentView->Redraw();
b5ac8292 9495 return 0;
9496}
9497
6b62b2da 9498//! Auxiliary function to print projection type
9499inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9500{
9501 switch (theProjType)
9502 {
9503 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9504 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9505 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9506 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9507 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9508 }
9509 return "UNKNOWN";
9510}
9511
b5ac8292 9512//===============================================================================================
6b62b2da 9513//function : VCamera
b5ac8292 9514//purpose :
9515//===============================================================================================
6b62b2da 9516static int VCamera (Draw_Interpretor& theDI,
9517 Standard_Integer theArgsNb,
9518 const char** theArgVec)
b5ac8292 9519{
6b62b2da 9520 Handle(V3d_View) aView = ViewerTest::CurrentView();
9521 if (aView.IsNull())
b5ac8292 9522 {
23fe70ec 9523 Message::SendFail ("Error: no active viewer");
b5ac8292 9524 return 1;
9525 }
9526
6b62b2da 9527 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9528 if (theArgsNb < 2)
b5ac8292 9529 {
6b62b2da 9530 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9531 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 9532 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9533 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 9534 theDI << "Distance: " << aCamera->Distance() << "\n";
9535 theDI << "IOD: " << aCamera->IOD() << "\n";
9536 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9537 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9538 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
9539 return 0;
b5ac8292 9540 }
9541
30a1b24e 9542 TCollection_AsciiString aPrsName;
6b62b2da 9543 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 9544 {
6b62b2da 9545 Standard_CString anArg = theArgVec[anArgIter];
9546 TCollection_AsciiString anArgCase (anArg);
9547 anArgCase.LowerCase();
9548 if (anArgCase == "-proj"
9549 || anArgCase == "-projection"
9550 || anArgCase == "-projtype"
9551 || anArgCase == "-projectiontype")
9552 {
9553 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9554 }
9555 else if (anArgCase == "-ortho"
9556 || anArgCase == "-orthographic")
b5ac8292 9557 {
9558 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 9559 }
9560 else if (anArgCase == "-persp"
9561 || anArgCase == "-perspective"
9562 || anArgCase == "-perspmono"
9563 || anArgCase == "-perspectivemono"
9564 || anArgCase == "-mono")
b5ac8292 9565 {
9566 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9567 }
6b62b2da 9568 else if (anArgCase == "-stereo"
9569 || anArgCase == "-stereoscopic"
9570 || anArgCase == "-perspstereo"
9571 || anArgCase == "-perspectivestereo")
9572 {
9573 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9574 }
9575 else if (anArgCase == "-left"
9576 || anArgCase == "-lefteye"
9577 || anArgCase == "-monoleft"
9578 || anArgCase == "-monolefteye"
9579 || anArgCase == "-perpsleft"
9580 || anArgCase == "-perpslefteye")
b5ac8292 9581 {
9582 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9583 }
6b62b2da 9584 else if (anArgCase == "-right"
9585 || anArgCase == "-righteye"
9586 || anArgCase == "-monoright"
9587 || anArgCase == "-monorighteye"
9588 || anArgCase == "-perpsright")
b5ac8292 9589 {
9590 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9591 }
6b62b2da 9592 else if (anArgCase == "-dist"
9593 || anArgCase == "-distance")
b5ac8292 9594 {
6b62b2da 9595 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9596 if (anArgValue != NULL
9597 && *anArgValue != '-')
9598 {
9599 ++anArgIter;
9600 aCamera->SetDistance (Draw::Atof (anArgValue));
9601 continue;
9602 }
9603 theDI << aCamera->Distance() << " ";
b5ac8292 9604 }
6b62b2da 9605 else if (anArgCase == "-iod")
b5ac8292 9606 {
6b62b2da 9607 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9608 if (anArgValue != NULL
9609 && *anArgValue != '-')
9610 {
9611 ++anArgIter;
9612 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9613 continue;
9614 }
9615 theDI << aCamera->IOD() << " ";
b5ac8292 9616 }
6b62b2da 9617 else if (anArgCase == "-iodtype")
b5ac8292 9618 {
6b62b2da 9619 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9620 TCollection_AsciiString anValueCase (anArgValue);
9621 anValueCase.LowerCase();
9622 if (anValueCase == "abs"
9623 || anValueCase == "absolute")
9624 {
9625 ++anArgIter;
9626 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9627 continue;
9628 }
9629 else if (anValueCase == "rel"
9630 || anValueCase == "relative")
9631 {
9632 ++anArgIter;
9633 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9634 continue;
9635 }
9636 else if (*anArgValue != '-')
9637 {
23fe70ec 9638 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 9639 return 1;
9640 }
9641 switch (aCamera->GetIODType())
9642 {
9643 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9644 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9645 }
b5ac8292 9646 }
6b62b2da 9647 else if (anArgCase == "-zfocus")
b5ac8292 9648 {
6b62b2da 9649 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9650 if (anArgValue != NULL
9651 && *anArgValue != '-')
9652 {
9653 ++anArgIter;
9654 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9655 continue;
9656 }
9657 theDI << aCamera->ZFocus() << " ";
b5ac8292 9658 }
6b62b2da 9659 else if (anArgCase == "-zfocustype")
b5ac8292 9660 {
6b62b2da 9661 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9662 TCollection_AsciiString anValueCase (anArgValue);
9663 anValueCase.LowerCase();
9664 if (anValueCase == "abs"
9665 || anValueCase == "absolute")
9666 {
9667 ++anArgIter;
9668 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9669 continue;
9670 }
9671 else if (anValueCase == "rel"
9672 || anValueCase == "relative")
9673 {
9674 ++anArgIter;
9675 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9676 continue;
9677 }
9678 else if (*anArgValue != '-')
9679 {
23fe70ec 9680 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 9681 return 1;
9682 }
9683 switch (aCamera->ZFocusType())
9684 {
9685 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9686 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9687 }
9688 }
b40cdc2b 9689 else if (anArgCase == "-lockzup"
9690 || anArgCase == "-turntable")
9691 {
9692 bool toLockUp = true;
9693 if (++anArgIter < theArgsNb
dae2a922 9694 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 9695 {
9696 --anArgIter;
9697 }
9698 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9699 }
6b62b2da 9700 else if (anArgCase == "-fov"
b40cdc2b 9701 || anArgCase == "-fovy"
9702 || anArgCase == "-fovx"
9703 || anArgCase == "-fov2d")
b5ac8292 9704 {
6b62b2da 9705 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9706 if (anArgValue != NULL
9707 && *anArgValue != '-')
9708 {
9709 ++anArgIter;
b40cdc2b 9710 if (anArgCase == "-fov2d")
9711 {
9712 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9713 }
9714 else if (anArgCase == "-fovx")
9715 {
9716 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9717 }
9718 else
9719 {
9720 aCamera->SetFOVy (Draw::Atof (anArgValue));
9721 }
6b62b2da 9722 continue;
9723 }
b40cdc2b 9724 if (anArgCase == "-fov2d")
9725 {
9726 theDI << aCamera->FOV2d() << " ";
9727 }
9728 else if (anArgCase == "-fovx")
9729 {
9730 theDI << aCamera->FOVx() << " ";
9731 }
9732 else
9733 {
9734 theDI << aCamera->FOVy() << " ";
9735 }
9736 }
9737 else if (anArgIter + 1 < theArgsNb
9738 && anArgCase == "-xrpose")
9739 {
9740 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9741 anXRArg.LowerCase();
9742 if (anXRArg == "base")
9743 {
9744 aCamera = aView->View()->BaseXRCamera();
9745 }
9746 else if (anXRArg == "head")
9747 {
9748 aCamera = aView->View()->PosedXRCamera();
9749 }
9750 else
9751 {
9752 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9753 return 1;
9754 }
9755 if (aCamera.IsNull())
9756 {
9757 Message::SendFail() << "Error: undefined XR pose";
9758 return 0;
9759 }
9760 if (aView->AutoZFitMode())
9761 {
9762 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9763 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9764 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9765 }
b5ac8292 9766 }
30a1b24e 9767 else if (aPrsName.IsEmpty()
9768 && !anArgCase.StartsWith ("-"))
9769 {
9770 aPrsName = anArg;
9771 }
b5ac8292 9772 else
9773 {
23fe70ec 9774 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 9775 return 1;
9776 }
9777 }
b5ac8292 9778
30a1b24e 9779 if (aPrsName.IsEmpty()
9780 || theArgsNb > 2)
9781 {
30a1b24e 9782 aView->Redraw();
9783 }
9784
9785 if (!aPrsName.IsEmpty())
9786 {
9787 Handle(AIS_CameraFrustum) aCameraFrustum;
9788 if (GetMapOfAIS().IsBound2 (aPrsName))
9789 {
9790 // find existing object
9791 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9792 if (aCameraFrustum.IsNull())
9793 {
23fe70ec 9794 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 9795 return 1;
9796 }
9797 }
9798
9799 if (aCameraFrustum.IsNull())
9800 {
9801 aCameraFrustum = new AIS_CameraFrustum();
9802 }
9803 else
9804 {
9805 // not include displayed object of old camera frustum in the new one.
9806 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9807 aView->ZFitAll();
9808 }
b40cdc2b 9809 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 9810
9811 ViewerTest::Display (aPrsName, aCameraFrustum);
9812 }
b5ac8292 9813
9814 return 0;
9815}
9816
f978241f 9817//! Parse stereo output mode
9818inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9819 Graphic3d_StereoMode& theMode)
9820{
9821 TCollection_AsciiString aFlag (theArg);
9822 aFlag.LowerCase();
9823 if (aFlag == "quadbuffer")
9824 {
9825 theMode = Graphic3d_StereoMode_QuadBuffer;
9826 }
9827 else if (aFlag == "anaglyph")
9828 {
9829 theMode = Graphic3d_StereoMode_Anaglyph;
9830 }
9831 else if (aFlag == "row"
9832 || aFlag == "rowinterlaced")
9833 {
9834 theMode = Graphic3d_StereoMode_RowInterlaced;
9835 }
9836 else if (aFlag == "col"
9837 || aFlag == "colinterlaced"
9838 || aFlag == "columninterlaced")
9839 {
9840 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9841 }
9842 else if (aFlag == "chess"
9843 || aFlag == "chessboard")
9844 {
9845 theMode = Graphic3d_StereoMode_ChessBoard;
9846 }
9847 else if (aFlag == "sbs"
9848 || aFlag == "sidebyside")
9849 {
9850 theMode = Graphic3d_StereoMode_SideBySide;
9851 }
9852 else if (aFlag == "ou"
9853 || aFlag == "overunder")
9854 {
9855 theMode = Graphic3d_StereoMode_OverUnder;
9856 }
9857 else if (aFlag == "pageflip"
9858 || aFlag == "softpageflip")
9859 {
9860 theMode = Graphic3d_StereoMode_SoftPageFlip;
9861 }
b40cdc2b 9862 else if (aFlag == "openvr"
9863 || aFlag == "vr")
9864 {
9865 theMode = Graphic3d_StereoMode_OpenVR;
9866 }
f978241f 9867 else
9868 {
9869 return Standard_False;
9870 }
9871 return Standard_True;
9872}
9873
9874//! Parse anaglyph filter
9875inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9876 Graphic3d_RenderingParams::Anaglyph& theFilter)
9877{
9878 TCollection_AsciiString aFlag (theArg);
9879 aFlag.LowerCase();
9880 if (aFlag == "redcyansimple")
9881 {
9882 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9883 }
9884 else if (aFlag == "redcyan"
9885 || aFlag == "redcyanoptimized")
9886 {
9887 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9888 }
9889 else if (aFlag == "yellowbluesimple")
9890 {
9891 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9892 }
9893 else if (aFlag == "yellowblue"
9894 || aFlag == "yellowblueoptimized")
9895 {
9896 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9897 }
9898 else if (aFlag == "greenmagenta"
9899 || aFlag == "greenmagentasimple")
9900 {
9901 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9902 }
9903 else
9904 {
9905 return Standard_False;
9906 }
9907 return Standard_True;
9908}
9909
b5ac8292 9910//==============================================================================
9911//function : VStereo
9912//purpose :
9913//==============================================================================
9914
9915static int VStereo (Draw_Interpretor& theDI,
9916 Standard_Integer theArgNb,
9917 const char** theArgVec)
9918{
f978241f 9919 Handle(V3d_View) aView = ViewerTest::CurrentView();
b8db9379 9920 if (aView.IsNull())
b5ac8292 9921 {
b8db9379 9922 Message::SendFail ("Error: no active viewer");
9923 return 0;
9924 }
b5ac8292 9925
b8db9379 9926 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9927 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9928 if (theArgNb < 2)
9929 {
9930 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
b5ac8292 9931 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 9932 if (isActive)
9933 {
9934 TCollection_AsciiString aMode;
9935 switch (aView->RenderingParams().StereoMode)
9936 {
9937 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
9938 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
9939 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
9940 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
9941 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
9942 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
9943 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 9944 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 9945 case Graphic3d_StereoMode_Anaglyph :
9946 aMode = "anaglyph";
9947 switch (aView->RenderingParams().AnaglyphFilter)
9948 {
9949 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9950 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9951 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9952 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9953 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9954 default: break;
9955 }
9956 default: break;
9957 }
9958 theDI << "Mode " << aMode << "\n";
9959 }
b5ac8292 9960 return 0;
9961 }
9962
b8db9379 9963 Graphic3d_StereoMode aMode = aParams->StereoMode;
f978241f 9964 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9965 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9966 {
9967 Standard_CString anArg = theArgVec[anArgIter];
9968 TCollection_AsciiString aFlag (anArg);
9969 aFlag.LowerCase();
9970 if (anUpdateTool.parseRedrawMode (aFlag))
9971 {
9972 continue;
9973 }
9974 else if (aFlag == "0"
9975 || aFlag == "off")
9976 {
9977 if (++anArgIter < theArgNb)
9978 {
23fe70ec 9979 Message::SendFail ("Error: wrong number of arguments");
f978241f 9980 return 1;
9981 }
9982
b8db9379 9983 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
f978241f 9984 {
9985 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9986 }
f978241f 9987 return 0;
9988 }
9989 else if (aFlag == "1"
9990 || aFlag == "on")
9991 {
9992 if (++anArgIter < theArgNb)
9993 {
23fe70ec 9994 Message::SendFail ("Error: wrong number of arguments");
f978241f 9995 return 1;
9996 }
9997
b8db9379 9998 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 9999 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10000 {
10001 return 0;
10002 }
f978241f 10003 }
10004 else if (aFlag == "-reverse"
10005 || aFlag == "-reversed"
10006 || aFlag == "-swap")
10007 {
10008 Standard_Boolean toEnable = Standard_True;
10009 if (++anArgIter < theArgNb
dae2a922 10010 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10011 {
10012 --anArgIter;
10013 }
10014 aParams->ToReverseStereo = toEnable;
10015 }
10016 else if (aFlag == "-noreverse"
10017 || aFlag == "-noswap")
10018 {
10019 Standard_Boolean toDisable = Standard_True;
10020 if (++anArgIter < theArgNb
dae2a922 10021 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10022 {
10023 --anArgIter;
10024 }
10025 aParams->ToReverseStereo = !toDisable;
10026 }
10027 else if (aFlag == "-mode"
10028 || aFlag == "-stereomode")
10029 {
10030 if (++anArgIter >= theArgNb
10031 || !parseStereoMode (theArgVec[anArgIter], aMode))
10032 {
23fe70ec 10033 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10034 return 1;
10035 }
10036
10037 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10038 {
b8db9379 10039 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10040 }
10041 }
10042 else if (aFlag == "-anaglyph"
10043 || aFlag == "-anaglyphfilter")
10044 {
10045 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10046 if (++anArgIter >= theArgNb
10047 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10048 {
23fe70ec 10049 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10050 return 1;
10051 }
10052
10053 aMode = Graphic3d_StereoMode_Anaglyph;
10054 aParams->AnaglyphFilter = aFilter;
10055 }
10056 else if (parseStereoMode (anArg, aMode)) // short syntax
10057 {
10058 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10059 {
b8db9379 10060 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10061 }
10062 }
b40cdc2b 10063 else if (anArgIter + 1 < theArgNb
10064 && aFlag == "-hmdfov2d")
10065 {
10066 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10067 if (aParams->HmdFov2d < 10.0f
10068 || aParams->HmdFov2d > 180.0f)
10069 {
10070 Message::SendFail() << "Error: FOV is out of range";
10071 return 1;
10072 }
10073 }
10074 else if (aFlag == "-mirror"
10075 || aFlag == "-mirrorcomposer")
10076 {
10077 Standard_Boolean toEnable = Standard_True;
10078 if (++anArgIter < theArgNb
dae2a922 10079 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10080 {
10081 --anArgIter;
10082 }
10083 aParams->ToMirrorComposer = toEnable;
10084 }
10085 else if (anArgIter + 1 < theArgNb
10086 && (aFlag == "-unitfactor"
10087 || aFlag == "-unitscale"))
10088 {
10089 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10090 }
f978241f 10091 else
10092 {
23fe70ec 10093 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10094 return 1;
10095 }
10096 }
10097
b8db9379 10098 aParams->StereoMode = aMode;
10099 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10100 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
f978241f 10101 {
b8db9379 10102 // initiate implicit continuous rendering
10103 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
f978241f 10104 }
b5ac8292 10105 return 0;
10106}
10107
392ac980 10108//===============================================================================================
10109//function : VDefaults
10110//purpose :
10111//===============================================================================================
10112static int VDefaults (Draw_Interpretor& theDi,
10113 Standard_Integer theArgsNb,
10114 const char** theArgVec)
10115{
10116 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10117 if (aCtx.IsNull())
10118 {
23fe70ec 10119 Message::SendFail ("Error: no active viewer");
392ac980 10120 return 1;
10121 }
10122
10123 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10124 if (theArgsNb < 2)
10125 {
10126 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10127 {
10128 theDi << "DeflType: relative\n"
10129 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10130 }
10131 else
10132 {
10133 theDi << "DeflType: absolute\n"
10134 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10135 }
67441d0c 10136 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10137 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10138 return 0;
10139 }
10140
10141 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10142 {
10143 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10144 anArg.UpperCase();
10145 if (anArg == "-ABSDEFL"
10146 || anArg == "-ABSOLUTEDEFLECTION"
10147 || anArg == "-DEFL"
10148 || anArg == "-DEFLECTION")
392ac980 10149 {
4c513386 10150 if (++anArgIter >= theArgsNb)
10151 {
23fe70ec 10152 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10153 return 1;
10154 }
392ac980 10155 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10156 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10157 }
4c513386 10158 else if (anArg == "-RELDEFL"
10159 || anArg == "-RELATIVEDEFLECTION"
10160 || anArg == "-DEVCOEFF"
10161 || anArg == "-DEVIATIONCOEFF"
10162 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10163 {
4c513386 10164 if (++anArgIter >= theArgsNb)
10165 {
23fe70ec 10166 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10167 return 1;
10168 }
392ac980 10169 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10170 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10171 }
4c513386 10172 else if (anArg == "-ANGDEFL"
10173 || anArg == "-ANGULARDEFL"
10174 || anArg == "-ANGULARDEFLECTION")
392ac980 10175 {
4c513386 10176 if (++anArgIter >= theArgsNb)
10177 {
23fe70ec 10178 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10179 return 1;
10180 }
67441d0c 10181 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10182 }
385c43e7 10183 else if (anArg == "-AUTOTR"
10184 || anArg == "-AUTOTRIANG"
10185 || anArg == "-AUTOTRIANGULATION")
4c513386 10186 {
14c7f553 10187 ++anArgIter;
10188 bool toTurnOn = true;
10189 if (anArgIter >= theArgsNb
dae2a922 10190 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10191 {
23fe70ec 10192 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10193 return 1;
10194 }
14c7f553 10195 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10196 }
10197 else
10198 {
23fe70ec 10199 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10200 return 1;
392ac980 10201 }
10202 }
10203
10204 return 0;
10205}
10206
12381341 10207//! Auxiliary method
10208inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10209 const Graphic3d_ZLayerId theLayer,
12381341 10210 const Standard_Boolean theIsGlobal)
10211{
10212 if (theLightNew.IsNull())
10213 {
10214 return;
10215 }
10216
992ed6b3 10217 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10218 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10219 {
992ed6b3 10220 aViewer->AddLight (theLightNew);
10221 if (theIsGlobal)
10222 {
10223 aViewer->SetLightOn (theLightNew);
10224 }
10225 else
10226 {
10227 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10228 }
12381341 10229 }
10230 else
10231 {
992ed6b3 10232 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10233 if (aSettings.Lights().IsNull())
10234 {
10235 aSettings.SetLights (new Graphic3d_LightSet());
10236 }
10237 aSettings.Lights()->Add (theLightNew);
10238 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10239 }
10240}
10241
10242//! Auxiliary method
10243inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10244{
10245 TCollection_AsciiString anArgNextCase (theArgNext);
10246 anArgNextCase.UpperCase();
10247 if (anArgNextCase.Length() > 5
10248 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10249 {
10250 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10251 }
10252 else
10253 {
10254 return theArgNext.IntegerValue();
10255 }
10256}
10257
2daa5d95 10258static Handle(AIS_LightSource) findLightPrs (const Handle(V3d_Light)& theLight,
10259 const bool theToShowErrors = true)
10260{
10261 if (theLight.IsNull())
10262 {
10263 if (theToShowErrors)
10264 {
10265 Message::SendFail() << "Syntax error: no active light source to find presentation";
10266 }
10267 return Handle(AIS_LightSource)();
10268 }
10269
10270 Handle(AIS_InteractiveObject) anObject;
10271 GetMapOfAIS().Find2 (theLight->Name(), anObject);
10272 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (anObject);
10273 if (aLightSource.IsNull())
10274 {
10275 if (theToShowErrors)
10276 {
10277 Message::SendFail() << "Syntax error: could not find '" << theLight->Name() << "' AIS object";
10278 }
10279 }
10280 return aLightSource;
10281}
10282
12381341 10283//===============================================================================================
10284//function : VLight
10285//purpose :
10286//===============================================================================================
10287static int VLight (Draw_Interpretor& theDi,
10288 Standard_Integer theArgsNb,
10289 const char** theArgVec)
10290{
10291 Handle(V3d_View) aView = ViewerTest::CurrentView();
10292 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10293 if (aView.IsNull()
10294 || aViewer.IsNull())
10295 {
23fe70ec 10296 Message::SendFail ("Error: no active viewer");
12381341 10297 return 1;
10298 }
10299
ee2be2a8 10300 Standard_Real anXYZ[3] = {};
10301 Standard_Real anAtten[2] = {};
12381341 10302 if (theArgsNb < 2)
10303 {
10304 // print lights info
10305 Standard_Integer aLightId = 0;
6a24c6de 10306 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10307 {
6a24c6de 10308 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10309 const Quantity_Color aColor = aLight->Color();
992ed6b3 10310 theDi << "Light #" << aLightId
10311 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10312 << " [" << aLight->GetId() << "]" << "\n";
12381341 10313 switch (aLight->Type())
10314 {
10315 case V3d_AMBIENT:
10316 {
189f85a3 10317 theDi << " Type: Ambient\n";
10318 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10319 break;
10320 }
10321 case V3d_DIRECTIONAL:
10322 {
189f85a3 10323 theDi << " Type: Directional\n";
10324 theDi << " Intensity: " << aLight->Intensity() << "\n";
10325 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10326 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10327 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10328 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10329 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10330 break;
10331 }
10332 case V3d_POSITIONAL:
10333 {
189f85a3 10334 theDi << " Type: Positional\n";
10335 theDi << " Intensity: " << aLight->Intensity() << "\n";
10336 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10337 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10338 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10339 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10340 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10341 aLight->Attenuation (anAtten[0], anAtten[1]);
10342 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
88b312d3 10343 theDi << " Range: " << aLight->Range() << "\n";
12381341 10344 break;
10345 }
10346 case V3d_SPOT:
10347 {
189f85a3 10348 theDi << " Type: Spot\n";
10349 theDi << " Intensity: " << aLight->Intensity() << "\n";
10350 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10351 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10352 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10353 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10354 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10355 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10356 aLight->Attenuation (anAtten[0], anAtten[1]);
10357 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10358 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10359 theDi << " Exponent: " << aLight->Concentration() << "\n";
88b312d3 10360 theDi << " Range: " << aLight->Range() << "\n";
12381341 10361 break;
10362 }
10363 default:
10364 {
189f85a3 10365 theDi << " Type: UNKNOWN\n";
12381341 10366 break;
10367 }
10368 }
992ed6b3 10369 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10370 }
10371 }
10372
2daa5d95 10373 Handle(V3d_Light) aLightNew, aLightOld;
992ed6b3 10374 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10375 Standard_Boolean isGlobal = Standard_True;
10376 Standard_Boolean toCreate = Standard_False;
761d8807 10377 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10378 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10379 {
992ed6b3 10380 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10381
10382 TCollection_AsciiString aName, aValue;
10383 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10384 TCollection_AsciiString anArgCase (anArg);
10385 anArgCase.UpperCase();
761d8807 10386 if (anUpdateTool.parseRedrawMode (anArg))
10387 {
10388 continue;
10389 }
10390
12381341 10391 if (anArgCase.IsEqual ("NEW")
10392 || anArgCase.IsEqual ("ADD")
992ed6b3 10393 || anArgCase.IsEqual ("CREATE")
10394 || anArgCase.IsEqual ("-NEW")
10395 || anArgCase.IsEqual ("-ADD")
10396 || anArgCase.IsEqual ("-CREATE"))
12381341 10397 {
10398 toCreate = Standard_True;
10399 }
992ed6b3 10400 else if (anArgCase.IsEqual ("-LAYER")
10401 || anArgCase.IsEqual ("-ZLAYER"))
10402 {
10403 if (++anArgIt >= theArgsNb)
10404 {
23fe70ec 10405 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10406 return 1;
10407 }
10408
10409 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10410 aValStr.LowerCase();
10411 if (aValStr == "default"
10412 || aValStr == "def")
10413 {
10414 aLayer = Graphic3d_ZLayerId_Default;
10415 }
10416 else if (aValStr == "top")
10417 {
10418 aLayer = Graphic3d_ZLayerId_Top;
10419 }
10420 else if (aValStr == "topmost")
10421 {
10422 aLayer = Graphic3d_ZLayerId_Topmost;
10423 }
10424 else if (aValStr == "toposd"
10425 || aValStr == "osd")
10426 {
10427 aLayer = Graphic3d_ZLayerId_TopOSD;
10428 }
10429 else if (aValStr == "botosd"
10430 || aValStr == "bottom")
10431 {
10432 aLayer = Graphic3d_ZLayerId_BotOSD;
10433 }
10434 else if (aValStr.IsIntegerValue())
10435 {
10436 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10437 }
10438 else
10439 {
23fe70ec 10440 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10441 return 1;
10442 }
10443 }
12381341 10444 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10445 || anArgCase.IsEqual ("GLOBAL")
10446 || anArgCase.IsEqual ("-GLOB")
10447 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10448 {
10449 isGlobal = Standard_True;
10450 }
10451 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10452 || anArgCase.IsEqual ("LOCAL")
10453 || anArgCase.IsEqual ("-LOC")
10454 || anArgCase.IsEqual ("-LOCAL"))
12381341 10455 {
10456 isGlobal = Standard_False;
10457 }
4fe9ad57 10458 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10459 || anArgCase.IsEqual ("DEFAULTS")
10460 || anArgCase.IsEqual ("-DEF")
10461 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10462 {
10463 toCreate = Standard_False;
10464 aViewer->SetDefaultLights();
10465 }
10466 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10467 || anArgCase.IsEqual ("CLEAR")
10468 || anArgCase.IsEqual ("-CLR")
10469 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10470 {
10471 toCreate = Standard_False;
992ed6b3 10472
10473 TColStd_SequenceOfInteger aLayers;
10474 aViewer->GetAllZLayers (aLayers);
10475 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10476 {
992ed6b3 10477 if (aLayeriter.Value() == aLayer
10478 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10479 {
10480 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10481 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10482 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10483 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10484 {
10485 break;
10486 }
10487 }
10488 }
10489
10490 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10491 {
2daa5d95 10492 ViewerTest_DoubleMapOfInteractiveAndName aMap = GetMapOfAIS();
992ed6b3 10493 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10494 {
10495 Handle(V3d_Light) aLight = aLightIter.Value();
2daa5d95 10496 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLight, false))
10497 {
10498 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10499 GetMapOfAIS().UnBind2 (aLight->Name());
10500 }
992ed6b3 10501 aViewer->DelLight (aLight);
10502 aLightIter = aView->ActiveLightIterator();
10503 }
4fe9ad57 10504 }
10505 }
12381341 10506 else if (anArgCase.IsEqual ("AMB")
10507 || anArgCase.IsEqual ("AMBIENT")
10508 || anArgCase.IsEqual ("AMBLIGHT"))
10509 {
12381341 10510 if (!toCreate)
10511 {
23fe70ec 10512 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10513 return 1;
10514 }
992ed6b3 10515
10516 addLight (aLightNew, aLayer, isGlobal);
12381341 10517 toCreate = Standard_False;
992ed6b3 10518 aLightNew = new V3d_AmbientLight();
12381341 10519 }
10520 else if (anArgCase.IsEqual ("DIRECTIONAL")
10521 || anArgCase.IsEqual ("DIRLIGHT"))
10522 {
12381341 10523 if (!toCreate)
10524 {
23fe70ec 10525 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10526 return 1;
10527 }
992ed6b3 10528
10529 addLight (aLightNew, aLayer, isGlobal);
12381341 10530 toCreate = Standard_False;
992ed6b3 10531 aLightNew = new V3d_DirectionalLight();
12381341 10532 }
10533 else if (anArgCase.IsEqual ("SPOT")
10534 || anArgCase.IsEqual ("SPOTLIGHT"))
10535 {
12381341 10536 if (!toCreate)
10537 {
23fe70ec 10538 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10539 return 1;
10540 }
992ed6b3 10541
10542 addLight (aLightNew, aLayer, isGlobal);
12381341 10543 toCreate = Standard_False;
992ed6b3 10544 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10545 }
10546 else if (anArgCase.IsEqual ("POSLIGHT")
10547 || anArgCase.IsEqual ("POSITIONAL"))
10548 {
12381341 10549 if (!toCreate)
10550 {
23fe70ec 10551 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10552 return 1;
10553 }
992ed6b3 10554
10555 addLight (aLightNew, aLayer, isGlobal);
12381341 10556 toCreate = Standard_False;
992ed6b3 10557 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10558 }
992ed6b3 10559 else if (anArgCase.IsEqual ("CHANGE")
10560 || anArgCase.IsEqual ("-CHANGE"))
12381341 10561 {
12381341 10562 if (++anArgIt >= theArgsNb)
10563 {
23fe70ec 10564 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10565 return 1;
10566 }
10567
992ed6b3 10568 addLight (aLightNew, aLayer, isGlobal);
10569 aLightNew.Nullify();
12381341 10570 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
10571 Standard_Integer aLightIt = 0;
6a24c6de 10572 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10573 {
10574 if (aLightIt == aLightId)
10575 {
6a24c6de 10576 aLightOld = aLightIter.Value();
12381341 10577 break;
10578 }
10579 }
10580
10581 if (aLightOld.IsNull())
10582 {
23fe70ec 10583 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
12381341 10584 return 1;
10585 }
10586 }
2daa5d95 10587 else if (anArgCase == "-DISPLAY"
10588 || anArgCase == "-DISP"
10589 || anArgCase == "-PRESENTATION"
10590 || anArgCase == "-PRS")
10591 {
10592 if (aLightCurr.IsNull())
10593 {
10594 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10595 return 1;
10596 }
10597
10598 TCollection_AsciiString aLightName = aLightCurr->Name();
10599 if (++anArgIt > theArgsNb
10600 && aLightName.IsEmpty())
10601 {
10602 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10603 return 1;
10604 }
10605 if (anArgIt < theArgsNb)
10606 {
10607 if (theArgVec[anArgIt][0] != '-')
10608 {
10609 aLightName = theArgVec[anArgIt];
10610 aLightCurr->SetName (aLightName);
10611 }
10612 else
10613 {
10614 --anArgIt;
10615 }
10616 }
10617 if (aLightName.IsEmpty())
10618 {
10619 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10620 return 1;
10621 }
10622 ViewerTest::Display (aLightName, new AIS_LightSource (aLightCurr), false);
10623 }
10624 else if (anArgCase == "DEL"
10625 || anArgCase == "DELETE"
10626 || anArgCase == "-DEL"
10627 || anArgCase == "-DELETE"
10628 || anArgCase == "-REMOVE")
12381341 10629 {
10630 Handle(V3d_Light) aLightDel;
10631 if (++anArgIt >= theArgsNb)
10632 {
23fe70ec 10633 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10634 return 1;
10635 }
10636
10637 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
10638 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
10639 Standard_Integer aLightIt = 0;
6a24c6de 10640 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10641 {
6a24c6de 10642 aLightDel = aLightIter.Value();
12381341 10643 if (aLightIt == aLightDelId)
10644 {
10645 break;
10646 }
10647 }
992ed6b3 10648 if (aLightDel.IsNull())
10649 {
10650 continue;
10651 }
10652
10653 TColStd_SequenceOfInteger aLayers;
10654 aViewer->GetAllZLayers (aLayers);
10655 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10656 {
10657 if (aLayeriter.Value() == aLayer
10658 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10659 {
10660 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10661 if (!aSettings.Lights().IsNull())
10662 {
10663 aSettings.Lights()->Remove (aLightDel);
10664 if (aSettings.Lights()->IsEmpty())
10665 {
10666 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10667 }
10668 }
10669 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10670 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10671 {
10672 break;
10673 }
10674 }
10675 }
10676
10677 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10678 {
2daa5d95 10679 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLightDel, false))
10680 {
10681 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10682 GetMapOfAIS().UnBind2 (aLightDel->Name());
10683 }
12381341 10684 aViewer->DelLight (aLightDel);
10685 }
10686 }
10687 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 10688 || anArgCase.IsEqual ("COLOUR")
10689 || anArgCase.IsEqual ("-COLOR")
10690 || anArgCase.IsEqual ("-COLOUR"))
12381341 10691 {
dae2a922 10692 Quantity_Color aColor;
10693 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10694 theArgVec + anArgIt + 1,
10695 aColor);
10696 anArgIt += aNbParsed;
10697 if (aNbParsed == 0
992ed6b3 10698 || aLightCurr.IsNull())
12381341 10699 {
23fe70ec 10700 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10701 return 1;
10702 }
992ed6b3 10703 aLightCurr->SetColor (aColor);
12381341 10704 }
2daa5d95 10705 else if (anArgCase == "POS"
10706 || anArgCase == "POSITION"
10707 || anArgCase == "-POS"
10708 || anArgCase == "-POSITION"
10709 || anArgCase == "-PRSPOSITION"
10710 || anArgCase == "-PRSPOS")
12381341 10711 {
2daa5d95 10712 gp_XYZ aPosXYZ;
992ed6b3 10713 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10714 || !parseXYZ (theArgVec + anArgIt + 1, aPosXYZ)
10715 || aLightCurr.IsNull())
12381341 10716 {
23fe70ec 10717 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10718 return 1;
10719 }
10720
2daa5d95 10721 anArgIt += 3;
10722 if (anArgCase == "-PRSPOSITION"
10723 || anArgCase == "-PRSPOS")
10724 {
10725 aLightCurr->SetDisplayPosition (aPosXYZ);
10726 }
10727 else
10728 {
10729 if (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10730 && aLightCurr->Type() != Graphic3d_TOLS_SPOT)
10731 {
10732 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10733 return 1;
10734 }
10735
10736 aLightCurr->SetPosition (aPosXYZ);
10737 }
12381341 10738 }
10739 else if (anArgCase.IsEqual ("DIR")
992ed6b3 10740 || anArgCase.IsEqual ("DIRECTION")
10741 || anArgCase.IsEqual ("-DIR")
10742 || anArgCase.IsEqual ("-DIRECTION"))
12381341 10743 {
2daa5d95 10744 gp_XYZ aDirXYZ;
992ed6b3 10745 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10746 || !parseXYZ (theArgVec + anArgIt + 1, aDirXYZ)
992ed6b3 10747 || aLightCurr.IsNull()
10748 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
10749 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10750 {
23fe70ec 10751 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10752 return 1;
10753 }
10754
2daa5d95 10755 anArgIt += 3;
10756 aLightCurr->SetDirection (gp_Dir (aDirXYZ));
12381341 10757 }
189f85a3 10758 else if (anArgCase.IsEqual ("SM")
992ed6b3 10759 || anArgCase.IsEqual ("SMOOTHNESS")
10760 || anArgCase.IsEqual ("-SM")
10761 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 10762 {
992ed6b3 10763 if (++anArgIt >= theArgsNb
10764 || aLightCurr.IsNull())
189f85a3 10765 {
23fe70ec 10766 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10767 return 1;
10768 }
10769
992ed6b3 10770 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10771 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 10772 {
10773 aLightCurr->SetIntensity (1.f);
10774 }
992ed6b3 10775 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 10776 {
10777 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10778 }
10779 else
10780 {
10781 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
10782 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10783 }
10784
992ed6b3 10785 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 10786 {
992ed6b3 10787 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 10788 }
992ed6b3 10789 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 10790 {
992ed6b3 10791 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 10792 }
10793 }
10794 else if (anArgCase.IsEqual ("INT")
992ed6b3 10795 || anArgCase.IsEqual ("INTENSITY")
10796 || anArgCase.IsEqual ("-INT")
10797 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 10798 {
992ed6b3 10799 if (++anArgIt >= theArgsNb
10800 || aLightCurr.IsNull())
189f85a3 10801 {
23fe70ec 10802 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10803 return 1;
10804 }
10805
992ed6b3 10806 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10807 aLightCurr->SetIntensity (aIntensity);
189f85a3 10808 }
4fe9ad57 10809 else if (anArgCase.IsEqual ("ANG")
992ed6b3 10810 || anArgCase.IsEqual ("ANGLE")
10811 || anArgCase.IsEqual ("-ANG")
10812 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 10813 {
992ed6b3 10814 if (++anArgIt >= theArgsNb
10815 || aLightCurr.IsNull()
10816 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 10817 {
23fe70ec 10818 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4fe9ad57 10819 return 1;
10820 }
992ed6b3 10821 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
2daa5d95 10822 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10823 aLightCurr->SetAngle (anAngle);
4fe9ad57 10824 }
12381341 10825 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 10826 || anArgCase.IsEqual ("CONSTATTENUATION")
10827 || anArgCase.IsEqual ("-CONSTATTEN")
10828 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 10829 {
992ed6b3 10830 if (++anArgIt >= theArgsNb
10831 || aLightCurr.IsNull()
10832 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10833 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10834 {
23fe70ec 10835 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10836 return 1;
10837 }
10838
992ed6b3 10839 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10840 anAtten[0] = Atof (theArgVec[anArgIt]);
10841 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10842 }
10843 else if (anArgCase.IsEqual ("LINATTEN")
10844 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 10845 || anArgCase.IsEqual ("LINEARATTENUATION")
10846 || anArgCase.IsEqual ("-LINATTEN")
10847 || anArgCase.IsEqual ("-LINEARATTEN")
10848 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 10849 {
992ed6b3 10850 if (++anArgIt >= theArgsNb
10851 || aLightCurr.IsNull()
10852 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10853 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10854 {
23fe70ec 10855 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10856 return 1;
10857 }
10858
992ed6b3 10859 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10860 anAtten[1] = Atof (theArgVec[anArgIt]);
10861 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10862 }
10863 else if (anArgCase.IsEqual ("EXP")
10864 || anArgCase.IsEqual ("EXPONENT")
10865 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 10866 || anArgCase.IsEqual ("SPOTEXPONENT")
10867 || anArgCase.IsEqual ("-EXP")
10868 || anArgCase.IsEqual ("-EXPONENT")
10869 || anArgCase.IsEqual ("-SPOTEXP")
10870 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 10871 {
992ed6b3 10872 if (++anArgIt >= theArgsNb
10873 || aLightCurr.IsNull()
10874 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 10875 {
23fe70ec 10876 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10877 return 1;
10878 }
10879
992ed6b3 10880 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 10881 }
88b312d3 10882 else if (anArgCase.IsEqual("RANGE")
10883 || anArgCase.IsEqual("-RANGE"))
10884 {
10885 if (++anArgIt >= theArgsNb
10886 || aLightCurr.IsNull()
10887 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
10888 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
10889 {
23fe70ec 10890 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
88b312d3 10891 return 1;
10892 }
2daa5d95 10893 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
10894 aLightCurr->SetRange (aRange);
88b312d3 10895 }
12381341 10896 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 10897 || anArgCase.IsEqual ("HEADLIGHT")
10898 || anArgCase.IsEqual ("-HEAD")
10899 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 10900 {
992ed6b3 10901 if (aLightCurr.IsNull()
10902 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 10903 {
23fe70ec 10904 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10905 return 1;
10906 }
10907
992ed6b3 10908 Standard_Boolean isHeadLight = Standard_True;
10909 if (anArgIt + 1 < theArgsNb
dae2a922 10910 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 10911 {
992ed6b3 10912 ++anArgIt;
12381341 10913 }
992ed6b3 10914 aLightCurr->SetHeadlight (isHeadLight);
12381341 10915 }
2daa5d95 10916 else if (anArgCase.IsEqual ("NAME")
10917 || anArgCase.IsEqual ("-NAME"))
10918 {
10919 if ((anArgIt + 1) >= theArgsNb
10920 || aLightCurr.IsNull())
10921 {
10922 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10923 return 1;
10924 }
10925 aName = theArgVec[++anArgIt];
10926 aLightCurr->SetName (aName);
10927 }
10928 else if (anArgCase == "-SHOWZOOMABLE"
10929 || anArgCase == "-PRSZOOMABLE"
10930 || anArgCase == "-ZOOMABLE")
10931 {
10932 if (aLightCurr.IsNull())
10933 {
10934 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10935 return 1;
10936 }
10937
10938 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
10939 {
10940 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10941 aLightSource->SetZoomable (isZoomable);
10942 }
10943 else
10944 {
10945 return 1;
10946 }
10947 }
10948 else if (anArgCase == "-SHOWNAME"
10949 || anArgCase == "-PRSNAME")
10950 {
10951 if (aLightCurr.IsNull())
10952 {
10953 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10954 return 1;
10955 }
10956
10957 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
10958 {
10959 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10960 aLightSource->SetDisplayName (toDisplay);
10961 }
10962 else
10963 {
10964 return 1;
10965 }
10966 }
10967 else if (anArgCase == "-SHOWRANGE"
10968 || anArgCase == "-PRSRANGE")
10969 {
10970 if (aLightCurr.IsNull()
10971 || (aLightCurr->Type() != Graphic3d_TOLS_SPOT
10972 && aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL))
10973 {
10974 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10975 return 1;
10976 }
10977
10978 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
10979 {
10980 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10981 aLightSource->SetDisplayRange (toDisplay);
10982 }
10983 else
10984 {
10985 return 1;
10986 }
10987 }
10988 else if (anArgCase == "-SHOWSIZE"
10989 || anArgCase == "-PRSSIZE")
10990 {
10991 Standard_Real aSize = 0.0;
10992 if ((anArgIt + 1) >= theArgsNb
10993 || !Draw::ParseReal (theArgVec[anArgIt + 1], aSize)
10994 || aSize <= 0.0)
10995 {
10996 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10997 return 1;
10998 }
10999
11000 ++anArgIt;
11001 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11002 {
11003 aLightSource->SetSize (aSize);
11004 }
11005 else
11006 {
11007 return 1;
11008 }
11009 }
d84e8669 11010 else if (anArgCase.IsEqual ("-CASTSHADOW")
11011 || anArgCase.IsEqual ("-CASTSHADOWS")
11012 || anArgCase.IsEqual ("-SHADOWS"))
11013 {
11014 if (aLightCurr.IsNull()
11015 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
11016 {
11017 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11018 return 1;
11019 }
11020
11021 bool toCastShadows = true;
11022 if (anArgIt + 1 < theArgsNb
11023 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
11024 {
11025 ++anArgIt;
11026 }
11027 aLightCurr->SetCastShadows (toCastShadows);
11028 }
12381341 11029 else
11030 {
23fe70ec 11031 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
12381341 11032 }
11033 }
11034
992ed6b3 11035 addLight (aLightNew, aLayer, isGlobal);
2daa5d95 11036
11037 struct LightPrsSort
11038 {
11039 bool operator() (const Handle(AIS_LightSource)& theLeft,
11040 const Handle(AIS_LightSource)& theRight)
11041 {
11042 return theLeft->Light()->GetId() < theRight->Light()->GetId();
11043 }
11044 };
11045
11046 AIS_ListOfInteractive aPrsList;
11047 ViewerTest::GetAISContext()->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
11048 if (!aPrsList.IsEmpty())
11049 {
11050 // update light source presentations
11051 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
11052 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
11053 {
11054 if (Handle(AIS_LightSource) aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
11055 {
11056 aLightPrsVec.push_back (aLightPrs);
11057 }
11058 }
11059
11060 // sort objects by id as AIS_InteractiveContext stores them in unordered map
11061 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
11062
11063 Standard_Integer aTopStack = 0;
11064 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
11065 {
11066 Handle(AIS_LightSource) aLightPrs = *aPrsIter;
11067 if (!aLightPrs->TransformPersistence().IsNull()
11068 && aLightPrs->TransformPersistence()->IsTrihedronOr2d())
11069 {
11070 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs->Size();
11071 aLightPrs->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
11072 aTopStack += aPrsSize + aPrsSize / 2;
11073 }
11074 ViewerTest::GetAISContext()->Redisplay (aLightPrs, false);
11075 ViewerTest::GetAISContext()->SetTransformPersistence (aLightPrs, aLightPrs->TransformPersistence());
11076 }
11077 }
12381341 11078 return 0;
11079}
11080
67312b79 11081//===============================================================================================
11082//function : VPBREnvironment
11083//purpose :
11084//===============================================================================================
11085static int VPBREnvironment (Draw_Interpretor&,
11086 Standard_Integer theArgsNb,
11087 const char** theArgVec)
11088{
11089 if (theArgsNb > 2)
11090 {
23fe70ec 11091 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11092 return 1;
11093 }
11094
11095 Handle(V3d_View) aView = ViewerTest::CurrentView();
11096 if (aView.IsNull())
11097 {
23fe70ec 11098 Message::SendFail ("Error: no active viewer");
67312b79 11099 return 1;
11100 }
11101
11102 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11103 anArg.LowerCase();
11104
11105 if (anArg == "-generate"
11106 || anArg == "-gen")
11107 {
11108 aView->GeneratePBREnvironment (Standard_True);
11109 }
11110 else if (anArg == "-clear")
11111 {
11112 aView->ClearPBREnvironment (Standard_True);
11113 }
11114 else
11115 {
23fe70ec 11116 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11117 return 1;
11118 }
11119
11120 return 0;
11121}
11122
15669413 11123//! Read Graphic3d_RenderingParams::PerfCounters flag.
11124static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11125 Standard_Boolean& theToReset,
11126 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11127 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11128{
11129 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11130 TCollection_AsciiString aVal = theValue;
11131 Standard_Boolean toReverse = Standard_False;
11132 if (aVal == "none")
11133 {
11134 theToReset = Standard_True;
11135 return Standard_True;
11136 }
11137 else if (aVal.StartsWith ("-"))
11138 {
11139 toReverse = Standard_True;
11140 aVal = aVal.SubString (2, aVal.Length());
11141 }
11142 else if (aVal.StartsWith ("no"))
11143 {
11144 toReverse = Standard_True;
11145 aVal = aVal.SubString (3, aVal.Length());
11146 }
11147 else if (aVal.StartsWith ("+"))
11148 {
11149 aVal = aVal.SubString (2, aVal.Length());
11150 }
11151 else
11152 {
11153 theToReset = Standard_True;
11154 }
11155
11156 if ( aVal == "fps"
11157 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11158 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11159 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11160 else if (aVal == "structs"
11161 || aVal == "structures"
11162 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11163 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11164 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11165 else if (aVal == "tris"
11166 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11167 else if (aVal == "pnts"
11168 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11169 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11170 else if (aVal == "mem"
11171 || aVal == "gpumem"
11172 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11173 else if (aVal == "skipimmediate"
11174 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11175 else if (aVal == "frametime"
11176 || aVal == "frametimers"
11177 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11178 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11179 else if (aVal == "extended"
11180 || aVal == "verbose"
11181 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11182 else if (aVal == "full"
11183 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11184 else
11185 {
11186 return Standard_False;
11187 }
11188
11189 if (toReverse)
11190 {
11191 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11192 }
11193 else
11194 {
11195 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11196 }
11197 return Standard_True;
11198}
11199
11200//! Read Graphic3d_RenderingParams::PerfCounters flags.
11201static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11202 Graphic3d_RenderingParams::PerfCounters& theFlags)
11203{
11204 TCollection_AsciiString aValue = theValue;
11205 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11206 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11207 Standard_Boolean toReset = Standard_False;
11208 for (;;)
11209 {
11210 Standard_Integer aSplitPos = aValue.Search ("|");
11211 if (aSplitPos <= 0)
11212 {
11213 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11214 {
11215 return Standard_False;
11216 }
11217 if (toReset)
11218 {
11219 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11220 }
11221 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11222 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11223 return Standard_True;
11224 }
11225
11226 if (aSplitPos > 1)
11227 {
11228 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11229 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11230 {
11231 return Standard_False;
11232 }
11233 }
11234 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11235 }
11236}
11237
e276548b 11238//=======================================================================
bc8c79bb 11239//function : VRenderParams
11240//purpose : Enables/disables rendering features
e276548b 11241//=======================================================================
11242
bc8c79bb 11243static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11244 Standard_Integer theArgNb,
11245 const char** theArgVec)
e276548b 11246{
7ae4a307 11247 Handle(V3d_View) aView = ViewerTest::CurrentView();
11248 if (aView.IsNull())
e276548b 11249 {
23fe70ec 11250 Message::SendFail ("Error: no active viewer");
e276548b 11251 return 1;
11252 }
bc8c79bb 11253
11254 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11255 TCollection_AsciiString aCmdName (theArgVec[0]);
11256 aCmdName.LowerCase();
11257 if (aCmdName == "vraytrace")
11258 {
11259 if (theArgNb == 1)
11260 {
11261 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11262 return 0;
11263 }
11264 else if (theArgNb == 2)
11265 {
11266 TCollection_AsciiString aValue (theArgVec[1]);
11267 aValue.LowerCase();
11268 if (aValue == "on"
11269 || aValue == "1")
11270 {
11271 aParams.Method = Graphic3d_RM_RAYTRACING;
11272 aView->Redraw();
11273 return 0;
11274 }
11275 else if (aValue == "off"
11276 || aValue == "0")
11277 {
11278 aParams.Method = Graphic3d_RM_RASTERIZATION;
11279 aView->Redraw();
11280 return 0;
11281 }
11282 else
11283 {
23fe70ec 11284 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11285 return 1;
11286 }
11287 }
11288 else
11289 {
23fe70ec 11290 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11291 return 1;
11292 }
11293 }
bc8c79bb 11294
11295 if (theArgNb < 2)
e276548b 11296 {
bc8c79bb 11297 theDI << "renderMode: ";
11298 switch (aParams.Method)
11299 {
11300 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11301 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11302 }
11303 theDI << "\n";
a1073ae2 11304 theDI << "transparency: ";
11305 switch (aParams.TransparencyMethod)
11306 {
11307 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11308 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11309 << TCollection_AsciiString (aParams.OitDepthFactor); break;
78c4e836 11310 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11311 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
a1073ae2 11312 }
11313 theDI << "\n";
b4327ba8 11314 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11315 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11316 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11317 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11318 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
d84e8669 11319 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11320 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
b4327ba8 11321 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11322 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11323 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11324 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11325 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11326 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11327 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11328 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11329 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11330 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11331 theDI << "shadingModel: ";
11332 switch (aView->ShadingModel())
11333 {
67312b79 11334 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11335 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11336 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11337 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11338 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11339 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11340 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11341 }
37f80e16 11342 theDI << "\n";
15669413 11343 {
11344 theDI << "perfCounters:";
11345 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11346 {
11347 theDI << " fps";
11348 }
11349 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11350 {
11351 theDI << " cpu";
11352 }
11353 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11354 {
11355 theDI << " structs";
11356 }
11357 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11358 {
11359 theDI << " groups";
11360 }
11361 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11362 {
11363 theDI << " arrays";
11364 }
11365 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11366 {
11367 theDI << " tris";
11368 }
b9f43ad1 11369 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11370 {
11371 theDI << " lines";
11372 }
15669413 11373 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11374 {
11375 theDI << " pnts";
11376 }
11377 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11378 {
11379 theDI << " gpumem";
11380 }
5e30547b 11381 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11382 {
11383 theDI << " frameTime";
11384 }
11385 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11386 {
11387 theDI << " skipimmediate";
11388 }
15669413 11389 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11390 {
11391 theDI << " none";
11392 }
11393 theDI << "\n";
11394 }
f88457e6 11395 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11396 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11397 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11398 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11399 "noUpdate") << "\n";
8625ef7e 11400 theDI << "\n";
bc8c79bb 11401 return 0;
e276548b 11402 }
11403
4c7a3fae 11404 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11405 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11406 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11407 {
bc8c79bb 11408 Standard_CString anArg (theArgVec[anArgIter]);
11409 TCollection_AsciiString aFlag (anArg);
11410 aFlag.LowerCase();
8625ef7e 11411 if (anUpdateTool.parseRedrawMode (aFlag))
11412 {
11413 continue;
11414 }
11415 else if (aFlag == "-echo"
11416 || aFlag == "-print")
e276548b 11417 {
bc8c79bb 11418 toPrint = Standard_True;
8625ef7e 11419 anUpdateTool.Invalidate();
e276548b 11420 }
4c7a3fae 11421 else if (aFlag == "-reset")
11422 {
11423 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11424 }
11425 else if (aFlag == "-sync"
11426 && (anArgIter + 1 < theArgNb))
11427 {
11428 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11429 aSyncFlag.LowerCase();
11430 if (aSyncFlag == "default"
11431 || aSyncFlag == "defaults"
11432 || aSyncFlag == "viewer")
11433 {
11434 toSyncDefaults = true;
11435 }
11436 else if (aSyncFlag == "allviews"
11437 || aSyncFlag == "views")
11438 {
11439 toSyncAllViews = true;
11440 }
11441 else
11442 {
11443 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11444 return 1;
11445 }
11446 }
bc8c79bb 11447 else if (aFlag == "-mode"
11448 || aFlag == "-rendermode"
11449 || aFlag == "-render_mode")
e276548b 11450 {
bc8c79bb 11451 if (toPrint)
11452 {
11453 switch (aParams.Method)
11454 {
11455 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11456 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11457 }
11458 continue;
11459 }
e276548b 11460 else
bc8c79bb 11461 {
23fe70ec 11462 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11463 return 1;
11464 }
11465 }
11466 else if (aFlag == "-ray"
11467 || aFlag == "-raytrace")
11468 {
11469 if (toPrint)
11470 {
11471 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11472 continue;
11473 }
11474
4c7a3fae 11475 bool isRayTrace = true;
11476 if (anArgIter + 1 < theArgNb
dae2a922 11477 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11478 {
11479 ++anArgIter;
11480 }
11481 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11482 }
bc8c79bb 11483 else if (aFlag == "-rast"
11484 || aFlag == "-raster"
11485 || aFlag == "-rasterization")
e276548b 11486 {
bc8c79bb 11487 if (toPrint)
11488 {
11489 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11490 continue;
11491 }
11492
4c7a3fae 11493 bool isRaster = true;
11494 if (anArgIter + 1 < theArgNb
dae2a922 11495 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11496 {
11497 ++anArgIter;
11498 }
11499 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11500 }
3c4b62a4 11501 else if (aFlag == "-msaa")
11502 {
11503 if (toPrint)
11504 {
11505 theDI << aParams.NbMsaaSamples << " ";
11506 continue;
11507 }
11508 else if (++anArgIter >= theArgNb)
11509 {
23fe70ec 11510 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11511 return 1;
11512 }
11513
11514 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11515 if (aNbSamples < 0)
11516 {
23fe70ec 11517 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 11518 return 1;
11519 }
11520 else
11521 {
11522 aParams.NbMsaaSamples = aNbSamples;
11523 }
11524 }
2a332745 11525 else if (aFlag == "-linefeather"
11526 || aFlag == "-edgefeather"
11527 || aFlag == "-feather")
11528 {
11529 if (toPrint)
11530 {
11531 theDI << " " << aParams.LineFeather << " ";
11532 continue;
11533 }
11534 else if (++anArgIter >= theArgNb)
11535 {
23fe70ec 11536 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 11537 return 1;
11538 }
11539
11540 TCollection_AsciiString aParam = theArgVec[anArgIter];
11541 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11542 if (aFeather <= 0.0f)
11543 {
23fe70ec 11544 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 11545 return 1;
11546 }
11547 aParams.LineFeather = aFeather;
11548 }
a1073ae2 11549 else if (aFlag == "-oit")
11550 {
11551 if (toPrint)
11552 {
11553 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11554 {
11555 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11556 }
78c4e836 11557 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11558 {
11559 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11560 }
a1073ae2 11561 else
11562 {
11563 theDI << "off" << " ";
11564 }
11565 continue;
11566 }
11567 else if (++anArgIter >= theArgNb)
11568 {
23fe70ec 11569 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11570 return 1;
11571 }
11572
11573 TCollection_AsciiString aParam = theArgVec[anArgIter];
11574 aParam.LowerCase();
78c4e836 11575 if (aParam == "peeling"
11576 || aParam == "peel")
11577 {
11578 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11579 if (anArgIter + 1 < theArgNb
11580 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11581 {
11582 ++anArgIter;
11583 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11584 if (aNbLayers < 2)
11585 {
11586 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11587 return 1;
11588 }
11589 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11590 }
11591 }
11592 else if (aParam == "weighted"
11593 || aParam == "weight")
11594 {
11595 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11596 if (anArgIter + 1 < theArgNb
11597 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11598 {
11599 ++anArgIter;
11600 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11601 if (aWeight < 0.f || aWeight > 1.f)
11602 {
11603 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11604 return 1;
11605 }
11606 aParams.OitDepthFactor = aWeight;
11607 }
11608 }
11609 else if (aParam.IsRealValue())
a1073ae2 11610 {
11611 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11612 if (aWeight < 0.f || aWeight > 1.f)
11613 {
23fe70ec 11614 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 11615 return 1;
11616 }
11617
11618 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11619 aParams.OitDepthFactor = aWeight;
11620 }
11621 else if (aParam == "off")
11622 {
11623 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11624 }
11625 else
11626 {
23fe70ec 11627 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11628 return 1;
11629 }
11630 }
d37aef5c 11631 else if (aFlag == "-fonthinting"
11632 || aFlag == "-fonthint")
11633 {
11634 if (toPrint)
11635 {
11636 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11637 {
11638 theDI << "normal" << " ";
11639 }
11640 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11641 {
11642 theDI << "light" << " ";
11643 }
11644 else
11645 {
11646 theDI << "off" << " ";
11647 }
11648 continue;
11649 }
11650 else if (anArgIter + 1 >= theArgNb)
11651 {
11652 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11653 return 1;
11654 }
11655
11656 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11657 aHintStyle.LowerCase();
11658 if (aHintStyle == "normal"
11659 || aHintStyle == "on"
11660 || aHintStyle == "1")
11661 {
11662 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11663 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11664 }
11665 else if (aHintStyle == "light")
11666 {
11667 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11668 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11669 }
11670 else if (aHintStyle == "no"
11671 || aHintStyle == "off"
11672 || aHintStyle == "0")
11673 {
11674 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11675 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11676 }
11677 else
11678 {
11679 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11680 return 1;
11681 }
11682 }
11683 else if (aFlag == "-fontautohinting"
11684 || aFlag == "-fontautohint")
11685 {
11686 if (toPrint)
11687 {
11688 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11689 {
11690 theDI << "force" << " ";
11691 }
11692 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11693 {
11694 theDI << "disallow" << " ";
11695 }
11696 else
11697 {
11698 theDI << "auto" << " ";
11699 }
11700 continue;
11701 }
11702 else if (anArgIter + 1 >= theArgNb)
11703 {
11704 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11705 return 1;
11706 }
11707
11708 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11709 aHintStyle.LowerCase();
11710 if (aHintStyle == "force")
11711 {
11712 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11713 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11714 }
11715 else if (aHintStyle == "disallow"
11716 || aHintStyle == "no")
11717 {
11718 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11719 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11720 }
11721 else if (aHintStyle == "auto")
11722 {
11723 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11724 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11725 }
11726 else
11727 {
11728 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11729 return 1;
11730 }
11731 }
f88457e6 11732 else if (aFlag == "-depthprepass")
11733 {
11734 if (toPrint)
11735 {
11736 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11737 continue;
11738 }
11739 aParams.ToEnableDepthPrepass = Standard_True;
11740 if (anArgIter + 1 < theArgNb
dae2a922 11741 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 11742 {
11743 ++anArgIter;
11744 }
11745 }
c40eb6b9 11746 else if (aFlag == "-samplealphatocoverage"
11747 || aFlag == "-alphatocoverage")
11748 {
11749 if (toPrint)
11750 {
11751 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11752 continue;
11753 }
11754 aParams.ToEnableAlphaToCoverage = Standard_True;
11755 if (anArgIter + 1 < theArgNb
dae2a922 11756 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 11757 {
11758 ++anArgIter;
11759 }
11760 }
56689b27 11761 else if (aFlag == "-rendscale"
11762 || aFlag == "-renderscale"
11763 || aFlag == "-renderresolutionscale")
11764 {
11765 if (toPrint)
11766 {
11767 theDI << aParams.RenderResolutionScale << " ";
11768 continue;
11769 }
11770 else if (++anArgIter >= theArgNb)
11771 {
23fe70ec 11772 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 11773 return 1;
11774 }
11775
11776 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11777 if (aScale < 0.01)
11778 {
23fe70ec 11779 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 11780 return 1;
11781 }
11782 else
11783 {
11784 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11785 }
11786 }
bc8c79bb 11787 else if (aFlag == "-raydepth"
11788 || aFlag == "-ray_depth")
11789 {
11790 if (toPrint)
11791 {
11792 theDI << aParams.RaytracingDepth << " ";
11793 continue;
11794 }
11795 else if (++anArgIter >= theArgNb)
11796 {
23fe70ec 11797 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11798 return 1;
11799 }
11800
11801 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 11802
11803 // We allow RaytracingDepth be more than 10 in case of GI enabled
11804 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 11805 {
23fe70ec 11806 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 11807 return 1;
11808 }
e276548b 11809 else
bc8c79bb 11810 {
11811 aParams.RaytracingDepth = aDepth;
11812 }
11813 }
11814 else if (aFlag == "-shad"
11815 || aFlag == "-shadows")
11816 {
11817 if (toPrint)
11818 {
11819 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11820 continue;
11821 }
11822
11823 Standard_Boolean toEnable = Standard_True;
11824 if (++anArgIter < theArgNb
dae2a922 11825 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11826 {
11827 --anArgIter;
11828 }
11829 aParams.IsShadowEnabled = toEnable;
11830 }
d84e8669 11831 else if (aFlag == "-shadowmapresolution"
11832 || aFlag == "-shadowmap")
11833 {
11834 if (toPrint)
11835 {
11836 theDI << aParams.ShadowMapResolution << " ";
11837 continue;
11838 }
11839 else if (++anArgIter >= theArgNb)
11840 {
11841 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11842 return 1;
11843 }
11844
11845 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11846 }
11847 else if (aFlag == "-shadowmapbias")
11848 {
11849 if (toPrint)
11850 {
11851 theDI << aParams.ShadowMapBias << " ";
11852 continue;
11853 }
11854 else if (++anArgIter >= theArgNb)
11855 {
11856 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11857 return 1;
11858 }
11859
11860 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11861 }
bc8c79bb 11862 else if (aFlag == "-refl"
11863 || aFlag == "-reflections")
11864 {
11865 if (toPrint)
11866 {
11867 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11868 continue;
11869 }
11870
11871 Standard_Boolean toEnable = Standard_True;
11872 if (++anArgIter < theArgNb
dae2a922 11873 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11874 {
11875 --anArgIter;
11876 }
11877 aParams.IsReflectionEnabled = toEnable;
11878 }
11879 else if (aFlag == "-fsaa")
11880 {
11881 if (toPrint)
11882 {
11883 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11884 continue;
11885 }
11886
11887 Standard_Boolean toEnable = Standard_True;
11888 if (++anArgIter < theArgNb
dae2a922 11889 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11890 {
11891 --anArgIter;
11892 }
11893 aParams.IsAntialiasingEnabled = toEnable;
11894 }
11895 else if (aFlag == "-gleam")
11896 {
11897 if (toPrint)
11898 {
11899 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11900 continue;
11901 }
11902
11903 Standard_Boolean toEnable = Standard_True;
11904 if (++anArgIter < theArgNb
dae2a922 11905 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11906 {
11907 --anArgIter;
11908 }
11909 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 11910 }
189f85a3 11911 else if (aFlag == "-gi")
11912 {
11913 if (toPrint)
11914 {
11915 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11916 continue;
11917 }
11918
11919 Standard_Boolean toEnable = Standard_True;
11920 if (++anArgIter < theArgNb
dae2a922 11921 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 11922 {
11923 --anArgIter;
11924 }
11925 aParams.IsGlobalIlluminationEnabled = toEnable;
11926 if (!toEnable)
11927 {
11928 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11929 }
11930 }
8c820969 11931 else if (aFlag == "-blockedrng"
11932 || aFlag == "-brng")
11933 {
11934 if (toPrint)
11935 {
11936 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11937 continue;
11938 }
11939
11940 Standard_Boolean toEnable = Standard_True;
11941 if (++anArgIter < theArgNb
dae2a922 11942 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 11943 {
11944 --anArgIter;
11945 }
11946 aParams.CoherentPathTracingMode = toEnable;
11947 }
b09447ed 11948 else if (aFlag == "-maxrad")
11949 {
11950 if (toPrint)
11951 {
11952 theDI << aParams.RadianceClampingValue << " ";
11953 continue;
11954 }
11955 else if (++anArgIter >= theArgNb)
11956 {
23fe70ec 11957 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11958 return 1;
11959 }
11960
11961 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
d45edf24 11962 if (!aMaxRadStr.IsRealValue (Standard_True))
b09447ed 11963 {
23fe70ec 11964 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11965 return 1;
11966 }
11967
11968 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11969 if (aMaxRadiance <= 0.0)
11970 {
23fe70ec 11971 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 11972 return 1;
11973 }
11974 else
11975 {
11976 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11977 }
11978 }
3a9b5dc8 11979 else if (aFlag == "-iss")
11980 {
11981 if (toPrint)
11982 {
11983 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11984 continue;
11985 }
11986
11987 Standard_Boolean toEnable = Standard_True;
11988 if (++anArgIter < theArgNb
dae2a922 11989 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 11990 {
11991 --anArgIter;
11992 }
11993 aParams.AdaptiveScreenSampling = toEnable;
11994 }
e084dbbc 11995 else if (aFlag == "-issatomic")
11996 {
11997 if (toPrint)
11998 {
11999 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12000 continue;
12001 }
12002
12003 Standard_Boolean toEnable = Standard_True;
12004 if (++anArgIter < theArgNb
dae2a922 12005 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 12006 {
12007 --anArgIter;
12008 }
12009 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12010 }
3a9b5dc8 12011 else if (aFlag == "-issd")
12012 {
12013 if (toPrint)
12014 {
12015 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12016 continue;
12017 }
12018
12019 Standard_Boolean toEnable = Standard_True;
12020 if (++anArgIter < theArgNb
dae2a922 12021 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12022 {
12023 --anArgIter;
12024 }
12025 aParams.ShowSamplingTiles = toEnable;
12026 }
66d1cdc6 12027 else if (aFlag == "-tilesize")
12028 {
12029 if (toPrint)
12030 {
12031 theDI << aParams.RayTracingTileSize << " ";
12032 continue;
12033 }
12034 else if (++anArgIter >= theArgNb)
12035 {
23fe70ec 12036 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 12037 return 1;
12038 }
12039
12040 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12041 if (aTileSize < 1)
12042 {
23fe70ec 12043 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 12044 return 1;
12045 }
12046 aParams.RayTracingTileSize = aTileSize;
12047 }
4eaaf9d8 12048 else if (aFlag == "-nbtiles")
12049 {
12050 if (toPrint)
12051 {
12052 theDI << aParams.NbRayTracingTiles << " ";
12053 continue;
12054 }
12055 else if (++anArgIter >= theArgNb)
12056 {
23fe70ec 12057 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 12058 return 1;
12059 }
12060
12061 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12062 if (aNbTiles < -1)
4eaaf9d8 12063 {
23fe70ec 12064 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 12065 return 1;
12066 }
66d1cdc6 12067 else if (aNbTiles > 0
12068 && (aNbTiles < 64
12069 || aNbTiles > 1024))
4eaaf9d8 12070 {
23fe70ec 12071 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 12072 }
66d1cdc6 12073 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 12074 }
189f85a3 12075 else if (aFlag == "-env")
12076 {
12077 if (toPrint)
12078 {
12079 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12080 continue;
12081 }
12082
12083 Standard_Boolean toEnable = Standard_True;
12084 if (++anArgIter < theArgNb
dae2a922 12085 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12086 {
12087 --anArgIter;
12088 }
12089 aParams.UseEnvironmentMapBackground = toEnable;
12090 }
78607702 12091 else if (aFlag == "-ignorenormalmap")
12092 {
12093 if (toPrint)
12094 {
12095 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12096 continue;
12097 }
12098
12099 Standard_Boolean toEnable = Standard_True;
12100 if (++anArgIter < theArgNb
dae2a922 12101 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12102 {
12103 --anArgIter;
12104 }
12105 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12106 }
b4327ba8 12107 else if (aFlag == "-twoside")
12108 {
12109 if (toPrint)
12110 {
12111 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12112 continue;
12113 }
12114
12115 Standard_Boolean toEnable = Standard_True;
12116 if (++anArgIter < theArgNb
dae2a922 12117 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12118 {
12119 --anArgIter;
12120 }
12121 aParams.TwoSidedBsdfModels = toEnable;
12122 }
8625ef7e 12123 else if (aFlag == "-shademodel"
12124 || aFlag == "-shadingmodel"
12125 || aFlag == "-shading")
12126 {
12127 if (toPrint)
12128 {
12129 switch (aView->ShadingModel())
12130 {
67312b79 12131 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12132 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12133 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12134 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12135 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12136 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12137 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12138 }
12139 continue;
12140 }
12141
12142 if (++anArgIter >= theArgNb)
12143 {
23fe70ec 12144 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12145 }
12146
dc89236f 12147 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12148 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12149 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12150 {
dc89236f 12151 aView->SetShadingModel (aModel);
8625ef7e 12152 }
12153 else
12154 {
23fe70ec 12155 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12156 return 1;
12157 }
12158 }
67312b79 12159 else if (aFlag == "-pbrenvpow2size"
12160 || aFlag == "-pbrenvp2s"
12161 || aFlag == "-pep2s")
12162 {
12163 if (++anArgIter >= theArgNb)
12164 {
23fe70ec 12165 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12166 return 1;
12167 }
12168
12169 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12170 if (aPbrEnvPow2Size < 1)
12171 {
23fe70ec 12172 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12173 return 1;
12174 }
12175 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12176 }
12177 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12178 || aFlag == "-pbrenvspecmapnblevels"
12179 || aFlag == "-pbrenvspecmaplevels"
12180 || aFlag == "-pbrenvsmln"
12181 || aFlag == "-pesmln")
12182 {
12183 if (++anArgIter >= theArgNb)
12184 {
23fe70ec 12185 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12186 return 1;
12187 }
12188
12189 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12190 if (aPbrEnvSpecMapNbLevels < 2)
12191 {
23fe70ec 12192 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12193 return 1;
12194 }
12195 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12196 }
12197 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12198 || aFlag == "-pbrenvbakingdiffsamples"
12199 || aFlag == "-pbrenvbdsn")
12200 {
12201 if (++anArgIter >= theArgNb)
12202 {
23fe70ec 12203 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12204 return 1;
12205 }
12206
12207 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12208 if (aPbrEnvBakingDiffNbSamples < 1)
12209 {
4551e1be 12210 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12211 return 1;
12212 }
12213 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12214 }
12215 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12216 || aFlag == "-pbrenvbakingspecsamples"
12217 || aFlag == "-pbrenvbssn")
12218 {
12219 if (++anArgIter >= theArgNb)
12220 {
23fe70ec 12221 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12222 return 1;
12223 }
12224
12225 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12226 if (aPbrEnvBakingSpecNbSamples < 1)
12227 {
4551e1be 12228 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12229 return 1;
12230 }
12231 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12232 }
12233 else if (aFlag == "-pbrenvbakingprobability"
12234 || aFlag == "-pbrenvbp")
12235 {
12236 if (++anArgIter >= theArgNb)
12237 {
23fe70ec 12238 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12239 return 1;
12240 }
12241 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12242 if (aPbrEnvBakingProbability < 0.f
12243 || aPbrEnvBakingProbability > 1.f)
12244 {
4551e1be 12245 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
67312b79 12246 return 1;
12247 }
12248 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12249 }
4b1c8733 12250 else if (aFlag == "-resolution")
12251 {
12252 if (++anArgIter >= theArgNb)
12253 {
23fe70ec 12254 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12255 return 1;
12256 }
12257
12258 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12259 if (aResolution.IsIntegerValue())
12260 {
12261 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12262 }
12263 else
12264 {
23fe70ec 12265 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12266 return 1;
12267 }
12268 }
d877e610 12269 else if (aFlag == "-rebuildglsl"
12270 || aFlag == "-rebuild")
12271 {
12272 if (toPrint)
12273 {
12274 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12275 continue;
12276 }
12277
12278 Standard_Boolean toEnable = Standard_True;
12279 if (++anArgIter < theArgNb
dae2a922 12280 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12281 {
12282 --anArgIter;
12283 }
12284 aParams.RebuildRayTracingShaders = toEnable;
12285 }
b27ab03d 12286 else if (aFlag == "-focal")
12287 {
12288 if (++anArgIter >= theArgNb)
12289 {
23fe70ec 12290 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12291 return 1;
12292 }
12293
12294 TCollection_AsciiString aParam (theArgVec[anArgIter]);
d45edf24 12295 if (aParam.IsRealValue (Standard_True))
b27ab03d 12296 {
12297 float aFocalDist = static_cast<float> (aParam.RealValue());
12298 if (aFocalDist < 0)
12299 {
23fe70ec 12300 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12301 return 1;
12302 }
12303 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12304 }
12305 else
12306 {
23fe70ec 12307 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12308 return 1;
12309 }
12310 }
12311 else if (aFlag == "-aperture")
12312 {
12313 if (++anArgIter >= theArgNb)
12314 {
23fe70ec 12315 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12316 return 1;
12317 }
12318
12319 TCollection_AsciiString aParam(theArgVec[anArgIter]);
d45edf24 12320 if (aParam.IsRealValue (Standard_True))
b27ab03d 12321 {
12322 float aApertureSize = static_cast<float> (aParam.RealValue());
12323 if (aApertureSize < 0)
12324 {
23fe70ec 12325 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12326 return 1;
12327 }
12328 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12329 }
12330 else
12331 {
23fe70ec 12332 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12333 return 1;
12334 }
12335 }
eb85ed36 12336 else if (aFlag == "-exposure")
12337 {
12338 if (++anArgIter >= theArgNb)
12339 {
23fe70ec 12340 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12341 return 1;
12342 }
12343
12344 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
d45edf24 12345 if (anExposure.IsRealValue (Standard_True))
eb85ed36 12346 {
12347 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12348 }
12349 else
12350 {
23fe70ec 12351 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12352 return 1;
12353 }
12354 }
12355 else if (aFlag == "-whitepoint")
12356 {
12357 if (++anArgIter >= theArgNb)
12358 {
23fe70ec 12359 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12360 return 1;
12361 }
12362
12363 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
d45edf24 12364 if (aWhitePoint.IsRealValue (Standard_True))
eb85ed36 12365 {
12366 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12367 }
12368 else
12369 {
23fe70ec 12370 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12371 return 1;
12372 }
12373 }
12374 else if (aFlag == "-tonemapping")
12375 {
12376 if (++anArgIter >= theArgNb)
12377 {
23fe70ec 12378 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12379 return 1;
12380 }
12381
12382 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12383 aMode.LowerCase();
12384
12385 if (aMode == "disabled")
12386 {
12387 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12388 }
12389 else if (aMode == "filmic")
12390 {
12391 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12392 }
12393 else
12394 {
23fe70ec 12395 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12396 return 1;
12397 }
12398 }
15669413 12399 else if (aFlag == "-performancestats"
12400 || aFlag == "-performancecounters"
12401 || aFlag == "-perfstats"
12402 || aFlag == "-perfcounters"
12403 || aFlag == "-stats")
12404 {
12405 if (++anArgIter >= theArgNb)
12406 {
23fe70ec 12407 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12408 return 1;
12409 }
12410
12411 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12412 aFlagsStr.LowerCase();
12413 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12414 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12415 {
23fe70ec 12416 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12417 return 1;
12418 }
12419 aView->ChangeRenderingParams().CollectedStats = aFlags;
12420 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12421 }
12422 else if (aFlag == "-perfupdateinterval"
12423 || aFlag == "-statsupdateinterval")
12424 {
12425 if (++anArgIter >= theArgNb)
12426 {
23fe70ec 12427 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12428 return 1;
12429 }
12430 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12431 }
5e30547b 12432 else if (aFlag == "-perfchart"
12433 || aFlag == "-statschart")
12434 {
12435 if (++anArgIter >= theArgNb)
12436 {
23fe70ec 12437 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12438 return 1;
12439 }
12440 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12441 }
12442 else if (aFlag == "-perfchartmax"
12443 || aFlag == "-statschartmax")
12444 {
12445 if (++anArgIter >= theArgNb)
12446 {
23fe70ec 12447 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12448 return 1;
12449 }
12450 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12451 }
0e3025bc 12452 else if (aFlag == "-frustumculling"
12453 || aFlag == "-culling")
12454 {
12455 if (toPrint)
12456 {
12457 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12458 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12459 "noUpdate") << " ";
12460 continue;
12461 }
12462
12463 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12464 if (++anArgIter < theArgNb)
12465 {
12466 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12467 aStateStr.LowerCase();
12468 bool toEnable = true;
dae2a922 12469 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12470 {
12471 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12472 }
12473 else if (aStateStr == "noupdate"
12474 || aStateStr == "freeze")
12475 {
12476 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12477 }
12478 else
12479 {
12480 --anArgIter;
12481 }
12482 }
12483 aParams.FrustumCullingState = aState;
12484 }
e276548b 12485 else
12486 {
23fe70ec 12487 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12488 return 1;
e276548b 12489 }
12490 }
189f85a3 12491
4c7a3fae 12492 // set current view parameters as defaults
12493 if (toSyncDefaults)
12494 {
12495 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12496 }
12497 if (toSyncAllViews)
12498 {
12499 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12500 {
12501 aViewIter.Value()->ChangeRenderingParams() = aParams;
12502 }
12503 }
189f85a3 12504 return 0;
12505}
12506
79b544e6 12507//=======================================================================
12508//function : searchInfo
12509//purpose :
12510//=======================================================================
12511inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12512 const TCollection_AsciiString& theKey)
12513{
12514 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12515 {
12516 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12517 {
12518 return anIter.Value();
12519 }
12520 }
12521 return TCollection_AsciiString();
12522}
12523
12524//=======================================================================
12525//function : VStatProfiler
12526//purpose :
12527//=======================================================================
12528static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12529 Standard_Integer theArgNb,
12530 const char** theArgVec)
12531{
12532 Handle(V3d_View) aView = ViewerTest::CurrentView();
12533 if (aView.IsNull())
12534 {
23fe70ec 12535 Message::SendFail ("Error: no active viewer");
79b544e6 12536 return 1;
12537 }
12538
12539 Standard_Boolean toRedraw = Standard_True;
12540 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12541 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12542 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12543 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12544 {
12545 Standard_CString anArg (theArgVec[anArgIter]);
12546 TCollection_AsciiString aFlag (anArg);
12547 aFlag.LowerCase();
12548 if (aFlag == "-noredraw")
12549 {
12550 toRedraw = Standard_False;
12551 }
12552 else
12553 {
12554 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12555 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12556 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12557 else if (aFlag == "alllayers"
12558 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12559 else if (aFlag == "allstructs"
a2803f37 12560 || aFlag == "allstructures"
12561 || aFlag == "structs"
12562 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12563 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12564 else if (aFlag == "allarrays"
12565 || aFlag == "fillarrays"
12566 || aFlag == "linearrays"
12567 || aFlag == "pointarrays"
12568 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12569 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12570 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12571 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12572 else if (aFlag == "geommem"
12573 || aFlag == "texturemem"
12574 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12575 else if (aFlag == "elapsedframe"
12576 || aFlag == "cpuframeaverage"
12577 || aFlag == "cpupickingaverage"
12578 || aFlag == "cpucullingaverage"
12579 || aFlag == "cpudynaverage"
12580 || aFlag == "cpuframemax"
12581 || aFlag == "cpupickingmax"
12582 || aFlag == "cpucullingmax"
12583 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12584 else
12585 {
23fe70ec 12586 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12587 continue;
12588 }
12589
12590 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12591 }
12592 }
12593
12594 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12595 {
12596 aView->ChangeRenderingParams().CollectedStats =
12597 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12598
12599 if (toRedraw)
12600 {
12601 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12602 aView->Redraw();
12603 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12604 }
12605
12606 TColStd_IndexedDataMapOfStringString aDict;
12607 aView->StatisticInformation (aDict);
12608
12609 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12610
12611 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12612 {
12613 Standard_CString anArg(theArgVec[anArgIter]);
12614 TCollection_AsciiString aFlag(anArg);
12615 aFlag.LowerCase();
12616 if (aFlag == "fps")
12617 {
12618 theDI << searchInfo (aDict, "FPS") << " ";
12619 }
12620 else if (aFlag == "cpu")
12621 {
12622 theDI << searchInfo (aDict, "CPU FPS") << " ";
12623 }
12624 else if (aFlag == "alllayers")
12625 {
12626 theDI << searchInfo (aDict, "Layers") << " ";
12627 }
12628 else if (aFlag == "layers")
12629 {
12630 theDI << searchInfo (aDict, "Rendered layers") << " ";
12631 }
a2803f37 12632 else if (aFlag == "allstructs"
12633 || aFlag == "allstructures")
79b544e6 12634 {
12635 theDI << searchInfo (aDict, "Structs") << " ";
12636 }
a2803f37 12637 else if (aFlag == "structs"
12638 || aFlag == "structures")
79b544e6 12639 {
a2803f37 12640 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12641 if (aRend.IsEmpty()) // all structures rendered
12642 {
12643 aRend = searchInfo (aDict, "Structs");
12644 }
12645 theDI << aRend << " ";
79b544e6 12646 }
12647 else if (aFlag == "groups")
12648 {
12649 theDI << searchInfo (aDict, "Rendered groups") << " ";
12650 }
12651 else if (aFlag == "allarrays")
12652 {
12653 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12654 }
12655 else if (aFlag == "fillarrays")
12656 {
12657 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12658 }
12659 else if (aFlag == "linearrays")
12660 {
12661 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12662 }
12663 else if (aFlag == "pointarrays")
12664 {
12665 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12666 }
12667 else if (aFlag == "textarrays")
12668 {
12669 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12670 }
12671 else if (aFlag == "triangles")
12672 {
12673 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12674 }
12675 else if (aFlag == "points")
12676 {
12677 theDI << searchInfo (aDict, "Rendered points") << " ";
12678 }
12679 else if (aFlag == "geommem")
12680 {
12681 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12682 }
12683 else if (aFlag == "texturemem")
12684 {
12685 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12686 }
12687 else if (aFlag == "framemem")
12688 {
12689 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12690 }
12691 else if (aFlag == "elapsedframe")
12692 {
12693 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12694 }
12695 else if (aFlag == "cpuframe_average")
12696 {
12697 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12698 }
12699 else if (aFlag == "cpupicking_average")
12700 {
12701 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12702 }
12703 else if (aFlag == "cpuculling_average")
12704 {
12705 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12706 }
12707 else if (aFlag == "cpudyn_average")
12708 {
12709 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12710 }
12711 else if (aFlag == "cpuframe_max")
12712 {
12713 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12714 }
12715 else if (aFlag == "cpupicking_max")
12716 {
12717 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12718 }
12719 else if (aFlag == "cpuculling_max")
12720 {
12721 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12722 }
12723 else if (aFlag == "cpudyn_max")
12724 {
12725 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12726 }
12727 }
12728 }
12729 else
12730 {
12731 if (toRedraw)
12732 {
12733 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12734 aView->Redraw();
12735 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12736 }
12737 theDI << "Statistic info:\n" << aView->StatisticInformation();
12738 }
12739 return 0;
12740}
12741
0717ddc1 12742//=======================================================================
12743//function : VXRotate
12744//purpose :
12745//=======================================================================
12746static Standard_Integer VXRotate (Draw_Interpretor& di,
12747 Standard_Integer argc,
12748 const char ** argv)
12749{
12750 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12751 if (aContext.IsNull())
12752 {
586db386 12753 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12754 return 1;
12755 }
8693dfd0 12756
0717ddc1 12757 if (argc != 3)
12758 {
586db386 12759 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12760 return 1;
12761 }
12762
12763 TCollection_AsciiString aName (argv[1]);
12764 Standard_Real anAngle = Draw::Atof (argv[2]);
12765
12766 // find object
12767 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12768 Handle(AIS_InteractiveObject) anIObj;
8f521168 12769 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12770 {
586db386 12771 di << "Use 'vdisplay' before\n";
0717ddc1 12772 return 1;
12773 }
0717ddc1 12774
8f521168 12775 gp_Trsf aTransform;
12776 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12777 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12778
8f521168 12779 aContext->SetLocation (anIObj, aTransform);
12780 aContext->UpdateCurrentViewer();
0717ddc1 12781 return 0;
12782}
12783
ff6122e0 12784namespace
12785{
12786 //! Structure for setting AIS_Manipulator::SetPart() property.
12787 struct ManipAxisModeOnOff
12788 {
12789 Standard_Integer Axis;
12790 AIS_ManipulatorMode Mode;
12791 Standard_Boolean ToEnable;
12792
12793 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12794 };
12795
12796 enum ManipAjustPosition
12797 {
12798 ManipAjustPosition_Off,
12799 ManipAjustPosition_Center,
12800 ManipAjustPosition_Location,
12801 ManipAjustPosition_ShapeLocation,
12802 };
12803}
12804
625e1958 12805//===============================================================================================
12806//function : VManipulator
12807//purpose :
12808//===============================================================================================
12809static int VManipulator (Draw_Interpretor& theDi,
12810 Standard_Integer theArgsNb,
12811 const char** theArgVec)
12812{
bbf3fcde 12813 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 12814 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 12815 if (aCurrentView.IsNull()
625e1958 12816 || aViewer.IsNull())
12817 {
23fe70ec 12818 Message::SendFail ("Error: no active viewer");
625e1958 12819 return 1;
12820 }
12821
12822 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12823 Standard_Integer anArgIter = 1;
ff6122e0 12824 Handle(AIS_Manipulator) aManipulator;
12825 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12826 TCollection_AsciiString aName;
12827 // parameters
12828 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12829 Standard_Real aGap = -1.0, aSize = -1.0;
12830 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12831 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12832 //
12833 bool toDetach = false;
12834 AIS_Manipulator::OptionsForAttach anAttachOptions;
12835 Handle(AIS_InteractiveObject) anAttachObject;
12836 Handle(V3d_View) aViewAffinity;
12837 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12838 //
12839 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12840 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12841 Standard_Integer toStopMouseTransform = -1;
12842 // explicit transformation
12843 gp_Trsf aTrsf;
12844 gp_XYZ aTmpXYZ;
12845 Standard_Real aTmpReal = 0.0;
12846 gp_XYZ aRotPnt, aRotAxis;
625e1958 12847 for (; anArgIter < theArgsNb; ++anArgIter)
12848 {
ff6122e0 12849 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12850 anArg.LowerCase();
12851 if (anUpdateTool.parseRedrawMode (anArg))
12852 {
12853 continue;
12854 }
12855 else if (anArg == "-help")
12856 {
12857 theDi.PrintHelp (theArgVec[0]);
12858 return 0;
12859 }
12860 //
12861 else if (anArg == "-autoactivate"
12862 || anArg == "-noautoactivate")
12863 {
12864 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12865 }
12866 else if (anArg == "-followtranslation"
12867 || anArg == "-nofollowtranslation")
12868 {
12869 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12870 }
12871 else if (anArg == "-followrotation"
12872 || anArg == "-nofollowrotation")
12873 {
12874 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12875 }
12876 else if (anArg == "-followdragging"
12877 || anArg == "-nofollowdragging")
12878 {
12879 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12880 }
12881 else if (anArg == "-gap"
12882 && anArgIter + 1 < theArgsNb
12883 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12884 && aGap >= 0.0)
12885 {
12886 ++anArgIter;
12887 }
12888 else if (anArg == "-size"
12889 && anArgIter + 1 < theArgsNb
12890 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12891 && aSize > 0.0)
12892 {
12893 ++anArgIter;
12894 }
12895 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12896 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12897 {
12898 ManipAxisModeOnOff aPart;
12899 Standard_Integer aMode = 0;
12900 if (anArg == "-part")
12901 {
12902 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12903 || aPart.Axis < 0 || aPart.Axis > 3)
12904 {
12905 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12906 return 1;
12907 }
12908 }
12909 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12910 || aMode < 1 || aMode > 4)
12911 {
12912 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12913 return 1;
12914 }
12915 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12916 {
12917 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12918 return 1;
12919 }
12920 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12921 aParts.Append (aPart);
12922 }
12923 else if (anArg == "-pos"
12924 && anArgIter + 3 < theArgsNb
12925 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12926 {
12927 anArgIter += 3;
12928 if (anArgIter + 3 < theArgsNb
12929 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12930 && aVDir.Modulus() > Precision::Confusion())
12931 {
12932 anArgIter += 3;
12933 }
12934 if (anArgIter + 3 < theArgsNb
12935 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12936 && anXDir.Modulus() > Precision::Confusion())
12937 {
12938 anArgIter += 3;
12939 }
12940 }
12941 else if (anArg == "-zoomable"
12942 || anArg == "-notzoomable")
12943 {
12944 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12945 }
12946 //
12947 else if (anArg == "-adjustposition"
12948 || anArg == "-noadjustposition")
12949 {
12950 anAttachPos = ManipAjustPosition_Center;
12951 if (anArgIter + 1 < theArgsNb)
12952 {
12953 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12954 aPosName.LowerCase();
12955 if (aPosName == "0")
12956 {
12957 anAttachPos = ManipAjustPosition_Off;
12958 }
12959 else if (aPosName == "1"
12960 || aPosName == "center")
12961 {
12962 anAttachPos = ManipAjustPosition_Center;
12963 }
12964 else if (aPosName == "transformation"
12965 || aPosName == "trsf"
12966 || aPosName == "location"
12967 || aPosName == "loc")
12968 {
12969 anAttachPos = ManipAjustPosition_Location;
12970 }
12971 else if (aPosName == "shapelocation"
12972 || aPosName == "shapeloc")
12973 {
12974 anAttachPos = ManipAjustPosition_ShapeLocation;
12975 }
12976 else
12977 {
12978 --anArgIter;
12979 }
12980 }
12981 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12982 }
12983 else if (anArg == "-adjustsize"
12984 || anArg == "-noadjustsize")
12985 {
12986 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12987 }
12988 else if (anArg == "-enablemodes"
12989 || anArg == "-enablemodes")
12990 {
12991 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12992 }
12993 //
12994 else if (anArg == "-starttransform"
12995 && anArgIter + 2 < theArgsNb
12996 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12997 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
12998 {
12999 anArgIter += 2;
13000 }
13001 else if (anArg == "-transform"
13002 && anArgIter + 2 < theArgsNb
13003 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
13004 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
13005 {
13006 anArgIter += 2;
13007 }
13008 else if (anArg == "-stoptransform")
13009 {
13010 toStopMouseTransform = 1;
13011 if (anArgIter + 1 < theArgsNb
13012 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
13013 {
13014 ++anArgIter;
13015 toStopMouseTransform = 0;
13016 }
13017 }
13018 //
13019 else if (anArg == "-move"
13020 && anArgIter + 3 < theArgsNb
13021 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
13022 {
13023 anArgIter += 3;
13024 aTrsf.SetTranslationPart (aTmpXYZ);
13025 }
13026 else if (anArg == "-scale"
13027 && anArgIter + 1 < theArgsNb
13028 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
13029 {
13030 ++anArgIter;
13031 aTrsf.SetScale (gp_Pnt(), aTmpReal);
13032 }
13033 else if (anArg == "-rotate"
13034 && anArgIter + 7 < theArgsNb
13035 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
13036 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
13037 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
13038 {
13039 anArgIter += 7;
13040 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
13041 }
13042 //
13043 else if (anArg == "-detach")
13044 {
13045 toDetach = true;
13046 }
13047 else if (anArg == "-attach"
13048 && anArgIter + 1 < theArgsNb)
13049 {
13050 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
13051 if (!aMapAIS.Find2 (anObjName, anAttachObject))
13052 {
13053 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
13054 return 1;
13055 }
625e1958 13056
ff6122e0 13057 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
13058 {
13059 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13060 if (!aManip.IsNull()
13061 && aManip->IsAttached()
13062 && aManip->Object() == anAttachObject)
13063 {
13064 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
13065 return 1;
13066 }
13067 }
13068 }
13069 else if (anArg == "-view"
13070 && anArgIter + 1 < theArgsNb
13071 && aViewAffinity.IsNull())
13072 {
13073 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
13074 if (aViewString == "active")
13075 {
13076 aViewAffinity = ViewerTest::CurrentView();
13077 }
13078 else // Check view name
13079 {
13080 ViewerTest_Names aViewNames (aViewString);
13081 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13082 {
13083 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13084 return 1;
13085 }
13086 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13087 if (aViewAffinity.IsNull())
13088 {
13089 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13090 return 1;
13091 }
13092 }
13093 }
13094 else if (aName.IsEmpty())
13095 {
13096 aName = theArgVec[anArgIter];
13097 if (!aMapAIS.IsBound2 (aName))
13098 {
13099 aManipulator = new AIS_Manipulator();
13100 aManipulator->SetModeActivationOnDetection (true);
13101 aMapAIS.Bind (aManipulator, aName);
13102 }
13103 else
13104 {
13105 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13106 if (aManipulator.IsNull())
13107 {
13108 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13109 return 1;
13110 }
13111 }
13112 }
13113 else
13114 {
13115 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13116 }
625e1958 13117 }
13118
625e1958 13119 if (aName.IsEmpty())
13120 {
23fe70ec 13121 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 13122 return 1;
13123 }
ff6122e0 13124 if (!toDetach
13125 && aManipulator.IsNull())
625e1958 13126 {
8b037fe4 13127 aManipulator = new AIS_Manipulator();
49582f9d 13128 aManipulator->SetModeActivationOnDetection (true);
625e1958 13129 aMapAIS.Bind (aManipulator, aName);
13130 }
625e1958 13131
13132 // -----------------------------------------
13133 // change properties of manipulator instance
13134 // -----------------------------------------
13135
ff6122e0 13136 if (toAutoActivate != -1)
625e1958 13137 {
ff6122e0 13138 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
625e1958 13139 }
ff6122e0 13140 if (toFollowTranslation != -1)
625e1958 13141 {
ff6122e0 13142 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
625e1958 13143 }
ff6122e0 13144 if (toFollowRotation != -1)
625e1958 13145 {
ff6122e0 13146 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
625e1958 13147 }
ff6122e0 13148 if (toFollowDragging != -1)
f522ce50 13149 {
ff6122e0 13150 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
f522ce50 13151 }
ff6122e0 13152 if (aGap >= 0.0f)
625e1958 13153 {
ff6122e0 13154 aManipulator->SetGap ((float )aGap);
625e1958 13155 }
ff6122e0 13156
13157 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
625e1958 13158 {
ff6122e0 13159 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13160 if (aPart.Axis == -1)
625e1958 13161 {
ff6122e0 13162 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
625e1958 13163 }
ff6122e0 13164 else
84b904bc 13165 {
ff6122e0 13166 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
84b904bc 13167 }
84b904bc 13168 }
625e1958 13169
ff6122e0 13170 if (aSize > 0.0)
625e1958 13171 {
ff6122e0 13172 aManipulator->SetSize ((float )aSize);
625e1958 13173 }
ff6122e0 13174 if (isZoomable != -1)
625e1958 13175 {
ff6122e0 13176 aManipulator->SetZoomPersistence (isZoomable == 0);
625e1958 13177
13178 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13179 {
13180 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13181 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13182 }
13183 }
13184
ff6122e0 13185 // ----------------------------------
13186 // detach existing manipulator object
13187 // ----------------------------------
13188
13189 if (toDetach)
13190 {
13191 aManipulator->Detach();
13192 aMapAIS.UnBind2 (aName);
13193 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13194 }
13195
625e1958 13196 // ---------------------------------------------------
13197 // attach, detach or access manipulator from an object
13198 // ---------------------------------------------------
13199
ff6122e0 13200 if (!anAttachObject.IsNull())
625e1958 13201 {
ff6122e0 13202 aManipulator->Attach (anAttachObject, anAttachOptions);
13203 }
13204 if (!aViewAffinity.IsNull())
13205 {
13206 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
8b037fe4 13207 anIter.More(); anIter.Next())
625e1958 13208 {
ff6122e0 13209 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
625e1958 13210 }
ff6122e0 13211 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13212 }
625e1958 13213
ff6122e0 13214 if (anAttachPos != ManipAjustPosition_Off
13215 && aManipulator->IsAttached()
13216 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13217 {
13218 gp_Ax2 aPosition = gp::XOY();
13219 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13220 switch (anAttachPos)
bbf3fcde 13221 {
ff6122e0 13222 case ManipAjustPosition_Off:
bbf3fcde 13223 {
ff6122e0 13224 break;
bbf3fcde 13225 }
ff6122e0 13226 case ManipAjustPosition_Location:
bbf3fcde 13227 {
ff6122e0 13228 aPosition = gp::XOY().Transformed (aBaseTrsf);
13229 break;
bbf3fcde 13230 }
ff6122e0 13231 case ManipAjustPosition_ShapeLocation:
bbf3fcde 13232 {
ff6122e0 13233 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
bbf3fcde 13234 {
ff6122e0 13235 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
bbf3fcde 13236 }
ff6122e0 13237 else
bbf3fcde 13238 {
ff6122e0 13239 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
bbf3fcde 13240 return 1;
13241 }
ff6122e0 13242 break;
bbf3fcde 13243 }
ff6122e0 13244 case ManipAjustPosition_Center:
bbf3fcde 13245 {
ff6122e0 13246 Bnd_Box aBox;
13247 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13248 {
13249 Bnd_Box anObjBox;
13250 anObjIter.Value()->BoundingBox (anObjBox);
13251 aBox.Add (anObjBox);
13252 }
13253 aBox = aBox.FinitePart();
13254 if (!aBox.IsVoid())
13255 {
13256 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13257 aPosition.SetLocation (aCenter);
13258 }
13259 break;
bbf3fcde 13260 }
bbf3fcde 13261 }
ff6122e0 13262 aManipulator->SetPosition (aPosition);
13263 }
13264 if (!Precision::IsInfinite (aLocation.X()))
13265 {
13266 if (aVDir.Modulus() <= Precision::Confusion())
13267 {
13268 aVDir = aManipulator->Position().Direction().XYZ();
13269 }
13270 if (anXDir.Modulus() <= Precision::Confusion())
13271 {
13272 anXDir = aManipulator->Position().XDirection().XYZ();
13273 }
13274 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
625e1958 13275 }
13276
13277 // --------------------------------------
13278 // apply transformation using manipulator
13279 // --------------------------------------
13280
ff6122e0 13281 if (aMousePosFrom.x() != IntegerLast())
625e1958 13282 {
ff6122e0 13283 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
625e1958 13284 }
ff6122e0 13285 if (aMousePosTo.x() != IntegerLast())
625e1958 13286 {
ff6122e0 13287 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
625e1958 13288 }
ff6122e0 13289 if (toStopMouseTransform != -1)
625e1958 13290 {
ff6122e0 13291 aManipulator->StopTransform (toStopMouseTransform == 1);
625e1958 13292 }
13293
ff6122e0 13294 if (aTrsf.Form() != gp_Identity)
625e1958 13295 {
ff6122e0 13296 aManipulator->Transform (aTrsf);
625e1958 13297 }
13298
ff6122e0 13299 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
625e1958 13300 {
ff6122e0 13301 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
625e1958 13302 }
625e1958 13303 return 0;
13304}
13305
8e5fb5ea 13306//===============================================================================================
13307//function : VSelectionProperties
13308//purpose :
13309//===============================================================================================
13310static int VSelectionProperties (Draw_Interpretor& theDi,
13311 Standard_Integer theArgsNb,
13312 const char** theArgVec)
13313{
13314 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13315 if (aCtx.IsNull())
13316 {
23fe70ec 13317 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13318 return 1;
13319 }
13320
be3d8cbc 13321 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13322 {
13323 // handle obsolete alias
13324 bool toEnable = true;
13325 if (theArgsNb < 2)
13326 {
13327 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13328 return 0;
13329 }
13330 else if (theArgsNb != 2
dae2a922 13331 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13332 {
23fe70ec 13333 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13334 return 1;
13335 }
13336 if (toEnable != aCtx->ToHilightSelected())
13337 {
13338 aCtx->ClearDetected();
13339 aCtx->SetToHilightSelected (toEnable);
13340 }
13341 return 0;
13342 }
13343
f838dac4 13344 Standard_Boolean toPrint = theArgsNb == 1;
13345 Standard_Boolean toRedraw = Standard_False;
13346 Standard_Integer anArgIter = 1;
13347 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13348 if (anArgIter < theArgsNb)
13349 {
13350 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13351 anArgFirst.LowerCase();
13352 ++anArgIter;
13353 if (anArgFirst == "dynhighlight"
13354 || anArgFirst == "dynhilight"
13355 || anArgFirst == "dynamichighlight"
13356 || anArgFirst == "dynamichilight")
13357 {
13358 aType = Prs3d_TypeOfHighlight_Dynamic;
13359 }
13360 else if (anArgFirst == "localdynhighlight"
13361 || anArgFirst == "localdynhilight"
13362 || anArgFirst == "localdynamichighlight"
13363 || anArgFirst == "localdynamichilight")
13364 {
13365 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13366 }
13367 else if (anArgFirst == "selhighlight"
13368 || anArgFirst == "selhilight"
13369 || anArgFirst == "selectedhighlight"
13370 || anArgFirst == "selectedhilight")
13371 {
13372 aType = Prs3d_TypeOfHighlight_Selected;
13373 }
13374 else if (anArgFirst == "localselhighlight"
13375 || anArgFirst == "localselhilight"
13376 || anArgFirst == "localselectedhighlight"
13377 || anArgFirst == "localselectedhilight")
13378 {
13379 aType = Prs3d_TypeOfHighlight_LocalSelected;
13380 }
13381 else
13382 {
13383 --anArgIter;
13384 }
13385 }
13386 for (; anArgIter < theArgsNb; ++anArgIter)
13387 {
13388 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13389 anArg.LowerCase();
13390 if (anArg == "-help")
13391 {
13392 theDi.PrintHelp (theArgVec[0]);
13393 return 0;
13394 }
13395 else if (anArg == "-print")
13396 {
13397 toPrint = Standard_True;
13398 }
13399 else if (anArg == "-autoactivate")
13400 {
13401 Standard_Boolean toEnable = Standard_True;
13402 if (anArgIter + 1 < theArgsNb
dae2a922 13403 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13404 {
13405 ++anArgIter;
13406 }
13407 aCtx->SetAutoActivateSelection (toEnable);
13408 }
be3d8cbc 13409 else if (anArg == "-automatichighlight"
13410 || anArg == "-automatichilight"
13411 || anArg == "-autohighlight"
13412 || anArg == "-autohilight")
13413 {
13414 Standard_Boolean toEnable = Standard_True;
13415 if (anArgIter + 1 < theArgsNb
dae2a922 13416 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13417 {
13418 ++anArgIter;
13419 }
13420 aCtx->ClearSelected (false);
13421 aCtx->ClearDetected();
13422 aCtx->SetAutomaticHilight (toEnable);
13423 toRedraw = true;
13424 }
13425 else if (anArg == "-highlightselected"
13426 || anArg == "-hilightselected")
13427 {
13428 Standard_Boolean toEnable = Standard_True;
13429 if (anArgIter + 1 < theArgsNb
dae2a922 13430 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13431 {
13432 ++anArgIter;
13433 }
13434 aCtx->ClearDetected();
13435 aCtx->SetToHilightSelected (toEnable);
13436 toRedraw = true;
13437 }
14c4193d 13438 else if (anArg == "-pickstrategy"
13439 || anArg == "-pickingstrategy")
13440 {
13441 if (++anArgIter >= theArgsNb)
13442 {
23fe70ec 13443 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13444 return 1;
13445 }
13446
13447 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13448 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13449 aVal.LowerCase();
13450 if (aVal == "first"
13451 || aVal == "firstaccepted"
13452 || aVal == "firstacceptable")
13453 {
13454 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13455 }
13456 else if (aVal == "topmost"
13457 || aVal == "onlyTopmost")
13458 {
13459 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13460 }
13461 else
13462 {
23fe70ec 13463 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13464 return 1;
13465 }
13466
13467 aCtx->SetPickingStrategy (aStrategy);
13468 }
f838dac4 13469 else if (anArg == "-pixtol"
13470 && anArgIter + 1 < theArgsNb)
13471 {
13472 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13473 }
8c36926a 13474 else if (anArg == "-preferclosest")
13475 {
13476 bool toPreferClosest = true;
13477 if (anArgIter + 1 < theArgsNb
13478 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13479 {
13480 ++anArgIter;
13481 }
13482 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13483 }
13484 else if ((anArg == "-depthtol"
13485 || anArg == "-depthtolerance")
13486 && anArgIter + 1 < theArgsNb)
13487 {
13488 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13489 aTolType.LowerCase();
13490 if (aTolType == "uniform")
13491 {
13492 if (anArgIter + 1 >= theArgsNb)
13493 {
13494 Message::SendFail() << "Syntax error: wrong number of arguments";
13495 return 1;
13496 }
13497 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13498 Draw::Atof (theArgVec[++anArgIter]));
13499 }
13500 else if (aTolType == "uniformpx")
13501 {
13502 if (anArgIter + 1 >= theArgsNb)
13503 {
13504 Message::SendFail() << "Syntax error: wrong number of arguments";
13505 return 1;
13506 }
13507 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13508 Draw::Atof (theArgVec[++anArgIter]));
13509 }
13510 else if (aTolType == "sensfactor")
13511 {
13512 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13513 }
13514 else
13515 {
13516 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13517 return 1;
13518 }
13519 }
f838dac4 13520 else if ((anArg == "-mode"
13521 || anArg == "-dispmode")
13522 && anArgIter + 1 < theArgsNb)
13523 {
13524 if (aType == Prs3d_TypeOfHighlight_None)
13525 {
23fe70ec 13526 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13527 return 1;
13528 }
8e5fb5ea 13529
f838dac4 13530 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13531 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13532 aStyle->SetDisplayMode (aDispMode);
13533 toRedraw = Standard_True;
13534 }
13535 else if (anArg == "-layer"
13536 && anArgIter + 1 < theArgsNb)
13537 {
13538 if (aType == Prs3d_TypeOfHighlight_None)
13539 {
23fe70ec 13540 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13541 return 1;
13542 }
8e5fb5ea 13543
55c8f0f7
BB
13544 ++anArgIter;
13545 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13546 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13547 {
23fe70ec 13548 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13549 return 1;
f838dac4 13550 }
8e5fb5ea 13551
f838dac4 13552 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13553 aStyle->SetZLayer (aNewLayer);
13554 toRedraw = Standard_True;
13555 }
13556 else if (anArg == "-hicolor"
13557 || anArg == "-selcolor"
13558 || anArg == "-color")
13559 {
13560 if (anArg.StartsWith ("-hi"))
13561 {
13562 aType = Prs3d_TypeOfHighlight_Dynamic;
13563 }
13564 else if (anArg.StartsWith ("-sel"))
13565 {
13566 aType = Prs3d_TypeOfHighlight_Selected;
13567 }
13568 else if (aType == Prs3d_TypeOfHighlight_None)
13569 {
23fe70ec 13570 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13571 return 1;
13572 }
8e5fb5ea 13573
f838dac4 13574 Quantity_Color aColor;
dae2a922 13575 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13576 theArgVec + anArgIter + 1,
13577 aColor);
f838dac4 13578 if (aNbParsed == 0)
13579 {
23fe70ec 13580 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13581 return 1;
13582 }
13583 anArgIter += aNbParsed;
8e5fb5ea 13584
f838dac4 13585 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13586 aStyle->SetColor (aColor);
13587 toRedraw = Standard_True;
13588 }
13589 else if ((anArg == "-transp"
13590 || anArg == "-transparency"
13591 || anArg == "-hitransp"
13592 || anArg == "-seltransp"
13593 || anArg == "-hitransplocal"
13594 || anArg == "-seltransplocal")
13595 && anArgIter + 1 < theArgsNb)
13596 {
13597 if (anArg.StartsWith ("-hi"))
13598 {
13599 aType = Prs3d_TypeOfHighlight_Dynamic;
13600 }
13601 else if (anArg.StartsWith ("-sel"))
13602 {
13603 aType = Prs3d_TypeOfHighlight_Selected;
13604 }
13605 else if (aType == Prs3d_TypeOfHighlight_None)
13606 {
23fe70ec 13607 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13608 return 1;
13609 }
8e5fb5ea 13610
f838dac4 13611 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13612 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13613 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13614 toRedraw = Standard_True;
13615 }
13616 else if ((anArg == "-mat"
13617 || anArg == "-material")
13618 && anArgIter + 1 < theArgsNb)
13619 {
13620 if (aType == Prs3d_TypeOfHighlight_None)
13621 {
23fe70ec 13622 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13623 return 1;
13624 }
8e5fb5ea 13625
f838dac4 13626 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13627 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 13628 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 13629 {
13630 ++anArgIter;
13631 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13632 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13633 Graphic3d_MaterialAspect aMat (aMatName);
13634 aMat.SetColor (aStyle->Color());
13635 aMat.SetTransparency (aStyle->Transparency());
13636 anAspect->SetFrontMaterial (aMat);
13637 anAspect->SetInteriorColor (aStyle->Color());
13638 aStyle->SetBasicFillAreaAspect (anAspect);
13639 }
13640 else
13641 {
13642 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13643 }
13644 toRedraw = Standard_True;
13645 }
13646 else
13647 {
23fe70ec 13648 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 13649 return 1;
f838dac4 13650 }
8e5fb5ea 13651 }
13652
f838dac4 13653 if (toPrint)
8e5fb5ea 13654 {
f838dac4 13655 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13656 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13657 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13658 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13659 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13660 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13661 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13662 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13663 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13664 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13665 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13666 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13667 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13668 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13669 }
13670
13671 if (aCtx->NbSelected() != 0 && toRedraw)
13672 {
13673 aCtx->HilightSelected (Standard_True);
13674 }
13675
13676 return 0;
13677}
13678
decdee7d 13679//===============================================================================================
13680//function : VDumpSelectionImage
13681//purpose :
13682//===============================================================================================
13683static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13684 Standard_Integer theArgsNb,
13685 const char** theArgVec)
13686{
decdee7d 13687 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 13688 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 13689 if (aContext.IsNull())
13690 {
23fe70ec 13691 Message::SendFail ("Error: no active viewer");
decdee7d 13692 return 1;
13693 }
13694
13695 TCollection_AsciiString aFile;
13696 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 13697 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 13698 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13699 Standard_Integer aPickedIndex = 1;
13700 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13701 {
13702 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13703 aParam.LowerCase();
13704 if (aParam == "-type")
13705 {
13706 if (++anArgIter >= theArgsNb)
13707 {
df23a355 13708 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
decdee7d 13709 return 1;
13710 }
13711
13712 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13713 aValue.LowerCase();
13714 if (aValue == "depth"
13715 || aValue == "normdepth"
13716 || aValue == "normalizeddepth")
13717 {
13718 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13719 anImgFormat = Image_Format_GrayF;
decdee7d 13720 }
df23a355 13721 else if (aValue == "depthinverted"
13722 || aValue == "normdepthinverted"
13723 || aValue == "normalizeddepthinverted"
13724 || aValue == "inverted")
decdee7d 13725 {
13726 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13727 anImgFormat = Image_Format_GrayF;
decdee7d 13728 }
13729 else if (aValue == "unnormdepth"
13730 || aValue == "unnormalizeddepth")
13731 {
13732 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13733 anImgFormat = Image_Format_GrayF;
decdee7d 13734 }
13735 else if (aValue == "objectcolor"
13736 || aValue == "object"
13737 || aValue == "color")
13738 {
13739 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13740 }
13741 else if (aValue == "entitycolor"
13742 || aValue == "entity")
13743 {
13744 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13745 }
13746 else if (aValue == "ownercolor"
13747 || aValue == "owner")
13748 {
13749 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13750 }
13751 else if (aValue == "selectionmodecolor"
13752 || aValue == "selectionmode"
13753 || aValue == "selmodecolor"
13754 || aValue == "selmode")
13755 {
13756 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13757 }
114e7a90 13758 else if (aValue == "surfnormal"
13759 || aValue == "surfacenormal"
13760 || aValue == "normal")
13761 {
13762 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13763 }
df23a355 13764 else
13765 {
13766 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13767 return 1;
13768 }
decdee7d 13769 }
13770 else if (aParam == "-picked"
13771 || aParam == "-pickeddepth"
13772 || aParam == "-pickedindex")
13773 {
13774 if (++anArgIter >= theArgsNb)
13775 {
23fe70ec 13776 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 13777 return 1;
13778 }
13779
13780 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13781 }
b40cdc2b 13782 else if (anArgIter + 1 < theArgsNb
13783 && aParam == "-xrpose")
13784 {
13785 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13786 anXRArg.LowerCase();
13787 if (anXRArg == "base")
13788 {
13789 aCustomCam = aView->View()->BaseXRCamera();
13790 }
13791 else if (anXRArg == "head")
13792 {
13793 aCustomCam = aView->View()->PosedXRCamera();
13794 }
13795 else
13796 {
13797 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13798 return 1;
13799 }
13800 if (aCustomCam.IsNull())
13801 {
13802 Message::SendFail() << "Error: undefined XR pose";
13803 return 0;
13804 }
13805 }
decdee7d 13806 else if (aFile.IsEmpty())
13807 {
13808 aFile = theArgVec[anArgIter];
13809 }
13810 else
13811 {
23fe70ec 13812 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 13813 return 1;
13814 }
13815 }
13816 if (aFile.IsEmpty())
13817 {
23fe70ec 13818 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 13819 return 1;
13820 }
13821
decdee7d 13822 Standard_Integer aWidth = 0, aHeight = 0;
13823 aView->Window()->Size (aWidth, aHeight);
13824
13825 Image_AlienPixMap aPixMap;
13826 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13827 {
23fe70ec 13828 Message::SendFail ("Error: can't allocate image");
decdee7d 13829 return 1;
13830 }
b40cdc2b 13831
13832 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13833 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13834 if (!aCustomCam.IsNull())
13835 {
13836 aView->SetCamera (aCustomCam);
13837 }
decdee7d 13838 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13839 {
23fe70ec 13840 Message::SendFail ("Error: can't generate selection image");
decdee7d 13841 return 1;
13842 }
b40cdc2b 13843 if (!aCustomCam.IsNull())
13844 {
13845 aView->SetCamera (aCamBack);
13846 }
13847 aView->SetImmediateUpdate (wasImmUpdate);
13848
decdee7d 13849 if (!aPixMap.Save (aFile))
13850 {
23fe70ec 13851 Message::SendFail ("Error: can't save selection image");
decdee7d 13852 return 0;
13853 }
13854 return 0;
13855}
13856
2108d9a2 13857//===============================================================================================
13858//function : VViewCube
13859//purpose :
13860//===============================================================================================
13861static int VViewCube (Draw_Interpretor& ,
13862 Standard_Integer theNbArgs,
13863 const char** theArgVec)
13864{
13865 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13866 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13867 if (aContext.IsNull() || aView.IsNull())
13868 {
23fe70ec 13869 Message::SendFail ("Error: no active viewer");
2108d9a2 13870 return 1;
13871 }
13872 else if (theNbArgs < 2)
13873 {
23fe70ec 13874 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 13875 return 1;
13876 }
13877
13878 Handle(AIS_ViewCube) aViewCube;
13879 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13880 Quantity_Color aColorRgb;
13881 TCollection_AsciiString aName;
13882 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13883 {
13884 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13885 anArg.LowerCase();
13886 if (anUpdateTool.parseRedrawMode (anArg))
13887 {
13888 //
13889 }
13890 else if (aViewCube.IsNull())
13891 {
13892 aName = theArgVec[anArgIter];
13893 if (aName.StartsWith ("-"))
13894 {
23fe70ec 13895 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 13896 return 1;
13897 }
13898 Handle(AIS_InteractiveObject) aPrs;
13899 GetMapOfAIS().Find2 (aName, aPrs);
13900 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13901 if (aViewCube.IsNull())
13902 {
13903 aViewCube = new AIS_ViewCube();
13904 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13905 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13906 aViewCube->SetFixedAnimationLoop (false);
13907 }
13908 }
13909 else if (anArg == "-reset")
13910 {
13911 aViewCube->ResetStyles();
13912 }
13913 else if (anArg == "-color"
13914 || anArg == "-boxcolor"
13915 || anArg == "-boxsidecolor"
13916 || anArg == "-sidecolor"
13917 || anArg == "-boxedgecolor"
13918 || anArg == "-edgecolor"
13919 || anArg == "-boxcornercolor"
13920 || anArg == "-cornercolor"
13921 || anArg == "-innercolor"
0aeb8984 13922 || anArg == "-textcolor"
13923 || anArg == "-xaxistextcolor"
13924 || anArg == "-yaxistextcolor"
13925 || anArg == "-zaxistextcolor")
2108d9a2 13926 {
dae2a922 13927 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13928 theArgVec + anArgIter + 1,
13929 aColorRgb);
2108d9a2 13930 if (aNbParsed == 0)
13931 {
23fe70ec 13932 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 13933 return 1;
13934 }
13935 anArgIter += aNbParsed;
13936 if (anArg == "-boxcolor")
13937 {
13938 aViewCube->SetBoxColor (aColorRgb);
13939 }
13940 else if (anArg == "-boxsidecolor"
13941 || anArg == "-sidecolor")
13942 {
13943 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13944 aViewCube->SynchronizeAspects();
13945 }
13946 else if (anArg == "-boxedgecolor"
13947 || anArg == "-edgecolor")
13948 {
13949 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13950 aViewCube->SynchronizeAspects();
13951 }
13952 else if (anArg == "-boxcornercolor"
13953 || anArg == "-cornercolor")
13954 {
13955 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13956 aViewCube->SynchronizeAspects();
13957 }
13958 else if (anArg == "-innercolor")
13959 {
13960 aViewCube->SetInnerColor (aColorRgb);
13961 }
13962 else if (anArg == "-textcolor")
13963 {
13964 aViewCube->SetTextColor (aColorRgb);
13965 }
0aeb8984 13966 else if (anArg == "-xaxistextcolor"
13967 || anArg == "-yaxistextcolor"
13968 || anArg == "-zaxistextcolor")
13969 {
13970 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13971 ? Prs3d_DatumParts_XAxis
13972 : (anArg.Value (2) == 'y'
13973 ? Prs3d_DatumParts_YAxis
13974 : Prs3d_DatumParts_ZAxis);
13975 aViewCube->Attributes()->SetOwnDatumAspects();
13976 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13977 }
2108d9a2 13978 else
13979 {
13980 aViewCube->SetColor (aColorRgb);
13981 }
13982 }
13983 else if (anArgIter + 1 < theNbArgs
13984 && (anArg == "-transparency"
13985 || anArg == "-boxtransparency"))
13986 {
13987 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13988 if (aValue < 0.0 || aValue > 1.0)
13989 {
23fe70ec 13990 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 13991 return 1;
13992 }
13993
13994 if (anArg == "-boxtransparency")
13995 {
13996 aViewCube->SetBoxTransparency (aValue);
13997 }
13998 else
13999 {
14000 aViewCube->SetTransparency (aValue);
14001 }
14002 }
14003 else if (anArg == "-axes"
14004 || anArg == "-edges"
14005 || anArg == "-vertices"
14006 || anArg == "-vertexes"
14007 || anArg == "-fixedanimation")
14008 {
14009 bool toShow = true;
14010 if (anArgIter + 1 < theNbArgs
dae2a922 14011 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 14012 {
14013 ++anArgIter;
14014 }
14015 if (anArg == "-fixedanimation")
14016 {
14017 aViewCube->SetFixedAnimationLoop (toShow);
14018 }
14019 else if (anArg == "-axes")
14020 {
14021 aViewCube->SetDrawAxes (toShow);
14022 }
14023 else if (anArg == "-edges")
14024 {
14025 aViewCube->SetDrawEdges (toShow);
14026 }
14027 else
14028 {
14029 aViewCube->SetDrawVertices (toShow);
14030 }
14031 }
14032 else if (anArg == "-yup"
14033 || anArg == "-zup")
14034 {
14035 bool isOn = true;
14036 if (anArgIter + 1 < theNbArgs
dae2a922 14037 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 14038 {
14039 ++anArgIter;
14040 }
14041 if (anArg == "-yup")
14042 {
14043 aViewCube->SetYup (isOn);
14044 }
14045 else
14046 {
14047 aViewCube->SetYup (!isOn);
14048 }
14049 }
14050 else if (anArgIter + 1 < theNbArgs
14051 && anArg == "-font")
14052 {
14053 aViewCube->SetFont (theArgVec[++anArgIter]);
14054 }
14055 else if (anArgIter + 1 < theNbArgs
14056 && anArg == "-fontheight")
14057 {
14058 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
14059 }
14060 else if (anArgIter + 1 < theNbArgs
14061 && (anArg == "-size"
14062 || anArg == "-boxsize"))
14063 {
14064 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
14065 anArg != "-boxsize");
14066 }
14067 else if (anArgIter + 1 < theNbArgs
14068 && (anArg == "-boxfacet"
14069 || anArg == "-boxfacetextension"
14070 || anArg == "-facetextension"
14071 || anArg == "-extension"))
14072 {
14073 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
14074 }
14075 else if (anArgIter + 1 < theNbArgs
14076 && (anArg == "-boxedgegap"
14077 || anArg == "-edgegap"))
14078 {
14079 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
14080 }
14081 else if (anArgIter + 1 < theNbArgs
14082 && (anArg == "-boxedgeminsize"
14083 || anArg == "-edgeminsize"))
14084 {
14085 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14086 }
14087 else if (anArgIter + 1 < theNbArgs
14088 && (anArg == "-boxcornerminsize"
14089 || anArg == "-cornerminsize"))
14090 {
14091 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14092 }
14093 else if (anArgIter + 1 < theNbArgs
14094 && anArg == "-axespadding")
14095 {
14096 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14097 }
14098 else if (anArgIter + 1 < theNbArgs
14099 && anArg == "-roundradius")
14100 {
14101 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14102 }
14103 else if (anArgIter + 1 < theNbArgs
14104 && anArg == "-duration")
14105 {
14106 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14107 }
6466cc9e 14108 else if (anArgIter + 1 < theNbArgs
14109 && anArg == "-axesradius")
14110 {
14111 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14112 }
14113 else if (anArgIter + 1 < theNbArgs
14114 && anArg == "-axesconeradius")
14115 {
14116 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14117 }
14118 else if (anArgIter + 1 < theNbArgs
14119 && anArg == "-axessphereradius")
14120 {
14121 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14122 }
2108d9a2 14123 else
14124 {
23fe70ec 14125 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 14126 return 1;
14127 }
14128 }
14129 if (aViewCube.IsNull())
14130 {
23fe70ec 14131 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 14132 return 1;
14133 }
14134
14135 ViewerTest::Display (aName, aViewCube, false);
14136 return 0;
14137}
14138
14b741b0 14139//===============================================================================================
14140//function : VColorConvert
14141//purpose :
14142//===============================================================================================
14143static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14144{
14145 if (theNbArgs != 6)
14146 {
14147 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14148 return 1;
14149 }
14150
14151 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14152 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14153 {
14154 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14155 return 1;
14156 }
14157
14158 const char* aTypeStr = theArgVec[2];
14159 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14160 if (! strcasecmp (aTypeStr, "srgb"))
14161 {
14162 aType = Quantity_TOC_sRGB;
14163 }
14164 else if (! strcasecmp (aTypeStr, "hls"))
14165 {
14166 aType = Quantity_TOC_HLS;
14167 }
14168 else if (! strcasecmp (aTypeStr, "lab"))
14169 {
14170 aType = Quantity_TOC_CIELab;
14171 }
14172 else if (! strcasecmp (aTypeStr, "lch"))
14173 {
14174 aType = Quantity_TOC_CIELch;
14175 }
14176 else
14177 {
14178 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14179 return 1;
14180 }
14181
14182 double aC1 = Draw::Atof (theArgVec[3]);
14183 double aC2 = Draw::Atof (theArgVec[4]);
14184 double aC3 = Draw::Atof (theArgVec[5]);
14185
14186 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14187 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14188
14189 // print values with 6 decimal digits
14190 char buffer[1024];
14191 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14192 theDI << buffer;
14193
14194 return 0;
14195}
14196
14197//===============================================================================================
14198//function : VColorDiff
14199//purpose :
14200//===============================================================================================
14201static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14202{
14203 if (theNbArgs != 7)
14204 {
14205 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14206 return 1;
14207 }
14208
14209 double aR1 = Draw::Atof (theArgVec[1]);
14210 double aG1 = Draw::Atof (theArgVec[2]);
14211 double aB1 = Draw::Atof (theArgVec[3]);
14212 double aR2 = Draw::Atof (theArgVec[4]);
14213 double aG2 = Draw::Atof (theArgVec[5]);
14214 double aB2 = Draw::Atof (theArgVec[6]);
14215
14216 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14217 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14218
14219 theDI << aColor1.DeltaE2000 (aColor2);
14220
14221 return 0;
14222}
14223
6a2fb7a1 14224//===============================================================================================
4551e1be 14225//function : VSelBvhBuild
6a2fb7a1 14226//purpose :
14227//===============================================================================================
14228static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14229{
14230 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14231 if (aCtx.IsNull())
14232 {
14233 Message::SendFail ("Error: no active viewer");
14234 return 1;
14235 }
14236
14237 if (theNbArgs < 2)
14238 {
14239 Message::SendFail ("Error: command syntax is incorrect, see help");
14240 return 1;
14241 }
14242
14243 Standard_Integer toEnable = -1;
14244 Standard_Integer aThreadsNb = -1;
14245 Standard_Boolean toWait = Standard_False;
14246
14247 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14248 {
14249 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14250 anArg.LowerCase();
14251
14252 if (anArg == "-nbthreads"
14253 && anArgIter + 1 < theNbArgs)
14254 {
14255 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14256 if (aThreadsNb < 1)
14257 {
14258 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14259 }
14260 }
14261 else if (anArg == "-wait")
14262 {
14263 toWait = Standard_True;
14264 }
14265 else if (toEnable == -1)
14266 {
14267 Standard_Boolean toEnableValue = Standard_True;
14268 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14269 {
14270 toEnable = toEnableValue ? 1 : 0;
14271 }
14272 else
14273 {
14274 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14275 return 1;
14276 }
14277 }
14278 else
14279 {
14280 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14281 return 1;
14282 }
14283 }
14284
14285 if (aThreadsNb == -1)
14286 {
14287 aThreadsNb = 1;
14288 }
14289 if (toEnable != -1)
14290 {
14291 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14292 }
14293 if (toWait)
14294 {
14295 aCtx->MainSelector()->WaitForBVHBuild();
14296 }
14297
14298 return 0;
14299}
14300
a6049685 14301//=======================================================================
14302//function : ViewerTest_ExitProc
14303//purpose :
14304//=======================================================================
14305static void ViewerTest_ExitProc (ClientData )
14306{
14307 NCollection_List<TCollection_AsciiString> aViewList;
14308 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14309 anIter.More(); anIter.Next())
14310 {
14311 aViewList.Append (anIter.Key1());
14312 }
14313
14314 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14315 anIter.More(); anIter.Next())
14316 {
14317 ViewerTest::RemoveView (anIter.Value(), true);
14318 }
14319}
14320
7fd59977 14321//=======================================================================
14322//function : ViewerCommands
14323//purpose :
14324//=======================================================================
14325
14326void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14327{
a6049685 14328 static bool TheIsInitialized = false;
14329 if (TheIsInitialized)
14330 {
14331 return;
14332 }
14333
14334 TheIsInitialized = true;
14335 // define destruction callback to destroy views in a well-defined order
14336 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
7fd59977 14337
14338 const char *group = "ZeViewer";
b8db9379 14339 theCommands.Add("vdriver",
14340 "vdriver [-list] [-default DriverName] [-load DriverName]"
14341 "\n\t\t: Manages active graphic driver factory."
14342 "\n\t\t: Prints current active driver when called without arguments."
14343 "\n\t\t: Makes specified driver active when ActiveName argument is specified."
14344 "\n\t\t: -list print registered factories"
14345 "\n\t\t: -default define which factory should be used by default (to be used by next vinit call)"
14346 "\n\t\t: -load try loading factory plugin and set it as default one",
14347 __FILE__, VDriver, group);
18d715bd 14348 theCommands.Add("vinit",
fd3f6bd0 14349 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
72ed0644 14350 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
b69e576a 14351 #if defined(HAVE_XLIB)
fd3f6bd0 14352 "\n\t\t: [-display displayName]"
14353 #endif
14354 "\n\t\t: Creates new View window with specified name viewName."
14355 "\n\t\t: By default the new view is created in the viewer and in"
14356 "\n\t\t: graphic driver shared with active view."
14357 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14358 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14359 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
b69e576a 14360#if defined(HAVE_XLIB)
fd3f6bd0 14361 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14362 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14363#endif
fd3f6bd0 14364 "\n\t\t: -left, -top pixel position of left top corner of the window."
4551e1be 14365 "\n\t\t: -width, -height width and height of window respectively."
72ed0644 14366 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
fd3f6bd0 14367 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14368 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
72ed0644 14369 "\n\t\t: -virtual create an offscreen window within interactive session"
2e93433e 14370 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14371 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14372 __FILE__,VInit,group);
18d715bd 14373 theCommands.Add("vclose" ,
d0cc1cb7 14374 "[view_id [keep_context=0|1]]\n"
18d715bd 14375 "or vclose ALL - to remove all created views\n"
14376 " - removes view(viewer window) defined by its view_id.\n"
14377 " - keep_context: by default 0; if 1 and the last view is deleted"
14378 " the current context is not removed.",
14379 __FILE__,VClose,group);
14380 theCommands.Add("vactivate" ,
e084dbbc 14381 "vactivate view_id [-noUpdate]"
18d715bd 14382 " - activates view(viewer window) defined by its view_id",
14383 __FILE__,VActivate,group);
14384 theCommands.Add("vviewlist",
14385 "vviewlist [format={tree, long}]"
14386 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14387 " - format: format of result output, if tree the output is a tree view;"
14388 "otherwise it's a list of full view names. By default format = tree",
14389 __FILE__,VViewList,group);
7fd59977 14390 theCommands.Add("vhelp" ,
14391 "vhelp : display help on the viewer commands",
14392 __FILE__,VHelp,group);
fc552d84 14393 theCommands.Add("vviewproj",
14394 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14395 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14396 "\n\t\t: Setup view direction"
14397 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14398 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14399 "\n\t\t: for example '+Z' will show front of the model,"
14400 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14401 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14402 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14403 __FILE__,VViewProj,group);
7fd59977 14404 theCommands.Add("vtop" ,
27af3052 14405 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14406 __FILE__,VViewProj,group);
44b8f2d6 14407 theCommands.Add("vbottom" ,
27af3052 14408 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14409 __FILE__,VViewProj,group);
44b8f2d6 14410 theCommands.Add("vleft" ,
27af3052 14411 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14412 __FILE__,VViewProj,group);
44b8f2d6 14413 theCommands.Add("vright" ,
27af3052 14414 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14415 __FILE__,VViewProj,group);
7fd59977 14416 theCommands.Add("vaxo" ,
27af3052 14417 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14418 __FILE__,VViewProj,group);
44b8f2d6 14419 theCommands.Add("vfront" ,
27af3052 14420 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14421 __FILE__,VViewProj,group);
44b8f2d6 14422 theCommands.Add("vback" ,
27af3052 14423 "vback : Back view. Orientation -X+Z" ,
fc552d84 14424 __FILE__,VViewProj,group);
7fd59977 14425 theCommands.Add("vpick" ,
14426 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14427 VPick,group);
1beb58d7 14428 theCommands.Add("vfit",
14429 "vfit or <F> [-selected] [-noupdate]"
b586500b 14430 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14431 __FILE__,VFit,group);
6262a303 14432 theCommands.Add ("vfitarea",
14433 "vfitarea x1 y1 x2 y2"
14434 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14435 "\n\t\t: Fit view to show area located between two points"
14436 "\n\t\t: given in world 2D or 3D corrdinates.",
14437 __FILE__, VFitArea, group);
197ac94e 14438 theCommands.Add ("vzfit", "vzfit [scale]\n"
14439 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14440 " \"scale\" - specifies factor to scale computed z range.\n",
14441 __FILE__, VZFit, group);
7fd59977 14442 theCommands.Add("vrepaint",
8693dfd0 14443 "vrepaint [-immediate] [-continuous FPS]"
14444 "\n\t\t: force redraw of active View"
14445 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14446 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14447 "\n\t\t: 0 means no continuous rendering,"
14448 "\n\t\t: -1 means non-stop redraws,"
14449 "\n\t\t: >0 specifies target framerate,",
7fd59977 14450 __FILE__,VRepaint,group);
14451 theCommands.Add("vclear",
faea8b40 14452 "vclear : vclear"
14453 "\n\t\t: remove all the object from the viewer",
7fd59977 14454 __FILE__,VClear,group);
293211ae 14455 theCommands.Add (
14456 "vbackground",
14457 "Changes background or some background settings.\n"
14458 "\n"
14459 "Usage:\n"
14460 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14461 " vbackground -imageMode FillType\n"
14462 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14463 " vbackground -gradientMode FillMethod\n"
077a220c 14464 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14465 " vbackground -color Color\n"
14466 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14467 " vbackground -default -color Color\n"
14468 " vbackground -help\n"
14469 "\n"
14470 "Options:\n"
14471 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14472 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14473 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14474 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
4551e1be 14475 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
077a220c 14476 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14477 " -order (-o): defines order of tiles in one image cubemap\n"
14478 " (has no effect in case of multi image cubemaps)\n"
293211ae 14479 " -color (-col): sets background color\n"
14480 " -default (-def): sets background default gradient or color\n"
14481 " -help (-h): outputs short help message\n"
14482 "\n"
14483 "Arguments:\n"
077a220c 14484 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14485 " or reals within the range [0.0, 1.0]\n"
077a220c 14486 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14487 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14488 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14489 "CORNER4\n"
077a220c 14490 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14491 " ImageFile: a name of the file with the image used as a background\n"
14492 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14493 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14494 __FILE__,
14495 vbackground,
14496 group);
14497 theCommands.Add ("vsetbg",
14498 "Loads image as background."
14499 "\n\t\t: vsetbg ImageFile [FillType]"
14500 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14501 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14502 __FILE__,
14503 vbackground,
14504 group);
14505 theCommands.Add ("vsetbgmode",
14506 "Changes background image fill type."
14507 "\n\t\t: vsetbgmode [-imageMode] FillType"
14508 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14509 __FILE__,
14510 vbackground,
14511 group);
14512 theCommands.Add ("vsetgradientbg",
14513 "Mounts gradient background."
14514 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14515 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14516 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14517 __FILE__,
14518 vbackground,
14519 group);
14520 theCommands.Add ("vsetgrbgmode",
14521 "Changes gradient background fill method."
14522 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14523 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14524 __FILE__,
14525 vbackground,
14526 group);
14527 theCommands.Add ("vsetcolorbg",
14528 "Sets background color."
14529 "\n\t\t: vsetcolorbg [-color] Color."
14530 "\n\t\t: Alias for 'vbackground -color Color'.",
14531 __FILE__,
14532 vbackground,
14533 group);
14534 theCommands.Add ("vsetdefaultbg",
14535 "Sets default viewer background fill color (flat/gradient)."
14536 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14537 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14538 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14539 "\n\t\t: vsetdefaultbg [-color] Color"
14540 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14541 __FILE__,
14542 vbackground,
14543 group);
7fd59977 14544 theCommands.Add("vscale",
14545 "vscale : vscale X Y Z",
14546 __FILE__,VScale,group);
14547 theCommands.Add("vzbufftrihedron",
536d98e2 14548 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14549 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14550 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14551 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14552 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
0aeb8984 14553 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
536d98e2 14554 "\n\t\t: Displays a trihedron",
14555 __FILE__,VZBuffTrihedron,group);
7fd59977 14556 theCommands.Add("vrotate",
4af098ba 14557 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14558 "\n : Option -mouseStart starts rotation according to the mouse position"
14559 "\n : Option -mouseMove continues rotation with angle computed"
14560 "\n : from last and new mouse position."
14561 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14562 __FILE__,VRotate,group);
14563 theCommands.Add("vzoom",
14564 "vzoom : vzoom coef",
14565 __FILE__,VZoom,group);
14566 theCommands.Add("vpan",
14567 "vpan : vpan dx dy",
14568 __FILE__,VPan,group);
7fd59977 14569 theCommands.Add("vcolorscale",
4b3d6eb1 14570 "vcolorscale name [-noupdate|-update] [-demo]"
14571 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14572 "\n\t\t: [-font HeightFont=20]"
14573 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14574 "\n\t\t: [-smoothTransition {on|off}=off]"
14575 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14576 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14577 "\n\t\t: [-textpos {left|right|center|none}=right]"
14578 "\n\t\t: [-labelAtBorder {on|off}=on]"
14579 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14580 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14581 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14582 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14583 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14584 "\n\t\t: -demo - displays a color scale with demonstratio values"
14585 "\n\t\t: -colors - set colors for all intervals"
14586 "\n\t\t: -color - set color for specific interval"
14b741b0 14587 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14588 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14589 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14590 "\n\t\t: at border means the value inbetween neighbor intervals,"
14591 "\n\t\t: at center means the center value within current interval"
14592 "\n\t\t: -labels - set labels for all intervals"
14593 "\n\t\t: -freeLabels - same as -labels but does not require"
14594 "\n\t\t: matching the number of intervals"
14595 "\n\t\t: -label - set label for specific interval"
14596 "\n\t\t: -title - set title"
14597 "\n\t\t: -reversed - setup smooth color transition between intervals"
14598 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14599 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14600 __FILE__, VColorScale, group);
7fd59977 14601 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14602 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14603 "\t[-namefont Name] [-valuesfont Name]\n"
14604 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14605 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14606 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14607 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14608 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14609 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14610 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14611 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14612 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14613 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14614 " - Displays or erases graduated trihedron"
14615 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14616 " - namefont - font of axes names. Default: Arial\n"
14617 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14618 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14619 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14620 " - valuesfont - font of axes values. Default: Arial\n"
14621 " - xcolor, ycolor, zcolor - color of axis and values\n"
14622 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14623 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14624 __FILE__,VGraduatedTrihedron,group);
3bffef55 14625 theCommands.Add("vtile" ,
14626 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14627 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14628 "\n\t\t: -totalSize the size of virtual bigger viewport"
14629 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14630 "\n\t\t: -lowerLeft tile offset as lower left corner"
14631 "\n\t\t: -upperLeft tile offset as upper left corner",
14632 __FILE__, VTile, group);
59f45b7c 14633 theCommands.Add("vzlayer",
7c3ef2f7 14634 "vzlayer [layerId]"
1c728f2d 14635 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14636 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14637 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14638 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14639 "\n\t\t: ZLayer list management:"
14640 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14641 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14642 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14643 "\n\t\t: -delete delete z layer"
14644 "\n\t\t: -get print sequence of z layers"
14645 "\n\t\t: -settings print status of z layer settings"
14646 "\n\t\t: -disable disables given setting"
14647 "\n\t\t: -enable enables given setting",
59f45b7c 14648 __FILE__,VZLayer,group);
20637bd2 14649 theCommands.Add("vlayerline",
14650 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14651 __FILE__,VLayerLine,group);
79931835 14652 theCommands.Add("vgrid",
14653 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14654 "\n\t\t: [-step X Y] [-size DX DY]"
14655 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 14656 __FILE__, VGrid, group);
c40b7d58 14657 theCommands.Add ("vpriviledgedplane",
14658 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14659 "\n\t\t: Ox, Oy, Oz - plane origin"
14660 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14661 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14662 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14663 __FILE__, VPriviledgedPlane, group);
f25b82d6 14664 theCommands.Add ("vconvert",
14665 "vconvert v [Mode={window|view}]"
14666 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14667 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14668 "\n\t\t: window - convert to window coordinates, pixels"
14669 "\n\t\t: view - convert to view projection plane"
14670 "\n\t\t: grid - convert to model coordinates, given on grid"
4551e1be 14671 "\n\t\t: ray - convert projection ray to model coordinates"
f25b82d6 14672 "\n\t\t: - vconvert v window : convert view to window;"
14673 "\n\t\t: - vconvert v view : convert window to view;"
14674 "\n\t\t: - vconvert x y window : convert view to window;"
14675 "\n\t\t: - vconvert x y view : convert window to view;"
14676 "\n\t\t: - vconvert x y : convert window to model;"
14677 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14678 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14679 "\n\t\t: - vconvert x y z window : convert model to window;"
14680 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14681 "\n\t\t: Converts the given coordinates to window/view/model space.",
14682 __FILE__, VConvert, group);
208e6839 14683 theCommands.Add ("vfps",
e084dbbc 14684 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 14685 __FILE__, VFps, group);
b5ac8292 14686 theCommands.Add ("vstereo",
f978241f 14687 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 14688 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 14689 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 14690 "\n\t\t: Control stereo output mode."
14691 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14692 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14693 "\n\t\t: Available modes for -mode:"
f978241f 14694 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14695 "\n\t\t: requires driver support."
14696 "\n\t\t: Should be called BEFORE vinit!"
14697 "\n\t\t: anaglyph - Anaglyph glasses"
14698 "\n\t\t: rowInterlaced - row-interlaced display"
14699 "\n\t\t: columnInterlaced - column-interlaced display"
14700 "\n\t\t: chessBoard - chess-board output"
14701 "\n\t\t: sideBySide - horizontal pair"
14702 "\n\t\t: overUnder - vertical pair"
b40cdc2b 14703 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 14704 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14705 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14706 "\n\t\t: greenMagentaSimple",
b5ac8292 14707 __FILE__, VStereo, group);
f0430952 14708 theCommands.Add ("vmemgpu",
14709 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14710 " with f option returns free memory in bytes",
14711 __FILE__, VMemGpu, group);
85e096c3 14712 theCommands.Add ("vreadpixel",
ba00aab7 14713 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 14714 " : Read pixel value for active view",
14715 __FILE__, VReadPixel, group);
692613e5 14716 theCommands.Add("diffimage",
fd3f6bd0 14717 "diffimage imageFile1 imageFile2 [diffImageFile]"
14718 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14719 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14720 "\n\t\t: Compare two images by content and generate difference image."
14721 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14722 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 14723 __FILE__, VDiffImage, group);
4754e164 14724 theCommands.Add ("vselect",
e76471b5 14725 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-replaceextra|-xor|-add|-remove]\n"
4754e164 14726 "- emulates different types of selection:\n"
14727 "- 1) single click selection\n"
14728 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14729 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 14730 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14731 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14732 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14733 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
e76471b5 14734 "- 5) selection scheme replace, replaceextra, xor, add or remove (replace by default)",
4754e164 14735 __FILE__, VSelect, group);
14736 theCommands.Add ("vmoveto",
8a590580 14737 "vmoveto [x y] [-reset]"
14738 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14739 "\n\t\t: -reset resets current highlighting",
4754e164 14740 __FILE__, VMoveTo, group);
0461e7fd 14741 theCommands.Add ("vselaxis",
14742 "vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14743 "\n\t\t: Provides intersection by given axis and print result intersection points"
14744 "\n\t\t: -onlyTop switches On/Off mode to find only top point or all"
14745 "\n\t\t: -display Name displays intersecting axis and result intersection points for debug goals"
14746 "\n\t\t: -showNormal adds displaying of normal in intersection point or not",
14747 __FILE__, VSelectByAxis, group);
1beb58d7 14748 theCommands.Add ("vviewparams",
14749 "vviewparams [-args] [-scale [s]]"
14750 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14751 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14752 "\n\t\t: Manage current view parameters or prints all"
14753 "\n\t\t: current values when called without argument."
14754 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14755 "\n\t\t: -eye [x y z] prints or sets eye location"
14756 "\n\t\t: -at [x y z] prints or sets center of look"
14757 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14758 "\n\t\t: -proj [x y z] prints or sets direction of look"
14759 "\n\t\t: -center x y sets location of center of the screen in pixels"
14760 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14761 "\n\t\t: or changes the size of its maximum dimension"
14762 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 14763 __FILE__, VViewParams, group);
1beb58d7 14764
2e93433e 14765 theCommands.Add("v2dmode",
14766 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14767 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14768 "\n\t\t: mode - switches On/Off rotation mode"
14769 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14770 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14771 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14772 "\n\t\t: View camera position might be changed only by commands.",
14773 __FILE__, V2DMode, group);
14774
1beb58d7 14775 theCommands.Add("vanimation", "Alias for vanim",
14776 __FILE__, VAnimation, group);
14777
14778 theCommands.Add("vanim",
14779 "List existing animations:"
14780 "\n\t\t: vanim"
14781 "\n\t\t: Animation playback:"
14782 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14783 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14784 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14785 "\n\t\t: -freeLook skip camera animations"
14786 "\n\t\t: -lockLoop disable any interactions"
14787 "\n\t\t:"
14788 "\n\t\t: Animation definition:"
14789 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14790 "\n\t\t: [start TimeSec] [duration TimeSec]"
14791 "\n\t\t:"
14792 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14793 "\n\t\t: specifies nested animations."
14794 "\n\t\t: There is no syntax to explicitly add new animation,"
14795 "\n\t\t: and all non-existing animations within the name will be"
14796 "\n\t\t: implicitly created on first use (including parents)."
14797 "\n\t\t:"
14798 "\n\t\t: Each animation might define the SINGLE action (see below),"
14799 "\n\t\t: like camera transition, object transformation or custom callback."
14800 "\n\t\t: Child animations can be used for defining concurrent actions."
14801 "\n\t\t:"
14802 "\n\t\t: Camera animation:"
14803 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14804 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14805 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14806 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14807 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14808 "\n\t\t: -atX camera Center positions pair"
14809 "\n\t\t: -upX camera Up directions pair"
14810 "\n\t\t: -scaleX camera Scale factors pair"
14811 "\n\t\t: Object animation:"
14812 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14813 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14814 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14815 "\n\t\t: -locX object Location points pair (translation)"
14816 "\n\t\t: -rotX object Orientations pair (quaternions)"
14817 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14818 "\n\t\t: Custom callback:"
14819 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14820 "\n\t\t: %Pts overall animation presentation timestamp"
14821 "\n\t\t: %LocalPts local animation timestamp"
14822 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 14823 "\n\t\t:"
14824 "\n\t\t: Video recording:"
14825 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14826 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14827 "\n\t\t: [-crf Value] [-preset Preset]"
14828 "\n\t\t: -fps video framerate"
14829 "\n\t\t: -format file format, container (matroska, etc.)"
14830 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14831 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14832 "\n\t\t: -crf constant rate factor (specific to codec)"
14833 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 14834 __FILE__, VAnimation, group);
14835
4754e164 14836 theCommands.Add("vchangeselected",
dc3fe572 14837 "vchangeselected shape"
4754e164 14838 "- adds to shape to selection or remove one from it",
14839 __FILE__, VChangeSelected, group);
4754e164 14840 theCommands.Add ("vnbselected",
faea8b40 14841 "vnbselected"
14842 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14843 theCommands.Add ("vcamera",
30a1b24e 14844 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14845 "\n\t\t: [-persp]"
14846 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14847 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14848 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14849 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 14850 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14851 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 14852 "\n\t\t: Manages camera parameters."
4551e1be 14853 "\n\t\t: Displays frustum when presentation name PrsName is specified."
6b62b2da 14854 "\n\t\t: Prints current value when option called without argument."
14855 "\n\t\t: Orthographic camera:"
14856 "\n\t\t: -ortho activate orthographic projection"
14857 "\n\t\t: Perspective camera:"
14858 "\n\t\t: -persp activate perspective projection (mono)"
14859 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 14860 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 14861 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 14862 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 14863 "\n\t\t: Stereoscopic camera:"
14864 "\n\t\t: -stereo perspective projection (stereo)"
14865 "\n\t\t: -leftEye perspective projection (left eye)"
14866 "\n\t\t: -rightEye perspective projection (right eye)"
14867 "\n\t\t: -iod intraocular distance value"
14868 "\n\t\t: -iodType distance type, absolute or relative"
14869 "\n\t\t: -zfocus stereographic focus value"
14870 "\n\t\t: -zfocusType focus type, absolute or relative",
14871 __FILE__, VCamera, group);
b5ac8292 14872 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14873 "- vautozfit [on={1|0}] [scale]\n"
14874 " Prints or changes parameters of automatic z-fit mode:\n"
14875 " \"on\" - turns automatic z-fit on or off\n"
14876 " \"scale\" - specifies factor to scale computed z range.\n",
14877 __FILE__, VAutoZFit, group);
b5ac8292 14878 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14879 " vzrange - without parameters shows current values\n"
14880 " vzrange [znear] [zfar] - applies provided values to view",
14881 __FILE__,VZRange, group);
4754e164 14882 theCommands.Add("vsetviewsize",
14883 "vsetviewsize size",
14884 __FILE__,VSetViewSize,group);
14885 theCommands.Add("vmoveview",
14886 "vmoveview Dx Dy Dz [Start = 1|0]",
14887 __FILE__,VMoveView,group);
14888 theCommands.Add("vtranslateview",
14889 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14890 __FILE__,VTranslateView,group);
14891 theCommands.Add("vturnview",
14892 "vturnview Ax Ay Az [Start = 1|0]",
14893 __FILE__,VTurnView,group);
269294d6 14894 theCommands.Add("vtextureenv",
14895 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14896 "or user-defined file and optionally applying texture mapping parameters\n"
14897 " Usage:\n"
14898 " vtextureenv off - disables environment mapping\n"
14899 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14900 " std_texture = (0..7)\n"
14901 " rep = {clamp|repeat}\n"
14902 " mod = {decal|modulate}\n"
14903 " flt = {nearest|bilinear|trilinear}\n"
14904 " ss, st - scale factors for s and t texture coordinates\n"
14905 " ts, tt - translation for s and t texture coordinates\n"
14906 " rot - texture rotation angle in degrees",
14907 __FILE__, VTextureEnv, group);
1eeef710 14908 theCommands.Add("vhlr",
14909 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14910 "\n\t\t: Hidden Line Removal algorithm."
14911 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14912 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 14913 __FILE__,VHLR,group);
1eeef710 14914 theCommands.Add("vhlrtype",
14915 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14916 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14917 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14918 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14919 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 14920 __FILE__,VHLRType,group);
3e05329c 14921 theCommands.Add("vclipplane",
14922 "vclipplane planeName [{0|1}]"
25c35042 14923 "\n\t\t: [-equation1 A B C D]"
14924 "\n\t\t: [-equation2 A B C D]"
14925 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 14926 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 14927 "\n\t\t: [-maxPlanes]"
14928 "\n\t\t: [-capping {0|1}]"
1b661a81 14929 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 14930 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14931 "\n\t\t: [-texRotate Angle]"
14932 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14933 "\n\t\t: [-useObjShader {0|1}]"
14934 "\n\t\t: Clipping planes management:"
14935 "\n\t\t: -maxPlanes print plane limit for view"
14936 "\n\t\t: -delete delete plane with given name"
14937 "\n\t\t: {off|on|0|1} turn clipping on/off"
14938 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14939 "\n\t\t: applied to active View when list is omitted"
14940 "\n\t\t: -equation A B C D change plane equation"
14941 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14942 "\n\t\t: Capping options:"
14943 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14944 "\n\t\t: -color R G B set capping color"
1b661a81 14945 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 14946 "\n\t\t: -texName Texture set capping texture"
14947 "\n\t\t: -texScale SX SY set capping tex scale"
14948 "\n\t\t: -texOrigin TX TY set capping tex origin"
14949 "\n\t\t: -texRotate Angle set capping tex rotation"
14950 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14951 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14952 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14953 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14954 __FILE__, VClipPlane, group);
392ac980 14955 theCommands.Add("vdefaults",
4c513386 14956 "vdefaults [-absDefl value]"
14957 "\n\t\t: [-devCoeff value]"
14958 "\n\t\t: [-angDefl value]"
14959 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14960 , __FILE__, VDefaults, group);
12381341 14961 theCommands.Add("vlight",
816d03ee 14962 "tool to manage light sources, without arguments shows list of lights."
14963 "\n Main commands: "
992ed6b3 14964 "\n '-clear' to clear lights"
2daa5d95 14965 "\n '-{def}aults' to load default lights"
992ed6b3 14966 "\n '-add' <type> to add any light source"
816d03ee 14967 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
14968 "\n 'change' <lightId> to edit light source with specified lightId"
14969 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 14970 "\n -layer Id"
14971 "\n -{pos}ition X Y Z"
14972 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
14973 "\n -color colorName"
14974 "\n -{head}light 0|1"
d84e8669 14975 "\n -castShadows 0|1"
992ed6b3 14976 "\n -{sm}oothness value"
14977 "\n -{int}ensity value"
14978 "\n -{constAtten}uation value"
14979 "\n -{linearAtten}uation value"
14980 "\n -angle angleDeg"
14981 "\n -{spotexp}onent value"
88b312d3 14982 "\n -range value"
992ed6b3 14983 "\n -local|-global"
2daa5d95 14984 "\n -name value"
14985 "\n -display nameOfLight (display light source with specified nameOfLight or its name)"
14986 "\n -showName {1|0} show/hide the name of light source; 1 by default"
14987 "\n -showRange {1|0} show/hide the range of spot/positional light source; 1 by default"
14988 "\n -prsZoomable {1|0} make light presentation zoomable/non-zoomable"
14989 "\n -prsSize {Value} set light presentation size"
14990 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
992ed6b3 14991 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 14992 __FILE__, VLight, group);
67312b79 14993 theCommands.Add("vpbrenv",
14994 "vpbrenv -clear|-generate"
14995 "\n\t\t: Clears or generates PBR environment map of active view."
14996 "\n\t\t: -clear clears PBR environment (fills by white color)"
14997 "\n\t\t: -generate generates PBR environment from current background cubemap",
14998 __FILE__, VPBREnvironment, group);
6b62b2da 14999 theCommands.Add("vraytrace",
15000 "vraytrace [0|1]"
189f85a3 15001 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 15002 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
15003 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
15004 __FILE__, VRenderParams, group);
bc8c79bb 15005 theCommands.Add("vrenderparams",
4c7a3fae 15006 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
15007 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
15008 "\n\t\t: Common parameters:"
15009 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
d37aef5c 15010 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1]"
15011 "\n\t\t: [-resolution value=72] [-fontHinting {off|normal|light}=off]"
15012 "\n\t\t: [-fontAutoHinting {auto|force|disallow}=auto]"
4c7a3fae 15013 "\n\t\t: [-oit {off|0.0-1.0}=off]"
d84e8669 15014 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
4c7a3fae 15015 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
15016 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
15017 "\n\t\t: [-sync {default|views}] [-reset]"
15018 "\n\t\t: -raster Disables GPU ray-tracing."
15019 "\n\t\t: -shadingModel Controls shading model."
15020 "\n\t\t: -msaa Specifies number of samples for MSAA."
15021 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
15022 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
d37aef5c 15023 "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens."
15024 "\n\t\t: -fontAutoHinting Manages font autohinting."
4c7a3fae 15025 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
15026 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
15027 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
15028 "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result,"
15029 "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)."
d84e8669 15030 "\n\t\t: -shadows Enables/disables shadows rendering."
15031 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
15032 "\n\t\t: -shadowMapBias Shadow map bias."
4c7a3fae 15033 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
15034 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
15035 "\n\t\t: sets state to check structures culled previously."
15036 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
15037 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
15038 "\n\t\t: Diagnostic output (on-screen overlay):"
15039 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
15040 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
15041 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
15042 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
15043 "\n\t\t: -perfUpdateInterval Performance counters update interval."
15044 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
15045 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
15046 "\n\t\t: Ray-Tracing options:"
d84e8669 15047 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
4c7a3fae 15048 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
15049 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
15050 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
15051 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
15052 "\n\t\t: [-maxRad {value>0}=30.0]"
15053 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15054 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15055 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15056 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
4c7a3fae 15057 "\n\t\t: -reflections Enables/disables specular reflections."
15058 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15059 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15060 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15061 "\n\t\t: -env Enables/disables environment map background."
15062 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15063 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15064 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15065 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15066 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15067 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15068 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15069 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15070 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15071 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15072 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15073 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15074 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15075 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15076 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15077 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15078 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15079 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15080 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15081 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15082 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15083 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15084 "\n\t\t: Debug options:"
15085 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15086 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15087 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15088 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 15089 __FILE__, VRenderParams, group);
79b544e6 15090 theCommands.Add("vstatprofiler",
15091 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15092 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 15093 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 15094 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15095 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15096 "\n [-noredraw]"
15097 "\n\t\t: Prints rendering statistics."
15098 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15099 "\n\t\t: else - print all performance counters set previously."
15100 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15101 __FILE__, VStatProfiler, group);
49e1a5c7 15102 theCommands.Add ("vplace",
15103 "vplace dx dy"
15104 "\n\t\t: Places the point (in pixels) at the center of the window",
15105 __FILE__, VPlace, group);
0717ddc1 15106 theCommands.Add("vxrotate",
15107 "vxrotate",
15108 __FILE__,VXRotate,group);
15109
625e1958 15110 theCommands.Add("vmanipulator",
15111 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15112 "\n tool to create and manage AIS manipulators."
15113 "\n Options: "
15114 "\n '-attach AISObject' attach manipulator to AISObject"
ff6122e0 15115 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
625e1958 15116 "\n '-adjustSize {0|1}' adjust size when attaching"
15117 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 15118 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15119 "\n by default it is displayed in all views of the current viewer"
625e1958 15120 "\n '-detach' detach manipulator"
15121 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15122 "\n '-transform mouse_x mouse_y' - invoke transformation"
15123 "\n '-stopTransform [abort]' - invoke stop of transformation"
15124 "\n '-move x y z' - move attached object"
15125 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15126 "\n '-scale factor' - scale attached object"
15127 "\n '-autoActivate {0|1}' - set activation on detection"
15128 "\n '-followTranslation {0|1}' - set following translation transform"
15129 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 15130 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 15131 "\n '-gap value' - set gap between sub-parts"
15132 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 15133 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 15134 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15135 "\n '-size value' - set size of manipulator"
15136 "\n '-zoomable {0|1}' - set zoom persistence",
15137 __FILE__, VManipulator, group);
15138
8e5fb5ea 15139 theCommands.Add("vselprops",
f838dac4 15140 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 15141 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15142 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 15143 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15144 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 15145 "\n -pickStrategy {first|topmost} : defines picking strategy"
15146 "\n 'first' to pick first acceptable (default)"
15147 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 15148 "\n -pixTol value : sets up pixel tolerance"
8c36926a 15149 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15150 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15151 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 15152 "\n -dispMode dispMode : sets display mode for highlighting"
15153 "\n -layer ZLayer : sets ZLayer for highlighting"
15154 "\n -color {name|r g b} : sets highlight color"
15155 "\n -transp value : sets transparency coefficient for highlight"
15156 "\n -material material : sets highlight material"
8e5fb5ea 15157 "\n -print : prints current state of all mentioned parameters",
15158 __FILE__, VSelectionProperties, group);
be3d8cbc 15159 theCommands.Add ("vhighlightselected",
15160 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15161 __FILE__, VSelectionProperties, group);
8e5fb5ea 15162
decdee7d 15163 theCommands.Add ("vseldump",
df23a355 15164 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|surfNormal}=depth -pickedIndex Index=1"
b40cdc2b 15165 "\n\t\t: [-xrPose base|head=base]"
decdee7d 15166 "\n\t\t: Generate an image based on detection results:"
15167 "\n\t\t: depth normalized depth values"
15168 "\n\t\t: unnormDepth unnormalized depth values"
15169 "\n\t\t: object color of detected object"
15170 "\n\t\t: owner color of detected owner"
15171 "\n\t\t: selMode color of selection mode"
114e7a90 15172 "\n\t\t: entity color of etected entity"
15173 "\n\t\t: surfNormal normal direction values",
decdee7d 15174 __FILE__, VDumpSelectionImage, group);
293211ae 15175
2108d9a2 15176 theCommands.Add ("vviewcube",
15177 "vviewcube name"
15178 "\n\t\t: Displays interactive view manipualtion object."
15179 "\n\t\t: Options: "
15180 "\n\t\t: -reset reset geomertical and visual attributes'"
15181 "\n\t\t: -size Size adapted size of View Cube"
15182 "\n\t\t: -boxSize Size box size"
0aeb8984 15183 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
2108d9a2 15184 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15185 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15186 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15187 "\n\t\t: -color Color color of View Cube"
15188 "\n\t\t: -boxColor Color box color"
15189 "\n\t\t: -boxSideColor Color box sides color"
15190 "\n\t\t: -boxEdgeColor Color box edges color"
15191 "\n\t\t: -boxCornerColor Color box corner color"
15192 "\n\t\t: -textColor Color color of side text of view cube"
15193 "\n\t\t: -innerColor Color inner box color"
15194 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15195 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
0aeb8984 15196 "\n\t\t: -xAxisTextColor Color color of X axis label"
15197 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15198 "\n\t\t: -zAxisTextColor Color color of Z axis label"
2108d9a2 15199 "\n\t\t: -font Name font name"
15200 "\n\t\t: -fontHeight Value font height"
15201 "\n\t\t: -boxFacetExtension Value box facet extension"
15202 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15203 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15204 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15205 "\n\t\t: -axesPadding Value padding between box and arrows"
15206 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15207 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15208 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15209 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15210 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15211 "\n\t\t: -duration Seconds animation duration in seconds",
15212 __FILE__, VViewCube, group);
15213
14b741b0 15214 theCommands.Add("vcolorconvert" ,
15215 "vcolorconvert {from|to} type C1 C2 C2"
15216 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15217 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15218 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15219 __FILE__,VColorConvert,group);
15220 theCommands.Add("vcolordiff" ,
15221 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15222 __FILE__,VColorDiff,group);
6a2fb7a1 15223 theCommands.Add("vselbvhbuild",
15224 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15225 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15226 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15227 "\n\t\t: -wait waits for building all of BVH",
15228 __FILE__,VSelBvhBuild,group);
2108d9a2 15229}