0032400: Visualization, TKIVtk - convert VTK camera to OCC
[occt.git] / src / ViewerTest / ViewerTest_ViewerCommands.cxx
CommitLineData
b311480e 1// Created on: 1998-09-01
2// Created by: Robert COUBLANC
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
b8db9379 17#if defined(_WIN32)
18 #include <windows.h>
19#endif
20
49582f9d 21#include <ViewerTest.hxx>
1beb58d7 22
1beb58d7 23#include <AIS_AnimationCamera.hxx>
24#include <AIS_AnimationObject.hxx>
0461e7fd 25#include <AIS_Axis.hxx>
30a1b24e 26#include <AIS_CameraFrustum.hxx>
7a324550 27#include <AIS_ColorScale.hxx>
49582f9d 28#include <AIS_InteractiveContext.hxx>
2daa5d95 29#include <AIS_LightSource.hxx>
0a768f56 30#include <AIS_ListOfInteractive.hxx>
31#include <AIS_ListIteratorOfListOfInteractive.hxx>
49582f9d 32#include <AIS_Manipulator.hxx>
2108d9a2 33#include <AIS_ViewCube.hxx>
49582f9d 34#include <AIS_Shape.hxx>
0461e7fd 35#include <AIS_Point.hxx>
49582f9d 36#include <Aspect_DisplayConnection.hxx>
8a590580 37#include <Aspect_Grid.hxx>
49582f9d 38#include <Aspect_TypeOfLine.hxx>
39#include <Draw.hxx>
40#include <Draw_Appli.hxx>
41#include <Draw_Interpretor.hxx>
08f8a185 42#include <Draw_ProgressIndicator.hxx>
49582f9d 43#include <gp_Dir.hxx>
44#include <gp_Pln.hxx>
45#include <gp_Pnt.hxx>
0461e7fd 46#include <Geom_Axis2Placement.hxx>
47#include <Geom_CartesianPoint.hxx>
61b0191c 48#include <Graphic3d_ArrayOfPolylines.hxx>
49582f9d 49#include <Graphic3d_AspectFillArea3d.hxx>
2bd4c032 50#include <Graphic3d_AspectMarker3d.hxx>
49582f9d 51#include <Graphic3d_ClipPlane.hxx>
077a220c 52#include <Graphic3d_CubeMapPacked.hxx>
53#include <Graphic3d_CubeMapSeparate.hxx>
a79f67f8 54#include <Graphic3d_GraduatedTrihedron.hxx>
b8db9379 55#include <Graphic3d_GraphicDriver.hxx>
56#include <Graphic3d_GraphicDriverFactory.hxx>
49582f9d 57#include <Graphic3d_NameOfTextureEnv.hxx>
58#include <Graphic3d_Texture2Dmanual.hxx>
269294d6 59#include <Graphic3d_TextureEnv.hxx>
60#include <Graphic3d_TextureParams.hxx>
61#include <Graphic3d_TypeOfTextureFilter.hxx>
49582f9d 62#include <Image_AlienPixMap.hxx>
63#include <Image_Diff.hxx>
64#include <Image_VideoRecorder.hxx>
b8db9379 65#include <Message.hxx>
7e785937 66#include <Message_ProgressScope.hxx>
67#include <Message_ProgressRange.hxx>
49582f9d 68#include <NCollection_DataMap.hxx>
18d715bd 69#include <NCollection_List.hxx>
d6fbb2ab 70#include <NCollection_LocalArray.hxx>
18d715bd 71#include <NCollection_Vector.hxx>
8693dfd0 72#include <OSD.hxx>
6a2fb7a1 73#include <OSD_Parallel.hxx>
208e6839 74#include <OSD_Timer.hxx>
4269bd1b 75#include <Prs3d_ShadingAspect.hxx>
0aeb8984 76#include <Prs3d_DatumAspect.hxx>
6262338c 77#include <Prs3d_Drawer.hxx>
61b0191c 78#include <Prs3d_LineAspect.hxx>
fd3f6bd0 79#include <Prs3d_Text.hxx>
80#include <Select3D_SensitivePrimitiveArray.hxx>
49582f9d 81#include <TColStd_HSequenceOfAsciiString.hxx>
82#include <TColStd_SequenceOfInteger.hxx>
83#include <TColStd_HSequenceOfReal.hxx>
84#include <TColgp_Array1OfPnt2d.hxx>
85#include <TColStd_MapOfAsciiString.hxx>
86#include <ViewerTest_AutoUpdater.hxx>
08b7a39f 87#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 88#include <ViewerTest_EventManager.hxx>
89#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
90#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
91#include <ViewerTest_CmdParser.hxx>
92#include <ViewerTest_V3dView.hxx>
93#include <V3d_AmbientLight.hxx>
94#include <V3d_DirectionalLight.hxx>
95#include <V3d_PositionalLight.hxx>
96#include <V3d_SpotLight.hxx>
0aeb8984 97#include <V3d_Trihedron.hxx>
1a96d253 98#include <V3d_Viewer.hxx>
0461e7fd 99#include <UnitsAPI.hxx>
7fd59977 100
293211ae 101#include <tcl.h>
102
692613e5 103#include <cstdlib>
25289ec1 104
58655684 105#if defined(_WIN32)
4fe56619 106 #include <WNT_WClass.hxx>
107 #include <WNT_Window.hxx>
d6fbb2ab 108 #include <WNT_HIDSpaceMouse.hxx>
b69e576a 109#elif defined(HAVE_XLIB)
4fe56619 110 #include <Xw_Window.hxx>
b69e576a 111 #include <X11/Xlib.h>
4fe56619 112 #include <X11/Xutil.h>
b69e576a 113#elif defined(__APPLE__)
114 #include <Cocoa_Window.hxx>
f9ab9f7f 115#elif defined(__EMSCRIPTEN__)
116 #include <Wasm_Window.hxx>
117 #include <emscripten/emscripten.h>
b69e576a 118#else
119 #include <Aspect_NeutralWindow.hxx>
7fd59977 120#endif
121
7fd59977 122//==============================================================================
123// VIEWER GLOBAL VARIABLES
124//==============================================================================
125
126Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 127Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 128
129Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 130extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 131
58655684 132#if defined(_WIN32)
b69e576a 133typedef WNT_Window ViewerTest_Window;
134#elif defined(HAVE_XLIB)
135typedef Xw_Window ViewerTest_Window;
136static void VProcessEvents(ClientData,int);
137#elif defined(__APPLE__)
138typedef Cocoa_Window ViewerTest_Window;
4fe56619 139extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 140extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
f9ab9f7f 141#elif defined(__EMSCRIPTEN__)
142typedef Wasm_Window ViewerTest_Window;
7fd59977 143#else
b69e576a 144typedef Aspect_NeutralWindow ViewerTest_Window;
7fd59977 145#endif
146
f9ab9f7f 147#if defined(__EMSCRIPTEN__)
148//! Return DOM id of default WebGL canvas from Module.canvas.
149EM_JS(char*, occJSModuleCanvasId, (), {
150 const aCanvasId = Module.canvas.id;
151 const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
152 const aStrPtr = Module._malloc (aNbBytes);
153 stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
154 return aStrPtr;
155});
156
157//! Return DOM id of default WebGL canvas from Module.canvas.
158static TCollection_AsciiString getModuleCanvasId()
159{
160 char* aRawId = occJSModuleCanvasId();
161 TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
162 free (aRawId);
163 return anId;
164}
165#endif
166
b69e576a 167static Handle(ViewerTest_Window)& VT_GetWindow()
168{
169 static Handle(ViewerTest_Window) aWindow;
170 return aWindow;
171}
172
18d715bd 173static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
174{
175 static Handle(Aspect_DisplayConnection) aDisplayConnection;
176 return aDisplayConnection;
177}
178
179static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
180{
181 GetDisplayConnection() = theDisplayConnection;
182}
183
18d715bd 184NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 185static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 186static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
18d715bd 187
f42753ed 188static struct
189{
190 Quantity_Color FlatColor;
191 Quantity_Color GradientColor1;
192 Quantity_Color GradientColor2;
193 Aspect_GradientFillMethod FillMethod;
194} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
195
7fd59977 196//==============================================================================
197// EVENT GLOBAL VARIABLES
198//==============================================================================
199
1beb58d7 200Standard_Boolean TheIsAnimating = Standard_False;
7fd59977 201
293211ae 202namespace
203{
204
205 //! Checks if some set is a subset of other set
206 //! @tparam TheSuperSet the type of the superset
207 //! @tparam TheSubSet the type of the subset
208 //! @param theSuperSet the superset
209 //! @param theSubSet the subset to be checked
210 //! @return true if the superset includes subset, or false otherwise
211 template <typename TheSuperSet, typename TheSubSet>
212 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
213 {
214 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
215 }
216
217 //! A variable set of keys for command-line options.
218 //! It includes a set of mandatory keys and a set of all possible keys.
219 class CommandOptionKeyVariableSet
220 {
221 public:
222 //! Default constructor
223 CommandOptionKeyVariableSet()
224 {
225 }
226
227 //! Constructor
228 //! @param theMandatoryKeySet the set of the mandatory option keys
229 //! @param theAdditionalKeySet the set of additional options that could be omitted
230 CommandOptionKeyVariableSet (
231 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
232 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
233 : myMandatoryKeySet (theMandatoryKeySet)
234 {
235 std::set_union (theMandatoryKeySet.begin(),
236 theMandatoryKeySet.end(),
237 theAdditionalKeySet.begin(),
238 theAdditionalKeySet.end(),
239 std::inserter (myFullKeySet, myFullKeySet.begin()));
240 }
241
242 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
243 //! and be contained in the full key set)
244 //! @param theCheckedKeySet the set of option keys to be checked
245 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
246 {
247 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
248 }
249
250 private:
251 //! A set of mandatory command-line option keys
252 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
253
254 //! A full set of command-line option keys (includes mandatory and additional option keys)
255 ViewerTest_CommandOptionKeySet myFullKeySet;
256 };
257
258 //! Gets some code by its name
259 //! @tparam TheCode the type of a code to be found
260 //! @param theCodeNameMap the map from code names to codes
261 //! @param theCodeName the name of a code to be found
262 //! @param theCode the code to be found
263 //! @return true if a code is found, or false otherwise
264 template <typename TheCode>
265 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
266 TCollection_AsciiString theCodeName,
267 TheCode& theCode)
268 {
269 theCodeName.LowerCase();
270 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
271 theCodeName);
272 if (aCodeIterator == theCodeNameMap.end())
273 {
274 return false;
275 }
276 theCode = aCodeIterator->second;
277 return true;
278 }
279
280 // Defines possible commands related to background changing
281 enum BackgroundCommand
282 {
077a220c 283 BackgroundCommand_Main, //!< The main command that manages other commands through options
284 BackgroundCommand_Image, //!< Sets an image as a background
285 BackgroundCommand_ImageMode, //!< Changes a background image mode
286 BackgroundCommand_Gradient, //!< Sets a gradient as a background
287 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
288 BackgroundCommand_Color, //!< Fills background with a specified color
289 BackgroundCommand_Default //!< Sets the background default color or gradient
293211ae 290 };
291
292 //! Map from background command names to its codes
293 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
294
295 //! Creates a map from background command names to its codes
296 //! @return a map from background command names to its codes
297 static BackgroundCommandNameMap createBackgroundCommandNameMap()
298 {
299 BackgroundCommandNameMap aBackgroundCommandNameMap;
077a220c 300 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
301 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
302 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
303 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
304 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
305 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
306 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
293211ae 307 return aBackgroundCommandNameMap;
308 }
309
310 //! Gets a background command by its name
311 //! @param theBackgroundCommandName the name of the background command
312 //! @param theBackgroundCommand the background command to be found
313 //! @return true if a background command is found, or false otherwise
314 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
315 BackgroundCommand& theBackgroundCommand)
316 {
317 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
318 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
319 }
320
321 //! Map from background image fill method names to its codes
322 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
323
324 //! Creates a map from background image fill method names to its codes
325 //! @return a map from background image fill method names to its codes
326 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
327 {
328 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
329 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
330 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
331 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
332 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
333 return aBackgroundImageFillMethodNameMap;
334 }
335
336 //! Gets a background image fill method by its name
337 //! @param theBackgroundImageFillMethodName the name of the background image fill method
338 //! @param theBackgroundImageFillMethod the background image fill method to be found
339 //! @return true if a background image fill method is found, or false otherwise
340 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
341 Aspect_FillMethod& theBackgroundImageFillMethod)
342 {
343 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
344 createBackgroundImageFillMethodNameMap();
345 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
346 theBackgroundImageFillMethodName,
347 theBackgroundImageFillMethod);
348 }
349
350 //! Map from background gradient fill method names to its codes
351 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
352
353 //! Creates a map from background gradient fill method names to its codes
354 //! @return a map from background gradient fill method names to its codes
355 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
356 {
357 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
358 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
359 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
360 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
361 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
362 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
363 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
364 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
365 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
366 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
367 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
368 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
369 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
370 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
371 return aBackgroundGradientFillMethodNameMap;
372 }
373
374 //! Gets a gradient fill method by its name
375 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
376 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
377 //! @return true if a gradient fill method is found, or false otherwise
378 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
379 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
380 {
381 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
382 createBackgroundGradientFillMethodNameMap();
383 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
384 theBackgroundGradientFillMethodName,
385 theBackgroundGradientFillMethod);
386 }
387
388 //! Changes the background in accordance with passed command line options
389 class BackgroundChanger
390 {
391 public:
392 //! Constructor. Prepares the command parser
393 BackgroundChanger()
394 {
395 prepareCommandParser();
396 }
397
398 //! Processes the command line and changes the background
399 //! @param theDrawInterpretor the interpreter of the Draw Harness application
400 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
401 //! @param theCommandLineArguments the array of command line arguments
402 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
403 const Standard_Integer theNumberOfCommandLineArguments,
404 const char* const* const theCommandLineArguments)
405 {
406 const char* const aBackgroundCommandName = theCommandLineArguments[0];
407 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
408 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
409 {
410 return false;
411 }
412 addCommandDescription (aBackgroundCommand);
413 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
414 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
415 }
416
417 private:
418 //! The type of functions that are able to set gradient background filling
419 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
420 const Quantity_Color& /* theColor2 */,
421 const Aspect_GradientFillMethod /* theGradientMode */);
422
423 //! The type of functions that are able to fill a background with a specific color
424 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
425
426 //! the command parser used to parse command line options and its arguments
427 ViewerTest_CmdParser myCommandParser;
428
429 //! the option key for the command that sets an image as a background
430 ViewerTest_CommandOptionKey myImageOptionKey;
431
432 //! the option key for the command that sets a background image fill type
433 ViewerTest_CommandOptionKey myImageModeOptionKey;
434
435 //! the option key for the command that sets a gradient filling for the background
436 ViewerTest_CommandOptionKey myGradientOptionKey;
437
438 //! the option key for the command that sets a background gradient filling method
439 ViewerTest_CommandOptionKey myGradientModeOptionKey;
440
441 //! the option key for the command that fills background with a specific color
442 ViewerTest_CommandOptionKey myColorOptionKey;
443
444 //! the option key for the command that sets default background gradient or color
445 ViewerTest_CommandOptionKey myDefaultOptionKey;
446
077a220c 447 //! the option key for the command that sets an environment cubemap as a background
448 ViewerTest_CommandOptionKey myCubeMapOptionKey;
449
450 //! the option key for the command that defines order of tiles in one image packed cubemap
451 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
452
453 //! the option key for the command that sets inversion of Z axis for background cubemap
454 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
455
67312b79 456 //! the option key for the command that allows skip IBL map generation
457 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
458
293211ae 459 //! the variable set of options that are allowed for the old scenario (without any option passed)
460 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
461
077a220c 462 //! the variable set of options that are allowed for setting an environment cubemap as background
463 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
464
293211ae 465 //! the variable set of options that are allowed for setting an image as a background
466 CommandOptionKeyVariableSet myImageOptionVariableSet;
467
468 //! the variable set of options that are allowed for setting a background image fill type
469 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
470
471 //! the variable set of options that are allowed for setting a gradient filling for the background
472 CommandOptionKeyVariableSet myGradientOptionVariableSet;
473
474 //! the variable set of options that are allowed for setting a background gradient filling method
475 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
476
477 //! the variable set of options that are allowed for filling a background with a specific color
478 CommandOptionKeyVariableSet myColorOptionVariableSet;
479
480 //! the variable set of options that are allowed for setting a default background gradient
481 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
482
483 //! the variable set of options that are allowed for setting a default background color
484 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
485
486 //! the variable set of options that are allowed for printing help
487 CommandOptionKeyVariableSet myHelpOptionVariableSet;
488
489 //! Adds options to command parser
490 void addOptionsToCommandParser()
491 {
492 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
493 "filename of image used as background");
494 myImageModeOptionKey = myCommandParser.AddOption (
495 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
496 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
497 "sets background gradient starting and ending colors");
498 myGradientModeOptionKey =
499 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
500 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
501 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
502 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
503 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
077a220c 504
505 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
506 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
507 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
508 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
67312b79 509 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
293211ae 510 }
511
512 //! Creates option sets used to determine if a passed option set is valid or not
513 void createOptionSets()
514 {
515 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
516 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
517 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
518
077a220c 519 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
520 aCubeMapOptionSet.insert (myCubeMapOptionKey);
521 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
522 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
67312b79 523 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
077a220c 524 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
525 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
526
293211ae 527 ViewerTest_CommandOptionKeySet anImageOptionSet;
528 anImageOptionSet.insert (myImageOptionKey);
529 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
530 anImageModeOptionSet.insert (myImageModeOptionKey);
531 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
532 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
533
534 ViewerTest_CommandOptionKeySet aGradientOptionSet;
535 aGradientOptionSet.insert (myGradientOptionKey);
536 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
537 aGradientModeOptionSet.insert (myGradientModeOptionKey);
538 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
539 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
540
541 ViewerTest_CommandOptionKeySet aColorOptionSet;
542 aColorOptionSet.insert (myColorOptionKey);
543 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
544
545 aGradientOptionSet.insert (myDefaultOptionKey);
546 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
547 aColorOptionSet.insert (myDefaultOptionKey);
548 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
549
550 ViewerTest_CommandOptionKeySet aHelpOptionSet;
551 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
552 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
553 }
554
555 //! Prepares the command parser. Adds options and creates option sets used to determine
556 //! if a passed option set is valid or not
557 void prepareCommandParser()
558 {
559 addOptionsToCommandParser();
560 createOptionSets();
561 }
562
563 //! Adds a command description to the command parser
564 //! @param theBackgroundCommand the key of the command which description is added to the command parser
565 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
566 {
567 std::string aDescription;
568 bool isMainCommand = false;
569 switch (theBackgroundCommand)
570 {
571 case BackgroundCommand_Main:
572 aDescription = "Command: vbackground (changes background or some background settings)";
573 isMainCommand = true;
574 break;
575 case BackgroundCommand_Image:
576 aDescription = "Command: vsetbg (loads image as a background)";
577 break;
578 case BackgroundCommand_ImageMode:
579 aDescription = "Command: vsetbgmode (changes background fill type)";
580 break;
581 case BackgroundCommand_Gradient:
582 aDescription = "Command: vsetgradientbg (mounts gradient background)";
583 break;
584 case BackgroundCommand_GradientMode:
585 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
586 break;
587 case BackgroundCommand_Color:
588 aDescription = "Command: vsetcolorbg (sets color background)";
589 break;
590 case BackgroundCommand_Default:
591 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
592 break;
593 default:
594 return;
595 }
596 if (!isMainCommand)
597 {
598 aDescription += "\nThis command is obsolete. Use vbackground instead.";
599 }
600 myCommandParser.SetDescription (aDescription);
601 }
602
603 //! Check if a viewer is needed to be initialized
604 //! @param theBackgroundCommand the key of the command that changes the background
605 //! @return true if processing was successful, or false otherwise
606 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
607 {
608 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
609 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
610 const bool aViewerIsNotNeeded =
611 (theBackgroundCommand == BackgroundCommand_Default)
612 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
613 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
614 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
615 return !aViewerIsNotNeeded;
616 }
617
618 //! Check if a viewer is initialized
619 //! @param theBackgroundCommandName the name of the command that changes the background
620 //! @param theDrawInterpretor the interpreter of the Draw Harness application
621 //! @return true if a viewer is initialized, or false otherwise
622 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
623 Draw_Interpretor& theDrawInterpretor)
624 {
625 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
626 if (anAISContext.IsNull())
627 {
628 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
629 return false;
630 }
631 return true;
632 }
633
634 //! Processes command options
635 //! @param theBackgroundCommandName the name of the command that changes the background
636 //! @param theBackgroundCommand the key of the command that changes the background
637 //! @param theDrawInterpretor the interpreter of the Draw Harness application
638 //! @return true if processing was successful, or false otherwise
639 bool processCommandOptions (const char* const theBackgroundCommandName,
640 const BackgroundCommand theBackgroundCommand,
641 Draw_Interpretor& theDrawInterpretor) const
642 {
643 if (myCommandParser.HasNoOption())
644 {
645 return printHelp (theBackgroundCommandName, theDrawInterpretor);
646 }
647 if (checkViewerIsNeeded (theBackgroundCommand)
648 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
649 {
650 return false;
651 }
652 if (myCommandParser.HasOnlyUnnamedOption())
653 {
654 return processUnnamedOption (theBackgroundCommand);
655 }
656 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
657 }
658
659 //! Processes the unnamed option
660 //! @param theBackgroundCommand the key of the command that changes the background
661 //! @return true if processing was successful, or false otherwise
662 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
663 {
664 switch (theBackgroundCommand)
665 {
666 case BackgroundCommand_Main:
667 return false;
668 case BackgroundCommand_Image:
669 return processImageUnnamedOption();
670 case BackgroundCommand_ImageMode:
671 return processImageModeUnnamedOption();
672 case BackgroundCommand_Gradient:
673 return processGradientUnnamedOption();
674 case BackgroundCommand_GradientMode:
675 return processGradientModeUnnamedOption();
676 case BackgroundCommand_Color:
677 return processColorUnnamedOption();
678 case BackgroundCommand_Default:
679 return processDefaultUnnamedOption();
680 default:
681 return false;
682 }
683 }
684
685 //! Processes the image unnamed option
686 //! @return true if processing was successful, or false otherwise
687 bool processImageUnnamedOption() const
688 {
689 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
690 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
691 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
692 {
693 return false;
694 }
695 std::string anImageFileName;
696 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
697 {
698 return false;
699 }
700 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
701 if (aNumberOfImageUnnamedOptionArguments == 2)
702 {
703 std::string anImageModeString;
704 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
705 {
706 return false;
707 }
708 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
709 {
710 return false;
711 }
712 }
713 setImage (anImageFileName.c_str(), anImageMode);
714 return true;
715 }
716
717 //! Processes the image mode unnamed option
718 //! @return true if processing was successful, or false otherwise
719 bool processImageModeUnnamedOption() const
720 {
721 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
722 }
723
724 //! Processes the gradient unnamed option
725 //! @param theSetGradient the function used to set a background gradient filling
726 //! @return true if processing was successful, or false otherwise
727 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
728 {
729 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
730 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
731 if (aNumberOfGradientUnnamedOptionArguments < 2)
732 {
733 return false;
734 }
735
736 Standard_Integer anArgumentIndex = 0;
737 Quantity_Color aColor1;
738 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
739 {
740 return false;
741 }
742 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
743 {
744 return false;
745 }
746
747 Quantity_Color aColor2;
748 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
749 {
750 return false;
751 }
752 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
753 {
754 return false;
755 }
756
757 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
758 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
759 {
760 std::string anGradientModeString;
761
762 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
763 anArgumentIndex,
764 anGradientModeString))
765 {
766 return false;
767 }
768 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
769 {
770 return false;
771 }
772 ++anArgumentIndex;
773 }
774 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
775 {
776 return false;
777 }
778 theSetGradient (aColor1, aColor2, aGradientMode);
779 return true;
780 }
781
782 //! Processes the gradient mode unnamed option
783 //! @return true if processing was successful, or false otherwise
784 bool processGradientModeUnnamedOption() const
785 {
786 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
787 }
788
789 //! Processes the color unnamed option
790 //! @param theSetColor the function used to set a background color
791 //! @return true if processing was successful, or false otherwise
792 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
793 {
794 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
795 }
796
797 //! Processes the default back unnamed option
798 //! @return true if processing was successful, or false otherwise
799 bool processDefaultUnnamedOption() const
800 {
801 if (processGradientUnnamedOption (setDefaultGradient))
802 {
803 return true;
804 }
805 return processColorUnnamedOption (setDefaultColor);
806 }
807
808 //! Processes named options
809 //! @param theBackgroundCommandName the name of the command that changes the background
810 //! @param theBackgroundCommand the key of the command that changes the background
811 //! @param theDrawInterpretor the interpreter of the Draw Harness application
812 //! @return true if processing was successful, or false otherwise
813 bool processNamedOptions (const char* const theBackgroundCommandName,
814 const BackgroundCommand theBackgroundCommand,
815 Draw_Interpretor& theDrawInterpretor) const
816 {
817 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
818 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
077a220c 819 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
820 {
821 return processCubeMapOptionSet();
822 }
293211ae 823 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
824 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
825 {
826 return processImageOptionSet();
827 }
828 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
829 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
830 {
831 return processImageModeOptionSet();
832 }
833 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
834 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
835 {
836 return processGradientOptionSet();
837 }
838 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
839 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
840 {
841 return processGradientModeOptionSet();
842 }
843 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
844 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
845 {
846 return processColorOptionSet();
847 }
848 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
849 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
850 && (theBackgroundCommand == BackgroundCommand_Default)))
851 {
852 return processDefaultGradientOptionSet();
853 }
854 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
855 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
856 {
857 return processDefaultColorOptionSet();
858 }
859 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
860 {
861 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
862 }
863 return false;
864 }
865
077a220c 866 //! Process the cubemap option set in named and unnamed case.
867 //! @return true if processing was successful, or false otherwise
868 bool processCubeMapOptionSet() const
869 {
870 NCollection_Array1<TCollection_AsciiString> aFilePaths;
871
872 if (!processCubeMapOptions (aFilePaths))
873 {
874 return false;
875 }
876
877 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
878
879 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
880 {
881 if (!processCubeMapOrderOptions (anOrder))
882 {
883 return false;
884 }
885 }
886
887 bool aZIsInverted = false;
888 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
889 {
890 if (!processCubeMapInvertedZOptionSet())
891 {
892 return false;
893 }
894 aZIsInverted = true;
895 }
896
67312b79 897 bool aToGenPBREnv = true;
898 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
899 {
900 if (!processCubeMapDoNotGenPBREnvOptionSet())
901 {
902 return false;
903 }
904 aToGenPBREnv = false;
905 }
906
907 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
077a220c 908 return true;
909 }
910
293211ae 911 //! Processes the image option set
912 //! @return true if processing was successful, or false otherwise
913 bool processImageOptionSet() const
914 {
915 std::string anImageFileName;
916 if (!processImageOption (anImageFileName))
917 {
918 return false;
919 }
920 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
921 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
922 {
923 return false;
924 }
925 setImage (anImageFileName.c_str(), anImageMode);
926 return true;
927 }
928
929 //! Processes the image mode option set
930 //! @return true if processing was successful, or false otherwise
931 bool processImageModeOptionSet() const
932 {
933 return processImageModeOptionSet (myImageModeOptionKey);
934 }
935
936 //! Processes the image mode option set
937 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
938 //! @return true if processing was successful, or false otherwise
939 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
940 {
941 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
942 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
943 {
944 return false;
945 }
946 setImageMode (anImageMode);
947 return true;
948 }
949
950 //! Processes the gradient option set
951 //! @param theSetGradient the function used to set a background gradient filling
952 //! @return true if processing was successful, or false otherwise
953 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
954 {
955 Quantity_Color aColor1;
956 Quantity_Color aColor2;
957 if (!processGradientOption (aColor1, aColor2))
958 {
959 return false;
960 }
961 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
962 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
963 {
964 return false;
965 }
966 theSetGradient (aColor1, aColor2, aGradientMode);
967 return true;
968 }
969
970 //! Processes the gradient mode option set
971 //! @return true if processing was successful, or false otherwise
972 bool processGradientModeOptionSet() const
973 {
974 return processGradientModeOptionSet (myGradientModeOptionKey);
975 }
976
977 //! Processes the gradient mode option set
978 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
979 //! @return true if processing was successful, or false otherwise
980 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
981 {
982 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
983 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
984 {
985 return false;
986 }
987 setGradientMode (aGradientMode);
988 return true;
989 }
990
991 //! Processes the color option set
992 //! @param theSetColor the function used to set a background color
993 //! @return true if processing was successful, or false otherwise
994 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
995 {
996 return processColorOptionSet (myColorOptionKey, theSetColor);
997 }
998
999 //! Processes the default color option set
1000 //! @return true if processing was successful, or false otherwise
1001 bool processDefaultGradientOptionSet() const
1002 {
1003 return processGradientOptionSet (setDefaultGradient);
1004 }
1005
1006 //! Processes the default gradient option set
1007 //! @return true if processing was successful, or false otherwise
1008 bool processDefaultColorOptionSet() const
1009 {
1010 return processColorOptionSet (setDefaultColor);
1011 }
1012
1013 //! Processes the color option set
1014 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1015 //! @param theSetColor the function used to set a background color
1016 //! @return true if processing was successful, or false otherwise
1017 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
1018 SetColorFunction* const theSetColor = setColor) const
1019 {
1020 Quantity_Color aColor;
1021 if (!processColorOption (theColorOptionKey, aColor))
1022 {
1023 return false;
1024 }
1025 theSetColor (aColor);
1026 return true;
1027 }
1028
1029 //! Processes the help option set
1030 //! @param theBackgroundCommandName the name of the command that changes the background
1031 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1032 //! @return true if processing was successful, or false otherwise
1033 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1034 {
1035 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1036 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1037 if (aNumberOfHelpOptionArguments != 0)
1038 {
1039 return false;
1040 }
1041 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1042 }
1043
077a220c 1044 //! Processes the cubemap option
1045 //! @param theFilePaths the array of filenames of cubemap sides
1046 //! @return true if processing was successful, or false otherwise
1047 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1048 {
1049 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1050
1051 if (aNumberOfCubeMapOptionArguments != 1
1052 && aNumberOfCubeMapOptionArguments != 6)
1053 {
1054 return false;
1055 }
1056
1057 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1058
1059 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1060 {
1061 std::string aCubeMapFileName;
1062 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1063 {
1064 return false;
1065 }
1066 theFilePaths[i] = aCubeMapFileName.c_str();
1067 }
1068
1069 return true;
1070 }
1071
67312b79 1072 //! Processes the inverted z cubemap option
077a220c 1073 //! @return true if processing was successful, or false otherwise
1074 bool processCubeMapInvertedZOptionSet () const
1075 {
1076 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1077 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1078
1079 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1080 {
1081 return false;
1082 }
1083
1084 return true;
1085 }
1086
67312b79 1087 //! Processes the option allowing to skip IBM maps generation
1088 //! @return true if processing was successful, or false otherwise
1089 bool processCubeMapDoNotGenPBREnvOptionSet() const
1090 {
1091 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1092 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1093
1094 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1095 {
1096 return false;
1097 }
1098
1099 return true;
1100 }
1101
077a220c 1102 //! Processes the tiles order option
1103 //! @param theOrder the array of indexes if cubemap sides in tile grid
1104 //! @return true if processing was successful, or false otherwise
1105 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1106 {
1107 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1108 myCubeMapOrderOptionKey);
1109
1110 if (aNumberOfCubeMapOrderOptionArguments != 6)
1111 {
1112 return false;
1113 }
1114
1115
1116 for (unsigned int i = 0; i < 6; ++i)
1117 {
1118 std::string anOrderItem;
1119 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1120 {
1121 return false;
1122 }
1123
1124 theOrder.Set (Graphic3d_CubeMapSide (i),
1125 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1126 }
1127
1128 return theOrder.IsValid();
1129 }
1130
293211ae 1131 //! Processes the image option
1132 //! @param theImageFileName the filename of the image to be used as a background
1133 //! @return true if processing was successful, or false otherwise
1134 bool processImageOption (std::string& theImageFileName) const
1135 {
1136 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1137 myImageOptionKey);
1138 if (aNumberOfImageOptionArguments != 1)
1139 {
1140 return false;
1141 }
1142 std::string anImageFileName;
1143 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1144 {
1145 return false;
1146 }
1147 theImageFileName = anImageFileName;
1148 return true;
1149 }
1150
1151 //! Processes the image mode option
1152 //! @param theImageMode the fill type used for a background image
1153 //! @return true if processing was successful, or false otherwise
1154 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1155 {
1156 return processImageModeOption (myImageModeOptionKey, theImageMode);
1157 }
1158
1159 //! Processes the image mode option
1160 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1161 //! @param theImageMode the fill type used for a background image
1162 //! @return true if processing was successful, or false otherwise
1163 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1164 Aspect_FillMethod& theImageMode) const
1165 {
1166 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1167 }
1168
1169 //! Processes the gradient option
1170 //! @param theColor1 the gradient starting color
1171 //! @param theColor2 the gradient ending color
1172 //! @return true if processing was successful, or false otherwise
1173 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1174 {
1175 Standard_Integer anArgumentIndex = 0;
1176 Quantity_Color aColor1;
1177 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1178 {
1179 return false;
1180 }
1181 Quantity_Color aColor2;
1182 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1183 {
1184 return false;
1185 }
1186 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1187 myGradientOptionKey);
1188 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1189 {
1190 return false;
1191 }
1192 theColor1 = aColor1;
1193 theColor2 = aColor2;
1194 return true;
1195 }
1196
1197 //! Processes the gradient mode option
1198 //! @param theGradientMode the fill method used for a background gradient filling
1199 //! @return true if processing was successful, or false otherwise
1200 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1201 {
1202 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1203 }
1204
1205 //! Processes the gradient mode option
1206 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1207 //! @param theGradientMode the fill method used for a background gradient filling
1208 //! @return true if processing was successful, or false otherwise
1209 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1210 Aspect_GradientFillMethod& theGradientMode) const
1211 {
1212 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1213 }
1214
1215 //! Processes some mode option
1216 //! @tparam TheMode the type of a mode to be processed
1217 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1218 //! @param theMode a mode to be processed
1219 //! @return true if processing was successful, or false otherwise
1220 template <typename TheMode>
1221 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1222 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1223 TheMode& /* theMode */),
1224 TheMode& theMode) const
1225 {
1226 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1227 theModeOptionKey);
1228 if (aNumberOfModeOptionArguments != 1)
1229 {
1230 return false;
1231 }
1232 std::string aModeString;
1233 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1234 {
1235 return false;
1236 }
1237 TheMode aMode = TheMode();
1238 if (!theGetModeByName (aModeString.c_str(), aMode))
1239 {
1240 return false;
1241 }
1242 theMode = aMode;
1243 return true;
1244 }
1245
1246 //! Processes the color option
1247 //! @param theColor a color used for filling a background
1248 //! @return true if processing was successful, or false otherwise
1249 bool processColorOption (Quantity_Color& theColor) const
1250 {
1251 return processColorOption (myColorOptionKey, theColor);
1252 }
1253
1254 //! Processes the color option
1255 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1256 //! @param theColor a color used for filling a background
1257 //! @return true if processing was successful, or false otherwise
1258 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1259 {
1260 Standard_Integer anArgumentIndex = 0;
1261 Quantity_Color aColor;
1262 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1263 {
1264 return false;
1265 }
1266 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1267 theColorOptionKey);
1268 if (anArgumentIndex != aNumberOfColorOptionArguments)
1269 {
1270 return false;
1271 }
1272 theColor = aColor;
1273 return true;
1274 }
1275
1276 //! Prints helping message
1277 //! @param theBackgroundCommandName the name of the command that changes the background
1278 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1279 //! @return true if printing was successful, or false otherwise
1280 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1281 {
1282 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1283 }
1284
077a220c 1285 //! Sets the cubemap as a background
1286 //! @param theFileNames the array of filenames of packed or multifile cubemap
1287 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1288 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1289 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
67312b79 1290 bool theZIsInverted = false,
1291 bool theToGenPBREnv = true)
077a220c 1292 {
1293 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1294 Handle(Graphic3d_CubeMap) aCubeMap;
1295
1296 if (theFileNames.Size() == 1)
1297 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1298 else
1299 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1300
1301 aCubeMap->SetZInversion (theZIsInverted);
1302
1303 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1304 aCubeMap->GetParams()->SetRepeat(Standard_False);
1305 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1306
67312b79 1307 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
077a220c 1308 }
1309
293211ae 1310 //! Sets the image as a background
1311 //! @param theImageFileName the filename of the image to be used as a background
1312 //! @param theImageMode the fill type used for a background image
1313 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1314 {
1315 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1316 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1317 }
1318
1319 //! Sets the fill type used for a background image
1320 //! @param theImageMode the fill type used for a background image
1321 static void setImageMode (const Aspect_FillMethod theImageMode)
1322 {
1323 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1324 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1325 }
1326
1327 //! Sets the gradient filling for a background
1328 //! @param theColor1 the gradient starting color
1329 //! @param theColor2 the gradient ending color
1330 //! @param theGradientMode the fill method used for a background gradient filling
1331 static void setGradient (const Quantity_Color& theColor1,
1332 const Quantity_Color& theColor2,
1333 const Aspect_GradientFillMethod theGradientMode)
1334 {
1335 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1336 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1337 }
1338
1339 //! Sets the fill method used for a background gradient filling
1340 //! @param theGradientMode the fill method used for a background gradient filling
1341 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1342 {
1343 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1344 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1345 }
1346
1347 //! Sets the color used for filling a background
1348 //! @param theColor the color used for filling a background
1349 static void setColor (const Quantity_Color& theColor)
1350 {
1351 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1352 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1353 aCurrentView->SetBackgroundColor (theColor);
1354 aCurrentView->Update();
1355 }
1356
1357 //! Sets the gradient filling for a background in a default viewer
1358 //! @param theColor1 the gradient starting color
1359 //! @param theColor2 the gradient ending color
1360 //! @param theGradientMode the fill method used for a background gradient filling
1361 static void setDefaultGradient (const Quantity_Color& theColor1,
1362 const Quantity_Color& theColor2,
1363 const Aspect_GradientFillMethod theGradientMode)
1364 {
1365 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1366 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1367 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1368 setDefaultGradient();
1369 }
1370
1371 //! Sets the color used for filling a background in a default viewer
1372 //! @param theColor the color used for filling a background
1373 static void setDefaultColor (const Quantity_Color& theColor)
1374 {
1375 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1376 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1377 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1378 ViewerTest_DefaultBackground.FlatColor = theColor;
1379 setDefaultGradient();
1380 setDefaultColor();
1381 }
1382
1383 //! Sets the gradient filling for a background in a default viewer.
1384 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1385 static void setDefaultGradient()
1386 {
1387 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1388 anInteractiveContextIterator (ViewerTest_myContexts);
1389 anInteractiveContextIterator.More();
1390 anInteractiveContextIterator.Next())
1391 {
1392 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1393 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1394 ViewerTest_DefaultBackground.GradientColor2,
1395 ViewerTest_DefaultBackground.FillMethod);
1396 }
1397 }
1398
1399 //! Sets the color used for filling a background in a default viewer.
1400 //! The color value is taken from ViewerTest_DefaultBackground structure
1401 static void setDefaultColor()
1402 {
1403 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1404 anInteractiveContextIterator (ViewerTest_myContexts);
1405 anInteractiveContextIterator.More();
1406 anInteractiveContextIterator.Next())
1407 {
1408 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1409 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1410 }
1411 }
1412 };
1413
1414} // namespace
b12e1c7b 1415
7fd59977 1416//==============================================================================
1417
57c28b61 1418#ifdef _WIN32
e8e157df 1419static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
7fd59977 1420#endif
1421
7fd59977 1422//==============================================================================
1423//function : WClass
1424//purpose :
1425//==============================================================================
1426
1bd04b5a 1427const Handle(WNT_WClass)& ViewerTest::WClass()
7fd59977 1428{
1bd04b5a 1429 static Handle(WNT_WClass) theWClass;
58655684 1430#if defined(_WIN32)
4fe56619 1431 if (theWClass.IsNull())
1432 {
7c65581d 1433 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1434 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1435 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1436 }
1437#endif
1438 return theWClass;
1439}
1440
18d715bd 1441//==============================================================================
1442//function : CreateName
1443//purpose : Create numerical name for new object in theMap
1444//==============================================================================
1445template <typename ObjectType>
1446TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1447 const TCollection_AsciiString& theDefaultString)
1448{
1449 if (theObjectMap.IsEmpty())
1450 return theDefaultString + TCollection_AsciiString(1);
1451
1452 Standard_Integer aNextKey = 1;
1453 Standard_Boolean isFound = Standard_False;
1454 while (!isFound)
1455 {
1456 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1457 // Look for objects with default names
1458 if (theObjectMap.IsBound1(aStringKey))
1459 {
1460 aNextKey++;
1461 }
1462 else
1463 isFound = Standard_True;
1464 }
1465
1466 return theDefaultString + TCollection_AsciiString(aNextKey);
1467}
1468
1469//==============================================================================
1470//structure : ViewerTest_Names
1471//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1472//==============================================================================
1473struct ViewerTest_Names
1474{
1475private:
1476 TCollection_AsciiString myDriverName;
1477 TCollection_AsciiString myViewerName;
1478 TCollection_AsciiString myViewName;
1479
1480public:
1481
1482 const TCollection_AsciiString& GetDriverName () const
1483 {
1484 return myDriverName;
1485 }
1486 void SetDriverName (const TCollection_AsciiString& theDriverName)
1487 {
1488 myDriverName = theDriverName;
1489 }
1490 const TCollection_AsciiString& GetViewerName () const
1491 {
1492 return myViewerName;
1493 }
1494 void SetViewerName (const TCollection_AsciiString& theViewerName)
1495 {
1496 myViewerName = theViewerName;
1497 }
1498 const TCollection_AsciiString& GetViewName () const
1499 {
1500 return myViewName;
1501 }
1502 void SetViewName (const TCollection_AsciiString& theViewName)
1503 {
1504 myViewName = theViewName;
1505 }
1506
1507 //===========================================================================
1508 //function : Constructor for ViewerTest_Names
1509 //purpose : Get view, viewer, driver names from custom string
1510 //===========================================================================
1511
1512 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1513 {
1514 TCollection_AsciiString aName(theInputString);
1515 if (theInputString.IsEmpty())
1516 {
1517 // Get current configuration
1518 if (ViewerTest_myDrivers.IsEmpty())
1519 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1520 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1521 else
1522 myDriverName = ViewerTest_myDrivers.Find2
1523 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1524
1525 if(ViewerTest_myContexts.IsEmpty())
1526 {
1527 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1528 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1529 }
1530 else
c48e2889 1531 {
18d715bd 1532 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1533 }
18d715bd 1534
c48e2889 1535 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1536 }
1537 else
1538 {
1539 // There is at least view name
1540 Standard_Integer aParserNumber = 0;
1541 for (Standard_Integer i = 0; i < 3; ++i)
1542 {
1543 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1544 if(aParserPos != -1)
1545 {
1546 aParserNumber++;
1547 aName.Split(aParserPos-1);
1548 }
1549 else
1550 break;
1551 }
1552 if (aParserNumber == 0)
1553 {
1554 // Only view name
1555 if (!ViewerTest::GetAISContext().IsNull())
1556 {
1557 myDriverName = ViewerTest_myDrivers.Find2
1558 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1559 myViewerName = ViewerTest_myContexts.Find2
1560 (ViewerTest::GetAISContext());
1561 }
1562 else
1563 {
1564 // There is no opened contexts here, need to create names for viewer and driver
1565 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1566 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1567
1568 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1569 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1570 }
1571 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1572 }
1573 else if (aParserNumber == 1)
1574 {
1575 // Here is viewerName/viewName
1576 if (!ViewerTest::GetAISContext().IsNull())
1577 myDriverName = ViewerTest_myDrivers.Find2
1578 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1579 else
1580 {
1581 // There is no opened contexts here, need to create name for driver
1582 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1583 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1584 }
1585 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1586
1587 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1588 }
1589 else
1590 {
1591 //Here is driverName/viewerName/viewName
1592 myDriverName = TCollection_AsciiString(aName);
1593
1594 TCollection_AsciiString aViewerName(theInputString);
1595 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1596 myViewerName = TCollection_AsciiString(aViewerName);
1597
1598 myViewName = TCollection_AsciiString(theInputString);
1599 }
1600 }
1601 }
1602};
1603
1604//==============================================================================
1605//function : FindContextByView
1606//purpose : Find AIS_InteractiveContext by View
1607//==============================================================================
1608
1609Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1610{
1611 Handle(AIS_InteractiveContext) anAISContext;
1612
1613 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1614 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1615 {
1616 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1617 return anIter.Key2();
1618 }
1619 return anAISContext;
1620}
1621
18d715bd 1622//==============================================================================
1623//function : IsWindowOverlapped
1624//purpose : Check if theWindow overlapp another view
1625//==============================================================================
1626
1627Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1628 const Standard_Integer thePxTop,
1629 const Standard_Integer thePxRight,
1630 const Standard_Integer thePxBottom,
1631 TCollection_AsciiString& theViewId)
1632{
1633 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1634 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1635 {
1636 Standard_Integer aTop = 0,
1637 aLeft = 0,
1638 aRight = 0,
1639 aBottom = 0;
1640 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1641 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1642 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1643 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1644 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1645 {
1646 theViewId = anIter.Key1();
1647 return Standard_True;
1648 }
1649 }
1650 return Standard_False;
1651}
1652
1653// Workaround: to create and delete non-orthographic views outside ViewerTest
1654void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1655{
1656 ViewerTest_myViews.UnBind1 (theName);
1657}
1658
1659void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1660 const Handle(V3d_View)& theView)
1661{
1662 ViewerTest_myViews.Bind (theName, theView);
1663}
1664
1665TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1666{
1667 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1668}
8693dfd0 1669
7fd59977 1670//==============================================================================
1671//function : ViewerInit
1672//purpose : Create the window viewer and initialize all the global variable
1673//==============================================================================
1674
18d715bd 1675TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1676 const Standard_Integer thePxTop,
1677 const Standard_Integer thePxWidth,
1678 const Standard_Integer thePxHeight,
9e04ccdc 1679 const TCollection_AsciiString& theViewName,
1680 const TCollection_AsciiString& theDisplayName,
72ed0644 1681 const Handle(V3d_View)& theViewToClone,
1682 const Standard_Boolean theIsVirtual)
7fd59977 1683{
8c3c9904 1684 // Default position and dimension of the viewer window.
4fe56619 1685 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1686 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1687 // The position corresponds to the window's client area, thus some
8c3c9904 1688 // gap is added for window frame to be visible.
f9ab9f7f 1689 Standard_Integer aPxLeft = 20, aPxTop = 40;
1690 Standard_Integer aPxWidth = 409, aPxHeight = 409;
1691 Standard_Boolean isDefViewSize = Standard_True;
18d715bd 1692 Standard_Boolean toCreateViewer = Standard_False;
72ed0644 1693 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
9e04ccdc 1694 if (!theViewToClone.IsNull())
1695 {
1696 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
f9ab9f7f 1697 isDefViewSize = Standard_False;
1698 #if !defined(__EMSCRIPTEN__)
1699 (void )isDefViewSize;
1700 #endif
9e04ccdc 1701 }
18d715bd 1702
b8db9379 1703 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1704 if (aFactory.IsNull())
1705 {
1706 Draw::GetInterpretor().Eval ("pload OPENGL");
1707 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1708 if (aFactory.IsNull())
1709 {
b8ef513c 1710 Draw::GetInterpretor().Eval ("pload GLES");
1711 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
1712 if (aFactory.IsNull())
1713 {
1714 throw Standard_ProgramError("Error: no graphic driver factory found");
1715 }
b8db9379 1716 }
1717 }
1718
1719 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
18d715bd 1720 ViewerTest_Names aViewNames(theViewName);
f9ab9f7f 1721 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1722 {
18d715bd 1723 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
f9ab9f7f 1724 }
18d715bd 1725
1726 if (thePxLeft != 0)
f9ab9f7f 1727 {
18d715bd 1728 aPxLeft = thePxLeft;
f9ab9f7f 1729 }
18d715bd 1730 if (thePxTop != 0)
f9ab9f7f 1731 {
18d715bd 1732 aPxTop = thePxTop;
f9ab9f7f 1733 }
18d715bd 1734 if (thePxWidth != 0)
f9ab9f7f 1735 {
1736 isDefViewSize = Standard_False;
18d715bd 1737 aPxWidth = thePxWidth;
f9ab9f7f 1738 }
18d715bd 1739 if (thePxHeight != 0)
f9ab9f7f 1740 {
1741 isDefViewSize = Standard_False;
7fd59977 1742 aPxHeight = thePxHeight;
f9ab9f7f 1743 }
4269bd1b 1744
18d715bd 1745 // Get graphic driver (create it or get from another view)
8693dfd0 1746 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1747 if (isNewDriver)
18d715bd 1748 {
1749 // Get connection string
b69e576a 1750 #if defined(HAVE_XLIB)
8693dfd0 1751 if (!theDisplayName.IsEmpty())
1752 {
1753 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1754 }
18d715bd 1755 else
8693dfd0 1756 {
b69e576a 1757 Aspect_XDisplay* aDispX = NULL;
8693dfd0 1758 // create dedicated display connection instead of reusing Tk connection
b69e576a 1759 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
8693dfd0 1760 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1761 Tcl_Interp* aTclInterp = aCommands.Interp();
1762 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1763 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1764 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1765 }
18d715bd 1766 #else
498ce76b 1767 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1768 SetDisplayConnection (new Aspect_DisplayConnection ());
1769 #endif
14cb22a1 1770
b8db9379 1771 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
72ed0644 1772 if (isVirtual)
14cb22a1 1773 {
1774 // don't waste the time waiting for VSync when window is not displayed on the screen
b8db9379 1775 aGraphicDriver->SetVerticalSync (false);
14cb22a1 1776 }
14cb22a1 1777
18d715bd 1778 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1779 toCreateViewer = Standard_True;
1780 }
1781 else
1782 {
b8db9379 1783 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
7fd59977 1784 }
1785
18d715bd 1786 //Dispose the window if input parameters are default
1787 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1788 {
18d715bd 1789 Standard_Integer aTop = 0,
1790 aLeft = 0,
1791 aRight = 0,
1792 aBottom = 0,
1793 aScreenWidth = 0,
1794 aScreenHeight = 0;
1795
1796 // Get screen resolution
b69e576a 1797#if defined(_WIN32)
18d715bd 1798 RECT aWindowSize;
1799 GetClientRect(GetDesktopWindow(), &aWindowSize);
1800 aScreenHeight = aWindowSize.bottom;
1801 aScreenWidth = aWindowSize.right;
b69e576a 1802#elif defined(HAVE_XLIB)
1803 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
1804 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
1805 aScreenWidth = WidthOfScreen(aScreen);
1806 aScreenHeight = HeightOfScreen(aScreen);
1807#elif defined(__APPLE__)
18d715bd 1808 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1809#else
b69e576a 1810 // not implemented
18d715bd 1811#endif
1812
1813 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1814
1815 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1816 {
18d715bd 1817 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1818
1819 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1820 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1821 {
1822 if (aBottom + aPxHeight + 40 > aScreenHeight)
1823 {
1824 aPxLeft = 20;
1825 aPxTop = 40;
1826 break;
1827 }
1828 aPxLeft = 20;
1829 aPxTop = aBottom + 40;
1830 }
1831 else
1832 aPxLeft = aRight + 20;
dc3fe572 1833 }
18d715bd 1834 }
1835
1836 // Get viewer name
1837 TCollection_AsciiString aTitle("3D View - ");
1838 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1839
1840 // Change name of current active window
49582f9d 1841 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
18d715bd 1842 {
49582f9d 1843 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
18d715bd 1844 }
1845
1846 // Create viewer
eb4320f2 1847 Handle(V3d_Viewer) a3DViewer;
18d715bd 1848 // If it's the single view, we first look for empty context
1849 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1850 {
1851 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1852 anIter(ViewerTest_myContexts);
1853 if (anIter.More())
1854 ViewerTest::SetAISContext (anIter.Value());
1855 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1856 }
1857 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1858 {
1859 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1860 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1861 }
eb4320f2 1862 else if (a3DViewer.IsNull())
18d715bd 1863 {
1864 toCreateViewer = Standard_True;
6a24c6de 1865 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1866 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1867 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1868 ViewerTest_DefaultBackground.GradientColor2,
1869 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1870 }
1871
1872 // AIS context setup
1873 if (ViewerTest::GetAISContext().IsNull() ||
1874 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1875 {
e79a94b9 1876 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1877 ViewerTest::SetAISContext (aContext);
1878 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1879 }
1880 else
e79a94b9 1881 {
18d715bd 1882 ViewerTest::ResetEventManager();
e79a94b9 1883 }
18d715bd 1884
1885 // Create window
e79a94b9 1886#if defined(_WIN32)
1bd04b5a 1887 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
72ed0644 1888 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1889 aPxLeft, aPxTop,
1890 aPxWidth, aPxHeight,
1891 Quantity_NOC_BLACK);
d6fbb2ab 1892 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
b69e576a 1893#elif defined(HAVE_XLIB)
1894 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1895 aTitle.ToCString(),
1896 aPxLeft, aPxTop,
1897 aPxWidth, aPxHeight);
1898#elif defined(__APPLE__)
e79a94b9 1899 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1900 aPxLeft, aPxTop,
1901 aPxWidth, aPxHeight);
1902 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
f9ab9f7f 1903#elif defined(__EMSCRIPTEN__)
1904 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
1905 // the code should be revised for handling multiple canvas elements (which is technically also possible)
1906 TCollection_AsciiString aCanvasId = getModuleCanvasId();
1907 if (!aCanvasId.IsEmpty())
1908 {
1909 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
1910 }
1911
1912 VT_GetWindow() = new Wasm_Window (aCanvasId);
1913 Graphic3d_Vec2i aRealSize;
1914 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
1915 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
1916 {
1917 // Wasm_Window wraps an existing HTML element without creating a new one.
1918 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
1919 // but resize canvas if vinit has been called with explicitly specified dimensions.
1920 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxWidth, aPxHeight));
1921 }
7fd59977 1922#else
b69e576a 1923 // not implemented
1924 VT_GetWindow() = new Aspect_NeutralWindow();
1925 VT_GetWindow()->SetSize (aPxWidth, aPxHeight);
7fd59977 1926#endif
72ed0644 1927 VT_GetWindow()->SetVirtual (isVirtual);
7fd59977 1928
d09dda09 1929 // View setup
9e04ccdc 1930 Handle(V3d_View) aView;
1931 if (!theViewToClone.IsNull())
1932 {
2e93433e 1933 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1934 }
1935 else
1936 {
2e93433e 1937 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1938 }
1939
d09dda09 1940 aView->SetWindow (VT_GetWindow());
c3282ec1 1941 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1942
18d715bd 1943 ViewerTest::CurrentView(aView);
1944 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1945
18d715bd 1946 // Setup for X11 or NT
f9ab9f7f 1947 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1948 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
7fd59977 1949
18d715bd 1950 // Set parameters for V3d_View and V3d_Viewer
1951 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1952 aV3dView->SetComputedMode(Standard_False);
7fd59977 1953
18d715bd 1954 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1955 if (toCreateViewer)
1956 {
7fd59977 1957 a3DViewer->SetDefaultLights();
1958 a3DViewer->SetLightOn();
18d715bd 1959 }
7fd59977 1960
b69e576a 1961#if defined(HAVE_XLIB)
8693dfd0 1962 if (isNewDriver)
1963 {
b69e576a 1964 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
8693dfd0 1965 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1966 }
1967#endif
7fd59977 1968
7fd59977 1969 VT_GetWindow()->Map();
4269bd1b 1970
18d715bd 1971 // Set the handle of created view in the event manager
1972 ViewerTest::ResetEventManager();
1973
4fe56619 1974 ViewerTest::CurrentView()->Redraw();
18d715bd 1975
1976 aView.Nullify();
1977 a3DViewer.Nullify();
18d715bd 1978
1979 return aViewNames.GetViewName();
1980}
1981
4269bd1b 1982//==============================================================================
1983//function : RedrawAllViews
1984//purpose : Redraw all created views
1985//==============================================================================
1986void ViewerTest::RedrawAllViews()
1987{
1988 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1989 for (; aViewIt.More(); aViewIt.Next())
1990 {
1991 const Handle(V3d_View)& aView = aViewIt.Key2();
1992 aView->Redraw();
1993 }
1994}
1995
b8db9379 1996//==============================================================================
1997//function : VDriver
1998//purpose :
1999//==============================================================================
2000static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2001{
2002 if (theArgsNb == 1)
2003 {
2004 theDi << "Registered: ";
2005 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2006 aFactoryIter.More(); aFactoryIter.Next())
2007 {
2008 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2009 theDi << aFactory->Name() << " ";
2010 }
2011
2012 theDi << "\n";
2013 theDi << "Default: ";
2014 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2015 {
2016 theDi << aFactory->Name();
2017 }
2018 else
2019 {
2020 theDi << "NONE";
2021 }
2022 return 0;
2023 }
2024
2025 TCollection_AsciiString aNewActive;
2026 bool toLoad = false;
2027 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
2028 {
2029 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2030 anArgCase.LowerCase();
2031 if (anArgCase == "-list")
2032 {
2033 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2034 aFactoryIter.More(); aFactoryIter.Next())
2035 {
2036 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
2037 theDi << aFactory->Name() << " ";
2038 }
2039 }
2040 else if ((anArgCase == "-default"
2041 || anArgCase == "-load")
2042 && aNewActive.IsEmpty())
2043 {
2044 toLoad = (anArgCase == "-load");
2045 if (anArgIter + 1 < theArgsNb)
2046 {
2047 aNewActive = theArgVec[++anArgIter];
2048 }
2049 else if (toLoad)
2050 {
2051 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
2052 return 1;
2053 }
2054 else
2055 {
2056 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
2057 {
2058 theDi << aFactory->Name();
2059 }
2060 else
2061 {
2062 theDi << "NONE";
2063 }
2064 }
2065 }
2066 else if (aNewActive.IsEmpty())
2067 {
2068 aNewActive = theArgVec[anArgIter];
2069 }
2070 else
2071 {
2072 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
2073 return 1;
2074 }
2075 }
2076
2077 if (!aNewActive.IsEmpty())
2078 {
2079 const TCollection_AsciiString aNameCopy = aNewActive;
2080 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
2081 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
2082 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
2083 {
2084 aNewActive = "tkopengl";
2085 }
b8ef513c 2086 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
2087 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
2088 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
2089 {
2090 aNewActive = "tkopengles";
2091 }
b8db9379 2092 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
2093 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
2094 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
2095 {
2096 aNewActive = "tkd3dhost";
2097 }
2098
2099 if (toLoad)
2100 {
2101 if (aNewActive == "tkopengl")
2102 {
2103 Draw::GetInterpretor().Eval ("pload OPENGL");
2104 }
b8ef513c 2105 else if (aNewActive == "tkopengles")
2106 {
2107 Draw::GetInterpretor().Eval ("pload GLES");
2108 }
b8db9379 2109 else if (aNewActive == "tkd3dhost")
2110 {
2111 Draw::GetInterpretor().Eval ("pload D3DHOST");
2112 }
2113 else
2114 {
2115 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
2116 return 1;
2117 }
2118 }
2119
2120 bool isFound = false;
2121 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
2122 aFactoryIter.More(); aFactoryIter.Next())
2123 {
2124 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
2125 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
2126 {
2127 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
2128 isFound = true;
2129 break;
2130 }
2131 }
2132
2133 if (!isFound)
2134 {
2135 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
2136 return 1;
2137 }
2138 }
2139
2140 return 0;
2141}
2142
7fd59977 2143//==============================================================================
2144//function : Vinit
2145//purpose : Create the window viewer and initialize all the global variable
87b68a0f 2146// Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 2147//==============================================================================
18d715bd 2148static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 2149{
e79a94b9 2150 TCollection_AsciiString aViewName, aDisplayName;
2151 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
72ed0644 2152 Standard_Boolean isVirtual = false;
9e04ccdc 2153 Handle(V3d_View) aCopyFrom;
e79a94b9 2154 TCollection_AsciiString aName, aValue;
2e93433e 2155 int is2dMode = -1;
e79a94b9 2156 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 2157 {
e79a94b9 2158 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2159 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 2160 anArgCase.LowerCase();
2161 if (anArgIt + 1 < theArgsNb
2162 && anArgCase == "-name")
2163 {
2164 aViewName = theArgVec[++anArgIt];
2165 }
2166 else if (anArgIt + 1 < theArgsNb
2167 && (anArgCase == "-left"
2168 || anArgCase == "-l"))
2169 {
2170 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2171 }
2172 else if (anArgIt + 1 < theArgsNb
2173 && (anArgCase == "-top"
2174 || anArgCase == "-t"))
2175 {
2176 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2177 }
2178 else if (anArgIt + 1 < theArgsNb
2179 && (anArgCase == "-width"
2180 || anArgCase == "-w"))
2181 {
2182 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2183 }
2184 else if (anArgIt + 1 < theArgsNb
2185 && (anArgCase == "-height"
2186 || anArgCase == "-h"))
18d715bd 2187 {
fd3f6bd0 2188 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2189 }
72ed0644 2190 else if (anArgCase == "-virtual"
2191 || anArgCase == "-offscreen")
2192 {
2193 isVirtual = true;
2194 if (anArgIt + 1 < theArgsNb
2195 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
2196 {
2197 ++anArgIt;
2198 }
2199 }
fd3f6bd0 2200 else if (anArgCase == "-exitonclose")
2201 {
49582f9d 2202 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 2203 if (anArgIt + 1 < theArgsNb
dae2a922 2204 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 2205 {
2206 ++anArgIt;
2207 }
2208 }
2209 else if (anArgCase == "-closeonescape"
2210 || anArgCase == "-closeonesc")
2211 {
49582f9d 2212 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 2213 if (anArgIt + 1 < theArgsNb
dae2a922 2214 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 2215 {
2216 ++anArgIt;
2217 }
2218 }
2e93433e 2219 else if (anArgCase == "-2d_mode"
2220 || anArgCase == "-2dmode"
2221 || anArgCase == "-2d")
2222 {
2223 bool toEnable = true;
2224 if (anArgIt + 1 < theArgsNb
dae2a922 2225 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2e93433e 2226 {
2227 ++anArgIt;
2228 }
2229 is2dMode = toEnable ? 1 : 0;
2230 }
fd3f6bd0 2231 else if (anArgIt + 1 < theArgsNb
2232 && (anArgCase == "-disp"
2233 || anArgCase == "-display"))
2234 {
2235 aDisplayName = theArgVec[++anArgIt];
2236 }
9e04ccdc 2237 else if (!ViewerTest::CurrentView().IsNull()
2238 && aCopyFrom.IsNull()
2239 && (anArgCase == "-copy"
2240 || anArgCase == "-clone"
2241 || anArgCase == "-cloneactive"
2242 || anArgCase == "-cloneactiveview"))
2243 {
2244 aCopyFrom = ViewerTest::CurrentView();
2245 }
fd3f6bd0 2246 // old syntax
2247 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2248 {
2249 aName.LowerCase();
2250 if (aName == "name")
18d715bd 2251 {
2252 aViewName = aValue;
2253 }
fd3f6bd0 2254 else if (aName == "l"
2255 || aName == "left")
e79a94b9 2256 {
18d715bd 2257 aPxLeft = aValue.IntegerValue();
e79a94b9 2258 }
fd3f6bd0 2259 else if (aName == "t"
2260 || aName == "top")
e79a94b9 2261 {
18d715bd 2262 aPxTop = aValue.IntegerValue();
e79a94b9 2263 }
fd3f6bd0 2264 else if (aName == "disp"
2265 || aName == "display")
e79a94b9 2266 {
18d715bd 2267 aDisplayName = aValue;
e79a94b9 2268 }
fd3f6bd0 2269 else if (aName == "w"
2270 || aName == "width")
e79a94b9 2271 {
18d715bd 2272 aPxWidth = aValue.IntegerValue();
e79a94b9 2273 }
fd3f6bd0 2274 else if (aName == "h"
2275 || aName == "height")
e79a94b9 2276 {
18d715bd 2277 aPxHeight = aValue.IntegerValue();
e79a94b9 2278 }
18d715bd 2279 else
2280 {
23fe70ec 2281 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2282 return 1;
18d715bd 2283 }
2284 }
e79a94b9 2285 else if (aViewName.IsEmpty())
2286 {
2287 aViewName = anArg;
2288 }
2289 else
2290 {
23fe70ec 2291 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2292 return 1;
e79a94b9 2293 }
18d715bd 2294 }
2295
b69e576a 2296#if !defined(HAVE_XLIB)
fd3f6bd0 2297 if (!aDisplayName.IsEmpty())
2298 {
2299 aDisplayName.Clear();
23fe70ec 2300 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
fd3f6bd0 2301 }
2302#endif
2303
18d715bd 2304 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2305 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2306 {
e79a94b9 2307 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2308 theDi.Eval (aCommand.ToCString());
2e93433e 2309 if (is2dMode != -1)
2310 {
2311 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2312 }
18d715bd 2313 return 0;
2314 }
2315
2316 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
72ed0644 2317 aViewName, aDisplayName, aCopyFrom, isVirtual);
2e93433e 2318 if (is2dMode != -1)
2319 {
2320 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2321 }
e79a94b9 2322 theDi << aViewId;
7fd59977 2323 return 0;
2324}
2325
1eeef710 2326//! Parse HLR algo type.
2327static Standard_Boolean parseHlrAlgoType (const char* theName,
2328 Prs3d_TypeOfHLR& theType)
2329{
2330 TCollection_AsciiString aName (theName);
2331 aName.LowerCase();
2332 if (aName == "polyalgo")
2333 {
2334 theType = Prs3d_TOH_PolyAlgo;
2335 }
2336 else if (aName == "algo")
2337 {
2338 theType = Prs3d_TOH_Algo;
2339 }
2340 else
2341 {
2342 return Standard_False;
2343 }
2344 return Standard_True;
2345}
2346
0a768f56 2347//==============================================================================
2348//function : VHLR
2349//purpose : hidden lines removal algorithm
2350//==============================================================================
2351
2352static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2353{
1eeef710 2354 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2355 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2356 if (aView.IsNull())
0a768f56 2357 {
23fe70ec 2358 Message::SendFail ("Error: no active viewer");
0a768f56 2359 return 1;
2360 }
2361
1eeef710 2362 Standard_Boolean hasHlrOnArg = Standard_False;
2363 Standard_Boolean hasShowHiddenArg = Standard_False;
2364 Standard_Boolean isHLROn = Standard_False;
2365 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2366 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2367 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2368 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2369 {
1eeef710 2370 TCollection_AsciiString anArg (argv[anArgIter]);
2371 anArg.LowerCase();
2372 if (anUpdateTool.parseRedrawMode (anArg))
2373 {
2374 continue;
2375 }
2376 else if (anArg == "-showhidden"
2377 && anArgIter + 1 < argc
dae2a922 2378 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1eeef710 2379 {
2380 ++anArgIter;
2381 hasShowHiddenArg = Standard_True;
2382 continue;
2383 }
2384 else if ((anArg == "-type"
2385 || anArg == "-algo"
2386 || anArg == "-algotype")
2387 && anArgIter + 1 < argc
2388 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2389 {
2390 ++anArgIter;
2391 continue;
2392 }
2393 else if (!hasHlrOnArg
dae2a922 2394 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1eeef710 2395 {
2396 hasHlrOnArg = Standard_True;
2397 continue;
2398 }
2399 // old syntax
2400 else if (!hasShowHiddenArg
dae2a922 2401 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1eeef710 2402 {
2403 hasShowHiddenArg = Standard_True;
2404 continue;
2405 }
2406 else
2407 {
23fe70ec 2408 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1eeef710 2409 return 1;
2410 }
0a768f56 2411 }
1eeef710 2412 if (!hasHlrOnArg)
0a768f56 2413 {
1eeef710 2414 di << "HLR: " << aView->ComputedMode() << "\n";
2415 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2416 di << "HlrAlgo: ";
2417 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2418 {
2419 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2420 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2421 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2422 }
2423 anUpdateTool.Invalidate();
2424 return 0;
0a768f56 2425 }
2426
1eeef710 2427 Standard_Boolean toRecompute = Standard_False;
2428 if (aTypeOfHLR != Prs3d_TOH_NotSet
2429 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2430 {
1eeef710 2431 toRecompute = Standard_True;
2432 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2433 }
2434 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2435 {
2436 toRecompute = Standard_True;
2437 if (toShowHidden)
e9224045 2438 {
1eeef710 2439 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2440 }
2441 else
2442 {
1eeef710 2443 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2444 }
1eeef710 2445 }
e9224045 2446
1eeef710 2447 // redisplay shapes
2448 if (aView->ComputedMode() && isHLROn && toRecompute)
2449 {
2450 AIS_ListOfInteractive aListOfShapes;
2451 aCtx->DisplayedObjects (aListOfShapes);
2452 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2453 {
1eeef710 2454 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2455 {
1eeef710 2456 aCtx->Redisplay (aShape, Standard_False);
e9224045 2457 }
2458 }
2459 }
0a768f56 2460
1eeef710 2461 aView->SetComputedMode (isHLROn);
0a768f56 2462 return 0;
2463}
2464
2465//==============================================================================
2466//function : VHLRType
2467//purpose : change type of using HLR algorithm
2468//==============================================================================
2469
1eeef710 2470static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2471{
1eeef710 2472 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2473 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2474 if (aView.IsNull())
0a768f56 2475 {
23fe70ec 2476 Message::SendFail ("Error: no active viewer");
0a768f56 2477 return 1;
2478 }
2479
1eeef710 2480 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2481 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2482 AIS_ListOfInteractive aListOfShapes;
2483 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2484 {
1eeef710 2485 TCollection_AsciiString anArg (argv[anArgIter]);
2486 anArg.LowerCase();
2487 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2488 {
1eeef710 2489 continue;
0a768f56 2490 }
1eeef710 2491 else if ((anArg == "-type"
2492 || anArg == "-algo"
2493 || anArg == "-algotype")
2494 && anArgIter + 1 < argc
2495 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2496 {
2497 ++anArgIter;
2498 continue;
2499 }
2500 // old syntax
2501 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2502 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2503 {
2504 continue;
2505 }
2506 else
0a768f56 2507 {
2508 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2509 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2510 if (!aMap.IsBound2 (aName))
2511 {
23fe70ec 2512 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1eeef710 2513 return 1;
0a768f56 2514 }
1eeef710 2515
2516 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2517 if (aShape.IsNull())
2518 {
23fe70ec 2519 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1eeef710 2520 return 1;
2521 }
2522 aListOfShapes.Append (aShape);
2523 continue;
0a768f56 2524 }
1eeef710 2525 }
2526 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2527 {
23fe70ec 2528 Message::SendFail ("Syntax error: wrong number of arguments");
1eeef710 2529 return 1;
2530 }
2531
2532 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2533 if (isGlobal)
2534 {
2535 aCtx->DisplayedObjects (aListOfShapes);
2536 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2537 }
2538
1eeef710 2539 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2540 {
2541 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2542 if (aShape.IsNull())
2543 {
2544 continue;
2545 }
2546
2547 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2548 && aView->ComputedMode();
2549 if (!isGlobal
2550 || aShape->TypeOfHLR() != aTypeOfHLR)
2551 {
2552 aShape->SetTypeOfHLR (aTypeOfHLR);
2553 }
2554 if (toUpdateShape)
2555 {
2556 aCtx->Redisplay (aShape, Standard_False);
2557 }
2558 }
0a768f56 2559 return 0;
2560}
2561
18d715bd 2562//==============================================================================
2563//function : FindViewIdByWindowHandle
2564//purpose : Find theView Id in the map of views by window handle
2565//==============================================================================
b69e576a 2566#if defined(_WIN32) || defined(HAVE_XLIB)
2567static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
18d715bd 2568{
2569 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2570 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2571 {
49582f9d 2572 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
18d715bd 2573 if (aWindowHandle == theWindowHandle)
2574 return anIter.Key1();
2575 }
2576 return TCollection_AsciiString("");
2577}
2578#endif
2579
e084dbbc 2580//! Make the view active
2581void ActivateView (const TCollection_AsciiString& theViewName,
2582 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2583{
2584 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2585 if (aView.IsNull())
18d715bd 2586 {
e084dbbc 2587 return;
2588 }
18d715bd 2589
e084dbbc 2590 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2591 if (!anAISContext.IsNull())
2592 {
49582f9d 2593 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
e084dbbc 2594 {
49582f9d 2595 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
e084dbbc 2596 }
2597
2598 ViewerTest::CurrentView (aView);
2599 ViewerTest::SetAISContext (anAISContext);
49582f9d 2600 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
f9ab9f7f 2601 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(ViewerTest::CurrentView()->Window());
e084dbbc 2602 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2603 if (theToUpdate)
2604 {
18d715bd 2605 ViewerTest::CurrentView()->Redraw();
2606 }
2607 }
2608}
2609
0e93d9e5 2610//==============================================================================
2611//function : RemoveView
2612//purpose :
2613//==============================================================================
2614void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2615 const Standard_Boolean theToRemoveContext)
2616{
2617 if (!ViewerTest_myViews.IsBound2 (theView))
2618 {
2619 return;
2620 }
2621
2622 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2623 RemoveView (aViewName, theToRemoveContext);
2624}
2625
18d715bd 2626//==============================================================================
2627//function : RemoveView
4551e1be 2628//purpose : Close and remove view from display, clear maps if necessary
18d715bd 2629//==============================================================================
2630void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2631{
2632 if (!ViewerTest_myViews.IsBound1(theViewName))
2633 {
23fe70ec 2634 Message::SendFail() << "Wrong view name";
18d715bd 2635 return;
2636 }
2637
2638 // Activate another view if it's active now
2639 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2640 {
2641 if (ViewerTest_myViews.Extent() > 1)
2642 {
2643 TCollection_AsciiString aNewViewName;
c48e2889 2644 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2645 anIter.More(); anIter.Next())
2646 {
18d715bd 2647 if (anIter.Key1() != theViewName)
2648 {
2649 aNewViewName = anIter.Key1();
2650 break;
2651 }
c48e2889 2652 }
2653 ActivateView (aNewViewName);
18d715bd 2654 }
2655 else
2656 {
e084dbbc 2657 VT_GetWindow().Nullify();
2658 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2659 if (isContextRemoved)
2660 {
2661 Handle(AIS_InteractiveContext) anEmptyContext;
2662 ViewerTest::SetAISContext(anEmptyContext);
2663 }
2664 }
2665 }
2666
2667 // Delete view
2668 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2669 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2670 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2671 aRedrawer.Stop (aView->Window());
18d715bd 2672
2673 // Remove view resources
18d715bd 2674 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2675 aView->Window()->Unmap();
18d715bd 2676 aView->Remove();
2677
b69e576a 2678#if defined(HAVE_XLIB)
2679 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
18d715bd 2680#endif
2681
2682 // Keep context opened only if the closed view is last to avoid
2683 // unused empty contexts
2684 if (!aCurrentContext.IsNull())
2685 {
2686 // Check if there are more difined views in the viewer
f7fc0c03 2687 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2688 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
18d715bd 2689 {
2690 // Remove driver if there is no viewers that use it
2691 Standard_Boolean isRemoveDriver = Standard_True;
2692 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2693 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2694 {
2695 if (aCurrentContext != anIter.Key2() &&
2696 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2697 {
2698 isRemoveDriver = Standard_False;
2699 break;
2700 }
2701 }
2ec85268 2702
2703 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2704 if(isRemoveDriver)
2705 {
2706 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
b69e576a 2707 #if defined(HAVE_XLIB)
2708 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
18d715bd 2709 #endif
2710 }
2711
2712 ViewerTest_myContexts.UnBind2(aCurrentContext);
2713 }
2714 }
23fe70ec 2715 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
49582f9d 2716 if (ViewerTest_EventManager::ToExitOnCloseView())
fd3f6bd0 2717 {
2718 Draw_Interprete ("exit");
2719 }
18d715bd 2720}
2721
2722//==============================================================================
2723//function : VClose
2724//purpose : Remove the view defined by its name
2725//==============================================================================
2726
d0cc1cb7 2727static int VClose (Draw_Interpretor& /*theDi*/,
2728 Standard_Integer theArgsNb,
2729 const char** theArgVec)
18d715bd 2730{
18d715bd 2731 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2732 if (theArgsNb > 1)
18d715bd 2733 {
d0cc1cb7 2734 TCollection_AsciiString anArg (theArgVec[1]);
2735 anArg.UpperCase();
2736 if (anArg.IsEqual ("ALL")
2737 || anArg.IsEqual ("*"))
2738 {
2739 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2740 anIter.More(); anIter.Next())
2741 {
2742 aViewList.Append (anIter.Key1());
2743 }
2744 if (aViewList.IsEmpty())
2745 {
2746 std::cout << "No view to close\n";
2747 return 0;
2748 }
2749 }
2750 else
18d715bd 2751 {
d0cc1cb7 2752 ViewerTest_Names aViewName (theArgVec[1]);
2753 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2754 {
23fe70ec 2755 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
d0cc1cb7 2756 return 1;
2757 }
2758 aViewList.Append (aViewName.GetViewName());
18d715bd 2759 }
2760 }
2761 else
2762 {
d0cc1cb7 2763 // close active view
2764 if (ViewerTest::CurrentView().IsNull())
2765 {
23fe70ec 2766 Message::SendFail ("Error: no active view");
d0cc1cb7 2767 return 1;
2768 }
2769 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2770 }
2771
d0cc1cb7 2772 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2773 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2774 anIter.More(); anIter.Next())
2775 {
d0cc1cb7 2776 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2777 }
2778
2779 return 0;
2780}
2781
2782//==============================================================================
2783//function : VActivate
2784//purpose : Activate the view defined by its ID
2785//==============================================================================
2786
2787static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2788{
e084dbbc 2789 if (theArgsNb == 1)
18d715bd 2790 {
2791 theDi.Eval("vviewlist");
2792 return 0;
2793 }
2794
e084dbbc 2795 TCollection_AsciiString aNameString;
2796 Standard_Boolean toUpdate = Standard_True;
2797 Standard_Boolean toActivate = Standard_True;
2798 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2799 {
e084dbbc 2800 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2801 anArg.LowerCase();
2802 if (toUpdate
2803 && anArg == "-noupdate")
2804 {
2805 toUpdate = Standard_False;
2806 }
2807 else if (toActivate
2808 && aNameString.IsEmpty()
2809 && anArg == "none")
2810 {
49582f9d 2811 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
e084dbbc 2812 VT_GetWindow().Nullify();
2813 ViewerTest::CurrentView (Handle(V3d_View)());
2814 ViewerTest::ResetEventManager();
2815 theDi << theArgVec[0] << ": all views are inactive\n";
2816 toActivate = Standard_False;
2817 }
2818 else if (toActivate
2819 && aNameString.IsEmpty())
2820 {
2821 aNameString = theArgVec[anArgIter];
2822 }
2823 else
2824 {
23fe70ec 2825 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
e084dbbc 2826 return 1;
2827 }
18d715bd 2828 }
2829
e084dbbc 2830 if (!toActivate)
2831 {
2832 return 0;
2833 }
2834 else if (aNameString.IsEmpty())
2835 {
23fe70ec 2836 Message::SendFail ("Syntax error: wrong number of arguments");
e084dbbc 2837 return 1;
2838 }
18d715bd 2839
2840 // Check if this view exists in the viewer with the driver
e084dbbc 2841 ViewerTest_Names aViewNames (aNameString);
18d715bd 2842 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2843 {
e084dbbc 2844 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2845 return 1;
2846 }
2847
2848 // Check if it is active already
2849 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2850 {
2851 theDi << theArgVec[0] << ": the view is active already\n";
2852 return 0;
2853 }
2854
e084dbbc 2855 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2856 return 0;
2857}
2858
2859//==============================================================================
2860//function : VViewList
2861//purpose : Print current list of views per viewer and graphic driver ID
2862// shared between viewers
2863//==============================================================================
2864
2865static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2866{
2867 if (theArgsNb > 2)
2868 {
2869 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2870 << "Usage: " << theArgVec[0] << " name";
18d715bd 2871 return 1;
2872 }
2873 if (ViewerTest_myContexts.Size() < 1)
2874 return 0;
2875
18d715bd 2876 Standard_Boolean isTreeView =
29cb310a 2877 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2878
2879 if (isTreeView)
c48e2889 2880 {
18d715bd 2881 theDi << theArgVec[0] <<":\n";
c48e2889 2882 }
18d715bd 2883
c48e2889 2884 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2885 aDriverIter.More(); aDriverIter.Next())
2886 {
2887 if (isTreeView)
2888 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2889
c48e2889 2890 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2891 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2892 {
2893 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2894 {
c48e2889 2895 if (isTreeView)
18d715bd 2896 {
c48e2889 2897 TCollection_AsciiString aContextName(aContextIter.Key1());
2898 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2899 }
18d715bd 2900
c48e2889 2901 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2902 aViewIter.More(); aViewIter.Next())
2903 {
2904 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2905 {
c48e2889 2906 TCollection_AsciiString aViewName(aViewIter.Key1());
2907 if (isTreeView)
18d715bd 2908 {
c48e2889 2909 if (aViewIter.Value() == ViewerTest::CurrentView())
2910 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2911 else
c48e2889 2912 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2913 }
2914 else
2915 {
2916 theDi << aViewName << " ";
18d715bd 2917 }
2918 }
2919 }
2920 }
2921 }
c48e2889 2922 }
18d715bd 2923 return 0;
2924}
2925
7fd59977 2926//==============================================================================
49582f9d 2927//function : GetMousePosition
2928//purpose :
7fd59977 2929//==============================================================================
49582f9d 2930void ViewerTest::GetMousePosition (Standard_Integer& theX,
2931 Standard_Integer& theY)
7fd59977 2932{
49582f9d 2933 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
4fe56619 2934 {
49582f9d 2935 theX = aViewCtrl->LastMousePosition().x();
2936 theY = aViewCtrl->LastMousePosition().y();
4fe56619 2937 }
7fd59977 2938}
2939
44b8f2d6 2940//==============================================================================
fc552d84 2941//function : VViewProj
2942//purpose : Switch view projection
44b8f2d6 2943//==============================================================================
fc552d84 2944static int VViewProj (Draw_Interpretor& ,
2945 Standard_Integer theNbArgs,
2946 const char** theArgVec)
44b8f2d6 2947{
fc552d84 2948 static Standard_Boolean isYup = Standard_False;
2949 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2950 if (aView.IsNull())
44b8f2d6 2951 {
23fe70ec 2952 Message::SendFail ("Error: no active viewer");
44b8f2d6 2953 return 1;
2954 }
2955
fc552d84 2956 TCollection_AsciiString aCmdName (theArgVec[0]);
2957 Standard_Boolean isGeneralCmd = Standard_False;
2958 if (aCmdName == "vfront")
2959 {
2960 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2961 }
2962 else if (aCmdName == "vback")
2963 {
2964 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2965 }
2966 else if (aCmdName == "vtop")
2967 {
2968 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2969 }
2970 else if (aCmdName == "vbottom")
2971 {
2972 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2973 }
2974 else if (aCmdName == "vleft")
2975 {
2976 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2977 }
2978 else if (aCmdName == "vright")
2979 {
2980 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2981 }
2982 else if (aCmdName == "vaxo")
2983 {
2984 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2985 }
2986 else
2987 {
2988 isGeneralCmd = Standard_True;
2989 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2990 {
2991 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2992 anArgCase.LowerCase();
2993 if (anArgCase == "-zup")
2994 {
2995 isYup = Standard_False;
2996 }
2997 else if (anArgCase == "-yup")
2998 {
2999 isYup = Standard_True;
3000 }
3001 else if (anArgCase == "-front"
3002 || anArgCase == "front"
3003 || anArgCase == "-f"
3004 || anArgCase == "f")
3005 {
3006 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
3007 }
3008 else if (anArgCase == "-back"
3009 || anArgCase == "back"
3010 || anArgCase == "-b"
3011 || anArgCase == "b")
3012 {
3013 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
3014 }
3015 else if (anArgCase == "-top"
3016 || anArgCase == "top"
3017 || anArgCase == "-t"
3018 || anArgCase == "t")
3019 {
3020 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
3021 }
3022 else if (anArgCase == "-bottom"
3023 || anArgCase == "bottom"
3024 || anArgCase == "-bot"
3025 || anArgCase == "bot"
3026 || anArgCase == "-b"
3027 || anArgCase == "b")
3028 {
3029 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
3030 }
3031 else if (anArgCase == "-left"
3032 || anArgCase == "left"
3033 || anArgCase == "-l"
3034 || anArgCase == "l")
3035 {
3036 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
3037 }
3038 else if (anArgCase == "-right"
3039 || anArgCase == "right"
3040 || anArgCase == "-r"
3041 || anArgCase == "r")
3042 {
3043 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
3044 }
3045 else if (anArgCase == "-axoleft"
3046 || anArgCase == "-leftaxo"
3047 || anArgCase == "axoleft"
3048 || anArgCase == "leftaxo")
3049 {
3050 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
3051 }
3052 else if (anArgCase == "-axo"
3053 || anArgCase == "axo"
3054 || anArgCase == "-a"
3055 || anArgCase == "a"
3056 || anArgCase == "-axoright"
3057 || anArgCase == "-rightaxo"
3058 || anArgCase == "axoright"
3059 || anArgCase == "rightaxo")
3060 {
3061 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
3062 }
3063 else if (anArgCase == "+x")
3064 {
3065 aView->SetProj (V3d_Xpos, isYup);
3066 }
3067 else if (anArgCase == "-x")
3068 {
3069 aView->SetProj (V3d_Xneg, isYup);
3070 }
3071 else if (anArgCase == "+y")
3072 {
3073 aView->SetProj (V3d_Ypos, isYup);
3074 }
3075 else if (anArgCase == "-y")
3076 {
3077 aView->SetProj (V3d_Yneg, isYup);
3078 }
3079 else if (anArgCase == "+z")
3080 {
3081 aView->SetProj (V3d_Zpos, isYup);
3082 }
3083 else if (anArgCase == "-z")
3084 {
3085 aView->SetProj (V3d_Zneg, isYup);
3086 }
3087 else if (anArgCase == "+x+y+z")
3088 {
3089 aView->SetProj (V3d_XposYposZpos, isYup);
3090 }
3091 else if (anArgCase == "+x+y-z")
3092 {
3093 aView->SetProj (V3d_XposYposZneg, isYup);
3094 }
3095 else if (anArgCase == "+x-y+z")
3096 {
3097 aView->SetProj (V3d_XposYnegZpos, isYup);
3098 }
3099 else if (anArgCase == "+x-y-z")
3100 {
3101 aView->SetProj (V3d_XposYnegZneg, isYup);
3102 }
3103 else if (anArgCase == "-x+y+z")
3104 {
3105 aView->SetProj (V3d_XnegYposZpos, isYup);
3106 }
3107 else if (anArgCase == "-x+y-z")
3108 {
3109 aView->SetProj (V3d_XnegYposZneg, isYup);
3110 }
3111 else if (anArgCase == "-x-y+z")
3112 {
3113 aView->SetProj (V3d_XnegYnegZpos, isYup);
3114 }
3115 else if (anArgCase == "-x-y-z")
3116 {
3117 aView->SetProj (V3d_XnegYnegZneg, isYup);
3118 }
3119 else if (anArgCase == "+x+y")
3120 {
3121 aView->SetProj (V3d_XposYpos, isYup);
3122 }
3123 else if (anArgCase == "+x-y")
3124 {
3125 aView->SetProj (V3d_XposYneg, isYup);
3126 }
3127 else if (anArgCase == "-x+y")
3128 {
3129 aView->SetProj (V3d_XnegYpos, isYup);
3130 }
3131 else if (anArgCase == "-x-y")
3132 {
3133 aView->SetProj (V3d_XnegYneg, isYup);
3134 }
3135 else if (anArgCase == "+x+z")
3136 {
3137 aView->SetProj (V3d_XposZpos, isYup);
3138 }
3139 else if (anArgCase == "+x-z")
3140 {
3141 aView->SetProj (V3d_XposZneg, isYup);
3142 }
3143 else if (anArgCase == "-x+z")
3144 {
3145 aView->SetProj (V3d_XnegZpos, isYup);
3146 }
3147 else if (anArgCase == "-x-z")
3148 {
3149 aView->SetProj (V3d_XnegZneg, isYup);
3150 }
3151 else if (anArgCase == "+y+z")
3152 {
3153 aView->SetProj (V3d_YposZpos, isYup);
3154 }
3155 else if (anArgCase == "+y-z")
3156 {
3157 aView->SetProj (V3d_YposZneg, isYup);
3158 }
3159 else if (anArgCase == "-y+z")
3160 {
3161 aView->SetProj (V3d_YnegZpos, isYup);
3162 }
3163 else if (anArgCase == "-y-z")
3164 {
3165 aView->SetProj (V3d_YnegZneg, isYup);
3166 }
3167 else if (anArgIter + 1 < theNbArgs
3168 && anArgCase == "-frame"
3169 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
3170 {
3171 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
3172 aFrameDef.LowerCase();
3173 gp_Dir aRight, anUp;
3174 if (aFrameDef.Value (2) == aFrameDef.Value (4))
3175 {
23fe70ec 3176 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3177 return 1;
3178 }
44b8f2d6 3179
fc552d84 3180 if (aFrameDef.Value (2) == 'x')
3181 {
3182 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
3183 }
3184 else if (aFrameDef.Value (2) == 'y')
3185 {
3186 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
3187 }
3188 else if (aFrameDef.Value (2) == 'z')
3189 {
3190 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
3191 }
3192 else
3193 {
23fe70ec 3194 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3195 return 1;
3196 }
7fd59977 3197
fc552d84 3198 if (aFrameDef.Value (4) == 'x')
3199 {
3200 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
3201 }
3202 else if (aFrameDef.Value (4) == 'y')
3203 {
3204 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
3205 }
3206 else if (aFrameDef.Value (4) == 'z')
3207 {
3208 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
3209 }
3210 else
3211 {
23fe70ec 3212 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3213 return 1;
3214 }
44b8f2d6 3215
fc552d84 3216 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3217 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3218 const gp_Dir aDir = anUp.Crossed (aRight);
3219 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3220 aCamera->SetDirection (aDir);
3221 aCamera->SetUp (anUp);
3222 aCamera->OrthogonalizeUp();
44b8f2d6 3223
fc552d84 3224 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3225 aView->Update();
3226 }
3227 else
3228 {
23fe70ec 3229 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3230 return 1;
3231 }
3232 }
3233 }
44b8f2d6 3234
fc552d84 3235 if (!isGeneralCmd
3236 && theNbArgs != 1)
3237 {
23fe70ec 3238 Message::SendFail ("Syntax error: wrong number of arguments");
fc552d84 3239 return 1;
3240 }
3241 return 0;
7fd59977 3242}
3243
3244//==============================================================================
3245//function : VHelp
3246//purpose : Dsiplay help on viewer Keyboead and mouse commands
3247//Draw arg : No args
3248//==============================================================================
3249
3250static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3251{
586db386 3252 di << "=========================\n";
3253 di << "F : FitAll\n";
3254 di << "T : TopView\n";
3255 di << "B : BottomView\n";
3256 di << "R : RightView\n";
3257 di << "L : LeftView\n";
d22962e4 3258 di << "Backspace : AxonometricView\n";
586db386 3259
3260 di << "=========================\n";
d22962e4 3261 di << "W, S : Fly forward/backward\n";
3262 di << "A, D : Slide left/right\n";
3263 di << "Q, E : Bank left/right\n";
3264 di << "-, + : Change flying speed\n";
3265 di << "Arrows : look left/right/up/down\n";
3266 di << "Arrows+Shift : slide left/right/up/down\n";
3267
3268 di << "=========================\n";
3269 di << "S + Ctrl : Shading\n";
3270 di << "W + Ctrl : Wireframe\n";
49582f9d 3271 di << "H : HiddenLineRemoval\n";
586db386 3272 di << "U : Unset display mode\n";
3273 di << "Delete : Remove selection from viewer\n";
3274
3275 di << "=========================\n";
3276 di << "Selection mode \n";
3277 di << "0 : Shape\n";
3278 di << "1 : Vertex\n";
3279 di << "2 : Edge\n";
3280 di << "3 : Wire\n";
3281 di << "4 : Face\n";
3282 di << "5 : Shell\n";
3283 di << "6 : Solid\n";
3284 di << "7 : Compound\n";
3285
3286 di << "=========================\n";
49582f9d 3287 di << "< : Hilight next detected\n";
3288 di << "> : Hilight previous detected\n";
7fd59977 3289
3290 return 0;
3291}
3292
57c28b61 3293#ifdef _WIN32
7fd59977 3294
49582f9d 3295static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3296 UINT theMsg,
3297 WPARAM wParam,
3298 LPARAM lParam )
7fd59977 3299{
49582f9d 3300 if (ViewerTest_myViews.IsEmpty())
3301 {
e8e157df 3302 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
49582f9d 3303 }
7fd59977 3304
49582f9d 3305 switch (theMsg)
3306 {
18d715bd 3307 case WM_CLOSE:
49582f9d 3308 {
3309 // Delete view from map of views
3310 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3311 return 0;
3312 }
18d715bd 3313 case WM_ACTIVATE:
49582f9d 3314 {
3315 if (LOWORD(wParam) == WA_CLICKACTIVE
3316 || LOWORD(wParam) == WA_ACTIVE
3317 || ViewerTest::CurrentView().IsNull())
18d715bd 3318 {
3319 // Activate inactive window
49582f9d 3320 if (VT_GetWindow().IsNull()
3321 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
625e1958 3322 {
49582f9d 3323 ActivateView (FindViewIdByWindowHandle (theWinHandle));
625e1958 3324 }
7fd59977 3325 }
e8e157df 3326 return 0;
49582f9d 3327 }
7fd59977 3328 case WM_LBUTTONDOWN:
49582f9d 3329 {
e8e157df 3330 TheIsAnimating = Standard_False;
f978241f 3331 }
e8e157df 3332 Standard_FALLTHROUGH
3333 default:
49582f9d 3334 {
e8e157df 3335 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3336 if (!aView.IsNull()
3337 && !VT_GetWindow().IsNull())
49582f9d 3338 {
e8e157df 3339 MSG aMsg = {};
3340 aMsg.hwnd = theWinHandle;
3341 aMsg.message = theMsg;
3342 aMsg.wParam = wParam;
3343 aMsg.lParam = lParam;
3344 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
49582f9d 3345 {
e8e157df 3346 return 0;
49582f9d 3347 }
3348 }
7fd59977 3349 }
49582f9d 3350 }
e8e157df 3351 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
7fd59977 3352}
3353
7fd59977 3354//==============================================================================
3355//function : ViewerMainLoop
3356//purpose : Get a Event on the view and dispatch it
3357//==============================================================================
3358
49582f9d 3359int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
7fd59977 3360{
49582f9d 3361 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3362 if (aViewCtrl.IsNull()
3363 || theNbArgs < 4)
3364 {
3365 return 0;
3366 }
7fd59977 3367
49582f9d 3368 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
7fd59977 3369
49582f9d 3370 std::cout << "Start picking\n";
7fd59977 3371
49582f9d 3372 MSG aMsg;
3373 aMsg.wParam = 1;
3374 while (aViewCtrl->ToPickPoint())
3375 {
3376 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3377 if (GetMessageW (&aMsg, NULL, 0, 0))
3378 {
3379 TranslateMessage (&aMsg);
3380 DispatchMessageW (&aMsg);
7fd59977 3381 }
7fd59977 3382 }
3383
49582f9d 3384 std::cout << "Picking done\n";
3385 return 0;
7fd59977 3386}
3387
b69e576a 3388#elif defined(HAVE_XLIB)
7fd59977 3389
49582f9d 3390int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
4269bd1b 3391{
18d715bd 3392 static XEvent aReport;
49582f9d 3393 const Standard_Boolean toPick = theNbArgs > 0;
3394 if (theNbArgs > 0)
3395 {
3396 if (ViewerTest::CurrentEventManager().IsNull())
3397 {
3398 return 0;
3399 }
3400 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3401 }
3402
b69e576a 3403 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
18d715bd 3404 XNextEvent (aDisplay, &aReport);
7fd59977 3405
18d715bd 3406 // Handle event for the chosen display connection
8693dfd0 3407 switch (aReport.type)
3408 {
3409 case ClientMessage:
3410 {
3411 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3412 {
3413 // Close the window
3414 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3415 return toPick ? 0 : 1;
3416 }
3417 break;
3418 }
3419 case FocusIn:
3420 {
3421 // Activate inactive view
49582f9d 3422 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3423 if (aWindow != aReport.xfocus.window)
3424 {
3425 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3426 }
3427 break;
3428 }
49582f9d 3429 case ButtonPress:
8693dfd0 3430 {
49582f9d 3431 if (aReport.xbutton.button == Button1)
8693dfd0 3432 {
e8e157df 3433 TheIsAnimating = Standard_False;
49582f9d 3434 }
8693dfd0 3435 }
e8e157df 3436 Standard_FALLTHROUGH
3437 default:
8693dfd0 3438 {
e8e157df 3439 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3440 if (!aView.IsNull()
3441 && !VT_GetWindow().IsNull())
8693dfd0 3442 {
e8e157df 3443 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
49582f9d 3444 }
8693dfd0 3445 break;
3446 }
3447 }
49582f9d 3448 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
7fd59977 3449}
3450
3451//==============================================================================
3452//function : VProcessEvents
8693dfd0 3453//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3454//==============================================================================
8693dfd0 3455static void VProcessEvents (ClientData theDispX, int)
7fd59977 3456{
8693dfd0 3457 Display* aDispX = (Display* )theDispX;
3458 Handle(Aspect_DisplayConnection) aDispConn;
3459 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3460 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3461 {
8693dfd0 3462 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
b69e576a 3463 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
8693dfd0 3464 {
3465 aDispConn = aDispConnTmp;
3466 break;
3467 }
3468 }
3469 if (aDispConn.IsNull())
3470 {
23fe70ec 3471 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
8693dfd0 3472 return;
4269bd1b 3473 }
8693dfd0 3474
3475 // process new events in queue
3476 SetDisplayConnection (aDispConn);
3477 int aNbRemain = 0;
3478 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3479 {
8693dfd0 3480 const int anEventResult = ViewerMainLoop (0, NULL);
3481 if (anEventResult == 0)
18d715bd 3482 {
8693dfd0 3483 return;
3484 }
3485
3486 aNbRemain = XPending (aDispX);
3487 if (++anEventIter >= aNbEventsMax
3488 || aNbRemain <= 0)
3489 {
3490 break;
18d715bd 3491 }
7fd59977 3492 }
4269bd1b 3493
8693dfd0 3494 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3495 // it is possible that new events will arrive to queue before the end of this callback
3496 // so that either this callback should go into an infinite loop (blocking processing of other events)
3497 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3498 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3499 if (aNbRemain != 0)
3500 {
3501 XEvent aDummyEvent;
3502 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3503 aDummyEvent.type = ClientMessage;
3504 aDummyEvent.xclient.format = 32;
3505 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3506 XFlush (aDispX);
3507 }
4269bd1b 3508
8693dfd0 3509 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3510 {
3511 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3512 }
7fd59977 3513}
b69e576a 3514#elif !defined(__APPLE__)
3515// =======================================================================
3516// function : ViewerMainLoop
3517// purpose :
3518// =======================================================================
3519int ViewerMainLoop (Standard_Integer , const char** )
3520{
3521 // unused
3522 return 0;
3523}
7fd59977 3524#endif
3525
7fd59977 3526//==============================================================================
3527//function : VFit
1beb58d7 3528//purpose :
7fd59977 3529//==============================================================================
3530
1beb58d7 3531static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 3532{
1beb58d7 3533 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3534 if (aView.IsNull())
b586500b 3535 {
23fe70ec 3536 Message::SendFail ("Error: no active viewer");
1beb58d7 3537 return 1;
b586500b 3538 }
3539
1beb58d7 3540 Standard_Boolean toFit = Standard_True;
3541 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3542 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 3543 {
1beb58d7 3544 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 3545 anArg.LowerCase();
1beb58d7 3546 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 3547 {
1beb58d7 3548 continue;
3549 }
3550 else if (anArg == "-selected")
3551 {
3552 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3553 toFit = Standard_False;
3554 }
3555 else
3556 {
23fe70ec 3557 Message::SendFail() << "Syntax error at '" << anArg << "'";
b586500b 3558 }
3559 }
3560
1beb58d7 3561 if (toFit)
3562 {
3563 aView->FitAll (0.01, Standard_False);
7fd59977 3564 }
3565 return 0;
3566}
3567
6262a303 3568//=======================================================================
3569//function : VFitArea
3570//purpose : Fit view to show area located between two points
3571// : given in world 2D or 3D coordinates.
3572//=======================================================================
3573static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3574{
3575 Handle(V3d_View) aView = ViewerTest::CurrentView();
3576 if (aView.IsNull())
3577 {
23fe70ec 3578 Message::SendFail ("Error: No active viewer");
6262a303 3579 return 1;
3580 }
3581
3582 // Parse arguments.
3583 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3584 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3585
3586 if (theArgNb == 5)
3587 {
3588 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3589 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3590 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3591 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3592 }
3593 else if (theArgNb == 7)
3594 {
3595 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3596 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3597 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3598 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3599 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3600 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3601 }
3602 else
3603 {
23fe70ec 3604 Message::SendFail ("Syntax error: Invalid number of arguments");
6262a303 3605 theDI.PrintHelp(theArgVec[0]);
3606 return 1;
3607 }
3608
3609 // Convert model coordinates to view space
3610 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3611 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3612 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3613
3614 // Determine fit area
3615 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3616 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3617
3618 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3619
3620 if (aDiagonal < Precision::Confusion())
3621 {
23fe70ec 3622 Message::SendFail ("Error: view area is too small");
6262a303 3623 return 1;
3624 }
3625
3626 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3627 return 0;
3628}
3629
7fd59977 3630//==============================================================================
3631//function : VZFit
3632//purpose : ZFitall, no DRAW arguments
3633//Draw arg : No args
3634//==============================================================================
197ac94e 3635static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 3636{
197ac94e 3637 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3638
3639 if (aCurrentView.IsNull())
3640 {
23fe70ec 3641 Message::SendFail ("Error: no active viewer");
197ac94e 3642 return 1;
3643 }
3644
3645 if (theArgsNb == 1)
3646 {
c357e426 3647 aCurrentView->ZFitAll();
197ac94e 3648 aCurrentView->Redraw();
3649 return 0;
3650 }
3651
3652 Standard_Real aScale = 1.0;
3653
3654 if (theArgsNb >= 2)
3655 {
3656 aScale = Draw::Atoi (theArgVec[1]);
3657 }
3658
c357e426 3659 aCurrentView->ZFitAll (aScale);
197ac94e 3660 aCurrentView->Redraw();
7fd59977 3661
197ac94e 3662 return 0;
3663}
7fd59977 3664
197ac94e 3665//==============================================================================
3666//function : VRepaint
3667//purpose :
3668//==============================================================================
56689b27 3669static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 3670{
56689b27 3671 Handle(V3d_View) aView = ViewerTest::CurrentView();
3672 if (aView.IsNull())
3673 {
23fe70ec 3674 Message::SendFail ("Error: no active viewer");
56689b27 3675 return 1;
3676 }
3677
3678 Standard_Boolean isImmediateUpdate = Standard_False;
3679 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3680 {
3681 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3682 anArg.LowerCase();
8693dfd0 3683 if (anArg == "-immediate"
3684 || anArg == "-imm")
56689b27 3685 {
3686 isImmediateUpdate = Standard_True;
3687 if (anArgIter + 1 < theArgNb
dae2a922 3688 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
56689b27 3689 {
3690 ++anArgIter;
3691 }
3692 }
8693dfd0 3693 else if (anArg == "-continuous"
3694 || anArg == "-cont"
3695 || anArg == "-fps"
3696 || anArg == "-framerate")
3697 {
3698 Standard_Real aFps = -1.0;
3699 if (anArgIter + 1 < theArgNb
d45edf24 3700 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
8693dfd0 3701 {
3702 aFps = Draw::Atof (theArgVec[++anArgIter]);
3703 }
3704
3705 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3706 if (Abs (aFps) >= 1.0)
3707 {
3708 aRedrawer.Start (aView->Window(), aFps);
3709 }
3710 else
3711 {
3712 aRedrawer.Stop();
3713 }
3714 }
56689b27 3715 else
3716 {
23fe70ec 3717 Message::SendFail() << "Syntax error at '" << anArg << "'";
8693dfd0 3718 return 1;
56689b27 3719 }
3720 }
3721
3722 if (isImmediateUpdate)
3723 {
3724 aView->RedrawImmediate();
3725 }
3726 else
3727 {
3728 aView->Redraw();
3729 }
3730 return 0;
7fd59977 3731}
3732
7fd59977 3733//==============================================================================
3734//function : VClear
3735//purpose : Remove all the object from the viewer
3736//Draw arg : No args
3737//==============================================================================
3738
3739static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3740{
3741 Handle(V3d_View) V = ViewerTest::CurrentView();
3742 if(!V.IsNull())
3743 ViewerTest::Clear();
3744 return 0;
3745}
3746
3747//==============================================================================
3748//function : VPick
3749//purpose :
3750//==============================================================================
3751
49582f9d 3752static int VPick (Draw_Interpretor& ,
3753 Standard_Integer theNbArgs,
3754 const char** theArgVec)
3755{
3756 if (ViewerTest::CurrentView().IsNull())
3757 {
3758 return 1;
3759 }
7fd59977 3760
49582f9d 3761 if (theNbArgs < 4)
3762 {
23fe70ec 3763 Message::SendFail ("Syntax error: wrong number of arguments");
49582f9d 3764 return 1;
3765 }
7fd59977 3766
49582f9d 3767 while (ViewerMainLoop (theNbArgs, theArgVec))
3768 {
3769 //
3770 }
7fd59977 3771
49582f9d 3772 return 0;
7fd59977 3773}
3774
293211ae 3775namespace
7fd59977 3776{
7fd59977 3777
293211ae 3778 //! Changes the background
3779 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3780 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3781 //! @param theCommandLineArguments the array of command line arguments
3782 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3783 static int vbackground (Draw_Interpretor& theDrawInterpretor,
3784 const Standard_Integer theNumberOfCommandLineArguments,
3785 const char** const theCommandLineArguments)
7fd59977 3786 {
293211ae 3787 if (theNumberOfCommandLineArguments < 1)
7fd59977 3788 {
293211ae 3789 return TCL_ERROR;
7fd59977 3790 }
293211ae 3791 BackgroundChanger aBackgroundChanger;
3792 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
3793 theNumberOfCommandLineArguments,
3794 theCommandLineArguments))
f8b2ed36 3795 {
293211ae 3796 theDrawInterpretor << "Wrong command arguments.\n"
3797 "Type 'help "
3798 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
3799 return TCL_ERROR;
f8b2ed36 3800 }
293211ae 3801 return TCL_OK;
f8b2ed36 3802 }
3803
293211ae 3804} // namespace
f42753ed 3805
7fd59977 3806//==============================================================================
3807//function : VScale
3808//purpose : View Scaling
3809//==============================================================================
3810
3811static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3812{
3813 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3814 if ( V3dView.IsNull() ) return 1;
3815
3816 if ( argc != 4 ) {
586db386 3817 di << argv[0] << "Invalid number of arguments\n";
7fd59977 3818 return 1;
3819 }
91322f44 3820 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 3821 return 0;
3822}
3823//==============================================================================
536d98e2 3824//function : VZBuffTrihedron
3825//purpose :
7fd59977 3826//==============================================================================
3827
536d98e2 3828static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3829 Standard_Integer theArgNb,
3830 const char** theArgVec)
7fd59977 3831{
536d98e2 3832 Handle(V3d_View) aView = ViewerTest::CurrentView();
3833 if (aView.IsNull())
3834 {
23fe70ec 3835 Message::SendFail ("Error: no active viewer");
536d98e2 3836 return 1;
3837 }
7fd59977 3838
536d98e2 3839 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 3840
536d98e2 3841 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3842 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
0aeb8984 3843 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3844 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3845 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
536d98e2 3846 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3847 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3848 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3849 Standard_Real aScale = 0.1;
3850 Standard_Real aSizeRatio = 0.8;
3851 Standard_Real anArrowDiam = 0.05;
3852 Standard_Integer aNbFacets = 12;
3853 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 3854 {
536d98e2 3855 Standard_CString anArg = theArgVec[anArgIter];
3856 TCollection_AsciiString aFlag (anArg);
3857 aFlag.LowerCase();
3858 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 3859 {
536d98e2 3860 continue;
3861 }
3862 else if (aFlag == "-on")
7c8a8fcc 3863 {
536d98e2 3864 continue;
3865 }
3866 else if (aFlag == "-off")
7c8a8fcc 3867 {
536d98e2 3868 aView->TriedronErase();
3869 return 0;
3870 }
3871 else if (aFlag == "-pos"
3872 || aFlag == "-position"
3873 || aFlag == "-corner")
7c8a8fcc 3874 {
536d98e2 3875 if (++anArgIter >= theArgNb)
3876 {
23fe70ec 3877 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3878 return 1;
3879 }
3880
3881 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3882 aPosName.LowerCase();
3883 if (aPosName == "center")
3884 {
3885 aPosition = Aspect_TOTP_CENTER;
3886 }
3887 else if (aPosName == "left_lower"
3888 || aPosName == "lower_left"
3889 || aPosName == "leftlower"
3890 || aPosName == "lowerleft")
3891 {
3892 aPosition = Aspect_TOTP_LEFT_LOWER;
3893 }
3894 else if (aPosName == "left_upper"
3895 || aPosName == "upper_left"
3896 || aPosName == "leftupper"
3897 || aPosName == "upperleft")
3898 {
3899 aPosition = Aspect_TOTP_LEFT_UPPER;
3900 }
3901 else if (aPosName == "right_lower"
3902 || aPosName == "lower_right"
3903 || aPosName == "rightlower"
3904 || aPosName == "lowerright")
3905 {
3906 aPosition = Aspect_TOTP_RIGHT_LOWER;
3907 }
3908 else if (aPosName == "right_upper"
3909 || aPosName == "upper_right"
3910 || aPosName == "rightupper"
3911 || aPosName == "upperright")
3912 {
3913 aPosition = Aspect_TOTP_RIGHT_UPPER;
3914 }
3915 else
3916 {
23fe70ec 3917 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
536d98e2 3918 return 1;
3919 }
3920 }
3921 else if (aFlag == "-type")
7c8a8fcc 3922 {
536d98e2 3923 if (++anArgIter >= theArgNb)
3924 {
23fe70ec 3925 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3926 return 1;
3927 }
3928
3929 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3930 aTypeName.LowerCase();
3931 if (aTypeName == "wireframe"
3932 || aTypeName == "wire")
3933 {
3934 aVisType = V3d_WIREFRAME;
3935 }
3936 else if (aTypeName == "zbuffer"
3937 || aTypeName == "shaded")
3938 {
3939 aVisType = V3d_ZBUFFER;
3940 }
3941 else
3942 {
23fe70ec 3943 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
536d98e2 3944 }
3945 }
3946 else if (aFlag == "-scale")
7c8a8fcc 3947 {
536d98e2 3948 if (++anArgIter >= theArgNb)
3949 {
23fe70ec 3950 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3951 return 1;
3952 }
3953
3954 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 3955 }
536d98e2 3956 else if (aFlag == "-size"
3957 || aFlag == "-sizeratio")
3958 {
3959 if (++anArgIter >= theArgNb)
3960 {
23fe70ec 3961 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3962 return 1;
3963 }
7c8a8fcc 3964
536d98e2 3965 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3966 }
3967 else if (aFlag == "-arrowdiam"
3968 || aFlag == "-arrowdiameter")
3969 {
3970 if (++anArgIter >= theArgNb)
3971 {
23fe70ec 3972 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3973 return 1;
3974 }
7c8a8fcc 3975
536d98e2 3976 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3977 }
3978 else if (aFlag == "-nbfacets")
3979 {
3980 if (++anArgIter >= theArgNb)
3981 {
23fe70ec 3982 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 3983 return 1;
3984 }
7c8a8fcc 3985
536d98e2 3986 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3987 }
3988 else if (aFlag == "-colorlabel"
0aeb8984 3989 || aFlag == "-colorlabels"
3990 || aFlag == "-colorlabelx"
3991 || aFlag == "-colorlabely"
3992 || aFlag == "-colorlabelz"
3993 || aFlag == "-colorarrowx"
3994 || aFlag == "-colorarrowy"
3995 || aFlag == "-colorarrowz")
7c8a8fcc 3996 {
0aeb8984 3997 Quantity_Color aColor;
dae2a922 3998 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3999 theArgVec + anArgIter + 1,
0aeb8984 4000 aColor);
536d98e2 4001 if (aNbParsed == 0)
4002 {
23fe70ec 4003 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4004 return 1;
4005 }
0aeb8984 4006
4007 if (aFlag == "-colorarrowx")
536d98e2 4008 {
0aeb8984 4009 anArrowColorX = aColor;
536d98e2 4010 }
0aeb8984 4011 else if (aFlag == "-colorarrowy")
536d98e2 4012 {
0aeb8984 4013 anArrowColorY = aColor;
536d98e2 4014 }
0aeb8984 4015 else if (aFlag == "-colorarrowz")
536d98e2 4016 {
0aeb8984 4017 anArrowColorZ = aColor;
4018 }
4019 else if (aFlag == "-colorlabelx")
4020 {
4021 aLabelsColorX = aColor;
4022 }
4023 else if (aFlag == "-colorlabely")
4024 {
4025 aLabelsColorY = aColor;
4026 }
4027 else if (aFlag == "-colorlabelz")
4028 {
4029 aLabelsColorZ = aColor;
4030 }
4031 else
4032 {
4033 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
536d98e2 4034 }
4035 anArgIter += aNbParsed;
4036 }
4037 else
4038 {
23fe70ec 4039 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
7c8a8fcc 4040 return 1;
4041 }
7c8a8fcc 4042 }
4043
0aeb8984 4044 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
4045 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
4046 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
4047 aTrihedron->SetSizeRatio (aSizeRatio);
4048 aTrihedron->SetNbFacets (aNbFacets);
4049 aTrihedron->SetArrowDiameter(anArrowDiam);
4050 aTrihedron->SetScale (aScale);
4051 aTrihedron->SetPosition (aPosition);
4052 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
4053 aTrihedron->Display (aView);
4054
c357e426 4055 aView->ZFitAll();
7fd59977 4056 return 0;
4057}
4058
4059//==============================================================================
4060//function : VRotate
4061//purpose : Camera Rotating
4062//==============================================================================
4063
4af098ba 4064static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4065{
4066 Handle(V3d_View) aView = ViewerTest::CurrentView();
4067 if (aView.IsNull())
4068 {
23fe70ec 4069 Message::SendFail ("Error: no active viewer");
7fd59977 4070 return 1;
4071 }
4072
4af098ba 4073 Standard_Boolean hasFlags = Standard_False;
4074 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4075 {
4076 Standard_CString anArg (theArgVec[anArgIter]);
4077 TCollection_AsciiString aFlag (anArg);
4078 aFlag.LowerCase();
4079 if (aFlag == "-mousestart"
4080 || aFlag == "-mousefrom")
4081 {
4082 hasFlags = Standard_True;
4083 if (anArgIter + 2 >= theArgNb)
4084 {
23fe70ec 4085 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4086 return 1;
4087 }
4088
4089 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4090 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4091 aView->StartRotation (anX, anY);
4092 }
4093 else if (aFlag == "-mousemove")
4094 {
4095 hasFlags = Standard_True;
4096 if (anArgIter + 2 >= theArgNb)
4097 {
23fe70ec 4098 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4099 return 1;
4100 }
4101
4102 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4103 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4104 aView->Rotation (anX, anY);
4105 }
4106 else if (theArgNb != 4
4107 && theArgNb != 7)
4108 {
23fe70ec 4109 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4110 return 1;
4111 }
4112 }
4113
4114 if (hasFlags)
4115 {
7fd59977 4116 return 0;
4af098ba 4117 }
4118 else if (theArgNb == 4)
4119 {
4120 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4121 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4122 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4123 aView->Rotate (anAX, anAY, anAZ);
4124 return 0;
4125 }
4126 else if (theArgNb == 7)
4127 {
4128 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4129 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4130 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4131
4132 Standard_Real anX = Draw::Atof (theArgVec[4]);
4133 Standard_Real anY = Draw::Atof (theArgVec[5]);
4134 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4135
4136 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4137 return 0;
7fd59977 4138 }
4af098ba 4139
23fe70ec 4140 Message::SendFail ("Error: Invalid number of arguments");
4af098ba 4141 return 1;
7fd59977 4142}
4143
4144//==============================================================================
4145//function : VZoom
4146//purpose : View zoom in / out (relative to current zoom)
4147//==============================================================================
4148
4149static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4150 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4151 if ( V3dView.IsNull() ) {
4152 return 1;
4153 }
4154
4155 if ( argc == 2 ) {
91322f44 4156 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4157 if ( coef <= 0.0 ) {
586db386 4158 di << argv[1] << "Invalid value\n";
7fd59977 4159 return 1;
4160 }
91322f44 4161 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4162 return 0;
4163 } else {
586db386 4164 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4165 return 1;
4166 }
4167}
4168
4169//==============================================================================
4170//function : VPan
4171//purpose : View panning (in pixels)
4172//==============================================================================
4173
4174static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4175 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4176 if ( V3dView.IsNull() ) return 1;
4177
4178 if ( argc == 3 ) {
91322f44 4179 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4180 return 0;
4181 } else {
586db386 4182 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4183 return 1;
4184 }
4185}
4186
49e1a5c7 4187//==============================================================================
4188//function : VPlace
4189//purpose : Place the point (in pixels) at the center of the window
4190//==============================================================================
4191static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4192{
4193 Handle(V3d_View) aView = ViewerTest::CurrentView();
4194 if (aView.IsNull())
4195 {
23fe70ec 4196 Message::SendFail ("Error: no active viewer");
49e1a5c7 4197 return 1;
4198 }
4199
4200 if (theArgNb != 3)
4201 {
23fe70ec 4202 Message::SendFail ("Syntax error: wrong number of arguments");
49e1a5c7 4203 return 1;
4204 }
4205
4206 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4207
4208 return 0;
4209}
7fd59977 4210
71215351 4211static int VColorScale (Draw_Interpretor& theDI,
4212 Standard_Integer theArgNb,
4213 const char** theArgVec)
4214{
7fd59977 4215 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4216 Handle(V3d_View) aView = ViewerTest::CurrentView();
4217 if (aContext.IsNull())
4218 {
23fe70ec 4219 Message::SendFail ("Error: no active viewer");
71215351 4220 return 1;
7fd59977 4221 }
24a88697 4222 if (theArgNb <= 1)
4223 {
23fe70ec 4224 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
24a88697 4225 return 1;
4226 }
7fd59977 4227
4b3d6eb1 4228 Handle(AIS_ColorScale) aColorScale;
7a324550 4229 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4230 {
4b3d6eb1 4231 // find existing object
4232 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4233 if (aColorScale.IsNull())
7a324550 4234 {
23fe70ec 4235 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
7a324550 4236 return 1;
4237 }
4238 }
71215351 4239
7a324550 4240 if (theArgNb <= 2)
4241 {
4b3d6eb1 4242 if (aColorScale.IsNull())
4243 {
23fe70ec 4244 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4b3d6eb1 4245 return 1;
4246 }
4247
7a324550 4248 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4249 << "Min range: " << aColorScale->GetMin() << "\n"
4250 << "Max range: " << aColorScale->GetMax() << "\n"
4251 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4252 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4253 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4254 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4255 << "Label position: ";
4b3d6eb1 4256 switch (aColorScale->GetLabelPosition())
71215351 4257 {
4258 case Aspect_TOCSP_NONE:
4259 theDI << "None\n";
4260 break;
4261 case Aspect_TOCSP_LEFT:
4262 theDI << "Left\n";
4263 break;
4264 case Aspect_TOCSP_RIGHT:
4265 theDI << "Right\n";
4266 break;
4267 case Aspect_TOCSP_CENTER:
4268 theDI << "Center\n";
4269 break;
4270 }
4271 return 0;
4272 }
71215351 4273
4b3d6eb1 4274 if (aColorScale.IsNull())
4275 {
4276 aColorScale = new AIS_ColorScale();
4277 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4278 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4279 }
4280
4281 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4282 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4283 {
4284 Standard_CString anArg = theArgVec[anArgIter];
4285 TCollection_AsciiString aFlag (anArg);
4286 aFlag.LowerCase();
4287 if (anUpdateTool.parseRedrawMode (aFlag))
4288 {
4289 continue;
4290 }
4291 else if (aFlag == "-range")
4292 {
4293 if (anArgIter + 3 >= theArgNb)
4294 {
23fe70ec 4295 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
71215351 4296 return 1;
4297 }
4298
4b3d6eb1 4299 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4300 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4301 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
d45edf24 4302 if (!aRangeMin.IsRealValue (Standard_True)
4303 || !aRangeMax.IsRealValue (Standard_True))
71215351 4304 {
23fe70ec 4305 Message::SendFail ("Syntax error: the range values should be real");
71215351 4306 return 1;
4307 }
4b3d6eb1 4308 else if (!aNbIntervals.IsIntegerValue())
71215351 4309 {
23fe70ec 4310 Message::SendFail ("Syntax error: the number of intervals should be integer");
71215351 4311 return 1;
4312 }
4313
4b3d6eb1 4314 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4315 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4316 }
4317 else if (aFlag == "-font")
4318 {
4319 if (anArgIter + 1 >= theArgNb)
4320 {
23fe70ec 4321 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4322 return 1;
4323 }
51740958 4324 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4325 if (!aFontArg.IsIntegerValue())
71215351 4326 {
23fe70ec 4327 Message::SendFail ("Syntax error: HeightFont value should be integer");
71215351 4328 return 1;
4329 }
4330
4b3d6eb1 4331 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4332 anArgIter += 1;
4333 }
4334 else if (aFlag == "-textpos")
4335 {
4336 if (anArgIter + 1 >= theArgNb)
4337 {
23fe70ec 4338 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4339 return 1;
4340 }
4b3d6eb1 4341
51740958 4342 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4343 aTextPosArg.LowerCase();
4b3d6eb1 4344 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4345 if (aTextPosArg == "none")
71215351 4346 {
4347 aLabPosition = Aspect_TOCSP_NONE;
4348 }
51740958 4349 else if (aTextPosArg == "left")
71215351 4350 {
4351 aLabPosition = Aspect_TOCSP_LEFT;
4352 }
51740958 4353 else if (aTextPosArg == "right")
71215351 4354 {
4355 aLabPosition = Aspect_TOCSP_RIGHT;
4356 }
51740958 4357 else if (aTextPosArg == "center")
71215351 4358 {
4359 aLabPosition = Aspect_TOCSP_CENTER;
4360 }
4361 else
4362 {
23fe70ec 4363 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
71215351 4364 return 1;
4365 }
4b3d6eb1 4366 aColorScale->SetLabelPosition (aLabPosition);
71215351 4367 }
24a88697 4368 else if (aFlag == "-logarithmic"
4369 || aFlag == "-log")
4370 {
4371 if (anArgIter + 1 >= theArgNb)
4372 {
23fe70ec 4373 Message::SendFail() << "Synta error at argument '" << anArg << "'";
24a88697 4374 return 1;
4375 }
4b3d6eb1 4376
24a88697 4377 Standard_Boolean IsLog;
dae2a922 4378 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
24a88697 4379 {
23fe70ec 4380 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
24a88697 4381 return 1;
4382 }
4b3d6eb1 4383 aColorScale->SetLogarithmic (IsLog);
4384 }
4385 else if (aFlag == "-huerange"
4386 || aFlag == "-hue")
4387 {
4388 if (anArgIter + 2 >= theArgNb)
4389 {
23fe70ec 4390 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4391 return 1;
4392 }
4393
4394 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4395 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4396 aColorScale->SetHueRange (aHueMin, aHueMax);
4397 }
4398 else if (aFlag == "-colorrange")
4399 {
4400 Quantity_Color aColorMin, aColorMax;
dae2a922 4401 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4402 theArgVec + (anArgIter + 1),
4403 aColorMin);
4b3d6eb1 4404 anArgIter += aNbParsed1;
dae2a922 4405 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4406 theArgVec + (anArgIter + 1),
4407 aColorMax);
4b3d6eb1 4408 anArgIter += aNbParsed2;
4409 if (aNbParsed1 == 0
4410 || aNbParsed2 == 0)
4411 {
23fe70ec 4412 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4b3d6eb1 4413 return 1;
4414 }
4415
4416 aColorScale->SetColorRange (aColorMin, aColorMax);
4417 }
4418 else if (aFlag == "-reversed"
4419 || aFlag == "-inverted"
4420 || aFlag == "-topdown"
4421 || aFlag == "-bottomup")
4422 {
4423 Standard_Boolean toEnable = Standard_True;
4424 if (anArgIter + 1 < theArgNb
dae2a922 4425 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4426 {
4427 ++anArgIter;
4428 }
4429 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4430 }
4431 else if (aFlag == "-smooth"
4432 || aFlag == "-smoothtransition")
4433 {
4434 Standard_Boolean toEnable = Standard_True;
4435 if (anArgIter + 1 < theArgNb
dae2a922 4436 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4437 {
4438 ++anArgIter;
4439 }
4440 aColorScale->SetSmoothTransition (toEnable);
24a88697 4441 }
71215351 4442 else if (aFlag == "-xy")
4443 {
4444 if (anArgIter + 2 >= theArgNb)
4445 {
23fe70ec 4446 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4447 return 1;
4448 }
4449
4b3d6eb1 4450 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4451 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4452 if (!anX.IsIntegerValue()
4453 || !anY.IsIntegerValue())
71215351 4454 {
23fe70ec 4455 Message::SendFail ("Syntax error: coordinates should be integer values");
71215351 4456 return 1;
4457 }
4458
4b3d6eb1 4459 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4460 }
4461 else if (aFlag == "-width"
4b3d6eb1 4462 || aFlag == "-w"
4463 || aFlag == "-breadth")
b4b2ecca 4464 {
4465 if (anArgIter + 1 >= theArgNb)
4466 {
23fe70ec 4467 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4468 return 1;
4469 }
4470
4b3d6eb1 4471 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4472 if (!aBreadth.IsIntegerValue())
b4b2ecca 4473 {
23fe70ec 4474 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4475 return 1;
4476 }
4b3d6eb1 4477 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4478 }
4479 else if (aFlag == "-height"
4480 || aFlag == "-h")
4481 {
4482 if (anArgIter + 1 >= theArgNb)
4483 {
23fe70ec 4484 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4485 return 1;
4486 }
4487
4b3d6eb1 4488 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4489 if (!aHeight.IsIntegerValue())
b4b2ecca 4490 {
23fe70ec 4491 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4492 return 1;
4493 }
4b3d6eb1 4494 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4495 }
4496 else if (aFlag == "-color")
4497 {
4b3d6eb1 4498 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4499 {
23fe70ec 4500 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
71215351 4501 return 1;
4502 }
4b3d6eb1 4503 else if (anArgIter + 2 >= theArgNb)
71215351 4504 {
23fe70ec 4505 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4506 return 1;
71215351 4507 }
4508
4b3d6eb1 4509 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 4510 if (!anInd.IsIntegerValue())
4511 {
23fe70ec 4512 Message::SendFail ("Syntax error: Index value should be integer");
71215351 4513 return 1;
4514 }
4b3d6eb1 4515 const Standard_Integer anIndex = anInd.IntegerValue();
4516 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 4517 {
23fe70ec 4518 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
71215351 4519 return 1;
4520 }
4521
4b3d6eb1 4522 Quantity_Color aColor;
dae2a922 4523 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4524 theArgVec + (anArgIter + 1),
4525 aColor);
4b3d6eb1 4526 if (aNbParsed == 0)
71215351 4527 {
23fe70ec 4528 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
71215351 4529 return 1;
4530 }
4b3d6eb1 4531 aColorScale->SetIntervalColor (aColor, anIndex);
4532 aColorScale->SetColorType (Aspect_TOCSD_USER);
4533 anArgIter += aNbParsed;
71215351 4534 }
4535 else if (aFlag == "-label")
4536 {
4b3d6eb1 4537 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4538 {
23fe70ec 4539 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
71215351 4540 return 1;
4541 }
4542 else if (anArgIter + 2 >= theArgNb)
4543 {
23fe70ec 4544 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4545 return 1;
4546 }
4547
4548 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 4549 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 4550 {
23fe70ec 4551 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
71215351 4552 return 1;
4553 }
4554
94f16a89 4555 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4b3d6eb1 4556 aColorScale->SetLabel (aText, anIndex);
4557 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4558 anArgIter += 2;
4559 }
4b3d6eb1 4560 else if (aFlag == "-labelat"
4561 || aFlag == "-labat"
4562 || aFlag == "-labelatborder"
4563 || aFlag == "-labatborder"
4564 || aFlag == "-labelatcenter"
4565 || aFlag == "-labatcenter")
71215351 4566 {
4b3d6eb1 4567 Standard_Boolean toEnable = Standard_True;
4568 if (aFlag == "-labelat"
4569 || aFlag == "-labat")
71215351 4570 {
4b3d6eb1 4571 Standard_Integer aLabAtBorder = -1;
4572 if (++anArgIter >= theArgNb)
71215351 4573 {
4b3d6eb1 4574 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4575 anAtBorder.LowerCase();
4576 if (anAtBorder == "border")
71215351 4577 {
4b3d6eb1 4578 aLabAtBorder = 1;
71215351 4579 }
4b3d6eb1 4580 else if (anAtBorder == "center")
71215351 4581 {
4b3d6eb1 4582 aLabAtBorder = 0;
71215351 4583 }
71215351 4584 }
4b3d6eb1 4585 if (aLabAtBorder == -1)
4586 {
23fe70ec 4587 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4588 return 1;
4589 }
4590 toEnable = (aLabAtBorder == 1);
4591 }
4592 else if (anArgIter + 1 < theArgNb
dae2a922 4593 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4594 {
4595 ++anArgIter;
71215351 4596 }
4b3d6eb1 4597 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4598 || aFlag == "-labatcenter"
4599 ? !toEnable
4600 : toEnable);
4601 }
4602 else if (aFlag == "-colors")
4603 {
4604 Aspect_SequenceOfColor aSeq;
4605 for (;;)
4606 {
4607 Quantity_Color aColor;
dae2a922 4608 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4609 theArgVec + (anArgIter + 1),
4610 aColor);
4b3d6eb1 4611 if (aNbParsed == 0)
4612 {
4613 break;
4614 }
4615 anArgIter += aNbParsed;
4616 aSeq.Append (aColor);
4617 }
4618 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 4619 {
23fe70ec 4620 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4621 << aColorScale->GetNumberOfIntervals() << " intervals";
71215351 4622 return 1;
4623 }
4624
4b3d6eb1 4625 aColorScale->SetColors (aSeq);
4626 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 4627 }
14b741b0 4628 else if (aFlag == "-uniform")
4629 {
4630 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4631 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4632 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4633 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4634 aColorScale->SetColorType (Aspect_TOCSD_USER);
4635 }
4b3d6eb1 4636 else if (aFlag == "-labels"
4637 || aFlag == "-freelabels")
71215351 4638 {
4b3d6eb1 4639 if (anArgIter + 1 >= theArgNb)
4640 {
23fe70ec 4641 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4642 return 1;
4643 }
4644
4645 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4646 ? aColorScale->GetNumberOfIntervals() + 1
4647 : aColorScale->GetNumberOfIntervals();
4648 if (aFlag == "-freelabels")
4649 {
4650 ++anArgIter;
4651 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4652 }
4653 if (anArgIter + aNbLabels >= theArgNb)
71215351 4654 {
23fe70ec 4655 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
71215351 4656 return 1;
4657 }
4658
4659 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 4660 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 4661 {
94f16a89 4662 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
71215351 4663 }
4b3d6eb1 4664 aColorScale->SetLabels (aSeq);
4665 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4666 }
4667 else if (aFlag == "-title")
4668 {
4669 if (anArgIter + 1 >= theArgNb)
4670 {
23fe70ec 4671 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4672 return 1;
4673 }
4674
4675 Standard_Boolean isTwoArgs = Standard_False;
4676 if (anArgIter + 2 < theArgNb)
4677 {
4678 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4679 aSecondArg.LowerCase();
4b3d6eb1 4680 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 4681 if (aSecondArg == "none")
4682 {
4b3d6eb1 4683 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 4684 isTwoArgs = Standard_True;
4685 }
4686 else if (aSecondArg == "left")
4687 {
4b3d6eb1 4688 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 4689 isTwoArgs = Standard_True;
4690 }
4691 else if (aSecondArg == "right")
4692 {
4b3d6eb1 4693 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 4694 isTwoArgs = Standard_True;
4695 }
4696 else if (aSecondArg == "center")
4697 {
4b3d6eb1 4698 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 4699 isTwoArgs = Standard_True;
4700 }
4b3d6eb1 4701 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 4702 }
4703
94f16a89 4704 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4705 aColorScale->SetTitle (aTitle);
71215351 4706 if (isTwoArgs)
4707 {
4708 anArgIter += 1;
4709 }
4710 anArgIter += 1;
4711 }
4712 else if (aFlag == "-demoversion"
4713 || aFlag == "-demo")
4714 {
4b3d6eb1 4715 aColorScale->SetPosition (0, 0);
4716 aColorScale->SetTextHeight (16);
4717 aColorScale->SetRange (0.0, 100.0);
4718 aColorScale->SetNumberOfIntervals (10);
4719 aColorScale->SetBreadth (0);
4720 aColorScale->SetHeight (0);
4721 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4722 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4723 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 4724 }
d5514578 4725 else if (aFlag == "-findcolor")
4726 {
4727 if (anArgIter + 1 >= theArgNb)
4728 {
23fe70ec 4729 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
d5514578 4730 return 1;
4731 }
4732
4733 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4734
d45edf24 4735 if (!anArg1.IsRealValue (Standard_True))
d5514578 4736 {
23fe70ec 4737 Message::SendFail ("Syntax error: the value should be real");
d5514578 4738 return 1;
4739 }
4740
4741 Quantity_Color aColor;
4b3d6eb1 4742 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 4743 theDI << Quantity_Color::StringName (aColor.Name());
4744 return 0;
4745 }
71215351 4746 else
4747 {
23fe70ec 4748 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
71215351 4749 return 1;
4750 }
4751 }
4b3d6eb1 4752
4753 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4754 aView->Window()->Size (aWinWidth, aWinHeight);
4755 if (aColorScale->GetBreadth() == 0)
b4b2ecca 4756 {
4b3d6eb1 4757 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 4758 }
4b3d6eb1 4759 if (aColorScale->GetHeight() == 0)
4760 {
4761 aColorScale->SetHeight (aWinHeight);
4762 }
4763 aColorScale->SetToUpdate();
4764 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 4765 return 0;
4766}
4767
4768//==============================================================================
4769//function : VGraduatedTrihedron
a79f67f8 4770//purpose : Displays or hides a graduated trihedron
7fd59977 4771//==============================================================================
a79f67f8 4772static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4773 Quantity_Color& theColor)
13a22457 4774{
a79f67f8 4775 Quantity_NameOfColor aColorName;
4776 TCollection_AsciiString aVal = theValue;
4777 aVal.UpperCase();
4778 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 4779 {
a79f67f8 4780 return Standard_False;
13a22457 4781 }
a79f67f8 4782 theColor = Quantity_Color (aColorName);
4783 return Standard_True;
13a22457
S
4784}
4785
a79f67f8 4786static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 4787{
a79f67f8 4788 if (theArgNum < 2)
13a22457 4789 {
23fe70ec 4790 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4791 << theArgs[0] <<"' for more information";
4792 return 1;
13a22457 4793 }
7fd59977 4794
a79f67f8 4795 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4796 TCollection_AsciiString aParseKey;
4797 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4798 {
4799 TCollection_AsciiString anArg (theArgs [anArgIt]);
4800
d45edf24 4801 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
a79f67f8 4802 {
4803 aParseKey = anArg;
4804 aParseKey.Remove (1);
4805 aParseKey.LowerCase();
4806 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4807 continue;
4808 }
13a22457 4809
a79f67f8 4810 if (aParseKey.IsEmpty())
4811 {
4812 continue;
4813 }
4814
4815 aMapOfArgs(aParseKey)->Append (anArg);
4816 }
4817
4818 // Check parameters
4819 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4820 aMapIt.More(); aMapIt.Next())
7fd59977 4821 {
a79f67f8 4822 const TCollection_AsciiString& aKey = aMapIt.Key();
4823 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4824
4825 // Bool key, without arguments
4826 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4827 && anArgs->IsEmpty())
4828 {
4829 continue;
4830 }
4831
4832 // One argument
4833 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4834 && anArgs->Length() == 1)
4835 {
4836 continue;
4837 }
4838
4839 // On/off arguments
4840 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4841 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 4842 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4843 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 4844 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4845 {
4846 continue;
4847 }
4848
4849 // One string argument
4850 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4851 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
d45edf24 4852 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
a79f67f8 4853 {
4854 continue;
4855 }
4856
4857 // One integer argument
4858 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4859 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4860 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4861 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4862 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4863 {
4864 continue;
4865 }
4866
4867 // One real argument
4868 if ( aKey.IsEqual ("arrowlength")
d45edf24 4869 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
a79f67f8 4870 {
4871 continue;
4872 }
4873
4874 // Two string arguments
4875 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
d45edf24 4876 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
13a22457 4877 {
a79f67f8 4878 continue;
13a22457 4879 }
a79f67f8 4880
4881 TCollection_AsciiString aLowerKey;
4882 aLowerKey = "-";
4883 aLowerKey += aKey;
4884 aLowerKey.LowerCase();
23fe70ec 4885 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4886 << "Type help for more information";
a79f67f8 4887 return 1;
7fd59977 4888 }
4889
a79f67f8 4890 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4891 if (anAISContext.IsNull())
4892 {
23fe70ec 4893 Message::SendFail ("Error: no active viewer");
a79f67f8 4894 return 1;
4895 }
7fd59977 4896
a79f67f8 4897 Standard_Boolean toDisplay = Standard_True;
4898 Quantity_Color aColor;
4899 Graphic3d_GraduatedTrihedron aTrihedronData;
4900 // Process parameters
4901 Handle(TColStd_HSequenceOfAsciiString) aValues;
4902 if (aMapOfArgs.Find ("off", aValues))
7fd59977 4903 {
a79f67f8 4904 toDisplay = Standard_False;
4905 }
13a22457 4906
a79f67f8 4907 // AXES NAMES
4908 if (aMapOfArgs.Find ("xname", aValues))
4909 {
4910 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4911 }
4912 if (aMapOfArgs.Find ("yname", aValues))
4913 {
4914 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4915 }
4916 if (aMapOfArgs.Find ("zname", aValues))
4917 {
4918 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4919 }
4920 if (aMapOfArgs.Find ("xdrawname", aValues))
4921 {
536d98e2 4922 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4923 }
4924 if (aMapOfArgs.Find ("ydrawname", aValues))
4925 {
536d98e2 4926 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4927 }
4928 if (aMapOfArgs.Find ("zdrawname", aValues))
4929 {
536d98e2 4930 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 4931 }
4932 if (aMapOfArgs.Find ("xnameoffset", aValues))
4933 {
4934 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4935 }
4936 if (aMapOfArgs.Find ("ynameoffset", aValues))
4937 {
4938 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4939 }
4940 if (aMapOfArgs.Find ("znameoffset", aValues))
4941 {
4942 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4943 }
13a22457 4944
a79f67f8 4945 // COLORS
4946 if (aMapOfArgs.Find ("xnamecolor", aValues))
4947 {
4948 if (!GetColor (aValues->Value(1), aColor))
13a22457 4949 {
23fe70ec 4950 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
a79f67f8 4951 return 1;
13a22457 4952 }
a79f67f8 4953 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4954 }
4955 if (aMapOfArgs.Find ("ynamecolor", aValues))
4956 {
4957 if (!GetColor (aValues->Value(1), aColor))
13a22457 4958 {
23fe70ec 4959 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
a79f67f8 4960 return 1;
4961 }
4962 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4963 }
4964 if (aMapOfArgs.Find ("znamecolor", aValues))
4965 {
4966 if (!GetColor (aValues->Value(1), aColor))
4967 {
23fe70ec 4968 Message::SendFail ("Syntax error: -znamecolor wrong color name");
a79f67f8 4969 return 1;
4970 }
4971 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4972 }
4973 if (aMapOfArgs.Find ("xcolor", aValues))
4974 {
4975 if (!GetColor (aValues->Value(1), aColor))
4976 {
23fe70ec 4977 Message::SendFail ("Syntax error: -xcolor wrong color name");
a79f67f8 4978 return 1;
4979 }
4980 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4981 }
4982 if (aMapOfArgs.Find ("ycolor", aValues))
4983 {
4984 if (!GetColor (aValues->Value(1), aColor))
4985 {
23fe70ec 4986 Message::SendFail ("Syntax error: -ycolor wrong color name");
a79f67f8 4987 return 1;
4988 }
4989 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4990 }
4991 if (aMapOfArgs.Find ("zcolor", aValues))
4992 {
4993 if (!GetColor (aValues->Value(1), aColor))
4994 {
23fe70ec 4995 Message::SendFail ("Syntax error: -zcolor wrong color name");
a79f67f8 4996 return 1;
4997 }
4998 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4999 }
5000
5001 // TICKMARKS
5002 if (aMapOfArgs.Find ("xticks", aValues))
5003 {
536d98e2 5004 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5005 }
5006 if (aMapOfArgs.Find ("yticks", aValues))
5007 {
536d98e2 5008 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5009 }
5010 if (aMapOfArgs.Find ("zticks", aValues))
5011 {
536d98e2 5012 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5013 }
5014 if (aMapOfArgs.Find ("xticklength", aValues))
5015 {
536d98e2 5016 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5017 }
5018 if (aMapOfArgs.Find ("yticklength", aValues))
5019 {
536d98e2 5020 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5021 }
5022 if (aMapOfArgs.Find ("zticklength", aValues))
5023 {
536d98e2 5024 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5025 }
5026 if (aMapOfArgs.Find ("xdrawticks", aValues))
5027 {
536d98e2 5028 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5029 }
5030 if (aMapOfArgs.Find ("ydrawticks", aValues))
5031 {
536d98e2 5032 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5033 }
5034 if (aMapOfArgs.Find ("zdrawticks", aValues))
5035 {
536d98e2 5036 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5037 }
5038
5039 // VALUES
5040 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5041 {
536d98e2 5042 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5043 }
5044 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5045 {
536d98e2 5046 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5047 }
5048 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5049 {
536d98e2 5050 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5051 }
5052 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5053 {
5054 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5055 }
5056 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5057 {
5058 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5059 }
5060 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5061 {
5062 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5063 }
5064
5065 // ARROWS
5066 if (aMapOfArgs.Find ("arrowlength", aValues))
5067 {
536d98e2 5068 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5069 }
5070
5071 // FONTS
5072 if (aMapOfArgs.Find ("namefont", aValues))
5073 {
5074 aTrihedronData.SetNamesFont (aValues->Value(1));
5075 }
5076 if (aMapOfArgs.Find ("valuesfont", aValues))
5077 {
5078 aTrihedronData.SetValuesFont (aValues->Value(1));
5079 }
5080
536d98e2 5081 if (aMapOfArgs.Find ("drawgrid", aValues))
5082 {
5083 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5084 }
5085 if (aMapOfArgs.Find ("drawaxes", aValues))
5086 {
5087 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5088 }
5089
a79f67f8 5090 // The final step: display of erase trihedron
5091 if (toDisplay)
5092 {
5093 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5094 }
7fd59977 5095 else
a79f67f8 5096 {
5097 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5098 }
7fd59977 5099
5100 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5101 ViewerTest::CurrentView()->Redraw();
13a22457 5102
7fd59977 5103 return 0;
5104}
5105
3bffef55 5106//==============================================================================
5107//function : VTile
5108//purpose :
5109//==============================================================================
5110static int VTile (Draw_Interpretor& theDI,
5111 Standard_Integer theArgNb,
5112 const char** theArgVec)
5113{
5114 Handle(V3d_View) aView = ViewerTest::CurrentView();
5115 if (aView.IsNull())
5116 {
23fe70ec 5117 Message::SendFail ("Error: no active viewer");
3bffef55 5118 return 1;
5119 }
5120
5121 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5122 if (theArgNb < 2)
5123 {
5124 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5125 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5126 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5127 return 0;
5128 }
5129
5130 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5131 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5132 {
5133 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5134 anArg.LowerCase();
5135 if (anArg == "-lowerleft"
5136 || anArg == "-upperleft")
5137 {
5138 if (anArgIter + 3 < theArgNb)
5139 {
23fe70ec 5140 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5141 return 1;
5142 }
5143 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5144 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5145 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5146 }
5147 else if (anArg == "-total"
5148 || anArg == "-totalsize"
5149 || anArg == "-viewsize")
5150 {
5151 if (anArgIter + 3 < theArgNb)
5152 {
23fe70ec 5153 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5154 return 1;
5155 }
5156 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5157 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5158 if (aTile.TotalSize.x() < 1
5159 || aTile.TotalSize.y() < 1)
5160 {
23fe70ec 5161 Message::SendFail ("Error: total size is incorrect");
3bffef55 5162 return 1;
5163 }
5164 }
5165 else if (anArg == "-tilesize")
5166 {
5167 if (anArgIter + 3 < theArgNb)
5168 {
23fe70ec 5169 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5170 return 1;
5171 }
5172
5173 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5174 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5175 if (aTile.TileSize.x() < 1
5176 || aTile.TileSize.y() < 1)
5177 {
23fe70ec 5178 Message::SendFail ("Error: tile size is incorrect");
3bffef55 5179 return 1;
5180 }
5181 }
5182 else if (anArg == "-unset")
5183 {
5184 aView->Camera()->SetTile (Graphic3d_CameraTile());
5185 aView->Redraw();
5186 return 0;
5187 }
5188 }
5189
5190 if (aTile.TileSize.x() < 1
5191 || aTile.TileSize.y() < 1)
5192 {
23fe70ec 5193 Message::SendFail ("Error: tile size is undefined");
3bffef55 5194 return 1;
5195 }
5196 else if (aTile.TotalSize.x() < 1
5197 || aTile.TotalSize.y() < 1)
5198 {
23fe70ec 5199 Message::SendFail ("Error: total size is undefined");
3bffef55 5200 return 1;
5201 }
5202
5203 aView->Camera()->SetTile (aTile);
5204 aView->Redraw();
5205 return 0;
5206}
5207
7c3ef2f7 5208//! Format ZLayer ID.
5209inline const char* formZLayerId (const Standard_Integer theLayerId)
5210{
5211 switch (theLayerId)
5212 {
5213 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5214 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5215 case Graphic3d_ZLayerId_Top: return "[TOP]";
5216 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5217 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5218 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5219 }
5220 return "";
5221}
5222
5223//! Print the ZLayer information.
5224inline void printZLayerInfo (Draw_Interpretor& theDI,
5225 const Graphic3d_ZLayerSettings& theLayer)
5226{
5227 if (!theLayer.Name().IsEmpty())
5228 {
5229 theDI << " Name: " << theLayer.Name() << "\n";
5230 }
5231 if (theLayer.IsImmediate())
5232 {
5233 theDI << " Immediate: TRUE\n";
5234 }
5235 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5236 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5237 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5238 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5239 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5240 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5241 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5242 {
5243 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5244 }
5245}
5246
59f45b7c 5247//==============================================================================
5248//function : VZLayer
5249//purpose : Test z layer operations for v3d viewer
5250//==============================================================================
7c3ef2f7 5251static int VZLayer (Draw_Interpretor& theDI,
5252 Standard_Integer theArgNb,
5253 const char** theArgVec)
59f45b7c 5254{
7c3ef2f7 5255 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5256 if (aContextAIS.IsNull())
5257 {
23fe70ec 5258 Message::SendFail ("Error: no active viewer");
59f45b7c 5259 return 1;
5260 }
5261
5262 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5263 if (theArgNb < 2)
59f45b7c 5264 {
7c3ef2f7 5265 TColStd_SequenceOfInteger aLayers;
5266 aViewer->GetAllZLayers (aLayers);
5267 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5268 {
5269 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5270 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5271 printZLayerInfo (theDI, aSettings);
5272 }
95bdefb2 5273 return 0;
59f45b7c 5274 }
5275
7c3ef2f7 5276 Standard_Integer anArgIter = 1;
5277 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5278 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5279 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5280 {
7c3ef2f7 5281 ++anArgIter;
5282 }
59f45b7c 5283
7c3ef2f7 5284 {
55c8f0f7
BB
5285 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5286 if (aFirstArg.IsIntegerValue())
c5751993 5287 {
7c3ef2f7 5288 ++anArgIter;
55c8f0f7 5289 aLayerId = aFirstArg.IntegerValue();
c5751993 5290 }
7c3ef2f7 5291 else
c5751993 5292 {
55c8f0f7 5293 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5294 {
55c8f0f7 5295 ++anArgIter;
7c3ef2f7 5296 }
c5751993 5297 }
7c3ef2f7 5298 }
c5751993 5299
1c728f2d 5300 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
7c3ef2f7 5301 for (; anArgIter < theArgNb; ++anArgIter)
5302 {
5303 // perform operation
5304 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5305 anArg.LowerCase();
5306 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5307 {
7c3ef2f7 5308 //
c5751993 5309 }
7c3ef2f7 5310 else if (anArg == "-add"
5311 || anArg == "add")
c5751993 5312 {
7c3ef2f7 5313 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5314 if (!aViewer->AddZLayer (aLayerId))
5315 {
23fe70ec 5316 Message::SendFail ("Error: can not add a new z layer");
7c3ef2f7 5317 return 0;
5318 }
5319
5320 theDI << aLayerId;
c5751993 5321 }
1c728f2d 5322 else if (anArg == "-insertbefore"
5323 && anArgIter + 1 < theArgNb
5324 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5325 {
5326 ++anArgIter;
5327 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5328 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5329 {
23fe70ec 5330 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5331 return 0;
5332 }
5333
5334 theDI << aLayerId;
5335 }
5336 else if (anArg == "-insertafter"
5337 && anArgIter + 1 < theArgNb
5338 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5339 {
5340 ++anArgIter;
5341 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5342 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5343 {
23fe70ec 5344 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5345 return 0;
5346 }
5347
5348 theDI << aLayerId;
5349 }
7c3ef2f7 5350 else if (anArg == "-del"
5351 || anArg == "-delete"
5352 || anArg == "del")
c5751993 5353 {
7c3ef2f7 5354 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5355 {
5356 if (++anArgIter >= theArgNb)
5357 {
23fe70ec 5358 Message::SendFail ("Syntax error: id of z layer to remove is missing");
7c3ef2f7 5359 return 1;
5360 }
5361
5362 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5363 }
5364
5365 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5366 || aLayerId == Graphic3d_ZLayerId_Default
5367 || aLayerId == Graphic3d_ZLayerId_Top
5368 || aLayerId == Graphic3d_ZLayerId_Topmost
5369 || aLayerId == Graphic3d_ZLayerId_TopOSD
5370 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5371 {
23fe70ec 5372 Message::SendFail ("Syntax error: standard Z layer can not be removed");
7c3ef2f7 5373 return 1;
5374 }
5375
5376 // move all object displayed in removing layer to default layer
5377 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5378 anObjIter.More(); anObjIter.Next())
5379 {
8f521168 5380 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5381 if (aPrs.IsNull()
5382 || aPrs->ZLayer() != aLayerId)
5383 {
5384 continue;
5385 }
5386 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5387 }
5388
5389 if (!aViewer->RemoveZLayer (aLayerId))
5390 {
23fe70ec 5391 Message::SendFail ("Z layer can not be removed");
7c3ef2f7 5392 }
5393 else
5394 {
5395 theDI << aLayerId << " ";
5396 }
c5751993 5397 }
7c3ef2f7 5398 else if (anArg == "-get"
5399 || anArg == "get")
c5751993 5400 {
7c3ef2f7 5401 TColStd_SequenceOfInteger aLayers;
5402 aViewer->GetAllZLayers (aLayers);
5403 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5404 {
5405 theDI << aLayeriter.Value() << " ";
5406 }
5407
5408 theDI << "\n";
c5751993 5409 }
7c3ef2f7 5410 else if (anArg == "-name")
c5751993 5411 {
7c3ef2f7 5412 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5413 {
23fe70ec 5414 Message::SendFail ("Syntax error: id of Z layer is missing");
c5751993 5415 return 1;
5416 }
5417
7c3ef2f7 5418 if (++anArgIter >= theArgNb)
5419 {
23fe70ec 5420 Message::SendFail ("Syntax error: name is missing");
7c3ef2f7 5421 return 1;
5422 }
c5751993 5423
7c3ef2f7 5424 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5425 aSettings.SetName (theArgVec[anArgIter]);
5426 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5427 }
7c3ef2f7 5428 else if (anArg == "-origin")
c5751993 5429 {
7c3ef2f7 5430 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5431 {
23fe70ec 5432 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5433 return 1;
5434 }
5435
5436 if (anArgIter + 2 >= theArgNb)
5437 {
23fe70ec 5438 Message::SendFail ("Syntax error: origin coordinates are missing");
7c3ef2f7 5439 return 1;
5440 }
5441
5442 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5443 gp_XYZ anOrigin;
5444 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5445 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5446 anOrigin.SetZ (0.0);
5447 if (anArgIter + 3 < theArgNb)
5448 {
5449 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5450 anArgIter += 3;
5451 }
5452 else
5453 {
5454 anArgIter += 2;
5455 }
5456 aSettings.SetOrigin (anOrigin);
5457 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5458 }
4ecf34cc 5459 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5460 && anArgIter + 1 < theArgNb
5461 && (anArg == "-cullingdistance"
5462 || anArg == "-cullingdist"
5463 || anArg == "-culldistance"
5464 || anArg == "-culldist"
5465 || anArg == "-distcull"
5466 || anArg == "-distculling"
5467 || anArg == "-distanceculling"))
5468 {
5469 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5470 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5471 aSettings.SetCullingDistance (aDist);
5472 aViewer->SetZLayerSettings (aLayerId, aSettings);
5473 }
5474 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5475 && anArgIter + 1 < theArgNb
5476 && (anArg == "-cullingsize"
5477 || anArg == "-cullsize"
5478 || anArg == "-sizecull"
5479 || anArg == "-sizeculling"))
5480 {
5481 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5482 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5483 aSettings.SetCullingSize (aSize);
5484 aViewer->SetZLayerSettings (aLayerId, aSettings);
5485 }
7c3ef2f7 5486 else if (anArg == "-settings"
5487 || anArg == "settings")
c5751993 5488 {
7c3ef2f7 5489 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5490 {
5491 if (++anArgIter >= theArgNb)
5492 {
23fe70ec 5493 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5494 return 1;
5495 }
5496
5497 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5498 }
5499
5500 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5501 printZLayerInfo (theDI, aSettings);
c5751993 5502 }
7c3ef2f7 5503 else if (anArg == "-enable"
5504 || anArg == "enable"
5505 || anArg == "-disable"
5506 || anArg == "disable")
83da37b1 5507 {
7c3ef2f7 5508 const Standard_Boolean toEnable = anArg == "-enable"
5509 || anArg == "enable";
5510 if (++anArgIter >= theArgNb)
5511 {
23fe70ec 5512 Message::SendFail ("Syntax error: option name is missing");
7c3ef2f7 5513 return 1;
5514 }
c5751993 5515
7c3ef2f7 5516 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5517 aSubOp.LowerCase();
5518 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5519 {
5520 if (++anArgIter >= theArgNb)
5521 {
23fe70ec 5522 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5523 return 1;
5524 }
c5751993 5525
7c3ef2f7 5526 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5527 }
c5751993 5528
7c3ef2f7 5529 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5530 if (aSubOp == "depthtest"
5531 || aSubOp == "test")
5532 {
5533 aSettings.SetEnableDepthTest (toEnable);
5534 }
5535 else if (aSubOp == "depthwrite"
5536 || aSubOp == "write")
5537 {
5538 aSettings.SetEnableDepthWrite (toEnable);
5539 }
5540 else if (aSubOp == "depthclear"
5541 || aSubOp == "clear")
5542 {
5543 aSettings.SetClearDepth (toEnable);
5544 }
5545 else if (aSubOp == "depthoffset"
5546 || aSubOp == "offset")
5547 {
5548 Graphic3d_PolygonOffset aParams;
5549 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5550 if (toEnable)
5551 {
5552 if (anArgIter + 2 >= theArgNb)
5553 {
23fe70ec 5554 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
7c3ef2f7 5555 return 1;
5556 }
c5751993 5557
7c3ef2f7 5558 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5559 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5560 }
5561 aSettings.SetPolygonOffset (aParams);
5562 }
5563 else if (aSubOp == "positiveoffset"
5564 || aSubOp == "poffset")
5565 {
5566 if (toEnable)
5567 {
5568 aSettings.SetDepthOffsetPositive();
5569 }
5570 else
5571 {
5572 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5573 }
5574 }
5575 else if (aSubOp == "negativeoffset"
5576 || aSubOp == "noffset")
5577 {
5578 if (toEnable)
5579 {
5580 aSettings.SetDepthOffsetNegative();
5581 }
5582 else
5583 {
5584 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5585 }
5586 }
5587 else if (aSubOp == "textureenv")
5588 {
5589 aSettings.SetEnvironmentTexture (toEnable);
5590 }
1c728f2d 5591 else if (aSubOp == "raytracing")
5592 {
5593 aSettings.SetRaytracable (toEnable);
5594 }
7c3ef2f7 5595
5596 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5597 }
7c3ef2f7 5598 else
83da37b1 5599 {
23fe70ec 5600 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
7c3ef2f7 5601 return 1;
83da37b1 5602 }
59f45b7c 5603 }
5604
5605 return 0;
5606}
5607
c357e426 5608// The interactive presentation of 2d layer item
5609// for "vlayerline" command it provides a presentation of
5610// line with user-defined linewidth, linetype and transparency.
61b0191c 5611class V3d_LineItem : public AIS_InteractiveObject
20637bd2 5612{
5613public:
5614 // CASCADE RTTI
92efcf78 5615 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 5616
20637bd2 5617 // constructor
5618 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5619 Standard_Real X2, Standard_Real Y2,
20637bd2 5620 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5621 Standard_Real theWidth = 0.5,
5622 Standard_Real theTransp = 1.0);
5623
decbff0d 5624private:
61b0191c 5625
decbff0d 5626 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5627 const Handle(Prs3d_Presentation)& thePrs,
5628 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 5629
decbff0d 5630 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5631 const Standard_Integer ) Standard_OVERRIDE
79104795 5632 {}
20637bd2 5633
5634private:
5635
5636 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 5637 Aspect_TypeOfLine myType;
20637bd2 5638 Standard_Real myWidth;
20637bd2 5639};
5640
20637bd2 5641// default constructor for line item
4fe56619 5642V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 5643 Standard_Real X2, Standard_Real Y2,
20637bd2 5644 Aspect_TypeOfLine theType,
5645 Standard_Real theWidth,
5646 Standard_Real theTransp) :
61b0191c 5647 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5648 myType(theType), myWidth(theWidth)
20637bd2 5649{
61b0191c 5650 SetTransparency (1-theTransp);
20637bd2 5651}
5652
5653// render line
decbff0d 5654void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
61b0191c 5655 const Handle(Prs3d_Presentation)& thePresentation,
decbff0d 5656 const Standard_Integer )
20637bd2 5657{
61b0191c 5658 thePresentation->Clear();
ba00aab7 5659 Quantity_Color aColor (Quantity_NOC_RED);
61b0191c 5660 Standard_Integer aWidth, aHeight;
5661 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
d6c48921 5662 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
61b0191c 5663 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5664 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5665 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5666 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5667 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5668 aGroup->AddPrimitiveArray (aPrim);
20637bd2 5669}
5670
5671//=============================================================================
5672//function : VLayerLine
5673//purpose : Draws line in the v3d view layer with given attributes: linetype,
5674// : linewidth, transparency coefficient
5675//============================================================================
5676static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5677{
5678 // get the active view
5679 Handle(V3d_View) aView = ViewerTest::CurrentView();
5680 if (aView.IsNull())
5681 {
5682 di << "Call vinit before!\n";
5683 return 1;
5684 }
5685 else if (argc < 5)
5686 {
5687 di << "Use: " << argv[0];
5688 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5689 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5690 di << " 0 - solid \n";
5691 di << " 1 - dashed \n";
5692 di << " 2 - dot \n";
5693 di << " 3 - dashdot\n";
5694 di << " transparency : { 0.0 - 1.0 } \n";
5695 di << " 0.0 - transparent\n";
5696 di << " 1.0 - visible \n";
5697 return 1;
5698 }
5699
61b0191c 5700 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 5701 // get the input params
91322f44 5702 Standard_Real X1 = Draw::Atof(argv[1]);
5703 Standard_Real Y1 = Draw::Atof(argv[2]);
5704 Standard_Real X2 = Draw::Atof(argv[3]);
5705 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 5706
3a4a3962 5707 Standard_Real aWidth = 0.5;
5708 Standard_Real aTransparency = 1.0;
20637bd2 5709
5710 // has width
5711 if (argc > 5)
91322f44 5712 aWidth = Draw::Atof(argv[5]);
20637bd2 5713
3a4a3962 5714 // select appropriate line type
5715 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5716 if (argc > 6
5717 && !ViewerTest::ParseLineType (argv[6], aLineType))
5718 {
23fe70ec 5719 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
3a4a3962 5720 return 1;
5721 }
20637bd2 5722
5723 // has transparency
5724 if (argc > 7)
5725 {
91322f44 5726 aTransparency = Draw::Atof(argv[7]);
4fe56619 5727 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 5728 aTransparency = 1.0;
5729 }
5730
61b0191c 5731 static Handle (V3d_LineItem) aLine;
5732 if (!aLine.IsNull())
25289ec1 5733 {
0577ae8c 5734 aContext->Erase (aLine, Standard_False);
25289ec1 5735 }
61b0191c 5736 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5737 aLineType, aWidth,
5738 aTransparency);
25289ec1 5739
778cd667 5740 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 5741 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5742 aLine->SetToUpdate();
5743 aContext->Display (aLine, Standard_True);
25289ec1 5744
5745 return 0;
5746}
5747
61b0191c 5748
2bd4c032 5749//==============================================================================
5750//function : VGrid
5751//purpose :
5752//==============================================================================
5753
35e08fe8 5754static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 5755 Standard_Integer theArgNb,
5756 const char** theArgVec)
5757{
2bd4c032 5758 Handle(V3d_View) aView = ViewerTest::CurrentView();
5759 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5760 if (aView.IsNull() || aViewer.IsNull())
5761 {
23fe70ec 5762 Message::SendFail ("Error: no active viewer");
2bd4c032 5763 return 1;
5764 }
5765
5766 Aspect_GridType aType = aViewer->GridType();
5767 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 5768 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5769 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5770 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 5771 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 5772 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 5773 {
79931835 5774 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5775 anArg.LowerCase();
5776 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 5777 {
5778 continue;
5779 }
79931835 5780 else if (anArgIter + 1 < theArgNb
5781 && anArg == "-type")
5782 {
5783 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5784 anArgNext.LowerCase();
5785 if (anArgNext == "r"
5786 || anArgNext == "rect"
5787 || anArgNext == "rectangular")
5788 {
5789 aType = Aspect_GT_Rectangular;
5790 }
5791 else if (anArgNext == "c"
5792 || anArgNext == "circ"
5793 || anArgNext == "circular")
5794 {
5795 aType = Aspect_GT_Circular;
5796 }
5797 else
5798 {
23fe70ec 5799 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5800 return 1;
5801 }
5802 }
5803 else if (anArgIter + 1 < theArgNb
5804 && anArg == "-mode")
5805 {
5806 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5807 anArgNext.LowerCase();
5808 if (anArgNext == "l"
5809 || anArgNext == "line"
5810 || anArgNext == "lines")
5811 {
5812 aMode = Aspect_GDM_Lines;
5813 }
5814 else if (anArgNext == "p"
5815 || anArgNext == "point"
5816 || anArgNext == "points")
5817 {
5818 aMode = Aspect_GDM_Points;
5819 }
5820 else
5821 {
23fe70ec 5822 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5823 return 1;
5824 }
5825 }
5826 else if (anArgIter + 2 < theArgNb
5827 && (anArg == "-origin"
5828 || anArg == "-orig"))
5829 {
5830 hasOrigin = true;
5831 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5832 Draw::Atof (theArgVec[anArgIter + 2]));
5833 anArgIter += 2;
5834 }
5835 else if (anArgIter + 2 < theArgNb
5836 && anArg == "-step")
5837 {
5838 hasStep = true;
5839 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5840 Draw::Atof (theArgVec[anArgIter + 2]));
5841 if (aNewStepXY.x() <= 0.0
5842 || aNewStepXY.y() <= 0.0)
5843 {
23fe70ec 5844 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 5845 return 1;
5846 }
5847 anArgIter += 2;
5848 }
5849 else if (anArgIter + 1 < theArgNb
5850 && (anArg == "-angle"
5851 || anArg == "-rotangle"
5852 || anArg == "-rotationangle"))
5853 {
5854 hasRotAngle = true;
5855 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5856 }
5857 else if (anArgIter + 1 < theArgNb
5858 && (anArg == "-zoffset"
5859 || anArg == "-dz"))
5860 {
5861 hasZOffset = true;
5862 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5863 }
5864 else if (anArgIter + 1 < theArgNb
5865 && anArg == "-radius")
5866 {
5867 hasSize = true;
5868 ++anArgIter;
5869 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5870 if (aNewStepXY.x() <= 0.0)
5871 {
23fe70ec 5872 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
79931835 5873 return 1;
5874 }
5875 }
5876 else if (anArgIter + 2 < theArgNb
5877 && anArg == "-size")
5878 {
5879 hasSize = true;
5880 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5881 Draw::Atof (theArgVec[anArgIter + 2]));
5882 if (aNewStepXY.x() <= 0.0
5883 || aNewStepXY.y() <= 0.0)
5884 {
23fe70ec 5885 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 5886 return 1;
5887 }
5888 anArgIter += 2;
5889 }
5890 else if (anArg == "r"
5891 || anArg == "rect"
5892 || anArg == "rectangular")
2bd4c032 5893 {
5894 aType = Aspect_GT_Rectangular;
5895 }
79931835 5896 else if (anArg == "c"
5897 || anArg == "circ"
5898 || anArg == "circular")
2bd4c032 5899 {
5900 aType = Aspect_GT_Circular;
5901 }
79931835 5902 else if (anArg == "l"
5903 || anArg == "line"
5904 || anArg == "lines")
2bd4c032 5905 {
5906 aMode = Aspect_GDM_Lines;
5907 }
79931835 5908 else if (anArg == "p"
5909 || anArg == "point"
5910 || anArg == "points")
2bd4c032 5911 {
5912 aMode = Aspect_GDM_Points;
5913 }
79931835 5914 else if (anArgIter + 1 >= theArgNb
5915 && anArg == "off")
2bd4c032 5916 {
5917 aViewer->DeactivateGrid();
5918 return 0;
5919 }
5920 else
5921 {
23fe70ec 5922 Message::SendFail() << "Syntax error at '" << anArg << "'";
79931835 5923 return 1;
2bd4c032 5924 }
5925 }
5926
2bd4c032 5927 if (aType == Aspect_GT_Rectangular)
5928 {
79931835 5929 Graphic3d_Vec2d anOrigXY, aStepXY;
5930 Standard_Real aRotAngle = 0.0;
5931 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5932 if (hasOrigin)
5933 {
5934 anOrigXY = aNewOriginXY;
5935 }
5936 if (hasStep)
5937 {
5938 aStepXY = aNewStepXY;
5939 }
5940 if (hasRotAngle)
5941 {
5942 aRotAngle = aNewRotAngle;
5943 }
5944 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5945 if (hasSize || hasZOffset)
2bd4c032 5946 {
79931835 5947 Graphic3d_Vec3d aSize;
5948 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5949 if (hasSize)
5950 {
5951 aSize.x() = aNewSizeXY.x();
5952 aSize.y() = aNewSizeXY.y();
5953 }
5954 if (hasZOffset)
5955 {
5956 aSize.z() = aNewZOffset;
5957 }
5958 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 5959 }
2bd4c032 5960 }
5961 else if (aType == Aspect_GT_Circular)
5962 {
79931835 5963 Graphic3d_Vec2d anOrigXY;
ee2be2a8 5964 Standard_Real aRadiusStep;
2bd4c032 5965 Standard_Integer aDivisionNumber;
79931835 5966 Standard_Real aRotAngle = 0.0;
5967 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5968 if (hasOrigin)
5969 {
5970 anOrigXY = aNewOriginXY;
5971 }
5972 if (hasStep)
5973 {
5974 aRadiusStep = aNewStepXY[0];
5975 aDivisionNumber = (int )aNewStepXY[1];
5976 if (aDivisionNumber < 1)
5977 {
23fe70ec 5978 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
79931835 5979 return 1;
5980 }
5981 }
5982 if (hasRotAngle)
2bd4c032 5983 {
79931835 5984 aRotAngle = aNewRotAngle;
2bd4c032 5985 }
5986
79931835 5987 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5988 if (hasSize || hasZOffset)
5989 {
5990 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5991 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5992 if (hasSize)
5993 {
5994 aRadius = aNewSizeXY.x();
5995 if (aNewSizeXY.y() != 0.0)
5996 {
23fe70ec 5997 Message::SendFail ("Syntax error: circular size should be specified as radius");
79931835 5998 return 1;
5999 }
6000 }
6001 if (hasZOffset)
6002 {
6003 aZOffset = aNewZOffset;
6004 }
6005 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6006 }
2bd4c032 6007 }
79931835 6008 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6009 return 0;
6010}
6011
c40b7d58 6012//==============================================================================
6013//function : VPriviledgedPlane
6014//purpose :
6015//==============================================================================
6016
6017static int VPriviledgedPlane (Draw_Interpretor& theDI,
6018 Standard_Integer theArgNb,
6019 const char** theArgVec)
6020{
6021 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6022 {
23fe70ec 6023 Message::SendFail ("Error: wrong number of arguments! See usage:");
c40b7d58 6024 theDI.PrintHelp (theArgVec[0]);
6025 return 1;
6026 }
6027
6028 // get the active viewer
6029 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6030 if (aViewer.IsNull())
6031 {
23fe70ec 6032 Message::SendFail ("Error: no active viewer");
c40b7d58 6033 return 1;
6034 }
6035
6036 if (theArgNb == 1)
6037 {
6038 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6039 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6040 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6041 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6042 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6043 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6044 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6045 return 0;
6046 }
6047
6048 Standard_Integer anArgIdx = 1;
6049 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6050 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6051 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6052 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6053 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6054 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6055
6056 gp_Ax3 aPriviledgedPlane;
6057 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6058 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6059 if (theArgNb > 7)
6060 {
6061 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6062 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6063 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6064 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6065 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6066 }
6067 else
6068 {
6069 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6070 }
6071
6072 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6073
6074 return 0;
6075}
6076
f25b82d6 6077//==============================================================================
6078//function : VConvert
6079//purpose :
6080//==============================================================================
6081
6082static int VConvert (Draw_Interpretor& theDI,
6083 Standard_Integer theArgNb,
6084 const char** theArgVec)
6085{
6086 // get the active view
6087 Handle(V3d_View) aView = ViewerTest::CurrentView();
6088 if (aView.IsNull())
6089 {
23fe70ec 6090 Message::SendFail ("Error: no active viewer");
f25b82d6 6091 return 1;
6092 }
6093
6094 enum { Model, Ray, View, Window, Grid } aMode = Model;
6095
6096 // access coordinate arguments
6097 TColStd_SequenceOfReal aCoord;
6098 Standard_Integer anArgIdx = 1;
6099 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6100 {
6101 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
d45edf24 6102 if (!anArg.IsRealValue (Standard_True))
f25b82d6 6103 {
6104 break;
6105 }
6106 aCoord.Append (anArg.RealValue());
6107 }
6108
6109 // non-numeric argument too early
6110 if (aCoord.IsEmpty())
6111 {
23fe70ec 6112 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6113 theDI.PrintHelp (theArgVec[0]);
6114 return 1;
6115 }
6116
6117 // collect all other arguments and options
6118 for (; anArgIdx < theArgNb; ++anArgIdx)
6119 {
6120 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6121 anArg.LowerCase();
6122 if (anArg == "window") aMode = Window;
6123 else if (anArg == "view") aMode = View;
6124 else if (anArg == "grid") aMode = Grid;
6125 else if (anArg == "ray") aMode = Ray;
6126 else
6127 {
23fe70ec 6128 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
f25b82d6 6129 theDI.PrintHelp (theArgVec[0]);
6130 return 1;
6131 }
6132 }
6133
6134 // complete input checks
6135 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6136 (aCoord.Length() == 2 && theArgNb > 4) ||
6137 (aCoord.Length() == 3 && theArgNb > 5))
6138 {
23fe70ec 6139 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6140 theDI.PrintHelp (theArgVec[0]);
6141 return 1;
6142 }
6143
6144 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6145 Standard_Integer aXYp[2] = {0, 0};
6146
6147 // convert one-dimensional coordinate
6148 if (aCoord.Length() == 1)
6149 {
6150 switch (aMode)
6151 {
ee2be2a8 6152 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6153 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6154 default:
23fe70ec 6155 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6156 theDI.PrintHelp (theArgVec[0]);
6157 return 1;
6158 }
6159 }
6160
6161 // convert 2D coordinates from projection or view reference space
6162 if (aCoord.Length() == 2)
6163 {
6164 switch (aMode)
6165 {
6166 case Model :
6167 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6168 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6169 return 0;
6170
6171 case View :
6172 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6173 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6174 return 0;
6175
6176 case Window :
ee2be2a8 6177 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6178 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6179 return 0;
6180
6181 case Grid :
6182 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6183 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6184 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6185 return 0;
6186
6187 case Ray :
6188 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6189 (Standard_Integer) aCoord (2),
6190 aXYZ[0], aXYZ[1], aXYZ[2],
6191 aXYZ[3], aXYZ[4], aXYZ[5]);
6192 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6193 return 0;
6194
6195 default:
23fe70ec 6196 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6197 theDI.PrintHelp (theArgVec[0]);
6198 return 1;
6199 }
6200 }
6201
6202 // convert 3D coordinates from view reference space
6203 else if (aCoord.Length() == 3)
6204 {
6205 switch (aMode)
6206 {
6207 case Window :
6208 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6209 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6210 return 0;
6211
6212 case Grid :
6213 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6214 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6215 return 0;
6216
6217 default:
23fe70ec 6218 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6219 theDI.PrintHelp (theArgVec[0]);
6220 return 1;
6221 }
6222 }
6223
6224 return 0;
6225}
6226
208e6839 6227//==============================================================================
6228//function : VFps
6229//purpose :
6230//==============================================================================
6231
6232static int VFps (Draw_Interpretor& theDI,
6233 Standard_Integer theArgNb,
6234 const char** theArgVec)
6235{
6236 // get the active view
6237 Handle(V3d_View) aView = ViewerTest::CurrentView();
6238 if (aView.IsNull())
6239 {
23fe70ec 6240 Message::SendFail ("Error: no active viewer");
208e6839 6241 return 1;
6242 }
6243
e084dbbc 6244 Standard_Integer aFramesNb = -1;
6245 Standard_Real aDuration = -1.0;
6246 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6247 {
e084dbbc 6248 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6249 anArg.LowerCase();
6250 if (aDuration < 0.0
6251 && anArgIter + 1 < theArgNb
6252 && (anArg == "-duration"
6253 || anArg == "-dur"
6254 || anArg == "-time"))
6255 {
6256 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6257 }
6258 else if (aFramesNb < 0
6259 && anArg.IsIntegerValue())
6260 {
6261 aFramesNb = anArg.IntegerValue();
6262 if (aFramesNb <= 0)
6263 {
23fe70ec 6264 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6265 return 1;
6266 }
6267 }
6268 else
6269 {
23fe70ec 6270 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6271 return 1;
6272 }
6273 }
6274 if (aFramesNb < 0 && aDuration < 0.0)
6275 {
6276 aFramesNb = 100;
208e6839 6277 }
6278
6279 // the time is meaningless for first call
6280 // due to async OpenGl rendering
6281 aView->Redraw();
6282
6283 // redraw view in loop to estimate average values
6284 OSD_Timer aTimer;
6285 aTimer.Start();
e084dbbc 6286 Standard_Integer aFrameIter = 1;
6287 for (;; ++aFrameIter)
208e6839 6288 {
6289 aView->Redraw();
e084dbbc 6290 if ((aFramesNb > 0
6291 && aFrameIter >= aFramesNb)
6292 || (aDuration > 0.0
6293 && aTimer.ElapsedTime() >= aDuration))
6294 {
6295 break;
6296 }
208e6839 6297 }
6298 aTimer.Stop();
6299 Standard_Real aCpu;
6300 const Standard_Real aTime = aTimer.ElapsedTime();
6301 aTimer.OSD_Chronometer::Show (aCpu);
6302
e084dbbc 6303 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6304 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6305
6306 // return statistics
6307 theDI << "FPS: " << aFpsAver << "\n"
6308 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6309
8c820969 6310 // compute additional statistics in ray-tracing mode
e084dbbc 6311 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6312 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6313 {
e084dbbc 6314 Graphic3d_Vec2i aWinSize (0, 0);
6315 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6316
6317 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6318 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6319 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6320 }
6321
208e6839 6322 return 0;
6323}
6324
a577aaab 6325
f0430952 6326//==============================================================================
6327//function : VMemGpu
6328//purpose :
6329//==============================================================================
6330
6331static int VMemGpu (Draw_Interpretor& theDI,
6332 Standard_Integer theArgNb,
6333 const char** theArgVec)
6334{
6335 // get the context
6336 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6337 if (aContextAIS.IsNull())
6338 {
23fe70ec 6339 Message::SendFail ("Error: no active viewer");
f0430952 6340 return 1;
6341 }
6342
dc3fe572 6343 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 6344 if (aDriver.IsNull())
6345 {
23fe70ec 6346 Message::SendFail ("Error: graphic driver not available");
f0430952 6347 return 1;
6348 }
6349
6350 Standard_Size aFreeBytes = 0;
6351 TCollection_AsciiString anInfo;
6352 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
6353 {
23fe70ec 6354 Message::SendFail ("Error: information not available");
f0430952 6355 return 1;
6356 }
6357
6358 if (theArgNb > 1 && *theArgVec[1] == 'f')
6359 {
6360 theDI << Standard_Real (aFreeBytes);
6361 }
6362 else
6363 {
6364 theDI << anInfo;
6365 }
6366
6367 return 0;
6368}
6369
85e096c3 6370// ==============================================================================
6371// function : VReadPixel
6372// purpose :
6373// ==============================================================================
6374static int VReadPixel (Draw_Interpretor& theDI,
6375 Standard_Integer theArgNb,
6376 const char** theArgVec)
6377{
6378 // get the active view
6379 Handle(V3d_View) aView = ViewerTest::CurrentView();
6380 if (aView.IsNull())
6381 {
23fe70ec 6382 Message::SendFail ("Error: no active viewer");
85e096c3 6383 return 1;
6384 }
6385 else if (theArgNb < 3)
6386 {
23fe70ec 6387 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
6388 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
85e096c3 6389 return 1;
6390 }
6391
dc858f4c 6392 Image_Format aFormat = Image_Format_RGBA;
6393 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 6394
85e096c3 6395 Standard_Integer aWidth, aHeight;
6396 aView->Window()->Size (aWidth, aHeight);
91322f44 6397 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
6398 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 6399 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
6400 {
23fe70ec 6401 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
85e096c3 6402 return 1;
6403 }
6404
ba00aab7 6405 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
85e096c3 6406 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
6407 {
dc858f4c 6408 TCollection_AsciiString aParam (theArgVec[anIter]);
6409 aParam.LowerCase();
55c8f0f7 6410 if (aParam == "-rgb"
ba00aab7 6411 || aParam == "rgb"
6412 || aParam == "-srgb"
6413 || aParam == "srgb")
85e096c3 6414 {
dc858f4c 6415 aFormat = Image_Format_RGB;
692613e5 6416 aBufferType = Graphic3d_BT_RGB;
ba00aab7 6417 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
85e096c3 6418 }
55c8f0f7
BB
6419 else if (aParam == "-hls"
6420 || aParam == "hls")
85e096c3 6421 {
dc858f4c 6422 aFormat = Image_Format_RGB;
692613e5 6423 aBufferType = Graphic3d_BT_RGB;
85e096c3 6424 toShowHls = Standard_True;
6425 }
55c8f0f7
BB
6426 else if (aParam == "-rgbf"
6427 || aParam == "rgbf")
85e096c3 6428 {
dc858f4c 6429 aFormat = Image_Format_RGBF;
692613e5 6430 aBufferType = Graphic3d_BT_RGB;
85e096c3 6431 }
55c8f0f7 6432 else if (aParam == "-rgba"
ba00aab7 6433 || aParam == "rgba"
6434 || aParam == "-srgba"
6435 || aParam == "srgba")
85e096c3 6436 {
dc858f4c 6437 aFormat = Image_Format_RGBA;
692613e5 6438 aBufferType = Graphic3d_BT_RGBA;
ba00aab7 6439 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
85e096c3 6440 }
55c8f0f7
BB
6441 else if (aParam == "-rgbaf"
6442 || aParam == "rgbaf")
85e096c3 6443 {
dc858f4c 6444 aFormat = Image_Format_RGBAF;
692613e5 6445 aBufferType = Graphic3d_BT_RGBA;
85e096c3 6446 }
55c8f0f7
BB
6447 else if (aParam == "-depth"
6448 || aParam == "depth")
85e096c3 6449 {
dc858f4c 6450 aFormat = Image_Format_GrayF;
692613e5 6451 aBufferType = Graphic3d_BT_Depth;
85e096c3 6452 }
55c8f0f7
BB
6453 else if (aParam == "-name"
6454 || aParam == "name")
85e096c3 6455 {
6456 toShowName = Standard_True;
6457 }
9196ea9d 6458 else if (aParam == "-hex"
6459 || aParam == "hex")
6460 {
6461 toShowHex = Standard_True;
6462 }
55c8f0f7
BB
6463 else
6464 {
23fe70ec 6465 Message::SendFail() << "Syntax error at '" << aParam << "'";
9196ea9d 6466 return 1;
55c8f0f7 6467 }
85e096c3 6468 }
6469
692613e5 6470 Image_PixMap anImage;
6471 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
6472 {
23fe70ec 6473 Message::SendFail ("Error: image allocation failed");
692613e5 6474 return 1;
6475 }
6476 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 6477 {
23fe70ec 6478 Message::SendFail ("Error: image dump failed");
85e096c3 6479 return 1;
6480 }
6481
68beaa3c 6482 // redirect possible warning messages that could have been added by ToPixMap
6483 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
6484 // contaminate result of the command
6485 Standard_CString aWarnLog = theDI.Result();
6486 if (aWarnLog != NULL && aWarnLog[0] != '\0')
6487 {
6488 std::cout << aWarnLog << std::endl;
6489 }
6490 theDI.Reset();
6491
ba00aab7 6492 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
85e096c3 6493 if (toShowName)
6494 {
692613e5 6495 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 6496 {
e958a649 6497 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 6498 }
6499 else
6500 {
e958a649 6501 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 6502 }
6503 }
9196ea9d 6504 else if (toShowHex)
6505 {
6506 if (aBufferType == Graphic3d_BT_RGBA)
6507 {
6508 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
6509 }
6510 else
6511 {
6512 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
6513 }
6514 }
85e096c3 6515 else
6516 {
6517 switch (aBufferType)
6518 {
6519 default:
692613e5 6520 case Graphic3d_BT_RGB:
85e096c3 6521 {
6522 if (toShowHls)
6523 {
e958a649 6524 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 6525 }
ba00aab7 6526 else if (toShow_sRGB)
6527 {
6528 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
6529 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
6530 }
85e096c3 6531 else
6532 {
e958a649 6533 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 6534 }
6535 break;
6536 }
692613e5 6537 case Graphic3d_BT_RGBA:
85e096c3 6538 {
ba00aab7 6539 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
6540 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
85e096c3 6541 break;
6542 }
692613e5 6543 case Graphic3d_BT_Depth:
85e096c3 6544 {
e958a649 6545 theDI << aColor.GetRGB().Red();
85e096c3 6546 break;
6547 }
6548 }
6549 }
6550
6551 return 0;
6552}
6553
fd3f6bd0 6554//! Auxiliary presentation for an image plane.
6555class ViewerTest_ImagePrs : public AIS_InteractiveObject
6556{
6557public:
6558 //! Main constructor.
6559 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
6560 const Standard_Real theWidth,
6561 const Standard_Real theHeight,
6562 const TCollection_AsciiString& theLabel)
6563 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
6564 {
6565 SetDisplayMode (0);
6566 SetHilightMode (1);
6567 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
6568 {
6569 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6570 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
6571 Graphic3d_MaterialAspect aMat;
6572 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
61168418 6573 aMat.SetAmbientColor (Quantity_NOC_BLACK);
6574 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
6575 aMat.SetSpecularColor (Quantity_NOC_BLACK);
6576 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
fd3f6bd0 6577 aFillAspect->SetFrontMaterial (aMat);
6578 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
6579 aFillAspect->SetTextureMapOn();
6580 }
6581 {
6582 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
6583 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
6584 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
6585 myDrawer->SetTextAspect (aTextAspect);
6586 }
6587 {
6588 const gp_Dir aNorm (0.0, 0.0, 1.0);
6589 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
6590 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
6591 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
6592 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
6593 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
6594 myTris->AddEdge (1);
6595 myTris->AddEdge (2);
6596 myTris->AddEdge (3);
6597 myTris->AddEdge (3);
6598 myTris->AddEdge (2);
6599 myTris->AddEdge (4);
6600
6601 myRect = new Graphic3d_ArrayOfPolylines (4);
6602 myRect->AddVertex (myTris->Vertice (1));
6603 myRect->AddVertex (myTris->Vertice (3));
6604 myRect->AddVertex (myTris->Vertice (4));
6605 myRect->AddVertex (myTris->Vertice (2));
6606 }
6607 }
6608
6609 //! Returns TRUE for accepted display modes.
6610 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
6611
6612 //! Compute presentation.
decbff0d 6613 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
6614 const Handle(Prs3d_Presentation)& thePrs,
6615 const Standard_Integer theMode) Standard_OVERRIDE
fd3f6bd0 6616 {
6617 switch (theMode)
6618 {
6619 case 0:
6620 {
6621 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6622 aGroup->AddPrimitiveArray (myTris);
6623 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6624 aGroup->AddPrimitiveArray (myRect);
6625 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6626 return;
6627 }
6628 case 1:
6629 {
6630 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6631 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6632 aGroup->AddPrimitiveArray (myRect);
6633 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6634 return;
6635 }
6636 }
6637 }
6638
6639 //! Compute selection.
6640 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6641 {
6642 if (theMode == 0)
6643 {
6644 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6645 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6646 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6647 theSel->Add (aSensitive);
6648 }
6649 }
6650
6651private:
6652 Handle(Graphic3d_ArrayOfTriangles) myTris;
6653 Handle(Graphic3d_ArrayOfPolylines) myRect;
6654 TCollection_AsciiString myLabel;
6655 Standard_Real myWidth;
6656 Standard_Real myHeight;
6657};
6658
692613e5 6659//==============================================================================
6660//function : VDiffImage
6661//purpose : The draw-command compares two images.
6662//==============================================================================
6663
6664static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6665{
fd3f6bd0 6666 if (theArgNb < 3)
692613e5 6667 {
23fe70ec 6668 Message::SendFail ("Syntax error: not enough arguments");
692613e5 6669 return 1;
6670 }
6671
fd3f6bd0 6672 Standard_Integer anArgIter = 1;
6673 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
6674 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
6675 TCollection_AsciiString aDiffImagePath;
6676 Standard_Real aTolColor = -1.0;
6677 Standard_Integer toBlackWhite = -1;
6678 Standard_Integer isBorderFilterOn = -1;
6679 Standard_Boolean isOldSyntax = Standard_False;
6680 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
6681 for (; anArgIter < theArgNb; ++anArgIter)
6682 {
6683 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6684 anArg.LowerCase();
6685 if (anArgIter + 1 < theArgNb
6686 && (anArg == "-toleranceofcolor"
6687 || anArg == "-tolerancecolor"
6688 || anArg == "-tolerance"
6689 || anArg == "-toler"))
6690 {
6691 aTolColor = Atof (theArgVec[++anArgIter]);
6692 if (aTolColor < 0.0 || aTolColor > 1.0)
6693 {
23fe70ec 6694 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 6695 return 1;
6696 }
6697 }
6698 else if (anArg == "-blackwhite")
6699 {
6700 Standard_Boolean toEnable = Standard_True;
6701 if (anArgIter + 1 < theArgNb
dae2a922 6702 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 6703 {
6704 ++anArgIter;
6705 }
6706 toBlackWhite = toEnable ? 1 : 0;
6707 }
6708 else if (anArg == "-borderfilter")
6709 {
6710 Standard_Boolean toEnable = Standard_True;
6711 if (anArgIter + 1 < theArgNb
dae2a922 6712 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 6713 {
6714 ++anArgIter;
6715 }
6716 isBorderFilterOn = toEnable ? 1 : 0;
6717 }
6718 else if (anArg == "-exitonclose")
6719 {
49582f9d 6720 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 6721 if (anArgIter + 1 < theArgNb
dae2a922 6722 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 6723 {
6724 ++anArgIter;
6725 }
6726 }
6727 else if (anArg == "-closeonescape"
6728 || anArg == "-closeonesc")
6729 {
49582f9d 6730 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 6731 if (anArgIter + 1 < theArgNb
dae2a922 6732 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 6733 {
6734 ++anArgIter;
6735 }
6736 }
6737 else if (anArgIter + 3 < theArgNb
6738 && anArg == "-display")
6739 {
6740 aViewName = theArgVec[++anArgIter];
6741 aPrsNameRef = theArgVec[++anArgIter];
6742 aPrsNameNew = theArgVec[++anArgIter];
6743 if (anArgIter + 1 < theArgNb
6744 && *theArgVec[anArgIter + 1] != '-')
6745 {
6746 aPrsNameDiff = theArgVec[++anArgIter];
6747 }
6748 }
6749 else if (aTolColor < 0.0
d45edf24 6750 && anArg.IsRealValue (Standard_True))
fd3f6bd0 6751 {
6752 isOldSyntax = Standard_True;
6753 aTolColor = anArg.RealValue();
6754 if (aTolColor < 0.0 || aTolColor > 1.0)
6755 {
23fe70ec 6756 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 6757 return 1;
6758 }
6759 }
6760 else if (isOldSyntax
6761 && toBlackWhite == -1
6762 && (anArg == "0" || anArg == "1"))
6763 {
6764 toBlackWhite = anArg == "1" ? 1 : 0;
6765 }
6766 else if (isOldSyntax
6767 && isBorderFilterOn == -1
6768 && (anArg == "0" || anArg == "1"))
6769 {
6770 isBorderFilterOn = anArg == "1" ? 1 : 0;
6771 }
6772 else if (aDiffImagePath.IsEmpty())
6773 {
6774 aDiffImagePath = theArgVec[anArgIter];
6775 }
6776 else
6777 {
23fe70ec 6778 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fd3f6bd0 6779 return 1;
6780 }
6781 }
692613e5 6782
fd3f6bd0 6783 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6784 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6785 if (!anImgRef->Load (anImgPathRef))
6786 {
23fe70ec 6787 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
fd3f6bd0 6788 return 1;
6789 }
6790 if (!anImgNew->Load (anImgPathNew))
6791 {
23fe70ec 6792 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
fd3f6bd0 6793 return 1;
6794 }
692613e5 6795
6796 // compare the images
6797 Image_Diff aComparer;
fd3f6bd0 6798 Standard_Integer aDiffColorsNb = -1;
6799 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 6800 {
fd3f6bd0 6801 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6802 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6803 aDiffColorsNb = aComparer.Compare();
6804 theDI << aDiffColorsNb << "\n";
692613e5 6805 }
6806
692613e5 6807 // save image of difference
fd3f6bd0 6808 Handle(Image_AlienPixMap) aDiff;
6809 if (aDiffColorsNb > 0
6810 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6811 {
6812 aDiff = new Image_AlienPixMap();
6813 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6814 {
23fe70ec 6815 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
fd3f6bd0 6816 return 1;
6817 }
6818 aComparer.SaveDiffImage (*aDiff);
6819 if (!aDiffImagePath.IsEmpty()
6820 && !aDiff->Save (aDiffImagePath))
6821 {
23fe70ec 6822 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
fd3f6bd0 6823 return 1;
6824 }
6825 }
6826
6827 if (aViewName.IsEmpty())
6828 {
6829 return 0;
6830 }
6831
6832 ViewerTest_Names aViewNames (aViewName);
6833 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6834 {
6835 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6836 theDI.Eval (aCommand.ToCString());
6837 }
6838
6839 Standard_Integer aPxLeft = 0;
6840 Standard_Integer aPxTop = 0;
6841 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
6842 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6843 ? int(anImgRef->SizeY() * 2)
6844 : int(anImgRef->SizeY());
6845 TCollection_AsciiString aDisplayName;
9e04ccdc 6846 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
6847 aViewName, aDisplayName);
fd3f6bd0 6848
6849 Standard_Real aRatio = anImgRef->Ratio();
6850 Standard_Real aSizeX = 1.0;
6851 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 6852 {
fd3f6bd0 6853 OSD_Path aPath (anImgPathRef);
6854 TCollection_AsciiString aLabelRef;
6855 if (!aPath.Name().IsEmpty())
6856 {
6857 aLabelRef = aPath.Name() + aPath.Extension();
6858 }
6859 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6860
6861 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6862 gp_Trsf aTrsfRef;
6863 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6864 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6865 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 6866 }
fd3f6bd0 6867 {
6868 OSD_Path aPath (anImgPathNew);
6869 TCollection_AsciiString aLabelNew;
6870 if (!aPath.Name().IsEmpty())
6871 {
6872 aLabelNew = aPath.Name() + aPath.Extension();
6873 }
6874 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 6875
fd3f6bd0 6876 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6877 gp_Trsf aTrsfRef;
6878 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6879 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6880 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6881 }
6882 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6883 if (!aDiff.IsNull())
6884 {
6885 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6886 gp_Trsf aTrsfDiff;
6887 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6888 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6889 }
6890 if (!aPrsNameDiff.IsEmpty())
6891 {
6892 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6893 }
6894 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6895 ViewerTest::CurrentView()->FitAll();
692613e5 6896 return 0;
6897}
6898
4754e164 6899//=======================================================================
6900//function : VSelect
6901//purpose : Emulates different types of selection by mouse:
6902// 1) single click selection
6903// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6904// 3) selection with polygon having corners at
dc3fe572 6905// pixel positions (x1,y1),...,(xn,yn)
4754e164 6906// 4) any of these selections with shift button pressed
6907//=======================================================================
49582f9d 6908static Standard_Integer VSelect (Draw_Interpretor& ,
6909 Standard_Integer theNbArgs,
6910 const char** theArgVec)
4754e164 6911{
49582f9d 6912 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6913 if (aCtx.IsNull())
4754e164 6914 {
23fe70ec 6915 Message::SendFail ("Error: no active viewer");
4754e164 6916 return 1;
6917 }
2157d6ac 6918
49582f9d 6919 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
75cf8250 6920 bool toAllowOverlap = false;
6921 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
49582f9d 6922 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2157d6ac 6923 {
49582f9d 6924 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6925 anArg.LowerCase();
6926 if (anArg == "-allowoverlap")
6927 {
6928 toAllowOverlap = true;
6929 if (anArgIter + 1 < theNbArgs
dae2a922 6930 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
49582f9d 6931 {
6932 ++anArgIter;
6933 }
6934 }
e3d4b879 6935 else if (anArg == "-replace")
6936 {
6937 aSelScheme = AIS_SelectionScheme_Replace;
6938 }
e76471b5 6939 else if (anArg == "-replaceextra")
6940 {
6941 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6942 }
e3d4b879 6943 else if (anArg == "-xor"
6944 || anArg == "-shift")
6945 {
6946 aSelScheme = AIS_SelectionScheme_XOR;
6947 }
6948 else if (anArg == "-add")
6949 {
6950 aSelScheme = AIS_SelectionScheme_Add;
6951 }
6952 else if (anArg == "-remove")
6953 {
6954 aSelScheme = AIS_SelectionScheme_Remove;
6955 }
49582f9d 6956 else if (anArgIter + 1 < theNbArgs
6957 && anArg.IsIntegerValue()
6958 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
2157d6ac 6959 {
49582f9d 6960 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6961 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6962 }
6963 else if (anArgIter + 1 == theNbArgs
6964 && anArg.IsIntegerValue())
6965 {
75cf8250 6966 if (anArg.IntegerValue() == 1)
6967 {
6968 aSelScheme = AIS_SelectionScheme_XOR;
6969 }
49582f9d 6970 }
6971 else
6972 {
23fe70ec 6973 Message::SendFail() << "Syntax error at '" << anArg << "'";
2157d6ac 6974 return 1;
6975 }
49582f9d 6976 }
a24a7821 6977
49582f9d 6978 if (toAllowOverlap)
6979 {
6980 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
2157d6ac 6981 }
6982
4754e164 6983 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
49582f9d 6984 if (aPnts.IsEmpty())
4754e164 6985 {
75cf8250 6986 aCtx->SelectDetected (aSelScheme);
49582f9d 6987 aCtx->CurrentViewer()->Invalidate();
4754e164 6988 }
49582f9d 6989 else if (aPnts.Length() == 2)
4754e164 6990 {
49582f9d 6991 if (toAllowOverlap
6992 && aPnts.First().y() < aPnts.Last().y())
6993 {
6994 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6995 }
6996 else if (!toAllowOverlap
6997 && aPnts.First().y() > aPnts.Last().y())
6998 {
6999 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7000 }
e3d4b879 7001
7002 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7003 }
7004 else
7005 {
e3d4b879 7006 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7007 }
49582f9d 7008 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
4754e164 7009 return 0;
7010}
7011
7012//=======================================================================
7013//function : VMoveTo
dc3fe572 7014//purpose : Emulates cursor movement to defined pixel position
4754e164 7015//=======================================================================
1e756cb9 7016static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7017 Standard_Integer theNbArgs,
7018 const char** theArgVec)
4754e164 7019{
8a590580 7020 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7021 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7022 if (aContext.IsNull())
4754e164 7023 {
23fe70ec 7024 Message::SendFail ("Error: no active viewer");
4754e164 7025 return 1;
7026 }
7027
8a590580 7028 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7029 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7030 {
8a590580 7031 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7032 anArgStr.LowerCase();
7033 if (anArgStr == "-reset"
7034 || anArgStr == "-clear")
7035 {
7036 if (anArgIter + 1 < theNbArgs)
7037 {
23fe70ec 7038 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
8a590580 7039 return 1;
7040 }
7041
5634c81a 7042 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
8a590580 7043 && aContext->CurrentViewer()->GridEcho();
7044 if (toEchoGrid)
7045 {
7046 aContext->CurrentViewer()->HideGridEcho (aView);
7047 }
7048 if (aContext->ClearDetected() || toEchoGrid)
7049 {
7050 aContext->CurrentViewer()->RedrawImmediate();
7051 }
7052 return 0;
7053 }
7054 else if (aMousePos.x() == IntegerLast()
7055 && anArgStr.IsIntegerValue())
7056 {
7057 aMousePos.x() = anArgStr.IntegerValue();
7058 }
7059 else if (aMousePos.y() == IntegerLast()
7060 && anArgStr.IsIntegerValue())
7061 {
7062 aMousePos.y() = anArgStr.IntegerValue();
7063 }
7064 else
7065 {
23fe70ec 7066 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8a590580 7067 return 1;
7068 }
7069 }
7070
7071 if (aMousePos.x() == IntegerLast()
7072 || aMousePos.y() == IntegerLast())
7073 {
23fe70ec 7074 Message::SendFail ("Syntax error: wrong number of arguments");
4754e164 7075 return 1;
7076 }
8a590580 7077
49582f9d 7078 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7079 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7080 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7081
1e756cb9 7082 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7083 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7084 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7085 {
7086 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7087 {
7088 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7089 break;
7090 }
7091 }
7092 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7093 return 0;
7094}
7095
0461e7fd 7096//=======================================================================
7097//function : VSelectByAxis
7098//purpose :
7099//=======================================================================
7100static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
7101 Standard_Integer theNbArgs,
7102 const char** theArgVec)
7103{
7104 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7105 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7106 if (aContext.IsNull())
7107 {
7108 Message::SendFail ("Error: no active viewer");
7109 return 1;
7110 }
7111
7112 TCollection_AsciiString aName;
7113 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
7114 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
7115 Standard_Boolean isOnlyTop = true;
7116 Standard_Boolean toShowNormal = false;
7117 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
7118 {
7119 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7120 anArgStr.LowerCase();
7121 if (anArgStr == "-display")
7122 {
7123 if (anArgIter + 1 >= theNbArgs)
7124 {
7125 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
7126 return 1;
7127 }
7128 aName = theArgVec[++anArgIter];
7129 }
7130 else if (anArgStr == "-onlytop")
7131 {
7132 isOnlyTop = true;
7133 if (anArgIter + 1 < theNbArgs
7134 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
7135 {
7136 ++anArgIter;
7137 }
7138 }
7139 else if (anArgStr == "-shownormal")
7140 {
7141 toShowNormal = true;
7142 if (anArgIter + 1 < theNbArgs
7143 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
7144 {
7145 ++anArgIter;
7146 }
7147 }
7148 else if (Precision::IsInfinite(anAxisLocation.X())
7149 && anArgStr.IsRealValue())
7150 {
7151 anAxisLocation.SetX (anArgStr.RealValue());
7152 }
7153 else if (Precision::IsInfinite(anAxisLocation.Y())
7154 && anArgStr.IsRealValue())
7155 {
7156 anAxisLocation.SetY (anArgStr.RealValue());
7157 }
7158 else if (Precision::IsInfinite(anAxisLocation.Z())
7159 && anArgStr.IsRealValue())
7160 {
7161 anAxisLocation.SetZ (anArgStr.RealValue());
7162 }
7163 else if (Precision::IsInfinite(anAxisDirection.X())
7164 && anArgStr.IsRealValue())
7165 {
7166 anAxisDirection.SetX (anArgStr.RealValue());
7167 }
7168 else if (Precision::IsInfinite(anAxisDirection.Y())
7169 && anArgStr.IsRealValue())
7170 {
7171 anAxisDirection.SetY (anArgStr.RealValue());
7172 }
7173 else if (Precision::IsInfinite(anAxisDirection.Z())
7174 && anArgStr.IsRealValue())
7175 {
7176 anAxisDirection.SetZ (anArgStr.RealValue());
7177 }
7178 else
7179 {
7180 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
7181 return 1;
7182 }
7183 }
7184
7185 if (Precision::IsInfinite (anAxisLocation.X()) ||
7186 Precision::IsInfinite (anAxisLocation.Y()) ||
7187 Precision::IsInfinite (anAxisLocation.Z()) ||
7188 Precision::IsInfinite (anAxisDirection.X()) ||
7189 Precision::IsInfinite (anAxisDirection.Y()) ||
7190 Precision::IsInfinite (anAxisDirection.Z()))
7191 {
7192 Message::SendFail() << "Invalid axis location and direction";
7193 return 1;
7194 }
7195
7196 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
7197 gp_Pnt aTopPnt;
7198 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
7199 {
7200 theDI << "There are no any intersections with this axis.";
7201 return 0;
7202 }
7203 NCollection_Sequence<gp_Pnt> aPoints;
7204 NCollection_Sequence<Graphic3d_Vec3> aNormals;
7205 NCollection_Sequence<Standard_Real> aNormalLengths;
7206 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
7207 {
7208 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
7209 aPoints.Append (aPickedData.Point);
7210 aNormals.Append (aPickedData.Normal);
7211 Standard_Real aNormalLength = 1.0;
7212 if (!aPickedData.Entity.IsNull())
7213 {
7214 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
7215 }
7216 aNormalLengths.Append (aNormalLength);
7217 }
7218 if (!aName.IsEmpty())
7219 {
7220 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
7221 aContext->SetAutoActivateSelection (false);
7222
7223 // Display axis
7224 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
7225 Handle(Geom_Axis2Placement) anAx2Axis =
7226 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
7227 Handle(AIS_Axis) anAISAxis = new AIS_Axis (anAx2Axis, AIS_TOAX_ZAxis);
7228 const Handle(Prs3d_Drawer)& anAxisDrawer = anAISAxis->Attributes();
7229 anAxisDrawer->SetOwnDatumAspects();
7230 Standard_Real aLength = UnitsAPI::AnyToLS (250000., "mm");
7231 anAxisDrawer->DatumAspect()->SetAxisLength (aLength, aLength, aLength);
7232 anAxisDrawer->DatumAspect()->SetDrawLabels (false);
7233 anAxisDrawer->DatumAspect()->SetDrawArrows (true);
7234 anAISAxis->SetColor (Quantity_NOC_GREEN);
7235 anAISAxis->SetAxis2Placement (anAx2Axis, AIS_TOAX_ZAxis); // This is workaround to update axis length
7236 ViewerTest::Display (TCollection_AsciiString(aName) + "_axis", anAISAxis, false);
7237
7238 // Display axis start point
7239 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
7240 anAISStartPnt->SetMarker (Aspect_TOM_O);
7241 anAISStartPnt->SetColor (anAxisColor);
7242 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
7243
7244 Standard_Integer anIndex = 0;
7245 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
7246 {
7247 const gp_Pnt& aPoint = aPntIter.Value();
7248
7249 // Display normals in intersection points
7250 if (toShowNormal)
7251 {
7252 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
7253 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
7254 if (aNormal.SquareModulus() > ShortRealEpsilon())
7255 {
7256 Handle(Geom_Axis2Placement) anAx2Normal =
7257 new Geom_Axis2Placement(gp_Ax2(aPoint, gp_Dir((Standard_Real )aNormal.x(), (Standard_Real )aNormal.y(), (Standard_Real )aNormal.z())));
7258 Handle(AIS_Axis) anAISNormal = new AIS_Axis (anAx2Normal, AIS_TOAX_ZAxis);
7259 const Handle(Prs3d_Drawer)& aNormalDrawer = anAISNormal->Attributes();
7260 aNormalDrawer->SetOwnDatumAspects();
7261 aNormalDrawer->DatumAspect()->SetAxisLength (aNormalLength, aNormalLength, aNormalLength);
7262 aNormalDrawer->DatumAspect()->SetDrawLabels (false);
7263 aNormalDrawer->DatumAspect()->SetDrawArrows (true);
7264 anAISNormal->SetColor (Quantity_NOC_BLUE);
7265 anAISNormal->SetAxis2Placement (anAx2Normal, AIS_TOAX_ZAxis); // This is workaround to update axis length
7266 anAISNormal->SetInfiniteState (false);
7267 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
7268 }
7269 }
7270
7271 // Display intersection points
7272 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
7273 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
7274 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
7275 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
7276 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
7277 }
7278
7279 aContext->SetAutoActivateSelection (wasAuto);
7280 }
7281
7282 Standard_Integer anIndex = 0;
7283 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
7284 {
7285 const gp_Pnt& aPnt = anIter.Value();
7286 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
7287 }
7288 return 0;
7289}
7290
1beb58d7 7291namespace
7292{
7293 //! Global map storing all animations registered in ViewerTest.
7294 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7295
7296 //! The animation calling the Draw Harness command.
7297 class ViewerTest_AnimationProc : public AIS_Animation
7298 {
7299 public:
7300
7301 //! Main constructor.
7302 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7303 Draw_Interpretor* theDI,
7304 const TCollection_AsciiString& theCommand)
7305 : AIS_Animation (theAnimationName),
7306 myDrawInter(theDI),
7307 myCommand (theCommand)
7308 {
7309 //
7310 }
7311
7312 protected:
7313
7314 //! Evaluate the command.
7315 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7316 {
7317 TCollection_AsciiString aCmd = myCommand;
7318 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7319 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7320 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7321 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7322 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7323 myDrawInter->Eval (aCmd.ToCString());
7324 }
7325
7326 //! Find the keyword in the command and replace it with value.
7327 //! @return the position of the keyword to pass value
7328 void replace (TCollection_AsciiString& theCmd,
7329 const TCollection_AsciiString& theKey,
7330 const TCollection_AsciiString& theVal)
7331 {
7332 TCollection_AsciiString aCmd (theCmd);
7333 aCmd.LowerCase();
7334 const Standard_Integer aPos = aCmd.Search (theKey);
7335 if (aPos == -1)
7336 {
7337 return;
7338 }
7339
7340 TCollection_AsciiString aPart1, aPart2;
7341 Standard_Integer aPart1To = aPos - 1;
7342 if (aPart1To >= 1
7343 && aPart1To <= theCmd.Length())
7344 {
7345 aPart1 = theCmd.SubString (1, aPart1To);
7346 }
7347
7348 Standard_Integer aPart2From = aPos + theKey.Length();
7349 if (aPart2From >= 1
7350 && aPart2From <= theCmd.Length())
7351 {
7352 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7353 }
7354
7355 theCmd = aPart1 + theVal + aPart2;
7356 }
7357
7358 protected:
7359
7360 Draw_Interpretor* myDrawInter;
7361 TCollection_AsciiString myCommand;
7362
7363 };
7364
7365 //! Replace the animation with the new one.
7366 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7367 Handle(AIS_Animation)& theAnimation,
7368 const Handle(AIS_Animation)& theAnimationNew)
7369 {
7370 theAnimationNew->CopyFrom (theAnimation);
7371 if (!theParentAnimation.IsNull())
7372 {
7373 theParentAnimation->Replace (theAnimation, theAnimationNew);
7374 }
7375 else
7376 {
7377 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7378 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7379 }
7380 theAnimation = theAnimationNew;
7381 }
7382
7383 //! Parse the point.
7384 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7385 {
7386 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
d45edf24 7387 if (!anXYZ[0].IsRealValue (Standard_True)
7388 || !anXYZ[1].IsRealValue (Standard_True)
7389 || !anXYZ[2].IsRealValue (Standard_True))
1beb58d7 7390 {
7391 return Standard_False;
7392 }
7393
7394 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7395 return Standard_True;
7396 }
7397
7398 //! Parse the quaternion.
7399 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7400 {
7401 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
d45edf24 7402 if (!anXYZW[0].IsRealValue (Standard_True)
7403 || !anXYZW[1].IsRealValue (Standard_True)
7404 || !anXYZW[2].IsRealValue (Standard_True)
7405 || !anXYZW[3].IsRealValue (Standard_True))
1beb58d7 7406 {
7407 return Standard_False;
7408 }
7409
7410 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7411 return Standard_True;
7412 }
7413
08f8a185 7414 //! Auxiliary class for flipping image upside-down.
7415 class ImageFlipper
7416 {
7417 public:
7418
7419 //! Empty constructor.
7420 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7421
7422 //! Perform flipping.
7423 Standard_Boolean FlipY (Image_PixMap& theImage)
7424 {
7425 if (theImage.IsEmpty()
7426 || theImage.SizeX() == 0
7427 || theImage.SizeY() == 0)
7428 {
7429 return Standard_False;
7430 }
7431
7432 const Standard_Size aRowSize = theImage.SizeRowBytes();
7433 if (myTmp.Size() < aRowSize
7434 && !myTmp.Allocate (aRowSize))
7435 {
7436 return Standard_False;
7437 }
7438
7439 // for odd height middle row should be left as is
7440 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7441 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7442 {
7443 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7444 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7445 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7446 memcpy (aTop, aBot, aRowSize);
7447 memcpy (aBot, myTmp.Data(), aRowSize);
7448 }
7449 return Standard_True;
7450 }
7451
7452 private:
7453 NCollection_Buffer myTmp;
7454 };
7455
1beb58d7 7456}
7457
197ac94e 7458//=================================================================================================
4754e164 7459//function : VViewParams
dc3fe572 7460//purpose : Gets or sets AIS View characteristics
197ac94e 7461//=================================================================================================
7462static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7463{
1beb58d7 7464 Handle(V3d_View) aView = ViewerTest::CurrentView();
7465 if (aView.IsNull())
4754e164 7466 {
23fe70ec 7467 Message::SendFail ("Error: no active viewer");
4754e164 7468 return 1;
7469 }
197ac94e 7470
1beb58d7 7471 Standard_Boolean toSetProj = Standard_False;
7472 Standard_Boolean toSetUp = Standard_False;
7473 Standard_Boolean toSetAt = Standard_False;
7474 Standard_Boolean toSetEye = Standard_False;
7475 Standard_Boolean toSetScale = Standard_False;
7476 Standard_Boolean toSetSize = Standard_False;
7477 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7478 Standard_Real aViewScale = aView->Scale();
168c27c6 7479 Standard_Real aViewAspect = aView->Camera()->Aspect();
ee2be2a8 7480 Standard_Real aViewSize = 1.0;
1beb58d7 7481 Graphic3d_Vec2i aCenter2d;
7482 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7483 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7484 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7485 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7486 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
168c27c6 7487 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
7488 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
197ac94e 7489 if (theArgsNb == 1)
4754e164 7490 {
197ac94e 7491 // print all of the available view parameters
1beb58d7 7492 char aText[4096];
7493 Sprintf (aText,
168c27c6 7494 "Scale: %g\n"
7495 "Aspect: %g\n"
7496 "Proj: %12g %12g %12g\n"
7497 "Up: %12g %12g %12g\n"
7498 "At: %12g %12g %12g\n"
7499 "Eye: %12g %12g %12g\n"
7500 "OrientMat: %12g %12g %12g %12g\n"
7501 " %12g %12g %12g %12g\n"
7502 " %12g %12g %12g %12g\n"
7503 " %12g %12g %12g %12g\n"
7504 "ProjMat: %12g %12g %12g %12g\n"
7505 " %12g %12g %12g %12g\n"
7506 " %12g %12g %12g %12g\n"
7507 " %12g %12g %12g %12g\n",
7508 aViewScale, aViewAspect,
1beb58d7 7509 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7510 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7511 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
168c27c6 7512 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
7513 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
7514 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
7515 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
7516 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
7517 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
7518 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
7519 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
7520 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
1beb58d7 7521 theDi << aText;
197ac94e 7522 return 0;
4754e164 7523 }
197ac94e 7524
1beb58d7 7525 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7526 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7527 {
1beb58d7 7528 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7529 anArg.LowerCase();
7530 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7531 {
197ac94e 7532 continue;
7533 }
1beb58d7 7534 else if (anArg == "-cmd"
7535 || anArg == "-command"
7536 || anArg == "-args")
7537 {
7538 char aText[4096];
7539 Sprintf (aText,
7540 "-scale %g "
7541 "-proj %g %g %g "
7542 "-up %g %g %g "
7543 "-at %g %g %g\n",
7544 aViewScale,
7545 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7546 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7547 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7548 theDi << aText;
7549 }
7550 else if (anArg == "-scale"
7551 || anArg == "-size")
7552 {
7553 if (anArgIter + 1 < theArgsNb
7554 && *theArgVec[anArgIter + 1] != '-')
7555 {
7556 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
d45edf24 7557 if (aValueArg.IsRealValue (Standard_True))
1beb58d7 7558 {
7559 ++anArgIter;
7560 if (anArg == "-scale")
7561 {
7562 toSetScale = Standard_True;
7563 aViewScale = aValueArg.RealValue();
7564 }
7565 else if (anArg == "-size")
7566 {
7567 toSetSize = Standard_True;
7568 aViewSize = aValueArg.RealValue();
7569 }
7570 continue;
7571 }
7572 }
7573 if (anArg == "-scale")
7574 {
7575 theDi << "Scale: " << aView->Scale() << "\n";
7576 }
7577 else if (anArg == "-size")
7578 {
7579 Graphic3d_Vec2d aSizeXY;
7580 aView->Size (aSizeXY.x(), aSizeXY.y());
7581 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7582 }
7583 }
7584 else if (anArg == "-eye"
7585 || anArg == "-at"
7586 || anArg == "-up"
7587 || anArg == "-proj")
7588 {
7589 if (anArgIter + 3 < theArgsNb)
7590 {
7591 gp_XYZ anXYZ;
7592 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7593 {
7594 anArgIter += 3;
7595 if (anArg == "-eye")
7596 {
7597 toSetEye = Standard_True;
7598 aViewEye = anXYZ;
7599 }
7600 else if (anArg == "-at")
7601 {
7602 toSetAt = Standard_True;
7603 aViewAt = anXYZ;
7604 }
7605 else if (anArg == "-up")
7606 {
7607 toSetUp = Standard_True;
7608 aViewUp = anXYZ;
7609 }
7610 else if (anArg == "-proj")
7611 {
7612 toSetProj = Standard_True;
7613 aViewProj = anXYZ;
7614 }
7615 continue;
7616 }
7617 }
197ac94e 7618
1beb58d7 7619 if (anArg == "-eye")
7620 {
7621 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7622 }
7623 else if (anArg == "-at")
7624 {
7625 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7626 }
7627 else if (anArg == "-up")
7628 {
7629 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7630 }
7631 else if (anArg == "-proj")
7632 {
7633 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7634 }
7635 }
7636 else if (anArg == "-center")
3dfe95cd 7637 {
1beb58d7 7638 if (anArgIter + 2 < theArgsNb)
7639 {
7640 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7641 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7642 if (anX.IsIntegerValue()
7643 && anY.IsIntegerValue())
7644 {
7645 toSetCenter2d = Standard_True;
7646 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7647 }
7648 }
7649 }
7650 else
7651 {
23fe70ec 7652 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 7653 return 1;
7654 }
1beb58d7 7655 }
3dfe95cd 7656
1beb58d7 7657 // change view parameters in proper order
7658 if (toSetScale)
7659 {
7660 aView->SetScale (aViewScale);
7661 }
7662 if (toSetSize)
7663 {
7664 aView->SetSize (aViewSize);
7665 }
7666 if (toSetEye)
7667 {
7668 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7669 }
7670 if (toSetAt)
7671 {
7672 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7673 }
7674 if (toSetProj)
7675 {
7676 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7677 }
7678 if (toSetUp)
7679 {
7680 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7681 }
7682 if (toSetCenter2d)
7683 {
7684 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 7685 }
7686
1beb58d7 7687 return 0;
7688}
197ac94e 7689
2e93433e 7690//==============================================================================
7691//function : V2DMode
7692//purpose :
7693//==============================================================================
7694static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7695{
7696 bool is2dMode = true;
7697 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7698 if (aV3dView.IsNull())
7699 {
23fe70ec 7700 Message::SendFail ("Error: no active viewer");
2e93433e 7701 return 1;
7702 }
7703 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7704 {
7705 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7706 TCollection_AsciiString anArgCase = anArg;
7707 anArgCase.LowerCase();
7708 if (anArgIt + 1 < theArgsNb
7709 && anArgCase == "-name")
7710 {
7711 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7712 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7713 if (!ViewerTest_myViews.IsBound1 (aViewName))
7714 {
23fe70ec 7715 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 7716 return 1;
7717 }
7718 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7719 }
7720 else if (anArgCase == "-mode")
7721 {
7722 if (anArgIt + 1 < theArgsNb
dae2a922 7723 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 7724 {
7725 ++anArgIt;
7726 }
7727 }
dae2a922 7728 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 7729 {
7730 //
7731 }
7732 else
7733 {
23fe70ec 7734 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 7735 return 1;
7736 }
7737 }
7738
7739 aV3dView->SetView2DMode (is2dMode);
7740 return 0;
7741}
7742
1beb58d7 7743//==============================================================================
7744//function : VAnimation
7745//purpose :
7746//==============================================================================
7747static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7748 Standard_Integer theArgNb,
7749 const char** theArgVec)
7750{
7751 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7752 if (theArgNb < 2)
4754e164 7753 {
1beb58d7 7754 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7755 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7756 {
7757 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7758 }
1beb58d7 7759 return 0;
7760 }
7761 if (aCtx.IsNull())
7762 {
23fe70ec 7763 Message::SendFail ("Error: no active viewer");
1beb58d7 7764 return 1;
4754e164 7765 }
197ac94e 7766
1beb58d7 7767 Standard_Integer anArgIter = 1;
7768 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7769 if (aNameArg.IsEmpty())
7770 {
23fe70ec 7771 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7772 return 1;
7773 }
7774
7775 TCollection_AsciiString aNameArgLower = aNameArg;
7776 aNameArgLower.LowerCase();
7777 if (aNameArgLower == "-reset"
7778 || aNameArgLower == "-clear")
7779 {
7780 ViewerTest_AnimationTimelineMap.Clear();
7781 return 0;
7782 }
7783 else if (aNameArg.Value (1) == '-')
7784 {
23fe70ec 7785 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 7786 return 1;
7787 }
197ac94e 7788
1beb58d7 7789 const char* aNameSplitter = "/";
7790 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7791 if (aSplitPos == -1)
197ac94e 7792 {
1beb58d7 7793 aNameSplitter = ".";
7794 aSplitPos = aNameArg.Search (aNameSplitter);
7795 }
7796
7797 // find existing or create a new animation by specified name within syntax "parent.child".
7798 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7799 for (; !aNameArg.IsEmpty();)
7800 {
7801 TCollection_AsciiString aNameParent;
7802 if (aSplitPos != -1)
197ac94e 7803 {
1beb58d7 7804 if (aSplitPos == aNameArg.Length())
7805 {
23fe70ec 7806 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 7807 return 1;
7808 }
7809
7810 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7811 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7812
7813 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 7814 }
7815 else
7816 {
1beb58d7 7817 aNameParent = aNameArg;
7818 aNameArg.Clear();
197ac94e 7819 }
1beb58d7 7820
7821 if (anAnimation.IsNull())
3dfe95cd 7822 {
1beb58d7 7823 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7824 {
7825 anAnimation = new AIS_Animation (aNameParent);
7826 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7827 }
7828 aRootAnimation = anAnimation;
3dfe95cd 7829 }
7830 else
7831 {
1beb58d7 7832 aParentAnimation = anAnimation;
7833 anAnimation = aParentAnimation->Find (aNameParent);
7834 if (anAnimation.IsNull())
7835 {
7836 anAnimation = new AIS_Animation (aNameParent);
7837 aParentAnimation->Add (anAnimation);
7838 }
3dfe95cd 7839 }
7840 }
1beb58d7 7841
7842 if (anArgIter >= theArgNb)
197ac94e 7843 {
1beb58d7 7844 // just print the list of children
7845 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 7846 {
1beb58d7 7847 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 7848 }
1beb58d7 7849 return 0;
197ac94e 7850 }
1beb58d7 7851
bf7b2ceb 7852 // animation parameters
1beb58d7 7853 Standard_Boolean toPlay = Standard_False;
7854 Standard_Real aPlaySpeed = 1.0;
7855 Standard_Real aPlayStartTime = anAnimation->StartPts();
7856 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 7857 Standard_Boolean isFreeCamera = Standard_False;
7858 Standard_Boolean isLockLoop = Standard_False;
08f8a185 7859
7860 // video recording parameters
7861 TCollection_AsciiString aRecFile;
7862 Image_VideoParams aRecParams;
7863
1beb58d7 7864 Handle(V3d_View) aView = ViewerTest::CurrentView();
7865 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 7866 {
1beb58d7 7867 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7868 anArg.LowerCase();
bf7b2ceb 7869 // general options
1beb58d7 7870 if (anArg == "-reset"
7871 || anArg == "-clear")
197ac94e 7872 {
1beb58d7 7873 anAnimation->Clear();
7874 }
7875 else if (anArg == "-remove"
7876 || anArg == "-del"
7877 || anArg == "-delete")
7878 {
7879 if (!aParentAnimation.IsNull())
7880 {
7881 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7882 }
7883 else
7884 {
7885 aParentAnimation->Remove (anAnimation);
7886 }
7887 }
bf7b2ceb 7888 // playback options
1beb58d7 7889 else if (anArg == "-play")
7890 {
7891 toPlay = Standard_True;
7892 if (++anArgIter < theArgNb)
7893 {
7894 if (*theArgVec[anArgIter] == '-')
7895 {
7896 --anArgIter;
7897 continue;
7898 }
7899 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7900
7901 if (++anArgIter < theArgNb)
7902 {
7903 if (*theArgVec[anArgIter] == '-')
7904 {
7905 --anArgIter;
7906 continue;
7907 }
7908 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7909 }
7910 }
7911 }
7912 else if (anArg == "-resume")
7913 {
7914 toPlay = Standard_True;
7915 aPlayStartTime = anAnimation->ElapsedTime();
7916 if (++anArgIter < theArgNb)
7917 {
7918 if (*theArgVec[anArgIter] == '-')
7919 {
7920 --anArgIter;
7921 continue;
7922 }
7923
7924 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7925 }
7926 }
7927 else if (anArg == "-playspeed"
7928 || anArg == "-speed")
7929 {
7930 if (++anArgIter >= theArgNb)
7931 {
23fe70ec 7932 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 7933 return 1;
7934 }
7935 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7936 }
7937 else if (anArg == "-lock"
7938 || anArg == "-lockloop"
7939 || anArg == "-playlockloop")
7940 {
7941 isLockLoop = Standard_True;
7942 }
7943 else if (anArg == "-freecamera"
7944 || anArg == "-playfreecamera"
7945 || anArg == "-freelook")
7946 {
7947 isFreeCamera = Standard_True;
7948 }
08f8a185 7949 // video recodring options
7950 else if (anArg == "-rec"
7951 || anArg == "-record")
7952 {
7953 if (++anArgIter >= theArgNb)
7954 {
23fe70ec 7955 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 7956 return 1;
7957 }
7958
7959 aRecFile = theArgVec[anArgIter];
7960 if (aRecParams.FpsNum <= 0)
7961 {
7962 aRecParams.FpsNum = 24;
7963 }
7964
7965 if (anArgIter + 2 < theArgNb
7966 && *theArgVec[anArgIter + 1] != '-'
7967 && *theArgVec[anArgIter + 2] != '-')
7968 {
7969 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7970 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7971 if (aWidthArg .IsIntegerValue()
7972 && aHeightArg.IsIntegerValue())
7973 {
7974 aRecParams.Width = aWidthArg .IntegerValue();
7975 aRecParams.Height = aHeightArg.IntegerValue();
7976 anArgIter += 2;
7977 }
7978 }
7979 }
1beb58d7 7980 else if (anArg == "-fps")
7981 {
7982 if (++anArgIter >= theArgNb)
7983 {
23fe70ec 7984 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 7985 return 1;
7986 }
bf7b2ceb 7987
7988 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7989 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7990 if (aSplitIndex == 0)
7991 {
08f8a185 7992 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 7993 }
7994 else
7995 {
7996 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7997 aFpsArg.Split (aFpsArg.Length() - 1);
7998 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 7999 aRecParams.FpsNum = aNumStr.IntegerValue();
8000 aRecParams.FpsDen = aDenStr.IntegerValue();
8001 if (aRecParams.FpsDen < 1)
bf7b2ceb 8002 {
23fe70ec 8003 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 8004 return 1;
8005 }
8006 }
1beb58d7 8007 }
08f8a185 8008 else if (anArg == "-format")
8009 {
8010 if (++anArgIter >= theArgNb)
8011 {
23fe70ec 8012 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8013 return 1;
8014 }
8015 aRecParams.Format = theArgVec[anArgIter];
8016 }
8017 else if (anArg == "-pix_fmt"
8018 || anArg == "-pixfmt"
8019 || anArg == "-pixelformat")
8020 {
8021 if (++anArgIter >= theArgNb)
8022 {
23fe70ec 8023 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8024 return 1;
8025 }
8026 aRecParams.PixelFormat = theArgVec[anArgIter];
8027 }
8028 else if (anArg == "-codec"
8029 || anArg == "-vcodec"
8030 || anArg == "-videocodec")
8031 {
8032 if (++anArgIter >= theArgNb)
8033 {
23fe70ec 8034 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8035 return 1;
8036 }
8037 aRecParams.VideoCodec = theArgVec[anArgIter];
8038 }
8039 else if (anArg == "-crf"
8040 || anArg == "-preset"
8041 || anArg == "-qp")
8042 {
8043 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8044 if (++anArgIter >= theArgNb)
8045 {
23fe70ec 8046 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8047 return 1;
8048 }
8049
8050 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8051 }
bf7b2ceb 8052 // animation definition options
1beb58d7 8053 else if (anArg == "-start"
8054 || anArg == "-starttime"
8055 || anArg == "-startpts")
8056 {
8057 if (++anArgIter >= theArgNb)
8058 {
23fe70ec 8059 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8060 return 1;
8061 }
8062
8063 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8064 aRootAnimation->UpdateTotalDuration();
8065 }
8066 else if (anArg == "-end"
8067 || anArg == "-endtime"
8068 || anArg == "-endpts")
8069 {
8070 if (++anArgIter >= theArgNb)
8071 {
23fe70ec 8072 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8073 return 1;
8074 }
8075
8076 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8077 aRootAnimation->UpdateTotalDuration();
8078 }
8079 else if (anArg == "-dur"
8080 || anArg == "-duration")
8081 {
8082 if (++anArgIter >= theArgNb)
8083 {
23fe70ec 8084 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8085 return 1;
8086 }
8087
8088 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8089 aRootAnimation->UpdateTotalDuration();
8090 }
8091 else if (anArg == "-command"
8092 || anArg == "-cmd"
8093 || anArg == "-invoke"
8094 || anArg == "-eval"
8095 || anArg == "-proc")
8096 {
8097 if (++anArgIter >= theArgNb)
8098 {
23fe70ec 8099 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8100 return 1;
8101 }
8102
8103 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8104 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8105 }
8106 else if (anArg == "-objecttrsf"
8107 || anArg == "-objectransformation"
8108 || anArg == "-objtransformation"
8109 || anArg == "-objtrsf"
8110 || anArg == "-object"
8111 || anArg == "-obj")
8112 {
8113 if (++anArgIter >= theArgNb)
8114 {
23fe70ec 8115 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8116 return 1;
8117 }
8118
8119 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8120 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8121 Handle(AIS_InteractiveObject) anObject;
8122 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8123 {
23fe70ec 8124 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8125 return 1;
8126 }
8127
1beb58d7 8128 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8129 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8130 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8131 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8132 Standard_Boolean isTrsfSet = Standard_False;
8133 Standard_Integer aTrsfArgIter = anArgIter + 1;
8134 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8135 {
8136 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8137 aTrsfArg.LowerCase();
8138 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8139 if (aTrsfArg.StartsWith ("-rotation")
8140 || aTrsfArg.StartsWith ("-rot"))
8141 {
8142 isTrsfSet = Standard_True;
8143 if (aTrsfArgIter + 4 >= theArgNb
8144 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8145 {
23fe70ec 8146 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8147 return 1;
8148 }
8149 aTrsfArgIter += 4;
8150 }
8151 else if (aTrsfArg.StartsWith ("-location")
8152 || aTrsfArg.StartsWith ("-loc"))
8153 {
8154 isTrsfSet = Standard_True;
8155 if (aTrsfArgIter + 3 >= theArgNb
8156 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8157 {
23fe70ec 8158 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8159 return 1;
8160 }
8161 aTrsfArgIter += 3;
8162 }
8163 else if (aTrsfArg.StartsWith ("-scale"))
8164 {
8165 isTrsfSet = Standard_True;
8166 if (++aTrsfArgIter >= theArgNb)
8167 {
23fe70ec 8168 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8169 return 1;
8170 }
8171
8172 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
d45edf24 8173 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8174 {
23fe70ec 8175 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8176 return 1;
8177 }
8178 aScales[anIndex] = aScaleStr.RealValue();
8179 }
8180 else
8181 {
8182 anArgIter = aTrsfArgIter - 1;
8183 break;
8184 }
8185 }
8186 if (!isTrsfSet)
8187 {
23fe70ec 8188 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8189 return 1;
8190 }
8191 else if (aTrsfArgIter >= theArgNb)
8192 {
8193 anArgIter = theArgNb;
8194 }
8195
8196 aTrsfs[0].SetRotation (aRotQuats[0]);
8197 aTrsfs[1].SetRotation (aRotQuats[1]);
8198 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8199 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8200 aTrsfs[0].SetScaleFactor (aScales[0]);
8201 aTrsfs[1].SetScaleFactor (aScales[1]);
8202
8203 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8204 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8205 }
8206 else if (anArg == "-viewtrsf"
8207 || anArg == "-view")
8208 {
8209 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8210 if (aCamAnimation.IsNull())
8211 {
8212 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8213 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8214 }
8215
8216 Handle(Graphic3d_Camera) aCams[2] =
8217 {
8218 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8219 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8220 };
8221
8222 Standard_Boolean isTrsfSet = Standard_False;
8223 Standard_Integer aViewArgIter = anArgIter + 1;
8224 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8225 {
8226 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8227 aViewArg.LowerCase();
8228 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8229 if (aViewArg.StartsWith ("-scale"))
8230 {
8231 isTrsfSet = Standard_True;
8232 if (++aViewArgIter >= theArgNb)
8233 {
23fe70ec 8234 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8235 return 1;
8236 }
8237
8238 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
d45edf24 8239 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8240 {
23fe70ec 8241 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8242 return 1;
8243 }
8244 Standard_Real aScale = aScaleStr.RealValue();
8245 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8246 aCams[anIndex]->SetScale (aScale);
8247 }
8248 else if (aViewArg.StartsWith ("-eye")
8249 || aViewArg.StartsWith ("-center")
8250 || aViewArg.StartsWith ("-at")
8251 || aViewArg.StartsWith ("-up"))
8252 {
8253 isTrsfSet = Standard_True;
8254 gp_XYZ anXYZ;
8255 if (aViewArgIter + 3 >= theArgNb
8256 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8257 {
23fe70ec 8258 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8259 return 1;
8260 }
8261 aViewArgIter += 3;
8262
8263 if (aViewArg.StartsWith ("-eye"))
8264 {
8265 aCams[anIndex]->SetEye (anXYZ);
8266 }
8267 else if (aViewArg.StartsWith ("-center")
8268 || aViewArg.StartsWith ("-at"))
8269 {
8270 aCams[anIndex]->SetCenter (anXYZ);
8271 }
8272 else if (aViewArg.StartsWith ("-up"))
8273 {
8274 aCams[anIndex]->SetUp (anXYZ);
8275 }
8276 }
8277 else
8278 {
8279 anArgIter = aViewArgIter - 1;
8280 break;
8281 }
8282 }
8283 if (!isTrsfSet)
8284 {
23fe70ec 8285 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8286 return 1;
8287 }
8288 else if (aViewArgIter >= theArgNb)
8289 {
8290 anArgIter = theArgNb;
8291 }
8292
8293 aCamAnimation->SetCameraStart(aCams[0]);
8294 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8295 }
8296 else
8297 {
23fe70ec 8298 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8299 return 1;
197ac94e 8300 }
8301 }
1beb58d7 8302
08f8a185 8303 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8304 {
1beb58d7 8305 return 0;
8306 }
8307
8308 // Start animation timeline and process frame updating.
8309 TheIsAnimating = Standard_True;
8310 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8311 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8312 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8313 if (isFreeCamera)
8314 {
8315 aView->Camera()->Copy (aCameraBack);
8316 }
8317
8318 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8319 if (aRecParams.FpsNum <= 0)
1beb58d7 8320 {
8321 while (!anAnimation->IsStopped())
197ac94e 8322 {
1beb58d7 8323 aCameraBack->Copy (aView->Camera());
8324 const Standard_Real aPts = anAnimation->UpdateTimer();
8325 if (isFreeCamera)
8326 {
8327 aView->Camera()->Copy (aCameraBack);
8328 }
8329
8330 if (aPts >= anUpperPts)
8331 {
8332 anAnimation->Pause();
8333 break;
8334 }
8335
8336 if (aView->IsInvalidated())
8337 {
8338 aView->Redraw();
8339 }
8340 else
8341 {
8342 aView->RedrawImmediate();
8343 }
8344
8345 if (!isLockLoop)
8346 {
8347 // handle user events
8348 theDI.Eval ("after 1 set waiter 1");
8349 theDI.Eval ("vwait waiter");
8350 }
8351 if (!TheIsAnimating)
8352 {
8353 anAnimation->Pause();
8354 theDI << aPts;
8355 break;
8356 }
8357 }
8358
8359 if (aView->IsInvalidated())
8360 {
8361 aView->Redraw();
197ac94e 8362 }
8363 else
8364 {
1beb58d7 8365 aView->RedrawImmediate();
197ac94e 8366 }
8367 }
1beb58d7 8368 else
197ac94e 8369 {
bf7b2ceb 8370 OSD_Timer aPerfTimer;
8371 aPerfTimer.Start();
1beb58d7 8372
08f8a185 8373 Handle(Image_VideoRecorder) aRecorder;
8374 ImageFlipper aFlipper;
8375 Handle(Draw_ProgressIndicator) aProgress;
8376 if (!aRecFile.IsEmpty())
8377 {
8378 if (aRecParams.Width <= 0
8379 || aRecParams.Height <= 0)
8380 {
8381 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8382 }
8383
8384 aRecorder = new Image_VideoRecorder();
8385 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8386 {
23fe70ec 8387 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8388 return 0;
8389 }
8390
8391 aProgress = new Draw_ProgressIndicator (theDI, 1);
8392 }
8393
1beb58d7 8394 // Manage frame-rated animation here
8395 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8396 int64_t aNbFrames = 0;
7e785937 8397 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8398 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8399 Standard_Integer aSecondsProgress = 0;
7e785937 8400 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8401 {
08f8a185 8402 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8403 aPts = aPlayStartTime + aRecPts;
8404 ++aNbFrames;
1beb58d7 8405 if (!anAnimation->Update (aPts))
8406 {
8407 break;
8408 }
8409
08f8a185 8410 if (!aRecorder.IsNull())
8411 {
8412 V3d_ImageDumpOptions aDumpParams;
8413 aDumpParams.Width = aRecParams.Width;
8414 aDumpParams.Height = aRecParams.Height;
8415 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8416 aDumpParams.StereoOptions = V3d_SDO_MONO;
8417 aDumpParams.ToAdjustAspect = Standard_True;
8418 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8419 {
23fe70ec 8420 Message::SendFail ("Error: view dump is failed");
08f8a185 8421 return 0;
8422 }
8423 aFlipper.FlipY (aRecorder->ChangeFrame());
8424 if (!aRecorder->PushFrame())
8425 {
8426 return 0;
8427 }
8428 }
8429 else
8430 {
8431 aView->Redraw();
8432 }
8433
8434 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8435 {
7e785937 8436 aPS.Next();
08f8a185 8437 ++aSecondsProgress;
8438 }
197ac94e 8439 }
bf7b2ceb 8440
8441 aPerfTimer.Stop();
1beb58d7 8442 anAnimation->Stop();
bf7b2ceb 8443 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8444 theDI << "Average FPS: " << aRecFps << "\n"
8445 << "Nb. Frames: " << Standard_Real(aNbFrames);
8446
8447 aView->Redraw();
197ac94e 8448 }
8449
1beb58d7 8450 aView->SetImmediateUpdate (wasImmediateUpdate);
8451 TheIsAnimating = Standard_False;
4754e164 8452 return 0;
8453}
8454
1beb58d7 8455
4754e164 8456//=======================================================================
8457//function : VChangeSelected
dc3fe572 8458//purpose : Adds the shape to selection or remove one from it
4754e164 8459//=======================================================================
8460static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8461 Standard_Integer argc,
8462 const char ** argv)
8463{
8464 if(argc != 2)
8465 {
8466 di<<"Usage : " << argv[0] << " shape \n";
8467 return 1;
8468 }
8469 //get AIS_Shape:
4754e164 8470 TCollection_AsciiString aName(argv[1]);
8471 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8472 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8473 || anAISObject.IsNull())
4754e164 8474 {
8475 di<<"Use 'vdisplay' before";
8476 return 1;
8477 }
4754e164 8478
8f521168 8479 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8480 return 0;
8481}
8482
4754e164 8483//=======================================================================
8484//function : VNbSelected
dc3fe572 8485//purpose : Returns number of selected objects
4754e164 8486//=======================================================================
8487static Standard_Integer VNbSelected (Draw_Interpretor& di,
8488 Standard_Integer argc,
8489 const char ** argv)
8490{
8491 if(argc != 1)
8492 {
8493 di << "Usage : " << argv[0] << "\n";
8494 return 1;
8495 }
8496 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8497 if(aContext.IsNull())
8498 {
8499 di << "use 'vinit' command before " << argv[0] << "\n";
8500 return 1;
8501 }
8502 di << aContext->NbSelected() << "\n";
8503 return 0;
8504}
8505
4754e164 8506//=======================================================================
8507//function : VSetViewSize
8508//purpose :
8509//=======================================================================
8510static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8511 Standard_Integer argc,
8512 const char ** argv)
8513{
8514 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8515 if(aContext.IsNull())
8516 {
8517 di << "use 'vinit' command before " << argv[0] << "\n";
8518 return 1;
8519 }
8520 if(argc != 2)
8521 {
8522 di<<"Usage : " << argv[0] << " Size\n";
8523 return 1;
8524 }
6b62b2da 8525 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8526 if (aSize <= 0.)
8527 {
8528 di<<"Bad Size value : " << aSize << "\n";
8529 return 1;
8530 }
8531
8532 Handle(V3d_View) aView = ViewerTest::CurrentView();
8533 aView->SetSize(aSize);
8534 return 0;
8535}
8536
8537//=======================================================================
8538//function : VMoveView
8539//purpose :
8540//=======================================================================
8541static Standard_Integer VMoveView (Draw_Interpretor& di,
8542 Standard_Integer argc,
8543 const char ** argv)
8544{
8545 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8546 if(aContext.IsNull())
8547 {
8548 di << "use 'vinit' command before " << argv[0] << "\n";
8549 return 1;
8550 }
8551 if(argc < 4 || argc > 5)
8552 {
8553 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8554 return 1;
8555 }
6b62b2da 8556 Standard_Real Dx = Draw::Atof (argv[1]);
8557 Standard_Real Dy = Draw::Atof (argv[2]);
8558 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8559 Standard_Boolean aStart = Standard_True;
8560 if (argc == 5)
8561 {
6b62b2da 8562 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8563 }
8564
8565 Handle(V3d_View) aView = ViewerTest::CurrentView();
8566 aView->Move(Dx,Dy,Dz,aStart);
8567 return 0;
8568}
8569
8570//=======================================================================
8571//function : VTranslateView
8572//purpose :
8573//=======================================================================
8574static Standard_Integer VTranslateView (Draw_Interpretor& di,
8575 Standard_Integer argc,
8576 const char ** argv)
8577{
8578 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8579 if(aContext.IsNull())
8580 {
8581 di << "use 'vinit' command before " << argv[0] << "\n";
8582 return 1;
8583 }
8584 if(argc < 4 || argc > 5)
8585 {
8586 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8587 return 1;
8588 }
6b62b2da 8589 Standard_Real Dx = Draw::Atof (argv[1]);
8590 Standard_Real Dy = Draw::Atof (argv[2]);
8591 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8592 Standard_Boolean aStart = Standard_True;
dc3fe572 8593 if (argc == 5)
4754e164 8594 {
6b62b2da 8595 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8596 }
8597
8598 Handle(V3d_View) aView = ViewerTest::CurrentView();
8599 aView->Translate(Dx,Dy,Dz,aStart);
8600 return 0;
8601}
8602
8603//=======================================================================
8604//function : VTurnView
8605//purpose :
8606//=======================================================================
8607static Standard_Integer VTurnView (Draw_Interpretor& di,
8608 Standard_Integer argc,
8609 const char ** argv)
8610{
8611 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8612 if(aContext.IsNull()) {
8613 di << "use 'vinit' command before " << argv[0] << "\n";
8614 return 1;
8615 }
8616 if(argc < 4 || argc > 5){
8617 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8618 return 1;
8619 }
6b62b2da 8620 Standard_Real Ax = Draw::Atof (argv[1]);
8621 Standard_Real Ay = Draw::Atof (argv[2]);
8622 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 8623 Standard_Boolean aStart = Standard_True;
dc3fe572 8624 if (argc == 5)
4754e164 8625 {
6b62b2da 8626 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8627 }
8628
8629 Handle(V3d_View) aView = ViewerTest::CurrentView();
8630 aView->Turn(Ax,Ay,Az,aStart);
8631 return 0;
8632}
8633
269294d6 8634//==============================================================================
8635//function : VTextureEnv
8636//purpose : ENables or disables environment mapping
8637//==============================================================================
8638class OCC_TextureEnv : public Graphic3d_TextureEnv
8639{
8640public:
8641 OCC_TextureEnv(const Standard_CString FileName);
8642 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8643 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8644 const Standard_Boolean theModulateFlag,
8645 const Graphic3d_TypeOfTextureFilter theFilter,
8646 const Standard_ShortReal theXScale,
8647 const Standard_ShortReal theYScale,
8648 const Standard_ShortReal theXShift,
8649 const Standard_ShortReal theYShift,
8650 const Standard_ShortReal theAngle);
68858c7d 8651 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 8652};
a3f6f591 8653DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 8654
269294d6 8655OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8656 : Graphic3d_TextureEnv(theFileName)
8657{
8658}
8659
8660OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8661 : Graphic3d_TextureEnv(theTexId)
8662{
8663}
8664
8665void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8666 const Standard_Boolean theModulateFlag,
8667 const Graphic3d_TypeOfTextureFilter theFilter,
8668 const Standard_ShortReal theXScale,
8669 const Standard_ShortReal theYScale,
8670 const Standard_ShortReal theXShift,
8671 const Standard_ShortReal theYShift,
8672 const Standard_ShortReal theAngle)
8673{
8674 myParams->SetRepeat (theRepeatFlag);
8675 myParams->SetModulate (theModulateFlag);
8676 myParams->SetFilter (theFilter);
8677 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8678 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8679 myParams->SetRotation (theAngle);
8680}
8681
35e08fe8 8682static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 8683{
8684 // get the active view
8685 Handle(V3d_View) aView = ViewerTest::CurrentView();
8686 if (aView.IsNull())
8687 {
23fe70ec 8688 Message::SendFail ("Error: no active viewer");
269294d6 8689 return 1;
8690 }
8691
8692 // Checking the input arguments
8693 Standard_Boolean anEnableFlag = Standard_False;
8694 Standard_Boolean isOk = theArgNb >= 2;
8695 if (isOk)
8696 {
8697 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8698 anEnableFlag = anEnableOpt.IsEqual("on");
8699 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8700 }
8701 if (anEnableFlag)
8702 {
8703 isOk = (theArgNb == 3 || theArgNb == 11);
8704 if (isOk)
8705 {
8706 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8707 isOk = (!aTextureOpt.IsIntegerValue() ||
8708 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8709
8710 if (isOk && theArgNb == 11)
8711 {
8712 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8713 aModulateOpt(theArgVec[4]),
8714 aFilterOpt (theArgVec[5]),
8715 aSScaleOpt (theArgVec[6]),
8716 aTScaleOpt (theArgVec[7]),
8717 aSTransOpt (theArgVec[8]),
8718 aTTransOpt (theArgVec[9]),
8719 anAngleOpt (theArgVec[10]);
8720 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8721 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8722 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
d45edf24 8723 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8724 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8725 anAngleOpt.IsRealValue (Standard_True));
269294d6 8726 }
8727 }
8728 }
8729
8730 if (!isOk)
8731 {
23fe70ec 8732 Message::SendFail() << "Usage:\n"
8733 << theArgVec[0] << " off\n"
8734 << 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 8735 return 1;
8736 }
8737
8738 if (anEnableFlag)
8739 {
8740 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8741 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8742 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8743 new OCC_TextureEnv(theArgVec[2]);
8744
8745 if (theArgNb == 11)
8746 {
8747 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8748 aTexEnv->SetTextureParameters(
8749 aRepeatOpt. IsEqual("repeat"),
8750 aModulateOpt.IsEqual("modulate"),
8751 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8752 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8753 Graphic3d_TOTF_TRILINEAR,
8754 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8755 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8756 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8757 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8758 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8759 );
8760 }
8761 aView->SetTextureEnv(aTexEnv);
269294d6 8762 }
8763 else // Disabling environment mapping
8764 {
269294d6 8765 Handle(Graphic3d_TextureEnv) aTexture;
8766 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8767 }
8768
8769 aView->Redraw();
8770 return 0;
8771}
8772
3e05329c 8773namespace
8774{
8775 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8776
8777 //! Remove registered clipping plane from all views and objects.
8778 static void removePlane (MapOfPlanes& theRegPlanes,
8779 const TCollection_AsciiString& theName)
8780 {
8781 Handle(Graphic3d_ClipPlane) aClipPlane;
8782 if (!theRegPlanes.Find (theName, aClipPlane))
8783 {
23fe70ec 8784 Message::SendWarning ("Warning: no such plane");
3e05329c 8785 return;
8786 }
8787
8788 theRegPlanes.UnBind (theName);
8789 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8790 anIObjIt.More(); anIObjIt.Next())
8791 {
8f521168 8792 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 8793 aPrs->RemoveClipPlane (aClipPlane);
8794 }
8795
8796 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8797 aViewIt.More(); aViewIt.Next())
8798 {
8799 const Handle(V3d_View)& aView = aViewIt.Key2();
8800 aView->RemoveClipPlane(aClipPlane);
8801 }
8802
8803 ViewerTest::RedrawAllViews();
8804 }
8805}
8806
4269bd1b 8807//===============================================================================================
8808//function : VClipPlane
8809//purpose :
8810//===============================================================================================
8811static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8812{
8813 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 8814 static MapOfPlanes aRegPlanes;
8815
8816 if (theArgsNb < 2)
8817 {
3e05329c 8818 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8819 {
8820 theDi << aPlaneIter.Key() << " ";
8821 }
8822 return 0;
4269bd1b 8823 }
8824
8825 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 8826 aCommand.LowerCase();
8827 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8828 if (anActiveView.IsNull())
8829 {
23fe70ec 8830 Message::SendFail ("Error: no active viewer");
3e05329c 8831 return 1;
8832 }
4269bd1b 8833
8834 // print maximum number of planes for current viewer
3e05329c 8835 if (aCommand == "-maxplanes"
8836 || aCommand == "maxplanes")
4269bd1b 8837 {
3e05329c 8838 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8839 << " plane slots provided by driver.\n";
4269bd1b 8840 return 0;
8841 }
8842
8843 // create / delete plane instance
3e05329c 8844 if (aCommand == "-create"
8845 || aCommand == "create"
8846 || aCommand == "-delete"
8847 || aCommand == "delete"
8848 || aCommand == "-clone"
8849 || aCommand == "clone")
4269bd1b 8850 {
8851 if (theArgsNb < 3)
8852 {
23fe70ec 8853 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 8854 return 1;
8855 }
8856
3e05329c 8857 Standard_Boolean toCreate = aCommand == "-create"
8858 || aCommand == "create";
8859 Standard_Boolean toClone = aCommand == "-clone"
8860 || aCommand == "clone";
8861 Standard_Boolean toDelete = aCommand == "-delete"
8862 || aCommand == "delete";
4269bd1b 8863 TCollection_AsciiString aPlane (theArgVec[2]);
8864
8865 if (toCreate)
8866 {
8867 if (aRegPlanes.IsBound (aPlane))
8868 {
3e05329c 8869 std::cout << "Warning: existing plane has been overridden.\n";
8870 toDelete = true;
8871 }
8872 else
8873 {
8874 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8875 return 0;
4269bd1b 8876 }
4269bd1b 8877 }
8878 else if (toClone) // toClone
8879 {
8880 if (!aRegPlanes.IsBound (aPlane))
8881 {
23fe70ec 8882 Message::SendFail ("Error: no such plane");
4269bd1b 8883 return 1;
8884 }
3e05329c 8885 else if (theArgsNb < 4)
4269bd1b 8886 {
23fe70ec 8887 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 8888 return 1;
8889 }
8890
8891 TCollection_AsciiString aClone (theArgVec[3]);
8892 if (aRegPlanes.IsBound (aClone))
8893 {
23fe70ec 8894 Message::SendFail ("Error: plane name is in use");
4269bd1b 8895 return 1;
8896 }
8897
8898 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8899
8900 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 8901 return 0;
4269bd1b 8902 }
4269bd1b 8903
3e05329c 8904 if (toDelete)
8905 {
8906 if (aPlane == "ALL"
8907 || aPlane == "all"
8908 || aPlane == "*")
4269bd1b 8909 {
3e05329c 8910 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8911 {
8912 aPlane = aPlaneIter.Key();
8913 removePlane (aRegPlanes, aPlane);
8914 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8915 }
4269bd1b 8916 }
3e05329c 8917 else
4269bd1b 8918 {
3e05329c 8919 removePlane (aRegPlanes, aPlane);
4269bd1b 8920 }
4269bd1b 8921 }
8922
3e05329c 8923 if (toCreate)
8924 {
8925 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8926 }
4269bd1b 8927 return 0;
8928 }
8929
8930 // set / unset plane command
3e05329c 8931 if (aCommand == "set"
8932 || aCommand == "unset")
4269bd1b 8933 {
3e05329c 8934 if (theArgsNb < 5)
4269bd1b 8935 {
23fe70ec 8936 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8937 return 1;
8938 }
8939
3e05329c 8940 // redirect to new syntax
8941 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8942 anArgVec.SetValue (1, theArgVec[0]);
8943 anArgVec.SetValue (2, theArgVec[2]);
8944 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8945 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 8946 {
3e05329c 8947 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 8948 }
8949
3e05329c 8950 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 8951 }
8952
8953 // change plane command
3e05329c 8954 TCollection_AsciiString aPlaneName;
8955 Handle(Graphic3d_ClipPlane) aClipPlane;
8956 Standard_Integer anArgIter = 0;
8957 if (aCommand == "-change"
8958 || aCommand == "change")
4269bd1b 8959 {
3e05329c 8960 // old syntax support
8961 if (theArgsNb < 3)
4269bd1b 8962 {
23fe70ec 8963 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 8964 return 1;
8965 }
8966
3e05329c 8967 anArgIter = 3;
8968 aPlaneName = theArgVec[2];
8969 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 8970 {
23fe70ec 8971 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 8972 return 1;
8973 }
3e05329c 8974 }
8975 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8976 {
8977 anArgIter = 2;
8978 aPlaneName = theArgVec[1];
8979 }
8980 else
8981 {
8982 anArgIter = 2;
8983 aPlaneName = theArgVec[1];
8984 aClipPlane = new Graphic3d_ClipPlane();
8985 aRegPlanes.Bind (aPlaneName, aClipPlane);
8986 theDi << "Created new plane " << aPlaneName << ".\n";
8987 }
4269bd1b 8988
3e05329c 8989 if (theArgsNb - anArgIter < 1)
8990 {
23fe70ec 8991 Message::SendFail ("Syntax error: need more arguments");
3e05329c 8992 return 1;
8993 }
4269bd1b 8994
3e05329c 8995 for (; anArgIter < theArgsNb; ++anArgIter)
8996 {
8997 const char** aChangeArgs = theArgVec + anArgIter;
8998 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8999 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9000 aChangeArg.LowerCase();
4269bd1b 9001
3e05329c 9002 Standard_Boolean toEnable = Standard_True;
dae2a922 9003 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 9004 {
3e05329c 9005 aClipPlane->SetOn (toEnable);
4269bd1b 9006 }
25c35042 9007 else if (aChangeArg.StartsWith ("-equation")
9008 || aChangeArg.StartsWith ("equation"))
4269bd1b 9009 {
3e05329c 9010 if (aNbChangeArgs < 5)
4269bd1b 9011 {
23fe70ec 9012 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9013 return 1;
9014 }
9015
25c35042 9016 Standard_Integer aSubIndex = 1;
9017 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9018 if (aPrefixLen < aChangeArg.Length())
9019 {
9020 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9021 if (!aSubStr.IsIntegerValue()
9022 || aSubStr.IntegerValue() <= 0)
9023 {
23fe70ec 9024 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9025 return 1;
9026 }
9027 aSubIndex = aSubStr.IntegerValue();
9028 }
9029
9030 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9031 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9032 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9033 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9034 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9035 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9036 {
9037 if (aSubPln->ChainNextPlane().IsNull())
9038 {
9039 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9040 }
9041 aSubPln = aSubPln->ChainNextPlane();
9042 }
9043 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9044 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9045 anArgIter += 4;
4269bd1b 9046 }
25c35042 9047 else if ((aChangeArg == "-boxinterior"
9048 || aChangeArg == "-boxint"
9049 || aChangeArg == "-box")
9050 && aNbChangeArgs >= 7)
9051 {
9052 Graphic3d_BndBox3d aBndBox;
9053 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9054 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9055 anArgIter += 6;
9056
9057 Standard_Integer aNbSubPlanes = 6;
9058 const Graphic3d_Vec3d aDirArray[6] =
9059 {
9060 Graphic3d_Vec3d (-1, 0, 0),
9061 Graphic3d_Vec3d ( 1, 0, 0),
9062 Graphic3d_Vec3d ( 0,-1, 0),
9063 Graphic3d_Vec3d ( 0, 1, 0),
9064 Graphic3d_Vec3d ( 0, 0,-1),
9065 Graphic3d_Vec3d ( 0, 0, 1),
9066 };
9067 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9068 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9069 {
9070 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9071 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9072 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9073 if (aSubPlaneIter + 1 == aNbSubPlanes)
9074 {
9075 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9076 }
9077 else
9078 {
9079 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9080 }
9081 aSubPln = aSubPln->ChainNextPlane();
9082 }
9083 }
3e05329c 9084 else if (aChangeArg == "-capping"
9085 || aChangeArg == "capping")
4269bd1b 9086 {
3e05329c 9087 if (aNbChangeArgs < 2)
4269bd1b 9088 {
23fe70ec 9089 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9090 return 1;
9091 }
9092
dae2a922 9093 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9094 {
3e05329c 9095 aClipPlane->SetCapping (toEnable);
9096 anArgIter += 1;
9097 }
9098 else
9099 {
9100 // just skip otherwise (old syntax)
9101 }
9102 }
9103 else if (aChangeArg == "-useobjectmaterial"
9104 || aChangeArg == "-useobjectmat"
9105 || aChangeArg == "-useobjmat"
9106 || aChangeArg == "-useobjmaterial")
9107 {
9108 if (aNbChangeArgs < 2)
9109 {
23fe70ec 9110 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9111 return 1;
9112 }
9113
dae2a922 9114 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9115 {
3e05329c 9116 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9117 anArgIter += 1;
4269bd1b 9118 }
3e05329c 9119 }
9120 else if (aChangeArg == "-useobjecttexture"
9121 || aChangeArg == "-useobjecttex"
9122 || aChangeArg == "-useobjtexture"
9123 || aChangeArg == "-useobjtex")
9124 {
9125 if (aNbChangeArgs < 2)
4269bd1b 9126 {
23fe70ec 9127 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9128 return 1;
9129 }
4269bd1b 9130
dae2a922 9131 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9132 {
9133 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9134 anArgIter += 1;
9135 }
9136 }
9137 else if (aChangeArg == "-useobjectshader"
9138 || aChangeArg == "-useobjshader")
9139 {
9140 if (aNbChangeArgs < 2)
9141 {
23fe70ec 9142 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9143 return 1;
9144 }
4269bd1b 9145
dae2a922 9146 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9147 {
9148 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9149 anArgIter += 1;
4269bd1b 9150 }
3e05329c 9151 }
9152 else if (aChangeArg == "-color"
9153 || aChangeArg == "color")
9154 {
9155 Quantity_Color aColor;
dae2a922 9156 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9157 aChangeArgs + 1,
9158 aColor);
3e05329c 9159 if (aNbParsed == 0)
4269bd1b 9160 {
23fe70ec 9161 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9162 return 1;
9163 }
61168418 9164 aClipPlane->SetCappingColor (aColor);
3e05329c 9165 anArgIter += aNbParsed;
9166 }
61168418 9167 else if (aNbChangeArgs >= 1
9168 && (aChangeArg == "-material"
9169 || aChangeArg == "material"))
9170 {
9171 ++anArgIter;
9172 Graphic3d_NameOfMaterial aMatName;
9173 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9174 {
23fe70ec 9175 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9176 return 1;
9177 }
9178 aClipPlane->SetCappingMaterial (aMatName);
9179 }
1b661a81 9180 else if ((aChangeArg == "-transparency"
9181 || aChangeArg == "-transp")
9182 && aNbChangeArgs >= 2)
9183 {
9184 TCollection_AsciiString aValStr (aChangeArgs[1]);
9185 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
d45edf24 9186 if (aValStr.IsRealValue (Standard_True))
1b661a81 9187 {
9188 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9189 aMat.SetTransparency ((float )aValStr.RealValue());
9190 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9191 aClipPlane->SetCappingMaterial (aMat);
9192 }
9193 else
9194 {
9195 aValStr.LowerCase();
9196 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9197 if (aValStr == "opaque")
9198 {
9199 aMode = Graphic3d_AlphaMode_Opaque;
9200 }
9201 else if (aValStr == "mask")
9202 {
9203 aMode = Graphic3d_AlphaMode_Mask;
9204 }
9205 else if (aValStr == "blend")
9206 {
9207 aMode = Graphic3d_AlphaMode_Blend;
9208 }
33425a46 9209 else if (aValStr == "maskblend"
9210 || aValStr == "blendmask")
9211 {
9212 aMode = Graphic3d_AlphaMode_MaskBlend;
9213 }
1b661a81 9214 else if (aValStr == "blendauto")
9215 {
9216 aMode = Graphic3d_AlphaMode_BlendAuto;
9217 }
9218 else
9219 {
23fe70ec 9220 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9221 return 1;
9222 }
9223 anAspect->SetAlphaMode (aMode);
9224 aClipPlane->SetCappingAspect (anAspect);
9225 }
9226 anArgIter += 1;
9227 }
3e05329c 9228 else if (aChangeArg == "-texname"
9229 || aChangeArg == "texname")
9230 {
9231 if (aNbChangeArgs < 2)
9232 {
23fe70ec 9233 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9234 return 1;
9235 }
4269bd1b 9236
3e05329c 9237 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9238 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9239 if (!aTexture->IsDone())
9240 {
9241 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9242 }
3e05329c 9243 else
4269bd1b 9244 {
3e05329c 9245 aTexture->EnableModulate();
9246 aTexture->EnableRepeat();
9247 aClipPlane->SetCappingTexture (aTexture);
9248 }
9249 anArgIter += 1;
9250 }
9251 else if (aChangeArg == "-texscale"
9252 || aChangeArg == "texscale")
9253 {
9254 if (aClipPlane->CappingTexture().IsNull())
9255 {
23fe70ec 9256 Message::SendFail ("Error: no texture is set");
3e05329c 9257 return 1;
9258 }
4269bd1b 9259
3e05329c 9260 if (aNbChangeArgs < 3)
9261 {
23fe70ec 9262 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9263 return 1;
9264 }
4269bd1b 9265
3e05329c 9266 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9267 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9268 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9269 anArgIter += 2;
9270 }
9271 else if (aChangeArg == "-texorigin"
9272 || aChangeArg == "texorigin") // texture origin
9273 {
9274 if (aClipPlane->CappingTexture().IsNull())
9275 {
23fe70ec 9276 Message::SendFail ("Error: no texture is set");
3e05329c 9277 return 1;
9278 }
4269bd1b 9279
3e05329c 9280 if (aNbChangeArgs < 3)
9281 {
23fe70ec 9282 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9283 return 1;
4269bd1b 9284 }
3e05329c 9285
9286 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9287 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9288
9289 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9290 anArgIter += 2;
9291 }
9292 else if (aChangeArg == "-texrotate"
9293 || aChangeArg == "texrotate") // texture rotation
9294 {
9295 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9296 {
23fe70ec 9297 Message::SendFail ("Error: no texture is set");
3e05329c 9298 return 1;
9299 }
4269bd1b 9300
3e05329c 9301 if (aNbChangeArgs < 2)
9302 {
23fe70ec 9303 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9304 return 1;
9305 }
4269bd1b 9306
3e05329c 9307 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9308 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9309 anArgIter += 1;
9310 }
9311 else if (aChangeArg == "-hatch"
9312 || aChangeArg == "hatch")
9313 {
9314 if (aNbChangeArgs < 2)
9315 {
23fe70ec 9316 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9317 return 1;
9318 }
4269bd1b 9319
3e05329c 9320 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9321 aHatchStr.LowerCase();
9322 if (aHatchStr == "on")
9323 {
9324 aClipPlane->SetCappingHatchOn();
9325 }
9326 else if (aHatchStr == "off")
9327 {
9328 aClipPlane->SetCappingHatchOff();
4269bd1b 9329 }
3e05329c 9330 else
4269bd1b 9331 {
3e05329c 9332 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9333 }
9334 anArgIter += 1;
9335 }
9336 else if (aChangeArg == "-delete"
9337 || aChangeArg == "delete")
9338 {
9339 removePlane (aRegPlanes, aPlaneName);
9340 return 0;
9341 }
9342 else if (aChangeArg == "-set"
32ca7711 9343 || aChangeArg == "-unset"
9344 || aChangeArg == "-setoverrideglobal")
3e05329c 9345 {
9346 // set / unset plane command
32ca7711 9347 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9348 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9349 Standard_Integer anIt = 1;
9350 for (; anIt < aNbChangeArgs; ++anIt)
9351 {
9352 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9353 if (anEntityName.IsEmpty()
9354 || anEntityName.Value (1) == '-')
4269bd1b 9355 {
3e05329c 9356 break;
4269bd1b 9357 }
32ca7711 9358 else if (!toOverrideGlobal
9359 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9360 {
3e05329c 9361 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9362 if (toSet)
9363 {
9364 aView->AddClipPlane (aClipPlane);
9365 }
9366 else
9367 {
9368 aView->RemoveClipPlane (aClipPlane);
9369 }
9370 continue;
4269bd1b 9371 }
3e05329c 9372 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9373 {
8f521168 9374 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9375 if (toSet)
9376 {
9377 aIObj->AddClipPlane (aClipPlane);
9378 }
9379 else
9380 {
9381 aIObj->RemoveClipPlane (aClipPlane);
9382 }
32ca7711 9383 if (!aIObj->ClipPlanes().IsNull())
9384 {
9385 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9386 }
4269bd1b 9387 }
3e05329c 9388 else
4269bd1b 9389 {
23fe70ec 9390 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9391 return 1;
4269bd1b 9392 }
3e05329c 9393 }
9394
9395 if (anIt == 1)
9396 {
9397 // apply to active view
9398 if (toSet)
4269bd1b 9399 {
3e05329c 9400 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9401 }
9402 else
9403 {
3e05329c 9404 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9405 }
9406 }
3e05329c 9407 else
9408 {
9409 anArgIter = anArgIter + anIt - 1;
9410 }
9411 }
9412 else
9413 {
23fe70ec 9414 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9415 return 1;
4269bd1b 9416 }
4269bd1b 9417 }
9418
3e05329c 9419 ViewerTest::RedrawAllViews();
9420 return 0;
4269bd1b 9421}
9422
b5ac8292 9423//===============================================================================================
9424//function : VZRange
9425//purpose :
9426//===============================================================================================
9427static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9428{
197ac94e 9429 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9430
9431 if (aCurrentView.IsNull())
b5ac8292 9432 {
23fe70ec 9433 Message::SendFail ("Error: no active viewer");
b5ac8292 9434 return 1;
9435 }
9436
197ac94e 9437 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9438
9439 if (theArgsNb < 2)
9440 {
9441 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9442 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9443 return 0;
9444 }
9445
9446 if (theArgsNb == 3)
9447 {
6b62b2da 9448 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9449 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9450
9451 if (aNewZNear >= aNewZFar)
9452 {
23fe70ec 9453 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9454 return 1;
9455 }
9456
9457 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9458 {
23fe70ec 9459 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9460 return 1;
9461 }
9462
9463 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9464 }
9465 else
9466 {
23fe70ec 9467 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9468 return 1;
9469 }
9470
197ac94e 9471 aCurrentView->Redraw();
9472
b5ac8292 9473 return 0;
9474}
9475
9476//===============================================================================================
9477//function : VAutoZFit
9478//purpose :
9479//===============================================================================================
9480static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9481{
197ac94e 9482 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9483
9484 if (aCurrentView.IsNull())
b5ac8292 9485 {
23fe70ec 9486 Message::SendFail ("Error: no active viewer");
b5ac8292 9487 return 1;
9488 }
9489
c357e426 9490 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9491
9492 if (theArgsNb > 3)
b5ac8292 9493 {
23fe70ec 9494 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9495 return 1;
b5ac8292 9496 }
9497
197ac94e 9498 if (theArgsNb < 2)
b5ac8292 9499 {
586db386 9500 theDi << "Auto z-fit mode: \n"
c357e426 9501 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9502 << "Scale: " << aScale << "\n";
9503 return 0;
b5ac8292 9504 }
197ac94e 9505
9506 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9507
9508 if (theArgsNb >= 3)
b5ac8292 9509 {
197ac94e 9510 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9511 }
9512
c357e426 9513 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9514 aCurrentView->Redraw();
b5ac8292 9515 return 0;
9516}
9517
6b62b2da 9518//! Auxiliary function to print projection type
9519inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9520{
9521 switch (theProjType)
9522 {
9523 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9524 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9525 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9526 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9527 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9528 }
9529 return "UNKNOWN";
9530}
9531
b5ac8292 9532//===============================================================================================
6b62b2da 9533//function : VCamera
b5ac8292 9534//purpose :
9535//===============================================================================================
6b62b2da 9536static int VCamera (Draw_Interpretor& theDI,
9537 Standard_Integer theArgsNb,
9538 const char** theArgVec)
b5ac8292 9539{
6b62b2da 9540 Handle(V3d_View) aView = ViewerTest::CurrentView();
9541 if (aView.IsNull())
b5ac8292 9542 {
23fe70ec 9543 Message::SendFail ("Error: no active viewer");
b5ac8292 9544 return 1;
9545 }
9546
6b62b2da 9547 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9548 if (theArgsNb < 2)
b5ac8292 9549 {
6b62b2da 9550 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9551 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 9552 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9553 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 9554 theDI << "Distance: " << aCamera->Distance() << "\n";
9555 theDI << "IOD: " << aCamera->IOD() << "\n";
9556 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9557 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9558 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
168c27c6 9559 theDI << "ZNear: " << aCamera->ZNear() << "\n";
9560 theDI << "ZFar: " << aCamera->ZFar() << "\n";
6b62b2da 9561 return 0;
b5ac8292 9562 }
9563
30a1b24e 9564 TCollection_AsciiString aPrsName;
6b62b2da 9565 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 9566 {
6b62b2da 9567 Standard_CString anArg = theArgVec[anArgIter];
9568 TCollection_AsciiString anArgCase (anArg);
9569 anArgCase.LowerCase();
9570 if (anArgCase == "-proj"
9571 || anArgCase == "-projection"
9572 || anArgCase == "-projtype"
9573 || anArgCase == "-projectiontype")
9574 {
9575 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9576 }
9577 else if (anArgCase == "-ortho"
9578 || anArgCase == "-orthographic")
b5ac8292 9579 {
9580 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 9581 }
9582 else if (anArgCase == "-persp"
9583 || anArgCase == "-perspective"
9584 || anArgCase == "-perspmono"
9585 || anArgCase == "-perspectivemono"
9586 || anArgCase == "-mono")
b5ac8292 9587 {
9588 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9589 }
6b62b2da 9590 else if (anArgCase == "-stereo"
9591 || anArgCase == "-stereoscopic"
9592 || anArgCase == "-perspstereo"
9593 || anArgCase == "-perspectivestereo")
9594 {
9595 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9596 }
9597 else if (anArgCase == "-left"
9598 || anArgCase == "-lefteye"
9599 || anArgCase == "-monoleft"
9600 || anArgCase == "-monolefteye"
9601 || anArgCase == "-perpsleft"
9602 || anArgCase == "-perpslefteye")
b5ac8292 9603 {
9604 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9605 }
6b62b2da 9606 else if (anArgCase == "-right"
9607 || anArgCase == "-righteye"
9608 || anArgCase == "-monoright"
9609 || anArgCase == "-monorighteye"
9610 || anArgCase == "-perpsright")
b5ac8292 9611 {
9612 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9613 }
6b62b2da 9614 else if (anArgCase == "-dist"
9615 || anArgCase == "-distance")
b5ac8292 9616 {
6b62b2da 9617 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9618 if (anArgValue != NULL
9619 && *anArgValue != '-')
9620 {
9621 ++anArgIter;
9622 aCamera->SetDistance (Draw::Atof (anArgValue));
9623 continue;
9624 }
9625 theDI << aCamera->Distance() << " ";
b5ac8292 9626 }
6b62b2da 9627 else if (anArgCase == "-iod")
b5ac8292 9628 {
6b62b2da 9629 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9630 if (anArgValue != NULL
9631 && *anArgValue != '-')
9632 {
9633 ++anArgIter;
9634 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9635 continue;
9636 }
9637 theDI << aCamera->IOD() << " ";
b5ac8292 9638 }
6b62b2da 9639 else if (anArgCase == "-iodtype")
b5ac8292 9640 {
6b62b2da 9641 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9642 TCollection_AsciiString anValueCase (anArgValue);
9643 anValueCase.LowerCase();
9644 if (anValueCase == "abs"
9645 || anValueCase == "absolute")
9646 {
9647 ++anArgIter;
9648 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9649 continue;
9650 }
9651 else if (anValueCase == "rel"
9652 || anValueCase == "relative")
9653 {
9654 ++anArgIter;
9655 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9656 continue;
9657 }
9658 else if (*anArgValue != '-')
9659 {
23fe70ec 9660 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 9661 return 1;
9662 }
9663 switch (aCamera->GetIODType())
9664 {
9665 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9666 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9667 }
b5ac8292 9668 }
6b62b2da 9669 else if (anArgCase == "-zfocus")
b5ac8292 9670 {
6b62b2da 9671 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9672 if (anArgValue != NULL
9673 && *anArgValue != '-')
9674 {
9675 ++anArgIter;
9676 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9677 continue;
9678 }
9679 theDI << aCamera->ZFocus() << " ";
b5ac8292 9680 }
6b62b2da 9681 else if (anArgCase == "-zfocustype")
b5ac8292 9682 {
6b62b2da 9683 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9684 TCollection_AsciiString anValueCase (anArgValue);
9685 anValueCase.LowerCase();
9686 if (anValueCase == "abs"
9687 || anValueCase == "absolute")
9688 {
9689 ++anArgIter;
9690 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9691 continue;
9692 }
9693 else if (anValueCase == "rel"
9694 || anValueCase == "relative")
9695 {
9696 ++anArgIter;
9697 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9698 continue;
9699 }
9700 else if (*anArgValue != '-')
9701 {
23fe70ec 9702 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 9703 return 1;
9704 }
9705 switch (aCamera->ZFocusType())
9706 {
9707 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9708 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9709 }
9710 }
b40cdc2b 9711 else if (anArgCase == "-lockzup"
9712 || anArgCase == "-turntable")
9713 {
9714 bool toLockUp = true;
9715 if (++anArgIter < theArgsNb
dae2a922 9716 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 9717 {
9718 --anArgIter;
9719 }
9720 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9721 }
6b62b2da 9722 else if (anArgCase == "-fov"
b40cdc2b 9723 || anArgCase == "-fovy"
9724 || anArgCase == "-fovx"
9725 || anArgCase == "-fov2d")
b5ac8292 9726 {
6b62b2da 9727 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9728 if (anArgValue != NULL
9729 && *anArgValue != '-')
9730 {
9731 ++anArgIter;
b40cdc2b 9732 if (anArgCase == "-fov2d")
9733 {
9734 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9735 }
9736 else if (anArgCase == "-fovx")
9737 {
9738 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9739 }
9740 else
9741 {
9742 aCamera->SetFOVy (Draw::Atof (anArgValue));
9743 }
6b62b2da 9744 continue;
9745 }
b40cdc2b 9746 if (anArgCase == "-fov2d")
9747 {
9748 theDI << aCamera->FOV2d() << " ";
9749 }
9750 else if (anArgCase == "-fovx")
9751 {
9752 theDI << aCamera->FOVx() << " ";
9753 }
9754 else
9755 {
9756 theDI << aCamera->FOVy() << " ";
9757 }
9758 }
9759 else if (anArgIter + 1 < theArgsNb
9760 && anArgCase == "-xrpose")
9761 {
9762 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9763 anXRArg.LowerCase();
9764 if (anXRArg == "base")
9765 {
9766 aCamera = aView->View()->BaseXRCamera();
9767 }
9768 else if (anXRArg == "head")
9769 {
9770 aCamera = aView->View()->PosedXRCamera();
9771 }
9772 else
9773 {
9774 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9775 return 1;
9776 }
9777 if (aCamera.IsNull())
9778 {
9779 Message::SendFail() << "Error: undefined XR pose";
9780 return 0;
9781 }
9782 if (aView->AutoZFitMode())
9783 {
9784 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9785 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9786 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9787 }
b5ac8292 9788 }
30a1b24e 9789 else if (aPrsName.IsEmpty()
9790 && !anArgCase.StartsWith ("-"))
9791 {
9792 aPrsName = anArg;
9793 }
b5ac8292 9794 else
9795 {
23fe70ec 9796 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 9797 return 1;
9798 }
9799 }
b5ac8292 9800
30a1b24e 9801 if (aPrsName.IsEmpty()
9802 || theArgsNb > 2)
9803 {
30a1b24e 9804 aView->Redraw();
9805 }
9806
9807 if (!aPrsName.IsEmpty())
9808 {
9809 Handle(AIS_CameraFrustum) aCameraFrustum;
9810 if (GetMapOfAIS().IsBound2 (aPrsName))
9811 {
9812 // find existing object
9813 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9814 if (aCameraFrustum.IsNull())
9815 {
23fe70ec 9816 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 9817 return 1;
9818 }
9819 }
9820
9821 if (aCameraFrustum.IsNull())
9822 {
9823 aCameraFrustum = new AIS_CameraFrustum();
9824 }
9825 else
9826 {
9827 // not include displayed object of old camera frustum in the new one.
9828 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9829 aView->ZFitAll();
9830 }
b40cdc2b 9831 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 9832
9833 ViewerTest::Display (aPrsName, aCameraFrustum);
9834 }
b5ac8292 9835
9836 return 0;
9837}
9838
f978241f 9839//! Parse stereo output mode
9840inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9841 Graphic3d_StereoMode& theMode)
9842{
9843 TCollection_AsciiString aFlag (theArg);
9844 aFlag.LowerCase();
9845 if (aFlag == "quadbuffer")
9846 {
9847 theMode = Graphic3d_StereoMode_QuadBuffer;
9848 }
9849 else if (aFlag == "anaglyph")
9850 {
9851 theMode = Graphic3d_StereoMode_Anaglyph;
9852 }
9853 else if (aFlag == "row"
9854 || aFlag == "rowinterlaced")
9855 {
9856 theMode = Graphic3d_StereoMode_RowInterlaced;
9857 }
9858 else if (aFlag == "col"
9859 || aFlag == "colinterlaced"
9860 || aFlag == "columninterlaced")
9861 {
9862 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9863 }
9864 else if (aFlag == "chess"
9865 || aFlag == "chessboard")
9866 {
9867 theMode = Graphic3d_StereoMode_ChessBoard;
9868 }
9869 else if (aFlag == "sbs"
9870 || aFlag == "sidebyside")
9871 {
9872 theMode = Graphic3d_StereoMode_SideBySide;
9873 }
9874 else if (aFlag == "ou"
9875 || aFlag == "overunder")
9876 {
9877 theMode = Graphic3d_StereoMode_OverUnder;
9878 }
9879 else if (aFlag == "pageflip"
9880 || aFlag == "softpageflip")
9881 {
9882 theMode = Graphic3d_StereoMode_SoftPageFlip;
9883 }
b40cdc2b 9884 else if (aFlag == "openvr"
9885 || aFlag == "vr")
9886 {
9887 theMode = Graphic3d_StereoMode_OpenVR;
9888 }
f978241f 9889 else
9890 {
9891 return Standard_False;
9892 }
9893 return Standard_True;
9894}
9895
9896//! Parse anaglyph filter
9897inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9898 Graphic3d_RenderingParams::Anaglyph& theFilter)
9899{
9900 TCollection_AsciiString aFlag (theArg);
9901 aFlag.LowerCase();
9902 if (aFlag == "redcyansimple")
9903 {
9904 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9905 }
9906 else if (aFlag == "redcyan"
9907 || aFlag == "redcyanoptimized")
9908 {
9909 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9910 }
9911 else if (aFlag == "yellowbluesimple")
9912 {
9913 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9914 }
9915 else if (aFlag == "yellowblue"
9916 || aFlag == "yellowblueoptimized")
9917 {
9918 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9919 }
9920 else if (aFlag == "greenmagenta"
9921 || aFlag == "greenmagentasimple")
9922 {
9923 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9924 }
9925 else
9926 {
9927 return Standard_False;
9928 }
9929 return Standard_True;
9930}
9931
b5ac8292 9932//==============================================================================
9933//function : VStereo
9934//purpose :
9935//==============================================================================
9936
9937static int VStereo (Draw_Interpretor& theDI,
9938 Standard_Integer theArgNb,
9939 const char** theArgVec)
9940{
f978241f 9941 Handle(V3d_View) aView = ViewerTest::CurrentView();
b8db9379 9942 if (aView.IsNull())
b5ac8292 9943 {
b8db9379 9944 Message::SendFail ("Error: no active viewer");
9945 return 0;
9946 }
b5ac8292 9947
b8db9379 9948 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9949 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9950 if (theArgNb < 2)
9951 {
9952 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
b5ac8292 9953 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 9954 if (isActive)
9955 {
9956 TCollection_AsciiString aMode;
9957 switch (aView->RenderingParams().StereoMode)
9958 {
9959 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
9960 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
9961 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
9962 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
9963 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
9964 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
9965 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 9966 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 9967 case Graphic3d_StereoMode_Anaglyph :
9968 aMode = "anaglyph";
9969 switch (aView->RenderingParams().AnaglyphFilter)
9970 {
9971 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9972 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9973 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9974 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9975 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9976 default: break;
9977 }
9978 default: break;
9979 }
9980 theDI << "Mode " << aMode << "\n";
9981 }
b5ac8292 9982 return 0;
9983 }
9984
b8db9379 9985 Graphic3d_StereoMode aMode = aParams->StereoMode;
f978241f 9986 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9987 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9988 {
9989 Standard_CString anArg = theArgVec[anArgIter];
9990 TCollection_AsciiString aFlag (anArg);
9991 aFlag.LowerCase();
9992 if (anUpdateTool.parseRedrawMode (aFlag))
9993 {
9994 continue;
9995 }
9996 else if (aFlag == "0"
9997 || aFlag == "off")
9998 {
9999 if (++anArgIter < theArgNb)
10000 {
23fe70ec 10001 Message::SendFail ("Error: wrong number of arguments");
f978241f 10002 return 1;
10003 }
10004
b8db9379 10005 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
f978241f 10006 {
10007 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10008 }
f978241f 10009 return 0;
10010 }
10011 else if (aFlag == "1"
10012 || aFlag == "on")
10013 {
10014 if (++anArgIter < theArgNb)
10015 {
23fe70ec 10016 Message::SendFail ("Error: wrong number of arguments");
f978241f 10017 return 1;
10018 }
10019
b8db9379 10020 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 10021 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10022 {
10023 return 0;
10024 }
f978241f 10025 }
10026 else if (aFlag == "-reverse"
10027 || aFlag == "-reversed"
10028 || aFlag == "-swap")
10029 {
10030 Standard_Boolean toEnable = Standard_True;
10031 if (++anArgIter < theArgNb
dae2a922 10032 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10033 {
10034 --anArgIter;
10035 }
10036 aParams->ToReverseStereo = toEnable;
10037 }
10038 else if (aFlag == "-noreverse"
10039 || aFlag == "-noswap")
10040 {
10041 Standard_Boolean toDisable = Standard_True;
10042 if (++anArgIter < theArgNb
dae2a922 10043 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10044 {
10045 --anArgIter;
10046 }
10047 aParams->ToReverseStereo = !toDisable;
10048 }
10049 else if (aFlag == "-mode"
10050 || aFlag == "-stereomode")
10051 {
10052 if (++anArgIter >= theArgNb
10053 || !parseStereoMode (theArgVec[anArgIter], aMode))
10054 {
23fe70ec 10055 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10056 return 1;
10057 }
10058
10059 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10060 {
b8db9379 10061 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10062 }
10063 }
10064 else if (aFlag == "-anaglyph"
10065 || aFlag == "-anaglyphfilter")
10066 {
10067 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10068 if (++anArgIter >= theArgNb
10069 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10070 {
23fe70ec 10071 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10072 return 1;
10073 }
10074
10075 aMode = Graphic3d_StereoMode_Anaglyph;
10076 aParams->AnaglyphFilter = aFilter;
10077 }
10078 else if (parseStereoMode (anArg, aMode)) // short syntax
10079 {
10080 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10081 {
b8db9379 10082 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
f978241f 10083 }
10084 }
b40cdc2b 10085 else if (anArgIter + 1 < theArgNb
10086 && aFlag == "-hmdfov2d")
10087 {
10088 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10089 if (aParams->HmdFov2d < 10.0f
10090 || aParams->HmdFov2d > 180.0f)
10091 {
10092 Message::SendFail() << "Error: FOV is out of range";
10093 return 1;
10094 }
10095 }
10096 else if (aFlag == "-mirror"
10097 || aFlag == "-mirrorcomposer")
10098 {
10099 Standard_Boolean toEnable = Standard_True;
10100 if (++anArgIter < theArgNb
dae2a922 10101 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10102 {
10103 --anArgIter;
10104 }
10105 aParams->ToMirrorComposer = toEnable;
10106 }
10107 else if (anArgIter + 1 < theArgNb
10108 && (aFlag == "-unitfactor"
10109 || aFlag == "-unitscale"))
10110 {
10111 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10112 }
f978241f 10113 else
10114 {
23fe70ec 10115 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10116 return 1;
10117 }
10118 }
10119
b8db9379 10120 aParams->StereoMode = aMode;
10121 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10122 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
f978241f 10123 {
b8db9379 10124 // initiate implicit continuous rendering
10125 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
f978241f 10126 }
b5ac8292 10127 return 0;
10128}
10129
392ac980 10130//===============================================================================================
10131//function : VDefaults
10132//purpose :
10133//===============================================================================================
10134static int VDefaults (Draw_Interpretor& theDi,
10135 Standard_Integer theArgsNb,
10136 const char** theArgVec)
10137{
10138 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10139 if (aCtx.IsNull())
10140 {
23fe70ec 10141 Message::SendFail ("Error: no active viewer");
392ac980 10142 return 1;
10143 }
10144
10145 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10146 if (theArgsNb < 2)
10147 {
10148 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10149 {
10150 theDi << "DeflType: relative\n"
10151 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10152 }
10153 else
10154 {
10155 theDi << "DeflType: absolute\n"
10156 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10157 }
67441d0c 10158 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10159 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10160 return 0;
10161 }
10162
10163 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10164 {
10165 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10166 anArg.UpperCase();
10167 if (anArg == "-ABSDEFL"
10168 || anArg == "-ABSOLUTEDEFLECTION"
10169 || anArg == "-DEFL"
10170 || anArg == "-DEFLECTION")
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_ABSOLUTE);
4c513386 10178 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10179 }
4c513386 10180 else if (anArg == "-RELDEFL"
10181 || anArg == "-RELATIVEDEFLECTION"
10182 || anArg == "-DEVCOEFF"
10183 || anArg == "-DEVIATIONCOEFF"
10184 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10185 {
4c513386 10186 if (++anArgIter >= theArgsNb)
10187 {
23fe70ec 10188 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10189 return 1;
10190 }
392ac980 10191 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10192 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10193 }
4c513386 10194 else if (anArg == "-ANGDEFL"
10195 || anArg == "-ANGULARDEFL"
10196 || anArg == "-ANGULARDEFLECTION")
392ac980 10197 {
4c513386 10198 if (++anArgIter >= theArgsNb)
10199 {
23fe70ec 10200 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10201 return 1;
10202 }
67441d0c 10203 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10204 }
385c43e7 10205 else if (anArg == "-AUTOTR"
10206 || anArg == "-AUTOTRIANG"
10207 || anArg == "-AUTOTRIANGULATION")
4c513386 10208 {
14c7f553 10209 ++anArgIter;
10210 bool toTurnOn = true;
10211 if (anArgIter >= theArgsNb
dae2a922 10212 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10213 {
23fe70ec 10214 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10215 return 1;
10216 }
14c7f553 10217 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10218 }
10219 else
10220 {
23fe70ec 10221 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10222 return 1;
392ac980 10223 }
10224 }
10225
10226 return 0;
10227}
10228
12381341 10229//! Auxiliary method
10230inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10231 const Graphic3d_ZLayerId theLayer,
12381341 10232 const Standard_Boolean theIsGlobal)
10233{
10234 if (theLightNew.IsNull())
10235 {
10236 return;
10237 }
10238
992ed6b3 10239 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10240 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10241 {
992ed6b3 10242 aViewer->AddLight (theLightNew);
10243 if (theIsGlobal)
10244 {
10245 aViewer->SetLightOn (theLightNew);
10246 }
10247 else
10248 {
10249 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10250 }
12381341 10251 }
10252 else
10253 {
992ed6b3 10254 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10255 if (aSettings.Lights().IsNull())
10256 {
10257 aSettings.SetLights (new Graphic3d_LightSet());
10258 }
10259 aSettings.Lights()->Add (theLightNew);
10260 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10261 }
10262}
10263
10264//! Auxiliary method
10265inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10266{
10267 TCollection_AsciiString anArgNextCase (theArgNext);
10268 anArgNextCase.UpperCase();
10269 if (anArgNextCase.Length() > 5
10270 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10271 {
10272 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10273 }
10274 else
10275 {
10276 return theArgNext.IntegerValue();
10277 }
10278}
10279
2daa5d95 10280static Handle(AIS_LightSource) findLightPrs (const Handle(V3d_Light)& theLight,
10281 const bool theToShowErrors = true)
10282{
10283 if (theLight.IsNull())
10284 {
10285 if (theToShowErrors)
10286 {
10287 Message::SendFail() << "Syntax error: no active light source to find presentation";
10288 }
10289 return Handle(AIS_LightSource)();
10290 }
10291
10292 Handle(AIS_InteractiveObject) anObject;
10293 GetMapOfAIS().Find2 (theLight->Name(), anObject);
10294 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (anObject);
10295 if (aLightSource.IsNull())
10296 {
10297 if (theToShowErrors)
10298 {
10299 Message::SendFail() << "Syntax error: could not find '" << theLight->Name() << "' AIS object";
10300 }
10301 }
10302 return aLightSource;
10303}
10304
12381341 10305//===============================================================================================
10306//function : VLight
10307//purpose :
10308//===============================================================================================
10309static int VLight (Draw_Interpretor& theDi,
10310 Standard_Integer theArgsNb,
10311 const char** theArgVec)
10312{
10313 Handle(V3d_View) aView = ViewerTest::CurrentView();
10314 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10315 if (aView.IsNull()
10316 || aViewer.IsNull())
10317 {
23fe70ec 10318 Message::SendFail ("Error: no active viewer");
12381341 10319 return 1;
10320 }
10321
ee2be2a8 10322 Standard_Real anXYZ[3] = {};
10323 Standard_Real anAtten[2] = {};
12381341 10324 if (theArgsNb < 2)
10325 {
10326 // print lights info
10327 Standard_Integer aLightId = 0;
6a24c6de 10328 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10329 {
6a24c6de 10330 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10331 const Quantity_Color aColor = aLight->Color();
992ed6b3 10332 theDi << "Light #" << aLightId
10333 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10334 << " [" << aLight->GetId() << "]" << "\n";
12381341 10335 switch (aLight->Type())
10336 {
10337 case V3d_AMBIENT:
10338 {
189f85a3 10339 theDi << " Type: Ambient\n";
10340 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10341 break;
10342 }
10343 case V3d_DIRECTIONAL:
10344 {
189f85a3 10345 theDi << " Type: Directional\n";
10346 theDi << " Intensity: " << aLight->Intensity() << "\n";
10347 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10348 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10349 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10350 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10351 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10352 break;
10353 }
10354 case V3d_POSITIONAL:
10355 {
189f85a3 10356 theDi << " Type: Positional\n";
10357 theDi << " Intensity: " << aLight->Intensity() << "\n";
10358 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10359 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10360 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10361 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10362 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10363 aLight->Attenuation (anAtten[0], anAtten[1]);
10364 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
88b312d3 10365 theDi << " Range: " << aLight->Range() << "\n";
12381341 10366 break;
10367 }
10368 case V3d_SPOT:
10369 {
189f85a3 10370 theDi << " Type: Spot\n";
10371 theDi << " Intensity: " << aLight->Intensity() << "\n";
10372 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10373 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10374 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10375 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10376 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10377 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10378 aLight->Attenuation (anAtten[0], anAtten[1]);
10379 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10380 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10381 theDi << " Exponent: " << aLight->Concentration() << "\n";
88b312d3 10382 theDi << " Range: " << aLight->Range() << "\n";
12381341 10383 break;
10384 }
10385 default:
10386 {
189f85a3 10387 theDi << " Type: UNKNOWN\n";
12381341 10388 break;
10389 }
10390 }
992ed6b3 10391 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10392 }
10393 }
10394
2daa5d95 10395 Handle(V3d_Light) aLightNew, aLightOld;
992ed6b3 10396 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10397 Standard_Boolean isGlobal = Standard_True;
10398 Standard_Boolean toCreate = Standard_False;
761d8807 10399 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10400 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10401 {
992ed6b3 10402 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10403
10404 TCollection_AsciiString aName, aValue;
10405 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10406 TCollection_AsciiString anArgCase (anArg);
10407 anArgCase.UpperCase();
761d8807 10408 if (anUpdateTool.parseRedrawMode (anArg))
10409 {
10410 continue;
10411 }
10412
12381341 10413 if (anArgCase.IsEqual ("NEW")
10414 || anArgCase.IsEqual ("ADD")
992ed6b3 10415 || anArgCase.IsEqual ("CREATE")
10416 || anArgCase.IsEqual ("-NEW")
10417 || anArgCase.IsEqual ("-ADD")
10418 || anArgCase.IsEqual ("-CREATE"))
12381341 10419 {
10420 toCreate = Standard_True;
10421 }
992ed6b3 10422 else if (anArgCase.IsEqual ("-LAYER")
10423 || anArgCase.IsEqual ("-ZLAYER"))
10424 {
10425 if (++anArgIt >= theArgsNb)
10426 {
23fe70ec 10427 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10428 return 1;
10429 }
10430
10431 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10432 aValStr.LowerCase();
10433 if (aValStr == "default"
10434 || aValStr == "def")
10435 {
10436 aLayer = Graphic3d_ZLayerId_Default;
10437 }
10438 else if (aValStr == "top")
10439 {
10440 aLayer = Graphic3d_ZLayerId_Top;
10441 }
10442 else if (aValStr == "topmost")
10443 {
10444 aLayer = Graphic3d_ZLayerId_Topmost;
10445 }
10446 else if (aValStr == "toposd"
10447 || aValStr == "osd")
10448 {
10449 aLayer = Graphic3d_ZLayerId_TopOSD;
10450 }
10451 else if (aValStr == "botosd"
10452 || aValStr == "bottom")
10453 {
10454 aLayer = Graphic3d_ZLayerId_BotOSD;
10455 }
10456 else if (aValStr.IsIntegerValue())
10457 {
10458 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10459 }
10460 else
10461 {
23fe70ec 10462 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10463 return 1;
10464 }
10465 }
12381341 10466 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10467 || anArgCase.IsEqual ("GLOBAL")
10468 || anArgCase.IsEqual ("-GLOB")
10469 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10470 {
10471 isGlobal = Standard_True;
10472 }
10473 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10474 || anArgCase.IsEqual ("LOCAL")
10475 || anArgCase.IsEqual ("-LOC")
10476 || anArgCase.IsEqual ("-LOCAL"))
12381341 10477 {
10478 isGlobal = Standard_False;
10479 }
4fe9ad57 10480 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10481 || anArgCase.IsEqual ("DEFAULTS")
10482 || anArgCase.IsEqual ("-DEF")
10483 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10484 {
10485 toCreate = Standard_False;
10486 aViewer->SetDefaultLights();
10487 }
10488 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10489 || anArgCase.IsEqual ("CLEAR")
10490 || anArgCase.IsEqual ("-CLR")
10491 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10492 {
10493 toCreate = Standard_False;
992ed6b3 10494
10495 TColStd_SequenceOfInteger aLayers;
10496 aViewer->GetAllZLayers (aLayers);
10497 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10498 {
992ed6b3 10499 if (aLayeriter.Value() == aLayer
10500 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10501 {
10502 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10503 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10504 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10505 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10506 {
10507 break;
10508 }
10509 }
10510 }
10511
10512 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10513 {
2daa5d95 10514 ViewerTest_DoubleMapOfInteractiveAndName aMap = GetMapOfAIS();
992ed6b3 10515 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10516 {
10517 Handle(V3d_Light) aLight = aLightIter.Value();
2daa5d95 10518 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLight, false))
10519 {
10520 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10521 GetMapOfAIS().UnBind2 (aLight->Name());
10522 }
992ed6b3 10523 aViewer->DelLight (aLight);
10524 aLightIter = aView->ActiveLightIterator();
10525 }
4fe9ad57 10526 }
10527 }
12381341 10528 else if (anArgCase.IsEqual ("AMB")
10529 || anArgCase.IsEqual ("AMBIENT")
10530 || anArgCase.IsEqual ("AMBLIGHT"))
10531 {
12381341 10532 if (!toCreate)
10533 {
23fe70ec 10534 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10535 return 1;
10536 }
992ed6b3 10537
10538 addLight (aLightNew, aLayer, isGlobal);
12381341 10539 toCreate = Standard_False;
992ed6b3 10540 aLightNew = new V3d_AmbientLight();
12381341 10541 }
10542 else if (anArgCase.IsEqual ("DIRECTIONAL")
10543 || anArgCase.IsEqual ("DIRLIGHT"))
10544 {
12381341 10545 if (!toCreate)
10546 {
23fe70ec 10547 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10548 return 1;
10549 }
992ed6b3 10550
10551 addLight (aLightNew, aLayer, isGlobal);
12381341 10552 toCreate = Standard_False;
992ed6b3 10553 aLightNew = new V3d_DirectionalLight();
12381341 10554 }
10555 else if (anArgCase.IsEqual ("SPOT")
10556 || anArgCase.IsEqual ("SPOTLIGHT"))
10557 {
12381341 10558 if (!toCreate)
10559 {
23fe70ec 10560 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10561 return 1;
10562 }
992ed6b3 10563
10564 addLight (aLightNew, aLayer, isGlobal);
12381341 10565 toCreate = Standard_False;
992ed6b3 10566 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10567 }
10568 else if (anArgCase.IsEqual ("POSLIGHT")
10569 || anArgCase.IsEqual ("POSITIONAL"))
10570 {
12381341 10571 if (!toCreate)
10572 {
23fe70ec 10573 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10574 return 1;
10575 }
992ed6b3 10576
10577 addLight (aLightNew, aLayer, isGlobal);
12381341 10578 toCreate = Standard_False;
992ed6b3 10579 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10580 }
992ed6b3 10581 else if (anArgCase.IsEqual ("CHANGE")
10582 || anArgCase.IsEqual ("-CHANGE"))
12381341 10583 {
12381341 10584 if (++anArgIt >= theArgsNb)
10585 {
23fe70ec 10586 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10587 return 1;
10588 }
10589
992ed6b3 10590 addLight (aLightNew, aLayer, isGlobal);
10591 aLightNew.Nullify();
12381341 10592 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
10593 Standard_Integer aLightIt = 0;
6a24c6de 10594 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10595 {
10596 if (aLightIt == aLightId)
10597 {
6a24c6de 10598 aLightOld = aLightIter.Value();
12381341 10599 break;
10600 }
10601 }
10602
10603 if (aLightOld.IsNull())
10604 {
23fe70ec 10605 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
12381341 10606 return 1;
10607 }
10608 }
2daa5d95 10609 else if (anArgCase == "-DISPLAY"
10610 || anArgCase == "-DISP"
10611 || anArgCase == "-PRESENTATION"
10612 || anArgCase == "-PRS")
10613 {
10614 if (aLightCurr.IsNull())
10615 {
10616 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10617 return 1;
10618 }
10619
10620 TCollection_AsciiString aLightName = aLightCurr->Name();
10621 if (++anArgIt > theArgsNb
10622 && aLightName.IsEmpty())
10623 {
10624 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10625 return 1;
10626 }
10627 if (anArgIt < theArgsNb)
10628 {
10629 if (theArgVec[anArgIt][0] != '-')
10630 {
10631 aLightName = theArgVec[anArgIt];
10632 aLightCurr->SetName (aLightName);
10633 }
10634 else
10635 {
10636 --anArgIt;
10637 }
10638 }
10639 if (aLightName.IsEmpty())
10640 {
10641 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10642 return 1;
10643 }
10644 ViewerTest::Display (aLightName, new AIS_LightSource (aLightCurr), false);
10645 }
10646 else if (anArgCase == "DEL"
10647 || anArgCase == "DELETE"
10648 || anArgCase == "-DEL"
10649 || anArgCase == "-DELETE"
10650 || anArgCase == "-REMOVE")
12381341 10651 {
10652 Handle(V3d_Light) aLightDel;
10653 if (++anArgIt >= theArgsNb)
10654 {
23fe70ec 10655 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10656 return 1;
10657 }
10658
10659 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
10660 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
10661 Standard_Integer aLightIt = 0;
6a24c6de 10662 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10663 {
6a24c6de 10664 aLightDel = aLightIter.Value();
12381341 10665 if (aLightIt == aLightDelId)
10666 {
10667 break;
10668 }
10669 }
992ed6b3 10670 if (aLightDel.IsNull())
10671 {
10672 continue;
10673 }
10674
10675 TColStd_SequenceOfInteger aLayers;
10676 aViewer->GetAllZLayers (aLayers);
10677 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10678 {
10679 if (aLayeriter.Value() == aLayer
10680 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10681 {
10682 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10683 if (!aSettings.Lights().IsNull())
10684 {
10685 aSettings.Lights()->Remove (aLightDel);
10686 if (aSettings.Lights()->IsEmpty())
10687 {
10688 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10689 }
10690 }
10691 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10692 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10693 {
10694 break;
10695 }
10696 }
10697 }
10698
10699 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10700 {
2daa5d95 10701 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLightDel, false))
10702 {
10703 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10704 GetMapOfAIS().UnBind2 (aLightDel->Name());
10705 }
12381341 10706 aViewer->DelLight (aLightDel);
10707 }
10708 }
10709 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 10710 || anArgCase.IsEqual ("COLOUR")
10711 || anArgCase.IsEqual ("-COLOR")
10712 || anArgCase.IsEqual ("-COLOUR"))
12381341 10713 {
dae2a922 10714 Quantity_Color aColor;
10715 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10716 theArgVec + anArgIt + 1,
10717 aColor);
10718 anArgIt += aNbParsed;
10719 if (aNbParsed == 0
992ed6b3 10720 || aLightCurr.IsNull())
12381341 10721 {
23fe70ec 10722 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10723 return 1;
10724 }
992ed6b3 10725 aLightCurr->SetColor (aColor);
12381341 10726 }
2daa5d95 10727 else if (anArgCase == "POS"
10728 || anArgCase == "POSITION"
10729 || anArgCase == "-POS"
10730 || anArgCase == "-POSITION"
10731 || anArgCase == "-PRSPOSITION"
10732 || anArgCase == "-PRSPOS")
12381341 10733 {
2daa5d95 10734 gp_XYZ aPosXYZ;
992ed6b3 10735 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10736 || !parseXYZ (theArgVec + anArgIt + 1, aPosXYZ)
10737 || aLightCurr.IsNull())
12381341 10738 {
23fe70ec 10739 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10740 return 1;
10741 }
10742
2daa5d95 10743 anArgIt += 3;
10744 if (anArgCase == "-PRSPOSITION"
10745 || anArgCase == "-PRSPOS")
10746 {
10747 aLightCurr->SetDisplayPosition (aPosXYZ);
10748 }
10749 else
10750 {
10751 if (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10752 && aLightCurr->Type() != Graphic3d_TOLS_SPOT)
10753 {
10754 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10755 return 1;
10756 }
10757
10758 aLightCurr->SetPosition (aPosXYZ);
10759 }
12381341 10760 }
10761 else if (anArgCase.IsEqual ("DIR")
992ed6b3 10762 || anArgCase.IsEqual ("DIRECTION")
10763 || anArgCase.IsEqual ("-DIR")
10764 || anArgCase.IsEqual ("-DIRECTION"))
12381341 10765 {
2daa5d95 10766 gp_XYZ aDirXYZ;
992ed6b3 10767 if ((anArgIt + 3) >= theArgsNb
2daa5d95 10768 || !parseXYZ (theArgVec + anArgIt + 1, aDirXYZ)
992ed6b3 10769 || aLightCurr.IsNull()
10770 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
10771 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10772 {
23fe70ec 10773 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10774 return 1;
10775 }
10776
2daa5d95 10777 anArgIt += 3;
10778 aLightCurr->SetDirection (gp_Dir (aDirXYZ));
12381341 10779 }
189f85a3 10780 else if (anArgCase.IsEqual ("SM")
992ed6b3 10781 || anArgCase.IsEqual ("SMOOTHNESS")
10782 || anArgCase.IsEqual ("-SM")
10783 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 10784 {
992ed6b3 10785 if (++anArgIt >= theArgsNb
10786 || aLightCurr.IsNull())
189f85a3 10787 {
23fe70ec 10788 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10789 return 1;
10790 }
10791
992ed6b3 10792 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10793 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 10794 {
10795 aLightCurr->SetIntensity (1.f);
10796 }
992ed6b3 10797 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 10798 {
10799 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10800 }
10801 else
10802 {
10803 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
10804 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10805 }
10806
992ed6b3 10807 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 10808 {
992ed6b3 10809 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 10810 }
992ed6b3 10811 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 10812 {
992ed6b3 10813 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 10814 }
10815 }
10816 else if (anArgCase.IsEqual ("INT")
992ed6b3 10817 || anArgCase.IsEqual ("INTENSITY")
10818 || anArgCase.IsEqual ("-INT")
10819 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 10820 {
992ed6b3 10821 if (++anArgIt >= theArgsNb
10822 || aLightCurr.IsNull())
189f85a3 10823 {
23fe70ec 10824 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 10825 return 1;
10826 }
10827
992ed6b3 10828 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
10829 aLightCurr->SetIntensity (aIntensity);
189f85a3 10830 }
4fe9ad57 10831 else if (anArgCase.IsEqual ("ANG")
992ed6b3 10832 || anArgCase.IsEqual ("ANGLE")
10833 || anArgCase.IsEqual ("-ANG")
10834 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 10835 {
992ed6b3 10836 if (++anArgIt >= theArgsNb
10837 || aLightCurr.IsNull()
10838 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 10839 {
23fe70ec 10840 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4fe9ad57 10841 return 1;
10842 }
992ed6b3 10843 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
2daa5d95 10844 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10845 aLightCurr->SetAngle (anAngle);
4fe9ad57 10846 }
12381341 10847 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 10848 || anArgCase.IsEqual ("CONSTATTENUATION")
10849 || anArgCase.IsEqual ("-CONSTATTEN")
10850 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 10851 {
992ed6b3 10852 if (++anArgIt >= theArgsNb
10853 || aLightCurr.IsNull()
10854 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10855 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10856 {
23fe70ec 10857 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10858 return 1;
10859 }
10860
992ed6b3 10861 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10862 anAtten[0] = Atof (theArgVec[anArgIt]);
10863 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10864 }
10865 else if (anArgCase.IsEqual ("LINATTEN")
10866 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 10867 || anArgCase.IsEqual ("LINEARATTENUATION")
10868 || anArgCase.IsEqual ("-LINATTEN")
10869 || anArgCase.IsEqual ("-LINEARATTEN")
10870 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 10871 {
992ed6b3 10872 if (++anArgIt >= theArgsNb
10873 || aLightCurr.IsNull()
10874 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
10875 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 10876 {
23fe70ec 10877 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10878 return 1;
10879 }
10880
992ed6b3 10881 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
10882 anAtten[1] = Atof (theArgVec[anArgIt]);
10883 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 10884 }
10885 else if (anArgCase.IsEqual ("EXP")
10886 || anArgCase.IsEqual ("EXPONENT")
10887 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 10888 || anArgCase.IsEqual ("SPOTEXPONENT")
10889 || anArgCase.IsEqual ("-EXP")
10890 || anArgCase.IsEqual ("-EXPONENT")
10891 || anArgCase.IsEqual ("-SPOTEXP")
10892 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 10893 {
992ed6b3 10894 if (++anArgIt >= theArgsNb
10895 || aLightCurr.IsNull()
10896 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 10897 {
23fe70ec 10898 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10899 return 1;
10900 }
10901
992ed6b3 10902 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 10903 }
88b312d3 10904 else if (anArgCase.IsEqual("RANGE")
10905 || anArgCase.IsEqual("-RANGE"))
10906 {
10907 if (++anArgIt >= theArgsNb
10908 || aLightCurr.IsNull()
10909 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
10910 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
10911 {
23fe70ec 10912 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
88b312d3 10913 return 1;
10914 }
2daa5d95 10915 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
10916 aLightCurr->SetRange (aRange);
88b312d3 10917 }
12381341 10918 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 10919 || anArgCase.IsEqual ("HEADLIGHT")
10920 || anArgCase.IsEqual ("-HEAD")
10921 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 10922 {
992ed6b3 10923 if (aLightCurr.IsNull()
10924 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 10925 {
23fe70ec 10926 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10927 return 1;
10928 }
10929
992ed6b3 10930 Standard_Boolean isHeadLight = Standard_True;
10931 if (anArgIt + 1 < theArgsNb
dae2a922 10932 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 10933 {
992ed6b3 10934 ++anArgIt;
12381341 10935 }
992ed6b3 10936 aLightCurr->SetHeadlight (isHeadLight);
12381341 10937 }
2daa5d95 10938 else if (anArgCase.IsEqual ("NAME")
10939 || anArgCase.IsEqual ("-NAME"))
10940 {
10941 if ((anArgIt + 1) >= theArgsNb
10942 || aLightCurr.IsNull())
10943 {
10944 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10945 return 1;
10946 }
10947 aName = theArgVec[++anArgIt];
10948 aLightCurr->SetName (aName);
10949 }
10950 else if (anArgCase == "-SHOWZOOMABLE"
10951 || anArgCase == "-PRSZOOMABLE"
10952 || anArgCase == "-ZOOMABLE")
10953 {
10954 if (aLightCurr.IsNull())
10955 {
10956 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10957 return 1;
10958 }
10959
10960 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
10961 {
10962 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10963 aLightSource->SetZoomable (isZoomable);
10964 }
10965 else
10966 {
10967 return 1;
10968 }
10969 }
10970 else if (anArgCase == "-SHOWNAME"
10971 || anArgCase == "-PRSNAME")
10972 {
10973 if (aLightCurr.IsNull())
10974 {
10975 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10976 return 1;
10977 }
10978
10979 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
10980 {
10981 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10982 aLightSource->SetDisplayName (toDisplay);
10983 }
10984 else
10985 {
10986 return 1;
10987 }
10988 }
10989 else if (anArgCase == "-SHOWRANGE"
10990 || anArgCase == "-PRSRANGE")
10991 {
10992 if (aLightCurr.IsNull()
10993 || (aLightCurr->Type() != Graphic3d_TOLS_SPOT
10994 && aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL))
10995 {
10996 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10997 return 1;
10998 }
10999
11000 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11001 {
11002 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11003 aLightSource->SetDisplayRange (toDisplay);
11004 }
11005 else
11006 {
11007 return 1;
11008 }
11009 }
11010 else if (anArgCase == "-SHOWSIZE"
11011 || anArgCase == "-PRSSIZE")
11012 {
11013 Standard_Real aSize = 0.0;
11014 if ((anArgIt + 1) >= theArgsNb
11015 || !Draw::ParseReal (theArgVec[anArgIt + 1], aSize)
11016 || aSize <= 0.0)
11017 {
11018 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11019 return 1;
11020 }
11021
11022 ++anArgIt;
11023 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11024 {
11025 aLightSource->SetSize (aSize);
11026 }
11027 else
11028 {
11029 return 1;
11030 }
11031 }
d84e8669 11032 else if (anArgCase.IsEqual ("-CASTSHADOW")
11033 || anArgCase.IsEqual ("-CASTSHADOWS")
11034 || anArgCase.IsEqual ("-SHADOWS"))
11035 {
11036 if (aLightCurr.IsNull()
11037 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
11038 {
11039 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11040 return 1;
11041 }
11042
11043 bool toCastShadows = true;
11044 if (anArgIt + 1 < theArgsNb
11045 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
11046 {
11047 ++anArgIt;
11048 }
11049 aLightCurr->SetCastShadows (toCastShadows);
11050 }
12381341 11051 else
11052 {
23fe70ec 11053 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
12381341 11054 }
11055 }
11056
992ed6b3 11057 addLight (aLightNew, aLayer, isGlobal);
2daa5d95 11058
11059 struct LightPrsSort
11060 {
11061 bool operator() (const Handle(AIS_LightSource)& theLeft,
11062 const Handle(AIS_LightSource)& theRight)
11063 {
11064 return theLeft->Light()->GetId() < theRight->Light()->GetId();
11065 }
11066 };
11067
11068 AIS_ListOfInteractive aPrsList;
11069 ViewerTest::GetAISContext()->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
11070 if (!aPrsList.IsEmpty())
11071 {
11072 // update light source presentations
11073 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
11074 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
11075 {
11076 if (Handle(AIS_LightSource) aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
11077 {
11078 aLightPrsVec.push_back (aLightPrs);
11079 }
11080 }
11081
11082 // sort objects by id as AIS_InteractiveContext stores them in unordered map
11083 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
11084
11085 Standard_Integer aTopStack = 0;
11086 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
11087 {
11088 Handle(AIS_LightSource) aLightPrs = *aPrsIter;
11089 if (!aLightPrs->TransformPersistence().IsNull()
11090 && aLightPrs->TransformPersistence()->IsTrihedronOr2d())
11091 {
11092 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs->Size();
11093 aLightPrs->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
11094 aTopStack += aPrsSize + aPrsSize / 2;
11095 }
11096 ViewerTest::GetAISContext()->Redisplay (aLightPrs, false);
11097 ViewerTest::GetAISContext()->SetTransformPersistence (aLightPrs, aLightPrs->TransformPersistence());
11098 }
11099 }
12381341 11100 return 0;
11101}
11102
67312b79 11103//===============================================================================================
11104//function : VPBREnvironment
11105//purpose :
11106//===============================================================================================
11107static int VPBREnvironment (Draw_Interpretor&,
11108 Standard_Integer theArgsNb,
11109 const char** theArgVec)
11110{
11111 if (theArgsNb > 2)
11112 {
23fe70ec 11113 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11114 return 1;
11115 }
11116
11117 Handle(V3d_View) aView = ViewerTest::CurrentView();
11118 if (aView.IsNull())
11119 {
23fe70ec 11120 Message::SendFail ("Error: no active viewer");
67312b79 11121 return 1;
11122 }
11123
11124 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11125 anArg.LowerCase();
11126
11127 if (anArg == "-generate"
11128 || anArg == "-gen")
11129 {
11130 aView->GeneratePBREnvironment (Standard_True);
11131 }
11132 else if (anArg == "-clear")
11133 {
11134 aView->ClearPBREnvironment (Standard_True);
11135 }
11136 else
11137 {
23fe70ec 11138 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11139 return 1;
11140 }
11141
11142 return 0;
11143}
11144
15669413 11145//! Read Graphic3d_RenderingParams::PerfCounters flag.
11146static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11147 Standard_Boolean& theToReset,
11148 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11149 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11150{
11151 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11152 TCollection_AsciiString aVal = theValue;
11153 Standard_Boolean toReverse = Standard_False;
11154 if (aVal == "none")
11155 {
11156 theToReset = Standard_True;
11157 return Standard_True;
11158 }
11159 else if (aVal.StartsWith ("-"))
11160 {
11161 toReverse = Standard_True;
11162 aVal = aVal.SubString (2, aVal.Length());
11163 }
11164 else if (aVal.StartsWith ("no"))
11165 {
11166 toReverse = Standard_True;
11167 aVal = aVal.SubString (3, aVal.Length());
11168 }
11169 else if (aVal.StartsWith ("+"))
11170 {
11171 aVal = aVal.SubString (2, aVal.Length());
11172 }
11173 else
11174 {
11175 theToReset = Standard_True;
11176 }
11177
11178 if ( aVal == "fps"
11179 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11180 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11181 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11182 else if (aVal == "structs"
11183 || aVal == "structures"
11184 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11185 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11186 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11187 else if (aVal == "tris"
11188 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11189 else if (aVal == "pnts"
11190 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11191 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11192 else if (aVal == "mem"
11193 || aVal == "gpumem"
11194 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11195 else if (aVal == "skipimmediate"
11196 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11197 else if (aVal == "frametime"
11198 || aVal == "frametimers"
11199 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11200 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11201 else if (aVal == "extended"
11202 || aVal == "verbose"
11203 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11204 else if (aVal == "full"
11205 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11206 else
11207 {
11208 return Standard_False;
11209 }
11210
11211 if (toReverse)
11212 {
11213 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11214 }
11215 else
11216 {
11217 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11218 }
11219 return Standard_True;
11220}
11221
11222//! Read Graphic3d_RenderingParams::PerfCounters flags.
11223static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11224 Graphic3d_RenderingParams::PerfCounters& theFlags)
11225{
11226 TCollection_AsciiString aValue = theValue;
11227 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11228 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11229 Standard_Boolean toReset = Standard_False;
11230 for (;;)
11231 {
11232 Standard_Integer aSplitPos = aValue.Search ("|");
11233 if (aSplitPos <= 0)
11234 {
11235 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11236 {
11237 return Standard_False;
11238 }
11239 if (toReset)
11240 {
11241 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11242 }
11243 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11244 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11245 return Standard_True;
11246 }
11247
11248 if (aSplitPos > 1)
11249 {
11250 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11251 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11252 {
11253 return Standard_False;
11254 }
11255 }
11256 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11257 }
11258}
11259
e276548b 11260//=======================================================================
bc8c79bb 11261//function : VRenderParams
11262//purpose : Enables/disables rendering features
e276548b 11263//=======================================================================
11264
bc8c79bb 11265static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11266 Standard_Integer theArgNb,
11267 const char** theArgVec)
e276548b 11268{
7ae4a307 11269 Handle(V3d_View) aView = ViewerTest::CurrentView();
11270 if (aView.IsNull())
e276548b 11271 {
23fe70ec 11272 Message::SendFail ("Error: no active viewer");
e276548b 11273 return 1;
11274 }
bc8c79bb 11275
11276 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11277 TCollection_AsciiString aCmdName (theArgVec[0]);
11278 aCmdName.LowerCase();
11279 if (aCmdName == "vraytrace")
11280 {
11281 if (theArgNb == 1)
11282 {
11283 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11284 return 0;
11285 }
11286 else if (theArgNb == 2)
11287 {
11288 TCollection_AsciiString aValue (theArgVec[1]);
11289 aValue.LowerCase();
11290 if (aValue == "on"
11291 || aValue == "1")
11292 {
11293 aParams.Method = Graphic3d_RM_RAYTRACING;
11294 aView->Redraw();
11295 return 0;
11296 }
11297 else if (aValue == "off"
11298 || aValue == "0")
11299 {
11300 aParams.Method = Graphic3d_RM_RASTERIZATION;
11301 aView->Redraw();
11302 return 0;
11303 }
11304 else
11305 {
23fe70ec 11306 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11307 return 1;
11308 }
11309 }
11310 else
11311 {
23fe70ec 11312 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11313 return 1;
11314 }
11315 }
bc8c79bb 11316
11317 if (theArgNb < 2)
e276548b 11318 {
bc8c79bb 11319 theDI << "renderMode: ";
11320 switch (aParams.Method)
11321 {
11322 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11323 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11324 }
11325 theDI << "\n";
a1073ae2 11326 theDI << "transparency: ";
11327 switch (aParams.TransparencyMethod)
11328 {
11329 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11330 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11331 << TCollection_AsciiString (aParams.OitDepthFactor); break;
78c4e836 11332 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11333 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
a1073ae2 11334 }
11335 theDI << "\n";
b4327ba8 11336 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11337 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11338 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11339 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11340 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
d84e8669 11341 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11342 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
b4327ba8 11343 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11344 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11345 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11346 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11347 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11348 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11349 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11350 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11351 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11352 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11353 theDI << "shadingModel: ";
11354 switch (aView->ShadingModel())
11355 {
67312b79 11356 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11357 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11358 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11359 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11360 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11361 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11362 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11363 }
37f80e16 11364 theDI << "\n";
15669413 11365 {
11366 theDI << "perfCounters:";
11367 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11368 {
11369 theDI << " fps";
11370 }
11371 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11372 {
11373 theDI << " cpu";
11374 }
11375 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11376 {
11377 theDI << " structs";
11378 }
11379 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11380 {
11381 theDI << " groups";
11382 }
11383 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11384 {
11385 theDI << " arrays";
11386 }
11387 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11388 {
11389 theDI << " tris";
11390 }
b9f43ad1 11391 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11392 {
11393 theDI << " lines";
11394 }
15669413 11395 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11396 {
11397 theDI << " pnts";
11398 }
11399 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11400 {
11401 theDI << " gpumem";
11402 }
5e30547b 11403 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11404 {
11405 theDI << " frameTime";
11406 }
11407 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11408 {
11409 theDI << " skipimmediate";
11410 }
15669413 11411 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11412 {
11413 theDI << " none";
11414 }
11415 theDI << "\n";
11416 }
f88457e6 11417 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11418 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11419 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11420 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11421 "noUpdate") << "\n";
8625ef7e 11422 theDI << "\n";
bc8c79bb 11423 return 0;
e276548b 11424 }
11425
4c7a3fae 11426 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11427 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11428 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11429 {
bc8c79bb 11430 Standard_CString anArg (theArgVec[anArgIter]);
11431 TCollection_AsciiString aFlag (anArg);
11432 aFlag.LowerCase();
8625ef7e 11433 if (anUpdateTool.parseRedrawMode (aFlag))
11434 {
11435 continue;
11436 }
11437 else if (aFlag == "-echo"
11438 || aFlag == "-print")
e276548b 11439 {
bc8c79bb 11440 toPrint = Standard_True;
8625ef7e 11441 anUpdateTool.Invalidate();
e276548b 11442 }
4c7a3fae 11443 else if (aFlag == "-reset")
11444 {
11445 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11446 }
11447 else if (aFlag == "-sync"
11448 && (anArgIter + 1 < theArgNb))
11449 {
11450 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11451 aSyncFlag.LowerCase();
11452 if (aSyncFlag == "default"
11453 || aSyncFlag == "defaults"
11454 || aSyncFlag == "viewer")
11455 {
11456 toSyncDefaults = true;
11457 }
11458 else if (aSyncFlag == "allviews"
11459 || aSyncFlag == "views")
11460 {
11461 toSyncAllViews = true;
11462 }
11463 else
11464 {
11465 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11466 return 1;
11467 }
11468 }
bc8c79bb 11469 else if (aFlag == "-mode"
11470 || aFlag == "-rendermode"
11471 || aFlag == "-render_mode")
e276548b 11472 {
bc8c79bb 11473 if (toPrint)
11474 {
11475 switch (aParams.Method)
11476 {
11477 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11478 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11479 }
11480 continue;
11481 }
e276548b 11482 else
bc8c79bb 11483 {
23fe70ec 11484 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11485 return 1;
11486 }
11487 }
11488 else if (aFlag == "-ray"
11489 || aFlag == "-raytrace")
11490 {
11491 if (toPrint)
11492 {
11493 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11494 continue;
11495 }
11496
4c7a3fae 11497 bool isRayTrace = true;
11498 if (anArgIter + 1 < theArgNb
dae2a922 11499 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11500 {
11501 ++anArgIter;
11502 }
11503 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11504 }
bc8c79bb 11505 else if (aFlag == "-rast"
11506 || aFlag == "-raster"
11507 || aFlag == "-rasterization")
e276548b 11508 {
bc8c79bb 11509 if (toPrint)
11510 {
11511 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11512 continue;
11513 }
11514
4c7a3fae 11515 bool isRaster = true;
11516 if (anArgIter + 1 < theArgNb
dae2a922 11517 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11518 {
11519 ++anArgIter;
11520 }
11521 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11522 }
3c4b62a4 11523 else if (aFlag == "-msaa")
11524 {
11525 if (toPrint)
11526 {
11527 theDI << aParams.NbMsaaSamples << " ";
11528 continue;
11529 }
11530 else if (++anArgIter >= theArgNb)
11531 {
23fe70ec 11532 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11533 return 1;
11534 }
11535
11536 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11537 if (aNbSamples < 0)
11538 {
23fe70ec 11539 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 11540 return 1;
11541 }
11542 else
11543 {
11544 aParams.NbMsaaSamples = aNbSamples;
11545 }
11546 }
2a332745 11547 else if (aFlag == "-linefeather"
11548 || aFlag == "-edgefeather"
11549 || aFlag == "-feather")
11550 {
11551 if (toPrint)
11552 {
11553 theDI << " " << aParams.LineFeather << " ";
11554 continue;
11555 }
11556 else if (++anArgIter >= theArgNb)
11557 {
23fe70ec 11558 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 11559 return 1;
11560 }
11561
11562 TCollection_AsciiString aParam = theArgVec[anArgIter];
11563 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11564 if (aFeather <= 0.0f)
11565 {
23fe70ec 11566 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 11567 return 1;
11568 }
11569 aParams.LineFeather = aFeather;
11570 }
a1073ae2 11571 else if (aFlag == "-oit")
11572 {
11573 if (toPrint)
11574 {
11575 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11576 {
11577 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11578 }
78c4e836 11579 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11580 {
11581 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11582 }
a1073ae2 11583 else
11584 {
11585 theDI << "off" << " ";
11586 }
11587 continue;
11588 }
11589 else if (++anArgIter >= theArgNb)
11590 {
23fe70ec 11591 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11592 return 1;
11593 }
11594
11595 TCollection_AsciiString aParam = theArgVec[anArgIter];
11596 aParam.LowerCase();
78c4e836 11597 if (aParam == "peeling"
11598 || aParam == "peel")
11599 {
11600 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11601 if (anArgIter + 1 < theArgNb
11602 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11603 {
11604 ++anArgIter;
11605 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11606 if (aNbLayers < 2)
11607 {
11608 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11609 return 1;
11610 }
11611 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11612 }
11613 }
11614 else if (aParam == "weighted"
11615 || aParam == "weight")
11616 {
11617 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11618 if (anArgIter + 1 < theArgNb
11619 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11620 {
11621 ++anArgIter;
11622 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11623 if (aWeight < 0.f || aWeight > 1.f)
11624 {
11625 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11626 return 1;
11627 }
11628 aParams.OitDepthFactor = aWeight;
11629 }
11630 }
11631 else if (aParam.IsRealValue())
a1073ae2 11632 {
11633 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11634 if (aWeight < 0.f || aWeight > 1.f)
11635 {
23fe70ec 11636 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 11637 return 1;
11638 }
11639
11640 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11641 aParams.OitDepthFactor = aWeight;
11642 }
11643 else if (aParam == "off")
11644 {
11645 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11646 }
11647 else
11648 {
23fe70ec 11649 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11650 return 1;
11651 }
11652 }
d37aef5c 11653 else if (aFlag == "-fonthinting"
11654 || aFlag == "-fonthint")
11655 {
11656 if (toPrint)
11657 {
11658 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11659 {
11660 theDI << "normal" << " ";
11661 }
11662 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11663 {
11664 theDI << "light" << " ";
11665 }
11666 else
11667 {
11668 theDI << "off" << " ";
11669 }
11670 continue;
11671 }
11672 else if (anArgIter + 1 >= theArgNb)
11673 {
11674 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11675 return 1;
11676 }
11677
11678 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11679 aHintStyle.LowerCase();
11680 if (aHintStyle == "normal"
11681 || aHintStyle == "on"
11682 || aHintStyle == "1")
11683 {
11684 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11685 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11686 }
11687 else if (aHintStyle == "light")
11688 {
11689 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11690 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11691 }
11692 else if (aHintStyle == "no"
11693 || aHintStyle == "off"
11694 || aHintStyle == "0")
11695 {
11696 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11697 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11698 }
11699 else
11700 {
11701 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11702 return 1;
11703 }
11704 }
11705 else if (aFlag == "-fontautohinting"
11706 || aFlag == "-fontautohint")
11707 {
11708 if (toPrint)
11709 {
11710 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11711 {
11712 theDI << "force" << " ";
11713 }
11714 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11715 {
11716 theDI << "disallow" << " ";
11717 }
11718 else
11719 {
11720 theDI << "auto" << " ";
11721 }
11722 continue;
11723 }
11724 else if (anArgIter + 1 >= theArgNb)
11725 {
11726 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11727 return 1;
11728 }
11729
11730 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11731 aHintStyle.LowerCase();
11732 if (aHintStyle == "force")
11733 {
11734 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11735 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11736 }
11737 else if (aHintStyle == "disallow"
11738 || aHintStyle == "no")
11739 {
11740 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11741 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11742 }
11743 else if (aHintStyle == "auto")
11744 {
11745 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11746 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11747 }
11748 else
11749 {
11750 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11751 return 1;
11752 }
11753 }
f88457e6 11754 else if (aFlag == "-depthprepass")
11755 {
11756 if (toPrint)
11757 {
11758 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11759 continue;
11760 }
11761 aParams.ToEnableDepthPrepass = Standard_True;
11762 if (anArgIter + 1 < theArgNb
dae2a922 11763 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 11764 {
11765 ++anArgIter;
11766 }
11767 }
c40eb6b9 11768 else if (aFlag == "-samplealphatocoverage"
11769 || aFlag == "-alphatocoverage")
11770 {
11771 if (toPrint)
11772 {
11773 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11774 continue;
11775 }
11776 aParams.ToEnableAlphaToCoverage = Standard_True;
11777 if (anArgIter + 1 < theArgNb
dae2a922 11778 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 11779 {
11780 ++anArgIter;
11781 }
11782 }
56689b27 11783 else if (aFlag == "-rendscale"
11784 || aFlag == "-renderscale"
11785 || aFlag == "-renderresolutionscale")
11786 {
11787 if (toPrint)
11788 {
11789 theDI << aParams.RenderResolutionScale << " ";
11790 continue;
11791 }
11792 else if (++anArgIter >= theArgNb)
11793 {
23fe70ec 11794 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 11795 return 1;
11796 }
11797
11798 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11799 if (aScale < 0.01)
11800 {
23fe70ec 11801 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 11802 return 1;
11803 }
11804 else
11805 {
11806 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11807 }
11808 }
bc8c79bb 11809 else if (aFlag == "-raydepth"
11810 || aFlag == "-ray_depth")
11811 {
11812 if (toPrint)
11813 {
11814 theDI << aParams.RaytracingDepth << " ";
11815 continue;
11816 }
11817 else if (++anArgIter >= theArgNb)
11818 {
23fe70ec 11819 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11820 return 1;
11821 }
11822
11823 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 11824
11825 // We allow RaytracingDepth be more than 10 in case of GI enabled
11826 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 11827 {
23fe70ec 11828 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 11829 return 1;
11830 }
e276548b 11831 else
bc8c79bb 11832 {
11833 aParams.RaytracingDepth = aDepth;
11834 }
11835 }
11836 else if (aFlag == "-shad"
11837 || aFlag == "-shadows")
11838 {
11839 if (toPrint)
11840 {
11841 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11842 continue;
11843 }
11844
11845 Standard_Boolean toEnable = Standard_True;
11846 if (++anArgIter < theArgNb
dae2a922 11847 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11848 {
11849 --anArgIter;
11850 }
11851 aParams.IsShadowEnabled = toEnable;
11852 }
d84e8669 11853 else if (aFlag == "-shadowmapresolution"
11854 || aFlag == "-shadowmap")
11855 {
11856 if (toPrint)
11857 {
11858 theDI << aParams.ShadowMapResolution << " ";
11859 continue;
11860 }
11861 else if (++anArgIter >= theArgNb)
11862 {
11863 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11864 return 1;
11865 }
11866
11867 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11868 }
11869 else if (aFlag == "-shadowmapbias")
11870 {
11871 if (toPrint)
11872 {
11873 theDI << aParams.ShadowMapBias << " ";
11874 continue;
11875 }
11876 else if (++anArgIter >= theArgNb)
11877 {
11878 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11879 return 1;
11880 }
11881
11882 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11883 }
bc8c79bb 11884 else if (aFlag == "-refl"
11885 || aFlag == "-reflections")
11886 {
11887 if (toPrint)
11888 {
11889 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11890 continue;
11891 }
11892
11893 Standard_Boolean toEnable = Standard_True;
11894 if (++anArgIter < theArgNb
dae2a922 11895 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11896 {
11897 --anArgIter;
11898 }
11899 aParams.IsReflectionEnabled = toEnable;
11900 }
11901 else if (aFlag == "-fsaa")
11902 {
11903 if (toPrint)
11904 {
11905 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11906 continue;
11907 }
11908
11909 Standard_Boolean toEnable = Standard_True;
11910 if (++anArgIter < theArgNb
dae2a922 11911 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11912 {
11913 --anArgIter;
11914 }
11915 aParams.IsAntialiasingEnabled = toEnable;
11916 }
11917 else if (aFlag == "-gleam")
11918 {
11919 if (toPrint)
11920 {
11921 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11922 continue;
11923 }
11924
11925 Standard_Boolean toEnable = Standard_True;
11926 if (++anArgIter < theArgNb
dae2a922 11927 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11928 {
11929 --anArgIter;
11930 }
11931 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 11932 }
189f85a3 11933 else if (aFlag == "-gi")
11934 {
11935 if (toPrint)
11936 {
11937 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11938 continue;
11939 }
11940
11941 Standard_Boolean toEnable = Standard_True;
11942 if (++anArgIter < theArgNb
dae2a922 11943 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 11944 {
11945 --anArgIter;
11946 }
11947 aParams.IsGlobalIlluminationEnabled = toEnable;
11948 if (!toEnable)
11949 {
11950 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11951 }
11952 }
8c820969 11953 else if (aFlag == "-blockedrng"
11954 || aFlag == "-brng")
11955 {
11956 if (toPrint)
11957 {
11958 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11959 continue;
11960 }
11961
11962 Standard_Boolean toEnable = Standard_True;
11963 if (++anArgIter < theArgNb
dae2a922 11964 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 11965 {
11966 --anArgIter;
11967 }
11968 aParams.CoherentPathTracingMode = toEnable;
11969 }
b09447ed 11970 else if (aFlag == "-maxrad")
11971 {
11972 if (toPrint)
11973 {
11974 theDI << aParams.RadianceClampingValue << " ";
11975 continue;
11976 }
11977 else if (++anArgIter >= theArgNb)
11978 {
23fe70ec 11979 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11980 return 1;
11981 }
11982
11983 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
d45edf24 11984 if (!aMaxRadStr.IsRealValue (Standard_True))
b09447ed 11985 {
23fe70ec 11986 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11987 return 1;
11988 }
11989
11990 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11991 if (aMaxRadiance <= 0.0)
11992 {
23fe70ec 11993 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 11994 return 1;
11995 }
11996 else
11997 {
11998 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11999 }
12000 }
3a9b5dc8 12001 else if (aFlag == "-iss")
12002 {
12003 if (toPrint)
12004 {
12005 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
12006 continue;
12007 }
12008
12009 Standard_Boolean toEnable = Standard_True;
12010 if (++anArgIter < theArgNb
dae2a922 12011 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12012 {
12013 --anArgIter;
12014 }
12015 aParams.AdaptiveScreenSampling = toEnable;
12016 }
e084dbbc 12017 else if (aFlag == "-issatomic")
12018 {
12019 if (toPrint)
12020 {
12021 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12022 continue;
12023 }
12024
12025 Standard_Boolean toEnable = Standard_True;
12026 if (++anArgIter < theArgNb
dae2a922 12027 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 12028 {
12029 --anArgIter;
12030 }
12031 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12032 }
3a9b5dc8 12033 else if (aFlag == "-issd")
12034 {
12035 if (toPrint)
12036 {
12037 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12038 continue;
12039 }
12040
12041 Standard_Boolean toEnable = Standard_True;
12042 if (++anArgIter < theArgNb
dae2a922 12043 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12044 {
12045 --anArgIter;
12046 }
12047 aParams.ShowSamplingTiles = toEnable;
12048 }
66d1cdc6 12049 else if (aFlag == "-tilesize")
12050 {
12051 if (toPrint)
12052 {
12053 theDI << aParams.RayTracingTileSize << " ";
12054 continue;
12055 }
12056 else if (++anArgIter >= theArgNb)
12057 {
23fe70ec 12058 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 12059 return 1;
12060 }
12061
12062 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12063 if (aTileSize < 1)
12064 {
23fe70ec 12065 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 12066 return 1;
12067 }
12068 aParams.RayTracingTileSize = aTileSize;
12069 }
4eaaf9d8 12070 else if (aFlag == "-nbtiles")
12071 {
12072 if (toPrint)
12073 {
12074 theDI << aParams.NbRayTracingTiles << " ";
12075 continue;
12076 }
12077 else if (++anArgIter >= theArgNb)
12078 {
23fe70ec 12079 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 12080 return 1;
12081 }
12082
12083 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12084 if (aNbTiles < -1)
4eaaf9d8 12085 {
23fe70ec 12086 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 12087 return 1;
12088 }
66d1cdc6 12089 else if (aNbTiles > 0
12090 && (aNbTiles < 64
12091 || aNbTiles > 1024))
4eaaf9d8 12092 {
23fe70ec 12093 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 12094 }
66d1cdc6 12095 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 12096 }
189f85a3 12097 else if (aFlag == "-env")
12098 {
12099 if (toPrint)
12100 {
12101 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12102 continue;
12103 }
12104
12105 Standard_Boolean toEnable = Standard_True;
12106 if (++anArgIter < theArgNb
dae2a922 12107 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12108 {
12109 --anArgIter;
12110 }
12111 aParams.UseEnvironmentMapBackground = toEnable;
12112 }
78607702 12113 else if (aFlag == "-ignorenormalmap")
12114 {
12115 if (toPrint)
12116 {
12117 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12118 continue;
12119 }
12120
12121 Standard_Boolean toEnable = Standard_True;
12122 if (++anArgIter < theArgNb
dae2a922 12123 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12124 {
12125 --anArgIter;
12126 }
12127 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12128 }
b4327ba8 12129 else if (aFlag == "-twoside")
12130 {
12131 if (toPrint)
12132 {
12133 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12134 continue;
12135 }
12136
12137 Standard_Boolean toEnable = Standard_True;
12138 if (++anArgIter < theArgNb
dae2a922 12139 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12140 {
12141 --anArgIter;
12142 }
12143 aParams.TwoSidedBsdfModels = toEnable;
12144 }
8625ef7e 12145 else if (aFlag == "-shademodel"
12146 || aFlag == "-shadingmodel"
12147 || aFlag == "-shading")
12148 {
12149 if (toPrint)
12150 {
12151 switch (aView->ShadingModel())
12152 {
67312b79 12153 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12154 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12155 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12156 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12157 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12158 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12159 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12160 }
12161 continue;
12162 }
12163
12164 if (++anArgIter >= theArgNb)
12165 {
23fe70ec 12166 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12167 }
12168
dc89236f 12169 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12170 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12171 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12172 {
dc89236f 12173 aView->SetShadingModel (aModel);
8625ef7e 12174 }
12175 else
12176 {
23fe70ec 12177 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12178 return 1;
12179 }
12180 }
67312b79 12181 else if (aFlag == "-pbrenvpow2size"
12182 || aFlag == "-pbrenvp2s"
12183 || aFlag == "-pep2s")
12184 {
12185 if (++anArgIter >= theArgNb)
12186 {
23fe70ec 12187 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12188 return 1;
12189 }
12190
12191 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12192 if (aPbrEnvPow2Size < 1)
12193 {
23fe70ec 12194 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12195 return 1;
12196 }
12197 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12198 }
12199 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12200 || aFlag == "-pbrenvspecmapnblevels"
12201 || aFlag == "-pbrenvspecmaplevels"
12202 || aFlag == "-pbrenvsmln"
12203 || aFlag == "-pesmln")
12204 {
12205 if (++anArgIter >= theArgNb)
12206 {
23fe70ec 12207 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12208 return 1;
12209 }
12210
12211 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12212 if (aPbrEnvSpecMapNbLevels < 2)
12213 {
23fe70ec 12214 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12215 return 1;
12216 }
12217 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12218 }
12219 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12220 || aFlag == "-pbrenvbakingdiffsamples"
12221 || aFlag == "-pbrenvbdsn")
12222 {
12223 if (++anArgIter >= theArgNb)
12224 {
23fe70ec 12225 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12226 return 1;
12227 }
12228
12229 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12230 if (aPbrEnvBakingDiffNbSamples < 1)
12231 {
4551e1be 12232 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12233 return 1;
12234 }
12235 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12236 }
12237 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12238 || aFlag == "-pbrenvbakingspecsamples"
12239 || aFlag == "-pbrenvbssn")
12240 {
12241 if (++anArgIter >= theArgNb)
12242 {
23fe70ec 12243 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12244 return 1;
12245 }
12246
12247 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12248 if (aPbrEnvBakingSpecNbSamples < 1)
12249 {
4551e1be 12250 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12251 return 1;
12252 }
12253 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12254 }
12255 else if (aFlag == "-pbrenvbakingprobability"
12256 || aFlag == "-pbrenvbp")
12257 {
12258 if (++anArgIter >= theArgNb)
12259 {
23fe70ec 12260 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12261 return 1;
12262 }
12263 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12264 if (aPbrEnvBakingProbability < 0.f
12265 || aPbrEnvBakingProbability > 1.f)
12266 {
4551e1be 12267 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
67312b79 12268 return 1;
12269 }
12270 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12271 }
4b1c8733 12272 else if (aFlag == "-resolution")
12273 {
12274 if (++anArgIter >= theArgNb)
12275 {
23fe70ec 12276 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12277 return 1;
12278 }
12279
12280 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12281 if (aResolution.IsIntegerValue())
12282 {
12283 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12284 }
12285 else
12286 {
23fe70ec 12287 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12288 return 1;
12289 }
12290 }
d877e610 12291 else if (aFlag == "-rebuildglsl"
12292 || aFlag == "-rebuild")
12293 {
12294 if (toPrint)
12295 {
12296 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12297 continue;
12298 }
12299
12300 Standard_Boolean toEnable = Standard_True;
12301 if (++anArgIter < theArgNb
dae2a922 12302 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12303 {
12304 --anArgIter;
12305 }
12306 aParams.RebuildRayTracingShaders = toEnable;
12307 }
b27ab03d 12308 else if (aFlag == "-focal")
12309 {
12310 if (++anArgIter >= theArgNb)
12311 {
23fe70ec 12312 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12313 return 1;
12314 }
12315
12316 TCollection_AsciiString aParam (theArgVec[anArgIter]);
d45edf24 12317 if (aParam.IsRealValue (Standard_True))
b27ab03d 12318 {
12319 float aFocalDist = static_cast<float> (aParam.RealValue());
12320 if (aFocalDist < 0)
12321 {
23fe70ec 12322 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12323 return 1;
12324 }
12325 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12326 }
12327 else
12328 {
23fe70ec 12329 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12330 return 1;
12331 }
12332 }
12333 else if (aFlag == "-aperture")
12334 {
12335 if (++anArgIter >= theArgNb)
12336 {
23fe70ec 12337 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12338 return 1;
12339 }
12340
12341 TCollection_AsciiString aParam(theArgVec[anArgIter]);
d45edf24 12342 if (aParam.IsRealValue (Standard_True))
b27ab03d 12343 {
12344 float aApertureSize = static_cast<float> (aParam.RealValue());
12345 if (aApertureSize < 0)
12346 {
23fe70ec 12347 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12348 return 1;
12349 }
12350 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12351 }
12352 else
12353 {
23fe70ec 12354 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12355 return 1;
12356 }
12357 }
eb85ed36 12358 else if (aFlag == "-exposure")
12359 {
12360 if (++anArgIter >= theArgNb)
12361 {
23fe70ec 12362 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12363 return 1;
12364 }
12365
12366 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
d45edf24 12367 if (anExposure.IsRealValue (Standard_True))
eb85ed36 12368 {
12369 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12370 }
12371 else
12372 {
23fe70ec 12373 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12374 return 1;
12375 }
12376 }
12377 else if (aFlag == "-whitepoint")
12378 {
12379 if (++anArgIter >= theArgNb)
12380 {
23fe70ec 12381 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12382 return 1;
12383 }
12384
12385 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
d45edf24 12386 if (aWhitePoint.IsRealValue (Standard_True))
eb85ed36 12387 {
12388 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12389 }
12390 else
12391 {
23fe70ec 12392 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12393 return 1;
12394 }
12395 }
12396 else if (aFlag == "-tonemapping")
12397 {
12398 if (++anArgIter >= theArgNb)
12399 {
23fe70ec 12400 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12401 return 1;
12402 }
12403
12404 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12405 aMode.LowerCase();
12406
12407 if (aMode == "disabled")
12408 {
12409 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12410 }
12411 else if (aMode == "filmic")
12412 {
12413 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12414 }
12415 else
12416 {
23fe70ec 12417 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12418 return 1;
12419 }
12420 }
15669413 12421 else if (aFlag == "-performancestats"
12422 || aFlag == "-performancecounters"
12423 || aFlag == "-perfstats"
12424 || aFlag == "-perfcounters"
12425 || aFlag == "-stats")
12426 {
12427 if (++anArgIter >= theArgNb)
12428 {
23fe70ec 12429 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12430 return 1;
12431 }
12432
12433 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12434 aFlagsStr.LowerCase();
12435 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12436 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12437 {
23fe70ec 12438 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12439 return 1;
12440 }
12441 aView->ChangeRenderingParams().CollectedStats = aFlags;
12442 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12443 }
12444 else if (aFlag == "-perfupdateinterval"
12445 || aFlag == "-statsupdateinterval")
12446 {
12447 if (++anArgIter >= theArgNb)
12448 {
23fe70ec 12449 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12450 return 1;
12451 }
12452 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12453 }
5e30547b 12454 else if (aFlag == "-perfchart"
12455 || aFlag == "-statschart")
12456 {
12457 if (++anArgIter >= theArgNb)
12458 {
23fe70ec 12459 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12460 return 1;
12461 }
12462 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12463 }
12464 else if (aFlag == "-perfchartmax"
12465 || aFlag == "-statschartmax")
12466 {
12467 if (++anArgIter >= theArgNb)
12468 {
23fe70ec 12469 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12470 return 1;
12471 }
12472 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12473 }
0e3025bc 12474 else if (aFlag == "-frustumculling"
12475 || aFlag == "-culling")
12476 {
12477 if (toPrint)
12478 {
12479 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12480 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12481 "noUpdate") << " ";
12482 continue;
12483 }
12484
12485 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12486 if (++anArgIter < theArgNb)
12487 {
12488 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12489 aStateStr.LowerCase();
12490 bool toEnable = true;
dae2a922 12491 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12492 {
12493 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12494 }
12495 else if (aStateStr == "noupdate"
12496 || aStateStr == "freeze")
12497 {
12498 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12499 }
12500 else
12501 {
12502 --anArgIter;
12503 }
12504 }
12505 aParams.FrustumCullingState = aState;
12506 }
e276548b 12507 else
12508 {
23fe70ec 12509 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12510 return 1;
e276548b 12511 }
12512 }
189f85a3 12513
4c7a3fae 12514 // set current view parameters as defaults
12515 if (toSyncDefaults)
12516 {
12517 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12518 }
12519 if (toSyncAllViews)
12520 {
12521 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12522 {
12523 aViewIter.Value()->ChangeRenderingParams() = aParams;
12524 }
12525 }
189f85a3 12526 return 0;
12527}
12528
79b544e6 12529//=======================================================================
12530//function : searchInfo
12531//purpose :
12532//=======================================================================
12533inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12534 const TCollection_AsciiString& theKey)
12535{
12536 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12537 {
12538 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12539 {
12540 return anIter.Value();
12541 }
12542 }
12543 return TCollection_AsciiString();
12544}
12545
12546//=======================================================================
12547//function : VStatProfiler
12548//purpose :
12549//=======================================================================
12550static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12551 Standard_Integer theArgNb,
12552 const char** theArgVec)
12553{
12554 Handle(V3d_View) aView = ViewerTest::CurrentView();
12555 if (aView.IsNull())
12556 {
23fe70ec 12557 Message::SendFail ("Error: no active viewer");
79b544e6 12558 return 1;
12559 }
12560
12561 Standard_Boolean toRedraw = Standard_True;
12562 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12563 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12564 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12565 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12566 {
12567 Standard_CString anArg (theArgVec[anArgIter]);
12568 TCollection_AsciiString aFlag (anArg);
12569 aFlag.LowerCase();
12570 if (aFlag == "-noredraw")
12571 {
12572 toRedraw = Standard_False;
12573 }
12574 else
12575 {
12576 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12577 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12578 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12579 else if (aFlag == "alllayers"
12580 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12581 else if (aFlag == "allstructs"
a2803f37 12582 || aFlag == "allstructures"
12583 || aFlag == "structs"
12584 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12585 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12586 else if (aFlag == "allarrays"
12587 || aFlag == "fillarrays"
12588 || aFlag == "linearrays"
12589 || aFlag == "pointarrays"
12590 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12591 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12592 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12593 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12594 else if (aFlag == "geommem"
12595 || aFlag == "texturemem"
12596 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12597 else if (aFlag == "elapsedframe"
12598 || aFlag == "cpuframeaverage"
12599 || aFlag == "cpupickingaverage"
12600 || aFlag == "cpucullingaverage"
12601 || aFlag == "cpudynaverage"
12602 || aFlag == "cpuframemax"
12603 || aFlag == "cpupickingmax"
12604 || aFlag == "cpucullingmax"
12605 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12606 else
12607 {
23fe70ec 12608 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12609 continue;
12610 }
12611
12612 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12613 }
12614 }
12615
12616 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12617 {
12618 aView->ChangeRenderingParams().CollectedStats =
12619 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12620
12621 if (toRedraw)
12622 {
12623 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12624 aView->Redraw();
12625 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12626 }
12627
12628 TColStd_IndexedDataMapOfStringString aDict;
12629 aView->StatisticInformation (aDict);
12630
12631 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12632
12633 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12634 {
12635 Standard_CString anArg(theArgVec[anArgIter]);
12636 TCollection_AsciiString aFlag(anArg);
12637 aFlag.LowerCase();
12638 if (aFlag == "fps")
12639 {
12640 theDI << searchInfo (aDict, "FPS") << " ";
12641 }
12642 else if (aFlag == "cpu")
12643 {
12644 theDI << searchInfo (aDict, "CPU FPS") << " ";
12645 }
12646 else if (aFlag == "alllayers")
12647 {
12648 theDI << searchInfo (aDict, "Layers") << " ";
12649 }
12650 else if (aFlag == "layers")
12651 {
12652 theDI << searchInfo (aDict, "Rendered layers") << " ";
12653 }
a2803f37 12654 else if (aFlag == "allstructs"
12655 || aFlag == "allstructures")
79b544e6 12656 {
12657 theDI << searchInfo (aDict, "Structs") << " ";
12658 }
a2803f37 12659 else if (aFlag == "structs"
12660 || aFlag == "structures")
79b544e6 12661 {
a2803f37 12662 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12663 if (aRend.IsEmpty()) // all structures rendered
12664 {
12665 aRend = searchInfo (aDict, "Structs");
12666 }
12667 theDI << aRend << " ";
79b544e6 12668 }
12669 else if (aFlag == "groups")
12670 {
12671 theDI << searchInfo (aDict, "Rendered groups") << " ";
12672 }
12673 else if (aFlag == "allarrays")
12674 {
12675 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12676 }
12677 else if (aFlag == "fillarrays")
12678 {
12679 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12680 }
12681 else if (aFlag == "linearrays")
12682 {
12683 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12684 }
12685 else if (aFlag == "pointarrays")
12686 {
12687 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12688 }
12689 else if (aFlag == "textarrays")
12690 {
12691 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12692 }
12693 else if (aFlag == "triangles")
12694 {
12695 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12696 }
12697 else if (aFlag == "points")
12698 {
12699 theDI << searchInfo (aDict, "Rendered points") << " ";
12700 }
12701 else if (aFlag == "geommem")
12702 {
12703 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12704 }
12705 else if (aFlag == "texturemem")
12706 {
12707 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12708 }
12709 else if (aFlag == "framemem")
12710 {
12711 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12712 }
12713 else if (aFlag == "elapsedframe")
12714 {
12715 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12716 }
12717 else if (aFlag == "cpuframe_average")
12718 {
12719 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12720 }
12721 else if (aFlag == "cpupicking_average")
12722 {
12723 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12724 }
12725 else if (aFlag == "cpuculling_average")
12726 {
12727 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12728 }
12729 else if (aFlag == "cpudyn_average")
12730 {
12731 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12732 }
12733 else if (aFlag == "cpuframe_max")
12734 {
12735 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12736 }
12737 else if (aFlag == "cpupicking_max")
12738 {
12739 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12740 }
12741 else if (aFlag == "cpuculling_max")
12742 {
12743 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12744 }
12745 else if (aFlag == "cpudyn_max")
12746 {
12747 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12748 }
12749 }
12750 }
12751 else
12752 {
12753 if (toRedraw)
12754 {
12755 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12756 aView->Redraw();
12757 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12758 }
12759 theDI << "Statistic info:\n" << aView->StatisticInformation();
12760 }
12761 return 0;
12762}
12763
0717ddc1 12764//=======================================================================
12765//function : VXRotate
12766//purpose :
12767//=======================================================================
12768static Standard_Integer VXRotate (Draw_Interpretor& di,
12769 Standard_Integer argc,
12770 const char ** argv)
12771{
12772 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12773 if (aContext.IsNull())
12774 {
586db386 12775 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12776 return 1;
12777 }
8693dfd0 12778
0717ddc1 12779 if (argc != 3)
12780 {
586db386 12781 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12782 return 1;
12783 }
12784
12785 TCollection_AsciiString aName (argv[1]);
12786 Standard_Real anAngle = Draw::Atof (argv[2]);
12787
12788 // find object
12789 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12790 Handle(AIS_InteractiveObject) anIObj;
8f521168 12791 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12792 {
586db386 12793 di << "Use 'vdisplay' before\n";
0717ddc1 12794 return 1;
12795 }
0717ddc1 12796
8f521168 12797 gp_Trsf aTransform;
12798 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12799 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12800
8f521168 12801 aContext->SetLocation (anIObj, aTransform);
12802 aContext->UpdateCurrentViewer();
0717ddc1 12803 return 0;
12804}
12805
ff6122e0 12806namespace
12807{
12808 //! Structure for setting AIS_Manipulator::SetPart() property.
12809 struct ManipAxisModeOnOff
12810 {
12811 Standard_Integer Axis;
12812 AIS_ManipulatorMode Mode;
12813 Standard_Boolean ToEnable;
12814
12815 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12816 };
12817
12818 enum ManipAjustPosition
12819 {
12820 ManipAjustPosition_Off,
12821 ManipAjustPosition_Center,
12822 ManipAjustPosition_Location,
12823 ManipAjustPosition_ShapeLocation,
12824 };
12825}
12826
625e1958 12827//===============================================================================================
12828//function : VManipulator
12829//purpose :
12830//===============================================================================================
12831static int VManipulator (Draw_Interpretor& theDi,
12832 Standard_Integer theArgsNb,
12833 const char** theArgVec)
12834{
bbf3fcde 12835 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 12836 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 12837 if (aCurrentView.IsNull()
625e1958 12838 || aViewer.IsNull())
12839 {
23fe70ec 12840 Message::SendFail ("Error: no active viewer");
625e1958 12841 return 1;
12842 }
12843
12844 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12845 Standard_Integer anArgIter = 1;
ff6122e0 12846 Handle(AIS_Manipulator) aManipulator;
12847 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12848 TCollection_AsciiString aName;
12849 // parameters
12850 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12851 Standard_Real aGap = -1.0, aSize = -1.0;
12852 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12853 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12854 //
12855 bool toDetach = false;
12856 AIS_Manipulator::OptionsForAttach anAttachOptions;
12857 Handle(AIS_InteractiveObject) anAttachObject;
12858 Handle(V3d_View) aViewAffinity;
12859 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12860 //
12861 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12862 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12863 Standard_Integer toStopMouseTransform = -1;
12864 // explicit transformation
12865 gp_Trsf aTrsf;
12866 gp_XYZ aTmpXYZ;
12867 Standard_Real aTmpReal = 0.0;
12868 gp_XYZ aRotPnt, aRotAxis;
625e1958 12869 for (; anArgIter < theArgsNb; ++anArgIter)
12870 {
ff6122e0 12871 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12872 anArg.LowerCase();
12873 if (anUpdateTool.parseRedrawMode (anArg))
12874 {
12875 continue;
12876 }
12877 else if (anArg == "-help")
12878 {
12879 theDi.PrintHelp (theArgVec[0]);
12880 return 0;
12881 }
12882 //
12883 else if (anArg == "-autoactivate"
12884 || anArg == "-noautoactivate")
12885 {
12886 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12887 }
12888 else if (anArg == "-followtranslation"
12889 || anArg == "-nofollowtranslation")
12890 {
12891 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12892 }
12893 else if (anArg == "-followrotation"
12894 || anArg == "-nofollowrotation")
12895 {
12896 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12897 }
12898 else if (anArg == "-followdragging"
12899 || anArg == "-nofollowdragging")
12900 {
12901 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12902 }
12903 else if (anArg == "-gap"
12904 && anArgIter + 1 < theArgsNb
12905 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12906 && aGap >= 0.0)
12907 {
12908 ++anArgIter;
12909 }
12910 else if (anArg == "-size"
12911 && anArgIter + 1 < theArgsNb
12912 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12913 && aSize > 0.0)
12914 {
12915 ++anArgIter;
12916 }
12917 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12918 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12919 {
12920 ManipAxisModeOnOff aPart;
12921 Standard_Integer aMode = 0;
12922 if (anArg == "-part")
12923 {
12924 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12925 || aPart.Axis < 0 || aPart.Axis > 3)
12926 {
12927 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12928 return 1;
12929 }
12930 }
12931 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12932 || aMode < 1 || aMode > 4)
12933 {
12934 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12935 return 1;
12936 }
12937 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12938 {
12939 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12940 return 1;
12941 }
12942 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12943 aParts.Append (aPart);
12944 }
12945 else if (anArg == "-pos"
12946 && anArgIter + 3 < theArgsNb
12947 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12948 {
12949 anArgIter += 3;
12950 if (anArgIter + 3 < theArgsNb
12951 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12952 && aVDir.Modulus() > Precision::Confusion())
12953 {
12954 anArgIter += 3;
12955 }
12956 if (anArgIter + 3 < theArgsNb
12957 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12958 && anXDir.Modulus() > Precision::Confusion())
12959 {
12960 anArgIter += 3;
12961 }
12962 }
12963 else if (anArg == "-zoomable"
12964 || anArg == "-notzoomable")
12965 {
12966 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12967 }
12968 //
12969 else if (anArg == "-adjustposition"
12970 || anArg == "-noadjustposition")
12971 {
12972 anAttachPos = ManipAjustPosition_Center;
12973 if (anArgIter + 1 < theArgsNb)
12974 {
12975 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12976 aPosName.LowerCase();
12977 if (aPosName == "0")
12978 {
12979 anAttachPos = ManipAjustPosition_Off;
12980 }
12981 else if (aPosName == "1"
12982 || aPosName == "center")
12983 {
12984 anAttachPos = ManipAjustPosition_Center;
12985 }
12986 else if (aPosName == "transformation"
12987 || aPosName == "trsf"
12988 || aPosName == "location"
12989 || aPosName == "loc")
12990 {
12991 anAttachPos = ManipAjustPosition_Location;
12992 }
12993 else if (aPosName == "shapelocation"
12994 || aPosName == "shapeloc")
12995 {
12996 anAttachPos = ManipAjustPosition_ShapeLocation;
12997 }
12998 else
12999 {
13000 --anArgIter;
13001 }
13002 }
13003 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
13004 }
13005 else if (anArg == "-adjustsize"
13006 || anArg == "-noadjustsize")
13007 {
13008 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13009 }
13010 else if (anArg == "-enablemodes"
13011 || anArg == "-enablemodes")
13012 {
13013 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13014 }
13015 //
13016 else if (anArg == "-starttransform"
13017 && anArgIter + 2 < theArgsNb
13018 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
13019 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
13020 {
13021 anArgIter += 2;
13022 }
13023 else if (anArg == "-transform"
13024 && anArgIter + 2 < theArgsNb
13025 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
13026 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
13027 {
13028 anArgIter += 2;
13029 }
13030 else if (anArg == "-stoptransform")
13031 {
13032 toStopMouseTransform = 1;
13033 if (anArgIter + 1 < theArgsNb
13034 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
13035 {
13036 ++anArgIter;
13037 toStopMouseTransform = 0;
13038 }
13039 }
13040 //
13041 else if (anArg == "-move"
13042 && anArgIter + 3 < theArgsNb
13043 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
13044 {
13045 anArgIter += 3;
13046 aTrsf.SetTranslationPart (aTmpXYZ);
13047 }
13048 else if (anArg == "-scale"
13049 && anArgIter + 1 < theArgsNb
13050 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
13051 {
13052 ++anArgIter;
13053 aTrsf.SetScale (gp_Pnt(), aTmpReal);
13054 }
13055 else if (anArg == "-rotate"
13056 && anArgIter + 7 < theArgsNb
13057 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
13058 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
13059 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
13060 {
13061 anArgIter += 7;
13062 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
13063 }
13064 //
13065 else if (anArg == "-detach")
13066 {
13067 toDetach = true;
13068 }
13069 else if (anArg == "-attach"
13070 && anArgIter + 1 < theArgsNb)
13071 {
13072 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
13073 if (!aMapAIS.Find2 (anObjName, anAttachObject))
13074 {
13075 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
13076 return 1;
13077 }
625e1958 13078
ff6122e0 13079 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
13080 {
13081 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13082 if (!aManip.IsNull()
13083 && aManip->IsAttached()
13084 && aManip->Object() == anAttachObject)
13085 {
13086 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
13087 return 1;
13088 }
13089 }
13090 }
13091 else if (anArg == "-view"
13092 && anArgIter + 1 < theArgsNb
13093 && aViewAffinity.IsNull())
13094 {
13095 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
13096 if (aViewString == "active")
13097 {
13098 aViewAffinity = ViewerTest::CurrentView();
13099 }
13100 else // Check view name
13101 {
13102 ViewerTest_Names aViewNames (aViewString);
13103 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13104 {
13105 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13106 return 1;
13107 }
13108 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13109 if (aViewAffinity.IsNull())
13110 {
13111 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13112 return 1;
13113 }
13114 }
13115 }
13116 else if (aName.IsEmpty())
13117 {
13118 aName = theArgVec[anArgIter];
13119 if (!aMapAIS.IsBound2 (aName))
13120 {
13121 aManipulator = new AIS_Manipulator();
13122 aManipulator->SetModeActivationOnDetection (true);
13123 aMapAIS.Bind (aManipulator, aName);
13124 }
13125 else
13126 {
13127 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13128 if (aManipulator.IsNull())
13129 {
13130 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13131 return 1;
13132 }
13133 }
13134 }
13135 else
13136 {
13137 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13138 }
625e1958 13139 }
13140
625e1958 13141 if (aName.IsEmpty())
13142 {
23fe70ec 13143 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 13144 return 1;
13145 }
ff6122e0 13146 if (!toDetach
13147 && aManipulator.IsNull())
625e1958 13148 {
8b037fe4 13149 aManipulator = new AIS_Manipulator();
49582f9d 13150 aManipulator->SetModeActivationOnDetection (true);
625e1958 13151 aMapAIS.Bind (aManipulator, aName);
13152 }
625e1958 13153
13154 // -----------------------------------------
13155 // change properties of manipulator instance
13156 // -----------------------------------------
13157
ff6122e0 13158 if (toAutoActivate != -1)
625e1958 13159 {
ff6122e0 13160 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
625e1958 13161 }
ff6122e0 13162 if (toFollowTranslation != -1)
625e1958 13163 {
ff6122e0 13164 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
625e1958 13165 }
ff6122e0 13166 if (toFollowRotation != -1)
625e1958 13167 {
ff6122e0 13168 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
625e1958 13169 }
ff6122e0 13170 if (toFollowDragging != -1)
f522ce50 13171 {
ff6122e0 13172 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
f522ce50 13173 }
ff6122e0 13174 if (aGap >= 0.0f)
625e1958 13175 {
ff6122e0 13176 aManipulator->SetGap ((float )aGap);
625e1958 13177 }
ff6122e0 13178
13179 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
625e1958 13180 {
ff6122e0 13181 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13182 if (aPart.Axis == -1)
625e1958 13183 {
ff6122e0 13184 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
625e1958 13185 }
ff6122e0 13186 else
84b904bc 13187 {
ff6122e0 13188 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
84b904bc 13189 }
84b904bc 13190 }
625e1958 13191
ff6122e0 13192 if (aSize > 0.0)
625e1958 13193 {
ff6122e0 13194 aManipulator->SetSize ((float )aSize);
625e1958 13195 }
ff6122e0 13196 if (isZoomable != -1)
625e1958 13197 {
ff6122e0 13198 aManipulator->SetZoomPersistence (isZoomable == 0);
625e1958 13199
13200 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13201 {
13202 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13203 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13204 }
13205 }
13206
ff6122e0 13207 // ----------------------------------
13208 // detach existing manipulator object
13209 // ----------------------------------
13210
13211 if (toDetach)
13212 {
13213 aManipulator->Detach();
13214 aMapAIS.UnBind2 (aName);
13215 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13216 }
13217
625e1958 13218 // ---------------------------------------------------
13219 // attach, detach or access manipulator from an object
13220 // ---------------------------------------------------
13221
ff6122e0 13222 if (!anAttachObject.IsNull())
625e1958 13223 {
ff6122e0 13224 aManipulator->Attach (anAttachObject, anAttachOptions);
13225 }
13226 if (!aViewAffinity.IsNull())
13227 {
13228 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
8b037fe4 13229 anIter.More(); anIter.Next())
625e1958 13230 {
ff6122e0 13231 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
625e1958 13232 }
ff6122e0 13233 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13234 }
625e1958 13235
ff6122e0 13236 if (anAttachPos != ManipAjustPosition_Off
13237 && aManipulator->IsAttached()
13238 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13239 {
13240 gp_Ax2 aPosition = gp::XOY();
13241 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13242 switch (anAttachPos)
bbf3fcde 13243 {
ff6122e0 13244 case ManipAjustPosition_Off:
bbf3fcde 13245 {
ff6122e0 13246 break;
bbf3fcde 13247 }
ff6122e0 13248 case ManipAjustPosition_Location:
bbf3fcde 13249 {
ff6122e0 13250 aPosition = gp::XOY().Transformed (aBaseTrsf);
13251 break;
bbf3fcde 13252 }
ff6122e0 13253 case ManipAjustPosition_ShapeLocation:
bbf3fcde 13254 {
ff6122e0 13255 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
bbf3fcde 13256 {
ff6122e0 13257 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
bbf3fcde 13258 }
ff6122e0 13259 else
bbf3fcde 13260 {
ff6122e0 13261 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
bbf3fcde 13262 return 1;
13263 }
ff6122e0 13264 break;
bbf3fcde 13265 }
ff6122e0 13266 case ManipAjustPosition_Center:
bbf3fcde 13267 {
ff6122e0 13268 Bnd_Box aBox;
13269 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13270 {
13271 Bnd_Box anObjBox;
13272 anObjIter.Value()->BoundingBox (anObjBox);
13273 aBox.Add (anObjBox);
13274 }
13275 aBox = aBox.FinitePart();
13276 if (!aBox.IsVoid())
13277 {
13278 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13279 aPosition.SetLocation (aCenter);
13280 }
13281 break;
bbf3fcde 13282 }
bbf3fcde 13283 }
ff6122e0 13284 aManipulator->SetPosition (aPosition);
13285 }
13286 if (!Precision::IsInfinite (aLocation.X()))
13287 {
13288 if (aVDir.Modulus() <= Precision::Confusion())
13289 {
13290 aVDir = aManipulator->Position().Direction().XYZ();
13291 }
13292 if (anXDir.Modulus() <= Precision::Confusion())
13293 {
13294 anXDir = aManipulator->Position().XDirection().XYZ();
13295 }
13296 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
625e1958 13297 }
13298
13299 // --------------------------------------
13300 // apply transformation using manipulator
13301 // --------------------------------------
13302
ff6122e0 13303 if (aMousePosFrom.x() != IntegerLast())
625e1958 13304 {
ff6122e0 13305 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
625e1958 13306 }
ff6122e0 13307 if (aMousePosTo.x() != IntegerLast())
625e1958 13308 {
ff6122e0 13309 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
625e1958 13310 }
ff6122e0 13311 if (toStopMouseTransform != -1)
625e1958 13312 {
ff6122e0 13313 aManipulator->StopTransform (toStopMouseTransform == 1);
625e1958 13314 }
13315
ff6122e0 13316 if (aTrsf.Form() != gp_Identity)
625e1958 13317 {
ff6122e0 13318 aManipulator->Transform (aTrsf);
625e1958 13319 }
13320
ff6122e0 13321 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
625e1958 13322 {
ff6122e0 13323 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
625e1958 13324 }
625e1958 13325 return 0;
13326}
13327
8e5fb5ea 13328//===============================================================================================
13329//function : VSelectionProperties
13330//purpose :
13331//===============================================================================================
13332static int VSelectionProperties (Draw_Interpretor& theDi,
13333 Standard_Integer theArgsNb,
13334 const char** theArgVec)
13335{
13336 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13337 if (aCtx.IsNull())
13338 {
23fe70ec 13339 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13340 return 1;
13341 }
13342
be3d8cbc 13343 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13344 {
13345 // handle obsolete alias
13346 bool toEnable = true;
13347 if (theArgsNb < 2)
13348 {
13349 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13350 return 0;
13351 }
13352 else if (theArgsNb != 2
dae2a922 13353 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13354 {
23fe70ec 13355 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13356 return 1;
13357 }
13358 if (toEnable != aCtx->ToHilightSelected())
13359 {
13360 aCtx->ClearDetected();
13361 aCtx->SetToHilightSelected (toEnable);
13362 }
13363 return 0;
13364 }
13365
f838dac4 13366 Standard_Boolean toPrint = theArgsNb == 1;
13367 Standard_Boolean toRedraw = Standard_False;
13368 Standard_Integer anArgIter = 1;
13369 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13370 if (anArgIter < theArgsNb)
13371 {
13372 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13373 anArgFirst.LowerCase();
13374 ++anArgIter;
13375 if (anArgFirst == "dynhighlight"
13376 || anArgFirst == "dynhilight"
13377 || anArgFirst == "dynamichighlight"
13378 || anArgFirst == "dynamichilight")
13379 {
13380 aType = Prs3d_TypeOfHighlight_Dynamic;
13381 }
13382 else if (anArgFirst == "localdynhighlight"
13383 || anArgFirst == "localdynhilight"
13384 || anArgFirst == "localdynamichighlight"
13385 || anArgFirst == "localdynamichilight")
13386 {
13387 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13388 }
13389 else if (anArgFirst == "selhighlight"
13390 || anArgFirst == "selhilight"
13391 || anArgFirst == "selectedhighlight"
13392 || anArgFirst == "selectedhilight")
13393 {
13394 aType = Prs3d_TypeOfHighlight_Selected;
13395 }
13396 else if (anArgFirst == "localselhighlight"
13397 || anArgFirst == "localselhilight"
13398 || anArgFirst == "localselectedhighlight"
13399 || anArgFirst == "localselectedhilight")
13400 {
13401 aType = Prs3d_TypeOfHighlight_LocalSelected;
13402 }
13403 else
13404 {
13405 --anArgIter;
13406 }
13407 }
13408 for (; anArgIter < theArgsNb; ++anArgIter)
13409 {
13410 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13411 anArg.LowerCase();
13412 if (anArg == "-help")
13413 {
13414 theDi.PrintHelp (theArgVec[0]);
13415 return 0;
13416 }
13417 else if (anArg == "-print")
13418 {
13419 toPrint = Standard_True;
13420 }
13421 else if (anArg == "-autoactivate")
13422 {
13423 Standard_Boolean toEnable = Standard_True;
13424 if (anArgIter + 1 < theArgsNb
dae2a922 13425 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13426 {
13427 ++anArgIter;
13428 }
13429 aCtx->SetAutoActivateSelection (toEnable);
13430 }
be3d8cbc 13431 else if (anArg == "-automatichighlight"
13432 || anArg == "-automatichilight"
13433 || anArg == "-autohighlight"
13434 || anArg == "-autohilight")
13435 {
13436 Standard_Boolean toEnable = Standard_True;
13437 if (anArgIter + 1 < theArgsNb
dae2a922 13438 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13439 {
13440 ++anArgIter;
13441 }
13442 aCtx->ClearSelected (false);
13443 aCtx->ClearDetected();
13444 aCtx->SetAutomaticHilight (toEnable);
13445 toRedraw = true;
13446 }
13447 else if (anArg == "-highlightselected"
13448 || anArg == "-hilightselected")
13449 {
13450 Standard_Boolean toEnable = Standard_True;
13451 if (anArgIter + 1 < theArgsNb
dae2a922 13452 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13453 {
13454 ++anArgIter;
13455 }
13456 aCtx->ClearDetected();
13457 aCtx->SetToHilightSelected (toEnable);
13458 toRedraw = true;
13459 }
14c4193d 13460 else if (anArg == "-pickstrategy"
13461 || anArg == "-pickingstrategy")
13462 {
13463 if (++anArgIter >= theArgsNb)
13464 {
23fe70ec 13465 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13466 return 1;
13467 }
13468
13469 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13470 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13471 aVal.LowerCase();
13472 if (aVal == "first"
13473 || aVal == "firstaccepted"
13474 || aVal == "firstacceptable")
13475 {
13476 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13477 }
13478 else if (aVal == "topmost"
13479 || aVal == "onlyTopmost")
13480 {
13481 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13482 }
13483 else
13484 {
23fe70ec 13485 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13486 return 1;
13487 }
13488
13489 aCtx->SetPickingStrategy (aStrategy);
13490 }
f838dac4 13491 else if (anArg == "-pixtol"
13492 && anArgIter + 1 < theArgsNb)
13493 {
13494 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13495 }
8c36926a 13496 else if (anArg == "-preferclosest")
13497 {
13498 bool toPreferClosest = true;
13499 if (anArgIter + 1 < theArgsNb
13500 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13501 {
13502 ++anArgIter;
13503 }
13504 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13505 }
13506 else if ((anArg == "-depthtol"
13507 || anArg == "-depthtolerance")
13508 && anArgIter + 1 < theArgsNb)
13509 {
13510 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13511 aTolType.LowerCase();
13512 if (aTolType == "uniform")
13513 {
13514 if (anArgIter + 1 >= theArgsNb)
13515 {
13516 Message::SendFail() << "Syntax error: wrong number of arguments";
13517 return 1;
13518 }
13519 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13520 Draw::Atof (theArgVec[++anArgIter]));
13521 }
13522 else if (aTolType == "uniformpx")
13523 {
13524 if (anArgIter + 1 >= theArgsNb)
13525 {
13526 Message::SendFail() << "Syntax error: wrong number of arguments";
13527 return 1;
13528 }
13529 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13530 Draw::Atof (theArgVec[++anArgIter]));
13531 }
13532 else if (aTolType == "sensfactor")
13533 {
13534 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13535 }
13536 else
13537 {
13538 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13539 return 1;
13540 }
13541 }
f838dac4 13542 else if ((anArg == "-mode"
13543 || anArg == "-dispmode")
13544 && anArgIter + 1 < theArgsNb)
13545 {
13546 if (aType == Prs3d_TypeOfHighlight_None)
13547 {
23fe70ec 13548 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13549 return 1;
13550 }
8e5fb5ea 13551
f838dac4 13552 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13553 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13554 aStyle->SetDisplayMode (aDispMode);
13555 toRedraw = Standard_True;
13556 }
13557 else if (anArg == "-layer"
13558 && anArgIter + 1 < theArgsNb)
13559 {
13560 if (aType == Prs3d_TypeOfHighlight_None)
13561 {
23fe70ec 13562 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13563 return 1;
13564 }
8e5fb5ea 13565
55c8f0f7
BB
13566 ++anArgIter;
13567 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13568 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13569 {
23fe70ec 13570 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13571 return 1;
f838dac4 13572 }
8e5fb5ea 13573
f838dac4 13574 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13575 aStyle->SetZLayer (aNewLayer);
13576 toRedraw = Standard_True;
13577 }
13578 else if (anArg == "-hicolor"
13579 || anArg == "-selcolor"
13580 || anArg == "-color")
13581 {
13582 if (anArg.StartsWith ("-hi"))
13583 {
13584 aType = Prs3d_TypeOfHighlight_Dynamic;
13585 }
13586 else if (anArg.StartsWith ("-sel"))
13587 {
13588 aType = Prs3d_TypeOfHighlight_Selected;
13589 }
13590 else if (aType == Prs3d_TypeOfHighlight_None)
13591 {
23fe70ec 13592 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13593 return 1;
13594 }
8e5fb5ea 13595
f838dac4 13596 Quantity_Color aColor;
dae2a922 13597 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13598 theArgVec + anArgIter + 1,
13599 aColor);
f838dac4 13600 if (aNbParsed == 0)
13601 {
23fe70ec 13602 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13603 return 1;
13604 }
13605 anArgIter += aNbParsed;
8e5fb5ea 13606
f838dac4 13607 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13608 aStyle->SetColor (aColor);
13609 toRedraw = Standard_True;
13610 }
13611 else if ((anArg == "-transp"
13612 || anArg == "-transparency"
13613 || anArg == "-hitransp"
13614 || anArg == "-seltransp"
13615 || anArg == "-hitransplocal"
13616 || anArg == "-seltransplocal")
13617 && anArgIter + 1 < theArgsNb)
13618 {
13619 if (anArg.StartsWith ("-hi"))
13620 {
13621 aType = Prs3d_TypeOfHighlight_Dynamic;
13622 }
13623 else if (anArg.StartsWith ("-sel"))
13624 {
13625 aType = Prs3d_TypeOfHighlight_Selected;
13626 }
13627 else if (aType == Prs3d_TypeOfHighlight_None)
13628 {
23fe70ec 13629 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13630 return 1;
13631 }
8e5fb5ea 13632
f838dac4 13633 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13634 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13635 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13636 toRedraw = Standard_True;
13637 }
13638 else if ((anArg == "-mat"
13639 || anArg == "-material")
13640 && anArgIter + 1 < theArgsNb)
13641 {
13642 if (aType == Prs3d_TypeOfHighlight_None)
13643 {
23fe70ec 13644 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13645 return 1;
13646 }
8e5fb5ea 13647
f838dac4 13648 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13649 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 13650 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 13651 {
13652 ++anArgIter;
13653 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13654 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13655 Graphic3d_MaterialAspect aMat (aMatName);
13656 aMat.SetColor (aStyle->Color());
13657 aMat.SetTransparency (aStyle->Transparency());
13658 anAspect->SetFrontMaterial (aMat);
13659 anAspect->SetInteriorColor (aStyle->Color());
13660 aStyle->SetBasicFillAreaAspect (anAspect);
13661 }
13662 else
13663 {
13664 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13665 }
13666 toRedraw = Standard_True;
13667 }
13668 else
13669 {
23fe70ec 13670 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 13671 return 1;
f838dac4 13672 }
8e5fb5ea 13673 }
13674
f838dac4 13675 if (toPrint)
8e5fb5ea 13676 {
f838dac4 13677 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13678 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13679 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13680 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13681 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13682 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13683 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13684 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13685 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13686 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13687 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13688 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13689 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13690 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13691 }
13692
13693 if (aCtx->NbSelected() != 0 && toRedraw)
13694 {
13695 aCtx->HilightSelected (Standard_True);
13696 }
13697
13698 return 0;
13699}
13700
decdee7d 13701//===============================================================================================
13702//function : VDumpSelectionImage
13703//purpose :
13704//===============================================================================================
13705static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13706 Standard_Integer theArgsNb,
13707 const char** theArgVec)
13708{
decdee7d 13709 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 13710 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 13711 if (aContext.IsNull())
13712 {
23fe70ec 13713 Message::SendFail ("Error: no active viewer");
decdee7d 13714 return 1;
13715 }
13716
13717 TCollection_AsciiString aFile;
13718 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 13719 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 13720 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13721 Standard_Integer aPickedIndex = 1;
13722 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13723 {
13724 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13725 aParam.LowerCase();
13726 if (aParam == "-type")
13727 {
13728 if (++anArgIter >= theArgsNb)
13729 {
df23a355 13730 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
decdee7d 13731 return 1;
13732 }
13733
13734 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13735 aValue.LowerCase();
13736 if (aValue == "depth"
13737 || aValue == "normdepth"
13738 || aValue == "normalizeddepth")
13739 {
13740 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13741 anImgFormat = Image_Format_GrayF;
decdee7d 13742 }
df23a355 13743 else if (aValue == "depthinverted"
13744 || aValue == "normdepthinverted"
13745 || aValue == "normalizeddepthinverted"
13746 || aValue == "inverted")
decdee7d 13747 {
13748 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13749 anImgFormat = Image_Format_GrayF;
decdee7d 13750 }
13751 else if (aValue == "unnormdepth"
13752 || aValue == "unnormalizeddepth")
13753 {
13754 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13755 anImgFormat = Image_Format_GrayF;
decdee7d 13756 }
13757 else if (aValue == "objectcolor"
13758 || aValue == "object"
13759 || aValue == "color")
13760 {
13761 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13762 }
13763 else if (aValue == "entitycolor"
13764 || aValue == "entity")
13765 {
13766 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13767 }
13768 else if (aValue == "ownercolor"
13769 || aValue == "owner")
13770 {
13771 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13772 }
13773 else if (aValue == "selectionmodecolor"
13774 || aValue == "selectionmode"
13775 || aValue == "selmodecolor"
13776 || aValue == "selmode")
13777 {
13778 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13779 }
114e7a90 13780 else if (aValue == "surfnormal"
13781 || aValue == "surfacenormal"
13782 || aValue == "normal")
13783 {
13784 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13785 }
df23a355 13786 else
13787 {
13788 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13789 return 1;
13790 }
decdee7d 13791 }
13792 else if (aParam == "-picked"
13793 || aParam == "-pickeddepth"
13794 || aParam == "-pickedindex")
13795 {
13796 if (++anArgIter >= theArgsNb)
13797 {
23fe70ec 13798 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 13799 return 1;
13800 }
13801
13802 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13803 }
b40cdc2b 13804 else if (anArgIter + 1 < theArgsNb
13805 && aParam == "-xrpose")
13806 {
13807 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13808 anXRArg.LowerCase();
13809 if (anXRArg == "base")
13810 {
13811 aCustomCam = aView->View()->BaseXRCamera();
13812 }
13813 else if (anXRArg == "head")
13814 {
13815 aCustomCam = aView->View()->PosedXRCamera();
13816 }
13817 else
13818 {
13819 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13820 return 1;
13821 }
13822 if (aCustomCam.IsNull())
13823 {
13824 Message::SendFail() << "Error: undefined XR pose";
13825 return 0;
13826 }
13827 }
decdee7d 13828 else if (aFile.IsEmpty())
13829 {
13830 aFile = theArgVec[anArgIter];
13831 }
13832 else
13833 {
23fe70ec 13834 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 13835 return 1;
13836 }
13837 }
13838 if (aFile.IsEmpty())
13839 {
23fe70ec 13840 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 13841 return 1;
13842 }
13843
decdee7d 13844 Standard_Integer aWidth = 0, aHeight = 0;
13845 aView->Window()->Size (aWidth, aHeight);
13846
13847 Image_AlienPixMap aPixMap;
13848 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13849 {
23fe70ec 13850 Message::SendFail ("Error: can't allocate image");
decdee7d 13851 return 1;
13852 }
b40cdc2b 13853
13854 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13855 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13856 if (!aCustomCam.IsNull())
13857 {
13858 aView->SetCamera (aCustomCam);
13859 }
decdee7d 13860 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13861 {
23fe70ec 13862 Message::SendFail ("Error: can't generate selection image");
decdee7d 13863 return 1;
13864 }
b40cdc2b 13865 if (!aCustomCam.IsNull())
13866 {
13867 aView->SetCamera (aCamBack);
13868 }
13869 aView->SetImmediateUpdate (wasImmUpdate);
13870
decdee7d 13871 if (!aPixMap.Save (aFile))
13872 {
23fe70ec 13873 Message::SendFail ("Error: can't save selection image");
decdee7d 13874 return 0;
13875 }
13876 return 0;
13877}
13878
2108d9a2 13879//===============================================================================================
13880//function : VViewCube
13881//purpose :
13882//===============================================================================================
13883static int VViewCube (Draw_Interpretor& ,
13884 Standard_Integer theNbArgs,
13885 const char** theArgVec)
13886{
13887 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13888 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13889 if (aContext.IsNull() || aView.IsNull())
13890 {
23fe70ec 13891 Message::SendFail ("Error: no active viewer");
2108d9a2 13892 return 1;
13893 }
13894 else if (theNbArgs < 2)
13895 {
23fe70ec 13896 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 13897 return 1;
13898 }
13899
13900 Handle(AIS_ViewCube) aViewCube;
13901 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13902 Quantity_Color aColorRgb;
13903 TCollection_AsciiString aName;
13904 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13905 {
13906 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13907 anArg.LowerCase();
13908 if (anUpdateTool.parseRedrawMode (anArg))
13909 {
13910 //
13911 }
13912 else if (aViewCube.IsNull())
13913 {
13914 aName = theArgVec[anArgIter];
13915 if (aName.StartsWith ("-"))
13916 {
23fe70ec 13917 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 13918 return 1;
13919 }
13920 Handle(AIS_InteractiveObject) aPrs;
13921 GetMapOfAIS().Find2 (aName, aPrs);
13922 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13923 if (aViewCube.IsNull())
13924 {
13925 aViewCube = new AIS_ViewCube();
13926 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13927 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13928 aViewCube->SetFixedAnimationLoop (false);
13929 }
13930 }
13931 else if (anArg == "-reset")
13932 {
13933 aViewCube->ResetStyles();
13934 }
13935 else if (anArg == "-color"
13936 || anArg == "-boxcolor"
13937 || anArg == "-boxsidecolor"
13938 || anArg == "-sidecolor"
13939 || anArg == "-boxedgecolor"
13940 || anArg == "-edgecolor"
13941 || anArg == "-boxcornercolor"
13942 || anArg == "-cornercolor"
13943 || anArg == "-innercolor"
0aeb8984 13944 || anArg == "-textcolor"
13945 || anArg == "-xaxistextcolor"
13946 || anArg == "-yaxistextcolor"
13947 || anArg == "-zaxistextcolor")
2108d9a2 13948 {
dae2a922 13949 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13950 theArgVec + anArgIter + 1,
13951 aColorRgb);
2108d9a2 13952 if (aNbParsed == 0)
13953 {
23fe70ec 13954 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 13955 return 1;
13956 }
13957 anArgIter += aNbParsed;
13958 if (anArg == "-boxcolor")
13959 {
13960 aViewCube->SetBoxColor (aColorRgb);
13961 }
13962 else if (anArg == "-boxsidecolor"
13963 || anArg == "-sidecolor")
13964 {
13965 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13966 aViewCube->SynchronizeAspects();
13967 }
13968 else if (anArg == "-boxedgecolor"
13969 || anArg == "-edgecolor")
13970 {
13971 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13972 aViewCube->SynchronizeAspects();
13973 }
13974 else if (anArg == "-boxcornercolor"
13975 || anArg == "-cornercolor")
13976 {
13977 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13978 aViewCube->SynchronizeAspects();
13979 }
13980 else if (anArg == "-innercolor")
13981 {
13982 aViewCube->SetInnerColor (aColorRgb);
13983 }
13984 else if (anArg == "-textcolor")
13985 {
13986 aViewCube->SetTextColor (aColorRgb);
13987 }
0aeb8984 13988 else if (anArg == "-xaxistextcolor"
13989 || anArg == "-yaxistextcolor"
13990 || anArg == "-zaxistextcolor")
13991 {
13992 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13993 ? Prs3d_DatumParts_XAxis
13994 : (anArg.Value (2) == 'y'
13995 ? Prs3d_DatumParts_YAxis
13996 : Prs3d_DatumParts_ZAxis);
13997 aViewCube->Attributes()->SetOwnDatumAspects();
13998 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13999 }
2108d9a2 14000 else
14001 {
14002 aViewCube->SetColor (aColorRgb);
14003 }
14004 }
14005 else if (anArgIter + 1 < theNbArgs
14006 && (anArg == "-transparency"
14007 || anArg == "-boxtransparency"))
14008 {
14009 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
14010 if (aValue < 0.0 || aValue > 1.0)
14011 {
23fe70ec 14012 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 14013 return 1;
14014 }
14015
14016 if (anArg == "-boxtransparency")
14017 {
14018 aViewCube->SetBoxTransparency (aValue);
14019 }
14020 else
14021 {
14022 aViewCube->SetTransparency (aValue);
14023 }
14024 }
14025 else if (anArg == "-axes"
14026 || anArg == "-edges"
14027 || anArg == "-vertices"
14028 || anArg == "-vertexes"
14029 || anArg == "-fixedanimation")
14030 {
14031 bool toShow = true;
14032 if (anArgIter + 1 < theNbArgs
dae2a922 14033 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 14034 {
14035 ++anArgIter;
14036 }
14037 if (anArg == "-fixedanimation")
14038 {
14039 aViewCube->SetFixedAnimationLoop (toShow);
14040 }
14041 else if (anArg == "-axes")
14042 {
14043 aViewCube->SetDrawAxes (toShow);
14044 }
14045 else if (anArg == "-edges")
14046 {
14047 aViewCube->SetDrawEdges (toShow);
14048 }
14049 else
14050 {
14051 aViewCube->SetDrawVertices (toShow);
14052 }
14053 }
14054 else if (anArg == "-yup"
14055 || anArg == "-zup")
14056 {
14057 bool isOn = true;
14058 if (anArgIter + 1 < theNbArgs
dae2a922 14059 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 14060 {
14061 ++anArgIter;
14062 }
14063 if (anArg == "-yup")
14064 {
14065 aViewCube->SetYup (isOn);
14066 }
14067 else
14068 {
14069 aViewCube->SetYup (!isOn);
14070 }
14071 }
14072 else if (anArgIter + 1 < theNbArgs
14073 && anArg == "-font")
14074 {
14075 aViewCube->SetFont (theArgVec[++anArgIter]);
14076 }
14077 else if (anArgIter + 1 < theNbArgs
14078 && anArg == "-fontheight")
14079 {
14080 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
14081 }
14082 else if (anArgIter + 1 < theNbArgs
14083 && (anArg == "-size"
14084 || anArg == "-boxsize"))
14085 {
14086 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
14087 anArg != "-boxsize");
14088 }
14089 else if (anArgIter + 1 < theNbArgs
14090 && (anArg == "-boxfacet"
14091 || anArg == "-boxfacetextension"
14092 || anArg == "-facetextension"
14093 || anArg == "-extension"))
14094 {
14095 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
14096 }
14097 else if (anArgIter + 1 < theNbArgs
14098 && (anArg == "-boxedgegap"
14099 || anArg == "-edgegap"))
14100 {
14101 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
14102 }
14103 else if (anArgIter + 1 < theNbArgs
14104 && (anArg == "-boxedgeminsize"
14105 || anArg == "-edgeminsize"))
14106 {
14107 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14108 }
14109 else if (anArgIter + 1 < theNbArgs
14110 && (anArg == "-boxcornerminsize"
14111 || anArg == "-cornerminsize"))
14112 {
14113 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14114 }
14115 else if (anArgIter + 1 < theNbArgs
14116 && anArg == "-axespadding")
14117 {
14118 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14119 }
14120 else if (anArgIter + 1 < theNbArgs
14121 && anArg == "-roundradius")
14122 {
14123 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14124 }
14125 else if (anArgIter + 1 < theNbArgs
14126 && anArg == "-duration")
14127 {
14128 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14129 }
6466cc9e 14130 else if (anArgIter + 1 < theNbArgs
14131 && anArg == "-axesradius")
14132 {
14133 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14134 }
14135 else if (anArgIter + 1 < theNbArgs
14136 && anArg == "-axesconeradius")
14137 {
14138 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14139 }
14140 else if (anArgIter + 1 < theNbArgs
14141 && anArg == "-axessphereradius")
14142 {
14143 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14144 }
2108d9a2 14145 else
14146 {
23fe70ec 14147 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 14148 return 1;
14149 }
14150 }
14151 if (aViewCube.IsNull())
14152 {
23fe70ec 14153 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 14154 return 1;
14155 }
14156
14157 ViewerTest::Display (aName, aViewCube, false);
14158 return 0;
14159}
14160
14b741b0 14161//===============================================================================================
14162//function : VColorConvert
14163//purpose :
14164//===============================================================================================
14165static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14166{
14167 if (theNbArgs != 6)
14168 {
14169 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14170 return 1;
14171 }
14172
14173 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14174 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14175 {
14176 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14177 return 1;
14178 }
14179
14180 const char* aTypeStr = theArgVec[2];
14181 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14182 if (! strcasecmp (aTypeStr, "srgb"))
14183 {
14184 aType = Quantity_TOC_sRGB;
14185 }
14186 else if (! strcasecmp (aTypeStr, "hls"))
14187 {
14188 aType = Quantity_TOC_HLS;
14189 }
14190 else if (! strcasecmp (aTypeStr, "lab"))
14191 {
14192 aType = Quantity_TOC_CIELab;
14193 }
14194 else if (! strcasecmp (aTypeStr, "lch"))
14195 {
14196 aType = Quantity_TOC_CIELch;
14197 }
14198 else
14199 {
14200 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14201 return 1;
14202 }
14203
14204 double aC1 = Draw::Atof (theArgVec[3]);
14205 double aC2 = Draw::Atof (theArgVec[4]);
14206 double aC3 = Draw::Atof (theArgVec[5]);
14207
14208 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14209 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14210
14211 // print values with 6 decimal digits
14212 char buffer[1024];
14213 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14214 theDI << buffer;
14215
14216 return 0;
14217}
14218
14219//===============================================================================================
14220//function : VColorDiff
14221//purpose :
14222//===============================================================================================
14223static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14224{
14225 if (theNbArgs != 7)
14226 {
14227 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14228 return 1;
14229 }
14230
14231 double aR1 = Draw::Atof (theArgVec[1]);
14232 double aG1 = Draw::Atof (theArgVec[2]);
14233 double aB1 = Draw::Atof (theArgVec[3]);
14234 double aR2 = Draw::Atof (theArgVec[4]);
14235 double aG2 = Draw::Atof (theArgVec[5]);
14236 double aB2 = Draw::Atof (theArgVec[6]);
14237
14238 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14239 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14240
14241 theDI << aColor1.DeltaE2000 (aColor2);
14242
14243 return 0;
14244}
14245
6a2fb7a1 14246//===============================================================================================
4551e1be 14247//function : VSelBvhBuild
6a2fb7a1 14248//purpose :
14249//===============================================================================================
14250static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14251{
14252 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14253 if (aCtx.IsNull())
14254 {
14255 Message::SendFail ("Error: no active viewer");
14256 return 1;
14257 }
14258
14259 if (theNbArgs < 2)
14260 {
14261 Message::SendFail ("Error: command syntax is incorrect, see help");
14262 return 1;
14263 }
14264
14265 Standard_Integer toEnable = -1;
14266 Standard_Integer aThreadsNb = -1;
14267 Standard_Boolean toWait = Standard_False;
14268
14269 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14270 {
14271 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14272 anArg.LowerCase();
14273
14274 if (anArg == "-nbthreads"
14275 && anArgIter + 1 < theNbArgs)
14276 {
14277 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14278 if (aThreadsNb < 1)
14279 {
14280 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14281 }
14282 }
14283 else if (anArg == "-wait")
14284 {
14285 toWait = Standard_True;
14286 }
14287 else if (toEnable == -1)
14288 {
14289 Standard_Boolean toEnableValue = Standard_True;
14290 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14291 {
14292 toEnable = toEnableValue ? 1 : 0;
14293 }
14294 else
14295 {
14296 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14297 return 1;
14298 }
14299 }
14300 else
14301 {
14302 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14303 return 1;
14304 }
14305 }
14306
14307 if (aThreadsNb == -1)
14308 {
14309 aThreadsNb = 1;
14310 }
14311 if (toEnable != -1)
14312 {
14313 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14314 }
14315 if (toWait)
14316 {
14317 aCtx->MainSelector()->WaitForBVHBuild();
14318 }
14319
14320 return 0;
14321}
14322
a6049685 14323//=======================================================================
14324//function : ViewerTest_ExitProc
14325//purpose :
14326//=======================================================================
14327static void ViewerTest_ExitProc (ClientData )
14328{
14329 NCollection_List<TCollection_AsciiString> aViewList;
14330 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14331 anIter.More(); anIter.Next())
14332 {
14333 aViewList.Append (anIter.Key1());
14334 }
14335
14336 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14337 anIter.More(); anIter.Next())
14338 {
14339 ViewerTest::RemoveView (anIter.Value(), true);
14340 }
14341}
14342
7fd59977 14343//=======================================================================
14344//function : ViewerCommands
14345//purpose :
14346//=======================================================================
14347
14348void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14349{
a6049685 14350 static bool TheIsInitialized = false;
14351 if (TheIsInitialized)
14352 {
14353 return;
14354 }
14355
14356 TheIsInitialized = true;
14357 // define destruction callback to destroy views in a well-defined order
14358 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
7fd59977 14359
14360 const char *group = "ZeViewer";
b8db9379 14361 theCommands.Add("vdriver",
14362 "vdriver [-list] [-default DriverName] [-load DriverName]"
14363 "\n\t\t: Manages active graphic driver factory."
14364 "\n\t\t: Prints current active driver when called without arguments."
14365 "\n\t\t: Makes specified driver active when ActiveName argument is specified."
14366 "\n\t\t: -list print registered factories"
14367 "\n\t\t: -default define which factory should be used by default (to be used by next vinit call)"
14368 "\n\t\t: -load try loading factory plugin and set it as default one",
14369 __FILE__, VDriver, group);
18d715bd 14370 theCommands.Add("vinit",
fd3f6bd0 14371 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
72ed0644 14372 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
b69e576a 14373 #if defined(HAVE_XLIB)
fd3f6bd0 14374 "\n\t\t: [-display displayName]"
14375 #endif
14376 "\n\t\t: Creates new View window with specified name viewName."
14377 "\n\t\t: By default the new view is created in the viewer and in"
14378 "\n\t\t: graphic driver shared with active view."
14379 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14380 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14381 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
b69e576a 14382#if defined(HAVE_XLIB)
fd3f6bd0 14383 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14384 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14385#endif
fd3f6bd0 14386 "\n\t\t: -left, -top pixel position of left top corner of the window."
4551e1be 14387 "\n\t\t: -width, -height width and height of window respectively."
72ed0644 14388 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
fd3f6bd0 14389 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14390 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
72ed0644 14391 "\n\t\t: -virtual create an offscreen window within interactive session"
2e93433e 14392 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14393 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14394 __FILE__,VInit,group);
18d715bd 14395 theCommands.Add("vclose" ,
d0cc1cb7 14396 "[view_id [keep_context=0|1]]\n"
18d715bd 14397 "or vclose ALL - to remove all created views\n"
14398 " - removes view(viewer window) defined by its view_id.\n"
14399 " - keep_context: by default 0; if 1 and the last view is deleted"
14400 " the current context is not removed.",
14401 __FILE__,VClose,group);
14402 theCommands.Add("vactivate" ,
e084dbbc 14403 "vactivate view_id [-noUpdate]"
18d715bd 14404 " - activates view(viewer window) defined by its view_id",
14405 __FILE__,VActivate,group);
14406 theCommands.Add("vviewlist",
14407 "vviewlist [format={tree, long}]"
14408 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14409 " - format: format of result output, if tree the output is a tree view;"
14410 "otherwise it's a list of full view names. By default format = tree",
14411 __FILE__,VViewList,group);
7fd59977 14412 theCommands.Add("vhelp" ,
14413 "vhelp : display help on the viewer commands",
14414 __FILE__,VHelp,group);
fc552d84 14415 theCommands.Add("vviewproj",
14416 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14417 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14418 "\n\t\t: Setup view direction"
14419 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14420 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14421 "\n\t\t: for example '+Z' will show front of the model,"
14422 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14423 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14424 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14425 __FILE__,VViewProj,group);
7fd59977 14426 theCommands.Add("vtop" ,
27af3052 14427 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14428 __FILE__,VViewProj,group);
44b8f2d6 14429 theCommands.Add("vbottom" ,
27af3052 14430 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14431 __FILE__,VViewProj,group);
44b8f2d6 14432 theCommands.Add("vleft" ,
27af3052 14433 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14434 __FILE__,VViewProj,group);
44b8f2d6 14435 theCommands.Add("vright" ,
27af3052 14436 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14437 __FILE__,VViewProj,group);
7fd59977 14438 theCommands.Add("vaxo" ,
27af3052 14439 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14440 __FILE__,VViewProj,group);
44b8f2d6 14441 theCommands.Add("vfront" ,
27af3052 14442 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14443 __FILE__,VViewProj,group);
44b8f2d6 14444 theCommands.Add("vback" ,
27af3052 14445 "vback : Back view. Orientation -X+Z" ,
fc552d84 14446 __FILE__,VViewProj,group);
7fd59977 14447 theCommands.Add("vpick" ,
14448 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14449 VPick,group);
1beb58d7 14450 theCommands.Add("vfit",
14451 "vfit or <F> [-selected] [-noupdate]"
b586500b 14452 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14453 __FILE__,VFit,group);
6262a303 14454 theCommands.Add ("vfitarea",
14455 "vfitarea x1 y1 x2 y2"
14456 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14457 "\n\t\t: Fit view to show area located between two points"
14458 "\n\t\t: given in world 2D or 3D corrdinates.",
14459 __FILE__, VFitArea, group);
197ac94e 14460 theCommands.Add ("vzfit", "vzfit [scale]\n"
14461 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14462 " \"scale\" - specifies factor to scale computed z range.\n",
14463 __FILE__, VZFit, group);
7fd59977 14464 theCommands.Add("vrepaint",
8693dfd0 14465 "vrepaint [-immediate] [-continuous FPS]"
14466 "\n\t\t: force redraw of active View"
14467 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14468 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14469 "\n\t\t: 0 means no continuous rendering,"
14470 "\n\t\t: -1 means non-stop redraws,"
14471 "\n\t\t: >0 specifies target framerate,",
7fd59977 14472 __FILE__,VRepaint,group);
14473 theCommands.Add("vclear",
faea8b40 14474 "vclear : vclear"
14475 "\n\t\t: remove all the object from the viewer",
7fd59977 14476 __FILE__,VClear,group);
293211ae 14477 theCommands.Add (
14478 "vbackground",
14479 "Changes background or some background settings.\n"
14480 "\n"
14481 "Usage:\n"
14482 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14483 " vbackground -imageMode FillType\n"
14484 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14485 " vbackground -gradientMode FillMethod\n"
077a220c 14486 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14487 " vbackground -color Color\n"
14488 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14489 " vbackground -default -color Color\n"
14490 " vbackground -help\n"
14491 "\n"
14492 "Options:\n"
14493 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14494 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14495 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14496 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
4551e1be 14497 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
077a220c 14498 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14499 " -order (-o): defines order of tiles in one image cubemap\n"
14500 " (has no effect in case of multi image cubemaps)\n"
293211ae 14501 " -color (-col): sets background color\n"
14502 " -default (-def): sets background default gradient or color\n"
14503 " -help (-h): outputs short help message\n"
14504 "\n"
14505 "Arguments:\n"
077a220c 14506 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14507 " or reals within the range [0.0, 1.0]\n"
077a220c 14508 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14509 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14510 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14511 "CORNER4\n"
077a220c 14512 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14513 " ImageFile: a name of the file with the image used as a background\n"
14514 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14515 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14516 __FILE__,
14517 vbackground,
14518 group);
14519 theCommands.Add ("vsetbg",
14520 "Loads image as background."
14521 "\n\t\t: vsetbg ImageFile [FillType]"
14522 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14523 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14524 __FILE__,
14525 vbackground,
14526 group);
14527 theCommands.Add ("vsetbgmode",
14528 "Changes background image fill type."
14529 "\n\t\t: vsetbgmode [-imageMode] FillType"
14530 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14531 __FILE__,
14532 vbackground,
14533 group);
14534 theCommands.Add ("vsetgradientbg",
14535 "Mounts gradient background."
14536 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14537 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14538 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14539 __FILE__,
14540 vbackground,
14541 group);
14542 theCommands.Add ("vsetgrbgmode",
14543 "Changes gradient background fill method."
14544 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14545 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14546 __FILE__,
14547 vbackground,
14548 group);
14549 theCommands.Add ("vsetcolorbg",
14550 "Sets background color."
14551 "\n\t\t: vsetcolorbg [-color] Color."
14552 "\n\t\t: Alias for 'vbackground -color Color'.",
14553 __FILE__,
14554 vbackground,
14555 group);
14556 theCommands.Add ("vsetdefaultbg",
14557 "Sets default viewer background fill color (flat/gradient)."
14558 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14559 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14560 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14561 "\n\t\t: vsetdefaultbg [-color] Color"
14562 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14563 __FILE__,
14564 vbackground,
14565 group);
7fd59977 14566 theCommands.Add("vscale",
14567 "vscale : vscale X Y Z",
14568 __FILE__,VScale,group);
14569 theCommands.Add("vzbufftrihedron",
536d98e2 14570 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14571 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14572 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14573 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14574 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
0aeb8984 14575 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
536d98e2 14576 "\n\t\t: Displays a trihedron",
14577 __FILE__,VZBuffTrihedron,group);
7fd59977 14578 theCommands.Add("vrotate",
4af098ba 14579 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14580 "\n : Option -mouseStart starts rotation according to the mouse position"
14581 "\n : Option -mouseMove continues rotation with angle computed"
14582 "\n : from last and new mouse position."
14583 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14584 __FILE__,VRotate,group);
14585 theCommands.Add("vzoom",
14586 "vzoom : vzoom coef",
14587 __FILE__,VZoom,group);
14588 theCommands.Add("vpan",
14589 "vpan : vpan dx dy",
14590 __FILE__,VPan,group);
7fd59977 14591 theCommands.Add("vcolorscale",
4b3d6eb1 14592 "vcolorscale name [-noupdate|-update] [-demo]"
14593 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14594 "\n\t\t: [-font HeightFont=20]"
14595 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14596 "\n\t\t: [-smoothTransition {on|off}=off]"
14597 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14598 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14599 "\n\t\t: [-textpos {left|right|center|none}=right]"
14600 "\n\t\t: [-labelAtBorder {on|off}=on]"
14601 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14602 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14603 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14604 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14605 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14606 "\n\t\t: -demo - displays a color scale with demonstratio values"
14607 "\n\t\t: -colors - set colors for all intervals"
14608 "\n\t\t: -color - set color for specific interval"
14b741b0 14609 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14610 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14611 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14612 "\n\t\t: at border means the value inbetween neighbor intervals,"
14613 "\n\t\t: at center means the center value within current interval"
14614 "\n\t\t: -labels - set labels for all intervals"
14615 "\n\t\t: -freeLabels - same as -labels but does not require"
14616 "\n\t\t: matching the number of intervals"
14617 "\n\t\t: -label - set label for specific interval"
14618 "\n\t\t: -title - set title"
14619 "\n\t\t: -reversed - setup smooth color transition between intervals"
14620 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14621 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14622 __FILE__, VColorScale, group);
7fd59977 14623 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14624 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14625 "\t[-namefont Name] [-valuesfont Name]\n"
14626 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14627 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14628 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14629 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14630 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14631 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14632 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14633 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14634 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14635 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14636 " - Displays or erases graduated trihedron"
14637 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14638 " - namefont - font of axes names. Default: Arial\n"
14639 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14640 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14641 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14642 " - valuesfont - font of axes values. Default: Arial\n"
14643 " - xcolor, ycolor, zcolor - color of axis and values\n"
14644 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14645 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14646 __FILE__,VGraduatedTrihedron,group);
3bffef55 14647 theCommands.Add("vtile" ,
14648 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14649 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14650 "\n\t\t: -totalSize the size of virtual bigger viewport"
14651 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14652 "\n\t\t: -lowerLeft tile offset as lower left corner"
14653 "\n\t\t: -upperLeft tile offset as upper left corner",
14654 __FILE__, VTile, group);
59f45b7c 14655 theCommands.Add("vzlayer",
7c3ef2f7 14656 "vzlayer [layerId]"
1c728f2d 14657 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14658 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14659 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14660 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14661 "\n\t\t: ZLayer list management:"
14662 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14663 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14664 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14665 "\n\t\t: -delete delete z layer"
14666 "\n\t\t: -get print sequence of z layers"
14667 "\n\t\t: -settings print status of z layer settings"
14668 "\n\t\t: -disable disables given setting"
14669 "\n\t\t: -enable enables given setting",
59f45b7c 14670 __FILE__,VZLayer,group);
20637bd2 14671 theCommands.Add("vlayerline",
14672 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14673 __FILE__,VLayerLine,group);
79931835 14674 theCommands.Add("vgrid",
14675 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14676 "\n\t\t: [-step X Y] [-size DX DY]"
14677 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 14678 __FILE__, VGrid, group);
c40b7d58 14679 theCommands.Add ("vpriviledgedplane",
14680 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14681 "\n\t\t: Ox, Oy, Oz - plane origin"
14682 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14683 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14684 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14685 __FILE__, VPriviledgedPlane, group);
f25b82d6 14686 theCommands.Add ("vconvert",
14687 "vconvert v [Mode={window|view}]"
14688 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14689 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14690 "\n\t\t: window - convert to window coordinates, pixels"
14691 "\n\t\t: view - convert to view projection plane"
14692 "\n\t\t: grid - convert to model coordinates, given on grid"
4551e1be 14693 "\n\t\t: ray - convert projection ray to model coordinates"
f25b82d6 14694 "\n\t\t: - vconvert v window : convert view to window;"
14695 "\n\t\t: - vconvert v view : convert window to view;"
14696 "\n\t\t: - vconvert x y window : convert view to window;"
14697 "\n\t\t: - vconvert x y view : convert window to view;"
14698 "\n\t\t: - vconvert x y : convert window to model;"
14699 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14700 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14701 "\n\t\t: - vconvert x y z window : convert model to window;"
14702 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14703 "\n\t\t: Converts the given coordinates to window/view/model space.",
14704 __FILE__, VConvert, group);
208e6839 14705 theCommands.Add ("vfps",
e084dbbc 14706 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 14707 __FILE__, VFps, group);
b5ac8292 14708 theCommands.Add ("vstereo",
f978241f 14709 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 14710 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 14711 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 14712 "\n\t\t: Control stereo output mode."
14713 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14714 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14715 "\n\t\t: Available modes for -mode:"
f978241f 14716 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14717 "\n\t\t: requires driver support."
14718 "\n\t\t: Should be called BEFORE vinit!"
14719 "\n\t\t: anaglyph - Anaglyph glasses"
14720 "\n\t\t: rowInterlaced - row-interlaced display"
14721 "\n\t\t: columnInterlaced - column-interlaced display"
14722 "\n\t\t: chessBoard - chess-board output"
14723 "\n\t\t: sideBySide - horizontal pair"
14724 "\n\t\t: overUnder - vertical pair"
b40cdc2b 14725 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 14726 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14727 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14728 "\n\t\t: greenMagentaSimple",
b5ac8292 14729 __FILE__, VStereo, group);
f0430952 14730 theCommands.Add ("vmemgpu",
14731 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14732 " with f option returns free memory in bytes",
14733 __FILE__, VMemGpu, group);
85e096c3 14734 theCommands.Add ("vreadpixel",
ba00aab7 14735 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 14736 " : Read pixel value for active view",
14737 __FILE__, VReadPixel, group);
692613e5 14738 theCommands.Add("diffimage",
fd3f6bd0 14739 "diffimage imageFile1 imageFile2 [diffImageFile]"
14740 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14741 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14742 "\n\t\t: Compare two images by content and generate difference image."
14743 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14744 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 14745 __FILE__, VDiffImage, group);
4754e164 14746 theCommands.Add ("vselect",
e76471b5 14747 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-replaceextra|-xor|-add|-remove]\n"
4754e164 14748 "- emulates different types of selection:\n"
14749 "- 1) single click selection\n"
14750 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14751 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 14752 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14753 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14754 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14755 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
e76471b5 14756 "- 5) selection scheme replace, replaceextra, xor, add or remove (replace by default)",
4754e164 14757 __FILE__, VSelect, group);
14758 theCommands.Add ("vmoveto",
8a590580 14759 "vmoveto [x y] [-reset]"
14760 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14761 "\n\t\t: -reset resets current highlighting",
4754e164 14762 __FILE__, VMoveTo, group);
0461e7fd 14763 theCommands.Add ("vselaxis",
14764 "vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14765 "\n\t\t: Provides intersection by given axis and print result intersection points"
14766 "\n\t\t: -onlyTop switches On/Off mode to find only top point or all"
14767 "\n\t\t: -display Name displays intersecting axis and result intersection points for debug goals"
14768 "\n\t\t: -showNormal adds displaying of normal in intersection point or not",
14769 __FILE__, VSelectByAxis, group);
1beb58d7 14770 theCommands.Add ("vviewparams",
14771 "vviewparams [-args] [-scale [s]]"
14772 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14773 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14774 "\n\t\t: Manage current view parameters or prints all"
14775 "\n\t\t: current values when called without argument."
14776 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14777 "\n\t\t: -eye [x y z] prints or sets eye location"
14778 "\n\t\t: -at [x y z] prints or sets center of look"
14779 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14780 "\n\t\t: -proj [x y z] prints or sets direction of look"
14781 "\n\t\t: -center x y sets location of center of the screen in pixels"
14782 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14783 "\n\t\t: or changes the size of its maximum dimension"
14784 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 14785 __FILE__, VViewParams, group);
1beb58d7 14786
2e93433e 14787 theCommands.Add("v2dmode",
14788 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14789 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14790 "\n\t\t: mode - switches On/Off rotation mode"
14791 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14792 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14793 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14794 "\n\t\t: View camera position might be changed only by commands.",
14795 __FILE__, V2DMode, group);
14796
1beb58d7 14797 theCommands.Add("vanimation", "Alias for vanim",
14798 __FILE__, VAnimation, group);
14799
14800 theCommands.Add("vanim",
14801 "List existing animations:"
14802 "\n\t\t: vanim"
14803 "\n\t\t: Animation playback:"
14804 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14805 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14806 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14807 "\n\t\t: -freeLook skip camera animations"
14808 "\n\t\t: -lockLoop disable any interactions"
14809 "\n\t\t:"
14810 "\n\t\t: Animation definition:"
14811 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14812 "\n\t\t: [start TimeSec] [duration TimeSec]"
14813 "\n\t\t:"
14814 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14815 "\n\t\t: specifies nested animations."
14816 "\n\t\t: There is no syntax to explicitly add new animation,"
14817 "\n\t\t: and all non-existing animations within the name will be"
14818 "\n\t\t: implicitly created on first use (including parents)."
14819 "\n\t\t:"
14820 "\n\t\t: Each animation might define the SINGLE action (see below),"
14821 "\n\t\t: like camera transition, object transformation or custom callback."
14822 "\n\t\t: Child animations can be used for defining concurrent actions."
14823 "\n\t\t:"
14824 "\n\t\t: Camera animation:"
14825 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14826 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14827 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14828 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14829 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14830 "\n\t\t: -atX camera Center positions pair"
14831 "\n\t\t: -upX camera Up directions pair"
14832 "\n\t\t: -scaleX camera Scale factors pair"
14833 "\n\t\t: Object animation:"
14834 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14835 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14836 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14837 "\n\t\t: -locX object Location points pair (translation)"
14838 "\n\t\t: -rotX object Orientations pair (quaternions)"
14839 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14840 "\n\t\t: Custom callback:"
14841 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14842 "\n\t\t: %Pts overall animation presentation timestamp"
14843 "\n\t\t: %LocalPts local animation timestamp"
14844 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 14845 "\n\t\t:"
14846 "\n\t\t: Video recording:"
14847 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14848 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14849 "\n\t\t: [-crf Value] [-preset Preset]"
14850 "\n\t\t: -fps video framerate"
14851 "\n\t\t: -format file format, container (matroska, etc.)"
14852 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14853 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14854 "\n\t\t: -crf constant rate factor (specific to codec)"
14855 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 14856 __FILE__, VAnimation, group);
14857
4754e164 14858 theCommands.Add("vchangeselected",
dc3fe572 14859 "vchangeselected shape"
4754e164 14860 "- adds to shape to selection or remove one from it",
14861 __FILE__, VChangeSelected, group);
4754e164 14862 theCommands.Add ("vnbselected",
faea8b40 14863 "vnbselected"
14864 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14865 theCommands.Add ("vcamera",
30a1b24e 14866 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14867 "\n\t\t: [-persp]"
14868 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14869 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14870 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14871 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 14872 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14873 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 14874 "\n\t\t: Manages camera parameters."
4551e1be 14875 "\n\t\t: Displays frustum when presentation name PrsName is specified."
6b62b2da 14876 "\n\t\t: Prints current value when option called without argument."
14877 "\n\t\t: Orthographic camera:"
14878 "\n\t\t: -ortho activate orthographic projection"
14879 "\n\t\t: Perspective camera:"
14880 "\n\t\t: -persp activate perspective projection (mono)"
14881 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 14882 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 14883 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 14884 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 14885 "\n\t\t: Stereoscopic camera:"
14886 "\n\t\t: -stereo perspective projection (stereo)"
14887 "\n\t\t: -leftEye perspective projection (left eye)"
14888 "\n\t\t: -rightEye perspective projection (right eye)"
14889 "\n\t\t: -iod intraocular distance value"
14890 "\n\t\t: -iodType distance type, absolute or relative"
14891 "\n\t\t: -zfocus stereographic focus value"
14892 "\n\t\t: -zfocusType focus type, absolute or relative",
14893 __FILE__, VCamera, group);
b5ac8292 14894 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14895 "- vautozfit [on={1|0}] [scale]\n"
14896 " Prints or changes parameters of automatic z-fit mode:\n"
14897 " \"on\" - turns automatic z-fit on or off\n"
14898 " \"scale\" - specifies factor to scale computed z range.\n",
14899 __FILE__, VAutoZFit, group);
b5ac8292 14900 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14901 " vzrange - without parameters shows current values\n"
14902 " vzrange [znear] [zfar] - applies provided values to view",
14903 __FILE__,VZRange, group);
4754e164 14904 theCommands.Add("vsetviewsize",
14905 "vsetviewsize size",
14906 __FILE__,VSetViewSize,group);
14907 theCommands.Add("vmoveview",
14908 "vmoveview Dx Dy Dz [Start = 1|0]",
14909 __FILE__,VMoveView,group);
14910 theCommands.Add("vtranslateview",
14911 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14912 __FILE__,VTranslateView,group);
14913 theCommands.Add("vturnview",
14914 "vturnview Ax Ay Az [Start = 1|0]",
14915 __FILE__,VTurnView,group);
269294d6 14916 theCommands.Add("vtextureenv",
14917 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14918 "or user-defined file and optionally applying texture mapping parameters\n"
14919 " Usage:\n"
14920 " vtextureenv off - disables environment mapping\n"
14921 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14922 " std_texture = (0..7)\n"
14923 " rep = {clamp|repeat}\n"
14924 " mod = {decal|modulate}\n"
14925 " flt = {nearest|bilinear|trilinear}\n"
14926 " ss, st - scale factors for s and t texture coordinates\n"
14927 " ts, tt - translation for s and t texture coordinates\n"
14928 " rot - texture rotation angle in degrees",
14929 __FILE__, VTextureEnv, group);
1eeef710 14930 theCommands.Add("vhlr",
14931 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14932 "\n\t\t: Hidden Line Removal algorithm."
14933 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14934 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 14935 __FILE__,VHLR,group);
1eeef710 14936 theCommands.Add("vhlrtype",
14937 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14938 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14939 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14940 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14941 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 14942 __FILE__,VHLRType,group);
3e05329c 14943 theCommands.Add("vclipplane",
14944 "vclipplane planeName [{0|1}]"
25c35042 14945 "\n\t\t: [-equation1 A B C D]"
14946 "\n\t\t: [-equation2 A B C D]"
14947 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 14948 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 14949 "\n\t\t: [-maxPlanes]"
14950 "\n\t\t: [-capping {0|1}]"
1b661a81 14951 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 14952 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14953 "\n\t\t: [-texRotate Angle]"
14954 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14955 "\n\t\t: [-useObjShader {0|1}]"
14956 "\n\t\t: Clipping planes management:"
14957 "\n\t\t: -maxPlanes print plane limit for view"
14958 "\n\t\t: -delete delete plane with given name"
14959 "\n\t\t: {off|on|0|1} turn clipping on/off"
14960 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14961 "\n\t\t: applied to active View when list is omitted"
14962 "\n\t\t: -equation A B C D change plane equation"
14963 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14964 "\n\t\t: Capping options:"
14965 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14966 "\n\t\t: -color R G B set capping color"
1b661a81 14967 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 14968 "\n\t\t: -texName Texture set capping texture"
14969 "\n\t\t: -texScale SX SY set capping tex scale"
14970 "\n\t\t: -texOrigin TX TY set capping tex origin"
14971 "\n\t\t: -texRotate Angle set capping tex rotation"
14972 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14973 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14974 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14975 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14976 __FILE__, VClipPlane, group);
392ac980 14977 theCommands.Add("vdefaults",
4c513386 14978 "vdefaults [-absDefl value]"
14979 "\n\t\t: [-devCoeff value]"
14980 "\n\t\t: [-angDefl value]"
14981 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14982 , __FILE__, VDefaults, group);
12381341 14983 theCommands.Add("vlight",
816d03ee 14984 "tool to manage light sources, without arguments shows list of lights."
14985 "\n Main commands: "
992ed6b3 14986 "\n '-clear' to clear lights"
2daa5d95 14987 "\n '-{def}aults' to load default lights"
992ed6b3 14988 "\n '-add' <type> to add any light source"
816d03ee 14989 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
14990 "\n 'change' <lightId> to edit light source with specified lightId"
14991 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 14992 "\n -layer Id"
14993 "\n -{pos}ition X Y Z"
14994 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
14995 "\n -color colorName"
14996 "\n -{head}light 0|1"
d84e8669 14997 "\n -castShadows 0|1"
992ed6b3 14998 "\n -{sm}oothness value"
14999 "\n -{int}ensity value"
15000 "\n -{constAtten}uation value"
15001 "\n -{linearAtten}uation value"
15002 "\n -angle angleDeg"
15003 "\n -{spotexp}onent value"
88b312d3 15004 "\n -range value"
992ed6b3 15005 "\n -local|-global"
2daa5d95 15006 "\n -name value"
15007 "\n -display nameOfLight (display light source with specified nameOfLight or its name)"
15008 "\n -showName {1|0} show/hide the name of light source; 1 by default"
15009 "\n -showRange {1|0} show/hide the range of spot/positional light source; 1 by default"
15010 "\n -prsZoomable {1|0} make light presentation zoomable/non-zoomable"
15011 "\n -prsSize {Value} set light presentation size"
15012 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
992ed6b3 15013 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 15014 __FILE__, VLight, group);
67312b79 15015 theCommands.Add("vpbrenv",
15016 "vpbrenv -clear|-generate"
15017 "\n\t\t: Clears or generates PBR environment map of active view."
15018 "\n\t\t: -clear clears PBR environment (fills by white color)"
15019 "\n\t\t: -generate generates PBR environment from current background cubemap",
15020 __FILE__, VPBREnvironment, group);
6b62b2da 15021 theCommands.Add("vraytrace",
15022 "vraytrace [0|1]"
189f85a3 15023 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 15024 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
15025 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
15026 __FILE__, VRenderParams, group);
bc8c79bb 15027 theCommands.Add("vrenderparams",
4c7a3fae 15028 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
15029 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
15030 "\n\t\t: Common parameters:"
15031 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
d37aef5c 15032 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1]"
15033 "\n\t\t: [-resolution value=72] [-fontHinting {off|normal|light}=off]"
15034 "\n\t\t: [-fontAutoHinting {auto|force|disallow}=auto]"
4c7a3fae 15035 "\n\t\t: [-oit {off|0.0-1.0}=off]"
d84e8669 15036 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
4c7a3fae 15037 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
15038 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
15039 "\n\t\t: [-sync {default|views}] [-reset]"
15040 "\n\t\t: -raster Disables GPU ray-tracing."
15041 "\n\t\t: -shadingModel Controls shading model."
15042 "\n\t\t: -msaa Specifies number of samples for MSAA."
15043 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
15044 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
d37aef5c 15045 "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens."
15046 "\n\t\t: -fontAutoHinting Manages font autohinting."
4c7a3fae 15047 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
15048 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
15049 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
15050 "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result,"
15051 "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)."
d84e8669 15052 "\n\t\t: -shadows Enables/disables shadows rendering."
15053 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
15054 "\n\t\t: -shadowMapBias Shadow map bias."
4c7a3fae 15055 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
15056 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
15057 "\n\t\t: sets state to check structures culled previously."
15058 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
15059 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
15060 "\n\t\t: Diagnostic output (on-screen overlay):"
15061 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
15062 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
15063 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
15064 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
15065 "\n\t\t: -perfUpdateInterval Performance counters update interval."
15066 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
15067 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
15068 "\n\t\t: Ray-Tracing options:"
d84e8669 15069 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
4c7a3fae 15070 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
15071 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
15072 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
15073 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
15074 "\n\t\t: [-maxRad {value>0}=30.0]"
15075 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15076 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15077 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15078 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
4c7a3fae 15079 "\n\t\t: -reflections Enables/disables specular reflections."
15080 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15081 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15082 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15083 "\n\t\t: -env Enables/disables environment map background."
15084 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15085 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15086 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15087 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15088 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15089 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15090 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15091 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15092 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15093 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15094 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15095 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15096 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15097 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15098 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15099 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15100 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15101 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15102 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15103 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15104 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15105 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15106 "\n\t\t: Debug options:"
15107 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15108 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15109 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15110 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 15111 __FILE__, VRenderParams, group);
79b544e6 15112 theCommands.Add("vstatprofiler",
15113 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15114 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 15115 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 15116 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15117 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15118 "\n [-noredraw]"
15119 "\n\t\t: Prints rendering statistics."
15120 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15121 "\n\t\t: else - print all performance counters set previously."
15122 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15123 __FILE__, VStatProfiler, group);
49e1a5c7 15124 theCommands.Add ("vplace",
15125 "vplace dx dy"
15126 "\n\t\t: Places the point (in pixels) at the center of the window",
15127 __FILE__, VPlace, group);
0717ddc1 15128 theCommands.Add("vxrotate",
15129 "vxrotate",
15130 __FILE__,VXRotate,group);
15131
625e1958 15132 theCommands.Add("vmanipulator",
15133 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15134 "\n tool to create and manage AIS manipulators."
15135 "\n Options: "
15136 "\n '-attach AISObject' attach manipulator to AISObject"
ff6122e0 15137 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
625e1958 15138 "\n '-adjustSize {0|1}' adjust size when attaching"
15139 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 15140 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15141 "\n by default it is displayed in all views of the current viewer"
625e1958 15142 "\n '-detach' detach manipulator"
15143 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15144 "\n '-transform mouse_x mouse_y' - invoke transformation"
15145 "\n '-stopTransform [abort]' - invoke stop of transformation"
15146 "\n '-move x y z' - move attached object"
15147 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15148 "\n '-scale factor' - scale attached object"
15149 "\n '-autoActivate {0|1}' - set activation on detection"
15150 "\n '-followTranslation {0|1}' - set following translation transform"
15151 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 15152 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 15153 "\n '-gap value' - set gap between sub-parts"
15154 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 15155 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 15156 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15157 "\n '-size value' - set size of manipulator"
15158 "\n '-zoomable {0|1}' - set zoom persistence",
15159 __FILE__, VManipulator, group);
15160
8e5fb5ea 15161 theCommands.Add("vselprops",
f838dac4 15162 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 15163 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15164 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 15165 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15166 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 15167 "\n -pickStrategy {first|topmost} : defines picking strategy"
15168 "\n 'first' to pick first acceptable (default)"
15169 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 15170 "\n -pixTol value : sets up pixel tolerance"
8c36926a 15171 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15172 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15173 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 15174 "\n -dispMode dispMode : sets display mode for highlighting"
15175 "\n -layer ZLayer : sets ZLayer for highlighting"
15176 "\n -color {name|r g b} : sets highlight color"
15177 "\n -transp value : sets transparency coefficient for highlight"
15178 "\n -material material : sets highlight material"
8e5fb5ea 15179 "\n -print : prints current state of all mentioned parameters",
15180 __FILE__, VSelectionProperties, group);
be3d8cbc 15181 theCommands.Add ("vhighlightselected",
15182 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15183 __FILE__, VSelectionProperties, group);
8e5fb5ea 15184
decdee7d 15185 theCommands.Add ("vseldump",
df23a355 15186 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|surfNormal}=depth -pickedIndex Index=1"
b40cdc2b 15187 "\n\t\t: [-xrPose base|head=base]"
decdee7d 15188 "\n\t\t: Generate an image based on detection results:"
15189 "\n\t\t: depth normalized depth values"
15190 "\n\t\t: unnormDepth unnormalized depth values"
15191 "\n\t\t: object color of detected object"
15192 "\n\t\t: owner color of detected owner"
15193 "\n\t\t: selMode color of selection mode"
114e7a90 15194 "\n\t\t: entity color of etected entity"
15195 "\n\t\t: surfNormal normal direction values",
decdee7d 15196 __FILE__, VDumpSelectionImage, group);
293211ae 15197
2108d9a2 15198 theCommands.Add ("vviewcube",
15199 "vviewcube name"
15200 "\n\t\t: Displays interactive view manipualtion object."
15201 "\n\t\t: Options: "
15202 "\n\t\t: -reset reset geomertical and visual attributes'"
15203 "\n\t\t: -size Size adapted size of View Cube"
15204 "\n\t\t: -boxSize Size box size"
0aeb8984 15205 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
2108d9a2 15206 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15207 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15208 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15209 "\n\t\t: -color Color color of View Cube"
15210 "\n\t\t: -boxColor Color box color"
15211 "\n\t\t: -boxSideColor Color box sides color"
15212 "\n\t\t: -boxEdgeColor Color box edges color"
15213 "\n\t\t: -boxCornerColor Color box corner color"
15214 "\n\t\t: -textColor Color color of side text of view cube"
15215 "\n\t\t: -innerColor Color inner box color"
15216 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15217 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
0aeb8984 15218 "\n\t\t: -xAxisTextColor Color color of X axis label"
15219 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15220 "\n\t\t: -zAxisTextColor Color color of Z axis label"
2108d9a2 15221 "\n\t\t: -font Name font name"
15222 "\n\t\t: -fontHeight Value font height"
15223 "\n\t\t: -boxFacetExtension Value box facet extension"
15224 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15225 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15226 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15227 "\n\t\t: -axesPadding Value padding between box and arrows"
15228 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15229 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15230 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15231 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15232 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15233 "\n\t\t: -duration Seconds animation duration in seconds",
15234 __FILE__, VViewCube, group);
15235
14b741b0 15236 theCommands.Add("vcolorconvert" ,
15237 "vcolorconvert {from|to} type C1 C2 C2"
15238 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15239 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15240 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15241 __FILE__,VColorConvert,group);
15242 theCommands.Add("vcolordiff" ,
15243 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15244 __FILE__,VColorDiff,group);
6a2fb7a1 15245 theCommands.Add("vselbvhbuild",
15246 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15247 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15248 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15249 "\n\t\t: -wait waits for building all of BVH",
15250 __FILE__,VSelBvhBuild,group);
2108d9a2 15251}