0032121: Draw Harness, ViewerTest - implement -reset option for vlight command
[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));
1f3c5058 7227 Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
7228 anAISAxis->SetColor (anAxisColor);
7229 ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
0461e7fd 7230
7231 // Display axis start point
7232 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
7233 anAISStartPnt->SetMarker (Aspect_TOM_O);
7234 anAISStartPnt->SetColor (anAxisColor);
7235 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
7236
7237 Standard_Integer anIndex = 0;
7238 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
7239 {
7240 const gp_Pnt& aPoint = aPntIter.Value();
7241
7242 // Display normals in intersection points
7243 if (toShowNormal)
7244 {
7245 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
7246 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
7247 if (aNormal.SquareModulus() > ShortRealEpsilon())
7248 {
1f3c5058 7249 gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
7250 Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
0461e7fd 7251 anAISNormal->SetColor (Quantity_NOC_BLUE);
0461e7fd 7252 anAISNormal->SetInfiniteState (false);
7253 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
7254 }
7255 }
7256
7257 // Display intersection points
7258 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
7259 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
7260 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
7261 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
7262 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
7263 }
7264
7265 aContext->SetAutoActivateSelection (wasAuto);
7266 }
7267
7268 Standard_Integer anIndex = 0;
7269 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
7270 {
7271 const gp_Pnt& aPnt = anIter.Value();
7272 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
7273 }
7274 return 0;
7275}
7276
1beb58d7 7277namespace
7278{
7279 //! Global map storing all animations registered in ViewerTest.
7280 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7281
7282 //! The animation calling the Draw Harness command.
7283 class ViewerTest_AnimationProc : public AIS_Animation
7284 {
7285 public:
7286
7287 //! Main constructor.
7288 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7289 Draw_Interpretor* theDI,
7290 const TCollection_AsciiString& theCommand)
7291 : AIS_Animation (theAnimationName),
7292 myDrawInter(theDI),
7293 myCommand (theCommand)
7294 {
7295 //
7296 }
7297
7298 protected:
7299
7300 //! Evaluate the command.
7301 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7302 {
7303 TCollection_AsciiString aCmd = myCommand;
7304 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7305 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7306 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7307 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7308 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7309 myDrawInter->Eval (aCmd.ToCString());
7310 }
7311
7312 //! Find the keyword in the command and replace it with value.
7313 //! @return the position of the keyword to pass value
7314 void replace (TCollection_AsciiString& theCmd,
7315 const TCollection_AsciiString& theKey,
7316 const TCollection_AsciiString& theVal)
7317 {
7318 TCollection_AsciiString aCmd (theCmd);
7319 aCmd.LowerCase();
7320 const Standard_Integer aPos = aCmd.Search (theKey);
7321 if (aPos == -1)
7322 {
7323 return;
7324 }
7325
7326 TCollection_AsciiString aPart1, aPart2;
7327 Standard_Integer aPart1To = aPos - 1;
7328 if (aPart1To >= 1
7329 && aPart1To <= theCmd.Length())
7330 {
7331 aPart1 = theCmd.SubString (1, aPart1To);
7332 }
7333
7334 Standard_Integer aPart2From = aPos + theKey.Length();
7335 if (aPart2From >= 1
7336 && aPart2From <= theCmd.Length())
7337 {
7338 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7339 }
7340
7341 theCmd = aPart1 + theVal + aPart2;
7342 }
7343
7344 protected:
7345
7346 Draw_Interpretor* myDrawInter;
7347 TCollection_AsciiString myCommand;
7348
7349 };
7350
7351 //! Replace the animation with the new one.
7352 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7353 Handle(AIS_Animation)& theAnimation,
7354 const Handle(AIS_Animation)& theAnimationNew)
7355 {
7356 theAnimationNew->CopyFrom (theAnimation);
7357 if (!theParentAnimation.IsNull())
7358 {
7359 theParentAnimation->Replace (theAnimation, theAnimationNew);
7360 }
7361 else
7362 {
7363 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7364 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7365 }
7366 theAnimation = theAnimationNew;
7367 }
7368
7369 //! Parse the point.
7370 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7371 {
7372 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
d45edf24 7373 if (!anXYZ[0].IsRealValue (Standard_True)
7374 || !anXYZ[1].IsRealValue (Standard_True)
7375 || !anXYZ[2].IsRealValue (Standard_True))
1beb58d7 7376 {
7377 return Standard_False;
7378 }
7379
7380 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7381 return Standard_True;
7382 }
7383
7384 //! Parse the quaternion.
7385 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7386 {
7387 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
d45edf24 7388 if (!anXYZW[0].IsRealValue (Standard_True)
7389 || !anXYZW[1].IsRealValue (Standard_True)
7390 || !anXYZW[2].IsRealValue (Standard_True)
7391 || !anXYZW[3].IsRealValue (Standard_True))
1beb58d7 7392 {
7393 return Standard_False;
7394 }
7395
7396 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7397 return Standard_True;
7398 }
7399
08f8a185 7400 //! Auxiliary class for flipping image upside-down.
7401 class ImageFlipper
7402 {
7403 public:
7404
7405 //! Empty constructor.
7406 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7407
7408 //! Perform flipping.
7409 Standard_Boolean FlipY (Image_PixMap& theImage)
7410 {
7411 if (theImage.IsEmpty()
7412 || theImage.SizeX() == 0
7413 || theImage.SizeY() == 0)
7414 {
7415 return Standard_False;
7416 }
7417
7418 const Standard_Size aRowSize = theImage.SizeRowBytes();
7419 if (myTmp.Size() < aRowSize
7420 && !myTmp.Allocate (aRowSize))
7421 {
7422 return Standard_False;
7423 }
7424
7425 // for odd height middle row should be left as is
7426 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7427 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7428 {
7429 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7430 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7431 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7432 memcpy (aTop, aBot, aRowSize);
7433 memcpy (aBot, myTmp.Data(), aRowSize);
7434 }
7435 return Standard_True;
7436 }
7437
7438 private:
7439 NCollection_Buffer myTmp;
7440 };
7441
1beb58d7 7442}
7443
197ac94e 7444//=================================================================================================
4754e164 7445//function : VViewParams
dc3fe572 7446//purpose : Gets or sets AIS View characteristics
197ac94e 7447//=================================================================================================
7448static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7449{
1beb58d7 7450 Handle(V3d_View) aView = ViewerTest::CurrentView();
7451 if (aView.IsNull())
4754e164 7452 {
23fe70ec 7453 Message::SendFail ("Error: no active viewer");
4754e164 7454 return 1;
7455 }
197ac94e 7456
1beb58d7 7457 Standard_Boolean toSetProj = Standard_False;
7458 Standard_Boolean toSetUp = Standard_False;
7459 Standard_Boolean toSetAt = Standard_False;
7460 Standard_Boolean toSetEye = Standard_False;
7461 Standard_Boolean toSetScale = Standard_False;
7462 Standard_Boolean toSetSize = Standard_False;
7463 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7464 Standard_Real aViewScale = aView->Scale();
168c27c6 7465 Standard_Real aViewAspect = aView->Camera()->Aspect();
ee2be2a8 7466 Standard_Real aViewSize = 1.0;
1beb58d7 7467 Graphic3d_Vec2i aCenter2d;
7468 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7469 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7470 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7471 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7472 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
168c27c6 7473 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
7474 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
197ac94e 7475 if (theArgsNb == 1)
4754e164 7476 {
197ac94e 7477 // print all of the available view parameters
1beb58d7 7478 char aText[4096];
7479 Sprintf (aText,
168c27c6 7480 "Scale: %g\n"
7481 "Aspect: %g\n"
7482 "Proj: %12g %12g %12g\n"
7483 "Up: %12g %12g %12g\n"
7484 "At: %12g %12g %12g\n"
7485 "Eye: %12g %12g %12g\n"
7486 "OrientMat: %12g %12g %12g %12g\n"
7487 " %12g %12g %12g %12g\n"
7488 " %12g %12g %12g %12g\n"
7489 " %12g %12g %12g %12g\n"
7490 "ProjMat: %12g %12g %12g %12g\n"
7491 " %12g %12g %12g %12g\n"
7492 " %12g %12g %12g %12g\n"
7493 " %12g %12g %12g %12g\n",
7494 aViewScale, aViewAspect,
1beb58d7 7495 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7496 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7497 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
168c27c6 7498 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
7499 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
7500 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
7501 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
7502 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
7503 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
7504 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
7505 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
7506 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
1beb58d7 7507 theDi << aText;
197ac94e 7508 return 0;
4754e164 7509 }
197ac94e 7510
1beb58d7 7511 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7512 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7513 {
1beb58d7 7514 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7515 anArg.LowerCase();
7516 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7517 {
197ac94e 7518 continue;
7519 }
1beb58d7 7520 else if (anArg == "-cmd"
7521 || anArg == "-command"
7522 || anArg == "-args")
7523 {
7524 char aText[4096];
7525 Sprintf (aText,
7526 "-scale %g "
7527 "-proj %g %g %g "
7528 "-up %g %g %g "
7529 "-at %g %g %g\n",
7530 aViewScale,
7531 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7532 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7533 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7534 theDi << aText;
7535 }
7536 else if (anArg == "-scale"
7537 || anArg == "-size")
7538 {
7539 if (anArgIter + 1 < theArgsNb
7540 && *theArgVec[anArgIter + 1] != '-')
7541 {
7542 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
d45edf24 7543 if (aValueArg.IsRealValue (Standard_True))
1beb58d7 7544 {
7545 ++anArgIter;
7546 if (anArg == "-scale")
7547 {
7548 toSetScale = Standard_True;
7549 aViewScale = aValueArg.RealValue();
7550 }
7551 else if (anArg == "-size")
7552 {
7553 toSetSize = Standard_True;
7554 aViewSize = aValueArg.RealValue();
7555 }
7556 continue;
7557 }
7558 }
7559 if (anArg == "-scale")
7560 {
7561 theDi << "Scale: " << aView->Scale() << "\n";
7562 }
7563 else if (anArg == "-size")
7564 {
7565 Graphic3d_Vec2d aSizeXY;
7566 aView->Size (aSizeXY.x(), aSizeXY.y());
7567 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7568 }
7569 }
7570 else if (anArg == "-eye"
7571 || anArg == "-at"
7572 || anArg == "-up"
7573 || anArg == "-proj")
7574 {
7575 if (anArgIter + 3 < theArgsNb)
7576 {
7577 gp_XYZ anXYZ;
7578 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7579 {
7580 anArgIter += 3;
7581 if (anArg == "-eye")
7582 {
7583 toSetEye = Standard_True;
7584 aViewEye = anXYZ;
7585 }
7586 else if (anArg == "-at")
7587 {
7588 toSetAt = Standard_True;
7589 aViewAt = anXYZ;
7590 }
7591 else if (anArg == "-up")
7592 {
7593 toSetUp = Standard_True;
7594 aViewUp = anXYZ;
7595 }
7596 else if (anArg == "-proj")
7597 {
7598 toSetProj = Standard_True;
7599 aViewProj = anXYZ;
7600 }
7601 continue;
7602 }
7603 }
197ac94e 7604
1beb58d7 7605 if (anArg == "-eye")
7606 {
7607 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7608 }
7609 else if (anArg == "-at")
7610 {
7611 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7612 }
7613 else if (anArg == "-up")
7614 {
7615 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7616 }
7617 else if (anArg == "-proj")
7618 {
7619 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7620 }
7621 }
7622 else if (anArg == "-center")
3dfe95cd 7623 {
1beb58d7 7624 if (anArgIter + 2 < theArgsNb)
7625 {
7626 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7627 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7628 if (anX.IsIntegerValue()
7629 && anY.IsIntegerValue())
7630 {
7631 toSetCenter2d = Standard_True;
7632 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7633 }
7634 }
7635 }
7636 else
7637 {
23fe70ec 7638 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 7639 return 1;
7640 }
1beb58d7 7641 }
3dfe95cd 7642
1beb58d7 7643 // change view parameters in proper order
7644 if (toSetScale)
7645 {
7646 aView->SetScale (aViewScale);
7647 }
7648 if (toSetSize)
7649 {
7650 aView->SetSize (aViewSize);
7651 }
7652 if (toSetEye)
7653 {
7654 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7655 }
7656 if (toSetAt)
7657 {
7658 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7659 }
7660 if (toSetProj)
7661 {
7662 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7663 }
7664 if (toSetUp)
7665 {
7666 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7667 }
7668 if (toSetCenter2d)
7669 {
7670 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 7671 }
7672
1beb58d7 7673 return 0;
7674}
197ac94e 7675
2e93433e 7676//==============================================================================
7677//function : V2DMode
7678//purpose :
7679//==============================================================================
7680static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7681{
7682 bool is2dMode = true;
7683 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7684 if (aV3dView.IsNull())
7685 {
23fe70ec 7686 Message::SendFail ("Error: no active viewer");
2e93433e 7687 return 1;
7688 }
7689 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7690 {
7691 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7692 TCollection_AsciiString anArgCase = anArg;
7693 anArgCase.LowerCase();
7694 if (anArgIt + 1 < theArgsNb
7695 && anArgCase == "-name")
7696 {
7697 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7698 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7699 if (!ViewerTest_myViews.IsBound1 (aViewName))
7700 {
23fe70ec 7701 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 7702 return 1;
7703 }
7704 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7705 }
7706 else if (anArgCase == "-mode")
7707 {
7708 if (anArgIt + 1 < theArgsNb
dae2a922 7709 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 7710 {
7711 ++anArgIt;
7712 }
7713 }
dae2a922 7714 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 7715 {
7716 //
7717 }
7718 else
7719 {
23fe70ec 7720 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 7721 return 1;
7722 }
7723 }
7724
7725 aV3dView->SetView2DMode (is2dMode);
7726 return 0;
7727}
7728
1beb58d7 7729//==============================================================================
7730//function : VAnimation
7731//purpose :
7732//==============================================================================
7733static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7734 Standard_Integer theArgNb,
7735 const char** theArgVec)
7736{
7737 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7738 if (theArgNb < 2)
4754e164 7739 {
1beb58d7 7740 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7741 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7742 {
7743 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7744 }
1beb58d7 7745 return 0;
7746 }
7747 if (aCtx.IsNull())
7748 {
23fe70ec 7749 Message::SendFail ("Error: no active viewer");
1beb58d7 7750 return 1;
4754e164 7751 }
197ac94e 7752
1beb58d7 7753 Standard_Integer anArgIter = 1;
7754 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7755 if (aNameArg.IsEmpty())
7756 {
23fe70ec 7757 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7758 return 1;
7759 }
7760
7761 TCollection_AsciiString aNameArgLower = aNameArg;
7762 aNameArgLower.LowerCase();
7763 if (aNameArgLower == "-reset"
7764 || aNameArgLower == "-clear")
7765 {
7766 ViewerTest_AnimationTimelineMap.Clear();
7767 return 0;
7768 }
7769 else if (aNameArg.Value (1) == '-')
7770 {
23fe70ec 7771 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 7772 return 1;
7773 }
197ac94e 7774
1beb58d7 7775 const char* aNameSplitter = "/";
7776 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7777 if (aSplitPos == -1)
197ac94e 7778 {
1beb58d7 7779 aNameSplitter = ".";
7780 aSplitPos = aNameArg.Search (aNameSplitter);
7781 }
7782
7783 // find existing or create a new animation by specified name within syntax "parent.child".
7784 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7785 for (; !aNameArg.IsEmpty();)
7786 {
7787 TCollection_AsciiString aNameParent;
7788 if (aSplitPos != -1)
197ac94e 7789 {
1beb58d7 7790 if (aSplitPos == aNameArg.Length())
7791 {
23fe70ec 7792 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7793 return 1;
7794 }
7795
7796 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7797 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7798
7799 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 7800 }
7801 else
7802 {
1beb58d7 7803 aNameParent = aNameArg;
7804 aNameArg.Clear();
197ac94e 7805 }
1beb58d7 7806
7807 if (anAnimation.IsNull())
3dfe95cd 7808 {
1beb58d7 7809 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7810 {
7811 anAnimation = new AIS_Animation (aNameParent);
7812 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7813 }
7814 aRootAnimation = anAnimation;
3dfe95cd 7815 }
7816 else
7817 {
1beb58d7 7818 aParentAnimation = anAnimation;
7819 anAnimation = aParentAnimation->Find (aNameParent);
7820 if (anAnimation.IsNull())
7821 {
7822 anAnimation = new AIS_Animation (aNameParent);
7823 aParentAnimation->Add (anAnimation);
7824 }
3dfe95cd 7825 }
7826 }
1beb58d7 7827
7828 if (anArgIter >= theArgNb)
197ac94e 7829 {
1beb58d7 7830 // just print the list of children
7831 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 7832 {
1beb58d7 7833 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7834 }
1beb58d7 7835 return 0;
197ac94e 7836 }
1beb58d7 7837
bf7b2ceb 7838 // animation parameters
1beb58d7 7839 Standard_Boolean toPlay = Standard_False;
7840 Standard_Real aPlaySpeed = 1.0;
7841 Standard_Real aPlayStartTime = anAnimation->StartPts();
7842 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 7843 Standard_Boolean isFreeCamera = Standard_False;
7844 Standard_Boolean isLockLoop = Standard_False;
08f8a185 7845
7846 // video recording parameters
7847 TCollection_AsciiString aRecFile;
7848 Image_VideoParams aRecParams;
7849
1beb58d7 7850 Handle(V3d_View) aView = ViewerTest::CurrentView();
7851 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 7852 {
1beb58d7 7853 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7854 anArg.LowerCase();
bf7b2ceb 7855 // general options
1beb58d7 7856 if (anArg == "-reset"
7857 || anArg == "-clear")
197ac94e 7858 {
1beb58d7 7859 anAnimation->Clear();
7860 }
7861 else if (anArg == "-remove"
7862 || anArg == "-del"
7863 || anArg == "-delete")
7864 {
7865 if (!aParentAnimation.IsNull())
7866 {
7867 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7868 }
7869 else
7870 {
7871 aParentAnimation->Remove (anAnimation);
7872 }
7873 }
bf7b2ceb 7874 // playback options
1beb58d7 7875 else if (anArg == "-play")
7876 {
7877 toPlay = Standard_True;
7878 if (++anArgIter < theArgNb)
7879 {
7880 if (*theArgVec[anArgIter] == '-')
7881 {
7882 --anArgIter;
7883 continue;
7884 }
7885 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7886
7887 if (++anArgIter < theArgNb)
7888 {
7889 if (*theArgVec[anArgIter] == '-')
7890 {
7891 --anArgIter;
7892 continue;
7893 }
7894 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7895 }
7896 }
7897 }
7898 else if (anArg == "-resume")
7899 {
7900 toPlay = Standard_True;
7901 aPlayStartTime = anAnimation->ElapsedTime();
7902 if (++anArgIter < theArgNb)
7903 {
7904 if (*theArgVec[anArgIter] == '-')
7905 {
7906 --anArgIter;
7907 continue;
7908 }
7909
7910 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7911 }
7912 }
7913 else if (anArg == "-playspeed"
7914 || anArg == "-speed")
7915 {
7916 if (++anArgIter >= theArgNb)
7917 {
23fe70ec 7918 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 7919 return 1;
7920 }
7921 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7922 }
7923 else if (anArg == "-lock"
7924 || anArg == "-lockloop"
7925 || anArg == "-playlockloop")
7926 {
7927 isLockLoop = Standard_True;
7928 }
7929 else if (anArg == "-freecamera"
7930 || anArg == "-playfreecamera"
7931 || anArg == "-freelook")
7932 {
7933 isFreeCamera = Standard_True;
7934 }
08f8a185 7935 // video recodring options
7936 else if (anArg == "-rec"
7937 || anArg == "-record")
7938 {
7939 if (++anArgIter >= theArgNb)
7940 {
23fe70ec 7941 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 7942 return 1;
7943 }
7944
7945 aRecFile = theArgVec[anArgIter];
7946 if (aRecParams.FpsNum <= 0)
7947 {
7948 aRecParams.FpsNum = 24;
7949 }
7950
7951 if (anArgIter + 2 < theArgNb
7952 && *theArgVec[anArgIter + 1] != '-'
7953 && *theArgVec[anArgIter + 2] != '-')
7954 {
7955 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7956 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7957 if (aWidthArg .IsIntegerValue()
7958 && aHeightArg.IsIntegerValue())
7959 {
7960 aRecParams.Width = aWidthArg .IntegerValue();
7961 aRecParams.Height = aHeightArg.IntegerValue();
7962 anArgIter += 2;
7963 }
7964 }
7965 }
1beb58d7 7966 else if (anArg == "-fps")
7967 {
7968 if (++anArgIter >= theArgNb)
7969 {
23fe70ec 7970 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 7971 return 1;
7972 }
bf7b2ceb 7973
7974 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7975 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7976 if (aSplitIndex == 0)
7977 {
08f8a185 7978 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 7979 }
7980 else
7981 {
7982 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7983 aFpsArg.Split (aFpsArg.Length() - 1);
7984 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 7985 aRecParams.FpsNum = aNumStr.IntegerValue();
7986 aRecParams.FpsDen = aDenStr.IntegerValue();
7987 if (aRecParams.FpsDen < 1)
bf7b2ceb 7988 {
23fe70ec 7989 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 7990 return 1;
7991 }
7992 }
1beb58d7 7993 }
08f8a185 7994 else if (anArg == "-format")
7995 {
7996 if (++anArgIter >= theArgNb)
7997 {
23fe70ec 7998 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 7999 return 1;
8000 }
8001 aRecParams.Format = theArgVec[anArgIter];
8002 }
8003 else if (anArg == "-pix_fmt"
8004 || anArg == "-pixfmt"
8005 || anArg == "-pixelformat")
8006 {
8007 if (++anArgIter >= theArgNb)
8008 {
23fe70ec 8009 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8010 return 1;
8011 }
8012 aRecParams.PixelFormat = theArgVec[anArgIter];
8013 }
8014 else if (anArg == "-codec"
8015 || anArg == "-vcodec"
8016 || anArg == "-videocodec")
8017 {
8018 if (++anArgIter >= theArgNb)
8019 {
23fe70ec 8020 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8021 return 1;
8022 }
8023 aRecParams.VideoCodec = theArgVec[anArgIter];
8024 }
8025 else if (anArg == "-crf"
8026 || anArg == "-preset"
8027 || anArg == "-qp")
8028 {
8029 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8030 if (++anArgIter >= theArgNb)
8031 {
23fe70ec 8032 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8033 return 1;
8034 }
8035
8036 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8037 }
bf7b2ceb 8038 // animation definition options
1beb58d7 8039 else if (anArg == "-start"
8040 || anArg == "-starttime"
8041 || anArg == "-startpts")
8042 {
8043 if (++anArgIter >= theArgNb)
8044 {
23fe70ec 8045 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8046 return 1;
8047 }
8048
8049 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8050 aRootAnimation->UpdateTotalDuration();
8051 }
8052 else if (anArg == "-end"
8053 || anArg == "-endtime"
8054 || anArg == "-endpts")
8055 {
8056 if (++anArgIter >= theArgNb)
8057 {
23fe70ec 8058 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8059 return 1;
8060 }
8061
8062 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8063 aRootAnimation->UpdateTotalDuration();
8064 }
8065 else if (anArg == "-dur"
8066 || anArg == "-duration")
8067 {
8068 if (++anArgIter >= theArgNb)
8069 {
23fe70ec 8070 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8071 return 1;
8072 }
8073
8074 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8075 aRootAnimation->UpdateTotalDuration();
8076 }
8077 else if (anArg == "-command"
8078 || anArg == "-cmd"
8079 || anArg == "-invoke"
8080 || anArg == "-eval"
8081 || anArg == "-proc")
8082 {
8083 if (++anArgIter >= theArgNb)
8084 {
23fe70ec 8085 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8086 return 1;
8087 }
8088
8089 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8090 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8091 }
8092 else if (anArg == "-objecttrsf"
8093 || anArg == "-objectransformation"
8094 || anArg == "-objtransformation"
8095 || anArg == "-objtrsf"
8096 || anArg == "-object"
8097 || anArg == "-obj")
8098 {
8099 if (++anArgIter >= theArgNb)
8100 {
23fe70ec 8101 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8102 return 1;
8103 }
8104
8105 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8106 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8107 Handle(AIS_InteractiveObject) anObject;
8108 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8109 {
23fe70ec 8110 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8111 return 1;
8112 }
8113
1beb58d7 8114 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8115 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8116 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8117 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8118 Standard_Boolean isTrsfSet = Standard_False;
8119 Standard_Integer aTrsfArgIter = anArgIter + 1;
8120 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8121 {
8122 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8123 aTrsfArg.LowerCase();
8124 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8125 if (aTrsfArg.StartsWith ("-rotation")
8126 || aTrsfArg.StartsWith ("-rot"))
8127 {
8128 isTrsfSet = Standard_True;
8129 if (aTrsfArgIter + 4 >= theArgNb
8130 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8131 {
23fe70ec 8132 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8133 return 1;
8134 }
8135 aTrsfArgIter += 4;
8136 }
8137 else if (aTrsfArg.StartsWith ("-location")
8138 || aTrsfArg.StartsWith ("-loc"))
8139 {
8140 isTrsfSet = Standard_True;
8141 if (aTrsfArgIter + 3 >= theArgNb
8142 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8143 {
23fe70ec 8144 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8145 return 1;
8146 }
8147 aTrsfArgIter += 3;
8148 }
8149 else if (aTrsfArg.StartsWith ("-scale"))
8150 {
8151 isTrsfSet = Standard_True;
8152 if (++aTrsfArgIter >= theArgNb)
8153 {
23fe70ec 8154 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8155 return 1;
8156 }
8157
8158 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
d45edf24 8159 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8160 {
23fe70ec 8161 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8162 return 1;
8163 }
8164 aScales[anIndex] = aScaleStr.RealValue();
8165 }
8166 else
8167 {
8168 anArgIter = aTrsfArgIter - 1;
8169 break;
8170 }
8171 }
8172 if (!isTrsfSet)
8173 {
23fe70ec 8174 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8175 return 1;
8176 }
8177 else if (aTrsfArgIter >= theArgNb)
8178 {
8179 anArgIter = theArgNb;
8180 }
8181
8182 aTrsfs[0].SetRotation (aRotQuats[0]);
8183 aTrsfs[1].SetRotation (aRotQuats[1]);
8184 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8185 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8186 aTrsfs[0].SetScaleFactor (aScales[0]);
8187 aTrsfs[1].SetScaleFactor (aScales[1]);
8188
8189 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8190 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8191 }
8192 else if (anArg == "-viewtrsf"
8193 || anArg == "-view")
8194 {
8195 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8196 if (aCamAnimation.IsNull())
8197 {
8198 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8199 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8200 }
8201
8202 Handle(Graphic3d_Camera) aCams[2] =
8203 {
8204 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8205 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8206 };
8207
8208 Standard_Boolean isTrsfSet = Standard_False;
8209 Standard_Integer aViewArgIter = anArgIter + 1;
8210 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8211 {
8212 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8213 aViewArg.LowerCase();
8214 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8215 if (aViewArg.StartsWith ("-scale"))
8216 {
8217 isTrsfSet = Standard_True;
8218 if (++aViewArgIter >= theArgNb)
8219 {
23fe70ec 8220 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8221 return 1;
8222 }
8223
8224 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
d45edf24 8225 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8226 {
23fe70ec 8227 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8228 return 1;
8229 }
8230 Standard_Real aScale = aScaleStr.RealValue();
8231 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8232 aCams[anIndex]->SetScale (aScale);
8233 }
8234 else if (aViewArg.StartsWith ("-eye")
8235 || aViewArg.StartsWith ("-center")
8236 || aViewArg.StartsWith ("-at")
8237 || aViewArg.StartsWith ("-up"))
8238 {
8239 isTrsfSet = Standard_True;
8240 gp_XYZ anXYZ;
8241 if (aViewArgIter + 3 >= theArgNb
8242 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8243 {
23fe70ec 8244 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8245 return 1;
8246 }
8247 aViewArgIter += 3;
8248
8249 if (aViewArg.StartsWith ("-eye"))
8250 {
8251 aCams[anIndex]->SetEye (anXYZ);
8252 }
8253 else if (aViewArg.StartsWith ("-center")
8254 || aViewArg.StartsWith ("-at"))
8255 {
8256 aCams[anIndex]->SetCenter (anXYZ);
8257 }
8258 else if (aViewArg.StartsWith ("-up"))
8259 {
8260 aCams[anIndex]->SetUp (anXYZ);
8261 }
8262 }
8263 else
8264 {
8265 anArgIter = aViewArgIter - 1;
8266 break;
8267 }
8268 }
8269 if (!isTrsfSet)
8270 {
23fe70ec 8271 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8272 return 1;
8273 }
8274 else if (aViewArgIter >= theArgNb)
8275 {
8276 anArgIter = theArgNb;
8277 }
8278
8279 aCamAnimation->SetCameraStart(aCams[0]);
8280 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8281 }
8282 else
8283 {
23fe70ec 8284 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8285 return 1;
197ac94e 8286 }
8287 }
1beb58d7 8288
08f8a185 8289 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8290 {
1beb58d7 8291 return 0;
8292 }
8293
8294 // Start animation timeline and process frame updating.
8295 TheIsAnimating = Standard_True;
8296 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8297 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8298 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8299 if (isFreeCamera)
8300 {
8301 aView->Camera()->Copy (aCameraBack);
8302 }
8303
8304 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8305 if (aRecParams.FpsNum <= 0)
1beb58d7 8306 {
8307 while (!anAnimation->IsStopped())
197ac94e 8308 {
1beb58d7 8309 aCameraBack->Copy (aView->Camera());
8310 const Standard_Real aPts = anAnimation->UpdateTimer();
8311 if (isFreeCamera)
8312 {
8313 aView->Camera()->Copy (aCameraBack);
8314 }
8315
8316 if (aPts >= anUpperPts)
8317 {
8318 anAnimation->Pause();
8319 break;
8320 }
8321
8322 if (aView->IsInvalidated())
8323 {
8324 aView->Redraw();
8325 }
8326 else
8327 {
8328 aView->RedrawImmediate();
8329 }
8330
8331 if (!isLockLoop)
8332 {
8333 // handle user events
8334 theDI.Eval ("after 1 set waiter 1");
8335 theDI.Eval ("vwait waiter");
8336 }
8337 if (!TheIsAnimating)
8338 {
8339 anAnimation->Pause();
8340 theDI << aPts;
8341 break;
8342 }
8343 }
8344
8345 if (aView->IsInvalidated())
8346 {
8347 aView->Redraw();
197ac94e 8348 }
8349 else
8350 {
1beb58d7 8351 aView->RedrawImmediate();
197ac94e 8352 }
8353 }
1beb58d7 8354 else
197ac94e 8355 {
bf7b2ceb 8356 OSD_Timer aPerfTimer;
8357 aPerfTimer.Start();
1beb58d7 8358
08f8a185 8359 Handle(Image_VideoRecorder) aRecorder;
8360 ImageFlipper aFlipper;
8361 Handle(Draw_ProgressIndicator) aProgress;
8362 if (!aRecFile.IsEmpty())
8363 {
8364 if (aRecParams.Width <= 0
8365 || aRecParams.Height <= 0)
8366 {
8367 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8368 }
8369
8370 aRecorder = new Image_VideoRecorder();
8371 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8372 {
23fe70ec 8373 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8374 return 0;
8375 }
8376
8377 aProgress = new Draw_ProgressIndicator (theDI, 1);
8378 }
8379
1beb58d7 8380 // Manage frame-rated animation here
8381 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8382 int64_t aNbFrames = 0;
7e785937 8383 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8384 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8385 Standard_Integer aSecondsProgress = 0;
7e785937 8386 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8387 {
08f8a185 8388 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8389 aPts = aPlayStartTime + aRecPts;
8390 ++aNbFrames;
1beb58d7 8391 if (!anAnimation->Update (aPts))
8392 {
8393 break;
8394 }
8395
08f8a185 8396 if (!aRecorder.IsNull())
8397 {
8398 V3d_ImageDumpOptions aDumpParams;
8399 aDumpParams.Width = aRecParams.Width;
8400 aDumpParams.Height = aRecParams.Height;
8401 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8402 aDumpParams.StereoOptions = V3d_SDO_MONO;
8403 aDumpParams.ToAdjustAspect = Standard_True;
8404 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8405 {
23fe70ec 8406 Message::SendFail ("Error: view dump is failed");
08f8a185 8407 return 0;
8408 }
8409 aFlipper.FlipY (aRecorder->ChangeFrame());
8410 if (!aRecorder->PushFrame())
8411 {
8412 return 0;
8413 }
8414 }
8415 else
8416 {
8417 aView->Redraw();
8418 }
8419
8420 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8421 {
7e785937 8422 aPS.Next();
08f8a185 8423 ++aSecondsProgress;
8424 }
197ac94e 8425 }
bf7b2ceb 8426
8427 aPerfTimer.Stop();
1beb58d7 8428 anAnimation->Stop();
bf7b2ceb 8429 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8430 theDI << "Average FPS: " << aRecFps << "\n"
8431 << "Nb. Frames: " << Standard_Real(aNbFrames);
8432
8433 aView->Redraw();
197ac94e 8434 }
8435
1beb58d7 8436 aView->SetImmediateUpdate (wasImmediateUpdate);
8437 TheIsAnimating = Standard_False;
4754e164 8438 return 0;
8439}
8440
1beb58d7 8441
4754e164 8442//=======================================================================
8443//function : VChangeSelected
dc3fe572 8444//purpose : Adds the shape to selection or remove one from it
4754e164 8445//=======================================================================
8446static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8447 Standard_Integer argc,
8448 const char ** argv)
8449{
8450 if(argc != 2)
8451 {
8452 di<<"Usage : " << argv[0] << " shape \n";
8453 return 1;
8454 }
8455 //get AIS_Shape:
4754e164 8456 TCollection_AsciiString aName(argv[1]);
8457 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8458 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8459 || anAISObject.IsNull())
4754e164 8460 {
8461 di<<"Use 'vdisplay' before";
8462 return 1;
8463 }
4754e164 8464
8f521168 8465 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8466 return 0;
8467}
8468
4754e164 8469//=======================================================================
8470//function : VNbSelected
dc3fe572 8471//purpose : Returns number of selected objects
4754e164 8472//=======================================================================
8473static Standard_Integer VNbSelected (Draw_Interpretor& di,
8474 Standard_Integer argc,
8475 const char ** argv)
8476{
8477 if(argc != 1)
8478 {
8479 di << "Usage : " << argv[0] << "\n";
8480 return 1;
8481 }
8482 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8483 if(aContext.IsNull())
8484 {
8485 di << "use 'vinit' command before " << argv[0] << "\n";
8486 return 1;
8487 }
8488 di << aContext->NbSelected() << "\n";
8489 return 0;
8490}
8491
4754e164 8492//=======================================================================
8493//function : VSetViewSize
8494//purpose :
8495//=======================================================================
8496static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8497 Standard_Integer argc,
8498 const char ** argv)
8499{
8500 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8501 if(aContext.IsNull())
8502 {
8503 di << "use 'vinit' command before " << argv[0] << "\n";
8504 return 1;
8505 }
8506 if(argc != 2)
8507 {
8508 di<<"Usage : " << argv[0] << " Size\n";
8509 return 1;
8510 }
6b62b2da 8511 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8512 if (aSize <= 0.)
8513 {
8514 di<<"Bad Size value : " << aSize << "\n";
8515 return 1;
8516 }
8517
8518 Handle(V3d_View) aView = ViewerTest::CurrentView();
8519 aView->SetSize(aSize);
8520 return 0;
8521}
8522
8523//=======================================================================
8524//function : VMoveView
8525//purpose :
8526//=======================================================================
8527static Standard_Integer VMoveView (Draw_Interpretor& di,
8528 Standard_Integer argc,
8529 const char ** argv)
8530{
8531 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8532 if(aContext.IsNull())
8533 {
8534 di << "use 'vinit' command before " << argv[0] << "\n";
8535 return 1;
8536 }
8537 if(argc < 4 || argc > 5)
8538 {
8539 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8540 return 1;
8541 }
6b62b2da 8542 Standard_Real Dx = Draw::Atof (argv[1]);
8543 Standard_Real Dy = Draw::Atof (argv[2]);
8544 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8545 Standard_Boolean aStart = Standard_True;
8546 if (argc == 5)
8547 {
6b62b2da 8548 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8549 }
8550
8551 Handle(V3d_View) aView = ViewerTest::CurrentView();
8552 aView->Move(Dx,Dy,Dz,aStart);
8553 return 0;
8554}
8555
8556//=======================================================================
8557//function : VTranslateView
8558//purpose :
8559//=======================================================================
8560static Standard_Integer VTranslateView (Draw_Interpretor& di,
8561 Standard_Integer argc,
8562 const char ** argv)
8563{
8564 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8565 if(aContext.IsNull())
8566 {
8567 di << "use 'vinit' command before " << argv[0] << "\n";
8568 return 1;
8569 }
8570 if(argc < 4 || argc > 5)
8571 {
8572 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8573 return 1;
8574 }
6b62b2da 8575 Standard_Real Dx = Draw::Atof (argv[1]);
8576 Standard_Real Dy = Draw::Atof (argv[2]);
8577 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8578 Standard_Boolean aStart = Standard_True;
dc3fe572 8579 if (argc == 5)
4754e164 8580 {
6b62b2da 8581 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8582 }
8583
8584 Handle(V3d_View) aView = ViewerTest::CurrentView();
8585 aView->Translate(Dx,Dy,Dz,aStart);
8586 return 0;
8587}
8588
8589//=======================================================================
8590//function : VTurnView
8591//purpose :
8592//=======================================================================
8593static Standard_Integer VTurnView (Draw_Interpretor& di,
8594 Standard_Integer argc,
8595 const char ** argv)
8596{
8597 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8598 if(aContext.IsNull()) {
8599 di << "use 'vinit' command before " << argv[0] << "\n";
8600 return 1;
8601 }
8602 if(argc < 4 || argc > 5){
8603 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8604 return 1;
8605 }
6b62b2da 8606 Standard_Real Ax = Draw::Atof (argv[1]);
8607 Standard_Real Ay = Draw::Atof (argv[2]);
8608 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 8609 Standard_Boolean aStart = Standard_True;
dc3fe572 8610 if (argc == 5)
4754e164 8611 {
6b62b2da 8612 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8613 }
8614
8615 Handle(V3d_View) aView = ViewerTest::CurrentView();
8616 aView->Turn(Ax,Ay,Az,aStart);
8617 return 0;
8618}
8619
269294d6 8620//==============================================================================
8621//function : VTextureEnv
8622//purpose : ENables or disables environment mapping
8623//==============================================================================
8624class OCC_TextureEnv : public Graphic3d_TextureEnv
8625{
8626public:
8627 OCC_TextureEnv(const Standard_CString FileName);
8628 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8629 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8630 const Standard_Boolean theModulateFlag,
8631 const Graphic3d_TypeOfTextureFilter theFilter,
8632 const Standard_ShortReal theXScale,
8633 const Standard_ShortReal theYScale,
8634 const Standard_ShortReal theXShift,
8635 const Standard_ShortReal theYShift,
8636 const Standard_ShortReal theAngle);
68858c7d 8637 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 8638};
a3f6f591 8639DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 8640
269294d6 8641OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8642 : Graphic3d_TextureEnv(theFileName)
8643{
8644}
8645
8646OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8647 : Graphic3d_TextureEnv(theTexId)
8648{
8649}
8650
8651void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8652 const Standard_Boolean theModulateFlag,
8653 const Graphic3d_TypeOfTextureFilter theFilter,
8654 const Standard_ShortReal theXScale,
8655 const Standard_ShortReal theYScale,
8656 const Standard_ShortReal theXShift,
8657 const Standard_ShortReal theYShift,
8658 const Standard_ShortReal theAngle)
8659{
8660 myParams->SetRepeat (theRepeatFlag);
8661 myParams->SetModulate (theModulateFlag);
8662 myParams->SetFilter (theFilter);
8663 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8664 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8665 myParams->SetRotation (theAngle);
8666}
8667
35e08fe8 8668static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 8669{
8670 // get the active view
8671 Handle(V3d_View) aView = ViewerTest::CurrentView();
8672 if (aView.IsNull())
8673 {
23fe70ec 8674 Message::SendFail ("Error: no active viewer");
269294d6 8675 return 1;
8676 }
8677
8678 // Checking the input arguments
8679 Standard_Boolean anEnableFlag = Standard_False;
8680 Standard_Boolean isOk = theArgNb >= 2;
8681 if (isOk)
8682 {
8683 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8684 anEnableFlag = anEnableOpt.IsEqual("on");
8685 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8686 }
8687 if (anEnableFlag)
8688 {
8689 isOk = (theArgNb == 3 || theArgNb == 11);
8690 if (isOk)
8691 {
8692 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8693 isOk = (!aTextureOpt.IsIntegerValue() ||
8694 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8695
8696 if (isOk && theArgNb == 11)
8697 {
8698 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8699 aModulateOpt(theArgVec[4]),
8700 aFilterOpt (theArgVec[5]),
8701 aSScaleOpt (theArgVec[6]),
8702 aTScaleOpt (theArgVec[7]),
8703 aSTransOpt (theArgVec[8]),
8704 aTTransOpt (theArgVec[9]),
8705 anAngleOpt (theArgVec[10]);
8706 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8707 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8708 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
d45edf24 8709 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8710 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8711 anAngleOpt.IsRealValue (Standard_True));
269294d6 8712 }
8713 }
8714 }
8715
8716 if (!isOk)
8717 {
23fe70ec 8718 Message::SendFail() << "Usage:\n"
8719 << theArgVec[0] << " off\n"
8720 << 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 8721 return 1;
8722 }
8723
8724 if (anEnableFlag)
8725 {
8726 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8727 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8728 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8729 new OCC_TextureEnv(theArgVec[2]);
8730
8731 if (theArgNb == 11)
8732 {
8733 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8734 aTexEnv->SetTextureParameters(
8735 aRepeatOpt. IsEqual("repeat"),
8736 aModulateOpt.IsEqual("modulate"),
8737 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8738 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8739 Graphic3d_TOTF_TRILINEAR,
8740 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8741 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8742 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8743 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8744 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8745 );
8746 }
8747 aView->SetTextureEnv(aTexEnv);
269294d6 8748 }
8749 else // Disabling environment mapping
8750 {
269294d6 8751 Handle(Graphic3d_TextureEnv) aTexture;
8752 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8753 }
8754
8755 aView->Redraw();
8756 return 0;
8757}
8758
3e05329c 8759namespace
8760{
8761 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8762
8763 //! Remove registered clipping plane from all views and objects.
8764 static void removePlane (MapOfPlanes& theRegPlanes,
8765 const TCollection_AsciiString& theName)
8766 {
8767 Handle(Graphic3d_ClipPlane) aClipPlane;
8768 if (!theRegPlanes.Find (theName, aClipPlane))
8769 {
23fe70ec 8770 Message::SendWarning ("Warning: no such plane");
3e05329c 8771 return;
8772 }
8773
8774 theRegPlanes.UnBind (theName);
8775 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8776 anIObjIt.More(); anIObjIt.Next())
8777 {
8f521168 8778 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 8779 aPrs->RemoveClipPlane (aClipPlane);
8780 }
8781
8782 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8783 aViewIt.More(); aViewIt.Next())
8784 {
8785 const Handle(V3d_View)& aView = aViewIt.Key2();
8786 aView->RemoveClipPlane(aClipPlane);
8787 }
8788
8789 ViewerTest::RedrawAllViews();
8790 }
8791}
8792
4269bd1b 8793//===============================================================================================
8794//function : VClipPlane
8795//purpose :
8796//===============================================================================================
8797static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8798{
8799 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 8800 static MapOfPlanes aRegPlanes;
8801
8802 if (theArgsNb < 2)
8803 {
3e05329c 8804 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8805 {
8806 theDi << aPlaneIter.Key() << " ";
8807 }
8808 return 0;
4269bd1b 8809 }
8810
8811 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 8812 aCommand.LowerCase();
8813 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8814 if (anActiveView.IsNull())
8815 {
23fe70ec 8816 Message::SendFail ("Error: no active viewer");
3e05329c 8817 return 1;
8818 }
4269bd1b 8819
8820 // print maximum number of planes for current viewer
3e05329c 8821 if (aCommand == "-maxplanes"
8822 || aCommand == "maxplanes")
4269bd1b 8823 {
3e05329c 8824 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8825 << " plane slots provided by driver.\n";
4269bd1b 8826 return 0;
8827 }
8828
8829 // create / delete plane instance
3e05329c 8830 if (aCommand == "-create"
8831 || aCommand == "create"
8832 || aCommand == "-delete"
8833 || aCommand == "delete"
8834 || aCommand == "-clone"
8835 || aCommand == "clone")
4269bd1b 8836 {
8837 if (theArgsNb < 3)
8838 {
23fe70ec 8839 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 8840 return 1;
8841 }
8842
3e05329c 8843 Standard_Boolean toCreate = aCommand == "-create"
8844 || aCommand == "create";
8845 Standard_Boolean toClone = aCommand == "-clone"
8846 || aCommand == "clone";
8847 Standard_Boolean toDelete = aCommand == "-delete"
8848 || aCommand == "delete";
4269bd1b 8849 TCollection_AsciiString aPlane (theArgVec[2]);
8850
8851 if (toCreate)
8852 {
8853 if (aRegPlanes.IsBound (aPlane))
8854 {
3e05329c 8855 std::cout << "Warning: existing plane has been overridden.\n";
8856 toDelete = true;
8857 }
8858 else
8859 {
8860 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8861 return 0;
4269bd1b 8862 }
4269bd1b 8863 }
8864 else if (toClone) // toClone
8865 {
8866 if (!aRegPlanes.IsBound (aPlane))
8867 {
23fe70ec 8868 Message::SendFail ("Error: no such plane");
4269bd1b 8869 return 1;
8870 }
3e05329c 8871 else if (theArgsNb < 4)
4269bd1b 8872 {
23fe70ec 8873 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 8874 return 1;
8875 }
8876
8877 TCollection_AsciiString aClone (theArgVec[3]);
8878 if (aRegPlanes.IsBound (aClone))
8879 {
23fe70ec 8880 Message::SendFail ("Error: plane name is in use");
4269bd1b 8881 return 1;
8882 }
8883
8884 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8885
8886 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 8887 return 0;
4269bd1b 8888 }
4269bd1b 8889
3e05329c 8890 if (toDelete)
8891 {
8892 if (aPlane == "ALL"
8893 || aPlane == "all"
8894 || aPlane == "*")
4269bd1b 8895 {
3e05329c 8896 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8897 {
8898 aPlane = aPlaneIter.Key();
8899 removePlane (aRegPlanes, aPlane);
8900 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8901 }
4269bd1b 8902 }
3e05329c 8903 else
4269bd1b 8904 {
3e05329c 8905 removePlane (aRegPlanes, aPlane);
4269bd1b 8906 }
4269bd1b 8907 }
8908
3e05329c 8909 if (toCreate)
8910 {
8911 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8912 }
4269bd1b 8913 return 0;
8914 }
8915
8916 // set / unset plane command
3e05329c 8917 if (aCommand == "set"
8918 || aCommand == "unset")
4269bd1b 8919 {
3e05329c 8920 if (theArgsNb < 5)
4269bd1b 8921 {
23fe70ec 8922 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8923 return 1;
8924 }
8925
3e05329c 8926 // redirect to new syntax
8927 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8928 anArgVec.SetValue (1, theArgVec[0]);
8929 anArgVec.SetValue (2, theArgVec[2]);
8930 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8931 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 8932 {
3e05329c 8933 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 8934 }
8935
3e05329c 8936 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 8937 }
8938
8939 // change plane command
3e05329c 8940 TCollection_AsciiString aPlaneName;
8941 Handle(Graphic3d_ClipPlane) aClipPlane;
8942 Standard_Integer anArgIter = 0;
8943 if (aCommand == "-change"
8944 || aCommand == "change")
4269bd1b 8945 {
3e05329c 8946 // old syntax support
8947 if (theArgsNb < 3)
4269bd1b 8948 {
23fe70ec 8949 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8950 return 1;
8951 }
8952
3e05329c 8953 anArgIter = 3;
8954 aPlaneName = theArgVec[2];
8955 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 8956 {
23fe70ec 8957 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 8958 return 1;
8959 }
3e05329c 8960 }
8961 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8962 {
8963 anArgIter = 2;
8964 aPlaneName = theArgVec[1];
8965 }
8966 else
8967 {
8968 anArgIter = 2;
8969 aPlaneName = theArgVec[1];
8970 aClipPlane = new Graphic3d_ClipPlane();
8971 aRegPlanes.Bind (aPlaneName, aClipPlane);
8972 theDi << "Created new plane " << aPlaneName << ".\n";
8973 }
4269bd1b 8974
3e05329c 8975 if (theArgsNb - anArgIter < 1)
8976 {
23fe70ec 8977 Message::SendFail ("Syntax error: need more arguments");
3e05329c 8978 return 1;
8979 }
4269bd1b 8980
3e05329c 8981 for (; anArgIter < theArgsNb; ++anArgIter)
8982 {
8983 const char** aChangeArgs = theArgVec + anArgIter;
8984 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8985 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
8986 aChangeArg.LowerCase();
4269bd1b 8987
3e05329c 8988 Standard_Boolean toEnable = Standard_True;
dae2a922 8989 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 8990 {
3e05329c 8991 aClipPlane->SetOn (toEnable);
4269bd1b 8992 }
25c35042 8993 else if (aChangeArg.StartsWith ("-equation")
8994 || aChangeArg.StartsWith ("equation"))
4269bd1b 8995 {
3e05329c 8996 if (aNbChangeArgs < 5)
4269bd1b 8997 {
23fe70ec 8998 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8999 return 1;
9000 }
9001
25c35042 9002 Standard_Integer aSubIndex = 1;
9003 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9004 if (aPrefixLen < aChangeArg.Length())
9005 {
9006 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9007 if (!aSubStr.IsIntegerValue()
9008 || aSubStr.IntegerValue() <= 0)
9009 {
23fe70ec 9010 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9011 return 1;
9012 }
9013 aSubIndex = aSubStr.IntegerValue();
9014 }
9015
9016 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9017 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9018 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9019 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9020 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9021 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9022 {
9023 if (aSubPln->ChainNextPlane().IsNull())
9024 {
9025 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9026 }
9027 aSubPln = aSubPln->ChainNextPlane();
9028 }
9029 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9030 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9031 anArgIter += 4;
4269bd1b 9032 }
25c35042 9033 else if ((aChangeArg == "-boxinterior"
9034 || aChangeArg == "-boxint"
9035 || aChangeArg == "-box")
9036 && aNbChangeArgs >= 7)
9037 {
9038 Graphic3d_BndBox3d aBndBox;
9039 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9040 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9041 anArgIter += 6;
9042
9043 Standard_Integer aNbSubPlanes = 6;
9044 const Graphic3d_Vec3d aDirArray[6] =
9045 {
9046 Graphic3d_Vec3d (-1, 0, 0),
9047 Graphic3d_Vec3d ( 1, 0, 0),
9048 Graphic3d_Vec3d ( 0,-1, 0),
9049 Graphic3d_Vec3d ( 0, 1, 0),
9050 Graphic3d_Vec3d ( 0, 0,-1),
9051 Graphic3d_Vec3d ( 0, 0, 1),
9052 };
9053 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9054 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9055 {
9056 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9057 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9058 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9059 if (aSubPlaneIter + 1 == aNbSubPlanes)
9060 {
9061 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9062 }
9063 else
9064 {
9065 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9066 }
9067 aSubPln = aSubPln->ChainNextPlane();
9068 }
9069 }
3e05329c 9070 else if (aChangeArg == "-capping"
9071 || aChangeArg == "capping")
4269bd1b 9072 {
3e05329c 9073 if (aNbChangeArgs < 2)
4269bd1b 9074 {
23fe70ec 9075 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9076 return 1;
9077 }
9078
dae2a922 9079 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9080 {
3e05329c 9081 aClipPlane->SetCapping (toEnable);
9082 anArgIter += 1;
9083 }
9084 else
9085 {
9086 // just skip otherwise (old syntax)
9087 }
9088 }
9089 else if (aChangeArg == "-useobjectmaterial"
9090 || aChangeArg == "-useobjectmat"
9091 || aChangeArg == "-useobjmat"
9092 || aChangeArg == "-useobjmaterial")
9093 {
9094 if (aNbChangeArgs < 2)
9095 {
23fe70ec 9096 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9097 return 1;
9098 }
9099
dae2a922 9100 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9101 {
3e05329c 9102 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9103 anArgIter += 1;
4269bd1b 9104 }
3e05329c 9105 }
9106 else if (aChangeArg == "-useobjecttexture"
9107 || aChangeArg == "-useobjecttex"
9108 || aChangeArg == "-useobjtexture"
9109 || aChangeArg == "-useobjtex")
9110 {
9111 if (aNbChangeArgs < 2)
4269bd1b 9112 {
23fe70ec 9113 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9114 return 1;
9115 }
4269bd1b 9116
dae2a922 9117 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9118 {
9119 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9120 anArgIter += 1;
9121 }
9122 }
9123 else if (aChangeArg == "-useobjectshader"
9124 || aChangeArg == "-useobjshader")
9125 {
9126 if (aNbChangeArgs < 2)
9127 {
23fe70ec 9128 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9129 return 1;
9130 }
4269bd1b 9131
dae2a922 9132 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9133 {
9134 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9135 anArgIter += 1;
4269bd1b 9136 }
3e05329c 9137 }
9138 else if (aChangeArg == "-color"
9139 || aChangeArg == "color")
9140 {
9141 Quantity_Color aColor;
dae2a922 9142 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9143 aChangeArgs + 1,
9144 aColor);
3e05329c 9145 if (aNbParsed == 0)
4269bd1b 9146 {
23fe70ec 9147 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9148 return 1;
9149 }
61168418 9150 aClipPlane->SetCappingColor (aColor);
3e05329c 9151 anArgIter += aNbParsed;
9152 }
61168418 9153 else if (aNbChangeArgs >= 1
9154 && (aChangeArg == "-material"
9155 || aChangeArg == "material"))
9156 {
9157 ++anArgIter;
9158 Graphic3d_NameOfMaterial aMatName;
9159 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9160 {
23fe70ec 9161 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9162 return 1;
9163 }
9164 aClipPlane->SetCappingMaterial (aMatName);
9165 }
1b661a81 9166 else if ((aChangeArg == "-transparency"
9167 || aChangeArg == "-transp")
9168 && aNbChangeArgs >= 2)
9169 {
9170 TCollection_AsciiString aValStr (aChangeArgs[1]);
9171 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
d45edf24 9172 if (aValStr.IsRealValue (Standard_True))
1b661a81 9173 {
9174 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9175 aMat.SetTransparency ((float )aValStr.RealValue());
9176 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9177 aClipPlane->SetCappingMaterial (aMat);
9178 }
9179 else
9180 {
9181 aValStr.LowerCase();
9182 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9183 if (aValStr == "opaque")
9184 {
9185 aMode = Graphic3d_AlphaMode_Opaque;
9186 }
9187 else if (aValStr == "mask")
9188 {
9189 aMode = Graphic3d_AlphaMode_Mask;
9190 }
9191 else if (aValStr == "blend")
9192 {
9193 aMode = Graphic3d_AlphaMode_Blend;
9194 }
33425a46 9195 else if (aValStr == "maskblend"
9196 || aValStr == "blendmask")
9197 {
9198 aMode = Graphic3d_AlphaMode_MaskBlend;
9199 }
1b661a81 9200 else if (aValStr == "blendauto")
9201 {
9202 aMode = Graphic3d_AlphaMode_BlendAuto;
9203 }
9204 else
9205 {
23fe70ec 9206 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9207 return 1;
9208 }
9209 anAspect->SetAlphaMode (aMode);
9210 aClipPlane->SetCappingAspect (anAspect);
9211 }
9212 anArgIter += 1;
9213 }
3e05329c 9214 else if (aChangeArg == "-texname"
9215 || aChangeArg == "texname")
9216 {
9217 if (aNbChangeArgs < 2)
9218 {
23fe70ec 9219 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9220 return 1;
9221 }
4269bd1b 9222
3e05329c 9223 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9224 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9225 if (!aTexture->IsDone())
9226 {
9227 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9228 }
3e05329c 9229 else
4269bd1b 9230 {
3e05329c 9231 aTexture->EnableModulate();
9232 aTexture->EnableRepeat();
9233 aClipPlane->SetCappingTexture (aTexture);
9234 }
9235 anArgIter += 1;
9236 }
9237 else if (aChangeArg == "-texscale"
9238 || aChangeArg == "texscale")
9239 {
9240 if (aClipPlane->CappingTexture().IsNull())
9241 {
23fe70ec 9242 Message::SendFail ("Error: no texture is set");
3e05329c 9243 return 1;
9244 }
4269bd1b 9245
3e05329c 9246 if (aNbChangeArgs < 3)
9247 {
23fe70ec 9248 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9249 return 1;
9250 }
4269bd1b 9251
3e05329c 9252 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9253 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9254 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9255 anArgIter += 2;
9256 }
9257 else if (aChangeArg == "-texorigin"
9258 || aChangeArg == "texorigin") // texture origin
9259 {
9260 if (aClipPlane->CappingTexture().IsNull())
9261 {
23fe70ec 9262 Message::SendFail ("Error: no texture is set");
3e05329c 9263 return 1;
9264 }
4269bd1b 9265
3e05329c 9266 if (aNbChangeArgs < 3)
9267 {
23fe70ec 9268 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9269 return 1;
4269bd1b 9270 }
3e05329c 9271
9272 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9273 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9274
9275 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9276 anArgIter += 2;
9277 }
9278 else if (aChangeArg == "-texrotate"
9279 || aChangeArg == "texrotate") // texture rotation
9280 {
9281 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9282 {
23fe70ec 9283 Message::SendFail ("Error: no texture is set");
3e05329c 9284 return 1;
9285 }
4269bd1b 9286
3e05329c 9287 if (aNbChangeArgs < 2)
9288 {
23fe70ec 9289 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9290 return 1;
9291 }
4269bd1b 9292
3e05329c 9293 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9294 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9295 anArgIter += 1;
9296 }
9297 else if (aChangeArg == "-hatch"
9298 || aChangeArg == "hatch")
9299 {
9300 if (aNbChangeArgs < 2)
9301 {
23fe70ec 9302 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9303 return 1;
9304 }
4269bd1b 9305
3e05329c 9306 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9307 aHatchStr.LowerCase();
9308 if (aHatchStr == "on")
9309 {
9310 aClipPlane->SetCappingHatchOn();
9311 }
9312 else if (aHatchStr == "off")
9313 {
9314 aClipPlane->SetCappingHatchOff();
4269bd1b 9315 }
3e05329c 9316 else
4269bd1b 9317 {
3e05329c 9318 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9319 }
9320 anArgIter += 1;
9321 }
9322 else if (aChangeArg == "-delete"
9323 || aChangeArg == "delete")
9324 {
9325 removePlane (aRegPlanes, aPlaneName);
9326 return 0;
9327 }
9328 else if (aChangeArg == "-set"
32ca7711 9329 || aChangeArg == "-unset"
9330 || aChangeArg == "-setoverrideglobal")
3e05329c 9331 {
9332 // set / unset plane command
32ca7711 9333 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9334 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9335 Standard_Integer anIt = 1;
9336 for (; anIt < aNbChangeArgs; ++anIt)
9337 {
9338 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9339 if (anEntityName.IsEmpty()
9340 || anEntityName.Value (1) == '-')
4269bd1b 9341 {
3e05329c 9342 break;
4269bd1b 9343 }
32ca7711 9344 else if (!toOverrideGlobal
9345 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9346 {
3e05329c 9347 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9348 if (toSet)
9349 {
9350 aView->AddClipPlane (aClipPlane);
9351 }
9352 else
9353 {
9354 aView->RemoveClipPlane (aClipPlane);
9355 }
9356 continue;
4269bd1b 9357 }
3e05329c 9358 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9359 {
8f521168 9360 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9361 if (toSet)
9362 {
9363 aIObj->AddClipPlane (aClipPlane);
9364 }
9365 else
9366 {
9367 aIObj->RemoveClipPlane (aClipPlane);
9368 }
32ca7711 9369 if (!aIObj->ClipPlanes().IsNull())
9370 {
9371 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9372 }
4269bd1b 9373 }
3e05329c 9374 else
4269bd1b 9375 {
23fe70ec 9376 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9377 return 1;
4269bd1b 9378 }
3e05329c 9379 }
9380
9381 if (anIt == 1)
9382 {
9383 // apply to active view
9384 if (toSet)
4269bd1b 9385 {
3e05329c 9386 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9387 }
9388 else
9389 {
3e05329c 9390 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9391 }
9392 }
3e05329c 9393 else
9394 {
9395 anArgIter = anArgIter + anIt - 1;
9396 }
9397 }
9398 else
9399 {
23fe70ec 9400 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9401 return 1;
4269bd1b 9402 }
4269bd1b 9403 }
9404
3e05329c 9405 ViewerTest::RedrawAllViews();
9406 return 0;
4269bd1b 9407}
9408
b5ac8292 9409//===============================================================================================
9410//function : VZRange
9411//purpose :
9412//===============================================================================================
9413static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9414{
197ac94e 9415 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9416
9417 if (aCurrentView.IsNull())
b5ac8292 9418 {
23fe70ec 9419 Message::SendFail ("Error: no active viewer");
b5ac8292 9420 return 1;
9421 }
9422
197ac94e 9423 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9424
9425 if (theArgsNb < 2)
9426 {
9427 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9428 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9429 return 0;
9430 }
9431
9432 if (theArgsNb == 3)
9433 {
6b62b2da 9434 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9435 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9436
9437 if (aNewZNear >= aNewZFar)
9438 {
23fe70ec 9439 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9440 return 1;
9441 }
9442
9443 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9444 {
23fe70ec 9445 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9446 return 1;
9447 }
9448
9449 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9450 }
9451 else
9452 {
23fe70ec 9453 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9454 return 1;
9455 }
9456
197ac94e 9457 aCurrentView->Redraw();
9458
b5ac8292 9459 return 0;
9460}
9461
9462//===============================================================================================
9463//function : VAutoZFit
9464//purpose :
9465//===============================================================================================
9466static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9467{
197ac94e 9468 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9469
9470 if (aCurrentView.IsNull())
b5ac8292 9471 {
23fe70ec 9472 Message::SendFail ("Error: no active viewer");
b5ac8292 9473 return 1;
9474 }
9475
c357e426 9476 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9477
9478 if (theArgsNb > 3)
b5ac8292 9479 {
23fe70ec 9480 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9481 return 1;
b5ac8292 9482 }
9483
197ac94e 9484 if (theArgsNb < 2)
b5ac8292 9485 {
586db386 9486 theDi << "Auto z-fit mode: \n"
c357e426 9487 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9488 << "Scale: " << aScale << "\n";
9489 return 0;
b5ac8292 9490 }
197ac94e 9491
9492 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9493
9494 if (theArgsNb >= 3)
b5ac8292 9495 {
197ac94e 9496 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9497 }
9498
c357e426 9499 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9500 aCurrentView->Redraw();
b5ac8292 9501 return 0;
9502}
9503
6b62b2da 9504//! Auxiliary function to print projection type
9505inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9506{
9507 switch (theProjType)
9508 {
9509 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9510 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9511 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9512 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9513 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9514 }
9515 return "UNKNOWN";
9516}
9517
b5ac8292 9518//===============================================================================================
6b62b2da 9519//function : VCamera
b5ac8292 9520//purpose :
9521//===============================================================================================
6b62b2da 9522static int VCamera (Draw_Interpretor& theDI,
9523 Standard_Integer theArgsNb,
9524 const char** theArgVec)
b5ac8292 9525{
6b62b2da 9526 Handle(V3d_View) aView = ViewerTest::CurrentView();
9527 if (aView.IsNull())
b5ac8292 9528 {
23fe70ec 9529 Message::SendFail ("Error: no active viewer");
b5ac8292 9530 return 1;
9531 }
9532
6b62b2da 9533 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9534 if (theArgsNb < 2)
b5ac8292 9535 {
6b62b2da 9536 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9537 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 9538 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9539 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 9540 theDI << "Distance: " << aCamera->Distance() << "\n";
9541 theDI << "IOD: " << aCamera->IOD() << "\n";
9542 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9543 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9544 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
168c27c6 9545 theDI << "ZNear: " << aCamera->ZNear() << "\n";
9546 theDI << "ZFar: " << aCamera->ZFar() << "\n";
6b62b2da 9547 return 0;
b5ac8292 9548 }
9549
30a1b24e 9550 TCollection_AsciiString aPrsName;
6b62b2da 9551 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 9552 {
6b62b2da 9553 Standard_CString anArg = theArgVec[anArgIter];
9554 TCollection_AsciiString anArgCase (anArg);
9555 anArgCase.LowerCase();
9556 if (anArgCase == "-proj"
9557 || anArgCase == "-projection"
9558 || anArgCase == "-projtype"
9559 || anArgCase == "-projectiontype")
9560 {
9561 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9562 }
9563 else if (anArgCase == "-ortho"
9564 || anArgCase == "-orthographic")
b5ac8292 9565 {
9566 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 9567 }
9568 else if (anArgCase == "-persp"
9569 || anArgCase == "-perspective"
9570 || anArgCase == "-perspmono"
9571 || anArgCase == "-perspectivemono"
9572 || anArgCase == "-mono")
b5ac8292 9573 {
9574 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9575 }
6b62b2da 9576 else if (anArgCase == "-stereo"
9577 || anArgCase == "-stereoscopic"
9578 || anArgCase == "-perspstereo"
9579 || anArgCase == "-perspectivestereo")
9580 {
9581 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9582 }
9583 else if (anArgCase == "-left"
9584 || anArgCase == "-lefteye"
9585 || anArgCase == "-monoleft"
9586 || anArgCase == "-monolefteye"
9587 || anArgCase == "-perpsleft"
9588 || anArgCase == "-perpslefteye")
b5ac8292 9589 {
9590 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9591 }
6b62b2da 9592 else if (anArgCase == "-right"
9593 || anArgCase == "-righteye"
9594 || anArgCase == "-monoright"
9595 || anArgCase == "-monorighteye"
9596 || anArgCase == "-perpsright")
b5ac8292 9597 {
9598 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9599 }
6b62b2da 9600 else if (anArgCase == "-dist"
9601 || anArgCase == "-distance")
b5ac8292 9602 {
6b62b2da 9603 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9604 if (anArgValue != NULL
9605 && *anArgValue != '-')
9606 {
9607 ++anArgIter;
9608 aCamera->SetDistance (Draw::Atof (anArgValue));
9609 continue;
9610 }
9611 theDI << aCamera->Distance() << " ";
b5ac8292 9612 }
6b62b2da 9613 else if (anArgCase == "-iod")
b5ac8292 9614 {
6b62b2da 9615 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9616 if (anArgValue != NULL
9617 && *anArgValue != '-')
9618 {
9619 ++anArgIter;
9620 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9621 continue;
9622 }
9623 theDI << aCamera->IOD() << " ";
b5ac8292 9624 }
6b62b2da 9625 else if (anArgCase == "-iodtype")
b5ac8292 9626 {
6b62b2da 9627 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9628 TCollection_AsciiString anValueCase (anArgValue);
9629 anValueCase.LowerCase();
9630 if (anValueCase == "abs"
9631 || anValueCase == "absolute")
9632 {
9633 ++anArgIter;
9634 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9635 continue;
9636 }
9637 else if (anValueCase == "rel"
9638 || anValueCase == "relative")
9639 {
9640 ++anArgIter;
9641 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9642 continue;
9643 }
9644 else if (*anArgValue != '-')
9645 {
23fe70ec 9646 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 9647 return 1;
9648 }
9649 switch (aCamera->GetIODType())
9650 {
9651 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9652 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9653 }
b5ac8292 9654 }
6b62b2da 9655 else if (anArgCase == "-zfocus")
b5ac8292 9656 {
6b62b2da 9657 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9658 if (anArgValue != NULL
9659 && *anArgValue != '-')
9660 {
9661 ++anArgIter;
9662 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9663 continue;
9664 }
9665 theDI << aCamera->ZFocus() << " ";
b5ac8292 9666 }
6b62b2da 9667 else if (anArgCase == "-zfocustype")
b5ac8292 9668 {
6b62b2da 9669 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9670 TCollection_AsciiString anValueCase (anArgValue);
9671 anValueCase.LowerCase();
9672 if (anValueCase == "abs"
9673 || anValueCase == "absolute")
9674 {
9675 ++anArgIter;
9676 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9677 continue;
9678 }
9679 else if (anValueCase == "rel"
9680 || anValueCase == "relative")
9681 {
9682 ++anArgIter;
9683 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9684 continue;
9685 }
9686 else if (*anArgValue != '-')
9687 {
23fe70ec 9688 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 9689 return 1;
9690 }
9691 switch (aCamera->ZFocusType())
9692 {
9693 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9694 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9695 }
9696 }
b40cdc2b 9697 else if (anArgCase == "-lockzup"
9698 || anArgCase == "-turntable")
9699 {
9700 bool toLockUp = true;
9701 if (++anArgIter < theArgsNb
dae2a922 9702 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 9703 {
9704 --anArgIter;
9705 }
9706 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9707 }
6b62b2da 9708 else if (anArgCase == "-fov"
b40cdc2b 9709 || anArgCase == "-fovy"
9710 || anArgCase == "-fovx"
9711 || anArgCase == "-fov2d")
b5ac8292 9712 {
6b62b2da 9713 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9714 if (anArgValue != NULL
9715 && *anArgValue != '-')
9716 {
9717 ++anArgIter;
b40cdc2b 9718 if (anArgCase == "-fov2d")
9719 {
9720 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9721 }
9722 else if (anArgCase == "-fovx")
9723 {
9724 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9725 }
9726 else
9727 {
9728 aCamera->SetFOVy (Draw::Atof (anArgValue));
9729 }
6b62b2da 9730 continue;
9731 }
b40cdc2b 9732 if (anArgCase == "-fov2d")
9733 {
9734 theDI << aCamera->FOV2d() << " ";
9735 }
9736 else if (anArgCase == "-fovx")
9737 {
9738 theDI << aCamera->FOVx() << " ";
9739 }
9740 else
9741 {
9742 theDI << aCamera->FOVy() << " ";
9743 }
9744 }
9745 else if (anArgIter + 1 < theArgsNb
9746 && anArgCase == "-xrpose")
9747 {
9748 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9749 anXRArg.LowerCase();
9750 if (anXRArg == "base")
9751 {
9752 aCamera = aView->View()->BaseXRCamera();
9753 }
9754 else if (anXRArg == "head")
9755 {
9756 aCamera = aView->View()->PosedXRCamera();
9757 }
9758 else
9759 {
9760 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9761 return 1;
9762 }
9763 if (aCamera.IsNull())
9764 {
9765 Message::SendFail() << "Error: undefined XR pose";
9766 return 0;
9767 }
9768 if (aView->AutoZFitMode())
9769 {
9770 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9771 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9772 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9773 }
b5ac8292 9774 }
30a1b24e 9775 else if (aPrsName.IsEmpty()
9776 && !anArgCase.StartsWith ("-"))
9777 {
9778 aPrsName = anArg;
9779 }
b5ac8292 9780 else
9781 {
23fe70ec 9782 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 9783 return 1;
9784 }
9785 }
b5ac8292 9786
30a1b24e 9787 if (aPrsName.IsEmpty()
9788 || theArgsNb > 2)
9789 {
30a1b24e 9790 aView->Redraw();
9791 }
9792
9793 if (!aPrsName.IsEmpty())
9794 {
9795 Handle(AIS_CameraFrustum) aCameraFrustum;
9796 if (GetMapOfAIS().IsBound2 (aPrsName))
9797 {
9798 // find existing object
9799 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9800 if (aCameraFrustum.IsNull())
9801 {
23fe70ec 9802 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 9803 return 1;
9804 }
9805 }
9806
9807 if (aCameraFrustum.IsNull())
9808 {
9809 aCameraFrustum = new AIS_CameraFrustum();
9810 }
9811 else
9812 {
9813 // not include displayed object of old camera frustum in the new one.
9814 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9815 aView->ZFitAll();
9816 }
b40cdc2b 9817 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 9818
9819 ViewerTest::Display (aPrsName, aCameraFrustum);
9820 }
b5ac8292 9821
9822 return 0;
9823}
9824
f978241f 9825//! Parse stereo output mode
9826inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9827 Graphic3d_StereoMode& theMode)
9828{
9829 TCollection_AsciiString aFlag (theArg);
9830 aFlag.LowerCase();
9831 if (aFlag == "quadbuffer")
9832 {
9833 theMode = Graphic3d_StereoMode_QuadBuffer;
9834 }
9835 else if (aFlag == "anaglyph")
9836 {
9837 theMode = Graphic3d_StereoMode_Anaglyph;
9838 }
9839 else if (aFlag == "row"
9840 || aFlag == "rowinterlaced")
9841 {
9842 theMode = Graphic3d_StereoMode_RowInterlaced;
9843 }
9844 else if (aFlag == "col"
9845 || aFlag == "colinterlaced"
9846 || aFlag == "columninterlaced")
9847 {
9848 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9849 }
9850 else if (aFlag == "chess"
9851 || aFlag == "chessboard")
9852 {
9853 theMode = Graphic3d_StereoMode_ChessBoard;
9854 }
9855 else if (aFlag == "sbs"
9856 || aFlag == "sidebyside")
9857 {
9858 theMode = Graphic3d_StereoMode_SideBySide;
9859 }
9860 else if (aFlag == "ou"
9861 || aFlag == "overunder")
9862 {
9863 theMode = Graphic3d_StereoMode_OverUnder;
9864 }
9865 else if (aFlag == "pageflip"
9866 || aFlag == "softpageflip")
9867 {
9868 theMode = Graphic3d_StereoMode_SoftPageFlip;
9869 }
b40cdc2b 9870 else if (aFlag == "openvr"
9871 || aFlag == "vr")
9872 {
9873 theMode = Graphic3d_StereoMode_OpenVR;
9874 }
f978241f 9875 else
9876 {
9877 return Standard_False;
9878 }
9879 return Standard_True;
9880}
9881
9882//! Parse anaglyph filter
9883inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9884 Graphic3d_RenderingParams::Anaglyph& theFilter)
9885{
9886 TCollection_AsciiString aFlag (theArg);
9887 aFlag.LowerCase();
9888 if (aFlag == "redcyansimple")
9889 {
9890 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9891 }
9892 else if (aFlag == "redcyan"
9893 || aFlag == "redcyanoptimized")
9894 {
9895 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9896 }
9897 else if (aFlag == "yellowbluesimple")
9898 {
9899 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9900 }
9901 else if (aFlag == "yellowblue"
9902 || aFlag == "yellowblueoptimized")
9903 {
9904 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9905 }
9906 else if (aFlag == "greenmagenta"
9907 || aFlag == "greenmagentasimple")
9908 {
9909 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9910 }
9911 else
9912 {
9913 return Standard_False;
9914 }
9915 return Standard_True;
9916}
9917
b5ac8292 9918//==============================================================================
9919//function : VStereo
9920//purpose :
9921//==============================================================================
9922
9923static int VStereo (Draw_Interpretor& theDI,
9924 Standard_Integer theArgNb,
9925 const char** theArgVec)
9926{
f978241f 9927 Handle(V3d_View) aView = ViewerTest::CurrentView();
b8db9379 9928 if (aView.IsNull())
b5ac8292 9929 {
b8db9379 9930 Message::SendFail ("Error: no active viewer");
9931 return 0;
9932 }
b5ac8292 9933
b8db9379 9934 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9935 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9936 if (theArgNb < 2)
9937 {
9938 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
b5ac8292 9939 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 9940 if (isActive)
9941 {
9942 TCollection_AsciiString aMode;
9943 switch (aView->RenderingParams().StereoMode)
9944 {
9945 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
9946 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
9947 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
9948 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
9949 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
9950 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
9951 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 9952 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 9953 case Graphic3d_StereoMode_Anaglyph :
9954 aMode = "anaglyph";
9955 switch (aView->RenderingParams().AnaglyphFilter)
9956 {
9957 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9958 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9959 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9960 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9961 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9962 default: break;
9963 }
9964 default: break;
9965 }
9966 theDI << "Mode " << aMode << "\n";
9967 }
b5ac8292 9968 return 0;
9969 }
9970
b8db9379 9971 Graphic3d_StereoMode aMode = aParams->StereoMode;
f978241f 9972 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9973 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9974 {
9975 Standard_CString anArg = theArgVec[anArgIter];
9976 TCollection_AsciiString aFlag (anArg);
9977 aFlag.LowerCase();
9978 if (anUpdateTool.parseRedrawMode (aFlag))
9979 {
9980 continue;
9981 }
9982 else if (aFlag == "0"
9983 || aFlag == "off")
9984 {
9985 if (++anArgIter < theArgNb)
9986 {
23fe70ec 9987 Message::SendFail ("Error: wrong number of arguments");
f978241f 9988 return 1;
9989 }
9990
b8db9379 9991 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
f978241f 9992 {
9993 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9994 }
f978241f 9995 return 0;
9996 }
9997 else if (aFlag == "1"
9998 || aFlag == "on")
9999 {
10000 if (++anArgIter < theArgNb)
10001 {
23fe70ec 10002 Message::SendFail ("Error: wrong number of arguments");
f978241f 10003 return 1;
10004 }
10005
b8db9379 10006 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 10007 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10008 {
10009 return 0;
10010 }
f978241f 10011 }
10012 else if (aFlag == "-reverse"
10013 || aFlag == "-reversed"
10014 || aFlag == "-swap")
10015 {
10016 Standard_Boolean toEnable = Standard_True;
10017 if (++anArgIter < theArgNb
dae2a922 10018 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10019 {
10020 --anArgIter;
10021 }
10022 aParams->ToReverseStereo = toEnable;
10023 }
10024 else if (aFlag == "-noreverse"
10025 || aFlag == "-noswap")
10026 {
10027 Standard_Boolean toDisable = Standard_True;
10028 if (++anArgIter < theArgNb
dae2a922 10029 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10030 {
10031 --anArgIter;
10032 }
10033 aParams->ToReverseStereo = !toDisable;
10034 }
10035 else if (aFlag == "-mode"
10036 || aFlag == "-stereomode")
10037 {
10038 if (++anArgIter >= theArgNb
10039 || !parseStereoMode (theArgVec[anArgIter], aMode))
10040 {
23fe70ec 10041 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10042 return 1;
10043 }
10044
10045 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10046 {
b8db9379 10047 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10048 }
10049 }
10050 else if (aFlag == "-anaglyph"
10051 || aFlag == "-anaglyphfilter")
10052 {
10053 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10054 if (++anArgIter >= theArgNb
10055 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10056 {
23fe70ec 10057 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10058 return 1;
10059 }
10060
10061 aMode = Graphic3d_StereoMode_Anaglyph;
10062 aParams->AnaglyphFilter = aFilter;
10063 }
10064 else if (parseStereoMode (anArg, aMode)) // short syntax
10065 {
10066 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10067 {
b8db9379 10068 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10069 }
10070 }
b40cdc2b 10071 else if (anArgIter + 1 < theArgNb
10072 && aFlag == "-hmdfov2d")
10073 {
10074 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10075 if (aParams->HmdFov2d < 10.0f
10076 || aParams->HmdFov2d > 180.0f)
10077 {
10078 Message::SendFail() << "Error: FOV is out of range";
10079 return 1;
10080 }
10081 }
10082 else if (aFlag == "-mirror"
10083 || aFlag == "-mirrorcomposer")
10084 {
10085 Standard_Boolean toEnable = Standard_True;
10086 if (++anArgIter < theArgNb
dae2a922 10087 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10088 {
10089 --anArgIter;
10090 }
10091 aParams->ToMirrorComposer = toEnable;
10092 }
10093 else if (anArgIter + 1 < theArgNb
10094 && (aFlag == "-unitfactor"
10095 || aFlag == "-unitscale"))
10096 {
10097 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10098 }
f978241f 10099 else
10100 {
23fe70ec 10101 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10102 return 1;
10103 }
10104 }
10105
b8db9379 10106 aParams->StereoMode = aMode;
10107 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10108 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
f978241f 10109 {
b8db9379 10110 // initiate implicit continuous rendering
10111 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
f978241f 10112 }
b5ac8292 10113 return 0;
10114}
10115
392ac980 10116//===============================================================================================
10117//function : VDefaults
10118//purpose :
10119//===============================================================================================
10120static int VDefaults (Draw_Interpretor& theDi,
10121 Standard_Integer theArgsNb,
10122 const char** theArgVec)
10123{
10124 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10125 if (aCtx.IsNull())
10126 {
23fe70ec 10127 Message::SendFail ("Error: no active viewer");
392ac980 10128 return 1;
10129 }
10130
10131 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10132 if (theArgsNb < 2)
10133 {
10134 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10135 {
10136 theDi << "DeflType: relative\n"
10137 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10138 }
10139 else
10140 {
10141 theDi << "DeflType: absolute\n"
10142 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10143 }
67441d0c 10144 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10145 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10146 return 0;
10147 }
10148
10149 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10150 {
10151 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10152 anArg.UpperCase();
10153 if (anArg == "-ABSDEFL"
10154 || anArg == "-ABSOLUTEDEFLECTION"
10155 || anArg == "-DEFL"
10156 || anArg == "-DEFLECTION")
392ac980 10157 {
4c513386 10158 if (++anArgIter >= theArgsNb)
10159 {
23fe70ec 10160 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10161 return 1;
10162 }
392ac980 10163 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10164 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10165 }
4c513386 10166 else if (anArg == "-RELDEFL"
10167 || anArg == "-RELATIVEDEFLECTION"
10168 || anArg == "-DEVCOEFF"
10169 || anArg == "-DEVIATIONCOEFF"
10170 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10171 {
4c513386 10172 if (++anArgIter >= theArgsNb)
10173 {
23fe70ec 10174 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10175 return 1;
10176 }
392ac980 10177 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10178 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10179 }
4c513386 10180 else if (anArg == "-ANGDEFL"
10181 || anArg == "-ANGULARDEFL"
10182 || anArg == "-ANGULARDEFLECTION")
392ac980 10183 {
4c513386 10184 if (++anArgIter >= theArgsNb)
10185 {
23fe70ec 10186 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10187 return 1;
10188 }
67441d0c 10189 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10190 }
385c43e7 10191 else if (anArg == "-AUTOTR"
10192 || anArg == "-AUTOTRIANG"
10193 || anArg == "-AUTOTRIANGULATION")
4c513386 10194 {
14c7f553 10195 ++anArgIter;
10196 bool toTurnOn = true;
10197 if (anArgIter >= theArgsNb
dae2a922 10198 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10199 {
23fe70ec 10200 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10201 return 1;
10202 }
14c7f553 10203 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10204 }
10205 else
10206 {
23fe70ec 10207 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10208 return 1;
392ac980 10209 }
10210 }
10211
10212 return 0;
10213}
10214
06d40093 10215//! Parse light source type from string.
10216static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
10217 Graphic3d_TypeOfLightSource& theType)
12381341 10218{
06d40093 10219 TCollection_AsciiString aType (theTypeName);
10220 aType.LowerCase();
10221 if (aType == "amb"
10222 || aType == "ambient"
10223 || aType == "amblight")
12381341 10224 {
06d40093 10225 theType = Graphic3d_TypeOfLightSource_Ambient;
12381341 10226 }
06d40093 10227 else if (aType == "directional"
10228 || aType == "dirlight")
12381341 10229 {
06d40093 10230 theType = Graphic3d_TypeOfLightSource_Directional;
12381341 10231 }
06d40093 10232 else if (aType == "spot"
10233 || aType == "spotlight")
12381341 10234 {
06d40093 10235 theType = Graphic3d_TypeOfLightSource_Spot;
12381341 10236 }
06d40093 10237 else if (aType == "poslight"
10238 || aType == "positional"
10239 || aType == "point"
10240 || aType == "pnt")
12381341 10241 {
06d40093 10242 theType = Graphic3d_TypeOfLightSource_Positional;
12381341 10243 }
10244 else
10245 {
06d40093 10246 return false;
12381341 10247 }
06d40093 10248 return true;
12381341 10249}
10250
06d40093 10251//! Find existing light by name or index.
10252static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
2daa5d95 10253{
06d40093 10254 Handle(V3d_Light) aLight;
10255 Standard_Integer aLightIndex = -1;
10256 Draw::ParseInteger (theName.ToCString(), aLightIndex);
10257 Standard_Integer aLightIt = 0;
10258 Handle(V3d_View) aView = ViewerTest::CurrentView();
10259 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
2daa5d95 10260 {
06d40093 10261 if (aLightIndex != -1)
2daa5d95 10262 {
06d40093 10263 if (aLightIt == aLightIndex)
10264 {
10265 return aLightIter.Value();
10266 }
2daa5d95 10267 }
06d40093 10268 else if (aLightIter.Value()->GetId() == theName
10269 || aLightIter.Value()->Name() == theName)
2daa5d95 10270 {
06d40093 10271 if (!aLight.IsNull())
10272 {
10273 Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
10274 break;
10275 }
10276 aLight = aLightIter.Value();
2daa5d95 10277 }
10278 }
06d40093 10279 return aLight;
2daa5d95 10280}
10281
12381341 10282//===============================================================================================
10283//function : VLight
10284//purpose :
10285//===============================================================================================
10286static int VLight (Draw_Interpretor& theDi,
10287 Standard_Integer theArgsNb,
10288 const char** theArgVec)
10289{
10290 Handle(V3d_View) aView = ViewerTest::CurrentView();
10291 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
06d40093 10292 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
12381341 10293 if (aView.IsNull()
10294 || aViewer.IsNull())
10295 {
23fe70ec 10296 Message::SendFail ("Error: no active viewer");
12381341 10297 return 1;
10298 }
10299
12381341 10300 if (theArgsNb < 2)
10301 {
10302 // print lights info
10303 Standard_Integer aLightId = 0;
6a24c6de 10304 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10305 {
6a24c6de 10306 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10307 const Quantity_Color aColor = aLight->Color();
992ed6b3 10308 theDi << "Light #" << aLightId
10309 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
06d40093 10310 << " [" << aLight->GetId() << "] "
10311 << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
12381341 10312 switch (aLight->Type())
10313 {
10314 case V3d_AMBIENT:
10315 {
06d40093 10316 theDi << " Type: Ambient\n"
10317 << " Intensity: " << aLight->Intensity() << "\n";
12381341 10318 break;
10319 }
10320 case V3d_DIRECTIONAL:
10321 {
06d40093 10322 theDi << " Type: Directional\n"
10323 << " Intensity: " << aLight->Intensity() << "\n"
10324 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10325 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10326 << " Smoothness: " << aLight->Smoothness() << "\n"
10327 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
12381341 10328 break;
10329 }
10330 case V3d_POSITIONAL:
10331 {
06d40093 10332 theDi << " Type: Positional\n"
10333 << " Intensity: " << aLight->Intensity() << "\n"
10334 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10335 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10336 << " Smoothness: " << aLight->Smoothness() << "\n"
10337 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
10338 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
10339 << " Range: " << aLight->Range() << "\n";
12381341 10340 break;
10341 }
10342 case V3d_SPOT:
10343 {
06d40093 10344 theDi << " Type: Spot\n"
10345 << " Intensity: " << aLight->Intensity() << "\n"
10346 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
10347 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
10348 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
10349 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
10350 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
10351 << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
10352 << " Exponent: " << aLight->Concentration() << "\n"
10353 << " Range: " << aLight->Range() << "\n";
12381341 10354 break;
10355 }
10356 default:
10357 {
189f85a3 10358 theDi << " Type: UNKNOWN\n";
12381341 10359 break;
10360 }
10361 }
06d40093 10362 theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10363 }
10364 }
10365
06d40093 10366 Handle(V3d_Light) aLightOld, aLightNew;
992ed6b3 10367 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
06d40093 10368 bool isGlobal = true;
10369 ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
10370 Handle(AIS_LightSource) aLightPrs;
12381341 10371 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10372 {
12381341 10373 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10374 TCollection_AsciiString anArgCase (anArg);
06d40093 10375 anArgCase.LowerCase();
761d8807 10376 if (anUpdateTool.parseRedrawMode (anArg))
10377 {
10378 continue;
10379 }
06d40093 10380 else if (anArgCase == "-new"
10381 || anArgCase == "-add"
10382 || anArgCase == "-create"
10383 || anArgCase == "-type"
10384 || (anArgCase == "-reset"
10385 && !aLightNew.IsNull())
10386 || (anArgCase == "-defaults"
10387 && !aLightNew.IsNull())
10388 || anArgCase == "add"
10389 || anArgCase == "new"
10390 || anArgCase == "create")
992ed6b3 10391 {
06d40093 10392 Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
10393 if (anArgCase == "-reset")
992ed6b3 10394 {
06d40093 10395 aType = aLightNew->Type();
992ed6b3 10396 }
06d40093 10397 else if (anArgIt + 1 >= theArgsNb
10398 || !parseLightSourceType (theArgVec[++anArgIt], aType))
992ed6b3 10399 {
06d40093 10400 theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
10401 return 1;
992ed6b3 10402 }
06d40093 10403
10404 TCollection_AsciiString aName;
10405 if (!aLightNew.IsNull())
992ed6b3 10406 {
06d40093 10407 aName = aLightNew->Name();
992ed6b3 10408 }
06d40093 10409 switch (aType)
992ed6b3 10410 {
06d40093 10411 case Graphic3d_TypeOfLightSource_Ambient:
10412 {
10413 aLightNew = new V3d_AmbientLight();
10414 break;
10415 }
10416 case Graphic3d_TypeOfLightSource_Directional:
10417 {
10418 aLightNew = new V3d_DirectionalLight();
10419 break;
10420 }
10421 case Graphic3d_TypeOfLightSource_Spot:
10422 {
10423 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
10424 break;
10425 }
10426 case Graphic3d_TypeOfLightSource_Positional:
10427 {
10428 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
10429 break;
10430 }
992ed6b3 10431 }
06d40093 10432
10433 if (anArgCase == "-type"
10434 && !aLightOld.IsNull())
992ed6b3 10435 {
06d40093 10436 aLightNew->CopyFrom (aLightOld);
992ed6b3 10437 }
06d40093 10438 aLightNew->SetName (aName);
10439 }
10440 else if ((anArgCase == "-layer"
10441 || anArgCase == "-zlayer")
10442 && anArgIt + 1 < theArgsNb)
10443 {
10444 if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
10445 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
992ed6b3 10446 {
06d40093 10447 Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
992ed6b3 10448 return 1;
10449 }
10450 }
06d40093 10451 else if (anArgCase == "-glob"
10452 || anArgCase == "-global"
10453 || anArgCase == "-loc"
10454 || anArgCase == "-local")
12381341 10455 {
06d40093 10456 isGlobal = anArgCase.StartsWith ("-glob");
12381341 10457 }
06d40093 10458 else if (anArgCase == "-def"
10459 || anArgCase == "-defaults"
10460 || anArgCase == "-reset")
12381341 10461 {
4fe9ad57 10462 aViewer->SetDefaultLights();
06d40093 10463 aLightOld.Nullify();
10464 aLightNew.Nullify();
10465 aLightPrs.Nullify();
4fe9ad57 10466 }
06d40093 10467 else if (anArgCase == "-clr"
10468 || anArgCase == "-clear"
10469 || anArgCase == "clear")
4fe9ad57 10470 {
992ed6b3 10471 TColStd_SequenceOfInteger aLayers;
10472 aViewer->GetAllZLayers (aLayers);
10473 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10474 {
992ed6b3 10475 if (aLayeriter.Value() == aLayer
10476 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10477 {
10478 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10479 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10480 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10481 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10482 {
10483 break;
10484 }
10485 }
10486 }
10487
10488 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10489 {
06d40093 10490 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
992ed6b3 10491 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10492 {
10493 Handle(V3d_Light) aLight = aLightIter.Value();
06d40093 10494 Handle(AIS_InteractiveObject) aPrsObject;
10495 GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
10496 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
2daa5d95 10497 {
06d40093 10498 aCtx->Remove (aLightSourceDel, false);
10499 aMap.UnBind1 (aLightSourceDel);
2daa5d95 10500 }
992ed6b3 10501 aViewer->DelLight (aLight);
10502 aLightIter = aView->ActiveLightIterator();
10503 }
4fe9ad57 10504 }
12381341 10505
06d40093 10506 aLightOld.Nullify();
992ed6b3 10507 aLightNew.Nullify();
06d40093 10508 aLightPrs.Nullify();
12381341 10509 }
06d40093 10510 else if (!aLightNew.IsNull()
10511 && (anArgCase == "-display"
10512 || anArgCase == "-disp"
10513 || anArgCase == "-presentation"
10514 || anArgCase == "-prs"))
2daa5d95 10515 {
06d40093 10516 TCollection_AsciiString aLightName = aLightNew->Name();
10517 if (anArgIt + 1 < theArgsNb
10518 && theArgVec[anArgIt + 1][0] != '-')
2daa5d95 10519 {
06d40093 10520 // old syntax
10521 aLightName = theArgVec[++anArgIt];
10522 if (aLightNew->Name() != aLightName)
2daa5d95 10523 {
06d40093 10524 if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
10525 {
10526 theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
10527 return 1;
10528 }
10529 aLightNew->SetName (aLightName);
2daa5d95 10530 }
10531 }
10532 if (aLightName.IsEmpty())
10533 {
06d40093 10534 Message::SendFail() << "Error: nameless light source cannot be displayed";
12381341 10535 return 1;
10536 }
06d40093 10537 if (aLightPrs.IsNull())
992ed6b3 10538 {
06d40093 10539 aLightPrs = new AIS_LightSource (aLightNew);
992ed6b3 10540 }
06d40093 10541 theDi << aLightName << " ";
10542 }
10543 else if (!aLightNew.IsNull()
10544 && (anArgCase == "-disable"
10545 || anArgCase == "-disabled"
10546 || anArgCase == "-enable"
10547 || anArgCase == "-enabled"))
10548 {
10549 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10550 if (anArgCase == "-disable"
10551 || anArgCase == "-disabled")
12381341 10552 {
06d40093 10553 toEnable = !toEnable;
12381341 10554 }
06d40093 10555 aLightNew->SetEnabled (toEnable);
12381341 10556 }
06d40093 10557 else if (!aLightNew.IsNull()
10558 && (anArgCase == "-color"
10559 || anArgCase == "-colour"
10560 || anArgCase == "color"))
12381341 10561 {
dae2a922 10562 Quantity_Color aColor;
10563 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10564 theArgVec + anArgIt + 1,
10565 aColor);
10566 anArgIt += aNbParsed;
06d40093 10567 if (aNbParsed == 0)
12381341 10568 {
23fe70ec 10569 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10570 return 1;
10571 }
06d40093 10572 aLightNew->SetColor (aColor);
12381341 10573 }
06d40093 10574 else if (!aLightNew.IsNull()
10575 && (anArgCase == "-pos"
10576 || anArgCase == "-position"
10577 || anArgCase == "-prsposition"
10578 || anArgCase == "-prspos"
10579 || anArgCase == "pos"
10580 || anArgCase == "position")
10581 && (anArgIt + 3) < theArgsNb)
12381341 10582 {
2daa5d95 10583 gp_XYZ aPosXYZ;
06d40093 10584 if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
12381341 10585 {
23fe70ec 10586 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10587 return 1;
10588 }
10589
2daa5d95 10590 anArgIt += 3;
06d40093 10591 if (anArgCase == "-prsposition"
10592 || anArgCase == "-prspos")
2daa5d95 10593 {
06d40093 10594 aLightNew->SetDisplayPosition (aPosXYZ);
2daa5d95 10595 }
10596 else
10597 {
06d40093 10598 if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
10599 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
2daa5d95 10600 {
10601 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10602 return 1;
10603 }
10604
06d40093 10605 aLightNew->SetPosition (aPosXYZ);
2daa5d95 10606 }
12381341 10607 }
06d40093 10608 else if (!aLightNew.IsNull()
10609 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
10610 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10611 && (anArgCase == "-dir"
10612 || anArgCase == "-direction")
10613 && (anArgIt + 3) < theArgsNb)
12381341 10614 {
2daa5d95 10615 gp_XYZ aDirXYZ;
06d40093 10616 if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
12381341 10617 {
23fe70ec 10618 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10619 return 1;
10620 }
10621
2daa5d95 10622 anArgIt += 3;
06d40093 10623 aLightNew->SetDirection (gp_Dir (aDirXYZ));
12381341 10624 }
06d40093 10625 else if (!aLightNew.IsNull()
10626 && (anArgCase == "-smoothangle"
10627 || anArgCase == "-smoothradius"
10628 || anArgCase == "-sm"
10629 || anArgCase == "-smoothness")
10630 && anArgIt + 1 < theArgsNb)
189f85a3 10631 {
06d40093 10632 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10633 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
189f85a3 10634 {
06d40093 10635 aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
189f85a3 10636 }
992ed6b3 10637 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 10638 {
06d40093 10639 aLightNew->SetIntensity (1.f);
189f85a3 10640 }
06d40093 10641 else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
189f85a3 10642 {
06d40093 10643 aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
189f85a3 10644 }
10645 else
10646 {
06d40093 10647 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
10648 aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
189f85a3 10649 }
10650
06d40093 10651 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
189f85a3 10652 {
06d40093 10653 aLightNew->SetSmoothRadius (aSmoothness);
189f85a3 10654 }
06d40093 10655 else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
189f85a3 10656 {
06d40093 10657 aLightNew->SetSmoothAngle (aSmoothness);
189f85a3 10658 }
10659 }
06d40093 10660 else if (!aLightNew.IsNull()
10661 && (anArgCase == "-int"
10662 || anArgCase == "-intensity")
10663 && anArgIt + 1 < theArgsNb)
189f85a3 10664 {
06d40093 10665 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10666 aLightNew->SetIntensity (aIntensity);
189f85a3 10667 }
06d40093 10668 else if (!aLightNew.IsNull()
10669 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10670 && (anArgCase == "-spotangle"
10671 || anArgCase == "-ang"
10672 || anArgCase == "-angle")
10673 && anArgIt + 1 < theArgsNb)
4fe9ad57 10674 {
06d40093 10675 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
2daa5d95 10676 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
06d40093 10677 aLightNew->SetAngle (anAngle);
10678 }
10679 else if (!aLightNew.IsNull()
10680 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10681 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10682 && (anArgCase == "-constatten"
10683 || anArgCase == "-constattenuation")
10684 && anArgIt + 1 < theArgsNb)
10685 {
10686 const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10687 aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
10688 }
10689 else if (!aLightNew.IsNull()
10690 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10691 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10692 && (anArgCase == "-linatten"
10693 || anArgCase == "-linearatten"
10694 || anArgCase == "-linearattenuation")
10695 && anArgIt + 1 < theArgsNb)
10696 {
10697 const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10698 aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
10699 }
10700 else if (!aLightNew.IsNull()
10701 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10702 && (anArgCase == "-spotexp"
10703 || anArgCase == "-spotexponent"
10704 || anArgCase == "-exp"
10705 || anArgCase == "-exponent")
10706 && anArgIt + 1 < theArgsNb)
10707 {
10708 aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
10709 }
10710 else if (!aLightNew.IsNull()
10711 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10712 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
10713 && anArgCase == "-range"
10714 && anArgIt + 1 < theArgsNb)
10715 {
10716 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
10717 aLightNew->SetRange (aRange);
10718 }
10719 else if (!aLightNew.IsNull()
10720 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10721 && (anArgCase == "-head"
10722 || anArgCase == "-headlight"))
12381341 10723 {
06d40093 10724 Standard_Boolean isHeadLight = Standard_True;
10725 if (anArgIt + 1 < theArgsNb
10726 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 10727 {
06d40093 10728 ++anArgIt;
12381341 10729 }
06d40093 10730 aLightNew->SetHeadlight (isHeadLight);
12381341 10731 }
06d40093 10732 else if (!aLightNew.IsNull()
10733 && anArgCase == "-name"
10734 && anArgIt + 1 < theArgsNb)
12381341 10735 {
06d40093 10736 const TCollection_AsciiString aName = theArgVec[++anArgIt];
10737 if (aLightNew->Name() == aName)
12381341 10738 {
06d40093 10739 continue;
12381341 10740 }
10741
06d40093 10742 if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
12381341 10743 {
06d40093 10744 theDi << "Syntax error: light with name '" << aName << "' is already defined";
12381341 10745 return 1;
10746 }
06d40093 10747 aLightNew->SetName (aName);
12381341 10748 }
06d40093 10749 else if (!aLightPrs.IsNull()
10750 && (anArgCase == "-showzoomable"
10751 || anArgCase == "-prszoomable"
10752 || anArgCase == "-zoomable"))
88b312d3 10753 {
06d40093 10754 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10755 aLightPrs->SetZoomable (isZoomable);
10756 }
10757 else if (!aLightPrs.IsNull()
10758 && (anArgCase == "-showname"
10759 || anArgCase == "-prsname"))
10760 {
10761 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10762 aLightPrs->SetDisplayName (toDisplay);
88b312d3 10763 }
06d40093 10764 else if (!aLightPrs.IsNull()
10765 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10766 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10767 && (anArgCase == "-showrange"
10768 || anArgCase == "-prsrange"))
12381341 10769 {
06d40093 10770 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10771 aLightPrs->SetDisplayRange (toDisplay);
10772 }
10773 else if (!aLightPrs.IsNull()
10774 && (anArgCase == "-showsize"
10775 || anArgCase == "-prssize")
10776 && anArgIt + 1 < theArgsNb)
10777 {
10778 Standard_Real aSize = 0.0;
10779 if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
10780 || aSize <= 0.0
10781 || aLightPrs.IsNull())
12381341 10782 {
23fe70ec 10783 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10784 return 1;
10785 }
10786
06d40093 10787 aLightPrs->SetSize (aSize);
10788 }
10789 else if (!aLightNew.IsNull()
10790 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10791 && (anArgCase == "-castshadow"
10792 || anArgCase == "-castshadows"
10793 || anArgCase == "-shadows"))
10794 {
10795 bool toCastShadows = true;
992ed6b3 10796 if (anArgIt + 1 < theArgsNb
06d40093 10797 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
12381341 10798 {
992ed6b3 10799 ++anArgIt;
12381341 10800 }
06d40093 10801 aLightNew->SetCastShadows (toCastShadows);
12381341 10802 }
06d40093 10803 else if (anArgCase == "-del"
10804 || anArgCase == "-delete"
10805 || anArgCase == "-remove"
10806 || anArgCase == "del"
10807 || anArgCase == "delete"
10808 || anArgCase == "remove")
2daa5d95 10809 {
06d40093 10810 if (aLightOld.IsNull())
2daa5d95 10811 {
06d40093 10812 if (!aLightNew.IsNull())
10813 {
10814 aLightNew.Nullify();
10815 continue;
10816 }
10817
10818 if (++anArgIt >= theArgsNb)
10819 {
10820 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10821 return 1;
10822 }
10823
10824 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10825 aLightOld = findLightSource (anOldName);
10826 if (aLightOld.IsNull())
10827 {
10828 Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
10829 continue;
10830 }
2daa5d95 10831 }
06d40093 10832
10833 aLightNew.Nullify();
10834 aLightPrs.Nullify();
2daa5d95 10835 }
06d40093 10836 else if (anArgCase == "-change"
10837 || anArgCase == "change")
2daa5d95 10838 {
06d40093 10839 // just skip old syntax
2daa5d95 10840 }
06d40093 10841 else if (aLightNew.IsNull()
10842 && !anArgCase.StartsWith ("-"))
2daa5d95 10843 {
06d40093 10844 if (!aLightNew.IsNull())
2daa5d95 10845 {
06d40093 10846 continue;
2daa5d95 10847 }
10848
06d40093 10849 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10850 aLightOld = findLightSource (anOldName);
10851 if (!aLightOld.IsNull())
2daa5d95 10852 {
06d40093 10853 aLightNew = aLightOld;
10854
10855 Handle(AIS_InteractiveObject) aPrsObject;
10856 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10857 aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
2daa5d95 10858 }
10859 else
10860 {
06d40093 10861 Standard_Integer aLightIndex = -1;
10862 Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
10863 if (aLightIndex != -1)
10864 {
10865 Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
10866 return 1;
10867 }
10868
10869 aLightNew = new V3d_AmbientLight();
10870 aLightNew->SetName (anOldName);
2daa5d95 10871 }
10872 }
06d40093 10873 else
2daa5d95 10874 {
06d40093 10875 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
10876 return 1;
10877 }
10878 }
2daa5d95 10879
06d40093 10880 // delete old light source
10881 if (!aLightOld.IsNull()
10882 && aLightOld != aLightNew)
10883 {
10884 TColStd_SequenceOfInteger aLayers;
10885 aViewer->GetAllZLayers (aLayers);
10886 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
10887 {
10888 if (aLayerIter.Value() == aLayer
10889 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
2daa5d95 10890 {
06d40093 10891 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
10892 if (!aSettings.Lights().IsNull())
10893 {
10894 aSettings.Lights()->Remove (aLightOld);
10895 if (aSettings.Lights()->IsEmpty())
10896 {
10897 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10898 }
10899 }
10900 aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
10901 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10902 {
10903 break;
10904 }
2daa5d95 10905 }
10906 }
06d40093 10907
10908 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
2daa5d95 10909 {
06d40093 10910 Handle(AIS_InteractiveObject) aPrsObject;
10911 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10912 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
2daa5d95 10913 {
06d40093 10914 aCtx->Remove (aLightSourceDel, false);
10915 GetMapOfAIS().UnBind1 (aLightSourceDel);
2daa5d95 10916 }
06d40093 10917 aViewer->DelLight (aLightOld);
10918 }
10919 aLightOld.Nullify();
10920 }
2daa5d95 10921
06d40093 10922 // add new light source
10923 if (!aLightNew.IsNull())
10924 {
10925 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10926 {
10927 aViewer->AddLight (aLightNew);
10928 if (isGlobal)
2daa5d95 10929 {
06d40093 10930 aViewer->SetLightOn (aLightNew);
2daa5d95 10931 }
10932 else
10933 {
06d40093 10934 aView->SetLightOn (aLightNew);
2daa5d95 10935 }
10936 }
06d40093 10937 else
d84e8669 10938 {
06d40093 10939 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
10940 if (aSettings.Lights().IsNull())
d84e8669 10941 {
06d40093 10942 aSettings.SetLights (new Graphic3d_LightSet());
d84e8669 10943 }
06d40093 10944 aSettings.Lights()->Add (aLightNew);
10945 aViewer->SetZLayerSettings (aLayer, aSettings);
d84e8669 10946 }
06d40093 10947
10948 if (!aLightPrs.IsNull())
12381341 10949 {
06d40093 10950 aLightPrs->SetLight (aLightNew);
10951 ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
12381341 10952 }
10953 }
10954
06d40093 10955 // manage presentations
2daa5d95 10956 struct LightPrsSort
10957 {
10958 bool operator() (const Handle(AIS_LightSource)& theLeft,
10959 const Handle(AIS_LightSource)& theRight)
10960 {
10961 return theLeft->Light()->GetId() < theRight->Light()->GetId();
10962 }
10963 };
10964
10965 AIS_ListOfInteractive aPrsList;
06d40093 10966 aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
2daa5d95 10967 if (!aPrsList.IsEmpty())
10968 {
10969 // update light source presentations
10970 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
10971 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
10972 {
06d40093 10973 if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
2daa5d95 10974 {
06d40093 10975 aLightPrsVec.push_back (aLightPrs2);
2daa5d95 10976 }
10977 }
10978
10979 // sort objects by id as AIS_InteractiveContext stores them in unordered map
10980 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
10981
10982 Standard_Integer aTopStack = 0;
10983 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
10984 {
06d40093 10985 Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
10986 if (!aLightPrs2->TransformPersistence().IsNull()
10987 && aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
2daa5d95 10988 {
06d40093 10989 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
10990 aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
2daa5d95 10991 aTopStack += aPrsSize + aPrsSize / 2;
10992 }
06d40093 10993 aCtx->Redisplay (aLightPrs2, false);
10994 aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
2daa5d95 10995 }
10996 }
12381341 10997 return 0;
10998}
10999
67312b79 11000//===============================================================================================
11001//function : VPBREnvironment
11002//purpose :
11003//===============================================================================================
11004static int VPBREnvironment (Draw_Interpretor&,
11005 Standard_Integer theArgsNb,
11006 const char** theArgVec)
11007{
11008 if (theArgsNb > 2)
11009 {
23fe70ec 11010 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11011 return 1;
11012 }
11013
11014 Handle(V3d_View) aView = ViewerTest::CurrentView();
11015 if (aView.IsNull())
11016 {
23fe70ec 11017 Message::SendFail ("Error: no active viewer");
67312b79 11018 return 1;
11019 }
11020
11021 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11022 anArg.LowerCase();
11023
11024 if (anArg == "-generate"
11025 || anArg == "-gen")
11026 {
11027 aView->GeneratePBREnvironment (Standard_True);
11028 }
11029 else if (anArg == "-clear")
11030 {
11031 aView->ClearPBREnvironment (Standard_True);
11032 }
11033 else
11034 {
23fe70ec 11035 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11036 return 1;
11037 }
11038
11039 return 0;
11040}
11041
15669413 11042//! Read Graphic3d_RenderingParams::PerfCounters flag.
11043static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11044 Standard_Boolean& theToReset,
11045 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11046 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11047{
11048 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11049 TCollection_AsciiString aVal = theValue;
11050 Standard_Boolean toReverse = Standard_False;
11051 if (aVal == "none")
11052 {
11053 theToReset = Standard_True;
11054 return Standard_True;
11055 }
11056 else if (aVal.StartsWith ("-"))
11057 {
11058 toReverse = Standard_True;
11059 aVal = aVal.SubString (2, aVal.Length());
11060 }
11061 else if (aVal.StartsWith ("no"))
11062 {
11063 toReverse = Standard_True;
11064 aVal = aVal.SubString (3, aVal.Length());
11065 }
11066 else if (aVal.StartsWith ("+"))
11067 {
11068 aVal = aVal.SubString (2, aVal.Length());
11069 }
11070 else
11071 {
11072 theToReset = Standard_True;
11073 }
11074
11075 if ( aVal == "fps"
11076 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11077 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11078 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11079 else if (aVal == "structs"
11080 || aVal == "structures"
11081 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11082 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11083 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11084 else if (aVal == "tris"
11085 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11086 else if (aVal == "pnts"
11087 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11088 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11089 else if (aVal == "mem"
11090 || aVal == "gpumem"
11091 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11092 else if (aVal == "skipimmediate"
11093 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11094 else if (aVal == "frametime"
11095 || aVal == "frametimers"
11096 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11097 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11098 else if (aVal == "extended"
11099 || aVal == "verbose"
11100 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11101 else if (aVal == "full"
11102 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11103 else
11104 {
11105 return Standard_False;
11106 }
11107
11108 if (toReverse)
11109 {
11110 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11111 }
11112 else
11113 {
11114 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11115 }
11116 return Standard_True;
11117}
11118
11119//! Read Graphic3d_RenderingParams::PerfCounters flags.
11120static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11121 Graphic3d_RenderingParams::PerfCounters& theFlags)
11122{
11123 TCollection_AsciiString aValue = theValue;
11124 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11125 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11126 Standard_Boolean toReset = Standard_False;
11127 for (;;)
11128 {
11129 Standard_Integer aSplitPos = aValue.Search ("|");
11130 if (aSplitPos <= 0)
11131 {
11132 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11133 {
11134 return Standard_False;
11135 }
11136 if (toReset)
11137 {
11138 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11139 }
11140 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11141 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11142 return Standard_True;
11143 }
11144
11145 if (aSplitPos > 1)
11146 {
11147 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11148 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11149 {
11150 return Standard_False;
11151 }
11152 }
11153 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11154 }
11155}
11156
e276548b 11157//=======================================================================
bc8c79bb 11158//function : VRenderParams
11159//purpose : Enables/disables rendering features
e276548b 11160//=======================================================================
11161
bc8c79bb 11162static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11163 Standard_Integer theArgNb,
11164 const char** theArgVec)
e276548b 11165{
7ae4a307 11166 Handle(V3d_View) aView = ViewerTest::CurrentView();
11167 if (aView.IsNull())
e276548b 11168 {
23fe70ec 11169 Message::SendFail ("Error: no active viewer");
e276548b 11170 return 1;
11171 }
bc8c79bb 11172
11173 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11174 TCollection_AsciiString aCmdName (theArgVec[0]);
11175 aCmdName.LowerCase();
11176 if (aCmdName == "vraytrace")
11177 {
11178 if (theArgNb == 1)
11179 {
11180 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11181 return 0;
11182 }
11183 else if (theArgNb == 2)
11184 {
11185 TCollection_AsciiString aValue (theArgVec[1]);
11186 aValue.LowerCase();
11187 if (aValue == "on"
11188 || aValue == "1")
11189 {
11190 aParams.Method = Graphic3d_RM_RAYTRACING;
11191 aView->Redraw();
11192 return 0;
11193 }
11194 else if (aValue == "off"
11195 || aValue == "0")
11196 {
11197 aParams.Method = Graphic3d_RM_RASTERIZATION;
11198 aView->Redraw();
11199 return 0;
11200 }
11201 else
11202 {
23fe70ec 11203 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11204 return 1;
11205 }
11206 }
11207 else
11208 {
23fe70ec 11209 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11210 return 1;
11211 }
11212 }
bc8c79bb 11213
11214 if (theArgNb < 2)
e276548b 11215 {
bc8c79bb 11216 theDI << "renderMode: ";
11217 switch (aParams.Method)
11218 {
11219 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11220 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11221 }
11222 theDI << "\n";
a1073ae2 11223 theDI << "transparency: ";
11224 switch (aParams.TransparencyMethod)
11225 {
11226 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11227 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11228 << TCollection_AsciiString (aParams.OitDepthFactor); break;
78c4e836 11229 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11230 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
a1073ae2 11231 }
11232 theDI << "\n";
b4327ba8 11233 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11234 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11235 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11236 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11237 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
d84e8669 11238 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11239 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
b4327ba8 11240 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11241 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11242 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11243 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11244 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11245 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11246 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11247 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11248 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11249 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11250 theDI << "shadingModel: ";
11251 switch (aView->ShadingModel())
11252 {
67312b79 11253 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11254 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11255 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11256 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11257 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11258 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11259 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11260 }
37f80e16 11261 theDI << "\n";
15669413 11262 {
11263 theDI << "perfCounters:";
11264 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11265 {
11266 theDI << " fps";
11267 }
11268 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11269 {
11270 theDI << " cpu";
11271 }
11272 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11273 {
11274 theDI << " structs";
11275 }
11276 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11277 {
11278 theDI << " groups";
11279 }
11280 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11281 {
11282 theDI << " arrays";
11283 }
11284 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11285 {
11286 theDI << " tris";
11287 }
b9f43ad1 11288 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11289 {
11290 theDI << " lines";
11291 }
15669413 11292 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11293 {
11294 theDI << " pnts";
11295 }
11296 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11297 {
11298 theDI << " gpumem";
11299 }
5e30547b 11300 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11301 {
11302 theDI << " frameTime";
11303 }
11304 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11305 {
11306 theDI << " skipimmediate";
11307 }
15669413 11308 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11309 {
11310 theDI << " none";
11311 }
11312 theDI << "\n";
11313 }
f88457e6 11314 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11315 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11316 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11317 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11318 "noUpdate") << "\n";
8625ef7e 11319 theDI << "\n";
bc8c79bb 11320 return 0;
e276548b 11321 }
11322
4c7a3fae 11323 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11324 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11325 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11326 {
bc8c79bb 11327 Standard_CString anArg (theArgVec[anArgIter]);
11328 TCollection_AsciiString aFlag (anArg);
11329 aFlag.LowerCase();
8625ef7e 11330 if (anUpdateTool.parseRedrawMode (aFlag))
11331 {
11332 continue;
11333 }
11334 else if (aFlag == "-echo"
11335 || aFlag == "-print")
e276548b 11336 {
bc8c79bb 11337 toPrint = Standard_True;
8625ef7e 11338 anUpdateTool.Invalidate();
e276548b 11339 }
4c7a3fae 11340 else if (aFlag == "-reset")
11341 {
11342 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11343 }
11344 else if (aFlag == "-sync"
11345 && (anArgIter + 1 < theArgNb))
11346 {
11347 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11348 aSyncFlag.LowerCase();
11349 if (aSyncFlag == "default"
11350 || aSyncFlag == "defaults"
11351 || aSyncFlag == "viewer")
11352 {
11353 toSyncDefaults = true;
11354 }
11355 else if (aSyncFlag == "allviews"
11356 || aSyncFlag == "views")
11357 {
11358 toSyncAllViews = true;
11359 }
11360 else
11361 {
11362 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11363 return 1;
11364 }
11365 }
bc8c79bb 11366 else if (aFlag == "-mode"
11367 || aFlag == "-rendermode"
11368 || aFlag == "-render_mode")
e276548b 11369 {
bc8c79bb 11370 if (toPrint)
11371 {
11372 switch (aParams.Method)
11373 {
11374 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11375 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11376 }
11377 continue;
11378 }
e276548b 11379 else
bc8c79bb 11380 {
23fe70ec 11381 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11382 return 1;
11383 }
11384 }
11385 else if (aFlag == "-ray"
11386 || aFlag == "-raytrace")
11387 {
11388 if (toPrint)
11389 {
11390 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11391 continue;
11392 }
11393
4c7a3fae 11394 bool isRayTrace = true;
11395 if (anArgIter + 1 < theArgNb
dae2a922 11396 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11397 {
11398 ++anArgIter;
11399 }
11400 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11401 }
bc8c79bb 11402 else if (aFlag == "-rast"
11403 || aFlag == "-raster"
11404 || aFlag == "-rasterization")
e276548b 11405 {
bc8c79bb 11406 if (toPrint)
11407 {
11408 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11409 continue;
11410 }
11411
4c7a3fae 11412 bool isRaster = true;
11413 if (anArgIter + 1 < theArgNb
dae2a922 11414 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11415 {
11416 ++anArgIter;
11417 }
11418 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11419 }
3c4b62a4 11420 else if (aFlag == "-msaa")
11421 {
11422 if (toPrint)
11423 {
11424 theDI << aParams.NbMsaaSamples << " ";
11425 continue;
11426 }
11427 else if (++anArgIter >= theArgNb)
11428 {
23fe70ec 11429 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11430 return 1;
11431 }
11432
11433 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11434 if (aNbSamples < 0)
11435 {
23fe70ec 11436 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 11437 return 1;
11438 }
11439 else
11440 {
11441 aParams.NbMsaaSamples = aNbSamples;
11442 }
11443 }
2a332745 11444 else if (aFlag == "-linefeather"
11445 || aFlag == "-edgefeather"
11446 || aFlag == "-feather")
11447 {
11448 if (toPrint)
11449 {
11450 theDI << " " << aParams.LineFeather << " ";
11451 continue;
11452 }
11453 else if (++anArgIter >= theArgNb)
11454 {
23fe70ec 11455 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 11456 return 1;
11457 }
11458
11459 TCollection_AsciiString aParam = theArgVec[anArgIter];
11460 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11461 if (aFeather <= 0.0f)
11462 {
23fe70ec 11463 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 11464 return 1;
11465 }
11466 aParams.LineFeather = aFeather;
11467 }
a1073ae2 11468 else if (aFlag == "-oit")
11469 {
11470 if (toPrint)
11471 {
11472 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11473 {
11474 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11475 }
78c4e836 11476 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11477 {
11478 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11479 }
a1073ae2 11480 else
11481 {
11482 theDI << "off" << " ";
11483 }
11484 continue;
11485 }
11486 else if (++anArgIter >= theArgNb)
11487 {
23fe70ec 11488 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11489 return 1;
11490 }
11491
11492 TCollection_AsciiString aParam = theArgVec[anArgIter];
11493 aParam.LowerCase();
78c4e836 11494 if (aParam == "peeling"
11495 || aParam == "peel")
11496 {
11497 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11498 if (anArgIter + 1 < theArgNb
11499 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11500 {
11501 ++anArgIter;
11502 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11503 if (aNbLayers < 2)
11504 {
11505 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11506 return 1;
11507 }
11508 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11509 }
11510 }
11511 else if (aParam == "weighted"
11512 || aParam == "weight")
11513 {
11514 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11515 if (anArgIter + 1 < theArgNb
11516 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11517 {
11518 ++anArgIter;
11519 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11520 if (aWeight < 0.f || aWeight > 1.f)
11521 {
11522 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11523 return 1;
11524 }
11525 aParams.OitDepthFactor = aWeight;
11526 }
11527 }
11528 else if (aParam.IsRealValue())
a1073ae2 11529 {
11530 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11531 if (aWeight < 0.f || aWeight > 1.f)
11532 {
23fe70ec 11533 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 11534 return 1;
11535 }
11536
11537 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11538 aParams.OitDepthFactor = aWeight;
11539 }
11540 else if (aParam == "off")
11541 {
11542 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11543 }
11544 else
11545 {
23fe70ec 11546 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11547 return 1;
11548 }
11549 }
d37aef5c 11550 else if (aFlag == "-fonthinting"
11551 || aFlag == "-fonthint")
11552 {
11553 if (toPrint)
11554 {
11555 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11556 {
11557 theDI << "normal" << " ";
11558 }
11559 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11560 {
11561 theDI << "light" << " ";
11562 }
11563 else
11564 {
11565 theDI << "off" << " ";
11566 }
11567 continue;
11568 }
11569 else if (anArgIter + 1 >= theArgNb)
11570 {
11571 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11572 return 1;
11573 }
11574
11575 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11576 aHintStyle.LowerCase();
11577 if (aHintStyle == "normal"
11578 || aHintStyle == "on"
11579 || aHintStyle == "1")
11580 {
11581 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11582 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11583 }
11584 else if (aHintStyle == "light")
11585 {
11586 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11587 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11588 }
11589 else if (aHintStyle == "no"
11590 || aHintStyle == "off"
11591 || aHintStyle == "0")
11592 {
11593 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11594 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11595 }
11596 else
11597 {
11598 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11599 return 1;
11600 }
11601 }
11602 else if (aFlag == "-fontautohinting"
11603 || aFlag == "-fontautohint")
11604 {
11605 if (toPrint)
11606 {
11607 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11608 {
11609 theDI << "force" << " ";
11610 }
11611 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11612 {
11613 theDI << "disallow" << " ";
11614 }
11615 else
11616 {
11617 theDI << "auto" << " ";
11618 }
11619 continue;
11620 }
11621 else if (anArgIter + 1 >= theArgNb)
11622 {
11623 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11624 return 1;
11625 }
11626
11627 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11628 aHintStyle.LowerCase();
11629 if (aHintStyle == "force")
11630 {
11631 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11632 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11633 }
11634 else if (aHintStyle == "disallow"
11635 || aHintStyle == "no")
11636 {
11637 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11638 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11639 }
11640 else if (aHintStyle == "auto")
11641 {
11642 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11643 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11644 }
11645 else
11646 {
11647 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11648 return 1;
11649 }
11650 }
f88457e6 11651 else if (aFlag == "-depthprepass")
11652 {
11653 if (toPrint)
11654 {
11655 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11656 continue;
11657 }
11658 aParams.ToEnableDepthPrepass = Standard_True;
11659 if (anArgIter + 1 < theArgNb
dae2a922 11660 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 11661 {
11662 ++anArgIter;
11663 }
11664 }
c40eb6b9 11665 else if (aFlag == "-samplealphatocoverage"
11666 || aFlag == "-alphatocoverage")
11667 {
11668 if (toPrint)
11669 {
11670 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11671 continue;
11672 }
11673 aParams.ToEnableAlphaToCoverage = Standard_True;
11674 if (anArgIter + 1 < theArgNb
dae2a922 11675 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 11676 {
11677 ++anArgIter;
11678 }
11679 }
56689b27 11680 else if (aFlag == "-rendscale"
11681 || aFlag == "-renderscale"
11682 || aFlag == "-renderresolutionscale")
11683 {
11684 if (toPrint)
11685 {
11686 theDI << aParams.RenderResolutionScale << " ";
11687 continue;
11688 }
11689 else if (++anArgIter >= theArgNb)
11690 {
23fe70ec 11691 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 11692 return 1;
11693 }
11694
11695 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11696 if (aScale < 0.01)
11697 {
23fe70ec 11698 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 11699 return 1;
11700 }
11701 else
11702 {
11703 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11704 }
11705 }
bc8c79bb 11706 else if (aFlag == "-raydepth"
11707 || aFlag == "-ray_depth")
11708 {
11709 if (toPrint)
11710 {
11711 theDI << aParams.RaytracingDepth << " ";
11712 continue;
11713 }
11714 else if (++anArgIter >= theArgNb)
11715 {
23fe70ec 11716 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11717 return 1;
11718 }
11719
11720 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 11721
11722 // We allow RaytracingDepth be more than 10 in case of GI enabled
11723 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 11724 {
23fe70ec 11725 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 11726 return 1;
11727 }
e276548b 11728 else
bc8c79bb 11729 {
11730 aParams.RaytracingDepth = aDepth;
11731 }
11732 }
11733 else if (aFlag == "-shad"
11734 || aFlag == "-shadows")
11735 {
11736 if (toPrint)
11737 {
11738 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11739 continue;
11740 }
11741
11742 Standard_Boolean toEnable = Standard_True;
11743 if (++anArgIter < theArgNb
dae2a922 11744 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11745 {
11746 --anArgIter;
11747 }
11748 aParams.IsShadowEnabled = toEnable;
11749 }
d84e8669 11750 else if (aFlag == "-shadowmapresolution"
11751 || aFlag == "-shadowmap")
11752 {
11753 if (toPrint)
11754 {
11755 theDI << aParams.ShadowMapResolution << " ";
11756 continue;
11757 }
11758 else if (++anArgIter >= theArgNb)
11759 {
11760 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11761 return 1;
11762 }
11763
11764 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11765 }
11766 else if (aFlag == "-shadowmapbias")
11767 {
11768 if (toPrint)
11769 {
11770 theDI << aParams.ShadowMapBias << " ";
11771 continue;
11772 }
11773 else if (++anArgIter >= theArgNb)
11774 {
11775 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11776 return 1;
11777 }
11778
11779 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11780 }
bc8c79bb 11781 else if (aFlag == "-refl"
11782 || aFlag == "-reflections")
11783 {
11784 if (toPrint)
11785 {
11786 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11787 continue;
11788 }
11789
11790 Standard_Boolean toEnable = Standard_True;
11791 if (++anArgIter < theArgNb
dae2a922 11792 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11793 {
11794 --anArgIter;
11795 }
11796 aParams.IsReflectionEnabled = toEnable;
11797 }
11798 else if (aFlag == "-fsaa")
11799 {
11800 if (toPrint)
11801 {
11802 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11803 continue;
11804 }
11805
11806 Standard_Boolean toEnable = Standard_True;
11807 if (++anArgIter < theArgNb
dae2a922 11808 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11809 {
11810 --anArgIter;
11811 }
11812 aParams.IsAntialiasingEnabled = toEnable;
11813 }
11814 else if (aFlag == "-gleam")
11815 {
11816 if (toPrint)
11817 {
11818 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11819 continue;
11820 }
11821
11822 Standard_Boolean toEnable = Standard_True;
11823 if (++anArgIter < theArgNb
dae2a922 11824 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11825 {
11826 --anArgIter;
11827 }
11828 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 11829 }
189f85a3 11830 else if (aFlag == "-gi")
11831 {
11832 if (toPrint)
11833 {
11834 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11835 continue;
11836 }
11837
11838 Standard_Boolean toEnable = Standard_True;
11839 if (++anArgIter < theArgNb
dae2a922 11840 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 11841 {
11842 --anArgIter;
11843 }
11844 aParams.IsGlobalIlluminationEnabled = toEnable;
11845 if (!toEnable)
11846 {
11847 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11848 }
11849 }
8c820969 11850 else if (aFlag == "-blockedrng"
11851 || aFlag == "-brng")
11852 {
11853 if (toPrint)
11854 {
11855 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11856 continue;
11857 }
11858
11859 Standard_Boolean toEnable = Standard_True;
11860 if (++anArgIter < theArgNb
dae2a922 11861 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 11862 {
11863 --anArgIter;
11864 }
11865 aParams.CoherentPathTracingMode = toEnable;
11866 }
b09447ed 11867 else if (aFlag == "-maxrad")
11868 {
11869 if (toPrint)
11870 {
11871 theDI << aParams.RadianceClampingValue << " ";
11872 continue;
11873 }
11874 else if (++anArgIter >= theArgNb)
11875 {
23fe70ec 11876 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11877 return 1;
11878 }
11879
11880 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
d45edf24 11881 if (!aMaxRadStr.IsRealValue (Standard_True))
b09447ed 11882 {
23fe70ec 11883 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11884 return 1;
11885 }
11886
11887 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11888 if (aMaxRadiance <= 0.0)
11889 {
23fe70ec 11890 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 11891 return 1;
11892 }
11893 else
11894 {
11895 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11896 }
11897 }
3a9b5dc8 11898 else if (aFlag == "-iss")
11899 {
11900 if (toPrint)
11901 {
11902 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11903 continue;
11904 }
11905
11906 Standard_Boolean toEnable = Standard_True;
11907 if (++anArgIter < theArgNb
dae2a922 11908 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 11909 {
11910 --anArgIter;
11911 }
11912 aParams.AdaptiveScreenSampling = toEnable;
11913 }
e084dbbc 11914 else if (aFlag == "-issatomic")
11915 {
11916 if (toPrint)
11917 {
11918 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
11919 continue;
11920 }
11921
11922 Standard_Boolean toEnable = Standard_True;
11923 if (++anArgIter < theArgNb
dae2a922 11924 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 11925 {
11926 --anArgIter;
11927 }
11928 aParams.AdaptiveScreenSamplingAtomic = toEnable;
11929 }
3a9b5dc8 11930 else if (aFlag == "-issd")
11931 {
11932 if (toPrint)
11933 {
11934 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
11935 continue;
11936 }
11937
11938 Standard_Boolean toEnable = Standard_True;
11939 if (++anArgIter < theArgNb
dae2a922 11940 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 11941 {
11942 --anArgIter;
11943 }
11944 aParams.ShowSamplingTiles = toEnable;
11945 }
66d1cdc6 11946 else if (aFlag == "-tilesize")
11947 {
11948 if (toPrint)
11949 {
11950 theDI << aParams.RayTracingTileSize << " ";
11951 continue;
11952 }
11953 else if (++anArgIter >= theArgNb)
11954 {
23fe70ec 11955 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 11956 return 1;
11957 }
11958
11959 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
11960 if (aTileSize < 1)
11961 {
23fe70ec 11962 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 11963 return 1;
11964 }
11965 aParams.RayTracingTileSize = aTileSize;
11966 }
4eaaf9d8 11967 else if (aFlag == "-nbtiles")
11968 {
11969 if (toPrint)
11970 {
11971 theDI << aParams.NbRayTracingTiles << " ";
11972 continue;
11973 }
11974 else if (++anArgIter >= theArgNb)
11975 {
23fe70ec 11976 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 11977 return 1;
11978 }
11979
11980 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 11981 if (aNbTiles < -1)
4eaaf9d8 11982 {
23fe70ec 11983 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 11984 return 1;
11985 }
66d1cdc6 11986 else if (aNbTiles > 0
11987 && (aNbTiles < 64
11988 || aNbTiles > 1024))
4eaaf9d8 11989 {
23fe70ec 11990 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 11991 }
66d1cdc6 11992 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 11993 }
189f85a3 11994 else if (aFlag == "-env")
11995 {
11996 if (toPrint)
11997 {
11998 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
11999 continue;
12000 }
12001
12002 Standard_Boolean toEnable = Standard_True;
12003 if (++anArgIter < theArgNb
dae2a922 12004 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12005 {
12006 --anArgIter;
12007 }
12008 aParams.UseEnvironmentMapBackground = toEnable;
12009 }
78607702 12010 else if (aFlag == "-ignorenormalmap")
12011 {
12012 if (toPrint)
12013 {
12014 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12015 continue;
12016 }
12017
12018 Standard_Boolean toEnable = Standard_True;
12019 if (++anArgIter < theArgNb
dae2a922 12020 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12021 {
12022 --anArgIter;
12023 }
12024 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12025 }
b4327ba8 12026 else if (aFlag == "-twoside")
12027 {
12028 if (toPrint)
12029 {
12030 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12031 continue;
12032 }
12033
12034 Standard_Boolean toEnable = Standard_True;
12035 if (++anArgIter < theArgNb
dae2a922 12036 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12037 {
12038 --anArgIter;
12039 }
12040 aParams.TwoSidedBsdfModels = toEnable;
12041 }
8625ef7e 12042 else if (aFlag == "-shademodel"
12043 || aFlag == "-shadingmodel"
12044 || aFlag == "-shading")
12045 {
12046 if (toPrint)
12047 {
12048 switch (aView->ShadingModel())
12049 {
67312b79 12050 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12051 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12052 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12053 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12054 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12055 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12056 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12057 }
12058 continue;
12059 }
12060
12061 if (++anArgIter >= theArgNb)
12062 {
23fe70ec 12063 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12064 }
12065
dc89236f 12066 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12067 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12068 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12069 {
dc89236f 12070 aView->SetShadingModel (aModel);
8625ef7e 12071 }
12072 else
12073 {
23fe70ec 12074 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12075 return 1;
12076 }
12077 }
67312b79 12078 else if (aFlag == "-pbrenvpow2size"
12079 || aFlag == "-pbrenvp2s"
12080 || aFlag == "-pep2s")
12081 {
12082 if (++anArgIter >= theArgNb)
12083 {
23fe70ec 12084 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12085 return 1;
12086 }
12087
12088 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12089 if (aPbrEnvPow2Size < 1)
12090 {
23fe70ec 12091 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12092 return 1;
12093 }
12094 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12095 }
12096 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12097 || aFlag == "-pbrenvspecmapnblevels"
12098 || aFlag == "-pbrenvspecmaplevels"
12099 || aFlag == "-pbrenvsmln"
12100 || aFlag == "-pesmln")
12101 {
12102 if (++anArgIter >= theArgNb)
12103 {
23fe70ec 12104 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12105 return 1;
12106 }
12107
12108 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12109 if (aPbrEnvSpecMapNbLevels < 2)
12110 {
23fe70ec 12111 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12112 return 1;
12113 }
12114 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12115 }
12116 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12117 || aFlag == "-pbrenvbakingdiffsamples"
12118 || aFlag == "-pbrenvbdsn")
12119 {
12120 if (++anArgIter >= theArgNb)
12121 {
23fe70ec 12122 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12123 return 1;
12124 }
12125
12126 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12127 if (aPbrEnvBakingDiffNbSamples < 1)
12128 {
4551e1be 12129 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12130 return 1;
12131 }
12132 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12133 }
12134 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12135 || aFlag == "-pbrenvbakingspecsamples"
12136 || aFlag == "-pbrenvbssn")
12137 {
12138 if (++anArgIter >= theArgNb)
12139 {
23fe70ec 12140 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12141 return 1;
12142 }
12143
12144 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12145 if (aPbrEnvBakingSpecNbSamples < 1)
12146 {
4551e1be 12147 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12148 return 1;
12149 }
12150 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12151 }
12152 else if (aFlag == "-pbrenvbakingprobability"
12153 || aFlag == "-pbrenvbp")
12154 {
12155 if (++anArgIter >= theArgNb)
12156 {
23fe70ec 12157 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12158 return 1;
12159 }
12160 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12161 if (aPbrEnvBakingProbability < 0.f
12162 || aPbrEnvBakingProbability > 1.f)
12163 {
4551e1be 12164 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
67312b79 12165 return 1;
12166 }
12167 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12168 }
4b1c8733 12169 else if (aFlag == "-resolution")
12170 {
12171 if (++anArgIter >= theArgNb)
12172 {
23fe70ec 12173 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12174 return 1;
12175 }
12176
12177 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12178 if (aResolution.IsIntegerValue())
12179 {
12180 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12181 }
12182 else
12183 {
23fe70ec 12184 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12185 return 1;
12186 }
12187 }
d877e610 12188 else if (aFlag == "-rebuildglsl"
12189 || aFlag == "-rebuild")
12190 {
12191 if (toPrint)
12192 {
12193 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12194 continue;
12195 }
12196
12197 Standard_Boolean toEnable = Standard_True;
12198 if (++anArgIter < theArgNb
dae2a922 12199 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12200 {
12201 --anArgIter;
12202 }
12203 aParams.RebuildRayTracingShaders = toEnable;
12204 }
b27ab03d 12205 else if (aFlag == "-focal")
12206 {
12207 if (++anArgIter >= theArgNb)
12208 {
23fe70ec 12209 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12210 return 1;
12211 }
12212
12213 TCollection_AsciiString aParam (theArgVec[anArgIter]);
d45edf24 12214 if (aParam.IsRealValue (Standard_True))
b27ab03d 12215 {
12216 float aFocalDist = static_cast<float> (aParam.RealValue());
12217 if (aFocalDist < 0)
12218 {
23fe70ec 12219 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12220 return 1;
12221 }
12222 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12223 }
12224 else
12225 {
23fe70ec 12226 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12227 return 1;
12228 }
12229 }
12230 else if (aFlag == "-aperture")
12231 {
12232 if (++anArgIter >= theArgNb)
12233 {
23fe70ec 12234 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12235 return 1;
12236 }
12237
12238 TCollection_AsciiString aParam(theArgVec[anArgIter]);
d45edf24 12239 if (aParam.IsRealValue (Standard_True))
b27ab03d 12240 {
12241 float aApertureSize = static_cast<float> (aParam.RealValue());
12242 if (aApertureSize < 0)
12243 {
23fe70ec 12244 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12245 return 1;
12246 }
12247 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12248 }
12249 else
12250 {
23fe70ec 12251 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12252 return 1;
12253 }
12254 }
eb85ed36 12255 else if (aFlag == "-exposure")
12256 {
12257 if (++anArgIter >= theArgNb)
12258 {
23fe70ec 12259 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12260 return 1;
12261 }
12262
12263 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
d45edf24 12264 if (anExposure.IsRealValue (Standard_True))
eb85ed36 12265 {
12266 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12267 }
12268 else
12269 {
23fe70ec 12270 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12271 return 1;
12272 }
12273 }
12274 else if (aFlag == "-whitepoint")
12275 {
12276 if (++anArgIter >= theArgNb)
12277 {
23fe70ec 12278 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12279 return 1;
12280 }
12281
12282 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
d45edf24 12283 if (aWhitePoint.IsRealValue (Standard_True))
eb85ed36 12284 {
12285 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12286 }
12287 else
12288 {
23fe70ec 12289 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12290 return 1;
12291 }
12292 }
12293 else if (aFlag == "-tonemapping")
12294 {
12295 if (++anArgIter >= theArgNb)
12296 {
23fe70ec 12297 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12298 return 1;
12299 }
12300
12301 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12302 aMode.LowerCase();
12303
12304 if (aMode == "disabled")
12305 {
12306 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12307 }
12308 else if (aMode == "filmic")
12309 {
12310 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12311 }
12312 else
12313 {
23fe70ec 12314 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12315 return 1;
12316 }
12317 }
15669413 12318 else if (aFlag == "-performancestats"
12319 || aFlag == "-performancecounters"
12320 || aFlag == "-perfstats"
12321 || aFlag == "-perfcounters"
12322 || aFlag == "-stats")
12323 {
12324 if (++anArgIter >= theArgNb)
12325 {
23fe70ec 12326 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12327 return 1;
12328 }
12329
12330 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12331 aFlagsStr.LowerCase();
12332 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12333 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12334 {
23fe70ec 12335 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12336 return 1;
12337 }
12338 aView->ChangeRenderingParams().CollectedStats = aFlags;
12339 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12340 }
12341 else if (aFlag == "-perfupdateinterval"
12342 || aFlag == "-statsupdateinterval")
12343 {
12344 if (++anArgIter >= theArgNb)
12345 {
23fe70ec 12346 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12347 return 1;
12348 }
12349 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12350 }
5e30547b 12351 else if (aFlag == "-perfchart"
12352 || aFlag == "-statschart")
12353 {
12354 if (++anArgIter >= theArgNb)
12355 {
23fe70ec 12356 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12357 return 1;
12358 }
12359 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12360 }
12361 else if (aFlag == "-perfchartmax"
12362 || aFlag == "-statschartmax")
12363 {
12364 if (++anArgIter >= theArgNb)
12365 {
23fe70ec 12366 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12367 return 1;
12368 }
12369 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12370 }
0e3025bc 12371 else if (aFlag == "-frustumculling"
12372 || aFlag == "-culling")
12373 {
12374 if (toPrint)
12375 {
12376 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12377 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12378 "noUpdate") << " ";
12379 continue;
12380 }
12381
12382 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12383 if (++anArgIter < theArgNb)
12384 {
12385 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12386 aStateStr.LowerCase();
12387 bool toEnable = true;
dae2a922 12388 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12389 {
12390 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12391 }
12392 else if (aStateStr == "noupdate"
12393 || aStateStr == "freeze")
12394 {
12395 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12396 }
12397 else
12398 {
12399 --anArgIter;
12400 }
12401 }
12402 aParams.FrustumCullingState = aState;
12403 }
e276548b 12404 else
12405 {
23fe70ec 12406 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12407 return 1;
e276548b 12408 }
12409 }
189f85a3 12410
4c7a3fae 12411 // set current view parameters as defaults
12412 if (toSyncDefaults)
12413 {
12414 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12415 }
12416 if (toSyncAllViews)
12417 {
12418 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12419 {
12420 aViewIter.Value()->ChangeRenderingParams() = aParams;
12421 }
12422 }
189f85a3 12423 return 0;
12424}
12425
79b544e6 12426//=======================================================================
12427//function : searchInfo
12428//purpose :
12429//=======================================================================
12430inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12431 const TCollection_AsciiString& theKey)
12432{
12433 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12434 {
12435 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12436 {
12437 return anIter.Value();
12438 }
12439 }
12440 return TCollection_AsciiString();
12441}
12442
12443//=======================================================================
12444//function : VStatProfiler
12445//purpose :
12446//=======================================================================
12447static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12448 Standard_Integer theArgNb,
12449 const char** theArgVec)
12450{
12451 Handle(V3d_View) aView = ViewerTest::CurrentView();
12452 if (aView.IsNull())
12453 {
23fe70ec 12454 Message::SendFail ("Error: no active viewer");
79b544e6 12455 return 1;
12456 }
12457
12458 Standard_Boolean toRedraw = Standard_True;
12459 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12460 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12461 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12462 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12463 {
12464 Standard_CString anArg (theArgVec[anArgIter]);
12465 TCollection_AsciiString aFlag (anArg);
12466 aFlag.LowerCase();
12467 if (aFlag == "-noredraw")
12468 {
12469 toRedraw = Standard_False;
12470 }
12471 else
12472 {
12473 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12474 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12475 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12476 else if (aFlag == "alllayers"
12477 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12478 else if (aFlag == "allstructs"
a2803f37 12479 || aFlag == "allstructures"
12480 || aFlag == "structs"
12481 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12482 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12483 else if (aFlag == "allarrays"
12484 || aFlag == "fillarrays"
12485 || aFlag == "linearrays"
12486 || aFlag == "pointarrays"
12487 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12488 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12489 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12490 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12491 else if (aFlag == "geommem"
12492 || aFlag == "texturemem"
12493 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12494 else if (aFlag == "elapsedframe"
12495 || aFlag == "cpuframeaverage"
12496 || aFlag == "cpupickingaverage"
12497 || aFlag == "cpucullingaverage"
12498 || aFlag == "cpudynaverage"
12499 || aFlag == "cpuframemax"
12500 || aFlag == "cpupickingmax"
12501 || aFlag == "cpucullingmax"
12502 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12503 else
12504 {
23fe70ec 12505 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12506 continue;
12507 }
12508
12509 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12510 }
12511 }
12512
12513 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12514 {
12515 aView->ChangeRenderingParams().CollectedStats =
12516 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12517
12518 if (toRedraw)
12519 {
12520 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12521 aView->Redraw();
12522 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12523 }
12524
12525 TColStd_IndexedDataMapOfStringString aDict;
12526 aView->StatisticInformation (aDict);
12527
12528 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12529
12530 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12531 {
12532 Standard_CString anArg(theArgVec[anArgIter]);
12533 TCollection_AsciiString aFlag(anArg);
12534 aFlag.LowerCase();
12535 if (aFlag == "fps")
12536 {
12537 theDI << searchInfo (aDict, "FPS") << " ";
12538 }
12539 else if (aFlag == "cpu")
12540 {
12541 theDI << searchInfo (aDict, "CPU FPS") << " ";
12542 }
12543 else if (aFlag == "alllayers")
12544 {
12545 theDI << searchInfo (aDict, "Layers") << " ";
12546 }
12547 else if (aFlag == "layers")
12548 {
12549 theDI << searchInfo (aDict, "Rendered layers") << " ";
12550 }
a2803f37 12551 else if (aFlag == "allstructs"
12552 || aFlag == "allstructures")
79b544e6 12553 {
12554 theDI << searchInfo (aDict, "Structs") << " ";
12555 }
a2803f37 12556 else if (aFlag == "structs"
12557 || aFlag == "structures")
79b544e6 12558 {
a2803f37 12559 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12560 if (aRend.IsEmpty()) // all structures rendered
12561 {
12562 aRend = searchInfo (aDict, "Structs");
12563 }
12564 theDI << aRend << " ";
79b544e6 12565 }
12566 else if (aFlag == "groups")
12567 {
12568 theDI << searchInfo (aDict, "Rendered groups") << " ";
12569 }
12570 else if (aFlag == "allarrays")
12571 {
12572 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12573 }
12574 else if (aFlag == "fillarrays")
12575 {
12576 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12577 }
12578 else if (aFlag == "linearrays")
12579 {
12580 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12581 }
12582 else if (aFlag == "pointarrays")
12583 {
12584 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12585 }
12586 else if (aFlag == "textarrays")
12587 {
12588 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12589 }
12590 else if (aFlag == "triangles")
12591 {
12592 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12593 }
12594 else if (aFlag == "points")
12595 {
12596 theDI << searchInfo (aDict, "Rendered points") << " ";
12597 }
12598 else if (aFlag == "geommem")
12599 {
12600 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12601 }
12602 else if (aFlag == "texturemem")
12603 {
12604 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12605 }
12606 else if (aFlag == "framemem")
12607 {
12608 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12609 }
12610 else if (aFlag == "elapsedframe")
12611 {
12612 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12613 }
12614 else if (aFlag == "cpuframe_average")
12615 {
12616 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12617 }
12618 else if (aFlag == "cpupicking_average")
12619 {
12620 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12621 }
12622 else if (aFlag == "cpuculling_average")
12623 {
12624 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12625 }
12626 else if (aFlag == "cpudyn_average")
12627 {
12628 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12629 }
12630 else if (aFlag == "cpuframe_max")
12631 {
12632 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12633 }
12634 else if (aFlag == "cpupicking_max")
12635 {
12636 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12637 }
12638 else if (aFlag == "cpuculling_max")
12639 {
12640 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12641 }
12642 else if (aFlag == "cpudyn_max")
12643 {
12644 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12645 }
12646 }
12647 }
12648 else
12649 {
12650 if (toRedraw)
12651 {
12652 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12653 aView->Redraw();
12654 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12655 }
12656 theDI << "Statistic info:\n" << aView->StatisticInformation();
12657 }
12658 return 0;
12659}
12660
0717ddc1 12661//=======================================================================
12662//function : VXRotate
12663//purpose :
12664//=======================================================================
12665static Standard_Integer VXRotate (Draw_Interpretor& di,
12666 Standard_Integer argc,
12667 const char ** argv)
12668{
12669 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12670 if (aContext.IsNull())
12671 {
586db386 12672 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12673 return 1;
12674 }
8693dfd0 12675
0717ddc1 12676 if (argc != 3)
12677 {
586db386 12678 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12679 return 1;
12680 }
12681
12682 TCollection_AsciiString aName (argv[1]);
12683 Standard_Real anAngle = Draw::Atof (argv[2]);
12684
12685 // find object
12686 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12687 Handle(AIS_InteractiveObject) anIObj;
8f521168 12688 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12689 {
586db386 12690 di << "Use 'vdisplay' before\n";
0717ddc1 12691 return 1;
12692 }
0717ddc1 12693
8f521168 12694 gp_Trsf aTransform;
12695 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12696 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12697
8f521168 12698 aContext->SetLocation (anIObj, aTransform);
12699 aContext->UpdateCurrentViewer();
0717ddc1 12700 return 0;
12701}
12702
ff6122e0 12703namespace
12704{
12705 //! Structure for setting AIS_Manipulator::SetPart() property.
12706 struct ManipAxisModeOnOff
12707 {
12708 Standard_Integer Axis;
12709 AIS_ManipulatorMode Mode;
12710 Standard_Boolean ToEnable;
12711
12712 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12713 };
12714
12715 enum ManipAjustPosition
12716 {
12717 ManipAjustPosition_Off,
12718 ManipAjustPosition_Center,
12719 ManipAjustPosition_Location,
12720 ManipAjustPosition_ShapeLocation,
12721 };
12722}
12723
625e1958 12724//===============================================================================================
12725//function : VManipulator
12726//purpose :
12727//===============================================================================================
12728static int VManipulator (Draw_Interpretor& theDi,
12729 Standard_Integer theArgsNb,
12730 const char** theArgVec)
12731{
bbf3fcde 12732 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 12733 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 12734 if (aCurrentView.IsNull()
625e1958 12735 || aViewer.IsNull())
12736 {
23fe70ec 12737 Message::SendFail ("Error: no active viewer");
625e1958 12738 return 1;
12739 }
12740
12741 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12742 Standard_Integer anArgIter = 1;
ff6122e0 12743 Handle(AIS_Manipulator) aManipulator;
12744 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12745 TCollection_AsciiString aName;
12746 // parameters
12747 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12748 Standard_Real aGap = -1.0, aSize = -1.0;
12749 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12750 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12751 //
12752 bool toDetach = false;
12753 AIS_Manipulator::OptionsForAttach anAttachOptions;
12754 Handle(AIS_InteractiveObject) anAttachObject;
12755 Handle(V3d_View) aViewAffinity;
12756 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12757 //
12758 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12759 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12760 Standard_Integer toStopMouseTransform = -1;
12761 // explicit transformation
12762 gp_Trsf aTrsf;
12763 gp_XYZ aTmpXYZ;
12764 Standard_Real aTmpReal = 0.0;
12765 gp_XYZ aRotPnt, aRotAxis;
625e1958 12766 for (; anArgIter < theArgsNb; ++anArgIter)
12767 {
ff6122e0 12768 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12769 anArg.LowerCase();
12770 if (anUpdateTool.parseRedrawMode (anArg))
12771 {
12772 continue;
12773 }
12774 else if (anArg == "-help")
12775 {
12776 theDi.PrintHelp (theArgVec[0]);
12777 return 0;
12778 }
12779 //
12780 else if (anArg == "-autoactivate"
12781 || anArg == "-noautoactivate")
12782 {
12783 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12784 }
12785 else if (anArg == "-followtranslation"
12786 || anArg == "-nofollowtranslation")
12787 {
12788 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12789 }
12790 else if (anArg == "-followrotation"
12791 || anArg == "-nofollowrotation")
12792 {
12793 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12794 }
12795 else if (anArg == "-followdragging"
12796 || anArg == "-nofollowdragging")
12797 {
12798 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12799 }
12800 else if (anArg == "-gap"
12801 && anArgIter + 1 < theArgsNb
12802 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12803 && aGap >= 0.0)
12804 {
12805 ++anArgIter;
12806 }
12807 else if (anArg == "-size"
12808 && anArgIter + 1 < theArgsNb
12809 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12810 && aSize > 0.0)
12811 {
12812 ++anArgIter;
12813 }
12814 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12815 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12816 {
12817 ManipAxisModeOnOff aPart;
12818 Standard_Integer aMode = 0;
12819 if (anArg == "-part")
12820 {
12821 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12822 || aPart.Axis < 0 || aPart.Axis > 3)
12823 {
12824 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12825 return 1;
12826 }
12827 }
12828 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12829 || aMode < 1 || aMode > 4)
12830 {
12831 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12832 return 1;
12833 }
12834 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12835 {
12836 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12837 return 1;
12838 }
12839 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12840 aParts.Append (aPart);
12841 }
12842 else if (anArg == "-pos"
12843 && anArgIter + 3 < theArgsNb
12844 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12845 {
12846 anArgIter += 3;
12847 if (anArgIter + 3 < theArgsNb
12848 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12849 && aVDir.Modulus() > Precision::Confusion())
12850 {
12851 anArgIter += 3;
12852 }
12853 if (anArgIter + 3 < theArgsNb
12854 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12855 && anXDir.Modulus() > Precision::Confusion())
12856 {
12857 anArgIter += 3;
12858 }
12859 }
12860 else if (anArg == "-zoomable"
12861 || anArg == "-notzoomable")
12862 {
12863 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12864 }
12865 //
12866 else if (anArg == "-adjustposition"
12867 || anArg == "-noadjustposition")
12868 {
12869 anAttachPos = ManipAjustPosition_Center;
12870 if (anArgIter + 1 < theArgsNb)
12871 {
12872 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12873 aPosName.LowerCase();
12874 if (aPosName == "0")
12875 {
12876 anAttachPos = ManipAjustPosition_Off;
12877 }
12878 else if (aPosName == "1"
12879 || aPosName == "center")
12880 {
12881 anAttachPos = ManipAjustPosition_Center;
12882 }
12883 else if (aPosName == "transformation"
12884 || aPosName == "trsf"
12885 || aPosName == "location"
12886 || aPosName == "loc")
12887 {
12888 anAttachPos = ManipAjustPosition_Location;
12889 }
12890 else if (aPosName == "shapelocation"
12891 || aPosName == "shapeloc")
12892 {
12893 anAttachPos = ManipAjustPosition_ShapeLocation;
12894 }
12895 else
12896 {
12897 --anArgIter;
12898 }
12899 }
12900 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12901 }
12902 else if (anArg == "-adjustsize"
12903 || anArg == "-noadjustsize")
12904 {
12905 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12906 }
12907 else if (anArg == "-enablemodes"
12908 || anArg == "-enablemodes")
12909 {
12910 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12911 }
12912 //
12913 else if (anArg == "-starttransform"
12914 && anArgIter + 2 < theArgsNb
12915 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12916 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
12917 {
12918 anArgIter += 2;
12919 }
12920 else if (anArg == "-transform"
12921 && anArgIter + 2 < theArgsNb
12922 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
12923 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
12924 {
12925 anArgIter += 2;
12926 }
12927 else if (anArg == "-stoptransform")
12928 {
12929 toStopMouseTransform = 1;
12930 if (anArgIter + 1 < theArgsNb
12931 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
12932 {
12933 ++anArgIter;
12934 toStopMouseTransform = 0;
12935 }
12936 }
12937 //
12938 else if (anArg == "-move"
12939 && anArgIter + 3 < theArgsNb
12940 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
12941 {
12942 anArgIter += 3;
12943 aTrsf.SetTranslationPart (aTmpXYZ);
12944 }
12945 else if (anArg == "-scale"
12946 && anArgIter + 1 < theArgsNb
12947 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
12948 {
12949 ++anArgIter;
12950 aTrsf.SetScale (gp_Pnt(), aTmpReal);
12951 }
12952 else if (anArg == "-rotate"
12953 && anArgIter + 7 < theArgsNb
12954 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
12955 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
12956 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
12957 {
12958 anArgIter += 7;
12959 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
12960 }
12961 //
12962 else if (anArg == "-detach")
12963 {
12964 toDetach = true;
12965 }
12966 else if (anArg == "-attach"
12967 && anArgIter + 1 < theArgsNb)
12968 {
12969 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
12970 if (!aMapAIS.Find2 (anObjName, anAttachObject))
12971 {
12972 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
12973 return 1;
12974 }
625e1958 12975
ff6122e0 12976 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
12977 {
12978 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
12979 if (!aManip.IsNull()
12980 && aManip->IsAttached()
12981 && aManip->Object() == anAttachObject)
12982 {
12983 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
12984 return 1;
12985 }
12986 }
12987 }
12988 else if (anArg == "-view"
12989 && anArgIter + 1 < theArgsNb
12990 && aViewAffinity.IsNull())
12991 {
12992 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
12993 if (aViewString == "active")
12994 {
12995 aViewAffinity = ViewerTest::CurrentView();
12996 }
12997 else // Check view name
12998 {
12999 ViewerTest_Names aViewNames (aViewString);
13000 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13001 {
13002 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13003 return 1;
13004 }
13005 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13006 if (aViewAffinity.IsNull())
13007 {
13008 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13009 return 1;
13010 }
13011 }
13012 }
13013 else if (aName.IsEmpty())
13014 {
13015 aName = theArgVec[anArgIter];
13016 if (!aMapAIS.IsBound2 (aName))
13017 {
13018 aManipulator = new AIS_Manipulator();
13019 aManipulator->SetModeActivationOnDetection (true);
13020 aMapAIS.Bind (aManipulator, aName);
13021 }
13022 else
13023 {
13024 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13025 if (aManipulator.IsNull())
13026 {
13027 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13028 return 1;
13029 }
13030 }
13031 }
13032 else
13033 {
13034 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13035 }
625e1958 13036 }
13037
625e1958 13038 if (aName.IsEmpty())
13039 {
23fe70ec 13040 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 13041 return 1;
13042 }
ff6122e0 13043 if (!toDetach
13044 && aManipulator.IsNull())
625e1958 13045 {
8b037fe4 13046 aManipulator = new AIS_Manipulator();
49582f9d 13047 aManipulator->SetModeActivationOnDetection (true);
625e1958 13048 aMapAIS.Bind (aManipulator, aName);
13049 }
625e1958 13050
13051 // -----------------------------------------
13052 // change properties of manipulator instance
13053 // -----------------------------------------
13054
ff6122e0 13055 if (toAutoActivate != -1)
625e1958 13056 {
ff6122e0 13057 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
625e1958 13058 }
ff6122e0 13059 if (toFollowTranslation != -1)
625e1958 13060 {
ff6122e0 13061 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
625e1958 13062 }
ff6122e0 13063 if (toFollowRotation != -1)
625e1958 13064 {
ff6122e0 13065 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
625e1958 13066 }
ff6122e0 13067 if (toFollowDragging != -1)
f522ce50 13068 {
ff6122e0 13069 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
f522ce50 13070 }
ff6122e0 13071 if (aGap >= 0.0f)
625e1958 13072 {
ff6122e0 13073 aManipulator->SetGap ((float )aGap);
625e1958 13074 }
ff6122e0 13075
13076 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
625e1958 13077 {
ff6122e0 13078 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13079 if (aPart.Axis == -1)
625e1958 13080 {
ff6122e0 13081 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
625e1958 13082 }
ff6122e0 13083 else
84b904bc 13084 {
ff6122e0 13085 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
84b904bc 13086 }
84b904bc 13087 }
625e1958 13088
ff6122e0 13089 if (aSize > 0.0)
625e1958 13090 {
ff6122e0 13091 aManipulator->SetSize ((float )aSize);
625e1958 13092 }
ff6122e0 13093 if (isZoomable != -1)
625e1958 13094 {
ff6122e0 13095 aManipulator->SetZoomPersistence (isZoomable == 0);
625e1958 13096
13097 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13098 {
13099 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13100 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13101 }
13102 }
13103
ff6122e0 13104 // ----------------------------------
13105 // detach existing manipulator object
13106 // ----------------------------------
13107
13108 if (toDetach)
13109 {
13110 aManipulator->Detach();
13111 aMapAIS.UnBind2 (aName);
13112 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13113 }
13114
625e1958 13115 // ---------------------------------------------------
13116 // attach, detach or access manipulator from an object
13117 // ---------------------------------------------------
13118
ff6122e0 13119 if (!anAttachObject.IsNull())
625e1958 13120 {
ff6122e0 13121 aManipulator->Attach (anAttachObject, anAttachOptions);
13122 }
13123 if (!aViewAffinity.IsNull())
13124 {
13125 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
8b037fe4 13126 anIter.More(); anIter.Next())
625e1958 13127 {
ff6122e0 13128 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
625e1958 13129 }
ff6122e0 13130 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13131 }
625e1958 13132
ff6122e0 13133 if (anAttachPos != ManipAjustPosition_Off
13134 && aManipulator->IsAttached()
13135 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13136 {
13137 gp_Ax2 aPosition = gp::XOY();
13138 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13139 switch (anAttachPos)
bbf3fcde 13140 {
ff6122e0 13141 case ManipAjustPosition_Off:
bbf3fcde 13142 {
ff6122e0 13143 break;
bbf3fcde 13144 }
ff6122e0 13145 case ManipAjustPosition_Location:
bbf3fcde 13146 {
ff6122e0 13147 aPosition = gp::XOY().Transformed (aBaseTrsf);
13148 break;
bbf3fcde 13149 }
ff6122e0 13150 case ManipAjustPosition_ShapeLocation:
bbf3fcde 13151 {
ff6122e0 13152 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
bbf3fcde 13153 {
ff6122e0 13154 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
bbf3fcde 13155 }
ff6122e0 13156 else
bbf3fcde 13157 {
ff6122e0 13158 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
bbf3fcde 13159 return 1;
13160 }
ff6122e0 13161 break;
bbf3fcde 13162 }
ff6122e0 13163 case ManipAjustPosition_Center:
bbf3fcde 13164 {
ff6122e0 13165 Bnd_Box aBox;
13166 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13167 {
13168 Bnd_Box anObjBox;
13169 anObjIter.Value()->BoundingBox (anObjBox);
13170 aBox.Add (anObjBox);
13171 }
13172 aBox = aBox.FinitePart();
13173 if (!aBox.IsVoid())
13174 {
13175 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13176 aPosition.SetLocation (aCenter);
13177 }
13178 break;
bbf3fcde 13179 }
bbf3fcde 13180 }
ff6122e0 13181 aManipulator->SetPosition (aPosition);
13182 }
13183 if (!Precision::IsInfinite (aLocation.X()))
13184 {
13185 if (aVDir.Modulus() <= Precision::Confusion())
13186 {
13187 aVDir = aManipulator->Position().Direction().XYZ();
13188 }
13189 if (anXDir.Modulus() <= Precision::Confusion())
13190 {
13191 anXDir = aManipulator->Position().XDirection().XYZ();
13192 }
13193 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
625e1958 13194 }
13195
13196 // --------------------------------------
13197 // apply transformation using manipulator
13198 // --------------------------------------
13199
ff6122e0 13200 if (aMousePosFrom.x() != IntegerLast())
625e1958 13201 {
ff6122e0 13202 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
625e1958 13203 }
ff6122e0 13204 if (aMousePosTo.x() != IntegerLast())
625e1958 13205 {
ff6122e0 13206 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
625e1958 13207 }
ff6122e0 13208 if (toStopMouseTransform != -1)
625e1958 13209 {
ff6122e0 13210 aManipulator->StopTransform (toStopMouseTransform == 1);
625e1958 13211 }
13212
ff6122e0 13213 if (aTrsf.Form() != gp_Identity)
625e1958 13214 {
ff6122e0 13215 aManipulator->Transform (aTrsf);
625e1958 13216 }
13217
ff6122e0 13218 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
625e1958 13219 {
ff6122e0 13220 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
625e1958 13221 }
625e1958 13222 return 0;
13223}
13224
8e5fb5ea 13225//===============================================================================================
13226//function : VSelectionProperties
13227//purpose :
13228//===============================================================================================
13229static int VSelectionProperties (Draw_Interpretor& theDi,
13230 Standard_Integer theArgsNb,
13231 const char** theArgVec)
13232{
13233 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13234 if (aCtx.IsNull())
13235 {
23fe70ec 13236 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13237 return 1;
13238 }
13239
be3d8cbc 13240 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13241 {
13242 // handle obsolete alias
13243 bool toEnable = true;
13244 if (theArgsNb < 2)
13245 {
13246 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13247 return 0;
13248 }
13249 else if (theArgsNb != 2
dae2a922 13250 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13251 {
23fe70ec 13252 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13253 return 1;
13254 }
13255 if (toEnable != aCtx->ToHilightSelected())
13256 {
13257 aCtx->ClearDetected();
13258 aCtx->SetToHilightSelected (toEnable);
13259 }
13260 return 0;
13261 }
13262
f838dac4 13263 Standard_Boolean toPrint = theArgsNb == 1;
13264 Standard_Boolean toRedraw = Standard_False;
13265 Standard_Integer anArgIter = 1;
13266 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13267 if (anArgIter < theArgsNb)
13268 {
13269 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13270 anArgFirst.LowerCase();
13271 ++anArgIter;
13272 if (anArgFirst == "dynhighlight"
13273 || anArgFirst == "dynhilight"
13274 || anArgFirst == "dynamichighlight"
13275 || anArgFirst == "dynamichilight")
13276 {
13277 aType = Prs3d_TypeOfHighlight_Dynamic;
13278 }
13279 else if (anArgFirst == "localdynhighlight"
13280 || anArgFirst == "localdynhilight"
13281 || anArgFirst == "localdynamichighlight"
13282 || anArgFirst == "localdynamichilight")
13283 {
13284 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13285 }
13286 else if (anArgFirst == "selhighlight"
13287 || anArgFirst == "selhilight"
13288 || anArgFirst == "selectedhighlight"
13289 || anArgFirst == "selectedhilight")
13290 {
13291 aType = Prs3d_TypeOfHighlight_Selected;
13292 }
13293 else if (anArgFirst == "localselhighlight"
13294 || anArgFirst == "localselhilight"
13295 || anArgFirst == "localselectedhighlight"
13296 || anArgFirst == "localselectedhilight")
13297 {
13298 aType = Prs3d_TypeOfHighlight_LocalSelected;
13299 }
13300 else
13301 {
13302 --anArgIter;
13303 }
13304 }
13305 for (; anArgIter < theArgsNb; ++anArgIter)
13306 {
13307 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13308 anArg.LowerCase();
13309 if (anArg == "-help")
13310 {
13311 theDi.PrintHelp (theArgVec[0]);
13312 return 0;
13313 }
13314 else if (anArg == "-print")
13315 {
13316 toPrint = Standard_True;
13317 }
13318 else if (anArg == "-autoactivate")
13319 {
13320 Standard_Boolean toEnable = Standard_True;
13321 if (anArgIter + 1 < theArgsNb
dae2a922 13322 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13323 {
13324 ++anArgIter;
13325 }
13326 aCtx->SetAutoActivateSelection (toEnable);
13327 }
be3d8cbc 13328 else if (anArg == "-automatichighlight"
13329 || anArg == "-automatichilight"
13330 || anArg == "-autohighlight"
13331 || anArg == "-autohilight")
13332 {
13333 Standard_Boolean toEnable = Standard_True;
13334 if (anArgIter + 1 < theArgsNb
dae2a922 13335 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13336 {
13337 ++anArgIter;
13338 }
13339 aCtx->ClearSelected (false);
13340 aCtx->ClearDetected();
13341 aCtx->SetAutomaticHilight (toEnable);
13342 toRedraw = true;
13343 }
13344 else if (anArg == "-highlightselected"
13345 || anArg == "-hilightselected")
13346 {
13347 Standard_Boolean toEnable = Standard_True;
13348 if (anArgIter + 1 < theArgsNb
dae2a922 13349 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13350 {
13351 ++anArgIter;
13352 }
13353 aCtx->ClearDetected();
13354 aCtx->SetToHilightSelected (toEnable);
13355 toRedraw = true;
13356 }
14c4193d 13357 else if (anArg == "-pickstrategy"
13358 || anArg == "-pickingstrategy")
13359 {
13360 if (++anArgIter >= theArgsNb)
13361 {
23fe70ec 13362 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13363 return 1;
13364 }
13365
13366 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13367 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13368 aVal.LowerCase();
13369 if (aVal == "first"
13370 || aVal == "firstaccepted"
13371 || aVal == "firstacceptable")
13372 {
13373 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13374 }
13375 else if (aVal == "topmost"
13376 || aVal == "onlyTopmost")
13377 {
13378 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13379 }
13380 else
13381 {
23fe70ec 13382 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13383 return 1;
13384 }
13385
13386 aCtx->SetPickingStrategy (aStrategy);
13387 }
f838dac4 13388 else if (anArg == "-pixtol"
13389 && anArgIter + 1 < theArgsNb)
13390 {
13391 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13392 }
8c36926a 13393 else if (anArg == "-preferclosest")
13394 {
13395 bool toPreferClosest = true;
13396 if (anArgIter + 1 < theArgsNb
13397 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13398 {
13399 ++anArgIter;
13400 }
13401 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13402 }
13403 else if ((anArg == "-depthtol"
13404 || anArg == "-depthtolerance")
13405 && anArgIter + 1 < theArgsNb)
13406 {
13407 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13408 aTolType.LowerCase();
13409 if (aTolType == "uniform")
13410 {
13411 if (anArgIter + 1 >= theArgsNb)
13412 {
13413 Message::SendFail() << "Syntax error: wrong number of arguments";
13414 return 1;
13415 }
13416 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13417 Draw::Atof (theArgVec[++anArgIter]));
13418 }
13419 else if (aTolType == "uniformpx")
13420 {
13421 if (anArgIter + 1 >= theArgsNb)
13422 {
13423 Message::SendFail() << "Syntax error: wrong number of arguments";
13424 return 1;
13425 }
13426 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13427 Draw::Atof (theArgVec[++anArgIter]));
13428 }
13429 else if (aTolType == "sensfactor")
13430 {
13431 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13432 }
13433 else
13434 {
13435 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13436 return 1;
13437 }
13438 }
f838dac4 13439 else if ((anArg == "-mode"
13440 || anArg == "-dispmode")
13441 && anArgIter + 1 < theArgsNb)
13442 {
13443 if (aType == Prs3d_TypeOfHighlight_None)
13444 {
23fe70ec 13445 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13446 return 1;
13447 }
8e5fb5ea 13448
f838dac4 13449 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13450 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13451 aStyle->SetDisplayMode (aDispMode);
13452 toRedraw = Standard_True;
13453 }
13454 else if (anArg == "-layer"
13455 && anArgIter + 1 < theArgsNb)
13456 {
13457 if (aType == Prs3d_TypeOfHighlight_None)
13458 {
23fe70ec 13459 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13460 return 1;
13461 }
8e5fb5ea 13462
55c8f0f7
BB
13463 ++anArgIter;
13464 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13465 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13466 {
23fe70ec 13467 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13468 return 1;
f838dac4 13469 }
8e5fb5ea 13470
f838dac4 13471 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13472 aStyle->SetZLayer (aNewLayer);
13473 toRedraw = Standard_True;
13474 }
13475 else if (anArg == "-hicolor"
13476 || anArg == "-selcolor"
13477 || anArg == "-color")
13478 {
13479 if (anArg.StartsWith ("-hi"))
13480 {
13481 aType = Prs3d_TypeOfHighlight_Dynamic;
13482 }
13483 else if (anArg.StartsWith ("-sel"))
13484 {
13485 aType = Prs3d_TypeOfHighlight_Selected;
13486 }
13487 else if (aType == Prs3d_TypeOfHighlight_None)
13488 {
23fe70ec 13489 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13490 return 1;
13491 }
8e5fb5ea 13492
f838dac4 13493 Quantity_Color aColor;
dae2a922 13494 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13495 theArgVec + anArgIter + 1,
13496 aColor);
f838dac4 13497 if (aNbParsed == 0)
13498 {
23fe70ec 13499 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13500 return 1;
13501 }
13502 anArgIter += aNbParsed;
8e5fb5ea 13503
f838dac4 13504 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13505 aStyle->SetColor (aColor);
13506 toRedraw = Standard_True;
13507 }
13508 else if ((anArg == "-transp"
13509 || anArg == "-transparency"
13510 || anArg == "-hitransp"
13511 || anArg == "-seltransp"
13512 || anArg == "-hitransplocal"
13513 || anArg == "-seltransplocal")
13514 && anArgIter + 1 < theArgsNb)
13515 {
13516 if (anArg.StartsWith ("-hi"))
13517 {
13518 aType = Prs3d_TypeOfHighlight_Dynamic;
13519 }
13520 else if (anArg.StartsWith ("-sel"))
13521 {
13522 aType = Prs3d_TypeOfHighlight_Selected;
13523 }
13524 else 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_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13531 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13532 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13533 toRedraw = Standard_True;
13534 }
13535 else if ((anArg == "-mat"
13536 || anArg == "-material")
13537 && anArgIter + 1 < theArgsNb)
13538 {
13539 if (aType == Prs3d_TypeOfHighlight_None)
13540 {
23fe70ec 13541 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13542 return 1;
13543 }
8e5fb5ea 13544
f838dac4 13545 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13546 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 13547 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 13548 {
13549 ++anArgIter;
13550 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13551 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13552 Graphic3d_MaterialAspect aMat (aMatName);
13553 aMat.SetColor (aStyle->Color());
13554 aMat.SetTransparency (aStyle->Transparency());
13555 anAspect->SetFrontMaterial (aMat);
13556 anAspect->SetInteriorColor (aStyle->Color());
13557 aStyle->SetBasicFillAreaAspect (anAspect);
13558 }
13559 else
13560 {
13561 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13562 }
13563 toRedraw = Standard_True;
13564 }
13565 else
13566 {
23fe70ec 13567 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 13568 return 1;
f838dac4 13569 }
8e5fb5ea 13570 }
13571
f838dac4 13572 if (toPrint)
8e5fb5ea 13573 {
f838dac4 13574 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13575 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13576 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13577 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13578 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13579 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13580 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13581 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13582 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13583 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13584 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13585 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13586 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13587 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13588 }
13589
13590 if (aCtx->NbSelected() != 0 && toRedraw)
13591 {
13592 aCtx->HilightSelected (Standard_True);
13593 }
13594
13595 return 0;
13596}
13597
decdee7d 13598//===============================================================================================
13599//function : VDumpSelectionImage
13600//purpose :
13601//===============================================================================================
13602static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13603 Standard_Integer theArgsNb,
13604 const char** theArgVec)
13605{
decdee7d 13606 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 13607 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 13608 if (aContext.IsNull())
13609 {
23fe70ec 13610 Message::SendFail ("Error: no active viewer");
decdee7d 13611 return 1;
13612 }
13613
13614 TCollection_AsciiString aFile;
13615 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 13616 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 13617 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13618 Standard_Integer aPickedIndex = 1;
13619 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13620 {
13621 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13622 aParam.LowerCase();
13623 if (aParam == "-type")
13624 {
13625 if (++anArgIter >= theArgsNb)
13626 {
df23a355 13627 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
decdee7d 13628 return 1;
13629 }
13630
13631 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13632 aValue.LowerCase();
13633 if (aValue == "depth"
13634 || aValue == "normdepth"
13635 || aValue == "normalizeddepth")
13636 {
13637 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13638 anImgFormat = Image_Format_GrayF;
decdee7d 13639 }
df23a355 13640 else if (aValue == "depthinverted"
13641 || aValue == "normdepthinverted"
13642 || aValue == "normalizeddepthinverted"
13643 || aValue == "inverted")
decdee7d 13644 {
13645 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13646 anImgFormat = Image_Format_GrayF;
decdee7d 13647 }
13648 else if (aValue == "unnormdepth"
13649 || aValue == "unnormalizeddepth")
13650 {
13651 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13652 anImgFormat = Image_Format_GrayF;
decdee7d 13653 }
13654 else if (aValue == "objectcolor"
13655 || aValue == "object"
13656 || aValue == "color")
13657 {
13658 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13659 }
13660 else if (aValue == "entitycolor"
13661 || aValue == "entity")
13662 {
13663 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13664 }
13665 else if (aValue == "ownercolor"
13666 || aValue == "owner")
13667 {
13668 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13669 }
13670 else if (aValue == "selectionmodecolor"
13671 || aValue == "selectionmode"
13672 || aValue == "selmodecolor"
13673 || aValue == "selmode")
13674 {
13675 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13676 }
114e7a90 13677 else if (aValue == "surfnormal"
13678 || aValue == "surfacenormal"
13679 || aValue == "normal")
13680 {
13681 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13682 }
df23a355 13683 else
13684 {
13685 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13686 return 1;
13687 }
decdee7d 13688 }
13689 else if (aParam == "-picked"
13690 || aParam == "-pickeddepth"
13691 || aParam == "-pickedindex")
13692 {
13693 if (++anArgIter >= theArgsNb)
13694 {
23fe70ec 13695 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 13696 return 1;
13697 }
13698
13699 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13700 }
b40cdc2b 13701 else if (anArgIter + 1 < theArgsNb
13702 && aParam == "-xrpose")
13703 {
13704 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13705 anXRArg.LowerCase();
13706 if (anXRArg == "base")
13707 {
13708 aCustomCam = aView->View()->BaseXRCamera();
13709 }
13710 else if (anXRArg == "head")
13711 {
13712 aCustomCam = aView->View()->PosedXRCamera();
13713 }
13714 else
13715 {
13716 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13717 return 1;
13718 }
13719 if (aCustomCam.IsNull())
13720 {
13721 Message::SendFail() << "Error: undefined XR pose";
13722 return 0;
13723 }
13724 }
decdee7d 13725 else if (aFile.IsEmpty())
13726 {
13727 aFile = theArgVec[anArgIter];
13728 }
13729 else
13730 {
23fe70ec 13731 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 13732 return 1;
13733 }
13734 }
13735 if (aFile.IsEmpty())
13736 {
23fe70ec 13737 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 13738 return 1;
13739 }
13740
decdee7d 13741 Standard_Integer aWidth = 0, aHeight = 0;
13742 aView->Window()->Size (aWidth, aHeight);
13743
13744 Image_AlienPixMap aPixMap;
13745 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13746 {
23fe70ec 13747 Message::SendFail ("Error: can't allocate image");
decdee7d 13748 return 1;
13749 }
b40cdc2b 13750
13751 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13752 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13753 if (!aCustomCam.IsNull())
13754 {
13755 aView->SetCamera (aCustomCam);
13756 }
decdee7d 13757 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13758 {
23fe70ec 13759 Message::SendFail ("Error: can't generate selection image");
decdee7d 13760 return 1;
13761 }
b40cdc2b 13762 if (!aCustomCam.IsNull())
13763 {
13764 aView->SetCamera (aCamBack);
13765 }
13766 aView->SetImmediateUpdate (wasImmUpdate);
13767
decdee7d 13768 if (!aPixMap.Save (aFile))
13769 {
23fe70ec 13770 Message::SendFail ("Error: can't save selection image");
decdee7d 13771 return 0;
13772 }
13773 return 0;
13774}
13775
2108d9a2 13776//===============================================================================================
13777//function : VViewCube
13778//purpose :
13779//===============================================================================================
13780static int VViewCube (Draw_Interpretor& ,
13781 Standard_Integer theNbArgs,
13782 const char** theArgVec)
13783{
13784 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13785 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13786 if (aContext.IsNull() || aView.IsNull())
13787 {
23fe70ec 13788 Message::SendFail ("Error: no active viewer");
2108d9a2 13789 return 1;
13790 }
13791 else if (theNbArgs < 2)
13792 {
23fe70ec 13793 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 13794 return 1;
13795 }
13796
13797 Handle(AIS_ViewCube) aViewCube;
13798 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13799 Quantity_Color aColorRgb;
13800 TCollection_AsciiString aName;
13801 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13802 {
13803 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13804 anArg.LowerCase();
13805 if (anUpdateTool.parseRedrawMode (anArg))
13806 {
13807 //
13808 }
13809 else if (aViewCube.IsNull())
13810 {
13811 aName = theArgVec[anArgIter];
13812 if (aName.StartsWith ("-"))
13813 {
23fe70ec 13814 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 13815 return 1;
13816 }
13817 Handle(AIS_InteractiveObject) aPrs;
13818 GetMapOfAIS().Find2 (aName, aPrs);
13819 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13820 if (aViewCube.IsNull())
13821 {
13822 aViewCube = new AIS_ViewCube();
13823 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13824 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13825 aViewCube->SetFixedAnimationLoop (false);
13826 }
13827 }
13828 else if (anArg == "-reset")
13829 {
13830 aViewCube->ResetStyles();
13831 }
13832 else if (anArg == "-color"
13833 || anArg == "-boxcolor"
13834 || anArg == "-boxsidecolor"
13835 || anArg == "-sidecolor"
13836 || anArg == "-boxedgecolor"
13837 || anArg == "-edgecolor"
13838 || anArg == "-boxcornercolor"
13839 || anArg == "-cornercolor"
13840 || anArg == "-innercolor"
0aeb8984 13841 || anArg == "-textcolor"
13842 || anArg == "-xaxistextcolor"
13843 || anArg == "-yaxistextcolor"
13844 || anArg == "-zaxistextcolor")
2108d9a2 13845 {
dae2a922 13846 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13847 theArgVec + anArgIter + 1,
13848 aColorRgb);
2108d9a2 13849 if (aNbParsed == 0)
13850 {
23fe70ec 13851 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 13852 return 1;
13853 }
13854 anArgIter += aNbParsed;
13855 if (anArg == "-boxcolor")
13856 {
13857 aViewCube->SetBoxColor (aColorRgb);
13858 }
13859 else if (anArg == "-boxsidecolor"
13860 || anArg == "-sidecolor")
13861 {
13862 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13863 aViewCube->SynchronizeAspects();
13864 }
13865 else if (anArg == "-boxedgecolor"
13866 || anArg == "-edgecolor")
13867 {
13868 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13869 aViewCube->SynchronizeAspects();
13870 }
13871 else if (anArg == "-boxcornercolor"
13872 || anArg == "-cornercolor")
13873 {
13874 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13875 aViewCube->SynchronizeAspects();
13876 }
13877 else if (anArg == "-innercolor")
13878 {
13879 aViewCube->SetInnerColor (aColorRgb);
13880 }
13881 else if (anArg == "-textcolor")
13882 {
13883 aViewCube->SetTextColor (aColorRgb);
13884 }
0aeb8984 13885 else if (anArg == "-xaxistextcolor"
13886 || anArg == "-yaxistextcolor"
13887 || anArg == "-zaxistextcolor")
13888 {
13889 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13890 ? Prs3d_DatumParts_XAxis
13891 : (anArg.Value (2) == 'y'
13892 ? Prs3d_DatumParts_YAxis
13893 : Prs3d_DatumParts_ZAxis);
13894 aViewCube->Attributes()->SetOwnDatumAspects();
13895 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13896 }
2108d9a2 13897 else
13898 {
13899 aViewCube->SetColor (aColorRgb);
13900 }
13901 }
13902 else if (anArgIter + 1 < theNbArgs
13903 && (anArg == "-transparency"
13904 || anArg == "-boxtransparency"))
13905 {
13906 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13907 if (aValue < 0.0 || aValue > 1.0)
13908 {
23fe70ec 13909 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 13910 return 1;
13911 }
13912
13913 if (anArg == "-boxtransparency")
13914 {
13915 aViewCube->SetBoxTransparency (aValue);
13916 }
13917 else
13918 {
13919 aViewCube->SetTransparency (aValue);
13920 }
13921 }
13922 else if (anArg == "-axes"
13923 || anArg == "-edges"
13924 || anArg == "-vertices"
13925 || anArg == "-vertexes"
13926 || anArg == "-fixedanimation")
13927 {
13928 bool toShow = true;
13929 if (anArgIter + 1 < theNbArgs
dae2a922 13930 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 13931 {
13932 ++anArgIter;
13933 }
13934 if (anArg == "-fixedanimation")
13935 {
13936 aViewCube->SetFixedAnimationLoop (toShow);
13937 }
13938 else if (anArg == "-axes")
13939 {
13940 aViewCube->SetDrawAxes (toShow);
13941 }
13942 else if (anArg == "-edges")
13943 {
13944 aViewCube->SetDrawEdges (toShow);
13945 }
13946 else
13947 {
13948 aViewCube->SetDrawVertices (toShow);
13949 }
13950 }
13951 else if (anArg == "-yup"
13952 || anArg == "-zup")
13953 {
13954 bool isOn = true;
13955 if (anArgIter + 1 < theNbArgs
dae2a922 13956 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 13957 {
13958 ++anArgIter;
13959 }
13960 if (anArg == "-yup")
13961 {
13962 aViewCube->SetYup (isOn);
13963 }
13964 else
13965 {
13966 aViewCube->SetYup (!isOn);
13967 }
13968 }
13969 else if (anArgIter + 1 < theNbArgs
13970 && anArg == "-font")
13971 {
13972 aViewCube->SetFont (theArgVec[++anArgIter]);
13973 }
13974 else if (anArgIter + 1 < theNbArgs
13975 && anArg == "-fontheight")
13976 {
13977 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13978 }
13979 else if (anArgIter + 1 < theNbArgs
13980 && (anArg == "-size"
13981 || anArg == "-boxsize"))
13982 {
13983 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13984 anArg != "-boxsize");
13985 }
13986 else if (anArgIter + 1 < theNbArgs
13987 && (anArg == "-boxfacet"
13988 || anArg == "-boxfacetextension"
13989 || anArg == "-facetextension"
13990 || anArg == "-extension"))
13991 {
13992 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13993 }
13994 else if (anArgIter + 1 < theNbArgs
13995 && (anArg == "-boxedgegap"
13996 || anArg == "-edgegap"))
13997 {
13998 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13999 }
14000 else if (anArgIter + 1 < theNbArgs
14001 && (anArg == "-boxedgeminsize"
14002 || anArg == "-edgeminsize"))
14003 {
14004 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14005 }
14006 else if (anArgIter + 1 < theNbArgs
14007 && (anArg == "-boxcornerminsize"
14008 || anArg == "-cornerminsize"))
14009 {
14010 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14011 }
14012 else if (anArgIter + 1 < theNbArgs
14013 && anArg == "-axespadding")
14014 {
14015 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14016 }
14017 else if (anArgIter + 1 < theNbArgs
14018 && anArg == "-roundradius")
14019 {
14020 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14021 }
14022 else if (anArgIter + 1 < theNbArgs
14023 && anArg == "-duration")
14024 {
14025 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14026 }
6466cc9e 14027 else if (anArgIter + 1 < theNbArgs
14028 && anArg == "-axesradius")
14029 {
14030 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14031 }
14032 else if (anArgIter + 1 < theNbArgs
14033 && anArg == "-axesconeradius")
14034 {
14035 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14036 }
14037 else if (anArgIter + 1 < theNbArgs
14038 && anArg == "-axessphereradius")
14039 {
14040 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14041 }
2108d9a2 14042 else
14043 {
23fe70ec 14044 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 14045 return 1;
14046 }
14047 }
14048 if (aViewCube.IsNull())
14049 {
23fe70ec 14050 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 14051 return 1;
14052 }
14053
14054 ViewerTest::Display (aName, aViewCube, false);
14055 return 0;
14056}
14057
14b741b0 14058//===============================================================================================
14059//function : VColorConvert
14060//purpose :
14061//===============================================================================================
14062static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14063{
14064 if (theNbArgs != 6)
14065 {
14066 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14067 return 1;
14068 }
14069
14070 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14071 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14072 {
14073 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14074 return 1;
14075 }
14076
14077 const char* aTypeStr = theArgVec[2];
14078 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14079 if (! strcasecmp (aTypeStr, "srgb"))
14080 {
14081 aType = Quantity_TOC_sRGB;
14082 }
14083 else if (! strcasecmp (aTypeStr, "hls"))
14084 {
14085 aType = Quantity_TOC_HLS;
14086 }
14087 else if (! strcasecmp (aTypeStr, "lab"))
14088 {
14089 aType = Quantity_TOC_CIELab;
14090 }
14091 else if (! strcasecmp (aTypeStr, "lch"))
14092 {
14093 aType = Quantity_TOC_CIELch;
14094 }
14095 else
14096 {
14097 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14098 return 1;
14099 }
14100
14101 double aC1 = Draw::Atof (theArgVec[3]);
14102 double aC2 = Draw::Atof (theArgVec[4]);
14103 double aC3 = Draw::Atof (theArgVec[5]);
14104
14105 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14106 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14107
14108 // print values with 6 decimal digits
14109 char buffer[1024];
14110 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14111 theDI << buffer;
14112
14113 return 0;
14114}
14115
14116//===============================================================================================
14117//function : VColorDiff
14118//purpose :
14119//===============================================================================================
14120static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14121{
14122 if (theNbArgs != 7)
14123 {
14124 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14125 return 1;
14126 }
14127
14128 double aR1 = Draw::Atof (theArgVec[1]);
14129 double aG1 = Draw::Atof (theArgVec[2]);
14130 double aB1 = Draw::Atof (theArgVec[3]);
14131 double aR2 = Draw::Atof (theArgVec[4]);
14132 double aG2 = Draw::Atof (theArgVec[5]);
14133 double aB2 = Draw::Atof (theArgVec[6]);
14134
14135 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14136 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14137
14138 theDI << aColor1.DeltaE2000 (aColor2);
14139
14140 return 0;
14141}
14142
6a2fb7a1 14143//===============================================================================================
4551e1be 14144//function : VSelBvhBuild
6a2fb7a1 14145//purpose :
14146//===============================================================================================
14147static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14148{
14149 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14150 if (aCtx.IsNull())
14151 {
14152 Message::SendFail ("Error: no active viewer");
14153 return 1;
14154 }
14155
14156 if (theNbArgs < 2)
14157 {
14158 Message::SendFail ("Error: command syntax is incorrect, see help");
14159 return 1;
14160 }
14161
14162 Standard_Integer toEnable = -1;
14163 Standard_Integer aThreadsNb = -1;
14164 Standard_Boolean toWait = Standard_False;
14165
14166 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14167 {
14168 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14169 anArg.LowerCase();
14170
14171 if (anArg == "-nbthreads"
14172 && anArgIter + 1 < theNbArgs)
14173 {
14174 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14175 if (aThreadsNb < 1)
14176 {
14177 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14178 }
14179 }
14180 else if (anArg == "-wait")
14181 {
14182 toWait = Standard_True;
14183 }
14184 else if (toEnable == -1)
14185 {
14186 Standard_Boolean toEnableValue = Standard_True;
14187 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14188 {
14189 toEnable = toEnableValue ? 1 : 0;
14190 }
14191 else
14192 {
14193 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14194 return 1;
14195 }
14196 }
14197 else
14198 {
14199 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14200 return 1;
14201 }
14202 }
14203
14204 if (aThreadsNb == -1)
14205 {
14206 aThreadsNb = 1;
14207 }
14208 if (toEnable != -1)
14209 {
14210 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14211 }
14212 if (toWait)
14213 {
14214 aCtx->MainSelector()->WaitForBVHBuild();
14215 }
14216
14217 return 0;
14218}
14219
a6049685 14220//=======================================================================
14221//function : ViewerTest_ExitProc
14222//purpose :
14223//=======================================================================
14224static void ViewerTest_ExitProc (ClientData )
14225{
14226 NCollection_List<TCollection_AsciiString> aViewList;
14227 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14228 anIter.More(); anIter.Next())
14229 {
14230 aViewList.Append (anIter.Key1());
14231 }
14232
14233 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14234 anIter.More(); anIter.Next())
14235 {
14236 ViewerTest::RemoveView (anIter.Value(), true);
14237 }
14238}
14239
7fd59977 14240//=======================================================================
14241//function : ViewerCommands
14242//purpose :
14243//=======================================================================
14244
14245void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14246{
a6049685 14247 static bool TheIsInitialized = false;
14248 if (TheIsInitialized)
14249 {
14250 return;
14251 }
14252
14253 TheIsInitialized = true;
14254 // define destruction callback to destroy views in a well-defined order
14255 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
7fd59977 14256
14257 const char *group = "ZeViewer";
b8db9379 14258 theCommands.Add("vdriver",
14259 "vdriver [-list] [-default DriverName] [-load DriverName]"
14260 "\n\t\t: Manages active graphic driver factory."
14261 "\n\t\t: Prints current active driver when called without arguments."
14262 "\n\t\t: Makes specified driver active when ActiveName argument is specified."
14263 "\n\t\t: -list print registered factories"
14264 "\n\t\t: -default define which factory should be used by default (to be used by next vinit call)"
14265 "\n\t\t: -load try loading factory plugin and set it as default one",
14266 __FILE__, VDriver, group);
18d715bd 14267 theCommands.Add("vinit",
fd3f6bd0 14268 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
72ed0644 14269 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
b69e576a 14270 #if defined(HAVE_XLIB)
fd3f6bd0 14271 "\n\t\t: [-display displayName]"
14272 #endif
14273 "\n\t\t: Creates new View window with specified name viewName."
14274 "\n\t\t: By default the new view is created in the viewer and in"
14275 "\n\t\t: graphic driver shared with active view."
14276 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14277 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14278 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
b69e576a 14279#if defined(HAVE_XLIB)
fd3f6bd0 14280 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14281 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14282#endif
fd3f6bd0 14283 "\n\t\t: -left, -top pixel position of left top corner of the window."
4551e1be 14284 "\n\t\t: -width, -height width and height of window respectively."
72ed0644 14285 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
fd3f6bd0 14286 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14287 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
72ed0644 14288 "\n\t\t: -virtual create an offscreen window within interactive session"
2e93433e 14289 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14290 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14291 __FILE__,VInit,group);
18d715bd 14292 theCommands.Add("vclose" ,
d0cc1cb7 14293 "[view_id [keep_context=0|1]]\n"
18d715bd 14294 "or vclose ALL - to remove all created views\n"
14295 " - removes view(viewer window) defined by its view_id.\n"
14296 " - keep_context: by default 0; if 1 and the last view is deleted"
14297 " the current context is not removed.",
14298 __FILE__,VClose,group);
14299 theCommands.Add("vactivate" ,
e084dbbc 14300 "vactivate view_id [-noUpdate]"
18d715bd 14301 " - activates view(viewer window) defined by its view_id",
14302 __FILE__,VActivate,group);
14303 theCommands.Add("vviewlist",
14304 "vviewlist [format={tree, long}]"
14305 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14306 " - format: format of result output, if tree the output is a tree view;"
14307 "otherwise it's a list of full view names. By default format = tree",
14308 __FILE__,VViewList,group);
7fd59977 14309 theCommands.Add("vhelp" ,
14310 "vhelp : display help on the viewer commands",
14311 __FILE__,VHelp,group);
fc552d84 14312 theCommands.Add("vviewproj",
14313 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14314 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14315 "\n\t\t: Setup view direction"
14316 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14317 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14318 "\n\t\t: for example '+Z' will show front of the model,"
14319 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14320 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14321 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14322 __FILE__,VViewProj,group);
7fd59977 14323 theCommands.Add("vtop" ,
27af3052 14324 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14325 __FILE__,VViewProj,group);
44b8f2d6 14326 theCommands.Add("vbottom" ,
27af3052 14327 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14328 __FILE__,VViewProj,group);
44b8f2d6 14329 theCommands.Add("vleft" ,
27af3052 14330 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14331 __FILE__,VViewProj,group);
44b8f2d6 14332 theCommands.Add("vright" ,
27af3052 14333 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14334 __FILE__,VViewProj,group);
7fd59977 14335 theCommands.Add("vaxo" ,
27af3052 14336 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14337 __FILE__,VViewProj,group);
44b8f2d6 14338 theCommands.Add("vfront" ,
27af3052 14339 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14340 __FILE__,VViewProj,group);
44b8f2d6 14341 theCommands.Add("vback" ,
27af3052 14342 "vback : Back view. Orientation -X+Z" ,
fc552d84 14343 __FILE__,VViewProj,group);
7fd59977 14344 theCommands.Add("vpick" ,
14345 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14346 VPick,group);
1beb58d7 14347 theCommands.Add("vfit",
14348 "vfit or <F> [-selected] [-noupdate]"
b586500b 14349 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14350 __FILE__,VFit,group);
6262a303 14351 theCommands.Add ("vfitarea",
14352 "vfitarea x1 y1 x2 y2"
14353 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14354 "\n\t\t: Fit view to show area located between two points"
14355 "\n\t\t: given in world 2D or 3D corrdinates.",
14356 __FILE__, VFitArea, group);
197ac94e 14357 theCommands.Add ("vzfit", "vzfit [scale]\n"
14358 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14359 " \"scale\" - specifies factor to scale computed z range.\n",
14360 __FILE__, VZFit, group);
7fd59977 14361 theCommands.Add("vrepaint",
8693dfd0 14362 "vrepaint [-immediate] [-continuous FPS]"
14363 "\n\t\t: force redraw of active View"
14364 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14365 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14366 "\n\t\t: 0 means no continuous rendering,"
14367 "\n\t\t: -1 means non-stop redraws,"
14368 "\n\t\t: >0 specifies target framerate,",
7fd59977 14369 __FILE__,VRepaint,group);
14370 theCommands.Add("vclear",
faea8b40 14371 "vclear : vclear"
14372 "\n\t\t: remove all the object from the viewer",
7fd59977 14373 __FILE__,VClear,group);
293211ae 14374 theCommands.Add (
14375 "vbackground",
14376 "Changes background or some background settings.\n"
14377 "\n"
14378 "Usage:\n"
14379 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14380 " vbackground -imageMode FillType\n"
14381 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14382 " vbackground -gradientMode FillMethod\n"
077a220c 14383 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14384 " vbackground -color Color\n"
14385 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14386 " vbackground -default -color Color\n"
14387 " vbackground -help\n"
14388 "\n"
14389 "Options:\n"
14390 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14391 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14392 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14393 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
4551e1be 14394 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
077a220c 14395 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14396 " -order (-o): defines order of tiles in one image cubemap\n"
14397 " (has no effect in case of multi image cubemaps)\n"
293211ae 14398 " -color (-col): sets background color\n"
14399 " -default (-def): sets background default gradient or color\n"
14400 " -help (-h): outputs short help message\n"
14401 "\n"
14402 "Arguments:\n"
077a220c 14403 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14404 " or reals within the range [0.0, 1.0]\n"
077a220c 14405 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14406 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14407 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14408 "CORNER4\n"
077a220c 14409 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14410 " ImageFile: a name of the file with the image used as a background\n"
14411 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14412 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14413 __FILE__,
14414 vbackground,
14415 group);
14416 theCommands.Add ("vsetbg",
14417 "Loads image as background."
14418 "\n\t\t: vsetbg ImageFile [FillType]"
14419 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14420 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14421 __FILE__,
14422 vbackground,
14423 group);
14424 theCommands.Add ("vsetbgmode",
14425 "Changes background image fill type."
14426 "\n\t\t: vsetbgmode [-imageMode] FillType"
14427 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14428 __FILE__,
14429 vbackground,
14430 group);
14431 theCommands.Add ("vsetgradientbg",
14432 "Mounts gradient background."
14433 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14434 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14435 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14436 __FILE__,
14437 vbackground,
14438 group);
14439 theCommands.Add ("vsetgrbgmode",
14440 "Changes gradient background fill method."
14441 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14442 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14443 __FILE__,
14444 vbackground,
14445 group);
14446 theCommands.Add ("vsetcolorbg",
14447 "Sets background color."
14448 "\n\t\t: vsetcolorbg [-color] Color."
14449 "\n\t\t: Alias for 'vbackground -color Color'.",
14450 __FILE__,
14451 vbackground,
14452 group);
14453 theCommands.Add ("vsetdefaultbg",
14454 "Sets default viewer background fill color (flat/gradient)."
14455 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14456 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14457 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14458 "\n\t\t: vsetdefaultbg [-color] Color"
14459 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14460 __FILE__,
14461 vbackground,
14462 group);
7fd59977 14463 theCommands.Add("vscale",
14464 "vscale : vscale X Y Z",
14465 __FILE__,VScale,group);
14466 theCommands.Add("vzbufftrihedron",
536d98e2 14467 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14468 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14469 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14470 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14471 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
0aeb8984 14472 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
536d98e2 14473 "\n\t\t: Displays a trihedron",
14474 __FILE__,VZBuffTrihedron,group);
7fd59977 14475 theCommands.Add("vrotate",
4af098ba 14476 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14477 "\n : Option -mouseStart starts rotation according to the mouse position"
14478 "\n : Option -mouseMove continues rotation with angle computed"
14479 "\n : from last and new mouse position."
14480 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14481 __FILE__,VRotate,group);
14482 theCommands.Add("vzoom",
14483 "vzoom : vzoom coef",
14484 __FILE__,VZoom,group);
14485 theCommands.Add("vpan",
14486 "vpan : vpan dx dy",
14487 __FILE__,VPan,group);
7fd59977 14488 theCommands.Add("vcolorscale",
4b3d6eb1 14489 "vcolorscale name [-noupdate|-update] [-demo]"
14490 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14491 "\n\t\t: [-font HeightFont=20]"
14492 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14493 "\n\t\t: [-smoothTransition {on|off}=off]"
14494 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14495 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14496 "\n\t\t: [-textpos {left|right|center|none}=right]"
14497 "\n\t\t: [-labelAtBorder {on|off}=on]"
14498 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14499 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14500 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14501 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14502 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14503 "\n\t\t: -demo - displays a color scale with demonstratio values"
14504 "\n\t\t: -colors - set colors for all intervals"
14505 "\n\t\t: -color - set color for specific interval"
14b741b0 14506 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14507 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14508 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14509 "\n\t\t: at border means the value inbetween neighbor intervals,"
14510 "\n\t\t: at center means the center value within current interval"
14511 "\n\t\t: -labels - set labels for all intervals"
14512 "\n\t\t: -freeLabels - same as -labels but does not require"
14513 "\n\t\t: matching the number of intervals"
14514 "\n\t\t: -label - set label for specific interval"
14515 "\n\t\t: -title - set title"
14516 "\n\t\t: -reversed - setup smooth color transition between intervals"
14517 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14518 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14519 __FILE__, VColorScale, group);
7fd59977 14520 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14521 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14522 "\t[-namefont Name] [-valuesfont Name]\n"
14523 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14524 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14525 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14526 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14527 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14528 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14529 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14530 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14531 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14532 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14533 " - Displays or erases graduated trihedron"
14534 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14535 " - namefont - font of axes names. Default: Arial\n"
14536 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14537 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14538 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14539 " - valuesfont - font of axes values. Default: Arial\n"
14540 " - xcolor, ycolor, zcolor - color of axis and values\n"
14541 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14542 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14543 __FILE__,VGraduatedTrihedron,group);
3bffef55 14544 theCommands.Add("vtile" ,
14545 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14546 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14547 "\n\t\t: -totalSize the size of virtual bigger viewport"
14548 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14549 "\n\t\t: -lowerLeft tile offset as lower left corner"
14550 "\n\t\t: -upperLeft tile offset as upper left corner",
14551 __FILE__, VTile, group);
59f45b7c 14552 theCommands.Add("vzlayer",
7c3ef2f7 14553 "vzlayer [layerId]"
1c728f2d 14554 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14555 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14556 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14557 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14558 "\n\t\t: ZLayer list management:"
14559 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14560 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14561 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14562 "\n\t\t: -delete delete z layer"
14563 "\n\t\t: -get print sequence of z layers"
14564 "\n\t\t: -settings print status of z layer settings"
14565 "\n\t\t: -disable disables given setting"
14566 "\n\t\t: -enable enables given setting",
59f45b7c 14567 __FILE__,VZLayer,group);
20637bd2 14568 theCommands.Add("vlayerline",
14569 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14570 __FILE__,VLayerLine,group);
79931835 14571 theCommands.Add("vgrid",
14572 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14573 "\n\t\t: [-step X Y] [-size DX DY]"
14574 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 14575 __FILE__, VGrid, group);
c40b7d58 14576 theCommands.Add ("vpriviledgedplane",
14577 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14578 "\n\t\t: Ox, Oy, Oz - plane origin"
14579 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14580 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14581 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14582 __FILE__, VPriviledgedPlane, group);
f25b82d6 14583 theCommands.Add ("vconvert",
14584 "vconvert v [Mode={window|view}]"
14585 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14586 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14587 "\n\t\t: window - convert to window coordinates, pixels"
14588 "\n\t\t: view - convert to view projection plane"
14589 "\n\t\t: grid - convert to model coordinates, given on grid"
4551e1be 14590 "\n\t\t: ray - convert projection ray to model coordinates"
f25b82d6 14591 "\n\t\t: - vconvert v window : convert view to window;"
14592 "\n\t\t: - vconvert v view : convert window to view;"
14593 "\n\t\t: - vconvert x y window : convert view to window;"
14594 "\n\t\t: - vconvert x y view : convert window to view;"
14595 "\n\t\t: - vconvert x y : convert window to model;"
14596 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14597 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14598 "\n\t\t: - vconvert x y z window : convert model to window;"
14599 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14600 "\n\t\t: Converts the given coordinates to window/view/model space.",
14601 __FILE__, VConvert, group);
208e6839 14602 theCommands.Add ("vfps",
e084dbbc 14603 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 14604 __FILE__, VFps, group);
b5ac8292 14605 theCommands.Add ("vstereo",
f978241f 14606 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 14607 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 14608 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 14609 "\n\t\t: Control stereo output mode."
14610 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14611 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14612 "\n\t\t: Available modes for -mode:"
f978241f 14613 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14614 "\n\t\t: requires driver support."
14615 "\n\t\t: Should be called BEFORE vinit!"
14616 "\n\t\t: anaglyph - Anaglyph glasses"
14617 "\n\t\t: rowInterlaced - row-interlaced display"
14618 "\n\t\t: columnInterlaced - column-interlaced display"
14619 "\n\t\t: chessBoard - chess-board output"
14620 "\n\t\t: sideBySide - horizontal pair"
14621 "\n\t\t: overUnder - vertical pair"
b40cdc2b 14622 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 14623 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14624 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14625 "\n\t\t: greenMagentaSimple",
b5ac8292 14626 __FILE__, VStereo, group);
f0430952 14627 theCommands.Add ("vmemgpu",
14628 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14629 " with f option returns free memory in bytes",
14630 __FILE__, VMemGpu, group);
85e096c3 14631 theCommands.Add ("vreadpixel",
ba00aab7 14632 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 14633 " : Read pixel value for active view",
14634 __FILE__, VReadPixel, group);
692613e5 14635 theCommands.Add("diffimage",
fd3f6bd0 14636 "diffimage imageFile1 imageFile2 [diffImageFile]"
14637 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14638 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14639 "\n\t\t: Compare two images by content and generate difference image."
14640 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14641 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 14642 __FILE__, VDiffImage, group);
4754e164 14643 theCommands.Add ("vselect",
e76471b5 14644 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-replaceextra|-xor|-add|-remove]\n"
4754e164 14645 "- emulates different types of selection:\n"
14646 "- 1) single click selection\n"
14647 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14648 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 14649 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14650 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14651 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14652 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
e76471b5 14653 "- 5) selection scheme replace, replaceextra, xor, add or remove (replace by default)",
4754e164 14654 __FILE__, VSelect, group);
14655 theCommands.Add ("vmoveto",
8a590580 14656 "vmoveto [x y] [-reset]"
14657 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14658 "\n\t\t: -reset resets current highlighting",
4754e164 14659 __FILE__, VMoveTo, group);
0461e7fd 14660 theCommands.Add ("vselaxis",
14661 "vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14662 "\n\t\t: Provides intersection by given axis and print result intersection points"
14663 "\n\t\t: -onlyTop switches On/Off mode to find only top point or all"
14664 "\n\t\t: -display Name displays intersecting axis and result intersection points for debug goals"
14665 "\n\t\t: -showNormal adds displaying of normal in intersection point or not",
14666 __FILE__, VSelectByAxis, group);
1beb58d7 14667 theCommands.Add ("vviewparams",
14668 "vviewparams [-args] [-scale [s]]"
14669 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14670 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14671 "\n\t\t: Manage current view parameters or prints all"
14672 "\n\t\t: current values when called without argument."
14673 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14674 "\n\t\t: -eye [x y z] prints or sets eye location"
14675 "\n\t\t: -at [x y z] prints or sets center of look"
14676 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14677 "\n\t\t: -proj [x y z] prints or sets direction of look"
14678 "\n\t\t: -center x y sets location of center of the screen in pixels"
14679 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14680 "\n\t\t: or changes the size of its maximum dimension"
14681 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 14682 __FILE__, VViewParams, group);
1beb58d7 14683
2e93433e 14684 theCommands.Add("v2dmode",
14685 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14686 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14687 "\n\t\t: mode - switches On/Off rotation mode"
14688 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14689 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14690 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14691 "\n\t\t: View camera position might be changed only by commands.",
14692 __FILE__, V2DMode, group);
14693
1beb58d7 14694 theCommands.Add("vanimation", "Alias for vanim",
14695 __FILE__, VAnimation, group);
14696
14697 theCommands.Add("vanim",
14698 "List existing animations:"
14699 "\n\t\t: vanim"
14700 "\n\t\t: Animation playback:"
14701 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14702 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14703 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14704 "\n\t\t: -freeLook skip camera animations"
14705 "\n\t\t: -lockLoop disable any interactions"
14706 "\n\t\t:"
14707 "\n\t\t: Animation definition:"
14708 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14709 "\n\t\t: [start TimeSec] [duration TimeSec]"
14710 "\n\t\t:"
14711 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14712 "\n\t\t: specifies nested animations."
14713 "\n\t\t: There is no syntax to explicitly add new animation,"
14714 "\n\t\t: and all non-existing animations within the name will be"
14715 "\n\t\t: implicitly created on first use (including parents)."
14716 "\n\t\t:"
14717 "\n\t\t: Each animation might define the SINGLE action (see below),"
14718 "\n\t\t: like camera transition, object transformation or custom callback."
14719 "\n\t\t: Child animations can be used for defining concurrent actions."
14720 "\n\t\t:"
14721 "\n\t\t: Camera animation:"
14722 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14723 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14724 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14725 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14726 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14727 "\n\t\t: -atX camera Center positions pair"
14728 "\n\t\t: -upX camera Up directions pair"
14729 "\n\t\t: -scaleX camera Scale factors pair"
14730 "\n\t\t: Object animation:"
14731 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14732 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14733 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14734 "\n\t\t: -locX object Location points pair (translation)"
14735 "\n\t\t: -rotX object Orientations pair (quaternions)"
14736 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14737 "\n\t\t: Custom callback:"
14738 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14739 "\n\t\t: %Pts overall animation presentation timestamp"
14740 "\n\t\t: %LocalPts local animation timestamp"
14741 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 14742 "\n\t\t:"
14743 "\n\t\t: Video recording:"
14744 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14745 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14746 "\n\t\t: [-crf Value] [-preset Preset]"
14747 "\n\t\t: -fps video framerate"
14748 "\n\t\t: -format file format, container (matroska, etc.)"
14749 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14750 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14751 "\n\t\t: -crf constant rate factor (specific to codec)"
14752 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 14753 __FILE__, VAnimation, group);
14754
4754e164 14755 theCommands.Add("vchangeselected",
dc3fe572 14756 "vchangeselected shape"
4754e164 14757 "- adds to shape to selection or remove one from it",
14758 __FILE__, VChangeSelected, group);
4754e164 14759 theCommands.Add ("vnbselected",
faea8b40 14760 "vnbselected"
14761 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14762 theCommands.Add ("vcamera",
30a1b24e 14763 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14764 "\n\t\t: [-persp]"
14765 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14766 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14767 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14768 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 14769 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14770 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 14771 "\n\t\t: Manages camera parameters."
4551e1be 14772 "\n\t\t: Displays frustum when presentation name PrsName is specified."
6b62b2da 14773 "\n\t\t: Prints current value when option called without argument."
14774 "\n\t\t: Orthographic camera:"
14775 "\n\t\t: -ortho activate orthographic projection"
14776 "\n\t\t: Perspective camera:"
14777 "\n\t\t: -persp activate perspective projection (mono)"
14778 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 14779 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 14780 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 14781 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 14782 "\n\t\t: Stereoscopic camera:"
14783 "\n\t\t: -stereo perspective projection (stereo)"
14784 "\n\t\t: -leftEye perspective projection (left eye)"
14785 "\n\t\t: -rightEye perspective projection (right eye)"
14786 "\n\t\t: -iod intraocular distance value"
14787 "\n\t\t: -iodType distance type, absolute or relative"
14788 "\n\t\t: -zfocus stereographic focus value"
14789 "\n\t\t: -zfocusType focus type, absolute or relative",
14790 __FILE__, VCamera, group);
b5ac8292 14791 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14792 "- vautozfit [on={1|0}] [scale]\n"
14793 " Prints or changes parameters of automatic z-fit mode:\n"
14794 " \"on\" - turns automatic z-fit on or off\n"
14795 " \"scale\" - specifies factor to scale computed z range.\n",
14796 __FILE__, VAutoZFit, group);
b5ac8292 14797 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14798 " vzrange - without parameters shows current values\n"
14799 " vzrange [znear] [zfar] - applies provided values to view",
14800 __FILE__,VZRange, group);
4754e164 14801 theCommands.Add("vsetviewsize",
14802 "vsetviewsize size",
14803 __FILE__,VSetViewSize,group);
14804 theCommands.Add("vmoveview",
14805 "vmoveview Dx Dy Dz [Start = 1|0]",
14806 __FILE__,VMoveView,group);
14807 theCommands.Add("vtranslateview",
14808 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14809 __FILE__,VTranslateView,group);
14810 theCommands.Add("vturnview",
14811 "vturnview Ax Ay Az [Start = 1|0]",
14812 __FILE__,VTurnView,group);
269294d6 14813 theCommands.Add("vtextureenv",
14814 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14815 "or user-defined file and optionally applying texture mapping parameters\n"
14816 " Usage:\n"
14817 " vtextureenv off - disables environment mapping\n"
14818 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14819 " std_texture = (0..7)\n"
14820 " rep = {clamp|repeat}\n"
14821 " mod = {decal|modulate}\n"
14822 " flt = {nearest|bilinear|trilinear}\n"
14823 " ss, st - scale factors for s and t texture coordinates\n"
14824 " ts, tt - translation for s and t texture coordinates\n"
14825 " rot - texture rotation angle in degrees",
14826 __FILE__, VTextureEnv, group);
1eeef710 14827 theCommands.Add("vhlr",
14828 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14829 "\n\t\t: Hidden Line Removal algorithm."
14830 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14831 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 14832 __FILE__,VHLR,group);
1eeef710 14833 theCommands.Add("vhlrtype",
14834 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14835 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14836 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14837 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14838 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 14839 __FILE__,VHLRType,group);
3e05329c 14840 theCommands.Add("vclipplane",
14841 "vclipplane planeName [{0|1}]"
25c35042 14842 "\n\t\t: [-equation1 A B C D]"
14843 "\n\t\t: [-equation2 A B C D]"
14844 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 14845 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 14846 "\n\t\t: [-maxPlanes]"
14847 "\n\t\t: [-capping {0|1}]"
1b661a81 14848 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 14849 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14850 "\n\t\t: [-texRotate Angle]"
14851 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14852 "\n\t\t: [-useObjShader {0|1}]"
14853 "\n\t\t: Clipping planes management:"
14854 "\n\t\t: -maxPlanes print plane limit for view"
14855 "\n\t\t: -delete delete plane with given name"
14856 "\n\t\t: {off|on|0|1} turn clipping on/off"
14857 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14858 "\n\t\t: applied to active View when list is omitted"
14859 "\n\t\t: -equation A B C D change plane equation"
14860 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14861 "\n\t\t: Capping options:"
14862 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14863 "\n\t\t: -color R G B set capping color"
1b661a81 14864 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 14865 "\n\t\t: -texName Texture set capping texture"
14866 "\n\t\t: -texScale SX SY set capping tex scale"
14867 "\n\t\t: -texOrigin TX TY set capping tex origin"
14868 "\n\t\t: -texRotate Angle set capping tex rotation"
14869 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14870 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14871 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14872 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14873 __FILE__, VClipPlane, group);
392ac980 14874 theCommands.Add("vdefaults",
4c513386 14875 "vdefaults [-absDefl value]"
14876 "\n\t\t: [-devCoeff value]"
14877 "\n\t\t: [-angDefl value]"
14878 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14879 , __FILE__, VDefaults, group);
12381341 14880 theCommands.Add("vlight",
06d40093 14881 "vlight [lightName] [-noupdate]"
14882 "\n\t\t: [-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]"
14883 "\n\t\t: [-type {ambient|directional|spotlight|positional}] [-name value]"
14884 "\n\t\t: [-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]"
14885 "\n\t\t: [-headlight 0|1] [-castShadows 0|1]"
14886 "\n\t\t: [-range value] [-constAttenuation value] [-linearAttenuation value]"
14887 "\n\t\t: [-spotExponent value] [-spotAngle angleDeg]"
14888 "\n\t\t: [-smoothAngle value] [-smoothRadius value]"
14889 "\n\t\t: [-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]"
14890 "\n\t\t: Command manages light sources. Without arguments shows list of lights."
14891 "\n\t\t: Arguments affecting the list of defined/active lights:"
14892 "\n\t\t: -clear remove all light sources"
14893 "\n\t\t: -defaults defines two standard light sources"
14894 "\n\t\t: -reset resets light source parameters to default values"
14895 "\n\t\t: -type sets type of light source"
14896 "\n\t\t: -name sets new name to light source"
14897 "\n\t\t: -global assigns light source to all views (default state)"
14898 "\n\t\t: -local assigns light source to active view"
14899 "\n\t\t: -zlayer assigns light source to specified Z-Layer"
14900 "\n\t\t: Ambient light parameters:"
14901 "\n\t\t: -color sets (normalized) light color"
14902 "\n\t\t: -intensity sets intensity of light source, 1.0 by default;"
14903 "\n\t\t: affects also environment cubemap intensity"
14904 "\n\t\t: Point light parameters:"
14905 "\n\t\t: -color sets (normalized) light color"
14906 "\n\t\t: -intensity sets PBR intensity"
14907 "\n\t\t: -range sets clamping distance"
14908 "\n\t\t: -constAtten (obsolete) sets constant attenuation factor"
14909 "\n\t\t: -linearAtten (obsolete) sets linear attenuation factor"
14910 "\n\t\t: -smoothRadius sets PBR smoothing radius"
14911 "\n\t\t: Directional light parameters:"
14912 "\n\t\t: -color sets (normalized) light color"
14913 "\n\t\t: -intensity sets PBR intensity"
14914 "\n\t\t: -direction sets direction"
14915 "\n\t\t: -headlight sets headlight flag"
14916 "\n\t\t: -castShadows enables/disables shadow casting"
14917 "\n\t\t: -smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range"
14918 "\n\t\t: Spot light parameters:"
14919 "\n\t\t: -color sets (normalized) light color"
14920 "\n\t\t: -intensity sets PBR intensity"
14921 "\n\t\t: -range sets clamping distance"
14922 "\n\t\t: -position sets position"
14923 "\n\t\t: -direction sets direction"
14924 "\n\t\t: -spotAngle sets spotlight angle"
14925 "\n\t\t: -spotExp sets spotlight exponenta"
14926 "\n\t\t: -headlight sets headlight flag"
14927 "\n\t\t: -constAtten (obsolete) sets constant attenuation factor"
14928 "\n\t\t: -linearAtten (obsolete) sets linear attenuation factor"
14929 "\n\t\t: Light presentation parameters:"
14930 "\n\t\t: -display adds light source presentation"
14931 "\n\t\t: -showName shows/hides the name of light source; 1 by default"
14932 "\n\t\t: -showRange shows/hides the range of spot/positional light source; 1 by default"
14933 "\n\t\t: -prsZoomable makes light presentation zoomable/non-zoomable"
14934 "\n\t\t: -prsSize sets light presentation size"
14935 "\n\t\t: Examples:"
14936 "\n\t\t: vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED"
14937 "\n\t\t: vlight redlight -delete",
12381341 14938 __FILE__, VLight, group);
67312b79 14939 theCommands.Add("vpbrenv",
14940 "vpbrenv -clear|-generate"
14941 "\n\t\t: Clears or generates PBR environment map of active view."
14942 "\n\t\t: -clear clears PBR environment (fills by white color)"
14943 "\n\t\t: -generate generates PBR environment from current background cubemap",
14944 __FILE__, VPBREnvironment, group);
6b62b2da 14945 theCommands.Add("vraytrace",
14946 "vraytrace [0|1]"
189f85a3 14947 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 14948 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
14949 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
14950 __FILE__, VRenderParams, group);
bc8c79bb 14951 theCommands.Add("vrenderparams",
4c7a3fae 14952 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
14953 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
14954 "\n\t\t: Common parameters:"
14955 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
d37aef5c 14956 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1]"
14957 "\n\t\t: [-resolution value=72] [-fontHinting {off|normal|light}=off]"
14958 "\n\t\t: [-fontAutoHinting {auto|force|disallow}=auto]"
c123c310 14959 "\n\t\t: [-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]"
d84e8669 14960 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
4c7a3fae 14961 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
14962 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
14963 "\n\t\t: [-sync {default|views}] [-reset]"
14964 "\n\t\t: -raster Disables GPU ray-tracing."
14965 "\n\t\t: -shadingModel Controls shading model."
14966 "\n\t\t: -msaa Specifies number of samples for MSAA."
14967 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
14968 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
d37aef5c 14969 "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens."
14970 "\n\t\t: -fontAutoHinting Manages font autohinting."
4c7a3fae 14971 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
14972 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
14973 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
c123c310 14974 "\n\t\t: off unordered transparency (but opaque objects implicitly draw first);"
14975 "\n\t\t: weighted weight OIT is managed by depth weight factor 0.0..1.0;"
14976 "\n\t\t: peeling depth peeling OIT is managed by number of peeling layers."
d84e8669 14977 "\n\t\t: -shadows Enables/disables shadows rendering."
14978 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
14979 "\n\t\t: -shadowMapBias Shadow map bias."
4c7a3fae 14980 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
14981 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
14982 "\n\t\t: sets state to check structures culled previously."
14983 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
14984 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
14985 "\n\t\t: Diagnostic output (on-screen overlay):"
14986 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
14987 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
14988 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
14989 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
14990 "\n\t\t: -perfUpdateInterval Performance counters update interval."
14991 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
14992 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
14993 "\n\t\t: Ray-Tracing options:"
d84e8669 14994 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
4c7a3fae 14995 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
14996 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
14997 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
14998 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
14999 "\n\t\t: [-maxRad {value>0}=30.0]"
15000 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15001 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15002 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15003 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
4c7a3fae 15004 "\n\t\t: -reflections Enables/disables specular reflections."
15005 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15006 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15007 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15008 "\n\t\t: -env Enables/disables environment map background."
15009 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15010 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15011 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15012 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15013 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15014 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15015 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15016 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15017 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15018 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15019 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15020 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15021 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15022 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15023 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15024 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15025 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15026 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15027 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15028 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15029 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15030 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15031 "\n\t\t: Debug options:"
15032 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15033 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15034 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15035 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 15036 __FILE__, VRenderParams, group);
79b544e6 15037 theCommands.Add("vstatprofiler",
15038 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15039 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 15040 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 15041 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15042 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15043 "\n [-noredraw]"
15044 "\n\t\t: Prints rendering statistics."
15045 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15046 "\n\t\t: else - print all performance counters set previously."
15047 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15048 __FILE__, VStatProfiler, group);
49e1a5c7 15049 theCommands.Add ("vplace",
15050 "vplace dx dy"
15051 "\n\t\t: Places the point (in pixels) at the center of the window",
15052 __FILE__, VPlace, group);
0717ddc1 15053 theCommands.Add("vxrotate",
15054 "vxrotate",
15055 __FILE__,VXRotate,group);
15056
625e1958 15057 theCommands.Add("vmanipulator",
15058 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15059 "\n tool to create and manage AIS manipulators."
15060 "\n Options: "
15061 "\n '-attach AISObject' attach manipulator to AISObject"
ff6122e0 15062 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
625e1958 15063 "\n '-adjustSize {0|1}' adjust size when attaching"
15064 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 15065 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15066 "\n by default it is displayed in all views of the current viewer"
625e1958 15067 "\n '-detach' detach manipulator"
15068 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15069 "\n '-transform mouse_x mouse_y' - invoke transformation"
15070 "\n '-stopTransform [abort]' - invoke stop of transformation"
15071 "\n '-move x y z' - move attached object"
15072 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15073 "\n '-scale factor' - scale attached object"
15074 "\n '-autoActivate {0|1}' - set activation on detection"
15075 "\n '-followTranslation {0|1}' - set following translation transform"
15076 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 15077 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 15078 "\n '-gap value' - set gap between sub-parts"
15079 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 15080 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 15081 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15082 "\n '-size value' - set size of manipulator"
15083 "\n '-zoomable {0|1}' - set zoom persistence",
15084 __FILE__, VManipulator, group);
15085
8e5fb5ea 15086 theCommands.Add("vselprops",
f838dac4 15087 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 15088 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15089 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 15090 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15091 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 15092 "\n -pickStrategy {first|topmost} : defines picking strategy"
15093 "\n 'first' to pick first acceptable (default)"
15094 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 15095 "\n -pixTol value : sets up pixel tolerance"
8c36926a 15096 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15097 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15098 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 15099 "\n -dispMode dispMode : sets display mode for highlighting"
15100 "\n -layer ZLayer : sets ZLayer for highlighting"
15101 "\n -color {name|r g b} : sets highlight color"
15102 "\n -transp value : sets transparency coefficient for highlight"
15103 "\n -material material : sets highlight material"
8e5fb5ea 15104 "\n -print : prints current state of all mentioned parameters",
15105 __FILE__, VSelectionProperties, group);
be3d8cbc 15106 theCommands.Add ("vhighlightselected",
15107 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15108 __FILE__, VSelectionProperties, group);
8e5fb5ea 15109
decdee7d 15110 theCommands.Add ("vseldump",
df23a355 15111 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|surfNormal}=depth -pickedIndex Index=1"
b40cdc2b 15112 "\n\t\t: [-xrPose base|head=base]"
decdee7d 15113 "\n\t\t: Generate an image based on detection results:"
15114 "\n\t\t: depth normalized depth values"
15115 "\n\t\t: unnormDepth unnormalized depth values"
15116 "\n\t\t: object color of detected object"
15117 "\n\t\t: owner color of detected owner"
15118 "\n\t\t: selMode color of selection mode"
114e7a90 15119 "\n\t\t: entity color of etected entity"
15120 "\n\t\t: surfNormal normal direction values",
decdee7d 15121 __FILE__, VDumpSelectionImage, group);
293211ae 15122
2108d9a2 15123 theCommands.Add ("vviewcube",
15124 "vviewcube name"
15125 "\n\t\t: Displays interactive view manipualtion object."
15126 "\n\t\t: Options: "
15127 "\n\t\t: -reset reset geomertical and visual attributes'"
15128 "\n\t\t: -size Size adapted size of View Cube"
15129 "\n\t\t: -boxSize Size box size"
0aeb8984 15130 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
2108d9a2 15131 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15132 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15133 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15134 "\n\t\t: -color Color color of View Cube"
15135 "\n\t\t: -boxColor Color box color"
15136 "\n\t\t: -boxSideColor Color box sides color"
15137 "\n\t\t: -boxEdgeColor Color box edges color"
15138 "\n\t\t: -boxCornerColor Color box corner color"
15139 "\n\t\t: -textColor Color color of side text of view cube"
15140 "\n\t\t: -innerColor Color inner box color"
15141 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15142 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
0aeb8984 15143 "\n\t\t: -xAxisTextColor Color color of X axis label"
15144 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15145 "\n\t\t: -zAxisTextColor Color color of Z axis label"
2108d9a2 15146 "\n\t\t: -font Name font name"
15147 "\n\t\t: -fontHeight Value font height"
15148 "\n\t\t: -boxFacetExtension Value box facet extension"
15149 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15150 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15151 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15152 "\n\t\t: -axesPadding Value padding between box and arrows"
15153 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15154 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15155 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15156 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15157 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15158 "\n\t\t: -duration Seconds animation duration in seconds",
15159 __FILE__, VViewCube, group);
15160
14b741b0 15161 theCommands.Add("vcolorconvert" ,
15162 "vcolorconvert {from|to} type C1 C2 C2"
15163 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15164 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15165 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15166 __FILE__,VColorConvert,group);
15167 theCommands.Add("vcolordiff" ,
15168 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15169 __FILE__,VColorDiff,group);
6a2fb7a1 15170 theCommands.Add("vselbvhbuild",
15171 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15172 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15173 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15174 "\n\t\t: -wait waits for building all of BVH",
15175 __FILE__,VSelBvhBuild,group);
2108d9a2 15176}