0031779: Visualization, AIS_ViewController - controller should handle selection schemes
[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
58655684 17#include <OpenGl_GlCore20.hxx>
49582f9d 18#include <ViewerTest.hxx>
1beb58d7 19
1beb58d7 20#include <AIS_AnimationCamera.hxx>
21#include <AIS_AnimationObject.hxx>
30a1b24e 22#include <AIS_CameraFrustum.hxx>
7a324550 23#include <AIS_ColorScale.hxx>
49582f9d 24#include <AIS_InteractiveContext.hxx>
2daa5d95 25#include <AIS_LightSource.hxx>
0a768f56 26#include <AIS_ListOfInteractive.hxx>
27#include <AIS_ListIteratorOfListOfInteractive.hxx>
49582f9d 28#include <AIS_Manipulator.hxx>
2108d9a2 29#include <AIS_ViewCube.hxx>
49582f9d 30#include <AIS_Shape.hxx>
31#include <Aspect_DisplayConnection.hxx>
8a590580 32#include <Aspect_Grid.hxx>
49582f9d 33#include <Aspect_TypeOfLine.hxx>
34#include <Draw.hxx>
35#include <Draw_Appli.hxx>
36#include <Draw_Interpretor.hxx>
08f8a185 37#include <Draw_ProgressIndicator.hxx>
49582f9d 38#include <gp_Dir.hxx>
39#include <gp_Pln.hxx>
40#include <gp_Pnt.hxx>
61b0191c 41#include <Graphic3d_ArrayOfPolylines.hxx>
49582f9d 42#include <Graphic3d_AspectFillArea3d.hxx>
2bd4c032 43#include <Graphic3d_AspectMarker3d.hxx>
49582f9d 44#include <Graphic3d_ClipPlane.hxx>
077a220c 45#include <Graphic3d_CubeMapPacked.hxx>
46#include <Graphic3d_CubeMapSeparate.hxx>
a79f67f8 47#include <Graphic3d_GraduatedTrihedron.hxx>
49582f9d 48#include <Graphic3d_NameOfTextureEnv.hxx>
49#include <Graphic3d_Texture2Dmanual.hxx>
269294d6 50#include <Graphic3d_TextureEnv.hxx>
51#include <Graphic3d_TextureParams.hxx>
52#include <Graphic3d_TypeOfTextureFilter.hxx>
49582f9d 53#include <Image_AlienPixMap.hxx>
54#include <Image_Diff.hxx>
55#include <Image_VideoRecorder.hxx>
7e785937 56#include <Message_ProgressScope.hxx>
57#include <Message_ProgressRange.hxx>
49582f9d 58#include <NCollection_DataMap.hxx>
18d715bd 59#include <NCollection_List.hxx>
d6fbb2ab 60#include <NCollection_LocalArray.hxx>
18d715bd 61#include <NCollection_Vector.hxx>
8693dfd0 62#include <OSD.hxx>
6a2fb7a1 63#include <OSD_Parallel.hxx>
208e6839 64#include <OSD_Timer.hxx>
49582f9d 65#include <OpenGl_GraphicDriver.hxx>
4269bd1b 66#include <Prs3d_ShadingAspect.hxx>
0aeb8984 67#include <Prs3d_DatumAspect.hxx>
6262338c 68#include <Prs3d_Drawer.hxx>
61b0191c 69#include <Prs3d_LineAspect.hxx>
fd3f6bd0 70#include <Prs3d_Text.hxx>
71#include <Select3D_SensitivePrimitiveArray.hxx>
49582f9d 72#include <TColStd_HSequenceOfAsciiString.hxx>
73#include <TColStd_SequenceOfInteger.hxx>
74#include <TColStd_HSequenceOfReal.hxx>
75#include <TColgp_Array1OfPnt2d.hxx>
76#include <TColStd_MapOfAsciiString.hxx>
77#include <ViewerTest_AutoUpdater.hxx>
08b7a39f 78#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 79#include <ViewerTest_EventManager.hxx>
80#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
81#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
82#include <ViewerTest_CmdParser.hxx>
83#include <ViewerTest_V3dView.hxx>
84#include <V3d_AmbientLight.hxx>
85#include <V3d_DirectionalLight.hxx>
86#include <V3d_PositionalLight.hxx>
87#include <V3d_SpotLight.hxx>
0aeb8984 88#include <V3d_Trihedron.hxx>
7fd59977 89
293211ae 90#include <tcl.h>
91
692613e5 92#include <cstdlib>
25289ec1 93
58655684 94#if defined(_WIN32)
4fe56619 95 #include <WNT_WClass.hxx>
96 #include <WNT_Window.hxx>
d6fbb2ab 97 #include <WNT_HIDSpaceMouse.hxx>
4fe56619 98#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 99 #include <Cocoa_Window.hxx>
7fd59977 100#else
4fe56619 101 #include <Xw_Window.hxx>
102 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
103 #include <X11/Xutil.h>
104 #include <tk.h>
7fd59977 105#endif
106
7fd59977 107//==============================================================================
108// VIEWER GLOBAL VARIABLES
109//==============================================================================
110
111Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 112Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 113
114Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 115extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 116
58655684 117#if defined(_WIN32)
7fd59977 118static Handle(WNT_Window)& VT_GetWindow() {
119 static Handle(WNT_Window) WNTWin;
120 return WNTWin;
121}
4fe56619 122#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 123static Handle(Cocoa_Window)& VT_GetWindow()
124{
125 static Handle(Cocoa_Window) aWindow;
126 return aWindow;
127}
128extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 129extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
130
7fd59977 131#else
7fd59977 132static Handle(Xw_Window)& VT_GetWindow(){
133 static Handle(Xw_Window) XWWin;
134 return XWWin;
135}
7fd59977 136
137static void VProcessEvents(ClientData,int);
138#endif
139
18d715bd 140static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
141{
142 static Handle(Aspect_DisplayConnection) aDisplayConnection;
143 return aDisplayConnection;
144}
145
146static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
147{
148 GetDisplayConnection() = theDisplayConnection;
149}
150
18d715bd 151NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 152static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 153static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
58655684 154static OpenGl_Caps ViewerTest_myDefaultCaps;
18d715bd 155
7fd59977 156static void OSWindowSetup();
157
f42753ed 158static struct
159{
160 Quantity_Color FlatColor;
161 Quantity_Color GradientColor1;
162 Quantity_Color GradientColor2;
163 Aspect_GradientFillMethod FillMethod;
164} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
165
7fd59977 166//==============================================================================
167// EVENT GLOBAL VARIABLES
168//==============================================================================
169
1beb58d7 170Standard_Boolean TheIsAnimating = Standard_False;
7fd59977 171
293211ae 172namespace
173{
174
175 //! Checks if some set is a subset of other set
176 //! @tparam TheSuperSet the type of the superset
177 //! @tparam TheSubSet the type of the subset
178 //! @param theSuperSet the superset
179 //! @param theSubSet the subset to be checked
180 //! @return true if the superset includes subset, or false otherwise
181 template <typename TheSuperSet, typename TheSubSet>
182 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
183 {
184 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
185 }
186
187 //! A variable set of keys for command-line options.
188 //! It includes a set of mandatory keys and a set of all possible keys.
189 class CommandOptionKeyVariableSet
190 {
191 public:
192 //! Default constructor
193 CommandOptionKeyVariableSet()
194 {
195 }
196
197 //! Constructor
198 //! @param theMandatoryKeySet the set of the mandatory option keys
199 //! @param theAdditionalKeySet the set of additional options that could be omitted
200 CommandOptionKeyVariableSet (
201 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
202 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
203 : myMandatoryKeySet (theMandatoryKeySet)
204 {
205 std::set_union (theMandatoryKeySet.begin(),
206 theMandatoryKeySet.end(),
207 theAdditionalKeySet.begin(),
208 theAdditionalKeySet.end(),
209 std::inserter (myFullKeySet, myFullKeySet.begin()));
210 }
211
212 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
213 //! and be contained in the full key set)
214 //! @param theCheckedKeySet the set of option keys to be checked
215 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
216 {
217 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
218 }
219
220 private:
221 //! A set of mandatory command-line option keys
222 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
223
224 //! A full set of command-line option keys (includes mandatory and additional option keys)
225 ViewerTest_CommandOptionKeySet myFullKeySet;
226 };
227
228 //! Gets some code by its name
229 //! @tparam TheCode the type of a code to be found
230 //! @param theCodeNameMap the map from code names to codes
231 //! @param theCodeName the name of a code to be found
232 //! @param theCode the code to be found
233 //! @return true if a code is found, or false otherwise
234 template <typename TheCode>
235 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
236 TCollection_AsciiString theCodeName,
237 TheCode& theCode)
238 {
239 theCodeName.LowerCase();
240 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
241 theCodeName);
242 if (aCodeIterator == theCodeNameMap.end())
243 {
244 return false;
245 }
246 theCode = aCodeIterator->second;
247 return true;
248 }
249
250 // Defines possible commands related to background changing
251 enum BackgroundCommand
252 {
077a220c 253 BackgroundCommand_Main, //!< The main command that manages other commands through options
254 BackgroundCommand_Image, //!< Sets an image as a background
255 BackgroundCommand_ImageMode, //!< Changes a background image mode
256 BackgroundCommand_Gradient, //!< Sets a gradient as a background
257 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
258 BackgroundCommand_Color, //!< Fills background with a specified color
259 BackgroundCommand_Default //!< Sets the background default color or gradient
293211ae 260 };
261
262 //! Map from background command names to its codes
263 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
264
265 //! Creates a map from background command names to its codes
266 //! @return a map from background command names to its codes
267 static BackgroundCommandNameMap createBackgroundCommandNameMap()
268 {
269 BackgroundCommandNameMap aBackgroundCommandNameMap;
077a220c 270 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
271 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
272 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
273 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
274 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
275 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
276 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
293211ae 277 return aBackgroundCommandNameMap;
278 }
279
280 //! Gets a background command by its name
281 //! @param theBackgroundCommandName the name of the background command
282 //! @param theBackgroundCommand the background command to be found
283 //! @return true if a background command is found, or false otherwise
284 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
285 BackgroundCommand& theBackgroundCommand)
286 {
287 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
288 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
289 }
290
291 //! Map from background image fill method names to its codes
292 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
293
294 //! Creates a map from background image fill method names to its codes
295 //! @return a map from background image fill method names to its codes
296 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
297 {
298 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
299 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
300 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
301 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
302 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
303 return aBackgroundImageFillMethodNameMap;
304 }
305
306 //! Gets a background image fill method by its name
307 //! @param theBackgroundImageFillMethodName the name of the background image fill method
308 //! @param theBackgroundImageFillMethod the background image fill method to be found
309 //! @return true if a background image fill method is found, or false otherwise
310 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
311 Aspect_FillMethod& theBackgroundImageFillMethod)
312 {
313 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
314 createBackgroundImageFillMethodNameMap();
315 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
316 theBackgroundImageFillMethodName,
317 theBackgroundImageFillMethod);
318 }
319
320 //! Map from background gradient fill method names to its codes
321 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
322
323 //! Creates a map from background gradient fill method names to its codes
324 //! @return a map from background gradient fill method names to its codes
325 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
326 {
327 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
328 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
329 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
330 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
331 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
332 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
333 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
334 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
335 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
336 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
337 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
338 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
339 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
340 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
341 return aBackgroundGradientFillMethodNameMap;
342 }
343
344 //! Gets a gradient fill method by its name
345 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
346 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
347 //! @return true if a gradient fill method is found, or false otherwise
348 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
349 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
350 {
351 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
352 createBackgroundGradientFillMethodNameMap();
353 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
354 theBackgroundGradientFillMethodName,
355 theBackgroundGradientFillMethod);
356 }
357
358 //! Changes the background in accordance with passed command line options
359 class BackgroundChanger
360 {
361 public:
362 //! Constructor. Prepares the command parser
363 BackgroundChanger()
364 {
365 prepareCommandParser();
366 }
367
368 //! Processes the command line and changes the background
369 //! @param theDrawInterpretor the interpreter of the Draw Harness application
370 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
371 //! @param theCommandLineArguments the array of command line arguments
372 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
373 const Standard_Integer theNumberOfCommandLineArguments,
374 const char* const* const theCommandLineArguments)
375 {
376 const char* const aBackgroundCommandName = theCommandLineArguments[0];
377 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
378 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
379 {
380 return false;
381 }
382 addCommandDescription (aBackgroundCommand);
383 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
384 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
385 }
386
387 private:
388 //! The type of functions that are able to set gradient background filling
389 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
390 const Quantity_Color& /* theColor2 */,
391 const Aspect_GradientFillMethod /* theGradientMode */);
392
393 //! The type of functions that are able to fill a background with a specific color
394 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
395
396 //! the command parser used to parse command line options and its arguments
397 ViewerTest_CmdParser myCommandParser;
398
399 //! the option key for the command that sets an image as a background
400 ViewerTest_CommandOptionKey myImageOptionKey;
401
402 //! the option key for the command that sets a background image fill type
403 ViewerTest_CommandOptionKey myImageModeOptionKey;
404
405 //! the option key for the command that sets a gradient filling for the background
406 ViewerTest_CommandOptionKey myGradientOptionKey;
407
408 //! the option key for the command that sets a background gradient filling method
409 ViewerTest_CommandOptionKey myGradientModeOptionKey;
410
411 //! the option key for the command that fills background with a specific color
412 ViewerTest_CommandOptionKey myColorOptionKey;
413
414 //! the option key for the command that sets default background gradient or color
415 ViewerTest_CommandOptionKey myDefaultOptionKey;
416
077a220c 417 //! the option key for the command that sets an environment cubemap as a background
418 ViewerTest_CommandOptionKey myCubeMapOptionKey;
419
420 //! the option key for the command that defines order of tiles in one image packed cubemap
421 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
422
423 //! the option key for the command that sets inversion of Z axis for background cubemap
424 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
425
67312b79 426 //! the option key for the command that allows skip IBL map generation
427 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
428
293211ae 429 //! the variable set of options that are allowed for the old scenario (without any option passed)
430 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
431
077a220c 432 //! the variable set of options that are allowed for setting an environment cubemap as background
433 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
434
293211ae 435 //! the variable set of options that are allowed for setting an image as a background
436 CommandOptionKeyVariableSet myImageOptionVariableSet;
437
438 //! the variable set of options that are allowed for setting a background image fill type
439 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
440
441 //! the variable set of options that are allowed for setting a gradient filling for the background
442 CommandOptionKeyVariableSet myGradientOptionVariableSet;
443
444 //! the variable set of options that are allowed for setting a background gradient filling method
445 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
446
447 //! the variable set of options that are allowed for filling a background with a specific color
448 CommandOptionKeyVariableSet myColorOptionVariableSet;
449
450 //! the variable set of options that are allowed for setting a default background gradient
451 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
452
453 //! the variable set of options that are allowed for setting a default background color
454 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
455
456 //! the variable set of options that are allowed for printing help
457 CommandOptionKeyVariableSet myHelpOptionVariableSet;
458
459 //! Adds options to command parser
460 void addOptionsToCommandParser()
461 {
462 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
463 "filename of image used as background");
464 myImageModeOptionKey = myCommandParser.AddOption (
465 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
466 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
467 "sets background gradient starting and ending colors");
468 myGradientModeOptionKey =
469 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
470 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
471 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
472 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
473 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
077a220c 474
475 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
476 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
477 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
478 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
67312b79 479 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
293211ae 480 }
481
482 //! Creates option sets used to determine if a passed option set is valid or not
483 void createOptionSets()
484 {
485 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
486 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
487 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
488
077a220c 489 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
490 aCubeMapOptionSet.insert (myCubeMapOptionKey);
491 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
492 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
67312b79 493 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
077a220c 494 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
495 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
496
293211ae 497 ViewerTest_CommandOptionKeySet anImageOptionSet;
498 anImageOptionSet.insert (myImageOptionKey);
499 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
500 anImageModeOptionSet.insert (myImageModeOptionKey);
501 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
502 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
503
504 ViewerTest_CommandOptionKeySet aGradientOptionSet;
505 aGradientOptionSet.insert (myGradientOptionKey);
506 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
507 aGradientModeOptionSet.insert (myGradientModeOptionKey);
508 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
509 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
510
511 ViewerTest_CommandOptionKeySet aColorOptionSet;
512 aColorOptionSet.insert (myColorOptionKey);
513 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
514
515 aGradientOptionSet.insert (myDefaultOptionKey);
516 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
517 aColorOptionSet.insert (myDefaultOptionKey);
518 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
519
520 ViewerTest_CommandOptionKeySet aHelpOptionSet;
521 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
522 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
523 }
524
525 //! Prepares the command parser. Adds options and creates option sets used to determine
526 //! if a passed option set is valid or not
527 void prepareCommandParser()
528 {
529 addOptionsToCommandParser();
530 createOptionSets();
531 }
532
533 //! Adds a command description to the command parser
534 //! @param theBackgroundCommand the key of the command which description is added to the command parser
535 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
536 {
537 std::string aDescription;
538 bool isMainCommand = false;
539 switch (theBackgroundCommand)
540 {
541 case BackgroundCommand_Main:
542 aDescription = "Command: vbackground (changes background or some background settings)";
543 isMainCommand = true;
544 break;
545 case BackgroundCommand_Image:
546 aDescription = "Command: vsetbg (loads image as a background)";
547 break;
548 case BackgroundCommand_ImageMode:
549 aDescription = "Command: vsetbgmode (changes background fill type)";
550 break;
551 case BackgroundCommand_Gradient:
552 aDescription = "Command: vsetgradientbg (mounts gradient background)";
553 break;
554 case BackgroundCommand_GradientMode:
555 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
556 break;
557 case BackgroundCommand_Color:
558 aDescription = "Command: vsetcolorbg (sets color background)";
559 break;
560 case BackgroundCommand_Default:
561 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
562 break;
563 default:
564 return;
565 }
566 if (!isMainCommand)
567 {
568 aDescription += "\nThis command is obsolete. Use vbackground instead.";
569 }
570 myCommandParser.SetDescription (aDescription);
571 }
572
573 //! Check if a viewer is needed to be initialized
574 //! @param theBackgroundCommand the key of the command that changes the background
575 //! @return true if processing was successful, or false otherwise
576 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
577 {
578 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
579 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
580 const bool aViewerIsNotNeeded =
581 (theBackgroundCommand == BackgroundCommand_Default)
582 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
583 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
584 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
585 return !aViewerIsNotNeeded;
586 }
587
588 //! Check if a viewer is initialized
589 //! @param theBackgroundCommandName the name of the command that changes the background
590 //! @param theDrawInterpretor the interpreter of the Draw Harness application
591 //! @return true if a viewer is initialized, or false otherwise
592 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
593 Draw_Interpretor& theDrawInterpretor)
594 {
595 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
596 if (anAISContext.IsNull())
597 {
598 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
599 return false;
600 }
601 return true;
602 }
603
604 //! Processes command options
605 //! @param theBackgroundCommandName the name of the command that changes the background
606 //! @param theBackgroundCommand the key of the command that changes the background
607 //! @param theDrawInterpretor the interpreter of the Draw Harness application
608 //! @return true if processing was successful, or false otherwise
609 bool processCommandOptions (const char* const theBackgroundCommandName,
610 const BackgroundCommand theBackgroundCommand,
611 Draw_Interpretor& theDrawInterpretor) const
612 {
613 if (myCommandParser.HasNoOption())
614 {
615 return printHelp (theBackgroundCommandName, theDrawInterpretor);
616 }
617 if (checkViewerIsNeeded (theBackgroundCommand)
618 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
619 {
620 return false;
621 }
622 if (myCommandParser.HasOnlyUnnamedOption())
623 {
624 return processUnnamedOption (theBackgroundCommand);
625 }
626 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
627 }
628
629 //! Processes the unnamed option
630 //! @param theBackgroundCommand the key of the command that changes the background
631 //! @return true if processing was successful, or false otherwise
632 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
633 {
634 switch (theBackgroundCommand)
635 {
636 case BackgroundCommand_Main:
637 return false;
638 case BackgroundCommand_Image:
639 return processImageUnnamedOption();
640 case BackgroundCommand_ImageMode:
641 return processImageModeUnnamedOption();
642 case BackgroundCommand_Gradient:
643 return processGradientUnnamedOption();
644 case BackgroundCommand_GradientMode:
645 return processGradientModeUnnamedOption();
646 case BackgroundCommand_Color:
647 return processColorUnnamedOption();
648 case BackgroundCommand_Default:
649 return processDefaultUnnamedOption();
650 default:
651 return false;
652 }
653 }
654
655 //! Processes the image unnamed option
656 //! @return true if processing was successful, or false otherwise
657 bool processImageUnnamedOption() const
658 {
659 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
660 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
661 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
662 {
663 return false;
664 }
665 std::string anImageFileName;
666 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
667 {
668 return false;
669 }
670 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
671 if (aNumberOfImageUnnamedOptionArguments == 2)
672 {
673 std::string anImageModeString;
674 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
675 {
676 return false;
677 }
678 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
679 {
680 return false;
681 }
682 }
683 setImage (anImageFileName.c_str(), anImageMode);
684 return true;
685 }
686
687 //! Processes the image mode unnamed option
688 //! @return true if processing was successful, or false otherwise
689 bool processImageModeUnnamedOption() const
690 {
691 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
692 }
693
694 //! Processes the gradient unnamed option
695 //! @param theSetGradient the function used to set a background gradient filling
696 //! @return true if processing was successful, or false otherwise
697 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
698 {
699 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
700 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
701 if (aNumberOfGradientUnnamedOptionArguments < 2)
702 {
703 return false;
704 }
705
706 Standard_Integer anArgumentIndex = 0;
707 Quantity_Color aColor1;
708 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
709 {
710 return false;
711 }
712 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
713 {
714 return false;
715 }
716
717 Quantity_Color aColor2;
718 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
719 {
720 return false;
721 }
722 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
723 {
724 return false;
725 }
726
727 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
728 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
729 {
730 std::string anGradientModeString;
731
732 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
733 anArgumentIndex,
734 anGradientModeString))
735 {
736 return false;
737 }
738 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
739 {
740 return false;
741 }
742 ++anArgumentIndex;
743 }
744 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
745 {
746 return false;
747 }
748 theSetGradient (aColor1, aColor2, aGradientMode);
749 return true;
750 }
751
752 //! Processes the gradient mode unnamed option
753 //! @return true if processing was successful, or false otherwise
754 bool processGradientModeUnnamedOption() const
755 {
756 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
757 }
758
759 //! Processes the color unnamed option
760 //! @param theSetColor the function used to set a background color
761 //! @return true if processing was successful, or false otherwise
762 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
763 {
764 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
765 }
766
767 //! Processes the default back unnamed option
768 //! @return true if processing was successful, or false otherwise
769 bool processDefaultUnnamedOption() const
770 {
771 if (processGradientUnnamedOption (setDefaultGradient))
772 {
773 return true;
774 }
775 return processColorUnnamedOption (setDefaultColor);
776 }
777
778 //! Processes named options
779 //! @param theBackgroundCommandName the name of the command that changes the background
780 //! @param theBackgroundCommand the key of the command that changes the background
781 //! @param theDrawInterpretor the interpreter of the Draw Harness application
782 //! @return true if processing was successful, or false otherwise
783 bool processNamedOptions (const char* const theBackgroundCommandName,
784 const BackgroundCommand theBackgroundCommand,
785 Draw_Interpretor& theDrawInterpretor) const
786 {
787 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
788 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
077a220c 789 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
790 {
791 return processCubeMapOptionSet();
792 }
293211ae 793 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
794 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
795 {
796 return processImageOptionSet();
797 }
798 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
799 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
800 {
801 return processImageModeOptionSet();
802 }
803 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
804 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
805 {
806 return processGradientOptionSet();
807 }
808 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
809 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
810 {
811 return processGradientModeOptionSet();
812 }
813 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
814 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
815 {
816 return processColorOptionSet();
817 }
818 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
819 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
820 && (theBackgroundCommand == BackgroundCommand_Default)))
821 {
822 return processDefaultGradientOptionSet();
823 }
824 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
825 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
826 {
827 return processDefaultColorOptionSet();
828 }
829 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
830 {
831 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
832 }
833 return false;
834 }
835
077a220c 836 //! Process the cubemap option set in named and unnamed case.
837 //! @return true if processing was successful, or false otherwise
838 bool processCubeMapOptionSet() const
839 {
840 NCollection_Array1<TCollection_AsciiString> aFilePaths;
841
842 if (!processCubeMapOptions (aFilePaths))
843 {
844 return false;
845 }
846
847 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
848
849 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
850 {
851 if (!processCubeMapOrderOptions (anOrder))
852 {
853 return false;
854 }
855 }
856
857 bool aZIsInverted = false;
858 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
859 {
860 if (!processCubeMapInvertedZOptionSet())
861 {
862 return false;
863 }
864 aZIsInverted = true;
865 }
866
67312b79 867 bool aToGenPBREnv = true;
868 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
869 {
870 if (!processCubeMapDoNotGenPBREnvOptionSet())
871 {
872 return false;
873 }
874 aToGenPBREnv = false;
875 }
876
877 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
077a220c 878 return true;
879 }
880
293211ae 881 //! Processes the image option set
882 //! @return true if processing was successful, or false otherwise
883 bool processImageOptionSet() const
884 {
885 std::string anImageFileName;
886 if (!processImageOption (anImageFileName))
887 {
888 return false;
889 }
890 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
891 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
892 {
893 return false;
894 }
895 setImage (anImageFileName.c_str(), anImageMode);
896 return true;
897 }
898
899 //! Processes the image mode option set
900 //! @return true if processing was successful, or false otherwise
901 bool processImageModeOptionSet() const
902 {
903 return processImageModeOptionSet (myImageModeOptionKey);
904 }
905
906 //! Processes the image mode option set
907 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
908 //! @return true if processing was successful, or false otherwise
909 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
910 {
911 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
912 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
913 {
914 return false;
915 }
916 setImageMode (anImageMode);
917 return true;
918 }
919
920 //! Processes the gradient option set
921 //! @param theSetGradient the function used to set a background gradient filling
922 //! @return true if processing was successful, or false otherwise
923 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
924 {
925 Quantity_Color aColor1;
926 Quantity_Color aColor2;
927 if (!processGradientOption (aColor1, aColor2))
928 {
929 return false;
930 }
931 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
932 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
933 {
934 return false;
935 }
936 theSetGradient (aColor1, aColor2, aGradientMode);
937 return true;
938 }
939
940 //! Processes the gradient mode option set
941 //! @return true if processing was successful, or false otherwise
942 bool processGradientModeOptionSet() const
943 {
944 return processGradientModeOptionSet (myGradientModeOptionKey);
945 }
946
947 //! Processes the gradient mode option set
948 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
949 //! @return true if processing was successful, or false otherwise
950 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
951 {
952 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
953 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
954 {
955 return false;
956 }
957 setGradientMode (aGradientMode);
958 return true;
959 }
960
961 //! Processes the color option set
962 //! @param theSetColor the function used to set a background color
963 //! @return true if processing was successful, or false otherwise
964 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
965 {
966 return processColorOptionSet (myColorOptionKey, theSetColor);
967 }
968
969 //! Processes the default color option set
970 //! @return true if processing was successful, or false otherwise
971 bool processDefaultGradientOptionSet() const
972 {
973 return processGradientOptionSet (setDefaultGradient);
974 }
975
976 //! Processes the default gradient option set
977 //! @return true if processing was successful, or false otherwise
978 bool processDefaultColorOptionSet() const
979 {
980 return processColorOptionSet (setDefaultColor);
981 }
982
983 //! Processes the color option set
984 //! @param theColorOptionKey the key of the option that is interpreted as a color option
985 //! @param theSetColor the function used to set a background color
986 //! @return true if processing was successful, or false otherwise
987 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
988 SetColorFunction* const theSetColor = setColor) const
989 {
990 Quantity_Color aColor;
991 if (!processColorOption (theColorOptionKey, aColor))
992 {
993 return false;
994 }
995 theSetColor (aColor);
996 return true;
997 }
998
999 //! Processes the help option set
1000 //! @param theBackgroundCommandName the name of the command that changes the background
1001 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1002 //! @return true if processing was successful, or false otherwise
1003 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1004 {
1005 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1006 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1007 if (aNumberOfHelpOptionArguments != 0)
1008 {
1009 return false;
1010 }
1011 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1012 }
1013
077a220c 1014 //! Processes the cubemap option
1015 //! @param theFilePaths the array of filenames of cubemap sides
1016 //! @return true if processing was successful, or false otherwise
1017 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1018 {
1019 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1020
1021 if (aNumberOfCubeMapOptionArguments != 1
1022 && aNumberOfCubeMapOptionArguments != 6)
1023 {
1024 return false;
1025 }
1026
1027 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1028
1029 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1030 {
1031 std::string aCubeMapFileName;
1032 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1033 {
1034 return false;
1035 }
1036 theFilePaths[i] = aCubeMapFileName.c_str();
1037 }
1038
1039 return true;
1040 }
1041
67312b79 1042 //! Processes the inverted z cubemap option
077a220c 1043 //! @return true if processing was successful, or false otherwise
1044 bool processCubeMapInvertedZOptionSet () const
1045 {
1046 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1047 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1048
1049 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1050 {
1051 return false;
1052 }
1053
1054 return true;
1055 }
1056
67312b79 1057 //! Processes the option allowing to skip IBM maps generation
1058 //! @return true if processing was successful, or false otherwise
1059 bool processCubeMapDoNotGenPBREnvOptionSet() const
1060 {
1061 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1062 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1063
1064 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1065 {
1066 return false;
1067 }
1068
1069 return true;
1070 }
1071
077a220c 1072 //! Processes the tiles order option
1073 //! @param theOrder the array of indexes if cubemap sides in tile grid
1074 //! @return true if processing was successful, or false otherwise
1075 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1076 {
1077 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1078 myCubeMapOrderOptionKey);
1079
1080 if (aNumberOfCubeMapOrderOptionArguments != 6)
1081 {
1082 return false;
1083 }
1084
1085
1086 for (unsigned int i = 0; i < 6; ++i)
1087 {
1088 std::string anOrderItem;
1089 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1090 {
1091 return false;
1092 }
1093
1094 theOrder.Set (Graphic3d_CubeMapSide (i),
1095 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1096 }
1097
1098 return theOrder.IsValid();
1099 }
1100
293211ae 1101 //! Processes the image option
1102 //! @param theImageFileName the filename of the image to be used as a background
1103 //! @return true if processing was successful, or false otherwise
1104 bool processImageOption (std::string& theImageFileName) const
1105 {
1106 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1107 myImageOptionKey);
1108 if (aNumberOfImageOptionArguments != 1)
1109 {
1110 return false;
1111 }
1112 std::string anImageFileName;
1113 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1114 {
1115 return false;
1116 }
1117 theImageFileName = anImageFileName;
1118 return true;
1119 }
1120
1121 //! Processes the image mode option
1122 //! @param theImageMode the fill type used for a background image
1123 //! @return true if processing was successful, or false otherwise
1124 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1125 {
1126 return processImageModeOption (myImageModeOptionKey, theImageMode);
1127 }
1128
1129 //! Processes the image mode option
1130 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1131 //! @param theImageMode the fill type used for a background image
1132 //! @return true if processing was successful, or false otherwise
1133 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1134 Aspect_FillMethod& theImageMode) const
1135 {
1136 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1137 }
1138
1139 //! Processes the gradient option
1140 //! @param theColor1 the gradient starting color
1141 //! @param theColor2 the gradient ending color
1142 //! @return true if processing was successful, or false otherwise
1143 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1144 {
1145 Standard_Integer anArgumentIndex = 0;
1146 Quantity_Color aColor1;
1147 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1148 {
1149 return false;
1150 }
1151 Quantity_Color aColor2;
1152 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1153 {
1154 return false;
1155 }
1156 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1157 myGradientOptionKey);
1158 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1159 {
1160 return false;
1161 }
1162 theColor1 = aColor1;
1163 theColor2 = aColor2;
1164 return true;
1165 }
1166
1167 //! Processes the gradient mode option
1168 //! @param theGradientMode the fill method used for a background gradient filling
1169 //! @return true if processing was successful, or false otherwise
1170 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1171 {
1172 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1173 }
1174
1175 //! Processes the gradient mode option
1176 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1177 //! @param theGradientMode the fill method used for a background gradient filling
1178 //! @return true if processing was successful, or false otherwise
1179 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1180 Aspect_GradientFillMethod& theGradientMode) const
1181 {
1182 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1183 }
1184
1185 //! Processes some mode option
1186 //! @tparam TheMode the type of a mode to be processed
1187 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1188 //! @param theMode a mode to be processed
1189 //! @return true if processing was successful, or false otherwise
1190 template <typename TheMode>
1191 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1192 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1193 TheMode& /* theMode */),
1194 TheMode& theMode) const
1195 {
1196 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1197 theModeOptionKey);
1198 if (aNumberOfModeOptionArguments != 1)
1199 {
1200 return false;
1201 }
1202 std::string aModeString;
1203 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1204 {
1205 return false;
1206 }
1207 TheMode aMode = TheMode();
1208 if (!theGetModeByName (aModeString.c_str(), aMode))
1209 {
1210 return false;
1211 }
1212 theMode = aMode;
1213 return true;
1214 }
1215
1216 //! Processes the color option
1217 //! @param theColor a color used for filling a background
1218 //! @return true if processing was successful, or false otherwise
1219 bool processColorOption (Quantity_Color& theColor) const
1220 {
1221 return processColorOption (myColorOptionKey, theColor);
1222 }
1223
1224 //! Processes the color option
1225 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1226 //! @param theColor a color used for filling a background
1227 //! @return true if processing was successful, or false otherwise
1228 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1229 {
1230 Standard_Integer anArgumentIndex = 0;
1231 Quantity_Color aColor;
1232 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1233 {
1234 return false;
1235 }
1236 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1237 theColorOptionKey);
1238 if (anArgumentIndex != aNumberOfColorOptionArguments)
1239 {
1240 return false;
1241 }
1242 theColor = aColor;
1243 return true;
1244 }
1245
1246 //! Prints helping message
1247 //! @param theBackgroundCommandName the name of the command that changes the background
1248 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1249 //! @return true if printing was successful, or false otherwise
1250 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1251 {
1252 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1253 }
1254
077a220c 1255 //! Sets the cubemap as a background
1256 //! @param theFileNames the array of filenames of packed or multifile cubemap
1257 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1258 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1259 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
67312b79 1260 bool theZIsInverted = false,
1261 bool theToGenPBREnv = true)
077a220c 1262 {
1263 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1264 Handle(Graphic3d_CubeMap) aCubeMap;
1265
1266 if (theFileNames.Size() == 1)
1267 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1268 else
1269 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1270
1271 aCubeMap->SetZInversion (theZIsInverted);
1272
1273 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1274 aCubeMap->GetParams()->SetRepeat(Standard_False);
1275 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1276
67312b79 1277 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
077a220c 1278 }
1279
293211ae 1280 //! Sets the image as a background
1281 //! @param theImageFileName the filename of the image to be used as a background
1282 //! @param theImageMode the fill type used for a background image
1283 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1284 {
1285 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1286 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1287 }
1288
1289 //! Sets the fill type used for a background image
1290 //! @param theImageMode the fill type used for a background image
1291 static void setImageMode (const Aspect_FillMethod theImageMode)
1292 {
1293 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1294 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1295 }
1296
1297 //! Sets the gradient filling for a background
1298 //! @param theColor1 the gradient starting color
1299 //! @param theColor2 the gradient ending color
1300 //! @param theGradientMode the fill method used for a background gradient filling
1301 static void setGradient (const Quantity_Color& theColor1,
1302 const Quantity_Color& theColor2,
1303 const Aspect_GradientFillMethod theGradientMode)
1304 {
1305 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1306 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1307 }
1308
1309 //! Sets the fill method used for a background gradient filling
1310 //! @param theGradientMode the fill method used for a background gradient filling
1311 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1312 {
1313 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1314 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1315 }
1316
1317 //! Sets the color used for filling a background
1318 //! @param theColor the color used for filling a background
1319 static void setColor (const Quantity_Color& theColor)
1320 {
1321 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1322 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1323 aCurrentView->SetBackgroundColor (theColor);
1324 aCurrentView->Update();
1325 }
1326
1327 //! Sets the gradient filling for a background in a default viewer
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 setDefaultGradient (const Quantity_Color& theColor1,
1332 const Quantity_Color& theColor2,
1333 const Aspect_GradientFillMethod theGradientMode)
1334 {
1335 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1336 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1337 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1338 setDefaultGradient();
1339 }
1340
1341 //! Sets the color used for filling a background in a default viewer
1342 //! @param theColor the color used for filling a background
1343 static void setDefaultColor (const Quantity_Color& theColor)
1344 {
1345 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1346 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1347 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1348 ViewerTest_DefaultBackground.FlatColor = theColor;
1349 setDefaultGradient();
1350 setDefaultColor();
1351 }
1352
1353 //! Sets the gradient filling for a background in a default viewer.
1354 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1355 static void setDefaultGradient()
1356 {
1357 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1358 anInteractiveContextIterator (ViewerTest_myContexts);
1359 anInteractiveContextIterator.More();
1360 anInteractiveContextIterator.Next())
1361 {
1362 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1363 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1364 ViewerTest_DefaultBackground.GradientColor2,
1365 ViewerTest_DefaultBackground.FillMethod);
1366 }
1367 }
1368
1369 //! Sets the color used for filling a background in a default viewer.
1370 //! The color value is taken from ViewerTest_DefaultBackground structure
1371 static void setDefaultColor()
1372 {
1373 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1374 anInteractiveContextIterator (ViewerTest_myContexts);
1375 anInteractiveContextIterator.More();
1376 anInteractiveContextIterator.Next())
1377 {
1378 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1379 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1380 }
1381 }
1382 };
1383
1384} // namespace
b12e1c7b 1385
7fd59977 1386//==============================================================================
1387
57c28b61 1388#ifdef _WIN32
7fd59977 1389static LRESULT WINAPI ViewerWindowProc(
1390 HWND hwnd,
1391 UINT uMsg,
1392 WPARAM wParam,
1393 LPARAM lParam );
1394static LRESULT WINAPI AdvViewerWindowProc(
1395 HWND hwnd,
1396 UINT uMsg,
1397 WPARAM wParam,
1398 LPARAM lParam );
1399#endif
1400
1401
1402//==============================================================================
1403//function : WClass
1404//purpose :
1405//==============================================================================
1406
1bd04b5a 1407const Handle(WNT_WClass)& ViewerTest::WClass()
7fd59977 1408{
1bd04b5a 1409 static Handle(WNT_WClass) theWClass;
58655684 1410#if defined(_WIN32)
4fe56619 1411 if (theWClass.IsNull())
1412 {
7c65581d 1413 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1414 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1415 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1416 }
1417#endif
1418 return theWClass;
1419}
1420
18d715bd 1421//==============================================================================
1422//function : CreateName
1423//purpose : Create numerical name for new object in theMap
1424//==============================================================================
1425template <typename ObjectType>
1426TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1427 const TCollection_AsciiString& theDefaultString)
1428{
1429 if (theObjectMap.IsEmpty())
1430 return theDefaultString + TCollection_AsciiString(1);
1431
1432 Standard_Integer aNextKey = 1;
1433 Standard_Boolean isFound = Standard_False;
1434 while (!isFound)
1435 {
1436 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1437 // Look for objects with default names
1438 if (theObjectMap.IsBound1(aStringKey))
1439 {
1440 aNextKey++;
1441 }
1442 else
1443 isFound = Standard_True;
1444 }
1445
1446 return theDefaultString + TCollection_AsciiString(aNextKey);
1447}
1448
1449//==============================================================================
1450//structure : ViewerTest_Names
1451//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1452//==============================================================================
1453struct ViewerTest_Names
1454{
1455private:
1456 TCollection_AsciiString myDriverName;
1457 TCollection_AsciiString myViewerName;
1458 TCollection_AsciiString myViewName;
1459
1460public:
1461
1462 const TCollection_AsciiString& GetDriverName () const
1463 {
1464 return myDriverName;
1465 }
1466 void SetDriverName (const TCollection_AsciiString& theDriverName)
1467 {
1468 myDriverName = theDriverName;
1469 }
1470 const TCollection_AsciiString& GetViewerName () const
1471 {
1472 return myViewerName;
1473 }
1474 void SetViewerName (const TCollection_AsciiString& theViewerName)
1475 {
1476 myViewerName = theViewerName;
1477 }
1478 const TCollection_AsciiString& GetViewName () const
1479 {
1480 return myViewName;
1481 }
1482 void SetViewName (const TCollection_AsciiString& theViewName)
1483 {
1484 myViewName = theViewName;
1485 }
1486
1487 //===========================================================================
1488 //function : Constructor for ViewerTest_Names
1489 //purpose : Get view, viewer, driver names from custom string
1490 //===========================================================================
1491
1492 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1493 {
1494 TCollection_AsciiString aName(theInputString);
1495 if (theInputString.IsEmpty())
1496 {
1497 // Get current configuration
1498 if (ViewerTest_myDrivers.IsEmpty())
1499 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1500 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1501 else
1502 myDriverName = ViewerTest_myDrivers.Find2
1503 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1504
1505 if(ViewerTest_myContexts.IsEmpty())
1506 {
1507 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1508 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1509 }
1510 else
c48e2889 1511 {
18d715bd 1512 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1513 }
18d715bd 1514
c48e2889 1515 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1516 }
1517 else
1518 {
1519 // There is at least view name
1520 Standard_Integer aParserNumber = 0;
1521 for (Standard_Integer i = 0; i < 3; ++i)
1522 {
1523 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1524 if(aParserPos != -1)
1525 {
1526 aParserNumber++;
1527 aName.Split(aParserPos-1);
1528 }
1529 else
1530 break;
1531 }
1532 if (aParserNumber == 0)
1533 {
1534 // Only view name
1535 if (!ViewerTest::GetAISContext().IsNull())
1536 {
1537 myDriverName = ViewerTest_myDrivers.Find2
1538 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1539 myViewerName = ViewerTest_myContexts.Find2
1540 (ViewerTest::GetAISContext());
1541 }
1542 else
1543 {
1544 // There is no opened contexts here, need to create names for viewer and driver
1545 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1546 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1547
1548 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1549 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1550 }
1551 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1552 }
1553 else if (aParserNumber == 1)
1554 {
1555 // Here is viewerName/viewName
1556 if (!ViewerTest::GetAISContext().IsNull())
1557 myDriverName = ViewerTest_myDrivers.Find2
1558 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1559 else
1560 {
1561 // There is no opened contexts here, need to create name for driver
1562 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1563 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1564 }
1565 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1566
1567 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1568 }
1569 else
1570 {
1571 //Here is driverName/viewerName/viewName
1572 myDriverName = TCollection_AsciiString(aName);
1573
1574 TCollection_AsciiString aViewerName(theInputString);
1575 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1576 myViewerName = TCollection_AsciiString(aViewerName);
1577
1578 myViewName = TCollection_AsciiString(theInputString);
1579 }
1580 }
1581 }
1582};
1583
1584//==============================================================================
1585//function : FindContextByView
1586//purpose : Find AIS_InteractiveContext by View
1587//==============================================================================
1588
1589Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1590{
1591 Handle(AIS_InteractiveContext) anAISContext;
1592
1593 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1594 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1595 {
1596 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1597 return anIter.Key2();
1598 }
1599 return anAISContext;
1600}
1601
18d715bd 1602//==============================================================================
1603//function : IsWindowOverlapped
1604//purpose : Check if theWindow overlapp another view
1605//==============================================================================
1606
1607Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1608 const Standard_Integer thePxTop,
1609 const Standard_Integer thePxRight,
1610 const Standard_Integer thePxBottom,
1611 TCollection_AsciiString& theViewId)
1612{
1613 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1614 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1615 {
1616 Standard_Integer aTop = 0,
1617 aLeft = 0,
1618 aRight = 0,
1619 aBottom = 0;
1620 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1621 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1622 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1623 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1624 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1625 {
1626 theViewId = anIter.Key1();
1627 return Standard_True;
1628 }
1629 }
1630 return Standard_False;
1631}
1632
1633// Workaround: to create and delete non-orthographic views outside ViewerTest
1634void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1635{
1636 ViewerTest_myViews.UnBind1 (theName);
1637}
1638
1639void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1640 const Handle(V3d_View)& theView)
1641{
1642 ViewerTest_myViews.Bind (theName, theView);
1643}
1644
1645TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1646{
1647 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1648}
8693dfd0 1649
7fd59977 1650//==============================================================================
1651//function : ViewerInit
1652//purpose : Create the window viewer and initialize all the global variable
1653//==============================================================================
1654
18d715bd 1655TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1656 const Standard_Integer thePxTop,
1657 const Standard_Integer thePxWidth,
1658 const Standard_Integer thePxHeight,
9e04ccdc 1659 const TCollection_AsciiString& theViewName,
1660 const TCollection_AsciiString& theDisplayName,
72ed0644 1661 const Handle(V3d_View)& theViewToClone,
1662 const Standard_Boolean theIsVirtual)
7fd59977 1663{
8c3c9904 1664 // Default position and dimension of the viewer window.
4fe56619 1665 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1666 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1667 // The position corresponds to the window's client area, thus some
8c3c9904 1668 // gap is added for window frame to be visible.
1669 Standard_Integer aPxLeft = 20;
1670 Standard_Integer aPxTop = 40;
7fd59977 1671 Standard_Integer aPxWidth = 409;
1672 Standard_Integer aPxHeight = 409;
18d715bd 1673 Standard_Boolean toCreateViewer = Standard_False;
72ed0644 1674 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
9e04ccdc 1675 if (!theViewToClone.IsNull())
1676 {
1677 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1678 }
18d715bd 1679
58655684 1680 Handle(OpenGl_GraphicDriver) aGraphicDriver;
18d715bd 1681 ViewerTest_Names aViewNames(theViewName);
1682 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
1683 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1684
1685 if (thePxLeft != 0)
1686 aPxLeft = thePxLeft;
1687 if (thePxTop != 0)
1688 aPxTop = thePxTop;
1689 if (thePxWidth != 0)
1690 aPxWidth = thePxWidth;
1691 if (thePxHeight != 0)
7fd59977 1692 aPxHeight = thePxHeight;
4269bd1b 1693
18d715bd 1694 // Get graphic driver (create it or get from another view)
8693dfd0 1695 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1696 if (isNewDriver)
18d715bd 1697 {
1698 // Get connection string
58655684 1699 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 1700 if (!theDisplayName.IsEmpty())
1701 {
1702 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1703 }
18d715bd 1704 else
8693dfd0 1705 {
1706 ::Display* aDispX = NULL;
1707 // create dedicated display connection instead of reusing Tk connection
1708 // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
1709 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1710 Tcl_Interp* aTclInterp = aCommands.Interp();
1711 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1712 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1713 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1714 }
18d715bd 1715 #else
498ce76b 1716 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1717 SetDisplayConnection (new Aspect_DisplayConnection ());
1718 #endif
14cb22a1 1719
72ed0644 1720 if (isVirtual)
14cb22a1 1721 {
1722 // don't waste the time waiting for VSync when window is not displayed on the screen
1723 ViewerTest_myDefaultCaps.swapInterval = 0;
1724 // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
1725 //ViewerTest_myDefaultCaps.buffersNoSwap = true;
1726 }
59515ca6 1727 aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection(), false);
58655684 1728 aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
59515ca6 1729 aGraphicDriver->InitContext();
14cb22a1 1730
18d715bd 1731 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1732 toCreateViewer = Standard_True;
1733 }
1734 else
1735 {
58655684 1736 aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
7fd59977 1737 }
1738
18d715bd 1739 //Dispose the window if input parameters are default
1740 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1741 {
18d715bd 1742 Standard_Integer aTop = 0,
1743 aLeft = 0,
1744 aRight = 0,
1745 aBottom = 0,
1746 aScreenWidth = 0,
1747 aScreenHeight = 0;
1748
1749 // Get screen resolution
1750#if defined(_WIN32) || defined(__WIN32__)
1751 RECT aWindowSize;
1752 GetClientRect(GetDesktopWindow(), &aWindowSize);
1753 aScreenHeight = aWindowSize.bottom;
1754 aScreenWidth = aWindowSize.right;
1755#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1756 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1757#else
1758 Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
1759 aScreenWidth = WidthOfScreen(aScreen);
1760 aScreenHeight = HeightOfScreen(aScreen);
1761#endif
1762
1763 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1764
1765 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1766 {
18d715bd 1767 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1768
1769 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1770 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1771 {
1772 if (aBottom + aPxHeight + 40 > aScreenHeight)
1773 {
1774 aPxLeft = 20;
1775 aPxTop = 40;
1776 break;
1777 }
1778 aPxLeft = 20;
1779 aPxTop = aBottom + 40;
1780 }
1781 else
1782 aPxLeft = aRight + 20;
dc3fe572 1783 }
18d715bd 1784 }
1785
1786 // Get viewer name
1787 TCollection_AsciiString aTitle("3D View - ");
1788 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1789
1790 // Change name of current active window
49582f9d 1791 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
18d715bd 1792 {
49582f9d 1793 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
18d715bd 1794 }
1795
1796 // Create viewer
eb4320f2 1797 Handle(V3d_Viewer) a3DViewer;
18d715bd 1798 // If it's the single view, we first look for empty context
1799 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1800 {
1801 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1802 anIter(ViewerTest_myContexts);
1803 if (anIter.More())
1804 ViewerTest::SetAISContext (anIter.Value());
1805 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1806 }
1807 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1808 {
1809 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1810 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1811 }
eb4320f2 1812 else if (a3DViewer.IsNull())
18d715bd 1813 {
1814 toCreateViewer = Standard_True;
6a24c6de 1815 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1816 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1817 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1818 ViewerTest_DefaultBackground.GradientColor2,
1819 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1820 }
1821
1822 // AIS context setup
1823 if (ViewerTest::GetAISContext().IsNull() ||
1824 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1825 {
e79a94b9 1826 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1827 ViewerTest::SetAISContext (aContext);
1828 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1829 }
1830 else
e79a94b9 1831 {
18d715bd 1832 ViewerTest::ResetEventManager();
e79a94b9 1833 }
18d715bd 1834
1835 // Create window
e79a94b9 1836#if defined(_WIN32)
1bd04b5a 1837 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
72ed0644 1838 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1839 aPxLeft, aPxTop,
1840 aPxWidth, aPxHeight,
1841 Quantity_NOC_BLACK);
d6fbb2ab 1842 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
4fe56619 1843#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e79a94b9 1844 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1845 aPxLeft, aPxTop,
1846 aPxWidth, aPxHeight);
1847 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
7fd59977 1848#else
e79a94b9 1849 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1850 aTitle.ToCString(),
1851 aPxLeft, aPxTop,
1852 aPxWidth, aPxHeight);
7fd59977 1853#endif
72ed0644 1854 VT_GetWindow()->SetVirtual (isVirtual);
7fd59977 1855
d09dda09 1856 // View setup
9e04ccdc 1857 Handle(V3d_View) aView;
1858 if (!theViewToClone.IsNull())
1859 {
2e93433e 1860 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1861 }
1862 else
1863 {
2e93433e 1864 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1865 }
1866
d09dda09 1867 aView->SetWindow (VT_GetWindow());
c3282ec1 1868 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1869
18d715bd 1870 ViewerTest::CurrentView(aView);
1871 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1872
18d715bd 1873 // Setup for X11 or NT
1874 OSWindowSetup();
7fd59977 1875
18d715bd 1876 // Set parameters for V3d_View and V3d_Viewer
1877 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1878 aV3dView->SetComputedMode(Standard_False);
7fd59977 1879
18d715bd 1880 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1881 if (toCreateViewer)
1882 {
7fd59977 1883 a3DViewer->SetDefaultLights();
1884 a3DViewer->SetLightOn();
18d715bd 1885 }
7fd59977 1886
8693dfd0 1887#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1888 if (isNewDriver)
1889 {
1890 ::Display* aDispX = GetDisplayConnection()->GetDisplay();
1891 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1892 }
1893#endif
7fd59977 1894
7fd59977 1895 VT_GetWindow()->Map();
4269bd1b 1896
18d715bd 1897 // Set the handle of created view in the event manager
1898 ViewerTest::ResetEventManager();
1899
4fe56619 1900 ViewerTest::CurrentView()->Redraw();
18d715bd 1901
1902 aView.Nullify();
1903 a3DViewer.Nullify();
18d715bd 1904
1905 return aViewNames.GetViewName();
1906}
1907
4269bd1b 1908//==============================================================================
1909//function : RedrawAllViews
1910//purpose : Redraw all created views
1911//==============================================================================
1912void ViewerTest::RedrawAllViews()
1913{
1914 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1915 for (; aViewIt.More(); aViewIt.Next())
1916 {
1917 const Handle(V3d_View)& aView = aViewIt.Key2();
1918 aView->Redraw();
1919 }
1920}
1921
7fd59977 1922//==============================================================================
1923//function : Vinit
1924//purpose : Create the window viewer and initialize all the global variable
e79a94b9 1925// Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 1926//==============================================================================
1927
18d715bd 1928static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 1929{
e79a94b9 1930 TCollection_AsciiString aViewName, aDisplayName;
1931 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
72ed0644 1932 Standard_Boolean isVirtual = false;
9e04ccdc 1933 Handle(V3d_View) aCopyFrom;
e79a94b9 1934 TCollection_AsciiString aName, aValue;
2e93433e 1935 int is2dMode = -1;
e79a94b9 1936 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 1937 {
e79a94b9 1938 const TCollection_AsciiString anArg = theArgVec[anArgIt];
1939 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 1940 anArgCase.LowerCase();
1941 if (anArgIt + 1 < theArgsNb
1942 && anArgCase == "-name")
1943 {
1944 aViewName = theArgVec[++anArgIt];
1945 }
1946 else if (anArgIt + 1 < theArgsNb
1947 && (anArgCase == "-left"
1948 || anArgCase == "-l"))
1949 {
1950 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
1951 }
1952 else if (anArgIt + 1 < theArgsNb
1953 && (anArgCase == "-top"
1954 || anArgCase == "-t"))
1955 {
1956 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
1957 }
1958 else if (anArgIt + 1 < theArgsNb
1959 && (anArgCase == "-width"
1960 || anArgCase == "-w"))
1961 {
1962 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
1963 }
1964 else if (anArgIt + 1 < theArgsNb
1965 && (anArgCase == "-height"
1966 || anArgCase == "-h"))
18d715bd 1967 {
fd3f6bd0 1968 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
1969 }
72ed0644 1970 else if (anArgCase == "-virtual"
1971 || anArgCase == "-offscreen")
1972 {
1973 isVirtual = true;
1974 if (anArgIt + 1 < theArgsNb
1975 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
1976 {
1977 ++anArgIt;
1978 }
1979 }
fd3f6bd0 1980 else if (anArgCase == "-exitonclose")
1981 {
49582f9d 1982 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 1983 if (anArgIt + 1 < theArgsNb
dae2a922 1984 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 1985 {
1986 ++anArgIt;
1987 }
1988 }
1989 else if (anArgCase == "-closeonescape"
1990 || anArgCase == "-closeonesc")
1991 {
49582f9d 1992 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 1993 if (anArgIt + 1 < theArgsNb
dae2a922 1994 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 1995 {
1996 ++anArgIt;
1997 }
1998 }
2e93433e 1999 else if (anArgCase == "-2d_mode"
2000 || anArgCase == "-2dmode"
2001 || anArgCase == "-2d")
2002 {
2003 bool toEnable = true;
2004 if (anArgIt + 1 < theArgsNb
dae2a922 2005 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2e93433e 2006 {
2007 ++anArgIt;
2008 }
2009 is2dMode = toEnable ? 1 : 0;
2010 }
fd3f6bd0 2011 else if (anArgIt + 1 < theArgsNb
2012 && (anArgCase == "-disp"
2013 || anArgCase == "-display"))
2014 {
2015 aDisplayName = theArgVec[++anArgIt];
2016 }
9e04ccdc 2017 else if (!ViewerTest::CurrentView().IsNull()
2018 && aCopyFrom.IsNull()
2019 && (anArgCase == "-copy"
2020 || anArgCase == "-clone"
2021 || anArgCase == "-cloneactive"
2022 || anArgCase == "-cloneactiveview"))
2023 {
2024 aCopyFrom = ViewerTest::CurrentView();
2025 }
fd3f6bd0 2026 // old syntax
2027 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2028 {
2029 aName.LowerCase();
2030 if (aName == "name")
18d715bd 2031 {
2032 aViewName = aValue;
2033 }
fd3f6bd0 2034 else if (aName == "l"
2035 || aName == "left")
e79a94b9 2036 {
18d715bd 2037 aPxLeft = aValue.IntegerValue();
e79a94b9 2038 }
fd3f6bd0 2039 else if (aName == "t"
2040 || aName == "top")
e79a94b9 2041 {
18d715bd 2042 aPxTop = aValue.IntegerValue();
e79a94b9 2043 }
fd3f6bd0 2044 else if (aName == "disp"
2045 || aName == "display")
e79a94b9 2046 {
18d715bd 2047 aDisplayName = aValue;
e79a94b9 2048 }
fd3f6bd0 2049 else if (aName == "w"
2050 || aName == "width")
e79a94b9 2051 {
18d715bd 2052 aPxWidth = aValue.IntegerValue();
e79a94b9 2053 }
fd3f6bd0 2054 else if (aName == "h"
2055 || aName == "height")
e79a94b9 2056 {
18d715bd 2057 aPxHeight = aValue.IntegerValue();
e79a94b9 2058 }
18d715bd 2059 else
2060 {
23fe70ec 2061 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2062 return 1;
18d715bd 2063 }
2064 }
e79a94b9 2065 else if (aViewName.IsEmpty())
2066 {
2067 aViewName = anArg;
2068 }
2069 else
2070 {
23fe70ec 2071 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2072 return 1;
e79a94b9 2073 }
18d715bd 2074 }
2075
fd3f6bd0 2076#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2077 if (!aDisplayName.IsEmpty())
2078 {
2079 aDisplayName.Clear();
23fe70ec 2080 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
fd3f6bd0 2081 }
2082#endif
2083
18d715bd 2084 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2085 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2086 {
e79a94b9 2087 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2088 theDi.Eval (aCommand.ToCString());
2e93433e 2089 if (is2dMode != -1)
2090 {
2091 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2092 }
18d715bd 2093 return 0;
2094 }
2095
2096 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
72ed0644 2097 aViewName, aDisplayName, aCopyFrom, isVirtual);
2e93433e 2098 if (is2dMode != -1)
2099 {
2100 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2101 }
e79a94b9 2102 theDi << aViewId;
7fd59977 2103 return 0;
2104}
2105
1eeef710 2106//! Parse HLR algo type.
2107static Standard_Boolean parseHlrAlgoType (const char* theName,
2108 Prs3d_TypeOfHLR& theType)
2109{
2110 TCollection_AsciiString aName (theName);
2111 aName.LowerCase();
2112 if (aName == "polyalgo")
2113 {
2114 theType = Prs3d_TOH_PolyAlgo;
2115 }
2116 else if (aName == "algo")
2117 {
2118 theType = Prs3d_TOH_Algo;
2119 }
2120 else
2121 {
2122 return Standard_False;
2123 }
2124 return Standard_True;
2125}
2126
0a768f56 2127//==============================================================================
2128//function : VHLR
2129//purpose : hidden lines removal algorithm
2130//==============================================================================
2131
2132static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2133{
1eeef710 2134 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2135 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2136 if (aView.IsNull())
0a768f56 2137 {
23fe70ec 2138 Message::SendFail ("Error: no active viewer");
0a768f56 2139 return 1;
2140 }
2141
1eeef710 2142 Standard_Boolean hasHlrOnArg = Standard_False;
2143 Standard_Boolean hasShowHiddenArg = Standard_False;
2144 Standard_Boolean isHLROn = Standard_False;
2145 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2146 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2147 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2148 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2149 {
1eeef710 2150 TCollection_AsciiString anArg (argv[anArgIter]);
2151 anArg.LowerCase();
2152 if (anUpdateTool.parseRedrawMode (anArg))
2153 {
2154 continue;
2155 }
2156 else if (anArg == "-showhidden"
2157 && anArgIter + 1 < argc
dae2a922 2158 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1eeef710 2159 {
2160 ++anArgIter;
2161 hasShowHiddenArg = Standard_True;
2162 continue;
2163 }
2164 else if ((anArg == "-type"
2165 || anArg == "-algo"
2166 || anArg == "-algotype")
2167 && anArgIter + 1 < argc
2168 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2169 {
2170 ++anArgIter;
2171 continue;
2172 }
2173 else if (!hasHlrOnArg
dae2a922 2174 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1eeef710 2175 {
2176 hasHlrOnArg = Standard_True;
2177 continue;
2178 }
2179 // old syntax
2180 else if (!hasShowHiddenArg
dae2a922 2181 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1eeef710 2182 {
2183 hasShowHiddenArg = Standard_True;
2184 continue;
2185 }
2186 else
2187 {
23fe70ec 2188 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1eeef710 2189 return 1;
2190 }
0a768f56 2191 }
1eeef710 2192 if (!hasHlrOnArg)
0a768f56 2193 {
1eeef710 2194 di << "HLR: " << aView->ComputedMode() << "\n";
2195 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2196 di << "HlrAlgo: ";
2197 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2198 {
2199 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2200 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2201 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2202 }
2203 anUpdateTool.Invalidate();
2204 return 0;
0a768f56 2205 }
2206
1eeef710 2207 Standard_Boolean toRecompute = Standard_False;
2208 if (aTypeOfHLR != Prs3d_TOH_NotSet
2209 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2210 {
1eeef710 2211 toRecompute = Standard_True;
2212 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2213 }
2214 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2215 {
2216 toRecompute = Standard_True;
2217 if (toShowHidden)
e9224045 2218 {
1eeef710 2219 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2220 }
2221 else
2222 {
1eeef710 2223 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2224 }
1eeef710 2225 }
e9224045 2226
1eeef710 2227 // redisplay shapes
2228 if (aView->ComputedMode() && isHLROn && toRecompute)
2229 {
2230 AIS_ListOfInteractive aListOfShapes;
2231 aCtx->DisplayedObjects (aListOfShapes);
2232 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2233 {
1eeef710 2234 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2235 {
1eeef710 2236 aCtx->Redisplay (aShape, Standard_False);
e9224045 2237 }
2238 }
2239 }
0a768f56 2240
1eeef710 2241 aView->SetComputedMode (isHLROn);
0a768f56 2242 return 0;
2243}
2244
2245//==============================================================================
2246//function : VHLRType
2247//purpose : change type of using HLR algorithm
2248//==============================================================================
2249
1eeef710 2250static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2251{
1eeef710 2252 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2253 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2254 if (aView.IsNull())
0a768f56 2255 {
23fe70ec 2256 Message::SendFail ("Error: no active viewer");
0a768f56 2257 return 1;
2258 }
2259
1eeef710 2260 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2261 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2262 AIS_ListOfInteractive aListOfShapes;
2263 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2264 {
1eeef710 2265 TCollection_AsciiString anArg (argv[anArgIter]);
2266 anArg.LowerCase();
2267 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2268 {
1eeef710 2269 continue;
0a768f56 2270 }
1eeef710 2271 else if ((anArg == "-type"
2272 || anArg == "-algo"
2273 || anArg == "-algotype")
2274 && anArgIter + 1 < argc
2275 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2276 {
2277 ++anArgIter;
2278 continue;
2279 }
2280 // old syntax
2281 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2282 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2283 {
2284 continue;
2285 }
2286 else
0a768f56 2287 {
2288 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2289 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2290 if (!aMap.IsBound2 (aName))
2291 {
23fe70ec 2292 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1eeef710 2293 return 1;
0a768f56 2294 }
1eeef710 2295
2296 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2297 if (aShape.IsNull())
2298 {
23fe70ec 2299 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1eeef710 2300 return 1;
2301 }
2302 aListOfShapes.Append (aShape);
2303 continue;
0a768f56 2304 }
1eeef710 2305 }
2306 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2307 {
23fe70ec 2308 Message::SendFail ("Syntax error: wrong number of arguments");
1eeef710 2309 return 1;
2310 }
2311
2312 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2313 if (isGlobal)
2314 {
2315 aCtx->DisplayedObjects (aListOfShapes);
2316 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2317 }
2318
1eeef710 2319 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2320 {
2321 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2322 if (aShape.IsNull())
2323 {
2324 continue;
2325 }
2326
2327 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2328 && aView->ComputedMode();
2329 if (!isGlobal
2330 || aShape->TypeOfHLR() != aTypeOfHLR)
2331 {
2332 aShape->SetTypeOfHLR (aTypeOfHLR);
2333 }
2334 if (toUpdateShape)
2335 {
2336 aCtx->Redisplay (aShape, Standard_False);
2337 }
2338 }
0a768f56 2339 return 0;
2340}
2341
18d715bd 2342//==============================================================================
2343//function : FindViewIdByWindowHandle
2344//purpose : Find theView Id in the map of views by window handle
2345//==============================================================================
49582f9d 2346#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2347TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
18d715bd 2348{
2349 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2350 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2351 {
49582f9d 2352 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
18d715bd 2353 if (aWindowHandle == theWindowHandle)
2354 return anIter.Key1();
2355 }
2356 return TCollection_AsciiString("");
2357}
2358#endif
2359
e084dbbc 2360//! Make the view active
2361void ActivateView (const TCollection_AsciiString& theViewName,
2362 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2363{
2364 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2365 if (aView.IsNull())
18d715bd 2366 {
e084dbbc 2367 return;
2368 }
18d715bd 2369
e084dbbc 2370 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2371 if (!anAISContext.IsNull())
2372 {
49582f9d 2373 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
e084dbbc 2374 {
49582f9d 2375 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
e084dbbc 2376 }
2377
2378 ViewerTest::CurrentView (aView);
2379 ViewerTest::SetAISContext (anAISContext);
49582f9d 2380 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
1eeef710 2381#if defined(_WIN32)
e084dbbc 2382 VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2383#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e084dbbc 2384 VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2385#else
e084dbbc 2386 VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2387#endif
e084dbbc 2388 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2389 if (theToUpdate)
2390 {
18d715bd 2391 ViewerTest::CurrentView()->Redraw();
2392 }
2393 }
2394}
2395
0e93d9e5 2396//==============================================================================
2397//function : RemoveView
2398//purpose :
2399//==============================================================================
2400void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2401 const Standard_Boolean theToRemoveContext)
2402{
2403 if (!ViewerTest_myViews.IsBound2 (theView))
2404 {
2405 return;
2406 }
2407
2408 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2409 RemoveView (aViewName, theToRemoveContext);
2410}
2411
18d715bd 2412//==============================================================================
2413//function : RemoveView
4551e1be 2414//purpose : Close and remove view from display, clear maps if necessary
18d715bd 2415//==============================================================================
2416void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2417{
2418 if (!ViewerTest_myViews.IsBound1(theViewName))
2419 {
23fe70ec 2420 Message::SendFail() << "Wrong view name";
18d715bd 2421 return;
2422 }
2423
2424 // Activate another view if it's active now
2425 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2426 {
2427 if (ViewerTest_myViews.Extent() > 1)
2428 {
2429 TCollection_AsciiString aNewViewName;
c48e2889 2430 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2431 anIter.More(); anIter.Next())
2432 {
18d715bd 2433 if (anIter.Key1() != theViewName)
2434 {
2435 aNewViewName = anIter.Key1();
2436 break;
2437 }
c48e2889 2438 }
2439 ActivateView (aNewViewName);
18d715bd 2440 }
2441 else
2442 {
e084dbbc 2443 VT_GetWindow().Nullify();
2444 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2445 if (isContextRemoved)
2446 {
2447 Handle(AIS_InteractiveContext) anEmptyContext;
2448 ViewerTest::SetAISContext(anEmptyContext);
2449 }
2450 }
2451 }
2452
2453 // Delete view
2454 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2455 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2456 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2457 aRedrawer.Stop (aView->Window());
18d715bd 2458
2459 // Remove view resources
18d715bd 2460 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2461 aView->Window()->Unmap();
18d715bd 2462 aView->Remove();
2463
2464#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2465 XFlush (GetDisplayConnection()->GetDisplay());
2466#endif
2467
2468 // Keep context opened only if the closed view is last to avoid
2469 // unused empty contexts
2470 if (!aCurrentContext.IsNull())
2471 {
2472 // Check if there are more difined views in the viewer
f7fc0c03 2473 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2474 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
18d715bd 2475 {
2476 // Remove driver if there is no viewers that use it
2477 Standard_Boolean isRemoveDriver = Standard_True;
2478 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2479 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2480 {
2481 if (aCurrentContext != anIter.Key2() &&
2482 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2483 {
2484 isRemoveDriver = Standard_False;
2485 break;
2486 }
2487 }
2ec85268 2488
2489 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2490 if(isRemoveDriver)
2491 {
2492 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2493 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 2494 Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
18d715bd 2495 #endif
2496 }
2497
2498 ViewerTest_myContexts.UnBind2(aCurrentContext);
2499 }
2500 }
23fe70ec 2501 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
49582f9d 2502 if (ViewerTest_EventManager::ToExitOnCloseView())
fd3f6bd0 2503 {
2504 Draw_Interprete ("exit");
2505 }
18d715bd 2506}
2507
2508//==============================================================================
2509//function : VClose
2510//purpose : Remove the view defined by its name
2511//==============================================================================
2512
d0cc1cb7 2513static int VClose (Draw_Interpretor& /*theDi*/,
2514 Standard_Integer theArgsNb,
2515 const char** theArgVec)
18d715bd 2516{
18d715bd 2517 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2518 if (theArgsNb > 1)
18d715bd 2519 {
d0cc1cb7 2520 TCollection_AsciiString anArg (theArgVec[1]);
2521 anArg.UpperCase();
2522 if (anArg.IsEqual ("ALL")
2523 || anArg.IsEqual ("*"))
2524 {
2525 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2526 anIter.More(); anIter.Next())
2527 {
2528 aViewList.Append (anIter.Key1());
2529 }
2530 if (aViewList.IsEmpty())
2531 {
2532 std::cout << "No view to close\n";
2533 return 0;
2534 }
2535 }
2536 else
18d715bd 2537 {
d0cc1cb7 2538 ViewerTest_Names aViewName (theArgVec[1]);
2539 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2540 {
23fe70ec 2541 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
d0cc1cb7 2542 return 1;
2543 }
2544 aViewList.Append (aViewName.GetViewName());
18d715bd 2545 }
2546 }
2547 else
2548 {
d0cc1cb7 2549 // close active view
2550 if (ViewerTest::CurrentView().IsNull())
2551 {
23fe70ec 2552 Message::SendFail ("Error: no active view");
d0cc1cb7 2553 return 1;
2554 }
2555 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2556 }
2557
d0cc1cb7 2558 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2559 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2560 anIter.More(); anIter.Next())
2561 {
d0cc1cb7 2562 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2563 }
2564
2565 return 0;
2566}
2567
2568//==============================================================================
2569//function : VActivate
2570//purpose : Activate the view defined by its ID
2571//==============================================================================
2572
2573static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2574{
e084dbbc 2575 if (theArgsNb == 1)
18d715bd 2576 {
2577 theDi.Eval("vviewlist");
2578 return 0;
2579 }
2580
e084dbbc 2581 TCollection_AsciiString aNameString;
2582 Standard_Boolean toUpdate = Standard_True;
2583 Standard_Boolean toActivate = Standard_True;
2584 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2585 {
e084dbbc 2586 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2587 anArg.LowerCase();
2588 if (toUpdate
2589 && anArg == "-noupdate")
2590 {
2591 toUpdate = Standard_False;
2592 }
2593 else if (toActivate
2594 && aNameString.IsEmpty()
2595 && anArg == "none")
2596 {
49582f9d 2597 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
e084dbbc 2598 VT_GetWindow().Nullify();
2599 ViewerTest::CurrentView (Handle(V3d_View)());
2600 ViewerTest::ResetEventManager();
2601 theDi << theArgVec[0] << ": all views are inactive\n";
2602 toActivate = Standard_False;
2603 }
2604 else if (toActivate
2605 && aNameString.IsEmpty())
2606 {
2607 aNameString = theArgVec[anArgIter];
2608 }
2609 else
2610 {
23fe70ec 2611 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
e084dbbc 2612 return 1;
2613 }
18d715bd 2614 }
2615
e084dbbc 2616 if (!toActivate)
2617 {
2618 return 0;
2619 }
2620 else if (aNameString.IsEmpty())
2621 {
23fe70ec 2622 Message::SendFail ("Syntax error: wrong number of arguments");
e084dbbc 2623 return 1;
2624 }
18d715bd 2625
2626 // Check if this view exists in the viewer with the driver
e084dbbc 2627 ViewerTest_Names aViewNames (aNameString);
18d715bd 2628 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2629 {
e084dbbc 2630 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2631 return 1;
2632 }
2633
2634 // Check if it is active already
2635 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2636 {
2637 theDi << theArgVec[0] << ": the view is active already\n";
2638 return 0;
2639 }
2640
e084dbbc 2641 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2642 return 0;
2643}
2644
2645//==============================================================================
2646//function : VViewList
2647//purpose : Print current list of views per viewer and graphic driver ID
2648// shared between viewers
2649//==============================================================================
2650
2651static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2652{
2653 if (theArgsNb > 2)
2654 {
2655 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2656 << "Usage: " << theArgVec[0] << " name";
18d715bd 2657 return 1;
2658 }
2659 if (ViewerTest_myContexts.Size() < 1)
2660 return 0;
2661
18d715bd 2662 Standard_Boolean isTreeView =
29cb310a 2663 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2664
2665 if (isTreeView)
c48e2889 2666 {
18d715bd 2667 theDi << theArgVec[0] <<":\n";
c48e2889 2668 }
18d715bd 2669
c48e2889 2670 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2671 aDriverIter.More(); aDriverIter.Next())
2672 {
2673 if (isTreeView)
2674 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2675
c48e2889 2676 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2677 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2678 {
2679 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2680 {
c48e2889 2681 if (isTreeView)
18d715bd 2682 {
c48e2889 2683 TCollection_AsciiString aContextName(aContextIter.Key1());
2684 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2685 }
18d715bd 2686
c48e2889 2687 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2688 aViewIter.More(); aViewIter.Next())
2689 {
2690 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2691 {
c48e2889 2692 TCollection_AsciiString aViewName(aViewIter.Key1());
2693 if (isTreeView)
18d715bd 2694 {
c48e2889 2695 if (aViewIter.Value() == ViewerTest::CurrentView())
2696 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2697 else
c48e2889 2698 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2699 }
2700 else
2701 {
2702 theDi << aViewName << " ";
18d715bd 2703 }
2704 }
2705 }
2706 }
2707 }
c48e2889 2708 }
18d715bd 2709 return 0;
2710}
2711
7fd59977 2712//==============================================================================
49582f9d 2713//function : GetMousePosition
2714//purpose :
7fd59977 2715//==============================================================================
49582f9d 2716void ViewerTest::GetMousePosition (Standard_Integer& theX,
2717 Standard_Integer& theY)
7fd59977 2718{
49582f9d 2719 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
4fe56619 2720 {
49582f9d 2721 theX = aViewCtrl->LastMousePosition().x();
2722 theY = aViewCtrl->LastMousePosition().y();
4fe56619 2723 }
7fd59977 2724}
2725
44b8f2d6 2726//==============================================================================
fc552d84 2727//function : VViewProj
2728//purpose : Switch view projection
44b8f2d6 2729//==============================================================================
fc552d84 2730static int VViewProj (Draw_Interpretor& ,
2731 Standard_Integer theNbArgs,
2732 const char** theArgVec)
44b8f2d6 2733{
fc552d84 2734 static Standard_Boolean isYup = Standard_False;
2735 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2736 if (aView.IsNull())
44b8f2d6 2737 {
23fe70ec 2738 Message::SendFail ("Error: no active viewer");
44b8f2d6 2739 return 1;
2740 }
2741
fc552d84 2742 TCollection_AsciiString aCmdName (theArgVec[0]);
2743 Standard_Boolean isGeneralCmd = Standard_False;
2744 if (aCmdName == "vfront")
2745 {
2746 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2747 }
2748 else if (aCmdName == "vback")
2749 {
2750 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2751 }
2752 else if (aCmdName == "vtop")
2753 {
2754 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2755 }
2756 else if (aCmdName == "vbottom")
2757 {
2758 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2759 }
2760 else if (aCmdName == "vleft")
2761 {
2762 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2763 }
2764 else if (aCmdName == "vright")
2765 {
2766 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2767 }
2768 else if (aCmdName == "vaxo")
2769 {
2770 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2771 }
2772 else
2773 {
2774 isGeneralCmd = Standard_True;
2775 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2776 {
2777 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2778 anArgCase.LowerCase();
2779 if (anArgCase == "-zup")
2780 {
2781 isYup = Standard_False;
2782 }
2783 else if (anArgCase == "-yup")
2784 {
2785 isYup = Standard_True;
2786 }
2787 else if (anArgCase == "-front"
2788 || anArgCase == "front"
2789 || anArgCase == "-f"
2790 || anArgCase == "f")
2791 {
2792 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2793 }
2794 else if (anArgCase == "-back"
2795 || anArgCase == "back"
2796 || anArgCase == "-b"
2797 || anArgCase == "b")
2798 {
2799 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2800 }
2801 else if (anArgCase == "-top"
2802 || anArgCase == "top"
2803 || anArgCase == "-t"
2804 || anArgCase == "t")
2805 {
2806 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2807 }
2808 else if (anArgCase == "-bottom"
2809 || anArgCase == "bottom"
2810 || anArgCase == "-bot"
2811 || anArgCase == "bot"
2812 || anArgCase == "-b"
2813 || anArgCase == "b")
2814 {
2815 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2816 }
2817 else if (anArgCase == "-left"
2818 || anArgCase == "left"
2819 || anArgCase == "-l"
2820 || anArgCase == "l")
2821 {
2822 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2823 }
2824 else if (anArgCase == "-right"
2825 || anArgCase == "right"
2826 || anArgCase == "-r"
2827 || anArgCase == "r")
2828 {
2829 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2830 }
2831 else if (anArgCase == "-axoleft"
2832 || anArgCase == "-leftaxo"
2833 || anArgCase == "axoleft"
2834 || anArgCase == "leftaxo")
2835 {
2836 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
2837 }
2838 else if (anArgCase == "-axo"
2839 || anArgCase == "axo"
2840 || anArgCase == "-a"
2841 || anArgCase == "a"
2842 || anArgCase == "-axoright"
2843 || anArgCase == "-rightaxo"
2844 || anArgCase == "axoright"
2845 || anArgCase == "rightaxo")
2846 {
2847 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2848 }
2849 else if (anArgCase == "+x")
2850 {
2851 aView->SetProj (V3d_Xpos, isYup);
2852 }
2853 else if (anArgCase == "-x")
2854 {
2855 aView->SetProj (V3d_Xneg, isYup);
2856 }
2857 else if (anArgCase == "+y")
2858 {
2859 aView->SetProj (V3d_Ypos, isYup);
2860 }
2861 else if (anArgCase == "-y")
2862 {
2863 aView->SetProj (V3d_Yneg, isYup);
2864 }
2865 else if (anArgCase == "+z")
2866 {
2867 aView->SetProj (V3d_Zpos, isYup);
2868 }
2869 else if (anArgCase == "-z")
2870 {
2871 aView->SetProj (V3d_Zneg, isYup);
2872 }
2873 else if (anArgCase == "+x+y+z")
2874 {
2875 aView->SetProj (V3d_XposYposZpos, isYup);
2876 }
2877 else if (anArgCase == "+x+y-z")
2878 {
2879 aView->SetProj (V3d_XposYposZneg, isYup);
2880 }
2881 else if (anArgCase == "+x-y+z")
2882 {
2883 aView->SetProj (V3d_XposYnegZpos, isYup);
2884 }
2885 else if (anArgCase == "+x-y-z")
2886 {
2887 aView->SetProj (V3d_XposYnegZneg, isYup);
2888 }
2889 else if (anArgCase == "-x+y+z")
2890 {
2891 aView->SetProj (V3d_XnegYposZpos, isYup);
2892 }
2893 else if (anArgCase == "-x+y-z")
2894 {
2895 aView->SetProj (V3d_XnegYposZneg, isYup);
2896 }
2897 else if (anArgCase == "-x-y+z")
2898 {
2899 aView->SetProj (V3d_XnegYnegZpos, isYup);
2900 }
2901 else if (anArgCase == "-x-y-z")
2902 {
2903 aView->SetProj (V3d_XnegYnegZneg, isYup);
2904 }
2905 else if (anArgCase == "+x+y")
2906 {
2907 aView->SetProj (V3d_XposYpos, isYup);
2908 }
2909 else if (anArgCase == "+x-y")
2910 {
2911 aView->SetProj (V3d_XposYneg, isYup);
2912 }
2913 else if (anArgCase == "-x+y")
2914 {
2915 aView->SetProj (V3d_XnegYpos, isYup);
2916 }
2917 else if (anArgCase == "-x-y")
2918 {
2919 aView->SetProj (V3d_XnegYneg, isYup);
2920 }
2921 else if (anArgCase == "+x+z")
2922 {
2923 aView->SetProj (V3d_XposZpos, isYup);
2924 }
2925 else if (anArgCase == "+x-z")
2926 {
2927 aView->SetProj (V3d_XposZneg, isYup);
2928 }
2929 else if (anArgCase == "-x+z")
2930 {
2931 aView->SetProj (V3d_XnegZpos, isYup);
2932 }
2933 else if (anArgCase == "-x-z")
2934 {
2935 aView->SetProj (V3d_XnegZneg, isYup);
2936 }
2937 else if (anArgCase == "+y+z")
2938 {
2939 aView->SetProj (V3d_YposZpos, isYup);
2940 }
2941 else if (anArgCase == "+y-z")
2942 {
2943 aView->SetProj (V3d_YposZneg, isYup);
2944 }
2945 else if (anArgCase == "-y+z")
2946 {
2947 aView->SetProj (V3d_YnegZpos, isYup);
2948 }
2949 else if (anArgCase == "-y-z")
2950 {
2951 aView->SetProj (V3d_YnegZneg, isYup);
2952 }
2953 else if (anArgIter + 1 < theNbArgs
2954 && anArgCase == "-frame"
2955 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
2956 {
2957 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
2958 aFrameDef.LowerCase();
2959 gp_Dir aRight, anUp;
2960 if (aFrameDef.Value (2) == aFrameDef.Value (4))
2961 {
23fe70ec 2962 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2963 return 1;
2964 }
44b8f2d6 2965
fc552d84 2966 if (aFrameDef.Value (2) == 'x')
2967 {
2968 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
2969 }
2970 else if (aFrameDef.Value (2) == 'y')
2971 {
2972 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
2973 }
2974 else if (aFrameDef.Value (2) == 'z')
2975 {
2976 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
2977 }
2978 else
2979 {
23fe70ec 2980 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2981 return 1;
2982 }
7fd59977 2983
fc552d84 2984 if (aFrameDef.Value (4) == 'x')
2985 {
2986 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
2987 }
2988 else if (aFrameDef.Value (4) == 'y')
2989 {
2990 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
2991 }
2992 else if (aFrameDef.Value (4) == 'z')
2993 {
2994 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
2995 }
2996 else
2997 {
23fe70ec 2998 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2999 return 1;
3000 }
44b8f2d6 3001
fc552d84 3002 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
3003 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
3004 const gp_Dir aDir = anUp.Crossed (aRight);
3005 aCamera->SetCenter (gp_Pnt (0, 0, 0));
3006 aCamera->SetDirection (aDir);
3007 aCamera->SetUp (anUp);
3008 aCamera->OrthogonalizeUp();
44b8f2d6 3009
fc552d84 3010 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
3011 aView->Update();
3012 }
3013 else
3014 {
23fe70ec 3015 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3016 return 1;
3017 }
3018 }
3019 }
44b8f2d6 3020
fc552d84 3021 if (!isGeneralCmd
3022 && theNbArgs != 1)
3023 {
23fe70ec 3024 Message::SendFail ("Syntax error: wrong number of arguments");
fc552d84 3025 return 1;
3026 }
3027 return 0;
7fd59977 3028}
3029
3030//==============================================================================
3031//function : VHelp
3032//purpose : Dsiplay help on viewer Keyboead and mouse commands
3033//Draw arg : No args
3034//==============================================================================
3035
3036static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3037{
586db386 3038 di << "=========================\n";
3039 di << "F : FitAll\n";
3040 di << "T : TopView\n";
3041 di << "B : BottomView\n";
3042 di << "R : RightView\n";
3043 di << "L : LeftView\n";
d22962e4 3044 di << "Backspace : AxonometricView\n";
586db386 3045
3046 di << "=========================\n";
d22962e4 3047 di << "W, S : Fly forward/backward\n";
3048 di << "A, D : Slide left/right\n";
3049 di << "Q, E : Bank left/right\n";
3050 di << "-, + : Change flying speed\n";
3051 di << "Arrows : look left/right/up/down\n";
3052 di << "Arrows+Shift : slide left/right/up/down\n";
3053
3054 di << "=========================\n";
3055 di << "S + Ctrl : Shading\n";
3056 di << "W + Ctrl : Wireframe\n";
49582f9d 3057 di << "H : HiddenLineRemoval\n";
586db386 3058 di << "U : Unset display mode\n";
3059 di << "Delete : Remove selection from viewer\n";
3060
3061 di << "=========================\n";
3062 di << "Selection mode \n";
3063 di << "0 : Shape\n";
3064 di << "1 : Vertex\n";
3065 di << "2 : Edge\n";
3066 di << "3 : Wire\n";
3067 di << "4 : Face\n";
3068 di << "5 : Shell\n";
3069 di << "6 : Solid\n";
3070 di << "7 : Compound\n";
3071
3072 di << "=========================\n";
49582f9d 3073 di << "< : Hilight next detected\n";
3074 di << "> : Hilight previous detected\n";
7fd59977 3075
3076 return 0;
3077}
3078
57c28b61 3079#ifdef _WIN32
7fd59977 3080
49582f9d 3081static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3082 UINT theMsg,
3083 WPARAM wParam,
3084 LPARAM lParam )
7fd59977 3085{
49582f9d 3086 if (ViewerTest_myViews.IsEmpty())
3087 {
3088 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
3089 }
7fd59977 3090
49582f9d 3091 switch (theMsg)
3092 {
18d715bd 3093 case WM_CLOSE:
49582f9d 3094 {
3095 // Delete view from map of views
3096 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3097 return 0;
3098 }
18d715bd 3099 case WM_ACTIVATE:
49582f9d 3100 {
3101 if (LOWORD(wParam) == WA_CLICKACTIVE
3102 || LOWORD(wParam) == WA_ACTIVE
3103 || ViewerTest::CurrentView().IsNull())
18d715bd 3104 {
3105 // Activate inactive window
49582f9d 3106 if (VT_GetWindow().IsNull()
3107 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
625e1958 3108 {
49582f9d 3109 ActivateView (FindViewIdByWindowHandle (theWinHandle));
625e1958 3110 }
7fd59977 3111 }
7fd59977 3112 break;
49582f9d 3113 }
7fd59977 3114 default:
49582f9d 3115 {
3116 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
7fd59977 3117 }
7fd59977 3118 }
49582f9d 3119 return 0;
7fd59977 3120}
3121
49582f9d 3122static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
3123 UINT theMsg,
3124 WPARAM wParam,
3125 LPARAM lParam)
7fd59977 3126{
f978241f 3127 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3128 if (aView.IsNull())
3129 {
49582f9d 3130 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
f978241f 3131 }
7fd59977 3132
49582f9d 3133 switch (theMsg)
3134 {
7fd59977 3135 case WM_PAINT:
49582f9d 3136 {
3137 PAINTSTRUCT aPaint;
3138 BeginPaint(theWinHandle, &aPaint);
3139 EndPaint (theWinHandle, &aPaint);
3140 ViewerTest::CurrentEventManager()->ProcessExpose();
7fd59977 3141 break;
49582f9d 3142 }
7fd59977 3143 case WM_SIZE:
49582f9d 3144 {
3145 ViewerTest::CurrentEventManager()->ProcessConfigure();
7fd59977 3146 break;
49582f9d 3147 }
f978241f 3148 case WM_MOVE:
3149 case WM_MOVING:
3150 case WM_SIZING:
49582f9d 3151 {
f978241f 3152 switch (aView->RenderingParams().StereoMode)
3153 {
3154 case Graphic3d_StereoMode_RowInterlaced:
3155 case Graphic3d_StereoMode_ColumnInterlaced:
3156 case Graphic3d_StereoMode_ChessBoard:
49582f9d 3157 {
3158 // track window moves to reverse stereo pair
3159 aView->MustBeResized();
3160 aView->Update();
f978241f 3161 break;
49582f9d 3162 }
f978241f 3163 default:
3164 break;
3165 }
3166 break;
49582f9d 3167 }
3168 case WM_KEYUP:
7fd59977 3169 case WM_KEYDOWN:
49582f9d 3170 {
3171 const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
3172 if (aVKey != Aspect_VKey_UNKNOWN)
4fe56619 3173 {
49582f9d 3174 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3175 if (theMsg == WM_KEYDOWN)
f978241f 3176 {
49582f9d 3177 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
f978241f 3178 }
49582f9d 3179 else
f978241f 3180 {
49582f9d 3181 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
f978241f 3182 }
49582f9d 3183 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
7fd59977 3184 }
3185 break;
49582f9d 3186 }
7fd59977 3187 case WM_LBUTTONUP:
3188 case WM_MBUTTONUP:
3189 case WM_RBUTTONUP:
7fd59977 3190 case WM_LBUTTONDOWN:
3191 case WM_MBUTTONDOWN:
3192 case WM_RBUTTONDOWN:
49582f9d 3193 {
3194 const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3195 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3196 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3197 switch (theMsg)
7fd59977 3198 {
49582f9d 3199 case WM_LBUTTONUP:
3200 case WM_LBUTTONDOWN:
3201 aButton = Aspect_VKeyMouse_LeftButton;
3202 break;
3203 case WM_MBUTTONUP:
3204 case WM_MBUTTONDOWN:
3205 aButton = Aspect_VKeyMouse_MiddleButton;
3206 break;
3207 case WM_RBUTTONUP:
3208 case WM_RBUTTONDOWN:
3209 aButton = Aspect_VKeyMouse_RightButton;
3210 break;
7fd59977 3211 }
49582f9d 3212 if (theMsg == WM_LBUTTONDOWN
3213 || theMsg == WM_MBUTTONDOWN
3214 || theMsg == WM_RBUTTONDOWN)
f978241f 3215 {
49582f9d 3216 if (aButton == Aspect_VKeyMouse_LeftButton)
f978241f 3217 {
49582f9d 3218 TheIsAnimating = Standard_False;
f978241f 3219 }
49582f9d 3220
3221 SetFocus (theWinHandle);
3222 SetCapture(theWinHandle);
3223 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
f978241f 3224 }
3225 else
3226 {
49582f9d 3227 ReleaseCapture();
3228 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
f978241f 3229 }
49582f9d 3230 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
f978241f 3231 break;
3232 }
49582f9d 3233 case WM_MOUSEWHEEL:
3234 {
3235 const int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
3236 const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
3237 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3238 Graphic3d_Vec2i aPos (int(short(LOWORD(lParam))), int(short(HIWORD(lParam))));
3239 POINT aCursorPnt = { aPos.x(), aPos.y() };
3240 if (ScreenToClient (theWinHandle, &aCursorPnt))
7fd59977 3241 {
49582f9d 3242 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3243 }
7fd59977 3244
49582f9d 3245 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3246 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3247 break;
3248 }
3249 case WM_MOUSEMOVE:
3250 {
3251 Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3252 Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (wParam);
3253 Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(wParam);
7fd59977 3254
49582f9d 3255 // don't make a slide-show from input events - fetch the actual mouse cursor position
3256 CURSORINFO aCursor;
3257 aCursor.cbSize = sizeof(aCursor);
3258 if (::GetCursorInfo (&aCursor) != FALSE)
3259 {
3260 POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
3261 if (ScreenToClient (theWinHandle, &aCursorPnt))
3262 {
3263 // as we override mouse position, we need overriding also mouse state
3264 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3265 aButtons = WNT_Window::MouseButtonsAsync();
3266 aFlags = WNT_Window::MouseKeyFlagsAsync();
3267 }
3268 }
7fd59977 3269
49582f9d 3270 if (VT_GetWindow().IsNull()
3271 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3272 {
3273 // mouse move events come also for inactive windows
3274 break;
7fd59977 3275 }
7fd59977 3276
49582f9d 3277 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3278 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
3279 break;
3280 }
d6fbb2ab 3281 case WM_INPUT:
3282 {
3283 UINT aSize = 0;
3284 ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
3285 NCollection_LocalArray<BYTE> aRawData (aSize);
3286 if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
3287 {
3288 break;
3289 }
3290
3291 const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
3292 if (aRawInput->header.dwType != RIM_TYPEHID)
3293 {
3294 break;
3295 }
3296
3297 RID_DEVICE_INFO aDevInfo;
3298 aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
3299 UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
3300 if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
3301 || (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
3302 && aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
3303 {
3304 break;
3305 }
3306
3307 WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
3308 if (ViewerTest::CurrentEventManager()->Update3dMouse (aSpaceData)
3309 && !VT_GetWindow().IsNull())
3310 {
3311 VT_GetWindow()->InvalidateContent();
3312 }
3313 break;
3314 }
7fd59977 3315 default:
49582f9d 3316 {
3317 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
7fd59977 3318 }
49582f9d 3319 }
3320 return 0L;
7fd59977 3321}
3322
7fd59977 3323//==============================================================================
3324//function : ViewerMainLoop
3325//purpose : Get a Event on the view and dispatch it
3326//==============================================================================
3327
49582f9d 3328int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
7fd59977 3329{
49582f9d 3330 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3331 if (aViewCtrl.IsNull()
3332 || theNbArgs < 4)
3333 {
3334 return 0;
3335 }
7fd59977 3336
49582f9d 3337 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
7fd59977 3338
49582f9d 3339 std::cout << "Start picking\n";
7fd59977 3340
49582f9d 3341 MSG aMsg;
3342 aMsg.wParam = 1;
3343 while (aViewCtrl->ToPickPoint())
3344 {
3345 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3346 if (GetMessageW (&aMsg, NULL, 0, 0))
3347 {
3348 TranslateMessage (&aMsg);
3349 DispatchMessageW (&aMsg);
7fd59977 3350 }
7fd59977 3351 }
3352
49582f9d 3353 std::cout << "Picking done\n";
3354 return 0;
7fd59977 3355}
3356
4fe56619 3357#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
7fd59977 3358
3359int min( int a, int b )
3360{
3361 if( a<b )
3362 return a;
3363 else
3364 return b;
3365}
3366
3367int max( int a, int b )
3368{
3369 if( a>b )
3370 return a;
3371 else
3372 return b;
3373}
3374
49582f9d 3375int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
4269bd1b 3376{
18d715bd 3377 static XEvent aReport;
49582f9d 3378 const Standard_Boolean toPick = theNbArgs > 0;
3379 if (theNbArgs > 0)
3380 {
3381 if (ViewerTest::CurrentEventManager().IsNull())
3382 {
3383 return 0;
3384 }
3385 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3386 }
3387
8693dfd0 3388 Display* aDisplay = GetDisplayConnection()->GetDisplay();
18d715bd 3389 XNextEvent (aDisplay, &aReport);
7fd59977 3390
18d715bd 3391 // Handle event for the chosen display connection
8693dfd0 3392 switch (aReport.type)
3393 {
3394 case ClientMessage:
3395 {
3396 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3397 {
3398 // Close the window
3399 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3400 return toPick ? 0 : 1;
3401 }
3402 break;
3403 }
3404 case FocusIn:
3405 {
3406 // Activate inactive view
49582f9d 3407 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3408 if (aWindow != aReport.xfocus.window)
3409 {
3410 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3411 }
3412 break;
3413 }
3414 case Expose:
3415 {
49582f9d 3416 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3417 if (anXWindow == aReport.xexpose.window)
3418 {
49582f9d 3419 ViewerTest::CurrentEventManager()->ProcessExpose();
8693dfd0 3420 }
3421
3422 // remove all the ExposureMask and process them at once
3423 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3424 {
3425 if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
18d715bd 3426 {
8693dfd0 3427 break;
18d715bd 3428 }
8693dfd0 3429 }
3430
3431 break;
3432 }
3433 case ConfigureNotify:
3434 {
3435 // remove all the StructureNotifyMask and process them at once
49582f9d 3436 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3437 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3438 {
3439 if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
3440 {
3441 break;
3442 }
3443 }
3444
3445 if (anXWindow == aReport.xconfigure.window)
3446 {
49582f9d 3447 ViewerTest::CurrentEventManager()->ProcessConfigure();
8693dfd0 3448 }
3449 break;
3450 }
3451 case KeyPress:
49582f9d 3452 case KeyRelease:
8693dfd0 3453 {
49582f9d 3454 XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
3455 const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
3456 const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
3457 if (aVKey != Aspect_VKey_UNKNOWN)
8693dfd0 3458 {
49582f9d 3459 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3460 if (aReport.type == KeyPress)
7fd59977 3461 {
49582f9d 3462 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
7fd59977 3463 }
8693dfd0 3464 else
7fd59977 3465 {
49582f9d 3466 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
7fd59977 3467 }
49582f9d 3468 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3469 }
3470 break;
3471 }
49582f9d 3472 case ButtonPress:
8693dfd0 3473 case ButtonRelease:
3474 {
49582f9d 3475 const Graphic3d_Vec2i aPos (aReport.xbutton.x, aReport.xbutton.y);
3476 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3477 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3478 if (aReport.xbutton.button == Button1)
8693dfd0 3479 {
49582f9d 3480 aButton = Aspect_VKeyMouse_LeftButton;
8693dfd0 3481 }
49582f9d 3482 if (aReport.xbutton.button == Button2)
8693dfd0 3483 {
49582f9d 3484 aButton = Aspect_VKeyMouse_MiddleButton;
8693dfd0 3485 }
49582f9d 3486 if (aReport.xbutton.button == Button3)
8693dfd0 3487 {
49582f9d 3488 aButton = Aspect_VKeyMouse_RightButton;
8693dfd0 3489 }
7fd59977 3490
49582f9d 3491 if (aReport.xbutton.state & ControlMask)
8693dfd0 3492 {
49582f9d 3493 aFlags |= Aspect_VKeyFlags_CTRL;
3494 }
3495 if (aReport.xbutton.state & ShiftMask)
3496 {
3497 aFlags |= Aspect_VKeyFlags_SHIFT;
3498 }
3499 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3500 {
3501 aFlags |= Aspect_VKeyFlags_ALT;
8693dfd0 3502 }
7fd59977 3503
49582f9d 3504 if (aReport.xbutton.button == Button4
3505 || aReport.xbutton.button == Button5)
8693dfd0 3506 {
49582f9d 3507 if (aReport.type != ButtonPress)
8693dfd0 3508 {
49582f9d 3509 break;
7fd59977 3510 }
49582f9d 3511
3512 const double aDeltaF = (aReport.xbutton.button == Button4 ? 1.0 : -1.0);
3513 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3514 }
3515 else if (aReport.type == ButtonPress)
3516 {
3517 if (aButton == Aspect_VKeyMouse_LeftButton)
7fd59977 3518 {
49582f9d 3519 TheIsAnimating = Standard_False;
7fd59977 3520 }
49582f9d 3521 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3522 }
3523 else
3524 {
49582f9d 3525 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3526 }
49582f9d 3527 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3528 break;
3529 }
3530 case MotionNotify:
3531 {
49582f9d 3532 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3533 if (anXWindow != aReport.xmotion.window)
3534 {
7fd59977 3535 break;
8693dfd0 3536 }
3537
3538 // remove all the ButtonMotionMask and process them at once
3539 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3540 {
3541 if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
7fd59977 3542 {
8693dfd0 3543 break;
3544 }
3545 }
7fd59977 3546
49582f9d 3547 Graphic3d_Vec2i aPos (aReport.xmotion.x, aReport.xmotion.y);
3548 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
3549 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3550 if ((aReport.xmotion.state & Button1Mask) != 0)
8693dfd0 3551 {
49582f9d 3552 aButtons |= Aspect_VKeyMouse_LeftButton;
3553 }
3554 else if ((aReport.xmotion.state & Button2Mask) != 0)
3555 {
3556 aButtons |= Aspect_VKeyMouse_MiddleButton;
3557 }
3558 else if ((aReport.xmotion.state & Button3Mask) != 0)
3559 {
3560 aButtons |= Aspect_VKeyMouse_RightButton;
3561 }
7fd59977 3562
49582f9d 3563 if (aReport.xmotion.state & ControlMask)
3564 {
3565 aFlags |= Aspect_VKeyFlags_CTRL;
8693dfd0 3566 }
49582f9d 3567 if (aReport.xmotion.state & ShiftMask)
8693dfd0 3568 {
49582f9d 3569 aFlags |= Aspect_VKeyFlags_SHIFT;
8693dfd0 3570 }
49582f9d 3571 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3572 {
3573 aFlags |= Aspect_VKeyFlags_ALT;
3574 }
3575
3576 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3577 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3578 break;
3579 }
3580 }
49582f9d 3581 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
7fd59977 3582}
3583
3584//==============================================================================
3585//function : VProcessEvents
8693dfd0 3586//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3587//==============================================================================
8693dfd0 3588static void VProcessEvents (ClientData theDispX, int)
7fd59977 3589{
8693dfd0 3590 Display* aDispX = (Display* )theDispX;
3591 Handle(Aspect_DisplayConnection) aDispConn;
3592 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3593 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3594 {
8693dfd0 3595 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3596 if (aDispConnTmp->GetDisplay() == aDispX)
3597 {
3598 aDispConn = aDispConnTmp;
3599 break;
3600 }
3601 }
3602 if (aDispConn.IsNull())
3603 {
23fe70ec 3604 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
8693dfd0 3605 return;
4269bd1b 3606 }
8693dfd0 3607
3608 // process new events in queue
3609 SetDisplayConnection (aDispConn);
3610 int aNbRemain = 0;
3611 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3612 {
8693dfd0 3613 const int anEventResult = ViewerMainLoop (0, NULL);
3614 if (anEventResult == 0)
18d715bd 3615 {
8693dfd0 3616 return;
3617 }
3618
3619 aNbRemain = XPending (aDispX);
3620 if (++anEventIter >= aNbEventsMax
3621 || aNbRemain <= 0)
3622 {
3623 break;
18d715bd 3624 }
7fd59977 3625 }
4269bd1b 3626
8693dfd0 3627 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3628 // it is possible that new events will arrive to queue before the end of this callback
3629 // so that either this callback should go into an infinite loop (blocking processing of other events)
3630 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3631 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3632 if (aNbRemain != 0)
3633 {
3634 XEvent aDummyEvent;
3635 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3636 aDummyEvent.type = ClientMessage;
3637 aDummyEvent.xclient.format = 32;
3638 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3639 XFlush (aDispX);
3640 }
4269bd1b 3641
8693dfd0 3642 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3643 {
3644 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3645 }
7fd59977 3646}
3647#endif
3648
3649//==============================================================================
3650//function : OSWindowSetup
3651//purpose : Setup for the X11 window to be able to cath the event
3652//==============================================================================
3653
3654
3655static void OSWindowSetup()
3656{
4fe56619 3657#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 3658 // X11
3659
3660 Window window = VT_GetWindow()->XWindow();
18d715bd 3661 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
3662 Display *aDisplay = GetDisplayConnection()->GetDisplay();
3663 XSynchronize(aDisplay, 1);
7fd59977 3664
3665 // X11 : For keyboard on SUN
3666 XWMHints wmhints;
3667 wmhints.flags = InputHint;
3668 wmhints.input = 1;
3669
18d715bd 3670 XSetWMHints( aDisplay, window, &wmhints);
7fd59977 3671
49582f9d 3672 XSelectInput( aDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask |
7fd59977 3673 ButtonPressMask | ButtonReleaseMask |
3674 StructureNotifyMask |
3675 PointerMotionMask |
3676 Button1MotionMask | Button2MotionMask |
18d715bd 3677 Button3MotionMask | FocusChangeMask
7fd59977 3678 );
18d715bd 3679 Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
3680 XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
7fd59977 3681
18d715bd 3682 XSynchronize(aDisplay, 0);
7fd59977 3683
3684#else
57c28b61 3685 // _WIN32
7fd59977 3686#endif
3687
3688}
3689
7fd59977 3690//==============================================================================
3691//function : VFit
1beb58d7 3692//purpose :
7fd59977 3693//==============================================================================
3694
1beb58d7 3695static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 3696{
1beb58d7 3697 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3698 if (aView.IsNull())
b586500b 3699 {
23fe70ec 3700 Message::SendFail ("Error: no active viewer");
1beb58d7 3701 return 1;
b586500b 3702 }
3703
1beb58d7 3704 Standard_Boolean toFit = Standard_True;
3705 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3706 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 3707 {
1beb58d7 3708 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 3709 anArg.LowerCase();
1beb58d7 3710 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 3711 {
1beb58d7 3712 continue;
3713 }
3714 else if (anArg == "-selected")
3715 {
3716 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3717 toFit = Standard_False;
3718 }
3719 else
3720 {
23fe70ec 3721 Message::SendFail() << "Syntax error at '" << anArg << "'";
b586500b 3722 }
3723 }
3724
1beb58d7 3725 if (toFit)
3726 {
3727 aView->FitAll (0.01, Standard_False);
7fd59977 3728 }
3729 return 0;
3730}
3731
6262a303 3732//=======================================================================
3733//function : VFitArea
3734//purpose : Fit view to show area located between two points
3735// : given in world 2D or 3D coordinates.
3736//=======================================================================
3737static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3738{
3739 Handle(V3d_View) aView = ViewerTest::CurrentView();
3740 if (aView.IsNull())
3741 {
23fe70ec 3742 Message::SendFail ("Error: No active viewer");
6262a303 3743 return 1;
3744 }
3745
3746 // Parse arguments.
3747 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3748 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3749
3750 if (theArgNb == 5)
3751 {
3752 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3753 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3754 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3755 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3756 }
3757 else if (theArgNb == 7)
3758 {
3759 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3760 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3761 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3762 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3763 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3764 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3765 }
3766 else
3767 {
23fe70ec 3768 Message::SendFail ("Syntax error: Invalid number of arguments");
6262a303 3769 theDI.PrintHelp(theArgVec[0]);
3770 return 1;
3771 }
3772
3773 // Convert model coordinates to view space
3774 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3775 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3776 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3777
3778 // Determine fit area
3779 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3780 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3781
3782 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3783
3784 if (aDiagonal < Precision::Confusion())
3785 {
23fe70ec 3786 Message::SendFail ("Error: view area is too small");
6262a303 3787 return 1;
3788 }
3789
3790 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3791 return 0;
3792}
3793
7fd59977 3794//==============================================================================
3795//function : VZFit
3796//purpose : ZFitall, no DRAW arguments
3797//Draw arg : No args
3798//==============================================================================
197ac94e 3799static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 3800{
197ac94e 3801 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3802
3803 if (aCurrentView.IsNull())
3804 {
23fe70ec 3805 Message::SendFail ("Error: no active viewer");
197ac94e 3806 return 1;
3807 }
3808
3809 if (theArgsNb == 1)
3810 {
c357e426 3811 aCurrentView->ZFitAll();
197ac94e 3812 aCurrentView->Redraw();
3813 return 0;
3814 }
3815
3816 Standard_Real aScale = 1.0;
3817
3818 if (theArgsNb >= 2)
3819 {
3820 aScale = Draw::Atoi (theArgVec[1]);
3821 }
3822
c357e426 3823 aCurrentView->ZFitAll (aScale);
197ac94e 3824 aCurrentView->Redraw();
7fd59977 3825
197ac94e 3826 return 0;
3827}
7fd59977 3828
197ac94e 3829//==============================================================================
3830//function : VRepaint
3831//purpose :
3832//==============================================================================
56689b27 3833static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 3834{
56689b27 3835 Handle(V3d_View) aView = ViewerTest::CurrentView();
3836 if (aView.IsNull())
3837 {
23fe70ec 3838 Message::SendFail ("Error: no active viewer");
56689b27 3839 return 1;
3840 }
3841
3842 Standard_Boolean isImmediateUpdate = Standard_False;
3843 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3844 {
3845 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3846 anArg.LowerCase();
8693dfd0 3847 if (anArg == "-immediate"
3848 || anArg == "-imm")
56689b27 3849 {
3850 isImmediateUpdate = Standard_True;
3851 if (anArgIter + 1 < theArgNb
dae2a922 3852 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
56689b27 3853 {
3854 ++anArgIter;
3855 }
3856 }
8693dfd0 3857 else if (anArg == "-continuous"
3858 || anArg == "-cont"
3859 || anArg == "-fps"
3860 || anArg == "-framerate")
3861 {
3862 Standard_Real aFps = -1.0;
3863 if (anArgIter + 1 < theArgNb
d45edf24 3864 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
8693dfd0 3865 {
3866 aFps = Draw::Atof (theArgVec[++anArgIter]);
3867 }
3868
3869 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3870 if (Abs (aFps) >= 1.0)
3871 {
3872 aRedrawer.Start (aView->Window(), aFps);
3873 }
3874 else
3875 {
3876 aRedrawer.Stop();
3877 }
3878 }
56689b27 3879 else
3880 {
23fe70ec 3881 Message::SendFail() << "Syntax error at '" << anArg << "'";
8693dfd0 3882 return 1;
56689b27 3883 }
3884 }
3885
3886 if (isImmediateUpdate)
3887 {
3888 aView->RedrawImmediate();
3889 }
3890 else
3891 {
3892 aView->Redraw();
3893 }
3894 return 0;
7fd59977 3895}
3896
7fd59977 3897//==============================================================================
3898//function : VClear
3899//purpose : Remove all the object from the viewer
3900//Draw arg : No args
3901//==============================================================================
3902
3903static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3904{
3905 Handle(V3d_View) V = ViewerTest::CurrentView();
3906 if(!V.IsNull())
3907 ViewerTest::Clear();
3908 return 0;
3909}
3910
3911//==============================================================================
3912//function : VPick
3913//purpose :
3914//==============================================================================
3915
49582f9d 3916static int VPick (Draw_Interpretor& ,
3917 Standard_Integer theNbArgs,
3918 const char** theArgVec)
3919{
3920 if (ViewerTest::CurrentView().IsNull())
3921 {
3922 return 1;
3923 }
7fd59977 3924
49582f9d 3925 if (theNbArgs < 4)
3926 {
23fe70ec 3927 Message::SendFail ("Syntax error: wrong number of arguments");
49582f9d 3928 return 1;
3929 }
7fd59977 3930
49582f9d 3931 while (ViewerMainLoop (theNbArgs, theArgVec))
3932 {
3933 //
3934 }
7fd59977 3935
49582f9d 3936 return 0;
7fd59977 3937}
3938
293211ae 3939namespace
7fd59977 3940{
7fd59977 3941
293211ae 3942 //! Changes the background
3943 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3944 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3945 //! @param theCommandLineArguments the array of command line arguments
3946 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3947 static int vbackground (Draw_Interpretor& theDrawInterpretor,
3948 const Standard_Integer theNumberOfCommandLineArguments,
3949 const char** const theCommandLineArguments)
7fd59977 3950 {
293211ae 3951 if (theNumberOfCommandLineArguments < 1)
7fd59977 3952 {
293211ae 3953 return TCL_ERROR;
7fd59977 3954 }
293211ae 3955 BackgroundChanger aBackgroundChanger;
3956 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
3957 theNumberOfCommandLineArguments,
3958 theCommandLineArguments))
f8b2ed36 3959 {
293211ae 3960 theDrawInterpretor << "Wrong command arguments.\n"
3961 "Type 'help "
3962 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
3963 return TCL_ERROR;
f8b2ed36 3964 }
293211ae 3965 return TCL_OK;
f8b2ed36 3966 }
3967
293211ae 3968} // namespace
f42753ed 3969
7fd59977 3970//==============================================================================
3971//function : VScale
3972//purpose : View Scaling
3973//==============================================================================
3974
3975static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3976{
3977 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3978 if ( V3dView.IsNull() ) return 1;
3979
3980 if ( argc != 4 ) {
586db386 3981 di << argv[0] << "Invalid number of arguments\n";
7fd59977 3982 return 1;
3983 }
91322f44 3984 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 3985 return 0;
3986}
3987//==============================================================================
536d98e2 3988//function : VZBuffTrihedron
3989//purpose :
7fd59977 3990//==============================================================================
3991
536d98e2 3992static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3993 Standard_Integer theArgNb,
3994 const char** theArgVec)
7fd59977 3995{
536d98e2 3996 Handle(V3d_View) aView = ViewerTest::CurrentView();
3997 if (aView.IsNull())
3998 {
23fe70ec 3999 Message::SendFail ("Error: no active viewer");
536d98e2 4000 return 1;
4001 }
7fd59977 4002
536d98e2 4003 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 4004
536d98e2 4005 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
4006 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
0aeb8984 4007 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
4008 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
4009 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
536d98e2 4010 Quantity_Color anArrowColorX = Quantity_NOC_RED;
4011 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
4012 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
4013 Standard_Real aScale = 0.1;
4014 Standard_Real aSizeRatio = 0.8;
4015 Standard_Real anArrowDiam = 0.05;
4016 Standard_Integer aNbFacets = 12;
4017 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 4018 {
536d98e2 4019 Standard_CString anArg = theArgVec[anArgIter];
4020 TCollection_AsciiString aFlag (anArg);
4021 aFlag.LowerCase();
4022 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 4023 {
536d98e2 4024 continue;
4025 }
4026 else if (aFlag == "-on")
7c8a8fcc 4027 {
536d98e2 4028 continue;
4029 }
4030 else if (aFlag == "-off")
7c8a8fcc 4031 {
536d98e2 4032 aView->TriedronErase();
4033 return 0;
4034 }
4035 else if (aFlag == "-pos"
4036 || aFlag == "-position"
4037 || aFlag == "-corner")
7c8a8fcc 4038 {
536d98e2 4039 if (++anArgIter >= theArgNb)
4040 {
23fe70ec 4041 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4042 return 1;
4043 }
4044
4045 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
4046 aPosName.LowerCase();
4047 if (aPosName == "center")
4048 {
4049 aPosition = Aspect_TOTP_CENTER;
4050 }
4051 else if (aPosName == "left_lower"
4052 || aPosName == "lower_left"
4053 || aPosName == "leftlower"
4054 || aPosName == "lowerleft")
4055 {
4056 aPosition = Aspect_TOTP_LEFT_LOWER;
4057 }
4058 else if (aPosName == "left_upper"
4059 || aPosName == "upper_left"
4060 || aPosName == "leftupper"
4061 || aPosName == "upperleft")
4062 {
4063 aPosition = Aspect_TOTP_LEFT_UPPER;
4064 }
4065 else if (aPosName == "right_lower"
4066 || aPosName == "lower_right"
4067 || aPosName == "rightlower"
4068 || aPosName == "lowerright")
4069 {
4070 aPosition = Aspect_TOTP_RIGHT_LOWER;
4071 }
4072 else if (aPosName == "right_upper"
4073 || aPosName == "upper_right"
4074 || aPosName == "rightupper"
4075 || aPosName == "upperright")
4076 {
4077 aPosition = Aspect_TOTP_RIGHT_UPPER;
4078 }
4079 else
4080 {
23fe70ec 4081 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
536d98e2 4082 return 1;
4083 }
4084 }
4085 else if (aFlag == "-type")
7c8a8fcc 4086 {
536d98e2 4087 if (++anArgIter >= theArgNb)
4088 {
23fe70ec 4089 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4090 return 1;
4091 }
4092
4093 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
4094 aTypeName.LowerCase();
4095 if (aTypeName == "wireframe"
4096 || aTypeName == "wire")
4097 {
4098 aVisType = V3d_WIREFRAME;
4099 }
4100 else if (aTypeName == "zbuffer"
4101 || aTypeName == "shaded")
4102 {
4103 aVisType = V3d_ZBUFFER;
4104 }
4105 else
4106 {
23fe70ec 4107 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
536d98e2 4108 }
4109 }
4110 else if (aFlag == "-scale")
7c8a8fcc 4111 {
536d98e2 4112 if (++anArgIter >= theArgNb)
4113 {
23fe70ec 4114 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4115 return 1;
4116 }
4117
4118 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 4119 }
536d98e2 4120 else if (aFlag == "-size"
4121 || aFlag == "-sizeratio")
4122 {
4123 if (++anArgIter >= theArgNb)
4124 {
23fe70ec 4125 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4126 return 1;
4127 }
7c8a8fcc 4128
536d98e2 4129 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
4130 }
4131 else if (aFlag == "-arrowdiam"
4132 || aFlag == "-arrowdiameter")
4133 {
4134 if (++anArgIter >= theArgNb)
4135 {
23fe70ec 4136 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4137 return 1;
4138 }
7c8a8fcc 4139
536d98e2 4140 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
4141 }
4142 else if (aFlag == "-nbfacets")
4143 {
4144 if (++anArgIter >= theArgNb)
4145 {
23fe70ec 4146 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4147 return 1;
4148 }
7c8a8fcc 4149
536d98e2 4150 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
4151 }
4152 else if (aFlag == "-colorlabel"
0aeb8984 4153 || aFlag == "-colorlabels"
4154 || aFlag == "-colorlabelx"
4155 || aFlag == "-colorlabely"
4156 || aFlag == "-colorlabelz"
4157 || aFlag == "-colorarrowx"
4158 || aFlag == "-colorarrowy"
4159 || aFlag == "-colorarrowz")
7c8a8fcc 4160 {
0aeb8984 4161 Quantity_Color aColor;
dae2a922 4162 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4163 theArgVec + anArgIter + 1,
0aeb8984 4164 aColor);
536d98e2 4165 if (aNbParsed == 0)
4166 {
23fe70ec 4167 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4168 return 1;
4169 }
0aeb8984 4170
4171 if (aFlag == "-colorarrowx")
536d98e2 4172 {
0aeb8984 4173 anArrowColorX = aColor;
536d98e2 4174 }
0aeb8984 4175 else if (aFlag == "-colorarrowy")
536d98e2 4176 {
0aeb8984 4177 anArrowColorY = aColor;
536d98e2 4178 }
0aeb8984 4179 else if (aFlag == "-colorarrowz")
536d98e2 4180 {
0aeb8984 4181 anArrowColorZ = aColor;
4182 }
4183 else if (aFlag == "-colorlabelx")
4184 {
4185 aLabelsColorX = aColor;
4186 }
4187 else if (aFlag == "-colorlabely")
4188 {
4189 aLabelsColorY = aColor;
4190 }
4191 else if (aFlag == "-colorlabelz")
4192 {
4193 aLabelsColorZ = aColor;
4194 }
4195 else
4196 {
4197 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
536d98e2 4198 }
4199 anArgIter += aNbParsed;
4200 }
4201 else
4202 {
23fe70ec 4203 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
7c8a8fcc 4204 return 1;
4205 }
7c8a8fcc 4206 }
4207
0aeb8984 4208 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
4209 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
4210 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
4211 aTrihedron->SetSizeRatio (aSizeRatio);
4212 aTrihedron->SetNbFacets (aNbFacets);
4213 aTrihedron->SetArrowDiameter(anArrowDiam);
4214 aTrihedron->SetScale (aScale);
4215 aTrihedron->SetPosition (aPosition);
4216 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
4217 aTrihedron->Display (aView);
4218
c357e426 4219 aView->ZFitAll();
7fd59977 4220 return 0;
4221}
4222
4223//==============================================================================
4224//function : VRotate
4225//purpose : Camera Rotating
4226//==============================================================================
4227
4af098ba 4228static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4229{
4230 Handle(V3d_View) aView = ViewerTest::CurrentView();
4231 if (aView.IsNull())
4232 {
23fe70ec 4233 Message::SendFail ("Error: no active viewer");
7fd59977 4234 return 1;
4235 }
4236
4af098ba 4237 Standard_Boolean hasFlags = Standard_False;
4238 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4239 {
4240 Standard_CString anArg (theArgVec[anArgIter]);
4241 TCollection_AsciiString aFlag (anArg);
4242 aFlag.LowerCase();
4243 if (aFlag == "-mousestart"
4244 || aFlag == "-mousefrom")
4245 {
4246 hasFlags = Standard_True;
4247 if (anArgIter + 2 >= theArgNb)
4248 {
23fe70ec 4249 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4250 return 1;
4251 }
4252
4253 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4254 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4255 aView->StartRotation (anX, anY);
4256 }
4257 else if (aFlag == "-mousemove")
4258 {
4259 hasFlags = Standard_True;
4260 if (anArgIter + 2 >= theArgNb)
4261 {
23fe70ec 4262 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4263 return 1;
4264 }
4265
4266 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4267 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4268 aView->Rotation (anX, anY);
4269 }
4270 else if (theArgNb != 4
4271 && theArgNb != 7)
4272 {
23fe70ec 4273 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4274 return 1;
4275 }
4276 }
4277
4278 if (hasFlags)
4279 {
7fd59977 4280 return 0;
4af098ba 4281 }
4282 else if (theArgNb == 4)
4283 {
4284 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4285 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4286 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4287 aView->Rotate (anAX, anAY, anAZ);
4288 return 0;
4289 }
4290 else if (theArgNb == 7)
4291 {
4292 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4293 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4294 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4295
4296 Standard_Real anX = Draw::Atof (theArgVec[4]);
4297 Standard_Real anY = Draw::Atof (theArgVec[5]);
4298 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4299
4300 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4301 return 0;
7fd59977 4302 }
4af098ba 4303
23fe70ec 4304 Message::SendFail ("Error: Invalid number of arguments");
4af098ba 4305 return 1;
7fd59977 4306}
4307
4308//==============================================================================
4309//function : VZoom
4310//purpose : View zoom in / out (relative to current zoom)
4311//==============================================================================
4312
4313static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4314 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4315 if ( V3dView.IsNull() ) {
4316 return 1;
4317 }
4318
4319 if ( argc == 2 ) {
91322f44 4320 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4321 if ( coef <= 0.0 ) {
586db386 4322 di << argv[1] << "Invalid value\n";
7fd59977 4323 return 1;
4324 }
91322f44 4325 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4326 return 0;
4327 } else {
586db386 4328 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4329 return 1;
4330 }
4331}
4332
4333//==============================================================================
4334//function : VPan
4335//purpose : View panning (in pixels)
4336//==============================================================================
4337
4338static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4339 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4340 if ( V3dView.IsNull() ) return 1;
4341
4342 if ( argc == 3 ) {
91322f44 4343 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4344 return 0;
4345 } else {
586db386 4346 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4347 return 1;
4348 }
4349}
4350
49e1a5c7 4351//==============================================================================
4352//function : VPlace
4353//purpose : Place the point (in pixels) at the center of the window
4354//==============================================================================
4355static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4356{
4357 Handle(V3d_View) aView = ViewerTest::CurrentView();
4358 if (aView.IsNull())
4359 {
23fe70ec 4360 Message::SendFail ("Error: no active viewer");
49e1a5c7 4361 return 1;
4362 }
4363
4364 if (theArgNb != 3)
4365 {
23fe70ec 4366 Message::SendFail ("Syntax error: wrong number of arguments");
49e1a5c7 4367 return 1;
4368 }
4369
4370 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4371
4372 return 0;
4373}
7fd59977 4374
71215351 4375static int VColorScale (Draw_Interpretor& theDI,
4376 Standard_Integer theArgNb,
4377 const char** theArgVec)
4378{
7fd59977 4379 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4380 Handle(V3d_View) aView = ViewerTest::CurrentView();
4381 if (aContext.IsNull())
4382 {
23fe70ec 4383 Message::SendFail ("Error: no active viewer");
71215351 4384 return 1;
7fd59977 4385 }
24a88697 4386 if (theArgNb <= 1)
4387 {
23fe70ec 4388 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
24a88697 4389 return 1;
4390 }
7fd59977 4391
4b3d6eb1 4392 Handle(AIS_ColorScale) aColorScale;
7a324550 4393 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4394 {
4b3d6eb1 4395 // find existing object
4396 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4397 if (aColorScale.IsNull())
7a324550 4398 {
23fe70ec 4399 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
7a324550 4400 return 1;
4401 }
4402 }
71215351 4403
7a324550 4404 if (theArgNb <= 2)
4405 {
4b3d6eb1 4406 if (aColorScale.IsNull())
4407 {
23fe70ec 4408 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4b3d6eb1 4409 return 1;
4410 }
4411
7a324550 4412 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4413 << "Min range: " << aColorScale->GetMin() << "\n"
4414 << "Max range: " << aColorScale->GetMax() << "\n"
4415 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4416 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4417 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4418 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4419 << "Label position: ";
4b3d6eb1 4420 switch (aColorScale->GetLabelPosition())
71215351 4421 {
4422 case Aspect_TOCSP_NONE:
4423 theDI << "None\n";
4424 break;
4425 case Aspect_TOCSP_LEFT:
4426 theDI << "Left\n";
4427 break;
4428 case Aspect_TOCSP_RIGHT:
4429 theDI << "Right\n";
4430 break;
4431 case Aspect_TOCSP_CENTER:
4432 theDI << "Center\n";
4433 break;
4434 }
4435 return 0;
4436 }
71215351 4437
4b3d6eb1 4438 if (aColorScale.IsNull())
4439 {
4440 aColorScale = new AIS_ColorScale();
4441 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4442 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4443 }
4444
4445 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4446 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4447 {
4448 Standard_CString anArg = theArgVec[anArgIter];
4449 TCollection_AsciiString aFlag (anArg);
4450 aFlag.LowerCase();
4451 if (anUpdateTool.parseRedrawMode (aFlag))
4452 {
4453 continue;
4454 }
4455 else if (aFlag == "-range")
4456 {
4457 if (anArgIter + 3 >= theArgNb)
4458 {
23fe70ec 4459 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
71215351 4460 return 1;
4461 }
4462
4b3d6eb1 4463 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4464 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4465 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
d45edf24 4466 if (!aRangeMin.IsRealValue (Standard_True)
4467 || !aRangeMax.IsRealValue (Standard_True))
71215351 4468 {
23fe70ec 4469 Message::SendFail ("Syntax error: the range values should be real");
71215351 4470 return 1;
4471 }
4b3d6eb1 4472 else if (!aNbIntervals.IsIntegerValue())
71215351 4473 {
23fe70ec 4474 Message::SendFail ("Syntax error: the number of intervals should be integer");
71215351 4475 return 1;
4476 }
4477
4b3d6eb1 4478 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4479 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4480 }
4481 else if (aFlag == "-font")
4482 {
4483 if (anArgIter + 1 >= theArgNb)
4484 {
23fe70ec 4485 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4486 return 1;
4487 }
51740958 4488 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4489 if (!aFontArg.IsIntegerValue())
71215351 4490 {
23fe70ec 4491 Message::SendFail ("Syntax error: HeightFont value should be integer");
71215351 4492 return 1;
4493 }
4494
4b3d6eb1 4495 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4496 anArgIter += 1;
4497 }
4498 else if (aFlag == "-textpos")
4499 {
4500 if (anArgIter + 1 >= theArgNb)
4501 {
23fe70ec 4502 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4503 return 1;
4504 }
4b3d6eb1 4505
51740958 4506 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4507 aTextPosArg.LowerCase();
4b3d6eb1 4508 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4509 if (aTextPosArg == "none")
71215351 4510 {
4511 aLabPosition = Aspect_TOCSP_NONE;
4512 }
51740958 4513 else if (aTextPosArg == "left")
71215351 4514 {
4515 aLabPosition = Aspect_TOCSP_LEFT;
4516 }
51740958 4517 else if (aTextPosArg == "right")
71215351 4518 {
4519 aLabPosition = Aspect_TOCSP_RIGHT;
4520 }
51740958 4521 else if (aTextPosArg == "center")
71215351 4522 {
4523 aLabPosition = Aspect_TOCSP_CENTER;
4524 }
4525 else
4526 {
23fe70ec 4527 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
71215351 4528 return 1;
4529 }
4b3d6eb1 4530 aColorScale->SetLabelPosition (aLabPosition);
71215351 4531 }
24a88697 4532 else if (aFlag == "-logarithmic"
4533 || aFlag == "-log")
4534 {
4535 if (anArgIter + 1 >= theArgNb)
4536 {
23fe70ec 4537 Message::SendFail() << "Synta error at argument '" << anArg << "'";
24a88697 4538 return 1;
4539 }
4b3d6eb1 4540
24a88697 4541 Standard_Boolean IsLog;
dae2a922 4542 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
24a88697 4543 {
23fe70ec 4544 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
24a88697 4545 return 1;
4546 }
4b3d6eb1 4547 aColorScale->SetLogarithmic (IsLog);
4548 }
4549 else if (aFlag == "-huerange"
4550 || aFlag == "-hue")
4551 {
4552 if (anArgIter + 2 >= theArgNb)
4553 {
23fe70ec 4554 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4555 return 1;
4556 }
4557
4558 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4559 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4560 aColorScale->SetHueRange (aHueMin, aHueMax);
4561 }
4562 else if (aFlag == "-colorrange")
4563 {
4564 Quantity_Color aColorMin, aColorMax;
dae2a922 4565 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4566 theArgVec + (anArgIter + 1),
4567 aColorMin);
4b3d6eb1 4568 anArgIter += aNbParsed1;
dae2a922 4569 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4570 theArgVec + (anArgIter + 1),
4571 aColorMax);
4b3d6eb1 4572 anArgIter += aNbParsed2;
4573 if (aNbParsed1 == 0
4574 || aNbParsed2 == 0)
4575 {
23fe70ec 4576 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4b3d6eb1 4577 return 1;
4578 }
4579
4580 aColorScale->SetColorRange (aColorMin, aColorMax);
4581 }
4582 else if (aFlag == "-reversed"
4583 || aFlag == "-inverted"
4584 || aFlag == "-topdown"
4585 || aFlag == "-bottomup")
4586 {
4587 Standard_Boolean toEnable = Standard_True;
4588 if (anArgIter + 1 < theArgNb
dae2a922 4589 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4590 {
4591 ++anArgIter;
4592 }
4593 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4594 }
4595 else if (aFlag == "-smooth"
4596 || aFlag == "-smoothtransition")
4597 {
4598 Standard_Boolean toEnable = Standard_True;
4599 if (anArgIter + 1 < theArgNb
dae2a922 4600 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4601 {
4602 ++anArgIter;
4603 }
4604 aColorScale->SetSmoothTransition (toEnable);
24a88697 4605 }
71215351 4606 else if (aFlag == "-xy")
4607 {
4608 if (anArgIter + 2 >= theArgNb)
4609 {
23fe70ec 4610 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4611 return 1;
4612 }
4613
4b3d6eb1 4614 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4615 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4616 if (!anX.IsIntegerValue()
4617 || !anY.IsIntegerValue())
71215351 4618 {
23fe70ec 4619 Message::SendFail ("Syntax error: coordinates should be integer values");
71215351 4620 return 1;
4621 }
4622
4b3d6eb1 4623 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4624 }
4625 else if (aFlag == "-width"
4b3d6eb1 4626 || aFlag == "-w"
4627 || aFlag == "-breadth")
b4b2ecca 4628 {
4629 if (anArgIter + 1 >= theArgNb)
4630 {
23fe70ec 4631 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4632 return 1;
4633 }
4634
4b3d6eb1 4635 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4636 if (!aBreadth.IsIntegerValue())
b4b2ecca 4637 {
23fe70ec 4638 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4639 return 1;
4640 }
4b3d6eb1 4641 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4642 }
4643 else if (aFlag == "-height"
4644 || aFlag == "-h")
4645 {
4646 if (anArgIter + 1 >= theArgNb)
4647 {
23fe70ec 4648 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4649 return 1;
4650 }
4651
4b3d6eb1 4652 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4653 if (!aHeight.IsIntegerValue())
b4b2ecca 4654 {
23fe70ec 4655 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4656 return 1;
4657 }
4b3d6eb1 4658 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4659 }
4660 else if (aFlag == "-color")
4661 {
4b3d6eb1 4662 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4663 {
23fe70ec 4664 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
71215351 4665 return 1;
4666 }
4b3d6eb1 4667 else if (anArgIter + 2 >= theArgNb)
71215351 4668 {
23fe70ec 4669 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4670 return 1;
71215351 4671 }
4672
4b3d6eb1 4673 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 4674 if (!anInd.IsIntegerValue())
4675 {
23fe70ec 4676 Message::SendFail ("Syntax error: Index value should be integer");
71215351 4677 return 1;
4678 }
4b3d6eb1 4679 const Standard_Integer anIndex = anInd.IntegerValue();
4680 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 4681 {
23fe70ec 4682 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
71215351 4683 return 1;
4684 }
4685
4b3d6eb1 4686 Quantity_Color aColor;
dae2a922 4687 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4688 theArgVec + (anArgIter + 1),
4689 aColor);
4b3d6eb1 4690 if (aNbParsed == 0)
71215351 4691 {
23fe70ec 4692 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
71215351 4693 return 1;
4694 }
4b3d6eb1 4695 aColorScale->SetIntervalColor (aColor, anIndex);
4696 aColorScale->SetColorType (Aspect_TOCSD_USER);
4697 anArgIter += aNbParsed;
71215351 4698 }
4699 else if (aFlag == "-label")
4700 {
4b3d6eb1 4701 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4702 {
23fe70ec 4703 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
71215351 4704 return 1;
4705 }
4706 else if (anArgIter + 2 >= theArgNb)
4707 {
23fe70ec 4708 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4709 return 1;
4710 }
4711
4712 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 4713 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 4714 {
23fe70ec 4715 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
71215351 4716 return 1;
4717 }
4718
94f16a89 4719 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4b3d6eb1 4720 aColorScale->SetLabel (aText, anIndex);
4721 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4722 anArgIter += 2;
4723 }
4b3d6eb1 4724 else if (aFlag == "-labelat"
4725 || aFlag == "-labat"
4726 || aFlag == "-labelatborder"
4727 || aFlag == "-labatborder"
4728 || aFlag == "-labelatcenter"
4729 || aFlag == "-labatcenter")
71215351 4730 {
4b3d6eb1 4731 Standard_Boolean toEnable = Standard_True;
4732 if (aFlag == "-labelat"
4733 || aFlag == "-labat")
71215351 4734 {
4b3d6eb1 4735 Standard_Integer aLabAtBorder = -1;
4736 if (++anArgIter >= theArgNb)
71215351 4737 {
4b3d6eb1 4738 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4739 anAtBorder.LowerCase();
4740 if (anAtBorder == "border")
71215351 4741 {
4b3d6eb1 4742 aLabAtBorder = 1;
71215351 4743 }
4b3d6eb1 4744 else if (anAtBorder == "center")
71215351 4745 {
4b3d6eb1 4746 aLabAtBorder = 0;
71215351 4747 }
71215351 4748 }
4b3d6eb1 4749 if (aLabAtBorder == -1)
4750 {
23fe70ec 4751 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4752 return 1;
4753 }
4754 toEnable = (aLabAtBorder == 1);
4755 }
4756 else if (anArgIter + 1 < theArgNb
dae2a922 4757 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4758 {
4759 ++anArgIter;
71215351 4760 }
4b3d6eb1 4761 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4762 || aFlag == "-labatcenter"
4763 ? !toEnable
4764 : toEnable);
4765 }
4766 else if (aFlag == "-colors")
4767 {
4768 Aspect_SequenceOfColor aSeq;
4769 for (;;)
4770 {
4771 Quantity_Color aColor;
dae2a922 4772 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4773 theArgVec + (anArgIter + 1),
4774 aColor);
4b3d6eb1 4775 if (aNbParsed == 0)
4776 {
4777 break;
4778 }
4779 anArgIter += aNbParsed;
4780 aSeq.Append (aColor);
4781 }
4782 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 4783 {
23fe70ec 4784 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4785 << aColorScale->GetNumberOfIntervals() << " intervals";
71215351 4786 return 1;
4787 }
4788
4b3d6eb1 4789 aColorScale->SetColors (aSeq);
4790 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 4791 }
14b741b0 4792 else if (aFlag == "-uniform")
4793 {
4794 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4795 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4796 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4797 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4798 aColorScale->SetColorType (Aspect_TOCSD_USER);
4799 }
4b3d6eb1 4800 else if (aFlag == "-labels"
4801 || aFlag == "-freelabels")
71215351 4802 {
4b3d6eb1 4803 if (anArgIter + 1 >= theArgNb)
4804 {
23fe70ec 4805 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4806 return 1;
4807 }
4808
4809 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4810 ? aColorScale->GetNumberOfIntervals() + 1
4811 : aColorScale->GetNumberOfIntervals();
4812 if (aFlag == "-freelabels")
4813 {
4814 ++anArgIter;
4815 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4816 }
4817 if (anArgIter + aNbLabels >= theArgNb)
71215351 4818 {
23fe70ec 4819 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
71215351 4820 return 1;
4821 }
4822
4823 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 4824 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 4825 {
94f16a89 4826 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
71215351 4827 }
4b3d6eb1 4828 aColorScale->SetLabels (aSeq);
4829 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4830 }
4831 else if (aFlag == "-title")
4832 {
4833 if (anArgIter + 1 >= theArgNb)
4834 {
23fe70ec 4835 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4836 return 1;
4837 }
4838
4839 Standard_Boolean isTwoArgs = Standard_False;
4840 if (anArgIter + 2 < theArgNb)
4841 {
4842 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4843 aSecondArg.LowerCase();
4b3d6eb1 4844 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 4845 if (aSecondArg == "none")
4846 {
4b3d6eb1 4847 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 4848 isTwoArgs = Standard_True;
4849 }
4850 else if (aSecondArg == "left")
4851 {
4b3d6eb1 4852 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 4853 isTwoArgs = Standard_True;
4854 }
4855 else if (aSecondArg == "right")
4856 {
4b3d6eb1 4857 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 4858 isTwoArgs = Standard_True;
4859 }
4860 else if (aSecondArg == "center")
4861 {
4b3d6eb1 4862 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 4863 isTwoArgs = Standard_True;
4864 }
4b3d6eb1 4865 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 4866 }
4867
94f16a89 4868 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4869 aColorScale->SetTitle (aTitle);
71215351 4870 if (isTwoArgs)
4871 {
4872 anArgIter += 1;
4873 }
4874 anArgIter += 1;
4875 }
4876 else if (aFlag == "-demoversion"
4877 || aFlag == "-demo")
4878 {
4b3d6eb1 4879 aColorScale->SetPosition (0, 0);
4880 aColorScale->SetTextHeight (16);
4881 aColorScale->SetRange (0.0, 100.0);
4882 aColorScale->SetNumberOfIntervals (10);
4883 aColorScale->SetBreadth (0);
4884 aColorScale->SetHeight (0);
4885 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4886 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4887 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 4888 }
d5514578 4889 else if (aFlag == "-findcolor")
4890 {
4891 if (anArgIter + 1 >= theArgNb)
4892 {
23fe70ec 4893 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
d5514578 4894 return 1;
4895 }
4896
4897 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4898
d45edf24 4899 if (!anArg1.IsRealValue (Standard_True))
d5514578 4900 {
23fe70ec 4901 Message::SendFail ("Syntax error: the value should be real");
d5514578 4902 return 1;
4903 }
4904
4905 Quantity_Color aColor;
4b3d6eb1 4906 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 4907 theDI << Quantity_Color::StringName (aColor.Name());
4908 return 0;
4909 }
71215351 4910 else
4911 {
23fe70ec 4912 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
71215351 4913 return 1;
4914 }
4915 }
4b3d6eb1 4916
4917 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4918 aView->Window()->Size (aWinWidth, aWinHeight);
4919 if (aColorScale->GetBreadth() == 0)
b4b2ecca 4920 {
4b3d6eb1 4921 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 4922 }
4b3d6eb1 4923 if (aColorScale->GetHeight() == 0)
4924 {
4925 aColorScale->SetHeight (aWinHeight);
4926 }
4927 aColorScale->SetToUpdate();
4928 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 4929 return 0;
4930}
4931
4932//==============================================================================
4933//function : VGraduatedTrihedron
a79f67f8 4934//purpose : Displays or hides a graduated trihedron
7fd59977 4935//==============================================================================
a79f67f8 4936static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4937 Quantity_Color& theColor)
13a22457 4938{
a79f67f8 4939 Quantity_NameOfColor aColorName;
4940 TCollection_AsciiString aVal = theValue;
4941 aVal.UpperCase();
4942 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 4943 {
a79f67f8 4944 return Standard_False;
13a22457 4945 }
a79f67f8 4946 theColor = Quantity_Color (aColorName);
4947 return Standard_True;
13a22457
S
4948}
4949
a79f67f8 4950static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 4951{
a79f67f8 4952 if (theArgNum < 2)
13a22457 4953 {
23fe70ec 4954 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4955 << theArgs[0] <<"' for more information";
4956 return 1;
13a22457 4957 }
7fd59977 4958
a79f67f8 4959 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4960 TCollection_AsciiString aParseKey;
4961 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4962 {
4963 TCollection_AsciiString anArg (theArgs [anArgIt]);
4964
d45edf24 4965 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
a79f67f8 4966 {
4967 aParseKey = anArg;
4968 aParseKey.Remove (1);
4969 aParseKey.LowerCase();
4970 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4971 continue;
4972 }
13a22457 4973
a79f67f8 4974 if (aParseKey.IsEmpty())
4975 {
4976 continue;
4977 }
4978
4979 aMapOfArgs(aParseKey)->Append (anArg);
4980 }
4981
4982 // Check parameters
4983 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4984 aMapIt.More(); aMapIt.Next())
7fd59977 4985 {
a79f67f8 4986 const TCollection_AsciiString& aKey = aMapIt.Key();
4987 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4988
4989 // Bool key, without arguments
4990 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4991 && anArgs->IsEmpty())
4992 {
4993 continue;
4994 }
4995
4996 // One argument
4997 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4998 && anArgs->Length() == 1)
4999 {
5000 continue;
5001 }
5002
5003 // On/off arguments
5004 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
5005 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 5006 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
5007 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 5008 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
5009 {
5010 continue;
5011 }
5012
5013 // One string argument
5014 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
5015 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
d45edf24 5016 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
a79f67f8 5017 {
5018 continue;
5019 }
5020
5021 // One integer argument
5022 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
5023 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
5024 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
5025 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
5026 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
5027 {
5028 continue;
5029 }
5030
5031 // One real argument
5032 if ( aKey.IsEqual ("arrowlength")
d45edf24 5033 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
a79f67f8 5034 {
5035 continue;
5036 }
5037
5038 // Two string arguments
5039 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
d45edf24 5040 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
13a22457 5041 {
a79f67f8 5042 continue;
13a22457 5043 }
a79f67f8 5044
5045 TCollection_AsciiString aLowerKey;
5046 aLowerKey = "-";
5047 aLowerKey += aKey;
5048 aLowerKey.LowerCase();
23fe70ec 5049 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
5050 << "Type help for more information";
a79f67f8 5051 return 1;
7fd59977 5052 }
5053
a79f67f8 5054 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5055 if (anAISContext.IsNull())
5056 {
23fe70ec 5057 Message::SendFail ("Error: no active viewer");
a79f67f8 5058 return 1;
5059 }
7fd59977 5060
a79f67f8 5061 Standard_Boolean toDisplay = Standard_True;
5062 Quantity_Color aColor;
5063 Graphic3d_GraduatedTrihedron aTrihedronData;
5064 // Process parameters
5065 Handle(TColStd_HSequenceOfAsciiString) aValues;
5066 if (aMapOfArgs.Find ("off", aValues))
7fd59977 5067 {
a79f67f8 5068 toDisplay = Standard_False;
5069 }
13a22457 5070
a79f67f8 5071 // AXES NAMES
5072 if (aMapOfArgs.Find ("xname", aValues))
5073 {
5074 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
5075 }
5076 if (aMapOfArgs.Find ("yname", aValues))
5077 {
5078 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
5079 }
5080 if (aMapOfArgs.Find ("zname", aValues))
5081 {
5082 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
5083 }
5084 if (aMapOfArgs.Find ("xdrawname", aValues))
5085 {
536d98e2 5086 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5087 }
5088 if (aMapOfArgs.Find ("ydrawname", aValues))
5089 {
536d98e2 5090 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5091 }
5092 if (aMapOfArgs.Find ("zdrawname", aValues))
5093 {
536d98e2 5094 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5095 }
5096 if (aMapOfArgs.Find ("xnameoffset", aValues))
5097 {
5098 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5099 }
5100 if (aMapOfArgs.Find ("ynameoffset", aValues))
5101 {
5102 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5103 }
5104 if (aMapOfArgs.Find ("znameoffset", aValues))
5105 {
5106 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5107 }
13a22457 5108
a79f67f8 5109 // COLORS
5110 if (aMapOfArgs.Find ("xnamecolor", aValues))
5111 {
5112 if (!GetColor (aValues->Value(1), aColor))
13a22457 5113 {
23fe70ec 5114 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
a79f67f8 5115 return 1;
13a22457 5116 }
a79f67f8 5117 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
5118 }
5119 if (aMapOfArgs.Find ("ynamecolor", aValues))
5120 {
5121 if (!GetColor (aValues->Value(1), aColor))
13a22457 5122 {
23fe70ec 5123 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
a79f67f8 5124 return 1;
5125 }
5126 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
5127 }
5128 if (aMapOfArgs.Find ("znamecolor", aValues))
5129 {
5130 if (!GetColor (aValues->Value(1), aColor))
5131 {
23fe70ec 5132 Message::SendFail ("Syntax error: -znamecolor wrong color name");
a79f67f8 5133 return 1;
5134 }
5135 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
5136 }
5137 if (aMapOfArgs.Find ("xcolor", aValues))
5138 {
5139 if (!GetColor (aValues->Value(1), aColor))
5140 {
23fe70ec 5141 Message::SendFail ("Syntax error: -xcolor wrong color name");
a79f67f8 5142 return 1;
5143 }
5144 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
5145 }
5146 if (aMapOfArgs.Find ("ycolor", aValues))
5147 {
5148 if (!GetColor (aValues->Value(1), aColor))
5149 {
23fe70ec 5150 Message::SendFail ("Syntax error: -ycolor wrong color name");
a79f67f8 5151 return 1;
5152 }
5153 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
5154 }
5155 if (aMapOfArgs.Find ("zcolor", aValues))
5156 {
5157 if (!GetColor (aValues->Value(1), aColor))
5158 {
23fe70ec 5159 Message::SendFail ("Syntax error: -zcolor wrong color name");
a79f67f8 5160 return 1;
5161 }
5162 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
5163 }
5164
5165 // TICKMARKS
5166 if (aMapOfArgs.Find ("xticks", aValues))
5167 {
536d98e2 5168 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5169 }
5170 if (aMapOfArgs.Find ("yticks", aValues))
5171 {
536d98e2 5172 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5173 }
5174 if (aMapOfArgs.Find ("zticks", aValues))
5175 {
536d98e2 5176 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5177 }
5178 if (aMapOfArgs.Find ("xticklength", aValues))
5179 {
536d98e2 5180 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5181 }
5182 if (aMapOfArgs.Find ("yticklength", aValues))
5183 {
536d98e2 5184 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5185 }
5186 if (aMapOfArgs.Find ("zticklength", aValues))
5187 {
536d98e2 5188 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5189 }
5190 if (aMapOfArgs.Find ("xdrawticks", aValues))
5191 {
536d98e2 5192 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5193 }
5194 if (aMapOfArgs.Find ("ydrawticks", aValues))
5195 {
536d98e2 5196 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5197 }
5198 if (aMapOfArgs.Find ("zdrawticks", aValues))
5199 {
536d98e2 5200 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5201 }
5202
5203 // VALUES
5204 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5205 {
536d98e2 5206 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5207 }
5208 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5209 {
536d98e2 5210 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5211 }
5212 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5213 {
536d98e2 5214 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5215 }
5216 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5217 {
5218 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5219 }
5220 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5221 {
5222 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5223 }
5224 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5225 {
5226 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5227 }
5228
5229 // ARROWS
5230 if (aMapOfArgs.Find ("arrowlength", aValues))
5231 {
536d98e2 5232 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5233 }
5234
5235 // FONTS
5236 if (aMapOfArgs.Find ("namefont", aValues))
5237 {
5238 aTrihedronData.SetNamesFont (aValues->Value(1));
5239 }
5240 if (aMapOfArgs.Find ("valuesfont", aValues))
5241 {
5242 aTrihedronData.SetValuesFont (aValues->Value(1));
5243 }
5244
536d98e2 5245 if (aMapOfArgs.Find ("drawgrid", aValues))
5246 {
5247 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5248 }
5249 if (aMapOfArgs.Find ("drawaxes", aValues))
5250 {
5251 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5252 }
5253
a79f67f8 5254 // The final step: display of erase trihedron
5255 if (toDisplay)
5256 {
5257 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5258 }
7fd59977 5259 else
a79f67f8 5260 {
5261 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5262 }
7fd59977 5263
5264 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5265 ViewerTest::CurrentView()->Redraw();
13a22457 5266
7fd59977 5267 return 0;
5268}
5269
3bffef55 5270//==============================================================================
5271//function : VTile
5272//purpose :
5273//==============================================================================
5274static int VTile (Draw_Interpretor& theDI,
5275 Standard_Integer theArgNb,
5276 const char** theArgVec)
5277{
5278 Handle(V3d_View) aView = ViewerTest::CurrentView();
5279 if (aView.IsNull())
5280 {
23fe70ec 5281 Message::SendFail ("Error: no active viewer");
3bffef55 5282 return 1;
5283 }
5284
5285 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5286 if (theArgNb < 2)
5287 {
5288 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5289 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5290 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5291 return 0;
5292 }
5293
5294 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5295 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5296 {
5297 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5298 anArg.LowerCase();
5299 if (anArg == "-lowerleft"
5300 || anArg == "-upperleft")
5301 {
5302 if (anArgIter + 3 < theArgNb)
5303 {
23fe70ec 5304 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5305 return 1;
5306 }
5307 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5308 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5309 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5310 }
5311 else if (anArg == "-total"
5312 || anArg == "-totalsize"
5313 || anArg == "-viewsize")
5314 {
5315 if (anArgIter + 3 < theArgNb)
5316 {
23fe70ec 5317 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5318 return 1;
5319 }
5320 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5321 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5322 if (aTile.TotalSize.x() < 1
5323 || aTile.TotalSize.y() < 1)
5324 {
23fe70ec 5325 Message::SendFail ("Error: total size is incorrect");
3bffef55 5326 return 1;
5327 }
5328 }
5329 else if (anArg == "-tilesize")
5330 {
5331 if (anArgIter + 3 < theArgNb)
5332 {
23fe70ec 5333 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5334 return 1;
5335 }
5336
5337 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5338 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5339 if (aTile.TileSize.x() < 1
5340 || aTile.TileSize.y() < 1)
5341 {
23fe70ec 5342 Message::SendFail ("Error: tile size is incorrect");
3bffef55 5343 return 1;
5344 }
5345 }
5346 else if (anArg == "-unset")
5347 {
5348 aView->Camera()->SetTile (Graphic3d_CameraTile());
5349 aView->Redraw();
5350 return 0;
5351 }
5352 }
5353
5354 if (aTile.TileSize.x() < 1
5355 || aTile.TileSize.y() < 1)
5356 {
23fe70ec 5357 Message::SendFail ("Error: tile size is undefined");
3bffef55 5358 return 1;
5359 }
5360 else if (aTile.TotalSize.x() < 1
5361 || aTile.TotalSize.y() < 1)
5362 {
23fe70ec 5363 Message::SendFail ("Error: total size is undefined");
3bffef55 5364 return 1;
5365 }
5366
5367 aView->Camera()->SetTile (aTile);
5368 aView->Redraw();
5369 return 0;
5370}
5371
7c3ef2f7 5372//! Format ZLayer ID.
5373inline const char* formZLayerId (const Standard_Integer theLayerId)
5374{
5375 switch (theLayerId)
5376 {
5377 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5378 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5379 case Graphic3d_ZLayerId_Top: return "[TOP]";
5380 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5381 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5382 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5383 }
5384 return "";
5385}
5386
5387//! Print the ZLayer information.
5388inline void printZLayerInfo (Draw_Interpretor& theDI,
5389 const Graphic3d_ZLayerSettings& theLayer)
5390{
5391 if (!theLayer.Name().IsEmpty())
5392 {
5393 theDI << " Name: " << theLayer.Name() << "\n";
5394 }
5395 if (theLayer.IsImmediate())
5396 {
5397 theDI << " Immediate: TRUE\n";
5398 }
5399 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5400 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5401 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5402 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5403 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5404 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5405 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5406 {
5407 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5408 }
5409}
5410
59f45b7c 5411//==============================================================================
5412//function : VZLayer
5413//purpose : Test z layer operations for v3d viewer
5414//==============================================================================
7c3ef2f7 5415static int VZLayer (Draw_Interpretor& theDI,
5416 Standard_Integer theArgNb,
5417 const char** theArgVec)
59f45b7c 5418{
7c3ef2f7 5419 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5420 if (aContextAIS.IsNull())
5421 {
23fe70ec 5422 Message::SendFail ("Error: no active viewer");
59f45b7c 5423 return 1;
5424 }
5425
5426 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5427 if (theArgNb < 2)
59f45b7c 5428 {
7c3ef2f7 5429 TColStd_SequenceOfInteger aLayers;
5430 aViewer->GetAllZLayers (aLayers);
5431 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5432 {
5433 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5434 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5435 printZLayerInfo (theDI, aSettings);
5436 }
59f45b7c 5437 return 1;
5438 }
5439
7c3ef2f7 5440 Standard_Integer anArgIter = 1;
5441 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5442 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5443 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5444 {
7c3ef2f7 5445 ++anArgIter;
5446 }
59f45b7c 5447
7c3ef2f7 5448 {
55c8f0f7
BB
5449 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5450 if (aFirstArg.IsIntegerValue())
c5751993 5451 {
7c3ef2f7 5452 ++anArgIter;
55c8f0f7 5453 aLayerId = aFirstArg.IntegerValue();
c5751993 5454 }
7c3ef2f7 5455 else
c5751993 5456 {
55c8f0f7 5457 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5458 {
55c8f0f7 5459 ++anArgIter;
7c3ef2f7 5460 }
c5751993 5461 }
7c3ef2f7 5462 }
c5751993 5463
1c728f2d 5464 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
7c3ef2f7 5465 for (; anArgIter < theArgNb; ++anArgIter)
5466 {
5467 // perform operation
5468 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5469 anArg.LowerCase();
5470 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5471 {
7c3ef2f7 5472 //
c5751993 5473 }
7c3ef2f7 5474 else if (anArg == "-add"
5475 || anArg == "add")
c5751993 5476 {
7c3ef2f7 5477 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5478 if (!aViewer->AddZLayer (aLayerId))
5479 {
23fe70ec 5480 Message::SendFail ("Error: can not add a new z layer");
7c3ef2f7 5481 return 0;
5482 }
5483
5484 theDI << aLayerId;
c5751993 5485 }
1c728f2d 5486 else if (anArg == "-insertbefore"
5487 && anArgIter + 1 < theArgNb
5488 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5489 {
5490 ++anArgIter;
5491 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5492 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5493 {
23fe70ec 5494 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5495 return 0;
5496 }
5497
5498 theDI << aLayerId;
5499 }
5500 else if (anArg == "-insertafter"
5501 && anArgIter + 1 < theArgNb
5502 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5503 {
5504 ++anArgIter;
5505 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5506 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5507 {
23fe70ec 5508 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5509 return 0;
5510 }
5511
5512 theDI << aLayerId;
5513 }
7c3ef2f7 5514 else if (anArg == "-del"
5515 || anArg == "-delete"
5516 || anArg == "del")
c5751993 5517 {
7c3ef2f7 5518 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5519 {
5520 if (++anArgIter >= theArgNb)
5521 {
23fe70ec 5522 Message::SendFail ("Syntax error: id of z layer to remove is missing");
7c3ef2f7 5523 return 1;
5524 }
5525
5526 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5527 }
5528
5529 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5530 || aLayerId == Graphic3d_ZLayerId_Default
5531 || aLayerId == Graphic3d_ZLayerId_Top
5532 || aLayerId == Graphic3d_ZLayerId_Topmost
5533 || aLayerId == Graphic3d_ZLayerId_TopOSD
5534 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5535 {
23fe70ec 5536 Message::SendFail ("Syntax error: standard Z layer can not be removed");
7c3ef2f7 5537 return 1;
5538 }
5539
5540 // move all object displayed in removing layer to default layer
5541 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5542 anObjIter.More(); anObjIter.Next())
5543 {
8f521168 5544 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5545 if (aPrs.IsNull()
5546 || aPrs->ZLayer() != aLayerId)
5547 {
5548 continue;
5549 }
5550 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5551 }
5552
5553 if (!aViewer->RemoveZLayer (aLayerId))
5554 {
23fe70ec 5555 Message::SendFail ("Z layer can not be removed");
7c3ef2f7 5556 }
5557 else
5558 {
5559 theDI << aLayerId << " ";
5560 }
c5751993 5561 }
7c3ef2f7 5562 else if (anArg == "-get"
5563 || anArg == "get")
c5751993 5564 {
7c3ef2f7 5565 TColStd_SequenceOfInteger aLayers;
5566 aViewer->GetAllZLayers (aLayers);
5567 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5568 {
5569 theDI << aLayeriter.Value() << " ";
5570 }
5571
5572 theDI << "\n";
c5751993 5573 }
7c3ef2f7 5574 else if (anArg == "-name")
c5751993 5575 {
7c3ef2f7 5576 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5577 {
23fe70ec 5578 Message::SendFail ("Syntax error: id of Z layer is missing");
c5751993 5579 return 1;
5580 }
5581
7c3ef2f7 5582 if (++anArgIter >= theArgNb)
5583 {
23fe70ec 5584 Message::SendFail ("Syntax error: name is missing");
7c3ef2f7 5585 return 1;
5586 }
c5751993 5587
7c3ef2f7 5588 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5589 aSettings.SetName (theArgVec[anArgIter]);
5590 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5591 }
7c3ef2f7 5592 else if (anArg == "-origin")
c5751993 5593 {
7c3ef2f7 5594 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5595 {
23fe70ec 5596 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5597 return 1;
5598 }
5599
5600 if (anArgIter + 2 >= theArgNb)
5601 {
23fe70ec 5602 Message::SendFail ("Syntax error: origin coordinates are missing");
7c3ef2f7 5603 return 1;
5604 }
5605
5606 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5607 gp_XYZ anOrigin;
5608 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5609 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5610 anOrigin.SetZ (0.0);
5611 if (anArgIter + 3 < theArgNb)
5612 {
5613 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5614 anArgIter += 3;
5615 }
5616 else
5617 {
5618 anArgIter += 2;
5619 }
5620 aSettings.SetOrigin (anOrigin);
5621 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5622 }
4ecf34cc 5623 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5624 && anArgIter + 1 < theArgNb
5625 && (anArg == "-cullingdistance"
5626 || anArg == "-cullingdist"
5627 || anArg == "-culldistance"
5628 || anArg == "-culldist"
5629 || anArg == "-distcull"
5630 || anArg == "-distculling"
5631 || anArg == "-distanceculling"))
5632 {
5633 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5634 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5635 aSettings.SetCullingDistance (aDist);
5636 aViewer->SetZLayerSettings (aLayerId, aSettings);
5637 }
5638 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5639 && anArgIter + 1 < theArgNb
5640 && (anArg == "-cullingsize"
5641 || anArg == "-cullsize"
5642 || anArg == "-sizecull"
5643 || anArg == "-sizeculling"))
5644 {
5645 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5646 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5647 aSettings.SetCullingSize (aSize);
5648 aViewer->SetZLayerSettings (aLayerId, aSettings);
5649 }
7c3ef2f7 5650 else if (anArg == "-settings"
5651 || anArg == "settings")
c5751993 5652 {
7c3ef2f7 5653 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5654 {
5655 if (++anArgIter >= theArgNb)
5656 {
23fe70ec 5657 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5658 return 1;
5659 }
5660
5661 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5662 }
5663
5664 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5665 printZLayerInfo (theDI, aSettings);
c5751993 5666 }
7c3ef2f7 5667 else if (anArg == "-enable"
5668 || anArg == "enable"
5669 || anArg == "-disable"
5670 || anArg == "disable")
83da37b1 5671 {
7c3ef2f7 5672 const Standard_Boolean toEnable = anArg == "-enable"
5673 || anArg == "enable";
5674 if (++anArgIter >= theArgNb)
5675 {
23fe70ec 5676 Message::SendFail ("Syntax error: option name is missing");
7c3ef2f7 5677 return 1;
5678 }
c5751993 5679
7c3ef2f7 5680 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5681 aSubOp.LowerCase();
5682 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5683 {
5684 if (++anArgIter >= theArgNb)
5685 {
23fe70ec 5686 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5687 return 1;
5688 }
c5751993 5689
7c3ef2f7 5690 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5691 }
c5751993 5692
7c3ef2f7 5693 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5694 if (aSubOp == "depthtest"
5695 || aSubOp == "test")
5696 {
5697 aSettings.SetEnableDepthTest (toEnable);
5698 }
5699 else if (aSubOp == "depthwrite"
5700 || aSubOp == "write")
5701 {
5702 aSettings.SetEnableDepthWrite (toEnable);
5703 }
5704 else if (aSubOp == "depthclear"
5705 || aSubOp == "clear")
5706 {
5707 aSettings.SetClearDepth (toEnable);
5708 }
5709 else if (aSubOp == "depthoffset"
5710 || aSubOp == "offset")
5711 {
5712 Graphic3d_PolygonOffset aParams;
5713 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5714 if (toEnable)
5715 {
5716 if (anArgIter + 2 >= theArgNb)
5717 {
23fe70ec 5718 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
7c3ef2f7 5719 return 1;
5720 }
c5751993 5721
7c3ef2f7 5722 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5723 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5724 }
5725 aSettings.SetPolygonOffset (aParams);
5726 }
5727 else if (aSubOp == "positiveoffset"
5728 || aSubOp == "poffset")
5729 {
5730 if (toEnable)
5731 {
5732 aSettings.SetDepthOffsetPositive();
5733 }
5734 else
5735 {
5736 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5737 }
5738 }
5739 else if (aSubOp == "negativeoffset"
5740 || aSubOp == "noffset")
5741 {
5742 if (toEnable)
5743 {
5744 aSettings.SetDepthOffsetNegative();
5745 }
5746 else
5747 {
5748 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5749 }
5750 }
5751 else if (aSubOp == "textureenv")
5752 {
5753 aSettings.SetEnvironmentTexture (toEnable);
5754 }
1c728f2d 5755 else if (aSubOp == "raytracing")
5756 {
5757 aSettings.SetRaytracable (toEnable);
5758 }
7c3ef2f7 5759
5760 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5761 }
7c3ef2f7 5762 else
83da37b1 5763 {
23fe70ec 5764 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
7c3ef2f7 5765 return 1;
83da37b1 5766 }
59f45b7c 5767 }
5768
5769 return 0;
5770}
5771
c357e426 5772// The interactive presentation of 2d layer item
5773// for "vlayerline" command it provides a presentation of
5774// line with user-defined linewidth, linetype and transparency.
61b0191c 5775class V3d_LineItem : public AIS_InteractiveObject
20637bd2 5776{
5777public:
5778 // CASCADE RTTI
92efcf78 5779 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 5780
20637bd2 5781 // constructor
5782 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5783 Standard_Real X2, Standard_Real Y2,
20637bd2 5784 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5785 Standard_Real theWidth = 0.5,
5786 Standard_Real theTransp = 1.0);
5787
decbff0d 5788private:
61b0191c 5789
decbff0d 5790 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5791 const Handle(Prs3d_Presentation)& thePrs,
5792 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 5793
decbff0d 5794 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5795 const Standard_Integer ) Standard_OVERRIDE
79104795 5796 {}
20637bd2 5797
5798private:
5799
5800 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 5801 Aspect_TypeOfLine myType;
20637bd2 5802 Standard_Real myWidth;
20637bd2 5803};
5804
20637bd2 5805// default constructor for line item
4fe56619 5806V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 5807 Standard_Real X2, Standard_Real Y2,
20637bd2 5808 Aspect_TypeOfLine theType,
5809 Standard_Real theWidth,
5810 Standard_Real theTransp) :
61b0191c 5811 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5812 myType(theType), myWidth(theWidth)
20637bd2 5813{
61b0191c 5814 SetTransparency (1-theTransp);
20637bd2 5815}
5816
5817// render line
decbff0d 5818void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
61b0191c 5819 const Handle(Prs3d_Presentation)& thePresentation,
decbff0d 5820 const Standard_Integer )
20637bd2 5821{
61b0191c 5822 thePresentation->Clear();
ba00aab7 5823 Quantity_Color aColor (Quantity_NOC_RED);
61b0191c 5824 Standard_Integer aWidth, aHeight;
5825 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
d6c48921 5826 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
61b0191c 5827 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5828 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5829 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5830 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5831 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5832 aGroup->AddPrimitiveArray (aPrim);
20637bd2 5833}
5834
5835//=============================================================================
5836//function : VLayerLine
5837//purpose : Draws line in the v3d view layer with given attributes: linetype,
5838// : linewidth, transparency coefficient
5839//============================================================================
5840static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5841{
5842 // get the active view
5843 Handle(V3d_View) aView = ViewerTest::CurrentView();
5844 if (aView.IsNull())
5845 {
5846 di << "Call vinit before!\n";
5847 return 1;
5848 }
5849 else if (argc < 5)
5850 {
5851 di << "Use: " << argv[0];
5852 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5853 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5854 di << " 0 - solid \n";
5855 di << " 1 - dashed \n";
5856 di << " 2 - dot \n";
5857 di << " 3 - dashdot\n";
5858 di << " transparency : { 0.0 - 1.0 } \n";
5859 di << " 0.0 - transparent\n";
5860 di << " 1.0 - visible \n";
5861 return 1;
5862 }
5863
61b0191c 5864 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 5865 // get the input params
91322f44 5866 Standard_Real X1 = Draw::Atof(argv[1]);
5867 Standard_Real Y1 = Draw::Atof(argv[2]);
5868 Standard_Real X2 = Draw::Atof(argv[3]);
5869 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 5870
3a4a3962 5871 Standard_Real aWidth = 0.5;
5872 Standard_Real aTransparency = 1.0;
20637bd2 5873
5874 // has width
5875 if (argc > 5)
91322f44 5876 aWidth = Draw::Atof(argv[5]);
20637bd2 5877
3a4a3962 5878 // select appropriate line type
5879 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5880 if (argc > 6
5881 && !ViewerTest::ParseLineType (argv[6], aLineType))
5882 {
23fe70ec 5883 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
3a4a3962 5884 return 1;
5885 }
20637bd2 5886
5887 // has transparency
5888 if (argc > 7)
5889 {
91322f44 5890 aTransparency = Draw::Atof(argv[7]);
4fe56619 5891 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 5892 aTransparency = 1.0;
5893 }
5894
61b0191c 5895 static Handle (V3d_LineItem) aLine;
5896 if (!aLine.IsNull())
25289ec1 5897 {
0577ae8c 5898 aContext->Erase (aLine, Standard_False);
25289ec1 5899 }
61b0191c 5900 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5901 aLineType, aWidth,
5902 aTransparency);
25289ec1 5903
778cd667 5904 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 5905 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5906 aLine->SetToUpdate();
5907 aContext->Display (aLine, Standard_True);
25289ec1 5908
5909 return 0;
5910}
5911
61b0191c 5912
2bd4c032 5913//==============================================================================
5914//function : VGrid
5915//purpose :
5916//==============================================================================
5917
35e08fe8 5918static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 5919 Standard_Integer theArgNb,
5920 const char** theArgVec)
5921{
2bd4c032 5922 Handle(V3d_View) aView = ViewerTest::CurrentView();
5923 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5924 if (aView.IsNull() || aViewer.IsNull())
5925 {
23fe70ec 5926 Message::SendFail ("Error: no active viewer");
2bd4c032 5927 return 1;
5928 }
5929
5930 Aspect_GridType aType = aViewer->GridType();
5931 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 5932 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5933 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5934 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 5935 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 5936 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 5937 {
79931835 5938 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5939 anArg.LowerCase();
5940 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 5941 {
5942 continue;
5943 }
79931835 5944 else if (anArgIter + 1 < theArgNb
5945 && anArg == "-type")
5946 {
5947 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5948 anArgNext.LowerCase();
5949 if (anArgNext == "r"
5950 || anArgNext == "rect"
5951 || anArgNext == "rectangular")
5952 {
5953 aType = Aspect_GT_Rectangular;
5954 }
5955 else if (anArgNext == "c"
5956 || anArgNext == "circ"
5957 || anArgNext == "circular")
5958 {
5959 aType = Aspect_GT_Circular;
5960 }
5961 else
5962 {
23fe70ec 5963 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5964 return 1;
5965 }
5966 }
5967 else if (anArgIter + 1 < theArgNb
5968 && anArg == "-mode")
5969 {
5970 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5971 anArgNext.LowerCase();
5972 if (anArgNext == "l"
5973 || anArgNext == "line"
5974 || anArgNext == "lines")
5975 {
5976 aMode = Aspect_GDM_Lines;
5977 }
5978 else if (anArgNext == "p"
5979 || anArgNext == "point"
5980 || anArgNext == "points")
5981 {
5982 aMode = Aspect_GDM_Points;
5983 }
5984 else
5985 {
23fe70ec 5986 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5987 return 1;
5988 }
5989 }
5990 else if (anArgIter + 2 < theArgNb
5991 && (anArg == "-origin"
5992 || anArg == "-orig"))
5993 {
5994 hasOrigin = true;
5995 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5996 Draw::Atof (theArgVec[anArgIter + 2]));
5997 anArgIter += 2;
5998 }
5999 else if (anArgIter + 2 < theArgNb
6000 && anArg == "-step")
6001 {
6002 hasStep = true;
6003 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6004 Draw::Atof (theArgVec[anArgIter + 2]));
6005 if (aNewStepXY.x() <= 0.0
6006 || aNewStepXY.y() <= 0.0)
6007 {
23fe70ec 6008 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 6009 return 1;
6010 }
6011 anArgIter += 2;
6012 }
6013 else if (anArgIter + 1 < theArgNb
6014 && (anArg == "-angle"
6015 || anArg == "-rotangle"
6016 || anArg == "-rotationangle"))
6017 {
6018 hasRotAngle = true;
6019 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
6020 }
6021 else if (anArgIter + 1 < theArgNb
6022 && (anArg == "-zoffset"
6023 || anArg == "-dz"))
6024 {
6025 hasZOffset = true;
6026 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
6027 }
6028 else if (anArgIter + 1 < theArgNb
6029 && anArg == "-radius")
6030 {
6031 hasSize = true;
6032 ++anArgIter;
6033 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
6034 if (aNewStepXY.x() <= 0.0)
6035 {
23fe70ec 6036 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
79931835 6037 return 1;
6038 }
6039 }
6040 else if (anArgIter + 2 < theArgNb
6041 && anArg == "-size")
6042 {
6043 hasSize = true;
6044 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6045 Draw::Atof (theArgVec[anArgIter + 2]));
6046 if (aNewStepXY.x() <= 0.0
6047 || aNewStepXY.y() <= 0.0)
6048 {
23fe70ec 6049 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 6050 return 1;
6051 }
6052 anArgIter += 2;
6053 }
6054 else if (anArg == "r"
6055 || anArg == "rect"
6056 || anArg == "rectangular")
2bd4c032 6057 {
6058 aType = Aspect_GT_Rectangular;
6059 }
79931835 6060 else if (anArg == "c"
6061 || anArg == "circ"
6062 || anArg == "circular")
2bd4c032 6063 {
6064 aType = Aspect_GT_Circular;
6065 }
79931835 6066 else if (anArg == "l"
6067 || anArg == "line"
6068 || anArg == "lines")
2bd4c032 6069 {
6070 aMode = Aspect_GDM_Lines;
6071 }
79931835 6072 else if (anArg == "p"
6073 || anArg == "point"
6074 || anArg == "points")
2bd4c032 6075 {
6076 aMode = Aspect_GDM_Points;
6077 }
79931835 6078 else if (anArgIter + 1 >= theArgNb
6079 && anArg == "off")
2bd4c032 6080 {
6081 aViewer->DeactivateGrid();
6082 return 0;
6083 }
6084 else
6085 {
23fe70ec 6086 Message::SendFail() << "Syntax error at '" << anArg << "'";
79931835 6087 return 1;
2bd4c032 6088 }
6089 }
6090
2bd4c032 6091 if (aType == Aspect_GT_Rectangular)
6092 {
79931835 6093 Graphic3d_Vec2d anOrigXY, aStepXY;
6094 Standard_Real aRotAngle = 0.0;
6095 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6096 if (hasOrigin)
6097 {
6098 anOrigXY = aNewOriginXY;
6099 }
6100 if (hasStep)
6101 {
6102 aStepXY = aNewStepXY;
6103 }
6104 if (hasRotAngle)
6105 {
6106 aRotAngle = aNewRotAngle;
6107 }
6108 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6109 if (hasSize || hasZOffset)
2bd4c032 6110 {
79931835 6111 Graphic3d_Vec3d aSize;
6112 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6113 if (hasSize)
6114 {
6115 aSize.x() = aNewSizeXY.x();
6116 aSize.y() = aNewSizeXY.y();
6117 }
6118 if (hasZOffset)
6119 {
6120 aSize.z() = aNewZOffset;
6121 }
6122 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 6123 }
2bd4c032 6124 }
6125 else if (aType == Aspect_GT_Circular)
6126 {
79931835 6127 Graphic3d_Vec2d anOrigXY;
ee2be2a8 6128 Standard_Real aRadiusStep;
2bd4c032 6129 Standard_Integer aDivisionNumber;
79931835 6130 Standard_Real aRotAngle = 0.0;
6131 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6132 if (hasOrigin)
6133 {
6134 anOrigXY = aNewOriginXY;
6135 }
6136 if (hasStep)
6137 {
6138 aRadiusStep = aNewStepXY[0];
6139 aDivisionNumber = (int )aNewStepXY[1];
6140 if (aDivisionNumber < 1)
6141 {
23fe70ec 6142 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
79931835 6143 return 1;
6144 }
6145 }
6146 if (hasRotAngle)
2bd4c032 6147 {
79931835 6148 aRotAngle = aNewRotAngle;
2bd4c032 6149 }
6150
79931835 6151 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6152 if (hasSize || hasZOffset)
6153 {
6154 Standard_Real aRadius = 0.0, aZOffset = 0.0;
6155 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
6156 if (hasSize)
6157 {
6158 aRadius = aNewSizeXY.x();
6159 if (aNewSizeXY.y() != 0.0)
6160 {
23fe70ec 6161 Message::SendFail ("Syntax error: circular size should be specified as radius");
79931835 6162 return 1;
6163 }
6164 }
6165 if (hasZOffset)
6166 {
6167 aZOffset = aNewZOffset;
6168 }
6169 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6170 }
2bd4c032 6171 }
79931835 6172 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6173 return 0;
6174}
6175
c40b7d58 6176//==============================================================================
6177//function : VPriviledgedPlane
6178//purpose :
6179//==============================================================================
6180
6181static int VPriviledgedPlane (Draw_Interpretor& theDI,
6182 Standard_Integer theArgNb,
6183 const char** theArgVec)
6184{
6185 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6186 {
23fe70ec 6187 Message::SendFail ("Error: wrong number of arguments! See usage:");
c40b7d58 6188 theDI.PrintHelp (theArgVec[0]);
6189 return 1;
6190 }
6191
6192 // get the active viewer
6193 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6194 if (aViewer.IsNull())
6195 {
23fe70ec 6196 Message::SendFail ("Error: no active viewer");
c40b7d58 6197 return 1;
6198 }
6199
6200 if (theArgNb == 1)
6201 {
6202 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6203 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6204 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6205 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6206 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6207 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6208 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6209 return 0;
6210 }
6211
6212 Standard_Integer anArgIdx = 1;
6213 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6214 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6215 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6216 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6217 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6218 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6219
6220 gp_Ax3 aPriviledgedPlane;
6221 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6222 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6223 if (theArgNb > 7)
6224 {
6225 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6226 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6227 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6228 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6229 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6230 }
6231 else
6232 {
6233 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6234 }
6235
6236 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6237
6238 return 0;
6239}
6240
f25b82d6 6241//==============================================================================
6242//function : VConvert
6243//purpose :
6244//==============================================================================
6245
6246static int VConvert (Draw_Interpretor& theDI,
6247 Standard_Integer theArgNb,
6248 const char** theArgVec)
6249{
6250 // get the active view
6251 Handle(V3d_View) aView = ViewerTest::CurrentView();
6252 if (aView.IsNull())
6253 {
23fe70ec 6254 Message::SendFail ("Error: no active viewer");
f25b82d6 6255 return 1;
6256 }
6257
6258 enum { Model, Ray, View, Window, Grid } aMode = Model;
6259
6260 // access coordinate arguments
6261 TColStd_SequenceOfReal aCoord;
6262 Standard_Integer anArgIdx = 1;
6263 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6264 {
6265 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
d45edf24 6266 if (!anArg.IsRealValue (Standard_True))
f25b82d6 6267 {
6268 break;
6269 }
6270 aCoord.Append (anArg.RealValue());
6271 }
6272
6273 // non-numeric argument too early
6274 if (aCoord.IsEmpty())
6275 {
23fe70ec 6276 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6277 theDI.PrintHelp (theArgVec[0]);
6278 return 1;
6279 }
6280
6281 // collect all other arguments and options
6282 for (; anArgIdx < theArgNb; ++anArgIdx)
6283 {
6284 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6285 anArg.LowerCase();
6286 if (anArg == "window") aMode = Window;
6287 else if (anArg == "view") aMode = View;
6288 else if (anArg == "grid") aMode = Grid;
6289 else if (anArg == "ray") aMode = Ray;
6290 else
6291 {
23fe70ec 6292 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
f25b82d6 6293 theDI.PrintHelp (theArgVec[0]);
6294 return 1;
6295 }
6296 }
6297
6298 // complete input checks
6299 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6300 (aCoord.Length() == 2 && theArgNb > 4) ||
6301 (aCoord.Length() == 3 && theArgNb > 5))
6302 {
23fe70ec 6303 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6304 theDI.PrintHelp (theArgVec[0]);
6305 return 1;
6306 }
6307
6308 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6309 Standard_Integer aXYp[2] = {0, 0};
6310
6311 // convert one-dimensional coordinate
6312 if (aCoord.Length() == 1)
6313 {
6314 switch (aMode)
6315 {
ee2be2a8 6316 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6317 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6318 default:
23fe70ec 6319 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6320 theDI.PrintHelp (theArgVec[0]);
6321 return 1;
6322 }
6323 }
6324
6325 // convert 2D coordinates from projection or view reference space
6326 if (aCoord.Length() == 2)
6327 {
6328 switch (aMode)
6329 {
6330 case Model :
6331 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6332 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6333 return 0;
6334
6335 case View :
6336 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6337 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6338 return 0;
6339
6340 case Window :
ee2be2a8 6341 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6342 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6343 return 0;
6344
6345 case Grid :
6346 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6347 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6348 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6349 return 0;
6350
6351 case Ray :
6352 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6353 (Standard_Integer) aCoord (2),
6354 aXYZ[0], aXYZ[1], aXYZ[2],
6355 aXYZ[3], aXYZ[4], aXYZ[5]);
6356 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6357 return 0;
6358
6359 default:
23fe70ec 6360 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6361 theDI.PrintHelp (theArgVec[0]);
6362 return 1;
6363 }
6364 }
6365
6366 // convert 3D coordinates from view reference space
6367 else if (aCoord.Length() == 3)
6368 {
6369 switch (aMode)
6370 {
6371 case Window :
6372 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6373 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6374 return 0;
6375
6376 case Grid :
6377 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6378 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6379 return 0;
6380
6381 default:
23fe70ec 6382 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6383 theDI.PrintHelp (theArgVec[0]);
6384 return 1;
6385 }
6386 }
6387
6388 return 0;
6389}
6390
208e6839 6391//==============================================================================
6392//function : VFps
6393//purpose :
6394//==============================================================================
6395
6396static int VFps (Draw_Interpretor& theDI,
6397 Standard_Integer theArgNb,
6398 const char** theArgVec)
6399{
6400 // get the active view
6401 Handle(V3d_View) aView = ViewerTest::CurrentView();
6402 if (aView.IsNull())
6403 {
23fe70ec 6404 Message::SendFail ("Error: no active viewer");
208e6839 6405 return 1;
6406 }
6407
e084dbbc 6408 Standard_Integer aFramesNb = -1;
6409 Standard_Real aDuration = -1.0;
6410 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6411 {
e084dbbc 6412 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6413 anArg.LowerCase();
6414 if (aDuration < 0.0
6415 && anArgIter + 1 < theArgNb
6416 && (anArg == "-duration"
6417 || anArg == "-dur"
6418 || anArg == "-time"))
6419 {
6420 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6421 }
6422 else if (aFramesNb < 0
6423 && anArg.IsIntegerValue())
6424 {
6425 aFramesNb = anArg.IntegerValue();
6426 if (aFramesNb <= 0)
6427 {
23fe70ec 6428 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6429 return 1;
6430 }
6431 }
6432 else
6433 {
23fe70ec 6434 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6435 return 1;
6436 }
6437 }
6438 if (aFramesNb < 0 && aDuration < 0.0)
6439 {
6440 aFramesNb = 100;
208e6839 6441 }
6442
6443 // the time is meaningless for first call
6444 // due to async OpenGl rendering
6445 aView->Redraw();
6446
6447 // redraw view in loop to estimate average values
6448 OSD_Timer aTimer;
6449 aTimer.Start();
e084dbbc 6450 Standard_Integer aFrameIter = 1;
6451 for (;; ++aFrameIter)
208e6839 6452 {
6453 aView->Redraw();
e084dbbc 6454 if ((aFramesNb > 0
6455 && aFrameIter >= aFramesNb)
6456 || (aDuration > 0.0
6457 && aTimer.ElapsedTime() >= aDuration))
6458 {
6459 break;
6460 }
208e6839 6461 }
6462 aTimer.Stop();
6463 Standard_Real aCpu;
6464 const Standard_Real aTime = aTimer.ElapsedTime();
6465 aTimer.OSD_Chronometer::Show (aCpu);
6466
e084dbbc 6467 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6468 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6469
6470 // return statistics
6471 theDI << "FPS: " << aFpsAver << "\n"
6472 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6473
8c820969 6474 // compute additional statistics in ray-tracing mode
e084dbbc 6475 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6476 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6477 {
e084dbbc 6478 Graphic3d_Vec2i aWinSize (0, 0);
6479 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6480
6481 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6482 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6483 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6484 }
6485
208e6839 6486 return 0;
6487}
6488
84e84755 6489//! Auxiliary function for parsing glsl dump level argument.
6490static Standard_Boolean parseGlslSourceFlag (Standard_CString theArg,
6491 OpenGl_ShaderProgramDumpLevel& theGlslDumpLevel)
6492{
6493 TCollection_AsciiString aTypeStr (theArg);
6494 aTypeStr.LowerCase();
6495 if (aTypeStr == "off"
6496 || aTypeStr == "0")
6497 {
6498 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6499 }
6500 else if (aTypeStr == "short")
6501 {
6502 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Short;
6503 }
6504 else if (aTypeStr == "full"
6505 || aTypeStr == "1")
6506 {
6507 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6508 }
6509 else
6510 {
6511 return Standard_False;
6512 }
6513 return Standard_True;
6514}
6515
58655684 6516//==============================================================================
6517//function : VGlDebug
6518//purpose :
6519//==============================================================================
6520
6521static int VGlDebug (Draw_Interpretor& theDI,
6522 Standard_Integer theArgNb,
6523 const char** theArgVec)
6524{
aaf512f1 6525 Handle(OpenGl_GraphicDriver) aDriver;
6526 Handle(V3d_View) aView = ViewerTest::CurrentView();
6527 if (!aView.IsNull())
6528 {
6529 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
6530 }
c87535af 6531 OpenGl_Caps* aDefCaps = &ViewerTest_myDefaultCaps;
6532 OpenGl_Caps* aCaps = !aDriver.IsNull() ? &aDriver->ChangeOptions() : NULL;
6533
58655684 6534 if (theArgNb < 2)
6535 {
c87535af 6536 TCollection_AsciiString aDebActive, aSyncActive;
6537 if (aCaps == NULL)
58655684 6538 {
c87535af 6539 aCaps = aDefCaps;
6540 }
6541 else
6542 {
6543 Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )::glGetString (GL_EXTENSIONS),
6544 "GL_ARB_debug_output");
6545 aDebActive = isActive ? " (active)" : " (inactive)";
6546 if (isActive)
6547 {
6548 // GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
6549 aSyncActive = ::glIsEnabled (0x8242) == GL_TRUE ? " (active)" : " (inactive)";
6550 }
58655684 6551 }
6552
84e84755 6553 TCollection_AsciiString aGlslCodeDebugStatus = TCollection_AsciiString()
6554 + "glslSourceCode: "
6555 + (aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Off
6556 ? "Off"
6557 : aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short
6558 ? "Short"
6559 : "Full")
6560 + "\n";
6561 theDI << "debug: " << (aCaps->contextDebug ? "1" : "0") << aDebActive << "\n"
6562 << "sync: " << (aCaps->contextSyncDebug ? "1" : "0") << aSyncActive << "\n"
6563 << "glslWarn: " << (aCaps->glslWarnings ? "1" : "0") << "\n"
6564 << aGlslCodeDebugStatus
6565 << "extraMsg: " << (aCaps->suppressExtraMsg ? "0" : "1") << "\n";
58655684 6566 return 0;
6567 }
6568
c87535af 6569 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
aaf512f1 6570 {
c87535af 6571 Standard_CString anArg = theArgVec[anArgIter];
6572 TCollection_AsciiString anArgCase (anArg);
6573 anArgCase.LowerCase();
6574 Standard_Boolean toEnableDebug = Standard_True;
6575 if (anArgCase == "-glsl"
6576 || anArgCase == "-glslwarn"
6577 || anArgCase == "-glslwarns"
6578 || anArgCase == "-glslwarnings")
6579 {
6580 Standard_Boolean toShowWarns = Standard_True;
6581 if (++anArgIter < theArgNb
dae2a922 6582 && !Draw::ParseOnOff (theArgVec[anArgIter], toShowWarns))
c87535af 6583 {
6584 --anArgIter;
6585 }
6586 aDefCaps->glslWarnings = toShowWarns;
6587 if (aCaps != NULL)
6588 {
6589 aCaps->glslWarnings = toShowWarns;
6590 }
6591 }
6592 else if (anArgCase == "-extra"
6593 || anArgCase == "-extramsg"
6594 || anArgCase == "-extramessages")
6595 {
6596 Standard_Boolean toShow = Standard_True;
6597 if (++anArgIter < theArgNb
dae2a922 6598 && !Draw::ParseOnOff (theArgVec[anArgIter], toShow))
c87535af 6599 {
6600 --anArgIter;
6601 }
6602 aDefCaps->suppressExtraMsg = !toShow;
6603 if (aCaps != NULL)
6604 {
6605 aCaps->suppressExtraMsg = !toShow;
6606 }
6607 }
6608 else if (anArgCase == "-noextra"
6609 || anArgCase == "-noextramsg"
6610 || anArgCase == "-noextramessages")
6611 {
6612 Standard_Boolean toSuppress = Standard_True;
6613 if (++anArgIter < theArgNb
dae2a922 6614 && !Draw::ParseOnOff (theArgVec[anArgIter], toSuppress))
c87535af 6615 {
6616 --anArgIter;
6617 }
6618 aDefCaps->suppressExtraMsg = toSuppress;
6619 if (aCaps != NULL)
6620 {
6621 aCaps->suppressExtraMsg = toSuppress;
6622 }
6623 }
6624 else if (anArgCase == "-sync")
6625 {
6626 Standard_Boolean toSync = Standard_True;
6627 if (++anArgIter < theArgNb
dae2a922 6628 && !Draw::ParseOnOff (theArgVec[anArgIter], toSync))
c87535af 6629 {
6630 --anArgIter;
6631 }
6632 aDefCaps->contextSyncDebug = toSync;
6633 if (toSync)
6634 {
6635 aDefCaps->contextDebug = Standard_True;
6636 }
6637 }
84e84755 6638 else if (anArgCase == "-glslsourcecode"
6639 || anArgCase == "-glslcode")
6640 {
6641 OpenGl_ShaderProgramDumpLevel aGslsDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6642 if (++anArgIter < theArgNb
6643 && !parseGlslSourceFlag (theArgVec[anArgIter], aGslsDumpLevel))
6644 {
6645 --anArgIter;
6646 }
6647 aDefCaps->glslDumpLevel = aGslsDumpLevel;
6648 if (aCaps != NULL)
6649 {
6650 aCaps->glslDumpLevel = aGslsDumpLevel;
6651 }
6652 }
c87535af 6653 else if (anArgCase == "-debug")
6654 {
6655 if (++anArgIter < theArgNb
dae2a922 6656 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnableDebug))
c87535af 6657 {
6658 --anArgIter;
6659 }
6660 aDefCaps->contextDebug = toEnableDebug;
6661 }
dae2a922 6662 else if (Draw::ParseOnOff (anArg, toEnableDebug)
c87535af 6663 && (anArgIter + 1 == theArgNb))
6664 {
6665 // simple alias to turn on almost everything
6666 aDefCaps->contextDebug = toEnableDebug;
6667 aDefCaps->contextSyncDebug = toEnableDebug;
6668 aDefCaps->glslWarnings = toEnableDebug;
3b4c6945 6669 if (!toEnableDebug)
6670 {
6671 aDefCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6672 }
84e84755 6673 aDefCaps->suppressExtraMsg = !toEnableDebug;
6674 if (aCaps != NULL)
6675 {
6676 aCaps->contextDebug = toEnableDebug;
6677 aCaps->contextSyncDebug = toEnableDebug;
6678 aCaps->glslWarnings = toEnableDebug;
3b4c6945 6679 if (!toEnableDebug)
6680 {
6681 aCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6682 }
84e84755 6683 aCaps->suppressExtraMsg = !toEnableDebug;
6684 }
c87535af 6685 }
6686 else
6687 {
23fe70ec 6688 Message::SendFail() << "Syntax error at '" << anArg << "'";
c87535af 6689 return 1;
6690 }
aaf512f1 6691 }
6692
58655684 6693 return 0;
6694}
208e6839 6695
6696//==============================================================================
6697//function : VVbo
6698//purpose :
6699//==============================================================================
6700
58655684 6701static int VVbo (Draw_Interpretor& theDI,
208e6839 6702 Standard_Integer theArgNb,
6703 const char** theArgVec)
6704{
58655684 6705 const Standard_Boolean toSet = (theArgNb > 1);
6706 const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
6707 if (toSet)
208e6839 6708 {
58655684 6709 ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
208e6839 6710 }
6711
58655684 6712 // get the context
6713 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6714 if (aContextAIS.IsNull())
208e6839 6715 {
58655684 6716 if (!toSet)
6717 {
23fe70ec 6718 Message::SendFail ("Error: no active viewer");
58655684 6719 }
208e6839 6720 return 1;
6721 }
58655684 6722 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
6723 if (!aDriver.IsNull())
208e6839 6724 {
58655684 6725 if (!toSet)
6726 {
6727 theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
6728 }
6729 else
6730 {
6731 aDriver->ChangeOptions().vboDisable = toUseVbo;
6732 }
208e6839 6733 }
6734
208e6839 6735 return 0;
6736}
6737
a577aaab 6738//==============================================================================
6739//function : VCaps
6740//purpose :
6741//==============================================================================
6742
6743static int VCaps (Draw_Interpretor& theDI,
6744 Standard_Integer theArgNb,
6745 const char** theArgVec)
6746{
6747 OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
6748 Handle(OpenGl_GraphicDriver) aDriver;
8625ef7e 6749 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6750 if (!aContext.IsNull())
a577aaab 6751 {
8625ef7e 6752 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
a577aaab 6753 aCaps = &aDriver->ChangeOptions();
6754 }
6755
6756 if (theArgNb < 2)
6757 {
ba00aab7 6758 theDI << "sRGB: " << (aCaps->sRGBDisable ? "0" : "1") << "\n";
a577aaab 6759 theDI << "VBO: " << (aCaps->vboDisable ? "0" : "1") << "\n";
6760 theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
abe46077 6761 theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
8625ef7e 6762 theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
2a332745 6763 theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
f978241f 6764 theDI << "VSync: " << aCaps->swapInterval << "\n";
4e1523ef 6765 theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
f978241f 6766 theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
56689b27 6767 theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n";
31174e1a 6768 theDI << "OpaqueAlpha: " << (aCaps->buffersOpaqueAlpha ? "1" : "0") << "\n";
59515ca6 6769 theDI << "NoExt:" << (aCaps->contextNoExtensions ? "1" : "0") << "\n";
6770 theDI << "MaxVersion:" << aCaps->contextMajorVersionUpper << "." << aCaps->contextMinorVersionUpper << "\n";
faff3767 6771 theDI << "CompressTextures: " << (aCaps->compressedTexturesDisable ? "0" : "1") << "\n";
a577aaab 6772 return 0;
6773 }
6774
8625ef7e 6775 ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
a577aaab 6776 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6777 {
8625ef7e 6778 Standard_CString anArg = theArgVec[anArgIter];
6779 TCollection_AsciiString anArgCase (anArg);
6780 anArgCase.LowerCase();
6781 if (anUpdateTool.parseRedrawMode (anArg))
6782 {
6783 continue;
6784 }
f978241f 6785 else if (anArgCase == "-vsync"
6786 || anArgCase == "-swapinterval")
6787 {
6788 Standard_Boolean toEnable = Standard_True;
6789 if (++anArgIter < theArgNb
dae2a922 6790 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 6791 {
6792 --anArgIter;
6793 }
6794 aCaps->swapInterval = toEnable;
6795 }
8625ef7e 6796 else if (anArgCase == "-ffp")
6797 {
6798 Standard_Boolean toEnable = Standard_True;
6799 if (++anArgIter < theArgNb
dae2a922 6800 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6801 {
6802 --anArgIter;
6803 }
6804 aCaps->ffpEnable = toEnable;
6805 }
2a332745 6806 else if (anArgCase == "-polygonmode")
6807 {
6808 Standard_Boolean toEnable = Standard_True;
6809 if (++anArgIter < theArgNb
dae2a922 6810 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
2a332745 6811 {
6812 --anArgIter;
6813 }
6814 aCaps->usePolygonMode = toEnable;
6815 }
ba00aab7 6816 else if (anArgCase == "-srgb")
6817 {
6818 Standard_Boolean toEnable = Standard_True;
6819 if (++anArgIter < theArgNb
dae2a922 6820 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
ba00aab7 6821 {
6822 --anArgIter;
6823 }
6824 aCaps->sRGBDisable = !toEnable;
6825 }
faff3767 6826 else if (anArgCase == "-compressedtextures")
6827 {
6828 Standard_Boolean toEnable = Standard_True;
6829 if (++anArgIter < theArgNb
dae2a922 6830 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
faff3767 6831 {
6832 --anArgIter;
6833 }
6834 aCaps->compressedTexturesDisable = !toEnable;
6835 }
8625ef7e 6836 else if (anArgCase == "-vbo")
a577aaab 6837 {
8625ef7e 6838 Standard_Boolean toEnable = Standard_True;
6839 if (++anArgIter < theArgNb
dae2a922 6840 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6841 {
6842 --anArgIter;
6843 }
6844 aCaps->vboDisable = !toEnable;
a577aaab 6845 }
8625ef7e 6846 else if (anArgCase == "-sprite"
6847 || anArgCase == "-sprites")
a577aaab 6848 {
8625ef7e 6849 Standard_Boolean toEnable = Standard_True;
6850 if (++anArgIter < theArgNb
dae2a922 6851 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6852 {
6853 --anArgIter;
6854 }
6855 aCaps->pntSpritesDisable = !toEnable;
a577aaab 6856 }
8625ef7e 6857 else if (anArgCase == "-softmode")
abe46077 6858 {
8625ef7e 6859 Standard_Boolean toEnable = Standard_True;
6860 if (++anArgIter < theArgNb
dae2a922 6861 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6862 {
6863 --anArgIter;
6864 }
6865 aCaps->contextNoAccel = toEnable;
6866 }
31174e1a 6867 else if (anArgCase == "-opaquealpha"
6868 || anArgCase == "-buffersOpaqueAlpha")
6869 {
6870 Standard_Boolean toEnable = Standard_True;
6871 if (++anArgIter < theArgNb
6872 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
6873 {
6874 --anArgIter;
6875 }
6876 aCaps->buffersOpaqueAlpha = toEnable;
6877 }
56689b27 6878 else if (anArgCase == "-winbuffer"
6879 || anArgCase == "-windowbuffer"
6880 || anArgCase == "-usewinbuffer"
6881 || anArgCase == "-usewindowbuffer"
6882 || anArgCase == "-usesystembuffer")
6883 {
6884 Standard_Boolean toEnable = Standard_True;
6885 if (++anArgIter < theArgNb
dae2a922 6886 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
56689b27 6887 {
6888 --anArgIter;
6889 }
6890 aCaps->useSystemBuffer = toEnable;
6891 }
8625ef7e 6892 else if (anArgCase == "-accel"
6893 || anArgCase == "-acceleration")
6894 {
6895 Standard_Boolean toEnable = Standard_True;
6896 if (++anArgIter < theArgNb
dae2a922 6897 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6898 {
6899 --anArgIter;
6900 }
6901 aCaps->contextNoAccel = !toEnable;
abe46077 6902 }
4e1523ef 6903 else if (anArgCase == "-compat"
6904 || anArgCase == "-compatprofile"
6905 || anArgCase == "-compatible"
6906 || anArgCase == "-compatibleprofile")
6907 {
6908 Standard_Boolean toEnable = Standard_True;
6909 if (++anArgIter < theArgNb
dae2a922 6910 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 6911 {
6912 --anArgIter;
6913 }
6914 aCaps->contextCompatible = toEnable;
6915 if (!aCaps->contextCompatible)
6916 {
6917 aCaps->ffpEnable = Standard_False;
6918 }
6919 }
6920 else if (anArgCase == "-core"
6921 || anArgCase == "-coreprofile")
6922 {
6923 Standard_Boolean toEnable = Standard_True;
6924 if (++anArgIter < theArgNb
dae2a922 6925 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 6926 {
6927 --anArgIter;
6928 }
6929 aCaps->contextCompatible = !toEnable;
6930 if (!aCaps->contextCompatible)
6931 {
6932 aCaps->ffpEnable = Standard_False;
6933 }
6934 }
f978241f 6935 else if (anArgCase == "-stereo"
6936 || anArgCase == "-quadbuffer")
6937 {
6938 Standard_Boolean toEnable = Standard_True;
6939 if (++anArgIter < theArgNb
dae2a922 6940 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 6941 {
6942 --anArgIter;
6943 }
6944 aCaps->contextStereo = toEnable;
6945 }
59515ca6 6946 else if (anArgCase == "-noext"
6947 || anArgCase == "-noextensions"
6948 || anArgCase == "-noextension")
6949 {
6950 Standard_Boolean toDisable = Standard_True;
6951 if (++anArgIter < theArgNb
dae2a922 6952 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
59515ca6 6953 {
6954 --anArgIter;
6955 }
6956 aCaps->contextNoExtensions = toDisable;
6957 }
6958 else if (anArgCase == "-maxversion"
6959 || anArgCase == "-upperversion"
6960 || anArgCase == "-limitversion")
6961 {
6962 Standard_Integer aVer[2] = { -2, -1 };
6963 for (Standard_Integer aValIter = 0; aValIter < 2; ++aValIter)
6964 {
6965 if (anArgIter + 1 < theArgNb)
6966 {
6967 const TCollection_AsciiString aStr (theArgVec[anArgIter + 1]);
6968 if (aStr.IsIntegerValue())
6969 {
6970 aVer[aValIter] = aStr.IntegerValue();
6971 ++anArgIter;
6972 }
6973 }
6974 }
6975 if (aVer[0] < -1
6976 || aVer[1] < -1)
6977 {
23fe70ec 6978 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
59515ca6 6979 return 1;
6980 }
6981 aCaps->contextMajorVersionUpper = aVer[0];
6982 aCaps->contextMinorVersionUpper = aVer[1];
6983 }
a577aaab 6984 else
6985 {
23fe70ec 6986 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
8625ef7e 6987 return 1;
a577aaab 6988 }
6989 }
6990 if (aCaps != &ViewerTest_myDefaultCaps)
6991 {
6992 ViewerTest_myDefaultCaps = *aCaps;
6993 }
6994 return 0;
6995}
6996
f0430952 6997//==============================================================================
6998//function : VMemGpu
6999//purpose :
7000//==============================================================================
7001
7002static int VMemGpu (Draw_Interpretor& theDI,
7003 Standard_Integer theArgNb,
7004 const char** theArgVec)
7005{
7006 // get the context
7007 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
7008 if (aContextAIS.IsNull())
7009 {
23fe70ec 7010 Message::SendFail ("Error: no active viewer");
f0430952 7011 return 1;
7012 }
7013
dc3fe572 7014 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 7015 if (aDriver.IsNull())
7016 {
23fe70ec 7017 Message::SendFail ("Error: graphic driver not available");
f0430952 7018 return 1;
7019 }
7020
7021 Standard_Size aFreeBytes = 0;
7022 TCollection_AsciiString anInfo;
7023 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
7024 {
23fe70ec 7025 Message::SendFail ("Error: information not available");
f0430952 7026 return 1;
7027 }
7028
7029 if (theArgNb > 1 && *theArgVec[1] == 'f')
7030 {
7031 theDI << Standard_Real (aFreeBytes);
7032 }
7033 else
7034 {
7035 theDI << anInfo;
7036 }
7037
7038 return 0;
7039}
7040
85e096c3 7041// ==============================================================================
7042// function : VReadPixel
7043// purpose :
7044// ==============================================================================
7045static int VReadPixel (Draw_Interpretor& theDI,
7046 Standard_Integer theArgNb,
7047 const char** theArgVec)
7048{
7049 // get the active view
7050 Handle(V3d_View) aView = ViewerTest::CurrentView();
7051 if (aView.IsNull())
7052 {
23fe70ec 7053 Message::SendFail ("Error: no active viewer");
85e096c3 7054 return 1;
7055 }
7056 else if (theArgNb < 3)
7057 {
23fe70ec 7058 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
7059 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
85e096c3 7060 return 1;
7061 }
7062
dc858f4c 7063 Image_Format aFormat = Image_Format_RGBA;
7064 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 7065
85e096c3 7066 Standard_Integer aWidth, aHeight;
7067 aView->Window()->Size (aWidth, aHeight);
91322f44 7068 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
7069 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 7070 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
7071 {
23fe70ec 7072 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
85e096c3 7073 return 1;
7074 }
7075
ba00aab7 7076 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
85e096c3 7077 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
7078 {
dc858f4c 7079 TCollection_AsciiString aParam (theArgVec[anIter]);
7080 aParam.LowerCase();
55c8f0f7 7081 if (aParam == "-rgb"
ba00aab7 7082 || aParam == "rgb"
7083 || aParam == "-srgb"
7084 || aParam == "srgb")
85e096c3 7085 {
dc858f4c 7086 aFormat = Image_Format_RGB;
692613e5 7087 aBufferType = Graphic3d_BT_RGB;
ba00aab7 7088 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
85e096c3 7089 }
55c8f0f7
BB
7090 else if (aParam == "-hls"
7091 || aParam == "hls")
85e096c3 7092 {
dc858f4c 7093 aFormat = Image_Format_RGB;
692613e5 7094 aBufferType = Graphic3d_BT_RGB;
85e096c3 7095 toShowHls = Standard_True;
7096 }
55c8f0f7
BB
7097 else if (aParam == "-rgbf"
7098 || aParam == "rgbf")
85e096c3 7099 {
dc858f4c 7100 aFormat = Image_Format_RGBF;
692613e5 7101 aBufferType = Graphic3d_BT_RGB;
85e096c3 7102 }
55c8f0f7 7103 else if (aParam == "-rgba"
ba00aab7 7104 || aParam == "rgba"
7105 || aParam == "-srgba"
7106 || aParam == "srgba")
85e096c3 7107 {
dc858f4c 7108 aFormat = Image_Format_RGBA;
692613e5 7109 aBufferType = Graphic3d_BT_RGBA;
ba00aab7 7110 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
85e096c3 7111 }
55c8f0f7
BB
7112 else if (aParam == "-rgbaf"
7113 || aParam == "rgbaf")
85e096c3 7114 {
dc858f4c 7115 aFormat = Image_Format_RGBAF;
692613e5 7116 aBufferType = Graphic3d_BT_RGBA;
85e096c3 7117 }
55c8f0f7
BB
7118 else if (aParam == "-depth"
7119 || aParam == "depth")
85e096c3 7120 {
dc858f4c 7121 aFormat = Image_Format_GrayF;
692613e5 7122 aBufferType = Graphic3d_BT_Depth;
85e096c3 7123 }
55c8f0f7
BB
7124 else if (aParam == "-name"
7125 || aParam == "name")
85e096c3 7126 {
7127 toShowName = Standard_True;
7128 }
9196ea9d 7129 else if (aParam == "-hex"
7130 || aParam == "hex")
7131 {
7132 toShowHex = Standard_True;
7133 }
55c8f0f7
BB
7134 else
7135 {
23fe70ec 7136 Message::SendFail() << "Syntax error at '" << aParam << "'";
9196ea9d 7137 return 1;
55c8f0f7 7138 }
85e096c3 7139 }
7140
692613e5 7141 Image_PixMap anImage;
7142 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
7143 {
23fe70ec 7144 Message::SendFail ("Error: image allocation failed");
692613e5 7145 return 1;
7146 }
7147 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 7148 {
23fe70ec 7149 Message::SendFail ("Error: image dump failed");
85e096c3 7150 return 1;
7151 }
7152
68beaa3c 7153 // redirect possible warning messages that could have been added by ToPixMap
7154 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
7155 // contaminate result of the command
7156 Standard_CString aWarnLog = theDI.Result();
7157 if (aWarnLog != NULL && aWarnLog[0] != '\0')
7158 {
7159 std::cout << aWarnLog << std::endl;
7160 }
7161 theDI.Reset();
7162
ba00aab7 7163 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
85e096c3 7164 if (toShowName)
7165 {
692613e5 7166 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 7167 {
e958a649 7168 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 7169 }
7170 else
7171 {
e958a649 7172 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 7173 }
7174 }
9196ea9d 7175 else if (toShowHex)
7176 {
7177 if (aBufferType == Graphic3d_BT_RGBA)
7178 {
7179 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
7180 }
7181 else
7182 {
7183 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
7184 }
7185 }
85e096c3 7186 else
7187 {
7188 switch (aBufferType)
7189 {
7190 default:
692613e5 7191 case Graphic3d_BT_RGB:
85e096c3 7192 {
7193 if (toShowHls)
7194 {
e958a649 7195 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 7196 }
ba00aab7 7197 else if (toShow_sRGB)
7198 {
7199 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
7200 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
7201 }
85e096c3 7202 else
7203 {
e958a649 7204 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 7205 }
7206 break;
7207 }
692613e5 7208 case Graphic3d_BT_RGBA:
85e096c3 7209 {
ba00aab7 7210 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
7211 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
85e096c3 7212 break;
7213 }
692613e5 7214 case Graphic3d_BT_Depth:
85e096c3 7215 {
e958a649 7216 theDI << aColor.GetRGB().Red();
85e096c3 7217 break;
7218 }
7219 }
7220 }
7221
7222 return 0;
7223}
7224
fd3f6bd0 7225//! Auxiliary presentation for an image plane.
7226class ViewerTest_ImagePrs : public AIS_InteractiveObject
7227{
7228public:
7229 //! Main constructor.
7230 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
7231 const Standard_Real theWidth,
7232 const Standard_Real theHeight,
7233 const TCollection_AsciiString& theLabel)
7234 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
7235 {
7236 SetDisplayMode (0);
7237 SetHilightMode (1);
7238 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
7239 {
7240 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
7241 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
7242 Graphic3d_MaterialAspect aMat;
7243 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
61168418 7244 aMat.SetAmbientColor (Quantity_NOC_BLACK);
7245 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
7246 aMat.SetSpecularColor (Quantity_NOC_BLACK);
7247 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
fd3f6bd0 7248 aFillAspect->SetFrontMaterial (aMat);
7249 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
7250 aFillAspect->SetTextureMapOn();
7251 }
7252 {
7253 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
7254 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
7255 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
7256 myDrawer->SetTextAspect (aTextAspect);
7257 }
7258 {
7259 const gp_Dir aNorm (0.0, 0.0, 1.0);
7260 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
7261 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
7262 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
7263 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
7264 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
7265 myTris->AddEdge (1);
7266 myTris->AddEdge (2);
7267 myTris->AddEdge (3);
7268 myTris->AddEdge (3);
7269 myTris->AddEdge (2);
7270 myTris->AddEdge (4);
7271
7272 myRect = new Graphic3d_ArrayOfPolylines (4);
7273 myRect->AddVertex (myTris->Vertice (1));
7274 myRect->AddVertex (myTris->Vertice (3));
7275 myRect->AddVertex (myTris->Vertice (4));
7276 myRect->AddVertex (myTris->Vertice (2));
7277 }
7278 }
7279
7280 //! Returns TRUE for accepted display modes.
7281 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
7282
7283 //! Compute presentation.
decbff0d 7284 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
7285 const Handle(Prs3d_Presentation)& thePrs,
7286 const Standard_Integer theMode) Standard_OVERRIDE
fd3f6bd0 7287 {
7288 switch (theMode)
7289 {
7290 case 0:
7291 {
7292 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7293 aGroup->AddPrimitiveArray (myTris);
7294 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
7295 aGroup->AddPrimitiveArray (myRect);
7296 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7297 return;
7298 }
7299 case 1:
7300 {
7301 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
7302 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7303 aGroup->AddPrimitiveArray (myRect);
7304 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7305 return;
7306 }
7307 }
7308 }
7309
7310 //! Compute selection.
7311 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
7312 {
7313 if (theMode == 0)
7314 {
7315 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
7316 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
7317 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
7318 theSel->Add (aSensitive);
7319 }
7320 }
7321
7322private:
7323 Handle(Graphic3d_ArrayOfTriangles) myTris;
7324 Handle(Graphic3d_ArrayOfPolylines) myRect;
7325 TCollection_AsciiString myLabel;
7326 Standard_Real myWidth;
7327 Standard_Real myHeight;
7328};
7329
692613e5 7330//==============================================================================
7331//function : VDiffImage
7332//purpose : The draw-command compares two images.
7333//==============================================================================
7334
7335static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
7336{
fd3f6bd0 7337 if (theArgNb < 3)
692613e5 7338 {
23fe70ec 7339 Message::SendFail ("Syntax error: not enough arguments");
692613e5 7340 return 1;
7341 }
7342
fd3f6bd0 7343 Standard_Integer anArgIter = 1;
7344 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
7345 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
7346 TCollection_AsciiString aDiffImagePath;
7347 Standard_Real aTolColor = -1.0;
7348 Standard_Integer toBlackWhite = -1;
7349 Standard_Integer isBorderFilterOn = -1;
7350 Standard_Boolean isOldSyntax = Standard_False;
7351 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
7352 for (; anArgIter < theArgNb; ++anArgIter)
7353 {
7354 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7355 anArg.LowerCase();
7356 if (anArgIter + 1 < theArgNb
7357 && (anArg == "-toleranceofcolor"
7358 || anArg == "-tolerancecolor"
7359 || anArg == "-tolerance"
7360 || anArg == "-toler"))
7361 {
7362 aTolColor = Atof (theArgVec[++anArgIter]);
7363 if (aTolColor < 0.0 || aTolColor > 1.0)
7364 {
23fe70ec 7365 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7366 return 1;
7367 }
7368 }
7369 else if (anArg == "-blackwhite")
7370 {
7371 Standard_Boolean toEnable = Standard_True;
7372 if (anArgIter + 1 < theArgNb
dae2a922 7373 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7374 {
7375 ++anArgIter;
7376 }
7377 toBlackWhite = toEnable ? 1 : 0;
7378 }
7379 else if (anArg == "-borderfilter")
7380 {
7381 Standard_Boolean toEnable = Standard_True;
7382 if (anArgIter + 1 < theArgNb
dae2a922 7383 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7384 {
7385 ++anArgIter;
7386 }
7387 isBorderFilterOn = toEnable ? 1 : 0;
7388 }
7389 else if (anArg == "-exitonclose")
7390 {
49582f9d 7391 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 7392 if (anArgIter + 1 < theArgNb
dae2a922 7393 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 7394 {
7395 ++anArgIter;
7396 }
7397 }
7398 else if (anArg == "-closeonescape"
7399 || anArg == "-closeonesc")
7400 {
49582f9d 7401 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 7402 if (anArgIter + 1 < theArgNb
dae2a922 7403 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 7404 {
7405 ++anArgIter;
7406 }
7407 }
7408 else if (anArgIter + 3 < theArgNb
7409 && anArg == "-display")
7410 {
7411 aViewName = theArgVec[++anArgIter];
7412 aPrsNameRef = theArgVec[++anArgIter];
7413 aPrsNameNew = theArgVec[++anArgIter];
7414 if (anArgIter + 1 < theArgNb
7415 && *theArgVec[anArgIter + 1] != '-')
7416 {
7417 aPrsNameDiff = theArgVec[++anArgIter];
7418 }
7419 }
7420 else if (aTolColor < 0.0
d45edf24 7421 && anArg.IsRealValue (Standard_True))
fd3f6bd0 7422 {
7423 isOldSyntax = Standard_True;
7424 aTolColor = anArg.RealValue();
7425 if (aTolColor < 0.0 || aTolColor > 1.0)
7426 {
23fe70ec 7427 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7428 return 1;
7429 }
7430 }
7431 else if (isOldSyntax
7432 && toBlackWhite == -1
7433 && (anArg == "0" || anArg == "1"))
7434 {
7435 toBlackWhite = anArg == "1" ? 1 : 0;
7436 }
7437 else if (isOldSyntax
7438 && isBorderFilterOn == -1
7439 && (anArg == "0" || anArg == "1"))
7440 {
7441 isBorderFilterOn = anArg == "1" ? 1 : 0;
7442 }
7443 else if (aDiffImagePath.IsEmpty())
7444 {
7445 aDiffImagePath = theArgVec[anArgIter];
7446 }
7447 else
7448 {
23fe70ec 7449 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fd3f6bd0 7450 return 1;
7451 }
7452 }
692613e5 7453
fd3f6bd0 7454 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
7455 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
7456 if (!anImgRef->Load (anImgPathRef))
7457 {
23fe70ec 7458 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
fd3f6bd0 7459 return 1;
7460 }
7461 if (!anImgNew->Load (anImgPathNew))
7462 {
23fe70ec 7463 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
fd3f6bd0 7464 return 1;
7465 }
692613e5 7466
7467 // compare the images
7468 Image_Diff aComparer;
fd3f6bd0 7469 Standard_Integer aDiffColorsNb = -1;
7470 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 7471 {
fd3f6bd0 7472 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
7473 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
7474 aDiffColorsNb = aComparer.Compare();
7475 theDI << aDiffColorsNb << "\n";
692613e5 7476 }
7477
692613e5 7478 // save image of difference
fd3f6bd0 7479 Handle(Image_AlienPixMap) aDiff;
7480 if (aDiffColorsNb > 0
7481 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
7482 {
7483 aDiff = new Image_AlienPixMap();
7484 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
7485 {
23fe70ec 7486 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
fd3f6bd0 7487 return 1;
7488 }
7489 aComparer.SaveDiffImage (*aDiff);
7490 if (!aDiffImagePath.IsEmpty()
7491 && !aDiff->Save (aDiffImagePath))
7492 {
23fe70ec 7493 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
fd3f6bd0 7494 return 1;
7495 }
7496 }
7497
7498 if (aViewName.IsEmpty())
7499 {
7500 return 0;
7501 }
7502
7503 ViewerTest_Names aViewNames (aViewName);
7504 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
7505 {
7506 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
7507 theDI.Eval (aCommand.ToCString());
7508 }
7509
7510 Standard_Integer aPxLeft = 0;
7511 Standard_Integer aPxTop = 0;
7512 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
7513 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
7514 ? int(anImgRef->SizeY() * 2)
7515 : int(anImgRef->SizeY());
7516 TCollection_AsciiString aDisplayName;
9e04ccdc 7517 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
7518 aViewName, aDisplayName);
fd3f6bd0 7519
7520 Standard_Real aRatio = anImgRef->Ratio();
7521 Standard_Real aSizeX = 1.0;
7522 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 7523 {
fd3f6bd0 7524 OSD_Path aPath (anImgPathRef);
7525 TCollection_AsciiString aLabelRef;
7526 if (!aPath.Name().IsEmpty())
7527 {
7528 aLabelRef = aPath.Name() + aPath.Extension();
7529 }
7530 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
7531
7532 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
7533 gp_Trsf aTrsfRef;
7534 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
7535 anImgRefPrs->SetLocalTransformation (aTrsfRef);
7536 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 7537 }
fd3f6bd0 7538 {
7539 OSD_Path aPath (anImgPathNew);
7540 TCollection_AsciiString aLabelNew;
7541 if (!aPath.Name().IsEmpty())
7542 {
7543 aLabelNew = aPath.Name() + aPath.Extension();
7544 }
7545 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 7546
fd3f6bd0 7547 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
7548 gp_Trsf aTrsfRef;
7549 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
7550 anImgNewPrs->SetLocalTransformation (aTrsfRef);
7551 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
7552 }
7553 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
7554 if (!aDiff.IsNull())
7555 {
7556 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
7557 gp_Trsf aTrsfDiff;
7558 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
7559 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
7560 }
7561 if (!aPrsNameDiff.IsEmpty())
7562 {
7563 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
7564 }
7565 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
7566 ViewerTest::CurrentView()->FitAll();
692613e5 7567 return 0;
7568}
7569
4754e164 7570//=======================================================================
7571//function : VSelect
7572//purpose : Emulates different types of selection by mouse:
7573// 1) single click selection
7574// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
7575// 3) selection with polygon having corners at
dc3fe572 7576// pixel positions (x1,y1),...,(xn,yn)
4754e164 7577// 4) any of these selections with shift button pressed
7578//=======================================================================
49582f9d 7579static Standard_Integer VSelect (Draw_Interpretor& ,
7580 Standard_Integer theNbArgs,
7581 const char** theArgVec)
4754e164 7582{
49582f9d 7583 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
7584 if (aCtx.IsNull())
4754e164 7585 {
23fe70ec 7586 Message::SendFail ("Error: no active viewer");
4754e164 7587 return 1;
7588 }
2157d6ac 7589
49582f9d 7590 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
75cf8250 7591 bool toAllowOverlap = false;
7592 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
49582f9d 7593 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2157d6ac 7594 {
49582f9d 7595 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7596 anArg.LowerCase();
7597 if (anArg == "-allowoverlap")
7598 {
7599 toAllowOverlap = true;
7600 if (anArgIter + 1 < theNbArgs
dae2a922 7601 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
49582f9d 7602 {
7603 ++anArgIter;
7604 }
7605 }
e3d4b879 7606 else if (anArg == "-replace")
7607 {
7608 aSelScheme = AIS_SelectionScheme_Replace;
7609 }
7610 else if (anArg == "-xor"
7611 || anArg == "-shift")
7612 {
7613 aSelScheme = AIS_SelectionScheme_XOR;
7614 }
7615 else if (anArg == "-add")
7616 {
7617 aSelScheme = AIS_SelectionScheme_Add;
7618 }
7619 else if (anArg == "-remove")
7620 {
7621 aSelScheme = AIS_SelectionScheme_Remove;
7622 }
49582f9d 7623 else if (anArgIter + 1 < theNbArgs
7624 && anArg.IsIntegerValue()
7625 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
2157d6ac 7626 {
49582f9d 7627 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
7628 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
7629 }
7630 else if (anArgIter + 1 == theNbArgs
7631 && anArg.IsIntegerValue())
7632 {
75cf8250 7633 if (anArg.IntegerValue() == 1)
7634 {
7635 aSelScheme = AIS_SelectionScheme_XOR;
7636 }
49582f9d 7637 }
7638 else
7639 {
23fe70ec 7640 Message::SendFail() << "Syntax error at '" << anArg << "'";
2157d6ac 7641 return 1;
7642 }
49582f9d 7643 }
a24a7821 7644
49582f9d 7645 if (toAllowOverlap)
7646 {
7647 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
2157d6ac 7648 }
7649
4754e164 7650 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
49582f9d 7651 if (aPnts.IsEmpty())
4754e164 7652 {
75cf8250 7653 aCtx->SelectDetected (aSelScheme);
49582f9d 7654 aCtx->CurrentViewer()->Invalidate();
4754e164 7655 }
49582f9d 7656 else if (aPnts.Length() == 2)
4754e164 7657 {
49582f9d 7658 if (toAllowOverlap
7659 && aPnts.First().y() < aPnts.Last().y())
7660 {
7661 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7662 }
7663 else if (!toAllowOverlap
7664 && aPnts.First().y() > aPnts.Last().y())
7665 {
7666 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7667 }
e3d4b879 7668
7669 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7670 }
7671 else
7672 {
e3d4b879 7673 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
4754e164 7674 }
49582f9d 7675 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
4754e164 7676 return 0;
7677}
7678
7679//=======================================================================
7680//function : VMoveTo
dc3fe572 7681//purpose : Emulates cursor movement to defined pixel position
4754e164 7682//=======================================================================
1e756cb9 7683static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7684 Standard_Integer theNbArgs,
7685 const char** theArgVec)
4754e164 7686{
8a590580 7687 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7688 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7689 if (aContext.IsNull())
4754e164 7690 {
23fe70ec 7691 Message::SendFail ("Error: no active viewer");
4754e164 7692 return 1;
7693 }
7694
8a590580 7695 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7696 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7697 {
8a590580 7698 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7699 anArgStr.LowerCase();
7700 if (anArgStr == "-reset"
7701 || anArgStr == "-clear")
7702 {
7703 if (anArgIter + 1 < theNbArgs)
7704 {
23fe70ec 7705 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
8a590580 7706 return 1;
7707 }
7708
5634c81a 7709 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
8a590580 7710 && aContext->CurrentViewer()->GridEcho();
7711 if (toEchoGrid)
7712 {
7713 aContext->CurrentViewer()->HideGridEcho (aView);
7714 }
7715 if (aContext->ClearDetected() || toEchoGrid)
7716 {
7717 aContext->CurrentViewer()->RedrawImmediate();
7718 }
7719 return 0;
7720 }
7721 else if (aMousePos.x() == IntegerLast()
7722 && anArgStr.IsIntegerValue())
7723 {
7724 aMousePos.x() = anArgStr.IntegerValue();
7725 }
7726 else if (aMousePos.y() == IntegerLast()
7727 && anArgStr.IsIntegerValue())
7728 {
7729 aMousePos.y() = anArgStr.IntegerValue();
7730 }
7731 else
7732 {
23fe70ec 7733 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8a590580 7734 return 1;
7735 }
7736 }
7737
7738 if (aMousePos.x() == IntegerLast()
7739 || aMousePos.y() == IntegerLast())
7740 {
23fe70ec 7741 Message::SendFail ("Syntax error: wrong number of arguments");
4754e164 7742 return 1;
7743 }
8a590580 7744
49582f9d 7745 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7746 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7747 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7748
1e756cb9 7749 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7750 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7751 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7752 {
7753 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7754 {
7755 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7756 break;
7757 }
7758 }
7759 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7760 return 0;
7761}
7762
1beb58d7 7763namespace
7764{
7765 //! Global map storing all animations registered in ViewerTest.
7766 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7767
7768 //! The animation calling the Draw Harness command.
7769 class ViewerTest_AnimationProc : public AIS_Animation
7770 {
7771 public:
7772
7773 //! Main constructor.
7774 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7775 Draw_Interpretor* theDI,
7776 const TCollection_AsciiString& theCommand)
7777 : AIS_Animation (theAnimationName),
7778 myDrawInter(theDI),
7779 myCommand (theCommand)
7780 {
7781 //
7782 }
7783
7784 protected:
7785
7786 //! Evaluate the command.
7787 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7788 {
7789 TCollection_AsciiString aCmd = myCommand;
7790 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7791 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7792 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7793 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7794 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7795 myDrawInter->Eval (aCmd.ToCString());
7796 }
7797
7798 //! Find the keyword in the command and replace it with value.
7799 //! @return the position of the keyword to pass value
7800 void replace (TCollection_AsciiString& theCmd,
7801 const TCollection_AsciiString& theKey,
7802 const TCollection_AsciiString& theVal)
7803 {
7804 TCollection_AsciiString aCmd (theCmd);
7805 aCmd.LowerCase();
7806 const Standard_Integer aPos = aCmd.Search (theKey);
7807 if (aPos == -1)
7808 {
7809 return;
7810 }
7811
7812 TCollection_AsciiString aPart1, aPart2;
7813 Standard_Integer aPart1To = aPos - 1;
7814 if (aPart1To >= 1
7815 && aPart1To <= theCmd.Length())
7816 {
7817 aPart1 = theCmd.SubString (1, aPart1To);
7818 }
7819
7820 Standard_Integer aPart2From = aPos + theKey.Length();
7821 if (aPart2From >= 1
7822 && aPart2From <= theCmd.Length())
7823 {
7824 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7825 }
7826
7827 theCmd = aPart1 + theVal + aPart2;
7828 }
7829
7830 protected:
7831
7832 Draw_Interpretor* myDrawInter;
7833 TCollection_AsciiString myCommand;
7834
7835 };
7836
7837 //! Replace the animation with the new one.
7838 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7839 Handle(AIS_Animation)& theAnimation,
7840 const Handle(AIS_Animation)& theAnimationNew)
7841 {
7842 theAnimationNew->CopyFrom (theAnimation);
7843 if (!theParentAnimation.IsNull())
7844 {
7845 theParentAnimation->Replace (theAnimation, theAnimationNew);
7846 }
7847 else
7848 {
7849 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7850 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7851 }
7852 theAnimation = theAnimationNew;
7853 }
7854
7855 //! Parse the point.
7856 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7857 {
7858 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
d45edf24 7859 if (!anXYZ[0].IsRealValue (Standard_True)
7860 || !anXYZ[1].IsRealValue (Standard_True)
7861 || !anXYZ[2].IsRealValue (Standard_True))
1beb58d7 7862 {
7863 return Standard_False;
7864 }
7865
7866 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7867 return Standard_True;
7868 }
7869
7870 //! Parse the quaternion.
7871 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7872 {
7873 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
d45edf24 7874 if (!anXYZW[0].IsRealValue (Standard_True)
7875 || !anXYZW[1].IsRealValue (Standard_True)
7876 || !anXYZW[2].IsRealValue (Standard_True)
7877 || !anXYZW[3].IsRealValue (Standard_True))
1beb58d7 7878 {
7879 return Standard_False;
7880 }
7881
7882 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7883 return Standard_True;
7884 }
7885
08f8a185 7886 //! Auxiliary class for flipping image upside-down.
7887 class ImageFlipper
7888 {
7889 public:
7890
7891 //! Empty constructor.
7892 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7893
7894 //! Perform flipping.
7895 Standard_Boolean FlipY (Image_PixMap& theImage)
7896 {
7897 if (theImage.IsEmpty()
7898 || theImage.SizeX() == 0
7899 || theImage.SizeY() == 0)
7900 {
7901 return Standard_False;
7902 }
7903
7904 const Standard_Size aRowSize = theImage.SizeRowBytes();
7905 if (myTmp.Size() < aRowSize
7906 && !myTmp.Allocate (aRowSize))
7907 {
7908 return Standard_False;
7909 }
7910
7911 // for odd height middle row should be left as is
7912 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7913 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7914 {
7915 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7916 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7917 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7918 memcpy (aTop, aBot, aRowSize);
7919 memcpy (aBot, myTmp.Data(), aRowSize);
7920 }
7921 return Standard_True;
7922 }
7923
7924 private:
7925 NCollection_Buffer myTmp;
7926 };
7927
1beb58d7 7928}
7929
197ac94e 7930//=================================================================================================
4754e164 7931//function : VViewParams
dc3fe572 7932//purpose : Gets or sets AIS View characteristics
197ac94e 7933//=================================================================================================
7934static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7935{
1beb58d7 7936 Handle(V3d_View) aView = ViewerTest::CurrentView();
7937 if (aView.IsNull())
4754e164 7938 {
23fe70ec 7939 Message::SendFail ("Error: no active viewer");
4754e164 7940 return 1;
7941 }
197ac94e 7942
1beb58d7 7943 Standard_Boolean toSetProj = Standard_False;
7944 Standard_Boolean toSetUp = Standard_False;
7945 Standard_Boolean toSetAt = Standard_False;
7946 Standard_Boolean toSetEye = Standard_False;
7947 Standard_Boolean toSetScale = Standard_False;
7948 Standard_Boolean toSetSize = Standard_False;
7949 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7950 Standard_Real aViewScale = aView->Scale();
7951 Standard_Real aViewSize = 1.0;
1beb58d7 7952 Graphic3d_Vec2i aCenter2d;
7953 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7954 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7955 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7956 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7957 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
197ac94e 7958 if (theArgsNb == 1)
4754e164 7959 {
197ac94e 7960 // print all of the available view parameters
1beb58d7 7961 char aText[4096];
7962 Sprintf (aText,
7963 "Scale: %g\n"
7964 "Proj: %12g %12g %12g\n"
7965 "Up: %12g %12g %12g\n"
7966 "At: %12g %12g %12g\n"
7967 "Eye: %12g %12g %12g\n",
7968 aViewScale,
7969 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7970 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7971 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7972 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7973 theDi << aText;
197ac94e 7974 return 0;
4754e164 7975 }
197ac94e 7976
1beb58d7 7977 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7978 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7979 {
1beb58d7 7980 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7981 anArg.LowerCase();
7982 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7983 {
197ac94e 7984 continue;
7985 }
1beb58d7 7986 else if (anArg == "-cmd"
7987 || anArg == "-command"
7988 || anArg == "-args")
7989 {
7990 char aText[4096];
7991 Sprintf (aText,
7992 "-scale %g "
7993 "-proj %g %g %g "
7994 "-up %g %g %g "
7995 "-at %g %g %g\n",
7996 aViewScale,
7997 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7998 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7999 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8000 theDi << aText;
8001 }
8002 else if (anArg == "-scale"
8003 || anArg == "-size")
8004 {
8005 if (anArgIter + 1 < theArgsNb
8006 && *theArgVec[anArgIter + 1] != '-')
8007 {
8008 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
d45edf24 8009 if (aValueArg.IsRealValue (Standard_True))
1beb58d7 8010 {
8011 ++anArgIter;
8012 if (anArg == "-scale")
8013 {
8014 toSetScale = Standard_True;
8015 aViewScale = aValueArg.RealValue();
8016 }
8017 else if (anArg == "-size")
8018 {
8019 toSetSize = Standard_True;
8020 aViewSize = aValueArg.RealValue();
8021 }
8022 continue;
8023 }
8024 }
8025 if (anArg == "-scale")
8026 {
8027 theDi << "Scale: " << aView->Scale() << "\n";
8028 }
8029 else if (anArg == "-size")
8030 {
8031 Graphic3d_Vec2d aSizeXY;
8032 aView->Size (aSizeXY.x(), aSizeXY.y());
8033 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
8034 }
8035 }
8036 else if (anArg == "-eye"
8037 || anArg == "-at"
8038 || anArg == "-up"
8039 || anArg == "-proj")
8040 {
8041 if (anArgIter + 3 < theArgsNb)
8042 {
8043 gp_XYZ anXYZ;
8044 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
8045 {
8046 anArgIter += 3;
8047 if (anArg == "-eye")
8048 {
8049 toSetEye = Standard_True;
8050 aViewEye = anXYZ;
8051 }
8052 else if (anArg == "-at")
8053 {
8054 toSetAt = Standard_True;
8055 aViewAt = anXYZ;
8056 }
8057 else if (anArg == "-up")
8058 {
8059 toSetUp = Standard_True;
8060 aViewUp = anXYZ;
8061 }
8062 else if (anArg == "-proj")
8063 {
8064 toSetProj = Standard_True;
8065 aViewProj = anXYZ;
8066 }
8067 continue;
8068 }
8069 }
197ac94e 8070
1beb58d7 8071 if (anArg == "-eye")
8072 {
8073 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
8074 }
8075 else if (anArg == "-at")
8076 {
8077 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
8078 }
8079 else if (anArg == "-up")
8080 {
8081 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
8082 }
8083 else if (anArg == "-proj")
8084 {
8085 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
8086 }
8087 }
8088 else if (anArg == "-center")
3dfe95cd 8089 {
1beb58d7 8090 if (anArgIter + 2 < theArgsNb)
8091 {
8092 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
8093 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
8094 if (anX.IsIntegerValue()
8095 && anY.IsIntegerValue())
8096 {
8097 toSetCenter2d = Standard_True;
8098 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
8099 }
8100 }
8101 }
8102 else
8103 {
23fe70ec 8104 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 8105 return 1;
8106 }
1beb58d7 8107 }
3dfe95cd 8108
1beb58d7 8109 // change view parameters in proper order
8110 if (toSetScale)
8111 {
8112 aView->SetScale (aViewScale);
8113 }
8114 if (toSetSize)
8115 {
8116 aView->SetSize (aViewSize);
8117 }
8118 if (toSetEye)
8119 {
8120 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
8121 }
8122 if (toSetAt)
8123 {
8124 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8125 }
8126 if (toSetProj)
8127 {
8128 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
8129 }
8130 if (toSetUp)
8131 {
8132 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
8133 }
8134 if (toSetCenter2d)
8135 {
8136 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 8137 }
8138
1beb58d7 8139 return 0;
8140}
197ac94e 8141
2e93433e 8142//==============================================================================
8143//function : V2DMode
8144//purpose :
8145//==============================================================================
8146static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
8147{
8148 bool is2dMode = true;
8149 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
8150 if (aV3dView.IsNull())
8151 {
23fe70ec 8152 Message::SendFail ("Error: no active viewer");
2e93433e 8153 return 1;
8154 }
8155 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
8156 {
8157 const TCollection_AsciiString anArg = theArgVec[anArgIt];
8158 TCollection_AsciiString anArgCase = anArg;
8159 anArgCase.LowerCase();
8160 if (anArgIt + 1 < theArgsNb
8161 && anArgCase == "-name")
8162 {
8163 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
8164 TCollection_AsciiString aViewName = aViewNames.GetViewName();
8165 if (!ViewerTest_myViews.IsBound1 (aViewName))
8166 {
23fe70ec 8167 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 8168 return 1;
8169 }
8170 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
8171 }
8172 else if (anArgCase == "-mode")
8173 {
8174 if (anArgIt + 1 < theArgsNb
dae2a922 8175 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 8176 {
8177 ++anArgIt;
8178 }
8179 }
dae2a922 8180 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 8181 {
8182 //
8183 }
8184 else
8185 {
23fe70ec 8186 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 8187 return 1;
8188 }
8189 }
8190
8191 aV3dView->SetView2DMode (is2dMode);
8192 return 0;
8193}
8194
1beb58d7 8195//==============================================================================
8196//function : VAnimation
8197//purpose :
8198//==============================================================================
8199static Standard_Integer VAnimation (Draw_Interpretor& theDI,
8200 Standard_Integer theArgNb,
8201 const char** theArgVec)
8202{
8203 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
8204 if (theArgNb < 2)
4754e164 8205 {
1beb58d7 8206 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
8207 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
8208 {
8209 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8210 }
1beb58d7 8211 return 0;
8212 }
8213 if (aCtx.IsNull())
8214 {
23fe70ec 8215 Message::SendFail ("Error: no active viewer");
1beb58d7 8216 return 1;
4754e164 8217 }
197ac94e 8218
1beb58d7 8219 Standard_Integer anArgIter = 1;
8220 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
8221 if (aNameArg.IsEmpty())
8222 {
23fe70ec 8223 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 8224 return 1;
8225 }
8226
8227 TCollection_AsciiString aNameArgLower = aNameArg;
8228 aNameArgLower.LowerCase();
8229 if (aNameArgLower == "-reset"
8230 || aNameArgLower == "-clear")
8231 {
8232 ViewerTest_AnimationTimelineMap.Clear();
8233 return 0;
8234 }
8235 else if (aNameArg.Value (1) == '-')
8236 {
23fe70ec 8237 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 8238 return 1;
8239 }
197ac94e 8240
1beb58d7 8241 const char* aNameSplitter = "/";
8242 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
8243 if (aSplitPos == -1)
197ac94e 8244 {
1beb58d7 8245 aNameSplitter = ".";
8246 aSplitPos = aNameArg.Search (aNameSplitter);
8247 }
8248
8249 // find existing or create a new animation by specified name within syntax "parent.child".
8250 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
8251 for (; !aNameArg.IsEmpty();)
8252 {
8253 TCollection_AsciiString aNameParent;
8254 if (aSplitPos != -1)
197ac94e 8255 {
1beb58d7 8256 if (aSplitPos == aNameArg.Length())
8257 {
23fe70ec 8258 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 8259 return 1;
8260 }
8261
8262 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
8263 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
8264
8265 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 8266 }
8267 else
8268 {
1beb58d7 8269 aNameParent = aNameArg;
8270 aNameArg.Clear();
197ac94e 8271 }
1beb58d7 8272
8273 if (anAnimation.IsNull())
3dfe95cd 8274 {
1beb58d7 8275 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
8276 {
8277 anAnimation = new AIS_Animation (aNameParent);
8278 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
8279 }
8280 aRootAnimation = anAnimation;
3dfe95cd 8281 }
8282 else
8283 {
1beb58d7 8284 aParentAnimation = anAnimation;
8285 anAnimation = aParentAnimation->Find (aNameParent);
8286 if (anAnimation.IsNull())
8287 {
8288 anAnimation = new AIS_Animation (aNameParent);
8289 aParentAnimation->Add (anAnimation);
8290 }
3dfe95cd 8291 }
8292 }
1beb58d7 8293
8294 if (anArgIter >= theArgNb)
197ac94e 8295 {
1beb58d7 8296 // just print the list of children
8297 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 8298 {
1beb58d7 8299 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8300 }
1beb58d7 8301 return 0;
197ac94e 8302 }
1beb58d7 8303
bf7b2ceb 8304 // animation parameters
1beb58d7 8305 Standard_Boolean toPlay = Standard_False;
8306 Standard_Real aPlaySpeed = 1.0;
8307 Standard_Real aPlayStartTime = anAnimation->StartPts();
8308 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 8309 Standard_Boolean isFreeCamera = Standard_False;
8310 Standard_Boolean isLockLoop = Standard_False;
08f8a185 8311
8312 // video recording parameters
8313 TCollection_AsciiString aRecFile;
8314 Image_VideoParams aRecParams;
8315
1beb58d7 8316 Handle(V3d_View) aView = ViewerTest::CurrentView();
8317 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 8318 {
1beb58d7 8319 TCollection_AsciiString anArg (theArgVec[anArgIter]);
8320 anArg.LowerCase();
bf7b2ceb 8321 // general options
1beb58d7 8322 if (anArg == "-reset"
8323 || anArg == "-clear")
197ac94e 8324 {
1beb58d7 8325 anAnimation->Clear();
8326 }
8327 else if (anArg == "-remove"
8328 || anArg == "-del"
8329 || anArg == "-delete")
8330 {
8331 if (!aParentAnimation.IsNull())
8332 {
8333 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
8334 }
8335 else
8336 {
8337 aParentAnimation->Remove (anAnimation);
8338 }
8339 }
bf7b2ceb 8340 // playback options
1beb58d7 8341 else if (anArg == "-play")
8342 {
8343 toPlay = Standard_True;
8344 if (++anArgIter < theArgNb)
8345 {
8346 if (*theArgVec[anArgIter] == '-')
8347 {
8348 --anArgIter;
8349 continue;
8350 }
8351 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
8352
8353 if (++anArgIter < theArgNb)
8354 {
8355 if (*theArgVec[anArgIter] == '-')
8356 {
8357 --anArgIter;
8358 continue;
8359 }
8360 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8361 }
8362 }
8363 }
8364 else if (anArg == "-resume")
8365 {
8366 toPlay = Standard_True;
8367 aPlayStartTime = anAnimation->ElapsedTime();
8368 if (++anArgIter < theArgNb)
8369 {
8370 if (*theArgVec[anArgIter] == '-')
8371 {
8372 --anArgIter;
8373 continue;
8374 }
8375
8376 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8377 }
8378 }
8379 else if (anArg == "-playspeed"
8380 || anArg == "-speed")
8381 {
8382 if (++anArgIter >= theArgNb)
8383 {
23fe70ec 8384 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 8385 return 1;
8386 }
8387 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8388 }
8389 else if (anArg == "-lock"
8390 || anArg == "-lockloop"
8391 || anArg == "-playlockloop")
8392 {
8393 isLockLoop = Standard_True;
8394 }
8395 else if (anArg == "-freecamera"
8396 || anArg == "-playfreecamera"
8397 || anArg == "-freelook")
8398 {
8399 isFreeCamera = Standard_True;
8400 }
08f8a185 8401 // video recodring options
8402 else if (anArg == "-rec"
8403 || anArg == "-record")
8404 {
8405 if (++anArgIter >= theArgNb)
8406 {
23fe70ec 8407 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8408 return 1;
8409 }
8410
8411 aRecFile = theArgVec[anArgIter];
8412 if (aRecParams.FpsNum <= 0)
8413 {
8414 aRecParams.FpsNum = 24;
8415 }
8416
8417 if (anArgIter + 2 < theArgNb
8418 && *theArgVec[anArgIter + 1] != '-'
8419 && *theArgVec[anArgIter + 2] != '-')
8420 {
8421 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8422 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8423 if (aWidthArg .IsIntegerValue()
8424 && aHeightArg.IsIntegerValue())
8425 {
8426 aRecParams.Width = aWidthArg .IntegerValue();
8427 aRecParams.Height = aHeightArg.IntegerValue();
8428 anArgIter += 2;
8429 }
8430 }
8431 }
1beb58d7 8432 else if (anArg == "-fps")
8433 {
8434 if (++anArgIter >= theArgNb)
8435 {
23fe70ec 8436 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8437 return 1;
8438 }
bf7b2ceb 8439
8440 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8441 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8442 if (aSplitIndex == 0)
8443 {
08f8a185 8444 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 8445 }
8446 else
8447 {
8448 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8449 aFpsArg.Split (aFpsArg.Length() - 1);
8450 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 8451 aRecParams.FpsNum = aNumStr.IntegerValue();
8452 aRecParams.FpsDen = aDenStr.IntegerValue();
8453 if (aRecParams.FpsDen < 1)
bf7b2ceb 8454 {
23fe70ec 8455 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 8456 return 1;
8457 }
8458 }
1beb58d7 8459 }
08f8a185 8460 else if (anArg == "-format")
8461 {
8462 if (++anArgIter >= theArgNb)
8463 {
23fe70ec 8464 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8465 return 1;
8466 }
8467 aRecParams.Format = theArgVec[anArgIter];
8468 }
8469 else if (anArg == "-pix_fmt"
8470 || anArg == "-pixfmt"
8471 || anArg == "-pixelformat")
8472 {
8473 if (++anArgIter >= theArgNb)
8474 {
23fe70ec 8475 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8476 return 1;
8477 }
8478 aRecParams.PixelFormat = theArgVec[anArgIter];
8479 }
8480 else if (anArg == "-codec"
8481 || anArg == "-vcodec"
8482 || anArg == "-videocodec")
8483 {
8484 if (++anArgIter >= theArgNb)
8485 {
23fe70ec 8486 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8487 return 1;
8488 }
8489 aRecParams.VideoCodec = theArgVec[anArgIter];
8490 }
8491 else if (anArg == "-crf"
8492 || anArg == "-preset"
8493 || anArg == "-qp")
8494 {
8495 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8496 if (++anArgIter >= theArgNb)
8497 {
23fe70ec 8498 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8499 return 1;
8500 }
8501
8502 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8503 }
bf7b2ceb 8504 // animation definition options
1beb58d7 8505 else if (anArg == "-start"
8506 || anArg == "-starttime"
8507 || anArg == "-startpts")
8508 {
8509 if (++anArgIter >= theArgNb)
8510 {
23fe70ec 8511 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8512 return 1;
8513 }
8514
8515 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8516 aRootAnimation->UpdateTotalDuration();
8517 }
8518 else if (anArg == "-end"
8519 || anArg == "-endtime"
8520 || anArg == "-endpts")
8521 {
8522 if (++anArgIter >= theArgNb)
8523 {
23fe70ec 8524 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8525 return 1;
8526 }
8527
8528 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8529 aRootAnimation->UpdateTotalDuration();
8530 }
8531 else if (anArg == "-dur"
8532 || anArg == "-duration")
8533 {
8534 if (++anArgIter >= theArgNb)
8535 {
23fe70ec 8536 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8537 return 1;
8538 }
8539
8540 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8541 aRootAnimation->UpdateTotalDuration();
8542 }
8543 else if (anArg == "-command"
8544 || anArg == "-cmd"
8545 || anArg == "-invoke"
8546 || anArg == "-eval"
8547 || anArg == "-proc")
8548 {
8549 if (++anArgIter >= theArgNb)
8550 {
23fe70ec 8551 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8552 return 1;
8553 }
8554
8555 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8556 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8557 }
8558 else if (anArg == "-objecttrsf"
8559 || anArg == "-objectransformation"
8560 || anArg == "-objtransformation"
8561 || anArg == "-objtrsf"
8562 || anArg == "-object"
8563 || anArg == "-obj")
8564 {
8565 if (++anArgIter >= theArgNb)
8566 {
23fe70ec 8567 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8568 return 1;
8569 }
8570
8571 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8572 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8573 Handle(AIS_InteractiveObject) anObject;
8574 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8575 {
23fe70ec 8576 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8577 return 1;
8578 }
8579
1beb58d7 8580 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8581 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8582 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8583 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8584 Standard_Boolean isTrsfSet = Standard_False;
8585 Standard_Integer aTrsfArgIter = anArgIter + 1;
8586 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8587 {
8588 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8589 aTrsfArg.LowerCase();
8590 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8591 if (aTrsfArg.StartsWith ("-rotation")
8592 || aTrsfArg.StartsWith ("-rot"))
8593 {
8594 isTrsfSet = Standard_True;
8595 if (aTrsfArgIter + 4 >= theArgNb
8596 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8597 {
23fe70ec 8598 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8599 return 1;
8600 }
8601 aTrsfArgIter += 4;
8602 }
8603 else if (aTrsfArg.StartsWith ("-location")
8604 || aTrsfArg.StartsWith ("-loc"))
8605 {
8606 isTrsfSet = Standard_True;
8607 if (aTrsfArgIter + 3 >= theArgNb
8608 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8609 {
23fe70ec 8610 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8611 return 1;
8612 }
8613 aTrsfArgIter += 3;
8614 }
8615 else if (aTrsfArg.StartsWith ("-scale"))
8616 {
8617 isTrsfSet = Standard_True;
8618 if (++aTrsfArgIter >= theArgNb)
8619 {
23fe70ec 8620 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8621 return 1;
8622 }
8623
8624 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
d45edf24 8625 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8626 {
23fe70ec 8627 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8628 return 1;
8629 }
8630 aScales[anIndex] = aScaleStr.RealValue();
8631 }
8632 else
8633 {
8634 anArgIter = aTrsfArgIter - 1;
8635 break;
8636 }
8637 }
8638 if (!isTrsfSet)
8639 {
23fe70ec 8640 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8641 return 1;
8642 }
8643 else if (aTrsfArgIter >= theArgNb)
8644 {
8645 anArgIter = theArgNb;
8646 }
8647
8648 aTrsfs[0].SetRotation (aRotQuats[0]);
8649 aTrsfs[1].SetRotation (aRotQuats[1]);
8650 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8651 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8652 aTrsfs[0].SetScaleFactor (aScales[0]);
8653 aTrsfs[1].SetScaleFactor (aScales[1]);
8654
8655 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8656 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8657 }
8658 else if (anArg == "-viewtrsf"
8659 || anArg == "-view")
8660 {
8661 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8662 if (aCamAnimation.IsNull())
8663 {
8664 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8665 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8666 }
8667
8668 Handle(Graphic3d_Camera) aCams[2] =
8669 {
8670 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8671 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8672 };
8673
8674 Standard_Boolean isTrsfSet = Standard_False;
8675 Standard_Integer aViewArgIter = anArgIter + 1;
8676 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8677 {
8678 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8679 aViewArg.LowerCase();
8680 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8681 if (aViewArg.StartsWith ("-scale"))
8682 {
8683 isTrsfSet = Standard_True;
8684 if (++aViewArgIter >= theArgNb)
8685 {
23fe70ec 8686 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8687 return 1;
8688 }
8689
8690 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
d45edf24 8691 if (!aScaleStr.IsRealValue (Standard_True))
1beb58d7 8692 {
23fe70ec 8693 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8694 return 1;
8695 }
8696 Standard_Real aScale = aScaleStr.RealValue();
8697 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8698 aCams[anIndex]->SetScale (aScale);
8699 }
8700 else if (aViewArg.StartsWith ("-eye")
8701 || aViewArg.StartsWith ("-center")
8702 || aViewArg.StartsWith ("-at")
8703 || aViewArg.StartsWith ("-up"))
8704 {
8705 isTrsfSet = Standard_True;
8706 gp_XYZ anXYZ;
8707 if (aViewArgIter + 3 >= theArgNb
8708 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8709 {
23fe70ec 8710 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8711 return 1;
8712 }
8713 aViewArgIter += 3;
8714
8715 if (aViewArg.StartsWith ("-eye"))
8716 {
8717 aCams[anIndex]->SetEye (anXYZ);
8718 }
8719 else if (aViewArg.StartsWith ("-center")
8720 || aViewArg.StartsWith ("-at"))
8721 {
8722 aCams[anIndex]->SetCenter (anXYZ);
8723 }
8724 else if (aViewArg.StartsWith ("-up"))
8725 {
8726 aCams[anIndex]->SetUp (anXYZ);
8727 }
8728 }
8729 else
8730 {
8731 anArgIter = aViewArgIter - 1;
8732 break;
8733 }
8734 }
8735 if (!isTrsfSet)
8736 {
23fe70ec 8737 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8738 return 1;
8739 }
8740 else if (aViewArgIter >= theArgNb)
8741 {
8742 anArgIter = theArgNb;
8743 }
8744
8745 aCamAnimation->SetCameraStart(aCams[0]);
8746 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8747 }
8748 else
8749 {
23fe70ec 8750 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8751 return 1;
197ac94e 8752 }
8753 }
1beb58d7 8754
08f8a185 8755 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8756 {
1beb58d7 8757 return 0;
8758 }
8759
8760 // Start animation timeline and process frame updating.
8761 TheIsAnimating = Standard_True;
8762 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8763 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8764 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8765 if (isFreeCamera)
8766 {
8767 aView->Camera()->Copy (aCameraBack);
8768 }
8769
8770 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8771 if (aRecParams.FpsNum <= 0)
1beb58d7 8772 {
8773 while (!anAnimation->IsStopped())
197ac94e 8774 {
1beb58d7 8775 aCameraBack->Copy (aView->Camera());
8776 const Standard_Real aPts = anAnimation->UpdateTimer();
8777 if (isFreeCamera)
8778 {
8779 aView->Camera()->Copy (aCameraBack);
8780 }
8781
8782 if (aPts >= anUpperPts)
8783 {
8784 anAnimation->Pause();
8785 break;
8786 }
8787
8788 if (aView->IsInvalidated())
8789 {
8790 aView->Redraw();
8791 }
8792 else
8793 {
8794 aView->RedrawImmediate();
8795 }
8796
8797 if (!isLockLoop)
8798 {
8799 // handle user events
8800 theDI.Eval ("after 1 set waiter 1");
8801 theDI.Eval ("vwait waiter");
8802 }
8803 if (!TheIsAnimating)
8804 {
8805 anAnimation->Pause();
8806 theDI << aPts;
8807 break;
8808 }
8809 }
8810
8811 if (aView->IsInvalidated())
8812 {
8813 aView->Redraw();
197ac94e 8814 }
8815 else
8816 {
1beb58d7 8817 aView->RedrawImmediate();
197ac94e 8818 }
8819 }
1beb58d7 8820 else
197ac94e 8821 {
bf7b2ceb 8822 OSD_Timer aPerfTimer;
8823 aPerfTimer.Start();
1beb58d7 8824
08f8a185 8825 Handle(Image_VideoRecorder) aRecorder;
8826 ImageFlipper aFlipper;
8827 Handle(Draw_ProgressIndicator) aProgress;
8828 if (!aRecFile.IsEmpty())
8829 {
8830 if (aRecParams.Width <= 0
8831 || aRecParams.Height <= 0)
8832 {
8833 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8834 }
8835
8836 aRecorder = new Image_VideoRecorder();
8837 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8838 {
23fe70ec 8839 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8840 return 0;
8841 }
8842
8843 aProgress = new Draw_ProgressIndicator (theDI, 1);
8844 }
8845
1beb58d7 8846 // Manage frame-rated animation here
8847 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8848 int64_t aNbFrames = 0;
7e785937 8849 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8850 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8851 Standard_Integer aSecondsProgress = 0;
7e785937 8852 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8853 {
08f8a185 8854 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8855 aPts = aPlayStartTime + aRecPts;
8856 ++aNbFrames;
1beb58d7 8857 if (!anAnimation->Update (aPts))
8858 {
8859 break;
8860 }
8861
08f8a185 8862 if (!aRecorder.IsNull())
8863 {
8864 V3d_ImageDumpOptions aDumpParams;
8865 aDumpParams.Width = aRecParams.Width;
8866 aDumpParams.Height = aRecParams.Height;
8867 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8868 aDumpParams.StereoOptions = V3d_SDO_MONO;
8869 aDumpParams.ToAdjustAspect = Standard_True;
8870 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8871 {
23fe70ec 8872 Message::SendFail ("Error: view dump is failed");
08f8a185 8873 return 0;
8874 }
8875 aFlipper.FlipY (aRecorder->ChangeFrame());
8876 if (!aRecorder->PushFrame())
8877 {
8878 return 0;
8879 }
8880 }
8881 else
8882 {
8883 aView->Redraw();
8884 }
8885
8886 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8887 {
7e785937 8888 aPS.Next();
08f8a185 8889 ++aSecondsProgress;
8890 }
197ac94e 8891 }
bf7b2ceb 8892
8893 aPerfTimer.Stop();
1beb58d7 8894 anAnimation->Stop();
bf7b2ceb 8895 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8896 theDI << "Average FPS: " << aRecFps << "\n"
8897 << "Nb. Frames: " << Standard_Real(aNbFrames);
8898
8899 aView->Redraw();
197ac94e 8900 }
8901
1beb58d7 8902 aView->SetImmediateUpdate (wasImmediateUpdate);
8903 TheIsAnimating = Standard_False;
4754e164 8904 return 0;
8905}
8906
1beb58d7 8907
4754e164 8908//=======================================================================
8909//function : VChangeSelected
dc3fe572 8910//purpose : Adds the shape to selection or remove one from it
4754e164 8911//=======================================================================
8912static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8913 Standard_Integer argc,
8914 const char ** argv)
8915{
8916 if(argc != 2)
8917 {
8918 di<<"Usage : " << argv[0] << " shape \n";
8919 return 1;
8920 }
8921 //get AIS_Shape:
4754e164 8922 TCollection_AsciiString aName(argv[1]);
8923 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8924 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8925 || anAISObject.IsNull())
4754e164 8926 {
8927 di<<"Use 'vdisplay' before";
8928 return 1;
8929 }
4754e164 8930
8f521168 8931 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8932 return 0;
8933}
8934
4754e164 8935//=======================================================================
8936//function : VNbSelected
dc3fe572 8937//purpose : Returns number of selected objects
4754e164 8938//=======================================================================
8939static Standard_Integer VNbSelected (Draw_Interpretor& di,
8940 Standard_Integer argc,
8941 const char ** argv)
8942{
8943 if(argc != 1)
8944 {
8945 di << "Usage : " << argv[0] << "\n";
8946 return 1;
8947 }
8948 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8949 if(aContext.IsNull())
8950 {
8951 di << "use 'vinit' command before " << argv[0] << "\n";
8952 return 1;
8953 }
8954 di << aContext->NbSelected() << "\n";
8955 return 0;
8956}
8957
4754e164 8958//=======================================================================
8959//function : VSetViewSize
8960//purpose :
8961//=======================================================================
8962static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8963 Standard_Integer argc,
8964 const char ** argv)
8965{
8966 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8967 if(aContext.IsNull())
8968 {
8969 di << "use 'vinit' command before " << argv[0] << "\n";
8970 return 1;
8971 }
8972 if(argc != 2)
8973 {
8974 di<<"Usage : " << argv[0] << " Size\n";
8975 return 1;
8976 }
6b62b2da 8977 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8978 if (aSize <= 0.)
8979 {
8980 di<<"Bad Size value : " << aSize << "\n";
8981 return 1;
8982 }
8983
8984 Handle(V3d_View) aView = ViewerTest::CurrentView();
8985 aView->SetSize(aSize);
8986 return 0;
8987}
8988
8989//=======================================================================
8990//function : VMoveView
8991//purpose :
8992//=======================================================================
8993static Standard_Integer VMoveView (Draw_Interpretor& di,
8994 Standard_Integer argc,
8995 const char ** argv)
8996{
8997 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8998 if(aContext.IsNull())
8999 {
9000 di << "use 'vinit' command before " << argv[0] << "\n";
9001 return 1;
9002 }
9003 if(argc < 4 || argc > 5)
9004 {
9005 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9006 return 1;
9007 }
6b62b2da 9008 Standard_Real Dx = Draw::Atof (argv[1]);
9009 Standard_Real Dy = Draw::Atof (argv[2]);
9010 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 9011 Standard_Boolean aStart = Standard_True;
9012 if (argc == 5)
9013 {
6b62b2da 9014 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9015 }
9016
9017 Handle(V3d_View) aView = ViewerTest::CurrentView();
9018 aView->Move(Dx,Dy,Dz,aStart);
9019 return 0;
9020}
9021
9022//=======================================================================
9023//function : VTranslateView
9024//purpose :
9025//=======================================================================
9026static Standard_Integer VTranslateView (Draw_Interpretor& di,
9027 Standard_Integer argc,
9028 const char ** argv)
9029{
9030 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9031 if(aContext.IsNull())
9032 {
9033 di << "use 'vinit' command before " << argv[0] << "\n";
9034 return 1;
9035 }
9036 if(argc < 4 || argc > 5)
9037 {
9038 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9039 return 1;
9040 }
6b62b2da 9041 Standard_Real Dx = Draw::Atof (argv[1]);
9042 Standard_Real Dy = Draw::Atof (argv[2]);
9043 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 9044 Standard_Boolean aStart = Standard_True;
dc3fe572 9045 if (argc == 5)
4754e164 9046 {
6b62b2da 9047 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9048 }
9049
9050 Handle(V3d_View) aView = ViewerTest::CurrentView();
9051 aView->Translate(Dx,Dy,Dz,aStart);
9052 return 0;
9053}
9054
9055//=======================================================================
9056//function : VTurnView
9057//purpose :
9058//=======================================================================
9059static Standard_Integer VTurnView (Draw_Interpretor& di,
9060 Standard_Integer argc,
9061 const char ** argv)
9062{
9063 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9064 if(aContext.IsNull()) {
9065 di << "use 'vinit' command before " << argv[0] << "\n";
9066 return 1;
9067 }
9068 if(argc < 4 || argc > 5){
9069 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
9070 return 1;
9071 }
6b62b2da 9072 Standard_Real Ax = Draw::Atof (argv[1]);
9073 Standard_Real Ay = Draw::Atof (argv[2]);
9074 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 9075 Standard_Boolean aStart = Standard_True;
dc3fe572 9076 if (argc == 5)
4754e164 9077 {
6b62b2da 9078 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9079 }
9080
9081 Handle(V3d_View) aView = ViewerTest::CurrentView();
9082 aView->Turn(Ax,Ay,Az,aStart);
9083 return 0;
9084}
9085
269294d6 9086//==============================================================================
9087//function : VTextureEnv
9088//purpose : ENables or disables environment mapping
9089//==============================================================================
9090class OCC_TextureEnv : public Graphic3d_TextureEnv
9091{
9092public:
9093 OCC_TextureEnv(const Standard_CString FileName);
9094 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
9095 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
9096 const Standard_Boolean theModulateFlag,
9097 const Graphic3d_TypeOfTextureFilter theFilter,
9098 const Standard_ShortReal theXScale,
9099 const Standard_ShortReal theYScale,
9100 const Standard_ShortReal theXShift,
9101 const Standard_ShortReal theYShift,
9102 const Standard_ShortReal theAngle);
68858c7d 9103 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 9104};
a3f6f591 9105DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 9106
269294d6 9107OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
9108 : Graphic3d_TextureEnv(theFileName)
9109{
9110}
9111
9112OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
9113 : Graphic3d_TextureEnv(theTexId)
9114{
9115}
9116
9117void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
9118 const Standard_Boolean theModulateFlag,
9119 const Graphic3d_TypeOfTextureFilter theFilter,
9120 const Standard_ShortReal theXScale,
9121 const Standard_ShortReal theYScale,
9122 const Standard_ShortReal theXShift,
9123 const Standard_ShortReal theYShift,
9124 const Standard_ShortReal theAngle)
9125{
9126 myParams->SetRepeat (theRepeatFlag);
9127 myParams->SetModulate (theModulateFlag);
9128 myParams->SetFilter (theFilter);
9129 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
9130 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
9131 myParams->SetRotation (theAngle);
9132}
9133
35e08fe8 9134static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 9135{
9136 // get the active view
9137 Handle(V3d_View) aView = ViewerTest::CurrentView();
9138 if (aView.IsNull())
9139 {
23fe70ec 9140 Message::SendFail ("Error: no active viewer");
269294d6 9141 return 1;
9142 }
9143
9144 // Checking the input arguments
9145 Standard_Boolean anEnableFlag = Standard_False;
9146 Standard_Boolean isOk = theArgNb >= 2;
9147 if (isOk)
9148 {
9149 TCollection_AsciiString anEnableOpt(theArgVec[1]);
9150 anEnableFlag = anEnableOpt.IsEqual("on");
9151 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
9152 }
9153 if (anEnableFlag)
9154 {
9155 isOk = (theArgNb == 3 || theArgNb == 11);
9156 if (isOk)
9157 {
9158 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9159 isOk = (!aTextureOpt.IsIntegerValue() ||
9160 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
9161
9162 if (isOk && theArgNb == 11)
9163 {
9164 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
9165 aModulateOpt(theArgVec[4]),
9166 aFilterOpt (theArgVec[5]),
9167 aSScaleOpt (theArgVec[6]),
9168 aTScaleOpt (theArgVec[7]),
9169 aSTransOpt (theArgVec[8]),
9170 aTTransOpt (theArgVec[9]),
9171 anAngleOpt (theArgVec[10]);
9172 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
9173 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
9174 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
d45edf24 9175 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
9176 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
9177 anAngleOpt.IsRealValue (Standard_True));
269294d6 9178 }
9179 }
9180 }
9181
9182 if (!isOk)
9183 {
23fe70ec 9184 Message::SendFail() << "Usage:\n"
9185 << theArgVec[0] << " off\n"
9186 << 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 9187 return 1;
9188 }
9189
9190 if (anEnableFlag)
9191 {
9192 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9193 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
9194 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
9195 new OCC_TextureEnv(theArgVec[2]);
9196
9197 if (theArgNb == 11)
9198 {
9199 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
9200 aTexEnv->SetTextureParameters(
9201 aRepeatOpt. IsEqual("repeat"),
9202 aModulateOpt.IsEqual("modulate"),
9203 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
9204 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
9205 Graphic3d_TOTF_TRILINEAR,
9206 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
9207 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
9208 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
9209 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
9210 (Standard_ShortReal)Draw::Atof(theArgVec[10])
9211 );
9212 }
9213 aView->SetTextureEnv(aTexEnv);
269294d6 9214 }
9215 else // Disabling environment mapping
9216 {
269294d6 9217 Handle(Graphic3d_TextureEnv) aTexture;
9218 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
9219 }
9220
9221 aView->Redraw();
9222 return 0;
9223}
9224
3e05329c 9225namespace
9226{
9227 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
9228
9229 //! Remove registered clipping plane from all views and objects.
9230 static void removePlane (MapOfPlanes& theRegPlanes,
9231 const TCollection_AsciiString& theName)
9232 {
9233 Handle(Graphic3d_ClipPlane) aClipPlane;
9234 if (!theRegPlanes.Find (theName, aClipPlane))
9235 {
23fe70ec 9236 Message::SendWarning ("Warning: no such plane");
3e05329c 9237 return;
9238 }
9239
9240 theRegPlanes.UnBind (theName);
9241 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
9242 anIObjIt.More(); anIObjIt.Next())
9243 {
8f521168 9244 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 9245 aPrs->RemoveClipPlane (aClipPlane);
9246 }
9247
9248 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
9249 aViewIt.More(); aViewIt.Next())
9250 {
9251 const Handle(V3d_View)& aView = aViewIt.Key2();
9252 aView->RemoveClipPlane(aClipPlane);
9253 }
9254
9255 ViewerTest::RedrawAllViews();
9256 }
9257}
9258
4269bd1b 9259//===============================================================================================
9260//function : VClipPlane
9261//purpose :
9262//===============================================================================================
9263static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9264{
9265 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 9266 static MapOfPlanes aRegPlanes;
9267
9268 if (theArgsNb < 2)
9269 {
3e05329c 9270 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
9271 {
9272 theDi << aPlaneIter.Key() << " ";
9273 }
9274 return 0;
4269bd1b 9275 }
9276
9277 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 9278 aCommand.LowerCase();
9279 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
9280 if (anActiveView.IsNull())
9281 {
23fe70ec 9282 Message::SendFail ("Error: no active viewer");
3e05329c 9283 return 1;
9284 }
4269bd1b 9285
9286 // print maximum number of planes for current viewer
3e05329c 9287 if (aCommand == "-maxplanes"
9288 || aCommand == "maxplanes")
4269bd1b 9289 {
3e05329c 9290 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
9291 << " plane slots provided by driver.\n";
4269bd1b 9292 return 0;
9293 }
9294
9295 // create / delete plane instance
3e05329c 9296 if (aCommand == "-create"
9297 || aCommand == "create"
9298 || aCommand == "-delete"
9299 || aCommand == "delete"
9300 || aCommand == "-clone"
9301 || aCommand == "clone")
4269bd1b 9302 {
9303 if (theArgsNb < 3)
9304 {
23fe70ec 9305 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 9306 return 1;
9307 }
9308
3e05329c 9309 Standard_Boolean toCreate = aCommand == "-create"
9310 || aCommand == "create";
9311 Standard_Boolean toClone = aCommand == "-clone"
9312 || aCommand == "clone";
9313 Standard_Boolean toDelete = aCommand == "-delete"
9314 || aCommand == "delete";
4269bd1b 9315 TCollection_AsciiString aPlane (theArgVec[2]);
9316
9317 if (toCreate)
9318 {
9319 if (aRegPlanes.IsBound (aPlane))
9320 {
3e05329c 9321 std::cout << "Warning: existing plane has been overridden.\n";
9322 toDelete = true;
9323 }
9324 else
9325 {
9326 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9327 return 0;
4269bd1b 9328 }
4269bd1b 9329 }
9330 else if (toClone) // toClone
9331 {
9332 if (!aRegPlanes.IsBound (aPlane))
9333 {
23fe70ec 9334 Message::SendFail ("Error: no such plane");
4269bd1b 9335 return 1;
9336 }
3e05329c 9337 else if (theArgsNb < 4)
4269bd1b 9338 {
23fe70ec 9339 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 9340 return 1;
9341 }
9342
9343 TCollection_AsciiString aClone (theArgVec[3]);
9344 if (aRegPlanes.IsBound (aClone))
9345 {
23fe70ec 9346 Message::SendFail ("Error: plane name is in use");
4269bd1b 9347 return 1;
9348 }
9349
9350 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
9351
9352 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 9353 return 0;
4269bd1b 9354 }
4269bd1b 9355
3e05329c 9356 if (toDelete)
9357 {
9358 if (aPlane == "ALL"
9359 || aPlane == "all"
9360 || aPlane == "*")
4269bd1b 9361 {
3e05329c 9362 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
9363 {
9364 aPlane = aPlaneIter.Key();
9365 removePlane (aRegPlanes, aPlane);
9366 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
9367 }
4269bd1b 9368 }
3e05329c 9369 else
4269bd1b 9370 {
3e05329c 9371 removePlane (aRegPlanes, aPlane);
4269bd1b 9372 }
4269bd1b 9373 }
9374
3e05329c 9375 if (toCreate)
9376 {
9377 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9378 }
4269bd1b 9379 return 0;
9380 }
9381
9382 // set / unset plane command
3e05329c 9383 if (aCommand == "set"
9384 || aCommand == "unset")
4269bd1b 9385 {
3e05329c 9386 if (theArgsNb < 5)
4269bd1b 9387 {
23fe70ec 9388 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9389 return 1;
9390 }
9391
3e05329c 9392 // redirect to new syntax
9393 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
9394 anArgVec.SetValue (1, theArgVec[0]);
9395 anArgVec.SetValue (2, theArgVec[2]);
9396 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
9397 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 9398 {
3e05329c 9399 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 9400 }
9401
3e05329c 9402 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 9403 }
9404
9405 // change plane command
3e05329c 9406 TCollection_AsciiString aPlaneName;
9407 Handle(Graphic3d_ClipPlane) aClipPlane;
9408 Standard_Integer anArgIter = 0;
9409 if (aCommand == "-change"
9410 || aCommand == "change")
4269bd1b 9411 {
3e05329c 9412 // old syntax support
9413 if (theArgsNb < 3)
4269bd1b 9414 {
23fe70ec 9415 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9416 return 1;
9417 }
9418
3e05329c 9419 anArgIter = 3;
9420 aPlaneName = theArgVec[2];
9421 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 9422 {
23fe70ec 9423 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 9424 return 1;
9425 }
3e05329c 9426 }
9427 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9428 {
9429 anArgIter = 2;
9430 aPlaneName = theArgVec[1];
9431 }
9432 else
9433 {
9434 anArgIter = 2;
9435 aPlaneName = theArgVec[1];
9436 aClipPlane = new Graphic3d_ClipPlane();
9437 aRegPlanes.Bind (aPlaneName, aClipPlane);
9438 theDi << "Created new plane " << aPlaneName << ".\n";
9439 }
4269bd1b 9440
3e05329c 9441 if (theArgsNb - anArgIter < 1)
9442 {
23fe70ec 9443 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9444 return 1;
9445 }
4269bd1b 9446
3e05329c 9447 for (; anArgIter < theArgsNb; ++anArgIter)
9448 {
9449 const char** aChangeArgs = theArgVec + anArgIter;
9450 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9451 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9452 aChangeArg.LowerCase();
4269bd1b 9453
3e05329c 9454 Standard_Boolean toEnable = Standard_True;
dae2a922 9455 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 9456 {
3e05329c 9457 aClipPlane->SetOn (toEnable);
4269bd1b 9458 }
25c35042 9459 else if (aChangeArg.StartsWith ("-equation")
9460 || aChangeArg.StartsWith ("equation"))
4269bd1b 9461 {
3e05329c 9462 if (aNbChangeArgs < 5)
4269bd1b 9463 {
23fe70ec 9464 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9465 return 1;
9466 }
9467
25c35042 9468 Standard_Integer aSubIndex = 1;
9469 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9470 if (aPrefixLen < aChangeArg.Length())
9471 {
9472 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9473 if (!aSubStr.IsIntegerValue()
9474 || aSubStr.IntegerValue() <= 0)
9475 {
23fe70ec 9476 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9477 return 1;
9478 }
9479 aSubIndex = aSubStr.IntegerValue();
9480 }
9481
9482 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9483 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9484 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9485 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9486 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9487 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9488 {
9489 if (aSubPln->ChainNextPlane().IsNull())
9490 {
9491 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9492 }
9493 aSubPln = aSubPln->ChainNextPlane();
9494 }
9495 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9496 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9497 anArgIter += 4;
4269bd1b 9498 }
25c35042 9499 else if ((aChangeArg == "-boxinterior"
9500 || aChangeArg == "-boxint"
9501 || aChangeArg == "-box")
9502 && aNbChangeArgs >= 7)
9503 {
9504 Graphic3d_BndBox3d aBndBox;
9505 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9506 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9507 anArgIter += 6;
9508
9509 Standard_Integer aNbSubPlanes = 6;
9510 const Graphic3d_Vec3d aDirArray[6] =
9511 {
9512 Graphic3d_Vec3d (-1, 0, 0),
9513 Graphic3d_Vec3d ( 1, 0, 0),
9514 Graphic3d_Vec3d ( 0,-1, 0),
9515 Graphic3d_Vec3d ( 0, 1, 0),
9516 Graphic3d_Vec3d ( 0, 0,-1),
9517 Graphic3d_Vec3d ( 0, 0, 1),
9518 };
9519 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9520 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9521 {
9522 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9523 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9524 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9525 if (aSubPlaneIter + 1 == aNbSubPlanes)
9526 {
9527 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9528 }
9529 else
9530 {
9531 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9532 }
9533 aSubPln = aSubPln->ChainNextPlane();
9534 }
9535 }
3e05329c 9536 else if (aChangeArg == "-capping"
9537 || aChangeArg == "capping")
4269bd1b 9538 {
3e05329c 9539 if (aNbChangeArgs < 2)
4269bd1b 9540 {
23fe70ec 9541 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9542 return 1;
9543 }
9544
dae2a922 9545 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9546 {
3e05329c 9547 aClipPlane->SetCapping (toEnable);
9548 anArgIter += 1;
9549 }
9550 else
9551 {
9552 // just skip otherwise (old syntax)
9553 }
9554 }
9555 else if (aChangeArg == "-useobjectmaterial"
9556 || aChangeArg == "-useobjectmat"
9557 || aChangeArg == "-useobjmat"
9558 || aChangeArg == "-useobjmaterial")
9559 {
9560 if (aNbChangeArgs < 2)
9561 {
23fe70ec 9562 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9563 return 1;
9564 }
9565
dae2a922 9566 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9567 {
3e05329c 9568 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9569 anArgIter += 1;
4269bd1b 9570 }
3e05329c 9571 }
9572 else if (aChangeArg == "-useobjecttexture"
9573 || aChangeArg == "-useobjecttex"
9574 || aChangeArg == "-useobjtexture"
9575 || aChangeArg == "-useobjtex")
9576 {
9577 if (aNbChangeArgs < 2)
4269bd1b 9578 {
23fe70ec 9579 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9580 return 1;
9581 }
4269bd1b 9582
dae2a922 9583 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9584 {
9585 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9586 anArgIter += 1;
9587 }
9588 }
9589 else if (aChangeArg == "-useobjectshader"
9590 || aChangeArg == "-useobjshader")
9591 {
9592 if (aNbChangeArgs < 2)
9593 {
23fe70ec 9594 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9595 return 1;
9596 }
4269bd1b 9597
dae2a922 9598 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9599 {
9600 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9601 anArgIter += 1;
4269bd1b 9602 }
3e05329c 9603 }
9604 else if (aChangeArg == "-color"
9605 || aChangeArg == "color")
9606 {
9607 Quantity_Color aColor;
dae2a922 9608 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9609 aChangeArgs + 1,
9610 aColor);
3e05329c 9611 if (aNbParsed == 0)
4269bd1b 9612 {
23fe70ec 9613 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9614 return 1;
9615 }
61168418 9616 aClipPlane->SetCappingColor (aColor);
3e05329c 9617 anArgIter += aNbParsed;
9618 }
61168418 9619 else if (aNbChangeArgs >= 1
9620 && (aChangeArg == "-material"
9621 || aChangeArg == "material"))
9622 {
9623 ++anArgIter;
9624 Graphic3d_NameOfMaterial aMatName;
9625 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9626 {
23fe70ec 9627 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9628 return 1;
9629 }
9630 aClipPlane->SetCappingMaterial (aMatName);
9631 }
1b661a81 9632 else if ((aChangeArg == "-transparency"
9633 || aChangeArg == "-transp")
9634 && aNbChangeArgs >= 2)
9635 {
9636 TCollection_AsciiString aValStr (aChangeArgs[1]);
9637 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
d45edf24 9638 if (aValStr.IsRealValue (Standard_True))
1b661a81 9639 {
9640 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9641 aMat.SetTransparency ((float )aValStr.RealValue());
9642 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9643 aClipPlane->SetCappingMaterial (aMat);
9644 }
9645 else
9646 {
9647 aValStr.LowerCase();
9648 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9649 if (aValStr == "opaque")
9650 {
9651 aMode = Graphic3d_AlphaMode_Opaque;
9652 }
9653 else if (aValStr == "mask")
9654 {
9655 aMode = Graphic3d_AlphaMode_Mask;
9656 }
9657 else if (aValStr == "blend")
9658 {
9659 aMode = Graphic3d_AlphaMode_Blend;
9660 }
33425a46 9661 else if (aValStr == "maskblend"
9662 || aValStr == "blendmask")
9663 {
9664 aMode = Graphic3d_AlphaMode_MaskBlend;
9665 }
1b661a81 9666 else if (aValStr == "blendauto")
9667 {
9668 aMode = Graphic3d_AlphaMode_BlendAuto;
9669 }
9670 else
9671 {
23fe70ec 9672 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9673 return 1;
9674 }
9675 anAspect->SetAlphaMode (aMode);
9676 aClipPlane->SetCappingAspect (anAspect);
9677 }
9678 anArgIter += 1;
9679 }
3e05329c 9680 else if (aChangeArg == "-texname"
9681 || aChangeArg == "texname")
9682 {
9683 if (aNbChangeArgs < 2)
9684 {
23fe70ec 9685 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9686 return 1;
9687 }
4269bd1b 9688
3e05329c 9689 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9690 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9691 if (!aTexture->IsDone())
9692 {
9693 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9694 }
3e05329c 9695 else
4269bd1b 9696 {
3e05329c 9697 aTexture->EnableModulate();
9698 aTexture->EnableRepeat();
9699 aClipPlane->SetCappingTexture (aTexture);
9700 }
9701 anArgIter += 1;
9702 }
9703 else if (aChangeArg == "-texscale"
9704 || aChangeArg == "texscale")
9705 {
9706 if (aClipPlane->CappingTexture().IsNull())
9707 {
23fe70ec 9708 Message::SendFail ("Error: no texture is set");
3e05329c 9709 return 1;
9710 }
4269bd1b 9711
3e05329c 9712 if (aNbChangeArgs < 3)
9713 {
23fe70ec 9714 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9715 return 1;
9716 }
4269bd1b 9717
3e05329c 9718 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9719 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9720 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9721 anArgIter += 2;
9722 }
9723 else if (aChangeArg == "-texorigin"
9724 || aChangeArg == "texorigin") // texture origin
9725 {
9726 if (aClipPlane->CappingTexture().IsNull())
9727 {
23fe70ec 9728 Message::SendFail ("Error: no texture is set");
3e05329c 9729 return 1;
9730 }
4269bd1b 9731
3e05329c 9732 if (aNbChangeArgs < 3)
9733 {
23fe70ec 9734 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9735 return 1;
4269bd1b 9736 }
3e05329c 9737
9738 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9739 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9740
9741 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9742 anArgIter += 2;
9743 }
9744 else if (aChangeArg == "-texrotate"
9745 || aChangeArg == "texrotate") // texture rotation
9746 {
9747 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9748 {
23fe70ec 9749 Message::SendFail ("Error: no texture is set");
3e05329c 9750 return 1;
9751 }
4269bd1b 9752
3e05329c 9753 if (aNbChangeArgs < 2)
9754 {
23fe70ec 9755 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9756 return 1;
9757 }
4269bd1b 9758
3e05329c 9759 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9760 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9761 anArgIter += 1;
9762 }
9763 else if (aChangeArg == "-hatch"
9764 || aChangeArg == "hatch")
9765 {
9766 if (aNbChangeArgs < 2)
9767 {
23fe70ec 9768 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9769 return 1;
9770 }
4269bd1b 9771
3e05329c 9772 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9773 aHatchStr.LowerCase();
9774 if (aHatchStr == "on")
9775 {
9776 aClipPlane->SetCappingHatchOn();
9777 }
9778 else if (aHatchStr == "off")
9779 {
9780 aClipPlane->SetCappingHatchOff();
4269bd1b 9781 }
3e05329c 9782 else
4269bd1b 9783 {
3e05329c 9784 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9785 }
9786 anArgIter += 1;
9787 }
9788 else if (aChangeArg == "-delete"
9789 || aChangeArg == "delete")
9790 {
9791 removePlane (aRegPlanes, aPlaneName);
9792 return 0;
9793 }
9794 else if (aChangeArg == "-set"
32ca7711 9795 || aChangeArg == "-unset"
9796 || aChangeArg == "-setoverrideglobal")
3e05329c 9797 {
9798 // set / unset plane command
32ca7711 9799 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9800 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9801 Standard_Integer anIt = 1;
9802 for (; anIt < aNbChangeArgs; ++anIt)
9803 {
9804 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9805 if (anEntityName.IsEmpty()
9806 || anEntityName.Value (1) == '-')
4269bd1b 9807 {
3e05329c 9808 break;
4269bd1b 9809 }
32ca7711 9810 else if (!toOverrideGlobal
9811 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9812 {
3e05329c 9813 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9814 if (toSet)
9815 {
9816 aView->AddClipPlane (aClipPlane);
9817 }
9818 else
9819 {
9820 aView->RemoveClipPlane (aClipPlane);
9821 }
9822 continue;
4269bd1b 9823 }
3e05329c 9824 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9825 {
8f521168 9826 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9827 if (toSet)
9828 {
9829 aIObj->AddClipPlane (aClipPlane);
9830 }
9831 else
9832 {
9833 aIObj->RemoveClipPlane (aClipPlane);
9834 }
32ca7711 9835 if (!aIObj->ClipPlanes().IsNull())
9836 {
9837 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9838 }
4269bd1b 9839 }
3e05329c 9840 else
4269bd1b 9841 {
23fe70ec 9842 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9843 return 1;
4269bd1b 9844 }
3e05329c 9845 }
9846
9847 if (anIt == 1)
9848 {
9849 // apply to active view
9850 if (toSet)
4269bd1b 9851 {
3e05329c 9852 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9853 }
9854 else
9855 {
3e05329c 9856 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9857 }
9858 }
3e05329c 9859 else
9860 {
9861 anArgIter = anArgIter + anIt - 1;
9862 }
9863 }
9864 else
9865 {
23fe70ec 9866 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9867 return 1;
4269bd1b 9868 }
4269bd1b 9869 }
9870
3e05329c 9871 ViewerTest::RedrawAllViews();
9872 return 0;
4269bd1b 9873}
9874
b5ac8292 9875//===============================================================================================
9876//function : VZRange
9877//purpose :
9878//===============================================================================================
9879static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9880{
197ac94e 9881 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9882
9883 if (aCurrentView.IsNull())
b5ac8292 9884 {
23fe70ec 9885 Message::SendFail ("Error: no active viewer");
b5ac8292 9886 return 1;
9887 }
9888
197ac94e 9889 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9890
9891 if (theArgsNb < 2)
9892 {
9893 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9894 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9895 return 0;
9896 }
9897
9898 if (theArgsNb == 3)
9899 {
6b62b2da 9900 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9901 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9902
9903 if (aNewZNear >= aNewZFar)
9904 {
23fe70ec 9905 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9906 return 1;
9907 }
9908
9909 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9910 {
23fe70ec 9911 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9912 return 1;
9913 }
9914
9915 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9916 }
9917 else
9918 {
23fe70ec 9919 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9920 return 1;
9921 }
9922
197ac94e 9923 aCurrentView->Redraw();
9924
b5ac8292 9925 return 0;
9926}
9927
9928//===============================================================================================
9929//function : VAutoZFit
9930//purpose :
9931//===============================================================================================
9932static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9933{
197ac94e 9934 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9935
9936 if (aCurrentView.IsNull())
b5ac8292 9937 {
23fe70ec 9938 Message::SendFail ("Error: no active viewer");
b5ac8292 9939 return 1;
9940 }
9941
c357e426 9942 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9943
9944 if (theArgsNb > 3)
b5ac8292 9945 {
23fe70ec 9946 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9947 return 1;
b5ac8292 9948 }
9949
197ac94e 9950 if (theArgsNb < 2)
b5ac8292 9951 {
586db386 9952 theDi << "Auto z-fit mode: \n"
c357e426 9953 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9954 << "Scale: " << aScale << "\n";
9955 return 0;
b5ac8292 9956 }
197ac94e 9957
9958 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9959
9960 if (theArgsNb >= 3)
b5ac8292 9961 {
197ac94e 9962 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9963 }
9964
c357e426 9965 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9966 aCurrentView->Redraw();
b5ac8292 9967 return 0;
9968}
9969
6b62b2da 9970//! Auxiliary function to print projection type
9971inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9972{
9973 switch (theProjType)
9974 {
9975 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9976 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9977 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9978 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9979 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9980 }
9981 return "UNKNOWN";
9982}
9983
b5ac8292 9984//===============================================================================================
6b62b2da 9985//function : VCamera
b5ac8292 9986//purpose :
9987//===============================================================================================
6b62b2da 9988static int VCamera (Draw_Interpretor& theDI,
9989 Standard_Integer theArgsNb,
9990 const char** theArgVec)
b5ac8292 9991{
6b62b2da 9992 Handle(V3d_View) aView = ViewerTest::CurrentView();
9993 if (aView.IsNull())
b5ac8292 9994 {
23fe70ec 9995 Message::SendFail ("Error: no active viewer");
b5ac8292 9996 return 1;
9997 }
9998
6b62b2da 9999 Handle(Graphic3d_Camera) aCamera = aView->Camera();
10000 if (theArgsNb < 2)
b5ac8292 10001 {
6b62b2da 10002 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
10003 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 10004 theDI << "FOVx: " << aCamera->FOVx() << "\n";
10005 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 10006 theDI << "Distance: " << aCamera->Distance() << "\n";
10007 theDI << "IOD: " << aCamera->IOD() << "\n";
10008 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
10009 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
10010 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
10011 return 0;
b5ac8292 10012 }
10013
30a1b24e 10014 TCollection_AsciiString aPrsName;
6b62b2da 10015 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 10016 {
6b62b2da 10017 Standard_CString anArg = theArgVec[anArgIter];
10018 TCollection_AsciiString anArgCase (anArg);
10019 anArgCase.LowerCase();
10020 if (anArgCase == "-proj"
10021 || anArgCase == "-projection"
10022 || anArgCase == "-projtype"
10023 || anArgCase == "-projectiontype")
10024 {
10025 theDI << projTypeName (aCamera->ProjectionType()) << " ";
10026 }
10027 else if (anArgCase == "-ortho"
10028 || anArgCase == "-orthographic")
b5ac8292 10029 {
10030 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 10031 }
10032 else if (anArgCase == "-persp"
10033 || anArgCase == "-perspective"
10034 || anArgCase == "-perspmono"
10035 || anArgCase == "-perspectivemono"
10036 || anArgCase == "-mono")
b5ac8292 10037 {
10038 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10039 }
6b62b2da 10040 else if (anArgCase == "-stereo"
10041 || anArgCase == "-stereoscopic"
10042 || anArgCase == "-perspstereo"
10043 || anArgCase == "-perspectivestereo")
10044 {
10045 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10046 }
10047 else if (anArgCase == "-left"
10048 || anArgCase == "-lefteye"
10049 || anArgCase == "-monoleft"
10050 || anArgCase == "-monolefteye"
10051 || anArgCase == "-perpsleft"
10052 || anArgCase == "-perpslefteye")
b5ac8292 10053 {
10054 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
10055 }
6b62b2da 10056 else if (anArgCase == "-right"
10057 || anArgCase == "-righteye"
10058 || anArgCase == "-monoright"
10059 || anArgCase == "-monorighteye"
10060 || anArgCase == "-perpsright")
b5ac8292 10061 {
10062 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
10063 }
6b62b2da 10064 else if (anArgCase == "-dist"
10065 || anArgCase == "-distance")
b5ac8292 10066 {
6b62b2da 10067 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10068 if (anArgValue != NULL
10069 && *anArgValue != '-')
10070 {
10071 ++anArgIter;
10072 aCamera->SetDistance (Draw::Atof (anArgValue));
10073 continue;
10074 }
10075 theDI << aCamera->Distance() << " ";
b5ac8292 10076 }
6b62b2da 10077 else if (anArgCase == "-iod")
b5ac8292 10078 {
6b62b2da 10079 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10080 if (anArgValue != NULL
10081 && *anArgValue != '-')
10082 {
10083 ++anArgIter;
10084 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
10085 continue;
10086 }
10087 theDI << aCamera->IOD() << " ";
b5ac8292 10088 }
6b62b2da 10089 else if (anArgCase == "-iodtype")
b5ac8292 10090 {
6b62b2da 10091 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10092 TCollection_AsciiString anValueCase (anArgValue);
10093 anValueCase.LowerCase();
10094 if (anValueCase == "abs"
10095 || anValueCase == "absolute")
10096 {
10097 ++anArgIter;
10098 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
10099 continue;
10100 }
10101 else if (anValueCase == "rel"
10102 || anValueCase == "relative")
10103 {
10104 ++anArgIter;
10105 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
10106 continue;
10107 }
10108 else if (*anArgValue != '-')
10109 {
23fe70ec 10110 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 10111 return 1;
10112 }
10113 switch (aCamera->GetIODType())
10114 {
10115 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
10116 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
10117 }
b5ac8292 10118 }
6b62b2da 10119 else if (anArgCase == "-zfocus")
b5ac8292 10120 {
6b62b2da 10121 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10122 if (anArgValue != NULL
10123 && *anArgValue != '-')
10124 {
10125 ++anArgIter;
10126 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
10127 continue;
10128 }
10129 theDI << aCamera->ZFocus() << " ";
b5ac8292 10130 }
6b62b2da 10131 else if (anArgCase == "-zfocustype")
b5ac8292 10132 {
6b62b2da 10133 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10134 TCollection_AsciiString anValueCase (anArgValue);
10135 anValueCase.LowerCase();
10136 if (anValueCase == "abs"
10137 || anValueCase == "absolute")
10138 {
10139 ++anArgIter;
10140 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
10141 continue;
10142 }
10143 else if (anValueCase == "rel"
10144 || anValueCase == "relative")
10145 {
10146 ++anArgIter;
10147 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
10148 continue;
10149 }
10150 else if (*anArgValue != '-')
10151 {
23fe70ec 10152 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 10153 return 1;
10154 }
10155 switch (aCamera->ZFocusType())
10156 {
10157 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
10158 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
10159 }
10160 }
b40cdc2b 10161 else if (anArgCase == "-lockzup"
10162 || anArgCase == "-turntable")
10163 {
10164 bool toLockUp = true;
10165 if (++anArgIter < theArgsNb
dae2a922 10166 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 10167 {
10168 --anArgIter;
10169 }
10170 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
10171 }
6b62b2da 10172 else if (anArgCase == "-fov"
b40cdc2b 10173 || anArgCase == "-fovy"
10174 || anArgCase == "-fovx"
10175 || anArgCase == "-fov2d")
b5ac8292 10176 {
6b62b2da 10177 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10178 if (anArgValue != NULL
10179 && *anArgValue != '-')
10180 {
10181 ++anArgIter;
b40cdc2b 10182 if (anArgCase == "-fov2d")
10183 {
10184 aCamera->SetFOV2d (Draw::Atof (anArgValue));
10185 }
10186 else if (anArgCase == "-fovx")
10187 {
10188 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
10189 }
10190 else
10191 {
10192 aCamera->SetFOVy (Draw::Atof (anArgValue));
10193 }
6b62b2da 10194 continue;
10195 }
b40cdc2b 10196 if (anArgCase == "-fov2d")
10197 {
10198 theDI << aCamera->FOV2d() << " ";
10199 }
10200 else if (anArgCase == "-fovx")
10201 {
10202 theDI << aCamera->FOVx() << " ";
10203 }
10204 else
10205 {
10206 theDI << aCamera->FOVy() << " ";
10207 }
10208 }
10209 else if (anArgIter + 1 < theArgsNb
10210 && anArgCase == "-xrpose")
10211 {
10212 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
10213 anXRArg.LowerCase();
10214 if (anXRArg == "base")
10215 {
10216 aCamera = aView->View()->BaseXRCamera();
10217 }
10218 else if (anXRArg == "head")
10219 {
10220 aCamera = aView->View()->PosedXRCamera();
10221 }
10222 else
10223 {
10224 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
10225 return 1;
10226 }
10227 if (aCamera.IsNull())
10228 {
10229 Message::SendFail() << "Error: undefined XR pose";
10230 return 0;
10231 }
10232 if (aView->AutoZFitMode())
10233 {
10234 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
10235 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
10236 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
10237 }
b5ac8292 10238 }
30a1b24e 10239 else if (aPrsName.IsEmpty()
10240 && !anArgCase.StartsWith ("-"))
10241 {
10242 aPrsName = anArg;
10243 }
b5ac8292 10244 else
10245 {
23fe70ec 10246 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 10247 return 1;
10248 }
10249 }
b5ac8292 10250
30a1b24e 10251 if (aPrsName.IsEmpty()
10252 || theArgsNb > 2)
10253 {
30a1b24e 10254 aView->Redraw();
10255 }
10256
10257 if (!aPrsName.IsEmpty())
10258 {
10259 Handle(AIS_CameraFrustum) aCameraFrustum;
10260 if (GetMapOfAIS().IsBound2 (aPrsName))
10261 {
10262 // find existing object
10263 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
10264 if (aCameraFrustum.IsNull())
10265 {
23fe70ec 10266 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 10267 return 1;
10268 }
10269 }
10270
10271 if (aCameraFrustum.IsNull())
10272 {
10273 aCameraFrustum = new AIS_CameraFrustum();
10274 }
10275 else
10276 {
10277 // not include displayed object of old camera frustum in the new one.
10278 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
10279 aView->ZFitAll();
10280 }
b40cdc2b 10281 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 10282
10283 ViewerTest::Display (aPrsName, aCameraFrustum);
10284 }
b5ac8292 10285
10286 return 0;
10287}
10288
f978241f 10289//! Parse stereo output mode
10290inline Standard_Boolean parseStereoMode (Standard_CString theArg,
10291 Graphic3d_StereoMode& theMode)
10292{
10293 TCollection_AsciiString aFlag (theArg);
10294 aFlag.LowerCase();
10295 if (aFlag == "quadbuffer")
10296 {
10297 theMode = Graphic3d_StereoMode_QuadBuffer;
10298 }
10299 else if (aFlag == "anaglyph")
10300 {
10301 theMode = Graphic3d_StereoMode_Anaglyph;
10302 }
10303 else if (aFlag == "row"
10304 || aFlag == "rowinterlaced")
10305 {
10306 theMode = Graphic3d_StereoMode_RowInterlaced;
10307 }
10308 else if (aFlag == "col"
10309 || aFlag == "colinterlaced"
10310 || aFlag == "columninterlaced")
10311 {
10312 theMode = Graphic3d_StereoMode_ColumnInterlaced;
10313 }
10314 else if (aFlag == "chess"
10315 || aFlag == "chessboard")
10316 {
10317 theMode = Graphic3d_StereoMode_ChessBoard;
10318 }
10319 else if (aFlag == "sbs"
10320 || aFlag == "sidebyside")
10321 {
10322 theMode = Graphic3d_StereoMode_SideBySide;
10323 }
10324 else if (aFlag == "ou"
10325 || aFlag == "overunder")
10326 {
10327 theMode = Graphic3d_StereoMode_OverUnder;
10328 }
10329 else if (aFlag == "pageflip"
10330 || aFlag == "softpageflip")
10331 {
10332 theMode = Graphic3d_StereoMode_SoftPageFlip;
10333 }
b40cdc2b 10334 else if (aFlag == "openvr"
10335 || aFlag == "vr")
10336 {
10337 theMode = Graphic3d_StereoMode_OpenVR;
10338 }
f978241f 10339 else
10340 {
10341 return Standard_False;
10342 }
10343 return Standard_True;
10344}
10345
10346//! Parse anaglyph filter
10347inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
10348 Graphic3d_RenderingParams::Anaglyph& theFilter)
10349{
10350 TCollection_AsciiString aFlag (theArg);
10351 aFlag.LowerCase();
10352 if (aFlag == "redcyansimple")
10353 {
10354 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10355 }
10356 else if (aFlag == "redcyan"
10357 || aFlag == "redcyanoptimized")
10358 {
10359 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
10360 }
10361 else if (aFlag == "yellowbluesimple")
10362 {
10363 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
10364 }
10365 else if (aFlag == "yellowblue"
10366 || aFlag == "yellowblueoptimized")
10367 {
10368 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
10369 }
10370 else if (aFlag == "greenmagenta"
10371 || aFlag == "greenmagentasimple")
10372 {
10373 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
10374 }
10375 else
10376 {
10377 return Standard_False;
10378 }
10379 return Standard_True;
10380}
10381
b5ac8292 10382//==============================================================================
10383//function : VStereo
10384//purpose :
10385//==============================================================================
10386
10387static int VStereo (Draw_Interpretor& theDI,
10388 Standard_Integer theArgNb,
10389 const char** theArgVec)
10390{
f978241f 10391 Handle(V3d_View) aView = ViewerTest::CurrentView();
b5ac8292 10392 if (theArgNb < 2)
10393 {
b5ac8292 10394 if (aView.IsNull())
10395 {
23fe70ec 10396 Message::SendFail ("Error: no active viewer");
b5ac8292 10397 return 0;
10398 }
10399
10400 Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
10401 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 10402 if (isActive)
10403 {
10404 TCollection_AsciiString aMode;
10405 switch (aView->RenderingParams().StereoMode)
10406 {
10407 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10408 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10409 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10410 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10411 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10412 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10413 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 10414 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 10415 case Graphic3d_StereoMode_Anaglyph :
10416 aMode = "anaglyph";
10417 switch (aView->RenderingParams().AnaglyphFilter)
10418 {
10419 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10420 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10421 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10422 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10423 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10424 default: break;
10425 }
10426 default: break;
10427 }
10428 theDI << "Mode " << aMode << "\n";
10429 }
b5ac8292 10430 return 0;
10431 }
10432
f978241f 10433 Handle(Graphic3d_Camera) aCamera;
10434 Graphic3d_RenderingParams* aParams = NULL;
10435 Graphic3d_StereoMode aMode = Graphic3d_StereoMode_QuadBuffer;
10436 if (!aView.IsNull())
10437 {
10438 aParams = &aView->ChangeRenderingParams();
10439 aMode = aParams->StereoMode;
10440 aCamera = aView->Camera();
10441 }
10442
10443 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10444 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10445 {
10446 Standard_CString anArg = theArgVec[anArgIter];
10447 TCollection_AsciiString aFlag (anArg);
10448 aFlag.LowerCase();
10449 if (anUpdateTool.parseRedrawMode (aFlag))
10450 {
10451 continue;
10452 }
10453 else if (aFlag == "0"
10454 || aFlag == "off")
10455 {
10456 if (++anArgIter < theArgNb)
10457 {
23fe70ec 10458 Message::SendFail ("Error: wrong number of arguments");
f978241f 10459 return 1;
10460 }
10461
10462 if (!aCamera.IsNull()
10463 && aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
10464 {
10465 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10466 }
10467 ViewerTest_myDefaultCaps.contextStereo = Standard_False;
10468 return 0;
10469 }
10470 else if (aFlag == "1"
10471 || aFlag == "on")
10472 {
10473 if (++anArgIter < theArgNb)
10474 {
23fe70ec 10475 Message::SendFail ("Error: wrong number of arguments");
f978241f 10476 return 1;
10477 }
10478
10479 if (!aCamera.IsNull())
10480 {
10481 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10482 }
10483 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
b40cdc2b 10484 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10485 {
10486 return 0;
10487 }
f978241f 10488 }
10489 else if (aFlag == "-reverse"
10490 || aFlag == "-reversed"
10491 || aFlag == "-swap")
10492 {
10493 Standard_Boolean toEnable = Standard_True;
10494 if (++anArgIter < theArgNb
dae2a922 10495 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10496 {
10497 --anArgIter;
10498 }
10499 aParams->ToReverseStereo = toEnable;
10500 }
10501 else if (aFlag == "-noreverse"
10502 || aFlag == "-noswap")
10503 {
10504 Standard_Boolean toDisable = Standard_True;
10505 if (++anArgIter < theArgNb
dae2a922 10506 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10507 {
10508 --anArgIter;
10509 }
10510 aParams->ToReverseStereo = !toDisable;
10511 }
10512 else if (aFlag == "-mode"
10513 || aFlag == "-stereomode")
10514 {
10515 if (++anArgIter >= theArgNb
10516 || !parseStereoMode (theArgVec[anArgIter], aMode))
10517 {
23fe70ec 10518 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10519 return 1;
10520 }
10521
10522 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10523 {
10524 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10525 }
10526 }
10527 else if (aFlag == "-anaglyph"
10528 || aFlag == "-anaglyphfilter")
10529 {
10530 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10531 if (++anArgIter >= theArgNb
10532 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10533 {
23fe70ec 10534 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10535 return 1;
10536 }
10537
10538 aMode = Graphic3d_StereoMode_Anaglyph;
10539 aParams->AnaglyphFilter = aFilter;
10540 }
10541 else if (parseStereoMode (anArg, aMode)) // short syntax
10542 {
10543 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10544 {
10545 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10546 }
10547 }
b40cdc2b 10548 else if (anArgIter + 1 < theArgNb
10549 && aFlag == "-hmdfov2d")
10550 {
10551 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10552 if (aParams->HmdFov2d < 10.0f
10553 || aParams->HmdFov2d > 180.0f)
10554 {
10555 Message::SendFail() << "Error: FOV is out of range";
10556 return 1;
10557 }
10558 }
10559 else if (aFlag == "-mirror"
10560 || aFlag == "-mirrorcomposer")
10561 {
10562 Standard_Boolean toEnable = Standard_True;
10563 if (++anArgIter < theArgNb
dae2a922 10564 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10565 {
10566 --anArgIter;
10567 }
10568 aParams->ToMirrorComposer = toEnable;
10569 }
10570 else if (anArgIter + 1 < theArgNb
10571 && (aFlag == "-unitfactor"
10572 || aFlag == "-unitscale"))
10573 {
10574 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10575 }
f978241f 10576 else
10577 {
23fe70ec 10578 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10579 return 1;
10580 }
10581 }
10582
10583 if (!aView.IsNull())
10584 {
10585 aParams->StereoMode = aMode;
10586 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 10587 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
10588 {
10589 // initiate implicit continuous rendering
10590 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
10591 }
f978241f 10592 }
b5ac8292 10593 return 0;
10594}
10595
392ac980 10596//===============================================================================================
10597//function : VDefaults
10598//purpose :
10599//===============================================================================================
10600static int VDefaults (Draw_Interpretor& theDi,
10601 Standard_Integer theArgsNb,
10602 const char** theArgVec)
10603{
10604 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10605 if (aCtx.IsNull())
10606 {
23fe70ec 10607 Message::SendFail ("Error: no active viewer");
392ac980 10608 return 1;
10609 }
10610
10611 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10612 if (theArgsNb < 2)
10613 {
10614 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10615 {
10616 theDi << "DeflType: relative\n"
10617 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10618 }
10619 else
10620 {
10621 theDi << "DeflType: absolute\n"
10622 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10623 }
67441d0c 10624 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10625 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10626 return 0;
10627 }
10628
10629 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10630 {
10631 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10632 anArg.UpperCase();
10633 if (anArg == "-ABSDEFL"
10634 || anArg == "-ABSOLUTEDEFLECTION"
10635 || anArg == "-DEFL"
10636 || anArg == "-DEFLECTION")
392ac980 10637 {
4c513386 10638 if (++anArgIter >= theArgsNb)
10639 {
23fe70ec 10640 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10641 return 1;
10642 }
392ac980 10643 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10644 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10645 }
4c513386 10646 else if (anArg == "-RELDEFL"
10647 || anArg == "-RELATIVEDEFLECTION"
10648 || anArg == "-DEVCOEFF"
10649 || anArg == "-DEVIATIONCOEFF"
10650 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10651 {
4c513386 10652 if (++anArgIter >= theArgsNb)
10653 {
23fe70ec 10654 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10655 return 1;
10656 }
392ac980 10657 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10658 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10659 }
4c513386 10660 else if (anArg == "-ANGDEFL"
10661 || anArg == "-ANGULARDEFL"
10662 || anArg == "-ANGULARDEFLECTION")
392ac980 10663 {
4c513386 10664 if (++anArgIter >= theArgsNb)
10665 {
23fe70ec 10666 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10667 return 1;
10668 }
67441d0c 10669 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10670 }
385c43e7 10671 else if (anArg == "-AUTOTR"
10672 || anArg == "-AUTOTRIANG"
10673 || anArg == "-AUTOTRIANGULATION")
4c513386 10674 {
14c7f553 10675 ++anArgIter;
10676 bool toTurnOn = true;
10677 if (anArgIter >= theArgsNb
dae2a922 10678 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10679 {
23fe70ec 10680 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10681 return 1;
10682 }
14c7f553 10683 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10684 }
10685 else
10686 {
23fe70ec 10687 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10688 return 1;
392ac980 10689 }
10690 }
10691
10692 return 0;
10693}
10694
12381341 10695//! Auxiliary method
10696inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10697 const Graphic3d_ZLayerId theLayer,
12381341 10698 const Standard_Boolean theIsGlobal)
10699{
10700 if (theLightNew.IsNull())
10701 {
10702 return;
10703 }
10704
992ed6b3 10705 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10706 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10707 {
992ed6b3 10708 aViewer->AddLight (theLightNew);
10709 if (theIsGlobal)
10710 {
10711 aViewer->SetLightOn (theLightNew);
10712 }
10713 else
10714 {
10715 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10716 }
12381341 10717 }
10718 else
10719 {
992ed6b3 10720 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10721 if (aSettings.Lights().IsNull())
10722 {
10723 aSettings.SetLights (new Graphic3d_LightSet());
10724 }
10725 aSettings.Lights()->Add (theLightNew);
10726 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10727 }
10728}
10729
10730//! Auxiliary method
10731inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10732{
10733 TCollection_AsciiString anArgNextCase (theArgNext);
10734 anArgNextCase.UpperCase();
10735 if (anArgNextCase.Length() > 5
10736 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10737 {
10738 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10739 }
10740 else
10741 {
10742 return theArgNext.IntegerValue();
10743 }
10744}
10745
2daa5d95 10746static Handle(AIS_LightSource) findLightPrs (const Handle(V3d_Light)& theLight,
10747 const bool theToShowErrors = true)
10748{
10749 if (theLight.IsNull())
10750 {
10751 if (theToShowErrors)
10752 {
10753 Message::SendFail() << "Syntax error: no active light source to find presentation";
10754 }
10755 return Handle(AIS_LightSource)();
10756 }
10757
10758 Handle(AIS_InteractiveObject) anObject;
10759 GetMapOfAIS().Find2 (theLight->Name(), anObject);
10760 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (anObject);
10761 if (aLightSource.IsNull())
10762 {
10763 if (theToShowErrors)
10764 {
10765 Message::SendFail() << "Syntax error: could not find '" << theLight->Name() << "' AIS object";
10766 }
10767 }
10768 return aLightSource;
10769}
10770
12381341 10771//===============================================================================================
10772//function : VLight
10773//purpose :
10774//===============================================================================================
10775static int VLight (Draw_Interpretor& theDi,
10776 Standard_Integer theArgsNb,
10777 const char** theArgVec)
10778{
10779 Handle(V3d_View) aView = ViewerTest::CurrentView();
10780 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10781 if (aView.IsNull()
10782 || aViewer.IsNull())
10783 {
23fe70ec 10784 Message::SendFail ("Error: no active viewer");
12381341 10785 return 1;
10786 }
10787
ee2be2a8 10788 Standard_Real anXYZ[3] = {};
10789 Standard_Real anAtten[2] = {};
12381341 10790 if (theArgsNb < 2)
10791 {
10792 // print lights info
10793 Standard_Integer aLightId = 0;
6a24c6de 10794 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10795 {
6a24c6de 10796 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10797 const Quantity_Color aColor = aLight->Color();
992ed6b3 10798 theDi << "Light #" << aLightId
10799 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10800 << " [" << aLight->GetId() << "]" << "\n";
12381341 10801 switch (aLight->Type())
10802 {
10803 case V3d_AMBIENT:
10804 {
189f85a3 10805 theDi << " Type: Ambient\n";
10806 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10807 break;
10808 }
10809 case V3d_DIRECTIONAL:
10810 {
189f85a3 10811 theDi << " Type: Directional\n";
10812 theDi << " Intensity: " << aLight->Intensity() << "\n";
10813 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10814 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10815 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10816 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10817 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10818 break;
10819 }
10820 case V3d_POSITIONAL:
10821 {
189f85a3 10822 theDi << " Type: Positional\n";
10823 theDi << " Intensity: " << aLight->Intensity() << "\n";
10824 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10825 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
189f85a3 10826 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10827 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10828 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10829 aLight->Attenuation (anAtten[0], anAtten[1]);
10830 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
88b312d3 10831 theDi << " Range: " << aLight->Range() << "\n";
12381341 10832 break;
10833 }
10834 case V3d_SPOT:
10835 {
189f85a3 10836 theDi << " Type: Spot\n";
10837 theDi << " Intensity: " << aLight->Intensity() << "\n";
10838 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
d84e8669 10839 theDi << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10840 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10841 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10842 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10843 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10844 aLight->Attenuation (anAtten[0], anAtten[1]);
10845 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10846 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10847 theDi << " Exponent: " << aLight->Concentration() << "\n";
88b312d3 10848 theDi << " Range: " << aLight->Range() << "\n";
12381341 10849 break;
10850 }
10851 default:
10852 {
189f85a3 10853 theDi << " Type: UNKNOWN\n";
12381341 10854 break;
10855 }
10856 }
992ed6b3 10857 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10858 }
10859 }
10860
2daa5d95 10861 Handle(V3d_Light) aLightNew, aLightOld;
992ed6b3 10862 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10863 Standard_Boolean isGlobal = Standard_True;
10864 Standard_Boolean toCreate = Standard_False;
761d8807 10865 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10866 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10867 {
992ed6b3 10868 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10869
10870 TCollection_AsciiString aName, aValue;
10871 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10872 TCollection_AsciiString anArgCase (anArg);
10873 anArgCase.UpperCase();
761d8807 10874 if (anUpdateTool.parseRedrawMode (anArg))
10875 {
10876 continue;
10877 }
10878
12381341 10879 if (anArgCase.IsEqual ("NEW")
10880 || anArgCase.IsEqual ("ADD")
992ed6b3 10881 || anArgCase.IsEqual ("CREATE")
10882 || anArgCase.IsEqual ("-NEW")
10883 || anArgCase.IsEqual ("-ADD")
10884 || anArgCase.IsEqual ("-CREATE"))
12381341 10885 {
10886 toCreate = Standard_True;
10887 }
992ed6b3 10888 else if (anArgCase.IsEqual ("-LAYER")
10889 || anArgCase.IsEqual ("-ZLAYER"))
10890 {
10891 if (++anArgIt >= theArgsNb)
10892 {
23fe70ec 10893 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10894 return 1;
10895 }
10896
10897 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10898 aValStr.LowerCase();
10899 if (aValStr == "default"
10900 || aValStr == "def")
10901 {
10902 aLayer = Graphic3d_ZLayerId_Default;
10903 }
10904 else if (aValStr == "top")
10905 {
10906 aLayer = Graphic3d_ZLayerId_Top;
10907 }
10908 else if (aValStr == "topmost")
10909 {
10910 aLayer = Graphic3d_ZLayerId_Topmost;
10911 }
10912 else if (aValStr == "toposd"
10913 || aValStr == "osd")
10914 {
10915 aLayer = Graphic3d_ZLayerId_TopOSD;
10916 }
10917 else if (aValStr == "botosd"
10918 || aValStr == "bottom")
10919 {
10920 aLayer = Graphic3d_ZLayerId_BotOSD;
10921 }
10922 else if (aValStr.IsIntegerValue())
10923 {
10924 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10925 }
10926 else
10927 {
23fe70ec 10928 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10929 return 1;
10930 }
10931 }
12381341 10932 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10933 || anArgCase.IsEqual ("GLOBAL")
10934 || anArgCase.IsEqual ("-GLOB")
10935 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10936 {
10937 isGlobal = Standard_True;
10938 }
10939 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10940 || anArgCase.IsEqual ("LOCAL")
10941 || anArgCase.IsEqual ("-LOC")
10942 || anArgCase.IsEqual ("-LOCAL"))
12381341 10943 {
10944 isGlobal = Standard_False;
10945 }
4fe9ad57 10946 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10947 || anArgCase.IsEqual ("DEFAULTS")
10948 || anArgCase.IsEqual ("-DEF")
10949 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10950 {
10951 toCreate = Standard_False;
10952 aViewer->SetDefaultLights();
10953 }
10954 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10955 || anArgCase.IsEqual ("CLEAR")
10956 || anArgCase.IsEqual ("-CLR")
10957 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10958 {
10959 toCreate = Standard_False;
992ed6b3 10960
10961 TColStd_SequenceOfInteger aLayers;
10962 aViewer->GetAllZLayers (aLayers);
10963 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10964 {
992ed6b3 10965 if (aLayeriter.Value() == aLayer
10966 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10967 {
10968 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10969 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10970 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10971 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10972 {
10973 break;
10974 }
10975 }
10976 }
10977
10978 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10979 {
2daa5d95 10980 ViewerTest_DoubleMapOfInteractiveAndName aMap = GetMapOfAIS();
992ed6b3 10981 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10982 {
10983 Handle(V3d_Light) aLight = aLightIter.Value();
2daa5d95 10984 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLight, false))
10985 {
10986 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
10987 GetMapOfAIS().UnBind2 (aLight->Name());
10988 }
992ed6b3 10989 aViewer->DelLight (aLight);
10990 aLightIter = aView->ActiveLightIterator();
10991 }
4fe9ad57 10992 }
10993 }
12381341 10994 else if (anArgCase.IsEqual ("AMB")
10995 || anArgCase.IsEqual ("AMBIENT")
10996 || anArgCase.IsEqual ("AMBLIGHT"))
10997 {
12381341 10998 if (!toCreate)
10999 {
23fe70ec 11000 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11001 return 1;
11002 }
992ed6b3 11003
11004 addLight (aLightNew, aLayer, isGlobal);
12381341 11005 toCreate = Standard_False;
992ed6b3 11006 aLightNew = new V3d_AmbientLight();
12381341 11007 }
11008 else if (anArgCase.IsEqual ("DIRECTIONAL")
11009 || anArgCase.IsEqual ("DIRLIGHT"))
11010 {
12381341 11011 if (!toCreate)
11012 {
23fe70ec 11013 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11014 return 1;
11015 }
992ed6b3 11016
11017 addLight (aLightNew, aLayer, isGlobal);
12381341 11018 toCreate = Standard_False;
992ed6b3 11019 aLightNew = new V3d_DirectionalLight();
12381341 11020 }
11021 else if (anArgCase.IsEqual ("SPOT")
11022 || anArgCase.IsEqual ("SPOTLIGHT"))
11023 {
12381341 11024 if (!toCreate)
11025 {
23fe70ec 11026 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11027 return 1;
11028 }
992ed6b3 11029
11030 addLight (aLightNew, aLayer, isGlobal);
12381341 11031 toCreate = Standard_False;
992ed6b3 11032 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 11033 }
11034 else if (anArgCase.IsEqual ("POSLIGHT")
11035 || anArgCase.IsEqual ("POSITIONAL"))
11036 {
12381341 11037 if (!toCreate)
11038 {
23fe70ec 11039 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11040 return 1;
11041 }
992ed6b3 11042
11043 addLight (aLightNew, aLayer, isGlobal);
12381341 11044 toCreate = Standard_False;
992ed6b3 11045 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 11046 }
992ed6b3 11047 else if (anArgCase.IsEqual ("CHANGE")
11048 || anArgCase.IsEqual ("-CHANGE"))
12381341 11049 {
12381341 11050 if (++anArgIt >= theArgsNb)
11051 {
23fe70ec 11052 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11053 return 1;
11054 }
11055
992ed6b3 11056 addLight (aLightNew, aLayer, isGlobal);
11057 aLightNew.Nullify();
12381341 11058 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
11059 Standard_Integer aLightIt = 0;
6a24c6de 11060 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 11061 {
11062 if (aLightIt == aLightId)
11063 {
6a24c6de 11064 aLightOld = aLightIter.Value();
12381341 11065 break;
11066 }
11067 }
11068
11069 if (aLightOld.IsNull())
11070 {
23fe70ec 11071 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
12381341 11072 return 1;
11073 }
11074 }
2daa5d95 11075 else if (anArgCase == "-DISPLAY"
11076 || anArgCase == "-DISP"
11077 || anArgCase == "-PRESENTATION"
11078 || anArgCase == "-PRS")
11079 {
11080 if (aLightCurr.IsNull())
11081 {
11082 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11083 return 1;
11084 }
11085
11086 TCollection_AsciiString aLightName = aLightCurr->Name();
11087 if (++anArgIt > theArgsNb
11088 && aLightName.IsEmpty())
11089 {
11090 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11091 return 1;
11092 }
11093 if (anArgIt < theArgsNb)
11094 {
11095 if (theArgVec[anArgIt][0] != '-')
11096 {
11097 aLightName = theArgVec[anArgIt];
11098 aLightCurr->SetName (aLightName);
11099 }
11100 else
11101 {
11102 --anArgIt;
11103 }
11104 }
11105 if (aLightName.IsEmpty())
11106 {
11107 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11108 return 1;
11109 }
11110 ViewerTest::Display (aLightName, new AIS_LightSource (aLightCurr), false);
11111 }
11112 else if (anArgCase == "DEL"
11113 || anArgCase == "DELETE"
11114 || anArgCase == "-DEL"
11115 || anArgCase == "-DELETE"
11116 || anArgCase == "-REMOVE")
12381341 11117 {
11118 Handle(V3d_Light) aLightDel;
11119 if (++anArgIt >= theArgsNb)
11120 {
23fe70ec 11121 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11122 return 1;
11123 }
11124
11125 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
11126 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
11127 Standard_Integer aLightIt = 0;
6a24c6de 11128 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 11129 {
6a24c6de 11130 aLightDel = aLightIter.Value();
12381341 11131 if (aLightIt == aLightDelId)
11132 {
11133 break;
11134 }
11135 }
992ed6b3 11136 if (aLightDel.IsNull())
11137 {
11138 continue;
11139 }
11140
11141 TColStd_SequenceOfInteger aLayers;
11142 aViewer->GetAllZLayers (aLayers);
11143 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
11144 {
11145 if (aLayeriter.Value() == aLayer
11146 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
11147 {
11148 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
11149 if (!aSettings.Lights().IsNull())
11150 {
11151 aSettings.Lights()->Remove (aLightDel);
11152 if (aSettings.Lights()->IsEmpty())
11153 {
11154 aSettings.SetLights (Handle(Graphic3d_LightSet)());
11155 }
11156 }
11157 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
11158 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
11159 {
11160 break;
11161 }
11162 }
11163 }
11164
11165 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 11166 {
2daa5d95 11167 if (Handle(AIS_LightSource) aLightSourceDel = findLightPrs (aLightDel, false))
11168 {
11169 ViewerTest::GetAISContext()->Remove (aLightSourceDel, false);
11170 GetMapOfAIS().UnBind2 (aLightDel->Name());
11171 }
12381341 11172 aViewer->DelLight (aLightDel);
11173 }
11174 }
11175 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 11176 || anArgCase.IsEqual ("COLOUR")
11177 || anArgCase.IsEqual ("-COLOR")
11178 || anArgCase.IsEqual ("-COLOUR"))
12381341 11179 {
dae2a922 11180 Quantity_Color aColor;
11181 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
11182 theArgVec + anArgIt + 1,
11183 aColor);
11184 anArgIt += aNbParsed;
11185 if (aNbParsed == 0
992ed6b3 11186 || aLightCurr.IsNull())
12381341 11187 {
23fe70ec 11188 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11189 return 1;
11190 }
992ed6b3 11191 aLightCurr->SetColor (aColor);
12381341 11192 }
2daa5d95 11193 else if (anArgCase == "POS"
11194 || anArgCase == "POSITION"
11195 || anArgCase == "-POS"
11196 || anArgCase == "-POSITION"
11197 || anArgCase == "-PRSPOSITION"
11198 || anArgCase == "-PRSPOS")
12381341 11199 {
2daa5d95 11200 gp_XYZ aPosXYZ;
992ed6b3 11201 if ((anArgIt + 3) >= theArgsNb
2daa5d95 11202 || !parseXYZ (theArgVec + anArgIt + 1, aPosXYZ)
11203 || aLightCurr.IsNull())
12381341 11204 {
23fe70ec 11205 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11206 return 1;
11207 }
11208
2daa5d95 11209 anArgIt += 3;
11210 if (anArgCase == "-PRSPOSITION"
11211 || anArgCase == "-PRSPOS")
11212 {
11213 aLightCurr->SetDisplayPosition (aPosXYZ);
11214 }
11215 else
11216 {
11217 if (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11218 && aLightCurr->Type() != Graphic3d_TOLS_SPOT)
11219 {
11220 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11221 return 1;
11222 }
11223
11224 aLightCurr->SetPosition (aPosXYZ);
11225 }
12381341 11226 }
11227 else if (anArgCase.IsEqual ("DIR")
992ed6b3 11228 || anArgCase.IsEqual ("DIRECTION")
11229 || anArgCase.IsEqual ("-DIR")
11230 || anArgCase.IsEqual ("-DIRECTION"))
12381341 11231 {
2daa5d95 11232 gp_XYZ aDirXYZ;
992ed6b3 11233 if ((anArgIt + 3) >= theArgsNb
2daa5d95 11234 || !parseXYZ (theArgVec + anArgIt + 1, aDirXYZ)
992ed6b3 11235 || aLightCurr.IsNull()
11236 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
11237 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11238 {
23fe70ec 11239 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11240 return 1;
11241 }
11242
2daa5d95 11243 anArgIt += 3;
11244 aLightCurr->SetDirection (gp_Dir (aDirXYZ));
12381341 11245 }
189f85a3 11246 else if (anArgCase.IsEqual ("SM")
992ed6b3 11247 || anArgCase.IsEqual ("SMOOTHNESS")
11248 || anArgCase.IsEqual ("-SM")
11249 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 11250 {
992ed6b3 11251 if (++anArgIt >= theArgsNb
11252 || aLightCurr.IsNull())
189f85a3 11253 {
23fe70ec 11254 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 11255 return 1;
11256 }
11257
992ed6b3 11258 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11259 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 11260 {
11261 aLightCurr->SetIntensity (1.f);
11262 }
992ed6b3 11263 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 11264 {
11265 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
11266 }
11267 else
11268 {
11269 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
11270 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
11271 }
11272
992ed6b3 11273 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 11274 {
992ed6b3 11275 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 11276 }
992ed6b3 11277 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 11278 {
992ed6b3 11279 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 11280 }
11281 }
11282 else if (anArgCase.IsEqual ("INT")
992ed6b3 11283 || anArgCase.IsEqual ("INTENSITY")
11284 || anArgCase.IsEqual ("-INT")
11285 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 11286 {
992ed6b3 11287 if (++anArgIt >= theArgsNb
11288 || aLightCurr.IsNull())
189f85a3 11289 {
23fe70ec 11290 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 11291 return 1;
11292 }
11293
992ed6b3 11294 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11295 aLightCurr->SetIntensity (aIntensity);
189f85a3 11296 }
4fe9ad57 11297 else if (anArgCase.IsEqual ("ANG")
992ed6b3 11298 || anArgCase.IsEqual ("ANGLE")
11299 || anArgCase.IsEqual ("-ANG")
11300 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 11301 {
992ed6b3 11302 if (++anArgIt >= theArgsNb
11303 || aLightCurr.IsNull()
11304 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 11305 {
23fe70ec 11306 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4fe9ad57 11307 return 1;
11308 }
992ed6b3 11309 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
2daa5d95 11310 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
11311 aLightCurr->SetAngle (anAngle);
4fe9ad57 11312 }
12381341 11313 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 11314 || anArgCase.IsEqual ("CONSTATTENUATION")
11315 || anArgCase.IsEqual ("-CONSTATTEN")
11316 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 11317 {
992ed6b3 11318 if (++anArgIt >= theArgsNb
11319 || aLightCurr.IsNull()
11320 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11321 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11322 {
23fe70ec 11323 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11324 return 1;
11325 }
11326
992ed6b3 11327 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11328 anAtten[0] = Atof (theArgVec[anArgIt]);
11329 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11330 }
11331 else if (anArgCase.IsEqual ("LINATTEN")
11332 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 11333 || anArgCase.IsEqual ("LINEARATTENUATION")
11334 || anArgCase.IsEqual ("-LINATTEN")
11335 || anArgCase.IsEqual ("-LINEARATTEN")
11336 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 11337 {
992ed6b3 11338 if (++anArgIt >= theArgsNb
11339 || aLightCurr.IsNull()
11340 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11341 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11342 {
23fe70ec 11343 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11344 return 1;
11345 }
11346
992ed6b3 11347 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11348 anAtten[1] = Atof (theArgVec[anArgIt]);
11349 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11350 }
11351 else if (anArgCase.IsEqual ("EXP")
11352 || anArgCase.IsEqual ("EXPONENT")
11353 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 11354 || anArgCase.IsEqual ("SPOTEXPONENT")
11355 || anArgCase.IsEqual ("-EXP")
11356 || anArgCase.IsEqual ("-EXPONENT")
11357 || anArgCase.IsEqual ("-SPOTEXP")
11358 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 11359 {
992ed6b3 11360 if (++anArgIt >= theArgsNb
11361 || aLightCurr.IsNull()
11362 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 11363 {
23fe70ec 11364 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11365 return 1;
11366 }
11367
992ed6b3 11368 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 11369 }
88b312d3 11370 else if (anArgCase.IsEqual("RANGE")
11371 || anArgCase.IsEqual("-RANGE"))
11372 {
11373 if (++anArgIt >= theArgsNb
11374 || aLightCurr.IsNull()
11375 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
11376 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
11377 {
23fe70ec 11378 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
88b312d3 11379 return 1;
11380 }
2daa5d95 11381 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
11382 aLightCurr->SetRange (aRange);
88b312d3 11383 }
12381341 11384 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 11385 || anArgCase.IsEqual ("HEADLIGHT")
11386 || anArgCase.IsEqual ("-HEAD")
11387 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 11388 {
992ed6b3 11389 if (aLightCurr.IsNull()
11390 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 11391 {
23fe70ec 11392 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11393 return 1;
11394 }
11395
992ed6b3 11396 Standard_Boolean isHeadLight = Standard_True;
11397 if (anArgIt + 1 < theArgsNb
dae2a922 11398 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 11399 {
992ed6b3 11400 ++anArgIt;
12381341 11401 }
992ed6b3 11402 aLightCurr->SetHeadlight (isHeadLight);
12381341 11403 }
2daa5d95 11404 else if (anArgCase.IsEqual ("NAME")
11405 || anArgCase.IsEqual ("-NAME"))
11406 {
11407 if ((anArgIt + 1) >= theArgsNb
11408 || aLightCurr.IsNull())
11409 {
11410 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11411 return 1;
11412 }
11413 aName = theArgVec[++anArgIt];
11414 aLightCurr->SetName (aName);
11415 }
11416 else if (anArgCase == "-SHOWZOOMABLE"
11417 || anArgCase == "-PRSZOOMABLE"
11418 || anArgCase == "-ZOOMABLE")
11419 {
11420 if (aLightCurr.IsNull())
11421 {
11422 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11423 return 1;
11424 }
11425
11426 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11427 {
11428 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11429 aLightSource->SetZoomable (isZoomable);
11430 }
11431 else
11432 {
11433 return 1;
11434 }
11435 }
11436 else if (anArgCase == "-SHOWNAME"
11437 || anArgCase == "-PRSNAME")
11438 {
11439 if (aLightCurr.IsNull())
11440 {
11441 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11442 return 1;
11443 }
11444
11445 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11446 {
11447 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11448 aLightSource->SetDisplayName (toDisplay);
11449 }
11450 else
11451 {
11452 return 1;
11453 }
11454 }
11455 else if (anArgCase == "-SHOWRANGE"
11456 || anArgCase == "-PRSRANGE")
11457 {
11458 if (aLightCurr.IsNull()
11459 || (aLightCurr->Type() != Graphic3d_TOLS_SPOT
11460 && aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL))
11461 {
11462 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11463 return 1;
11464 }
11465
11466 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11467 {
11468 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
11469 aLightSource->SetDisplayRange (toDisplay);
11470 }
11471 else
11472 {
11473 return 1;
11474 }
11475 }
11476 else if (anArgCase == "-SHOWSIZE"
11477 || anArgCase == "-PRSSIZE")
11478 {
11479 Standard_Real aSize = 0.0;
11480 if ((anArgIt + 1) >= theArgsNb
11481 || !Draw::ParseReal (theArgVec[anArgIt + 1], aSize)
11482 || aSize <= 0.0)
11483 {
11484 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11485 return 1;
11486 }
11487
11488 ++anArgIt;
11489 if (Handle(AIS_LightSource) aLightSource = findLightPrs (aLightCurr))
11490 {
11491 aLightSource->SetSize (aSize);
11492 }
11493 else
11494 {
11495 return 1;
11496 }
11497 }
d84e8669 11498 else if (anArgCase.IsEqual ("-CASTSHADOW")
11499 || anArgCase.IsEqual ("-CASTSHADOWS")
11500 || anArgCase.IsEqual ("-SHADOWS"))
11501 {
11502 if (aLightCurr.IsNull()
11503 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
11504 {
11505 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11506 return 1;
11507 }
11508
11509 bool toCastShadows = true;
11510 if (anArgIt + 1 < theArgsNb
11511 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
11512 {
11513 ++anArgIt;
11514 }
11515 aLightCurr->SetCastShadows (toCastShadows);
11516 }
12381341 11517 else
11518 {
23fe70ec 11519 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
12381341 11520 }
11521 }
11522
992ed6b3 11523 addLight (aLightNew, aLayer, isGlobal);
2daa5d95 11524
11525 struct LightPrsSort
11526 {
11527 bool operator() (const Handle(AIS_LightSource)& theLeft,
11528 const Handle(AIS_LightSource)& theRight)
11529 {
11530 return theLeft->Light()->GetId() < theRight->Light()->GetId();
11531 }
11532 };
11533
11534 AIS_ListOfInteractive aPrsList;
11535 ViewerTest::GetAISContext()->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
11536 if (!aPrsList.IsEmpty())
11537 {
11538 // update light source presentations
11539 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
11540 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
11541 {
11542 if (Handle(AIS_LightSource) aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
11543 {
11544 aLightPrsVec.push_back (aLightPrs);
11545 }
11546 }
11547
11548 // sort objects by id as AIS_InteractiveContext stores them in unordered map
11549 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
11550
11551 Standard_Integer aTopStack = 0;
11552 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
11553 {
11554 Handle(AIS_LightSource) aLightPrs = *aPrsIter;
11555 if (!aLightPrs->TransformPersistence().IsNull()
11556 && aLightPrs->TransformPersistence()->IsTrihedronOr2d())
11557 {
11558 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs->Size();
11559 aLightPrs->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
11560 aTopStack += aPrsSize + aPrsSize / 2;
11561 }
11562 ViewerTest::GetAISContext()->Redisplay (aLightPrs, false);
11563 ViewerTest::GetAISContext()->SetTransformPersistence (aLightPrs, aLightPrs->TransformPersistence());
11564 }
11565 }
12381341 11566 return 0;
11567}
11568
67312b79 11569//===============================================================================================
11570//function : VPBREnvironment
11571//purpose :
11572//===============================================================================================
11573static int VPBREnvironment (Draw_Interpretor&,
11574 Standard_Integer theArgsNb,
11575 const char** theArgVec)
11576{
11577 if (theArgsNb > 2)
11578 {
23fe70ec 11579 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11580 return 1;
11581 }
11582
11583 Handle(V3d_View) aView = ViewerTest::CurrentView();
11584 if (aView.IsNull())
11585 {
23fe70ec 11586 Message::SendFail ("Error: no active viewer");
67312b79 11587 return 1;
11588 }
11589
11590 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11591 anArg.LowerCase();
11592
11593 if (anArg == "-generate"
11594 || anArg == "-gen")
11595 {
11596 aView->GeneratePBREnvironment (Standard_True);
11597 }
11598 else if (anArg == "-clear")
11599 {
11600 aView->ClearPBREnvironment (Standard_True);
11601 }
11602 else
11603 {
23fe70ec 11604 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11605 return 1;
11606 }
11607
11608 return 0;
11609}
11610
15669413 11611//! Read Graphic3d_RenderingParams::PerfCounters flag.
11612static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11613 Standard_Boolean& theToReset,
11614 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11615 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11616{
11617 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11618 TCollection_AsciiString aVal = theValue;
11619 Standard_Boolean toReverse = Standard_False;
11620 if (aVal == "none")
11621 {
11622 theToReset = Standard_True;
11623 return Standard_True;
11624 }
11625 else if (aVal.StartsWith ("-"))
11626 {
11627 toReverse = Standard_True;
11628 aVal = aVal.SubString (2, aVal.Length());
11629 }
11630 else if (aVal.StartsWith ("no"))
11631 {
11632 toReverse = Standard_True;
11633 aVal = aVal.SubString (3, aVal.Length());
11634 }
11635 else if (aVal.StartsWith ("+"))
11636 {
11637 aVal = aVal.SubString (2, aVal.Length());
11638 }
11639 else
11640 {
11641 theToReset = Standard_True;
11642 }
11643
11644 if ( aVal == "fps"
11645 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11646 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11647 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11648 else if (aVal == "structs"
11649 || aVal == "structures"
11650 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11651 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11652 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11653 else if (aVal == "tris"
11654 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11655 else if (aVal == "pnts"
11656 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11657 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11658 else if (aVal == "mem"
11659 || aVal == "gpumem"
11660 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11661 else if (aVal == "skipimmediate"
11662 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11663 else if (aVal == "frametime"
11664 || aVal == "frametimers"
11665 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11666 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11667 else if (aVal == "extended"
11668 || aVal == "verbose"
11669 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11670 else if (aVal == "full"
11671 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11672 else
11673 {
11674 return Standard_False;
11675 }
11676
11677 if (toReverse)
11678 {
11679 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11680 }
11681 else
11682 {
11683 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11684 }
11685 return Standard_True;
11686}
11687
11688//! Read Graphic3d_RenderingParams::PerfCounters flags.
11689static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11690 Graphic3d_RenderingParams::PerfCounters& theFlags)
11691{
11692 TCollection_AsciiString aValue = theValue;
11693 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11694 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11695 Standard_Boolean toReset = Standard_False;
11696 for (;;)
11697 {
11698 Standard_Integer aSplitPos = aValue.Search ("|");
11699 if (aSplitPos <= 0)
11700 {
11701 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11702 {
11703 return Standard_False;
11704 }
11705 if (toReset)
11706 {
11707 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11708 }
11709 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11710 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11711 return Standard_True;
11712 }
11713
11714 if (aSplitPos > 1)
11715 {
11716 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11717 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11718 {
11719 return Standard_False;
11720 }
11721 }
11722 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11723 }
11724}
11725
e276548b 11726//=======================================================================
bc8c79bb 11727//function : VRenderParams
11728//purpose : Enables/disables rendering features
e276548b 11729//=======================================================================
11730
bc8c79bb 11731static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11732 Standard_Integer theArgNb,
11733 const char** theArgVec)
e276548b 11734{
7ae4a307 11735 Handle(V3d_View) aView = ViewerTest::CurrentView();
11736 if (aView.IsNull())
e276548b 11737 {
23fe70ec 11738 Message::SendFail ("Error: no active viewer");
e276548b 11739 return 1;
11740 }
bc8c79bb 11741
11742 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11743 TCollection_AsciiString aCmdName (theArgVec[0]);
11744 aCmdName.LowerCase();
11745 if (aCmdName == "vraytrace")
11746 {
11747 if (theArgNb == 1)
11748 {
11749 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11750 return 0;
11751 }
11752 else if (theArgNb == 2)
11753 {
11754 TCollection_AsciiString aValue (theArgVec[1]);
11755 aValue.LowerCase();
11756 if (aValue == "on"
11757 || aValue == "1")
11758 {
11759 aParams.Method = Graphic3d_RM_RAYTRACING;
11760 aView->Redraw();
11761 return 0;
11762 }
11763 else if (aValue == "off"
11764 || aValue == "0")
11765 {
11766 aParams.Method = Graphic3d_RM_RASTERIZATION;
11767 aView->Redraw();
11768 return 0;
11769 }
11770 else
11771 {
23fe70ec 11772 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11773 return 1;
11774 }
11775 }
11776 else
11777 {
23fe70ec 11778 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11779 return 1;
11780 }
11781 }
bc8c79bb 11782
11783 if (theArgNb < 2)
e276548b 11784 {
bc8c79bb 11785 theDI << "renderMode: ";
11786 switch (aParams.Method)
11787 {
11788 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11789 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11790 }
11791 theDI << "\n";
a1073ae2 11792 theDI << "transparency: ";
11793 switch (aParams.TransparencyMethod)
11794 {
11795 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11796 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11797 << TCollection_AsciiString (aParams.OitDepthFactor); break;
78c4e836 11798 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
11799 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
a1073ae2 11800 }
11801 theDI << "\n";
b4327ba8 11802 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11803 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11804 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11805 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11806 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
d84e8669 11807 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
11808 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
b4327ba8 11809 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11810 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11811 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11812 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11813 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11814 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11815 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11816 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11817 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11818 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11819 theDI << "shadingModel: ";
11820 switch (aView->ShadingModel())
11821 {
67312b79 11822 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11823 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11824 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11825 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11826 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11827 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11828 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11829 }
37f80e16 11830 theDI << "\n";
15669413 11831 {
11832 theDI << "perfCounters:";
11833 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11834 {
11835 theDI << " fps";
11836 }
11837 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11838 {
11839 theDI << " cpu";
11840 }
11841 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11842 {
11843 theDI << " structs";
11844 }
11845 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11846 {
11847 theDI << " groups";
11848 }
11849 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11850 {
11851 theDI << " arrays";
11852 }
11853 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11854 {
11855 theDI << " tris";
11856 }
b9f43ad1 11857 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11858 {
11859 theDI << " lines";
11860 }
15669413 11861 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11862 {
11863 theDI << " pnts";
11864 }
11865 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11866 {
11867 theDI << " gpumem";
11868 }
5e30547b 11869 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11870 {
11871 theDI << " frameTime";
11872 }
11873 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11874 {
11875 theDI << " skipimmediate";
11876 }
15669413 11877 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11878 {
11879 theDI << " none";
11880 }
11881 theDI << "\n";
11882 }
f88457e6 11883 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11884 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11885 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11886 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11887 "noUpdate") << "\n";
8625ef7e 11888 theDI << "\n";
bc8c79bb 11889 return 0;
e276548b 11890 }
11891
4c7a3fae 11892 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11893 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11894 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11895 {
bc8c79bb 11896 Standard_CString anArg (theArgVec[anArgIter]);
11897 TCollection_AsciiString aFlag (anArg);
11898 aFlag.LowerCase();
8625ef7e 11899 if (anUpdateTool.parseRedrawMode (aFlag))
11900 {
11901 continue;
11902 }
11903 else if (aFlag == "-echo"
11904 || aFlag == "-print")
e276548b 11905 {
bc8c79bb 11906 toPrint = Standard_True;
8625ef7e 11907 anUpdateTool.Invalidate();
e276548b 11908 }
4c7a3fae 11909 else if (aFlag == "-reset")
11910 {
11911 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11912 }
11913 else if (aFlag == "-sync"
11914 && (anArgIter + 1 < theArgNb))
11915 {
11916 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11917 aSyncFlag.LowerCase();
11918 if (aSyncFlag == "default"
11919 || aSyncFlag == "defaults"
11920 || aSyncFlag == "viewer")
11921 {
11922 toSyncDefaults = true;
11923 }
11924 else if (aSyncFlag == "allviews"
11925 || aSyncFlag == "views")
11926 {
11927 toSyncAllViews = true;
11928 }
11929 else
11930 {
11931 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11932 return 1;
11933 }
11934 }
bc8c79bb 11935 else if (aFlag == "-mode"
11936 || aFlag == "-rendermode"
11937 || aFlag == "-render_mode")
e276548b 11938 {
bc8c79bb 11939 if (toPrint)
11940 {
11941 switch (aParams.Method)
11942 {
11943 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11944 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11945 }
11946 continue;
11947 }
e276548b 11948 else
bc8c79bb 11949 {
23fe70ec 11950 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11951 return 1;
11952 }
11953 }
11954 else if (aFlag == "-ray"
11955 || aFlag == "-raytrace")
11956 {
11957 if (toPrint)
11958 {
11959 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11960 continue;
11961 }
11962
4c7a3fae 11963 bool isRayTrace = true;
11964 if (anArgIter + 1 < theArgNb
dae2a922 11965 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11966 {
11967 ++anArgIter;
11968 }
11969 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11970 }
bc8c79bb 11971 else if (aFlag == "-rast"
11972 || aFlag == "-raster"
11973 || aFlag == "-rasterization")
e276548b 11974 {
bc8c79bb 11975 if (toPrint)
11976 {
11977 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11978 continue;
11979 }
11980
4c7a3fae 11981 bool isRaster = true;
11982 if (anArgIter + 1 < theArgNb
dae2a922 11983 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11984 {
11985 ++anArgIter;
11986 }
11987 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11988 }
3c4b62a4 11989 else if (aFlag == "-msaa")
11990 {
11991 if (toPrint)
11992 {
11993 theDI << aParams.NbMsaaSamples << " ";
11994 continue;
11995 }
11996 else if (++anArgIter >= theArgNb)
11997 {
23fe70ec 11998 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11999 return 1;
12000 }
12001
12002 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12003 if (aNbSamples < 0)
12004 {
23fe70ec 12005 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 12006 return 1;
12007 }
12008 else
12009 {
12010 aParams.NbMsaaSamples = aNbSamples;
12011 }
12012 }
2a332745 12013 else if (aFlag == "-linefeather"
12014 || aFlag == "-edgefeather"
12015 || aFlag == "-feather")
12016 {
12017 if (toPrint)
12018 {
12019 theDI << " " << aParams.LineFeather << " ";
12020 continue;
12021 }
12022 else if (++anArgIter >= theArgNb)
12023 {
23fe70ec 12024 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 12025 return 1;
12026 }
12027
12028 TCollection_AsciiString aParam = theArgVec[anArgIter];
12029 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
12030 if (aFeather <= 0.0f)
12031 {
23fe70ec 12032 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 12033 return 1;
12034 }
12035 aParams.LineFeather = aFeather;
12036 }
a1073ae2 12037 else if (aFlag == "-oit")
12038 {
12039 if (toPrint)
12040 {
12041 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
12042 {
12043 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
12044 }
78c4e836 12045 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
12046 {
12047 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
12048 }
a1073ae2 12049 else
12050 {
12051 theDI << "off" << " ";
12052 }
12053 continue;
12054 }
12055 else if (++anArgIter >= theArgNb)
12056 {
23fe70ec 12057 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 12058 return 1;
12059 }
12060
12061 TCollection_AsciiString aParam = theArgVec[anArgIter];
12062 aParam.LowerCase();
78c4e836 12063 if (aParam == "peeling"
12064 || aParam == "peel")
12065 {
12066 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
12067 if (anArgIter + 1 < theArgNb
12068 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
12069 {
12070 ++anArgIter;
12071 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
12072 if (aNbLayers < 2)
12073 {
12074 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
12075 return 1;
12076 }
12077 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
12078 }
12079 }
12080 else if (aParam == "weighted"
12081 || aParam == "weight")
12082 {
12083 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
12084 if (anArgIter + 1 < theArgNb
12085 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
12086 {
12087 ++anArgIter;
12088 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
12089 if (aWeight < 0.f || aWeight > 1.f)
12090 {
12091 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
12092 return 1;
12093 }
12094 aParams.OitDepthFactor = aWeight;
12095 }
12096 }
12097 else if (aParam.IsRealValue())
a1073ae2 12098 {
12099 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
12100 if (aWeight < 0.f || aWeight > 1.f)
12101 {
23fe70ec 12102 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 12103 return 1;
12104 }
12105
12106 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
12107 aParams.OitDepthFactor = aWeight;
12108 }
12109 else if (aParam == "off")
12110 {
12111 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
12112 }
12113 else
12114 {
23fe70ec 12115 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 12116 return 1;
12117 }
12118 }
f88457e6 12119 else if (aFlag == "-depthprepass")
12120 {
12121 if (toPrint)
12122 {
12123 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
12124 continue;
12125 }
12126 aParams.ToEnableDepthPrepass = Standard_True;
12127 if (anArgIter + 1 < theArgNb
dae2a922 12128 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 12129 {
12130 ++anArgIter;
12131 }
12132 }
c40eb6b9 12133 else if (aFlag == "-samplealphatocoverage"
12134 || aFlag == "-alphatocoverage")
12135 {
12136 if (toPrint)
12137 {
12138 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
12139 continue;
12140 }
12141 aParams.ToEnableAlphaToCoverage = Standard_True;
12142 if (anArgIter + 1 < theArgNb
dae2a922 12143 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 12144 {
12145 ++anArgIter;
12146 }
12147 }
56689b27 12148 else if (aFlag == "-rendscale"
12149 || aFlag == "-renderscale"
12150 || aFlag == "-renderresolutionscale")
12151 {
12152 if (toPrint)
12153 {
12154 theDI << aParams.RenderResolutionScale << " ";
12155 continue;
12156 }
12157 else if (++anArgIter >= theArgNb)
12158 {
23fe70ec 12159 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 12160 return 1;
12161 }
12162
12163 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
12164 if (aScale < 0.01)
12165 {
23fe70ec 12166 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 12167 return 1;
12168 }
12169 else
12170 {
12171 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
12172 }
12173 }
bc8c79bb 12174 else if (aFlag == "-raydepth"
12175 || aFlag == "-ray_depth")
12176 {
12177 if (toPrint)
12178 {
12179 theDI << aParams.RaytracingDepth << " ";
12180 continue;
12181 }
12182 else if (++anArgIter >= theArgNb)
12183 {
23fe70ec 12184 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 12185 return 1;
12186 }
12187
12188 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 12189
12190 // We allow RaytracingDepth be more than 10 in case of GI enabled
12191 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 12192 {
23fe70ec 12193 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 12194 return 1;
12195 }
e276548b 12196 else
bc8c79bb 12197 {
12198 aParams.RaytracingDepth = aDepth;
12199 }
12200 }
12201 else if (aFlag == "-shad"
12202 || aFlag == "-shadows")
12203 {
12204 if (toPrint)
12205 {
12206 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
12207 continue;
12208 }
12209
12210 Standard_Boolean toEnable = Standard_True;
12211 if (++anArgIter < theArgNb
dae2a922 12212 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12213 {
12214 --anArgIter;
12215 }
12216 aParams.IsShadowEnabled = toEnable;
12217 }
d84e8669 12218 else if (aFlag == "-shadowmapresolution"
12219 || aFlag == "-shadowmap")
12220 {
12221 if (toPrint)
12222 {
12223 theDI << aParams.ShadowMapResolution << " ";
12224 continue;
12225 }
12226 else if (++anArgIter >= theArgNb)
12227 {
12228 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12229 return 1;
12230 }
12231
12232 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
12233 }
12234 else if (aFlag == "-shadowmapbias")
12235 {
12236 if (toPrint)
12237 {
12238 theDI << aParams.ShadowMapBias << " ";
12239 continue;
12240 }
12241 else if (++anArgIter >= theArgNb)
12242 {
12243 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12244 return 1;
12245 }
12246
12247 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
12248 }
bc8c79bb 12249 else if (aFlag == "-refl"
12250 || aFlag == "-reflections")
12251 {
12252 if (toPrint)
12253 {
12254 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
12255 continue;
12256 }
12257
12258 Standard_Boolean toEnable = Standard_True;
12259 if (++anArgIter < theArgNb
dae2a922 12260 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12261 {
12262 --anArgIter;
12263 }
12264 aParams.IsReflectionEnabled = toEnable;
12265 }
12266 else if (aFlag == "-fsaa")
12267 {
12268 if (toPrint)
12269 {
12270 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
12271 continue;
12272 }
12273
12274 Standard_Boolean toEnable = Standard_True;
12275 if (++anArgIter < theArgNb
dae2a922 12276 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12277 {
12278 --anArgIter;
12279 }
12280 aParams.IsAntialiasingEnabled = toEnable;
12281 }
12282 else if (aFlag == "-gleam")
12283 {
12284 if (toPrint)
12285 {
12286 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
12287 continue;
12288 }
12289
12290 Standard_Boolean toEnable = Standard_True;
12291 if (++anArgIter < theArgNb
dae2a922 12292 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 12293 {
12294 --anArgIter;
12295 }
12296 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 12297 }
189f85a3 12298 else if (aFlag == "-gi")
12299 {
12300 if (toPrint)
12301 {
12302 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
12303 continue;
12304 }
12305
12306 Standard_Boolean toEnable = Standard_True;
12307 if (++anArgIter < theArgNb
dae2a922 12308 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12309 {
12310 --anArgIter;
12311 }
12312 aParams.IsGlobalIlluminationEnabled = toEnable;
12313 if (!toEnable)
12314 {
12315 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
12316 }
12317 }
8c820969 12318 else if (aFlag == "-blockedrng"
12319 || aFlag == "-brng")
12320 {
12321 if (toPrint)
12322 {
12323 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
12324 continue;
12325 }
12326
12327 Standard_Boolean toEnable = Standard_True;
12328 if (++anArgIter < theArgNb
dae2a922 12329 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 12330 {
12331 --anArgIter;
12332 }
12333 aParams.CoherentPathTracingMode = toEnable;
12334 }
b09447ed 12335 else if (aFlag == "-maxrad")
12336 {
12337 if (toPrint)
12338 {
12339 theDI << aParams.RadianceClampingValue << " ";
12340 continue;
12341 }
12342 else if (++anArgIter >= theArgNb)
12343 {
23fe70ec 12344 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 12345 return 1;
12346 }
12347
12348 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
d45edf24 12349 if (!aMaxRadStr.IsRealValue (Standard_True))
b09447ed 12350 {
23fe70ec 12351 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 12352 return 1;
12353 }
12354
12355 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
12356 if (aMaxRadiance <= 0.0)
12357 {
23fe70ec 12358 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 12359 return 1;
12360 }
12361 else
12362 {
12363 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
12364 }
12365 }
3a9b5dc8 12366 else if (aFlag == "-iss")
12367 {
12368 if (toPrint)
12369 {
12370 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
12371 continue;
12372 }
12373
12374 Standard_Boolean toEnable = Standard_True;
12375 if (++anArgIter < theArgNb
dae2a922 12376 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12377 {
12378 --anArgIter;
12379 }
12380 aParams.AdaptiveScreenSampling = toEnable;
12381 }
e084dbbc 12382 else if (aFlag == "-issatomic")
12383 {
12384 if (toPrint)
12385 {
12386 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12387 continue;
12388 }
12389
12390 Standard_Boolean toEnable = Standard_True;
12391 if (++anArgIter < theArgNb
dae2a922 12392 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 12393 {
12394 --anArgIter;
12395 }
12396 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12397 }
3a9b5dc8 12398 else if (aFlag == "-issd")
12399 {
12400 if (toPrint)
12401 {
12402 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12403 continue;
12404 }
12405
12406 Standard_Boolean toEnable = Standard_True;
12407 if (++anArgIter < theArgNb
dae2a922 12408 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12409 {
12410 --anArgIter;
12411 }
12412 aParams.ShowSamplingTiles = toEnable;
12413 }
66d1cdc6 12414 else if (aFlag == "-tilesize")
12415 {
12416 if (toPrint)
12417 {
12418 theDI << aParams.RayTracingTileSize << " ";
12419 continue;
12420 }
12421 else if (++anArgIter >= theArgNb)
12422 {
23fe70ec 12423 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 12424 return 1;
12425 }
12426
12427 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12428 if (aTileSize < 1)
12429 {
23fe70ec 12430 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 12431 return 1;
12432 }
12433 aParams.RayTracingTileSize = aTileSize;
12434 }
4eaaf9d8 12435 else if (aFlag == "-nbtiles")
12436 {
12437 if (toPrint)
12438 {
12439 theDI << aParams.NbRayTracingTiles << " ";
12440 continue;
12441 }
12442 else if (++anArgIter >= theArgNb)
12443 {
23fe70ec 12444 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 12445 return 1;
12446 }
12447
12448 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12449 if (aNbTiles < -1)
4eaaf9d8 12450 {
23fe70ec 12451 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 12452 return 1;
12453 }
66d1cdc6 12454 else if (aNbTiles > 0
12455 && (aNbTiles < 64
12456 || aNbTiles > 1024))
4eaaf9d8 12457 {
23fe70ec 12458 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 12459 }
66d1cdc6 12460 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 12461 }
189f85a3 12462 else if (aFlag == "-env")
12463 {
12464 if (toPrint)
12465 {
12466 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12467 continue;
12468 }
12469
12470 Standard_Boolean toEnable = Standard_True;
12471 if (++anArgIter < theArgNb
dae2a922 12472 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12473 {
12474 --anArgIter;
12475 }
12476 aParams.UseEnvironmentMapBackground = toEnable;
12477 }
78607702 12478 else if (aFlag == "-ignorenormalmap")
12479 {
12480 if (toPrint)
12481 {
12482 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12483 continue;
12484 }
12485
12486 Standard_Boolean toEnable = Standard_True;
12487 if (++anArgIter < theArgNb
dae2a922 12488 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12489 {
12490 --anArgIter;
12491 }
12492 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12493 }
b4327ba8 12494 else if (aFlag == "-twoside")
12495 {
12496 if (toPrint)
12497 {
12498 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12499 continue;
12500 }
12501
12502 Standard_Boolean toEnable = Standard_True;
12503 if (++anArgIter < theArgNb
dae2a922 12504 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12505 {
12506 --anArgIter;
12507 }
12508 aParams.TwoSidedBsdfModels = toEnable;
12509 }
8625ef7e 12510 else if (aFlag == "-shademodel"
12511 || aFlag == "-shadingmodel"
12512 || aFlag == "-shading")
12513 {
12514 if (toPrint)
12515 {
12516 switch (aView->ShadingModel())
12517 {
67312b79 12518 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12519 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12520 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12521 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12522 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12523 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12524 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12525 }
12526 continue;
12527 }
12528
12529 if (++anArgIter >= theArgNb)
12530 {
23fe70ec 12531 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12532 }
12533
dc89236f 12534 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12535 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12536 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12537 {
dc89236f 12538 aView->SetShadingModel (aModel);
8625ef7e 12539 }
12540 else
12541 {
23fe70ec 12542 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12543 return 1;
12544 }
12545 }
67312b79 12546 else if (aFlag == "-pbrenvpow2size"
12547 || aFlag == "-pbrenvp2s"
12548 || aFlag == "-pep2s")
12549 {
12550 if (++anArgIter >= theArgNb)
12551 {
23fe70ec 12552 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12553 return 1;
12554 }
12555
12556 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12557 if (aPbrEnvPow2Size < 1)
12558 {
23fe70ec 12559 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12560 return 1;
12561 }
12562 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12563 }
12564 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12565 || aFlag == "-pbrenvspecmapnblevels"
12566 || aFlag == "-pbrenvspecmaplevels"
12567 || aFlag == "-pbrenvsmln"
12568 || aFlag == "-pesmln")
12569 {
12570 if (++anArgIter >= theArgNb)
12571 {
23fe70ec 12572 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12573 return 1;
12574 }
12575
12576 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12577 if (aPbrEnvSpecMapNbLevels < 2)
12578 {
23fe70ec 12579 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12580 return 1;
12581 }
12582 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12583 }
12584 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12585 || aFlag == "-pbrenvbakingdiffsamples"
12586 || aFlag == "-pbrenvbdsn")
12587 {
12588 if (++anArgIter >= theArgNb)
12589 {
23fe70ec 12590 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12591 return 1;
12592 }
12593
12594 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12595 if (aPbrEnvBakingDiffNbSamples < 1)
12596 {
4551e1be 12597 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12598 return 1;
12599 }
12600 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12601 }
12602 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12603 || aFlag == "-pbrenvbakingspecsamples"
12604 || aFlag == "-pbrenvbssn")
12605 {
12606 if (++anArgIter >= theArgNb)
12607 {
23fe70ec 12608 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12609 return 1;
12610 }
12611
12612 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12613 if (aPbrEnvBakingSpecNbSamples < 1)
12614 {
4551e1be 12615 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
67312b79 12616 return 1;
12617 }
12618 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12619 }
12620 else if (aFlag == "-pbrenvbakingprobability"
12621 || aFlag == "-pbrenvbp")
12622 {
12623 if (++anArgIter >= theArgNb)
12624 {
23fe70ec 12625 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12626 return 1;
12627 }
12628 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12629 if (aPbrEnvBakingProbability < 0.f
12630 || aPbrEnvBakingProbability > 1.f)
12631 {
4551e1be 12632 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
67312b79 12633 return 1;
12634 }
12635 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12636 }
4b1c8733 12637 else if (aFlag == "-resolution")
12638 {
12639 if (++anArgIter >= theArgNb)
12640 {
23fe70ec 12641 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12642 return 1;
12643 }
12644
12645 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12646 if (aResolution.IsIntegerValue())
12647 {
12648 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12649 }
12650 else
12651 {
23fe70ec 12652 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12653 return 1;
12654 }
12655 }
d877e610 12656 else if (aFlag == "-rebuildglsl"
12657 || aFlag == "-rebuild")
12658 {
12659 if (toPrint)
12660 {
12661 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12662 continue;
12663 }
12664
12665 Standard_Boolean toEnable = Standard_True;
12666 if (++anArgIter < theArgNb
dae2a922 12667 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12668 {
12669 --anArgIter;
12670 }
12671 aParams.RebuildRayTracingShaders = toEnable;
12672 }
b27ab03d 12673 else if (aFlag == "-focal")
12674 {
12675 if (++anArgIter >= theArgNb)
12676 {
23fe70ec 12677 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12678 return 1;
12679 }
12680
12681 TCollection_AsciiString aParam (theArgVec[anArgIter]);
d45edf24 12682 if (aParam.IsRealValue (Standard_True))
b27ab03d 12683 {
12684 float aFocalDist = static_cast<float> (aParam.RealValue());
12685 if (aFocalDist < 0)
12686 {
23fe70ec 12687 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12688 return 1;
12689 }
12690 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12691 }
12692 else
12693 {
23fe70ec 12694 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12695 return 1;
12696 }
12697 }
12698 else if (aFlag == "-aperture")
12699 {
12700 if (++anArgIter >= theArgNb)
12701 {
23fe70ec 12702 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12703 return 1;
12704 }
12705
12706 TCollection_AsciiString aParam(theArgVec[anArgIter]);
d45edf24 12707 if (aParam.IsRealValue (Standard_True))
b27ab03d 12708 {
12709 float aApertureSize = static_cast<float> (aParam.RealValue());
12710 if (aApertureSize < 0)
12711 {
23fe70ec 12712 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12713 return 1;
12714 }
12715 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12716 }
12717 else
12718 {
23fe70ec 12719 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12720 return 1;
12721 }
12722 }
eb85ed36 12723 else if (aFlag == "-exposure")
12724 {
12725 if (++anArgIter >= theArgNb)
12726 {
23fe70ec 12727 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12728 return 1;
12729 }
12730
12731 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
d45edf24 12732 if (anExposure.IsRealValue (Standard_True))
eb85ed36 12733 {
12734 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12735 }
12736 else
12737 {
23fe70ec 12738 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12739 return 1;
12740 }
12741 }
12742 else if (aFlag == "-whitepoint")
12743 {
12744 if (++anArgIter >= theArgNb)
12745 {
23fe70ec 12746 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12747 return 1;
12748 }
12749
12750 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
d45edf24 12751 if (aWhitePoint.IsRealValue (Standard_True))
eb85ed36 12752 {
12753 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12754 }
12755 else
12756 {
23fe70ec 12757 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12758 return 1;
12759 }
12760 }
12761 else if (aFlag == "-tonemapping")
12762 {
12763 if (++anArgIter >= theArgNb)
12764 {
23fe70ec 12765 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12766 return 1;
12767 }
12768
12769 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12770 aMode.LowerCase();
12771
12772 if (aMode == "disabled")
12773 {
12774 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12775 }
12776 else if (aMode == "filmic")
12777 {
12778 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12779 }
12780 else
12781 {
23fe70ec 12782 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12783 return 1;
12784 }
12785 }
15669413 12786 else if (aFlag == "-performancestats"
12787 || aFlag == "-performancecounters"
12788 || aFlag == "-perfstats"
12789 || aFlag == "-perfcounters"
12790 || aFlag == "-stats")
12791 {
12792 if (++anArgIter >= theArgNb)
12793 {
23fe70ec 12794 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12795 return 1;
12796 }
12797
12798 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12799 aFlagsStr.LowerCase();
12800 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12801 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12802 {
23fe70ec 12803 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12804 return 1;
12805 }
12806 aView->ChangeRenderingParams().CollectedStats = aFlags;
12807 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12808 }
12809 else if (aFlag == "-perfupdateinterval"
12810 || aFlag == "-statsupdateinterval")
12811 {
12812 if (++anArgIter >= theArgNb)
12813 {
23fe70ec 12814 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12815 return 1;
12816 }
12817 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12818 }
5e30547b 12819 else if (aFlag == "-perfchart"
12820 || aFlag == "-statschart")
12821 {
12822 if (++anArgIter >= theArgNb)
12823 {
23fe70ec 12824 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12825 return 1;
12826 }
12827 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12828 }
12829 else if (aFlag == "-perfchartmax"
12830 || aFlag == "-statschartmax")
12831 {
12832 if (++anArgIter >= theArgNb)
12833 {
23fe70ec 12834 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12835 return 1;
12836 }
12837 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12838 }
0e3025bc 12839 else if (aFlag == "-frustumculling"
12840 || aFlag == "-culling")
12841 {
12842 if (toPrint)
12843 {
12844 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12845 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12846 "noUpdate") << " ";
12847 continue;
12848 }
12849
12850 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12851 if (++anArgIter < theArgNb)
12852 {
12853 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12854 aStateStr.LowerCase();
12855 bool toEnable = true;
dae2a922 12856 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12857 {
12858 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12859 }
12860 else if (aStateStr == "noupdate"
12861 || aStateStr == "freeze")
12862 {
12863 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12864 }
12865 else
12866 {
12867 --anArgIter;
12868 }
12869 }
12870 aParams.FrustumCullingState = aState;
12871 }
e276548b 12872 else
12873 {
23fe70ec 12874 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12875 return 1;
e276548b 12876 }
12877 }
189f85a3 12878
4c7a3fae 12879 // set current view parameters as defaults
12880 if (toSyncDefaults)
12881 {
12882 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12883 }
12884 if (toSyncAllViews)
12885 {
12886 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12887 {
12888 aViewIter.Value()->ChangeRenderingParams() = aParams;
12889 }
12890 }
189f85a3 12891 return 0;
12892}
12893
79b544e6 12894//=======================================================================
12895//function : searchInfo
12896//purpose :
12897//=======================================================================
12898inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12899 const TCollection_AsciiString& theKey)
12900{
12901 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12902 {
12903 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12904 {
12905 return anIter.Value();
12906 }
12907 }
12908 return TCollection_AsciiString();
12909}
12910
12911//=======================================================================
12912//function : VStatProfiler
12913//purpose :
12914//=======================================================================
12915static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12916 Standard_Integer theArgNb,
12917 const char** theArgVec)
12918{
12919 Handle(V3d_View) aView = ViewerTest::CurrentView();
12920 if (aView.IsNull())
12921 {
23fe70ec 12922 Message::SendFail ("Error: no active viewer");
79b544e6 12923 return 1;
12924 }
12925
12926 Standard_Boolean toRedraw = Standard_True;
12927 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12928 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12929 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12930 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12931 {
12932 Standard_CString anArg (theArgVec[anArgIter]);
12933 TCollection_AsciiString aFlag (anArg);
12934 aFlag.LowerCase();
12935 if (aFlag == "-noredraw")
12936 {
12937 toRedraw = Standard_False;
12938 }
12939 else
12940 {
12941 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12942 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12943 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12944 else if (aFlag == "alllayers"
12945 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12946 else if (aFlag == "allstructs"
a2803f37 12947 || aFlag == "allstructures"
12948 || aFlag == "structs"
12949 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12950 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12951 else if (aFlag == "allarrays"
12952 || aFlag == "fillarrays"
12953 || aFlag == "linearrays"
12954 || aFlag == "pointarrays"
12955 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12956 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12957 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12958 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12959 else if (aFlag == "geommem"
12960 || aFlag == "texturemem"
12961 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12962 else if (aFlag == "elapsedframe"
12963 || aFlag == "cpuframeaverage"
12964 || aFlag == "cpupickingaverage"
12965 || aFlag == "cpucullingaverage"
12966 || aFlag == "cpudynaverage"
12967 || aFlag == "cpuframemax"
12968 || aFlag == "cpupickingmax"
12969 || aFlag == "cpucullingmax"
12970 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12971 else
12972 {
23fe70ec 12973 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12974 continue;
12975 }
12976
12977 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12978 }
12979 }
12980
12981 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12982 {
12983 aView->ChangeRenderingParams().CollectedStats =
12984 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12985
12986 if (toRedraw)
12987 {
12988 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12989 aView->Redraw();
12990 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12991 }
12992
12993 TColStd_IndexedDataMapOfStringString aDict;
12994 aView->StatisticInformation (aDict);
12995
12996 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12997
12998 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12999 {
13000 Standard_CString anArg(theArgVec[anArgIter]);
13001 TCollection_AsciiString aFlag(anArg);
13002 aFlag.LowerCase();
13003 if (aFlag == "fps")
13004 {
13005 theDI << searchInfo (aDict, "FPS") << " ";
13006 }
13007 else if (aFlag == "cpu")
13008 {
13009 theDI << searchInfo (aDict, "CPU FPS") << " ";
13010 }
13011 else if (aFlag == "alllayers")
13012 {
13013 theDI << searchInfo (aDict, "Layers") << " ";
13014 }
13015 else if (aFlag == "layers")
13016 {
13017 theDI << searchInfo (aDict, "Rendered layers") << " ";
13018 }
a2803f37 13019 else if (aFlag == "allstructs"
13020 || aFlag == "allstructures")
79b544e6 13021 {
13022 theDI << searchInfo (aDict, "Structs") << " ";
13023 }
a2803f37 13024 else if (aFlag == "structs"
13025 || aFlag == "structures")
79b544e6 13026 {
a2803f37 13027 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
13028 if (aRend.IsEmpty()) // all structures rendered
13029 {
13030 aRend = searchInfo (aDict, "Structs");
13031 }
13032 theDI << aRend << " ";
79b544e6 13033 }
13034 else if (aFlag == "groups")
13035 {
13036 theDI << searchInfo (aDict, "Rendered groups") << " ";
13037 }
13038 else if (aFlag == "allarrays")
13039 {
13040 theDI << searchInfo (aDict, "Rendered arrays") << " ";
13041 }
13042 else if (aFlag == "fillarrays")
13043 {
13044 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
13045 }
13046 else if (aFlag == "linearrays")
13047 {
13048 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
13049 }
13050 else if (aFlag == "pointarrays")
13051 {
13052 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
13053 }
13054 else if (aFlag == "textarrays")
13055 {
13056 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
13057 }
13058 else if (aFlag == "triangles")
13059 {
13060 theDI << searchInfo (aDict, "Rendered triangles") << " ";
13061 }
13062 else if (aFlag == "points")
13063 {
13064 theDI << searchInfo (aDict, "Rendered points") << " ";
13065 }
13066 else if (aFlag == "geommem")
13067 {
13068 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
13069 }
13070 else if (aFlag == "texturemem")
13071 {
13072 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
13073 }
13074 else if (aFlag == "framemem")
13075 {
13076 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
13077 }
13078 else if (aFlag == "elapsedframe")
13079 {
13080 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
13081 }
13082 else if (aFlag == "cpuframe_average")
13083 {
13084 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
13085 }
13086 else if (aFlag == "cpupicking_average")
13087 {
13088 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
13089 }
13090 else if (aFlag == "cpuculling_average")
13091 {
13092 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
13093 }
13094 else if (aFlag == "cpudyn_average")
13095 {
13096 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
13097 }
13098 else if (aFlag == "cpuframe_max")
13099 {
13100 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
13101 }
13102 else if (aFlag == "cpupicking_max")
13103 {
13104 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
13105 }
13106 else if (aFlag == "cpuculling_max")
13107 {
13108 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
13109 }
13110 else if (aFlag == "cpudyn_max")
13111 {
13112 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
13113 }
13114 }
13115 }
13116 else
13117 {
13118 if (toRedraw)
13119 {
13120 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
13121 aView->Redraw();
13122 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
13123 }
13124 theDI << "Statistic info:\n" << aView->StatisticInformation();
13125 }
13126 return 0;
13127}
13128
0717ddc1 13129//=======================================================================
13130//function : VXRotate
13131//purpose :
13132//=======================================================================
13133static Standard_Integer VXRotate (Draw_Interpretor& di,
13134 Standard_Integer argc,
13135 const char ** argv)
13136{
13137 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
13138 if (aContext.IsNull())
13139 {
586db386 13140 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 13141 return 1;
13142 }
8693dfd0 13143
0717ddc1 13144 if (argc != 3)
13145 {
586db386 13146 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 13147 return 1;
13148 }
13149
13150 TCollection_AsciiString aName (argv[1]);
13151 Standard_Real anAngle = Draw::Atof (argv[2]);
13152
13153 // find object
13154 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
13155 Handle(AIS_InteractiveObject) anIObj;
8f521168 13156 if (!aMap.Find2 (aName, anIObj))
0717ddc1 13157 {
586db386 13158 di << "Use 'vdisplay' before\n";
0717ddc1 13159 return 1;
13160 }
0717ddc1 13161
8f521168 13162 gp_Trsf aTransform;
13163 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
13164 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 13165
8f521168 13166 aContext->SetLocation (anIObj, aTransform);
13167 aContext->UpdateCurrentViewer();
0717ddc1 13168 return 0;
13169}
13170
ff6122e0 13171namespace
13172{
13173 //! Structure for setting AIS_Manipulator::SetPart() property.
13174 struct ManipAxisModeOnOff
13175 {
13176 Standard_Integer Axis;
13177 AIS_ManipulatorMode Mode;
13178 Standard_Boolean ToEnable;
13179
13180 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
13181 };
13182
13183 enum ManipAjustPosition
13184 {
13185 ManipAjustPosition_Off,
13186 ManipAjustPosition_Center,
13187 ManipAjustPosition_Location,
13188 ManipAjustPosition_ShapeLocation,
13189 };
13190}
13191
625e1958 13192//===============================================================================================
13193//function : VManipulator
13194//purpose :
13195//===============================================================================================
13196static int VManipulator (Draw_Interpretor& theDi,
13197 Standard_Integer theArgsNb,
13198 const char** theArgVec)
13199{
bbf3fcde 13200 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 13201 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 13202 if (aCurrentView.IsNull()
625e1958 13203 || aViewer.IsNull())
13204 {
23fe70ec 13205 Message::SendFail ("Error: no active viewer");
625e1958 13206 return 1;
13207 }
13208
13209 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
13210 Standard_Integer anArgIter = 1;
ff6122e0 13211 Handle(AIS_Manipulator) aManipulator;
13212 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
13213 TCollection_AsciiString aName;
13214 // parameters
13215 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
13216 Standard_Real aGap = -1.0, aSize = -1.0;
13217 NCollection_Sequence<ManipAxisModeOnOff> aParts;
13218 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
13219 //
13220 bool toDetach = false;
13221 AIS_Manipulator::OptionsForAttach anAttachOptions;
13222 Handle(AIS_InteractiveObject) anAttachObject;
13223 Handle(V3d_View) aViewAffinity;
13224 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
13225 //
13226 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
13227 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
13228 Standard_Integer toStopMouseTransform = -1;
13229 // explicit transformation
13230 gp_Trsf aTrsf;
13231 gp_XYZ aTmpXYZ;
13232 Standard_Real aTmpReal = 0.0;
13233 gp_XYZ aRotPnt, aRotAxis;
625e1958 13234 for (; anArgIter < theArgsNb; ++anArgIter)
13235 {
ff6122e0 13236 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13237 anArg.LowerCase();
13238 if (anUpdateTool.parseRedrawMode (anArg))
13239 {
13240 continue;
13241 }
13242 else if (anArg == "-help")
13243 {
13244 theDi.PrintHelp (theArgVec[0]);
13245 return 0;
13246 }
13247 //
13248 else if (anArg == "-autoactivate"
13249 || anArg == "-noautoactivate")
13250 {
13251 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13252 }
13253 else if (anArg == "-followtranslation"
13254 || anArg == "-nofollowtranslation")
13255 {
13256 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13257 }
13258 else if (anArg == "-followrotation"
13259 || anArg == "-nofollowrotation")
13260 {
13261 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13262 }
13263 else if (anArg == "-followdragging"
13264 || anArg == "-nofollowdragging")
13265 {
13266 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13267 }
13268 else if (anArg == "-gap"
13269 && anArgIter + 1 < theArgsNb
13270 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
13271 && aGap >= 0.0)
13272 {
13273 ++anArgIter;
13274 }
13275 else if (anArg == "-size"
13276 && anArgIter + 1 < theArgsNb
13277 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
13278 && aSize > 0.0)
13279 {
13280 ++anArgIter;
13281 }
13282 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
13283 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
13284 {
13285 ManipAxisModeOnOff aPart;
13286 Standard_Integer aMode = 0;
13287 if (anArg == "-part")
13288 {
13289 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
13290 || aPart.Axis < 0 || aPart.Axis > 3)
13291 {
13292 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
13293 return 1;
13294 }
13295 }
13296 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
13297 || aMode < 1 || aMode > 4)
13298 {
13299 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
13300 return 1;
13301 }
13302 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
13303 {
13304 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
13305 return 1;
13306 }
13307 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
13308 aParts.Append (aPart);
13309 }
13310 else if (anArg == "-pos"
13311 && anArgIter + 3 < theArgsNb
13312 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
13313 {
13314 anArgIter += 3;
13315 if (anArgIter + 3 < theArgsNb
13316 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
13317 && aVDir.Modulus() > Precision::Confusion())
13318 {
13319 anArgIter += 3;
13320 }
13321 if (anArgIter + 3 < theArgsNb
13322 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
13323 && anXDir.Modulus() > Precision::Confusion())
13324 {
13325 anArgIter += 3;
13326 }
13327 }
13328 else if (anArg == "-zoomable"
13329 || anArg == "-notzoomable")
13330 {
13331 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
13332 }
13333 //
13334 else if (anArg == "-adjustposition"
13335 || anArg == "-noadjustposition")
13336 {
13337 anAttachPos = ManipAjustPosition_Center;
13338 if (anArgIter + 1 < theArgsNb)
13339 {
13340 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
13341 aPosName.LowerCase();
13342 if (aPosName == "0")
13343 {
13344 anAttachPos = ManipAjustPosition_Off;
13345 }
13346 else if (aPosName == "1"
13347 || aPosName == "center")
13348 {
13349 anAttachPos = ManipAjustPosition_Center;
13350 }
13351 else if (aPosName == "transformation"
13352 || aPosName == "trsf"
13353 || aPosName == "location"
13354 || aPosName == "loc")
13355 {
13356 anAttachPos = ManipAjustPosition_Location;
13357 }
13358 else if (aPosName == "shapelocation"
13359 || aPosName == "shapeloc")
13360 {
13361 anAttachPos = ManipAjustPosition_ShapeLocation;
13362 }
13363 else
13364 {
13365 --anArgIter;
13366 }
13367 }
13368 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
13369 }
13370 else if (anArg == "-adjustsize"
13371 || anArg == "-noadjustsize")
13372 {
13373 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13374 }
13375 else if (anArg == "-enablemodes"
13376 || anArg == "-enablemodes")
13377 {
13378 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
13379 }
13380 //
13381 else if (anArg == "-starttransform"
13382 && anArgIter + 2 < theArgsNb
13383 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
13384 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
13385 {
13386 anArgIter += 2;
13387 }
13388 else if (anArg == "-transform"
13389 && anArgIter + 2 < theArgsNb
13390 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
13391 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
13392 {
13393 anArgIter += 2;
13394 }
13395 else if (anArg == "-stoptransform")
13396 {
13397 toStopMouseTransform = 1;
13398 if (anArgIter + 1 < theArgsNb
13399 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
13400 {
13401 ++anArgIter;
13402 toStopMouseTransform = 0;
13403 }
13404 }
13405 //
13406 else if (anArg == "-move"
13407 && anArgIter + 3 < theArgsNb
13408 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
13409 {
13410 anArgIter += 3;
13411 aTrsf.SetTranslationPart (aTmpXYZ);
13412 }
13413 else if (anArg == "-scale"
13414 && anArgIter + 1 < theArgsNb
13415 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
13416 {
13417 ++anArgIter;
13418 aTrsf.SetScale (gp_Pnt(), aTmpReal);
13419 }
13420 else if (anArg == "-rotate"
13421 && anArgIter + 7 < theArgsNb
13422 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
13423 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
13424 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
13425 {
13426 anArgIter += 7;
13427 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
13428 }
13429 //
13430 else if (anArg == "-detach")
13431 {
13432 toDetach = true;
13433 }
13434 else if (anArg == "-attach"
13435 && anArgIter + 1 < theArgsNb)
13436 {
13437 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
13438 if (!aMapAIS.Find2 (anObjName, anAttachObject))
13439 {
13440 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
13441 return 1;
13442 }
625e1958 13443
ff6122e0 13444 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
13445 {
13446 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13447 if (!aManip.IsNull()
13448 && aManip->IsAttached()
13449 && aManip->Object() == anAttachObject)
13450 {
13451 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
13452 return 1;
13453 }
13454 }
13455 }
13456 else if (anArg == "-view"
13457 && anArgIter + 1 < theArgsNb
13458 && aViewAffinity.IsNull())
13459 {
13460 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
13461 if (aViewString == "active")
13462 {
13463 aViewAffinity = ViewerTest::CurrentView();
13464 }
13465 else // Check view name
13466 {
13467 ViewerTest_Names aViewNames (aViewString);
13468 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13469 {
13470 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
13471 return 1;
13472 }
13473 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13474 if (aViewAffinity.IsNull())
13475 {
13476 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
13477 return 1;
13478 }
13479 }
13480 }
13481 else if (aName.IsEmpty())
13482 {
13483 aName = theArgVec[anArgIter];
13484 if (!aMapAIS.IsBound2 (aName))
13485 {
13486 aManipulator = new AIS_Manipulator();
13487 aManipulator->SetModeActivationOnDetection (true);
13488 aMapAIS.Bind (aManipulator, aName);
13489 }
13490 else
13491 {
13492 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
13493 if (aManipulator.IsNull())
13494 {
13495 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
13496 return 1;
13497 }
13498 }
13499 }
13500 else
13501 {
13502 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13503 }
625e1958 13504 }
13505
625e1958 13506 if (aName.IsEmpty())
13507 {
23fe70ec 13508 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 13509 return 1;
13510 }
ff6122e0 13511 if (!toDetach
13512 && aManipulator.IsNull())
625e1958 13513 {
8b037fe4 13514 aManipulator = new AIS_Manipulator();
49582f9d 13515 aManipulator->SetModeActivationOnDetection (true);
625e1958 13516 aMapAIS.Bind (aManipulator, aName);
13517 }
625e1958 13518
13519 // -----------------------------------------
13520 // change properties of manipulator instance
13521 // -----------------------------------------
13522
ff6122e0 13523 if (toAutoActivate != -1)
625e1958 13524 {
ff6122e0 13525 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
625e1958 13526 }
ff6122e0 13527 if (toFollowTranslation != -1)
625e1958 13528 {
ff6122e0 13529 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
625e1958 13530 }
ff6122e0 13531 if (toFollowRotation != -1)
625e1958 13532 {
ff6122e0 13533 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
625e1958 13534 }
ff6122e0 13535 if (toFollowDragging != -1)
f522ce50 13536 {
ff6122e0 13537 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
f522ce50 13538 }
ff6122e0 13539 if (aGap >= 0.0f)
625e1958 13540 {
ff6122e0 13541 aManipulator->SetGap ((float )aGap);
625e1958 13542 }
ff6122e0 13543
13544 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
625e1958 13545 {
ff6122e0 13546 const ManipAxisModeOnOff& aPart = aPartIter.Value();
13547 if (aPart.Axis == -1)
625e1958 13548 {
ff6122e0 13549 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
625e1958 13550 }
ff6122e0 13551 else
84b904bc 13552 {
ff6122e0 13553 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
84b904bc 13554 }
84b904bc 13555 }
625e1958 13556
ff6122e0 13557 if (aSize > 0.0)
625e1958 13558 {
ff6122e0 13559 aManipulator->SetSize ((float )aSize);
625e1958 13560 }
ff6122e0 13561 if (isZoomable != -1)
625e1958 13562 {
ff6122e0 13563 aManipulator->SetZoomPersistence (isZoomable == 0);
625e1958 13564
13565 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13566 {
13567 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13568 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13569 }
13570 }
13571
ff6122e0 13572 // ----------------------------------
13573 // detach existing manipulator object
13574 // ----------------------------------
13575
13576 if (toDetach)
13577 {
13578 aManipulator->Detach();
13579 aMapAIS.UnBind2 (aName);
13580 ViewerTest::GetAISContext()->Remove (aManipulator, false);
13581 }
13582
625e1958 13583 // ---------------------------------------------------
13584 // attach, detach or access manipulator from an object
13585 // ---------------------------------------------------
13586
ff6122e0 13587 if (!anAttachObject.IsNull())
625e1958 13588 {
ff6122e0 13589 aManipulator->Attach (anAttachObject, anAttachOptions);
13590 }
13591 if (!aViewAffinity.IsNull())
13592 {
13593 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
8b037fe4 13594 anIter.More(); anIter.Next())
625e1958 13595 {
ff6122e0 13596 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
625e1958 13597 }
ff6122e0 13598 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
13599 }
625e1958 13600
ff6122e0 13601 if (anAttachPos != ManipAjustPosition_Off
13602 && aManipulator->IsAttached()
13603 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
13604 {
13605 gp_Ax2 aPosition = gp::XOY();
13606 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
13607 switch (anAttachPos)
bbf3fcde 13608 {
ff6122e0 13609 case ManipAjustPosition_Off:
bbf3fcde 13610 {
ff6122e0 13611 break;
bbf3fcde 13612 }
ff6122e0 13613 case ManipAjustPosition_Location:
bbf3fcde 13614 {
ff6122e0 13615 aPosition = gp::XOY().Transformed (aBaseTrsf);
13616 break;
bbf3fcde 13617 }
ff6122e0 13618 case ManipAjustPosition_ShapeLocation:
bbf3fcde 13619 {
ff6122e0 13620 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
bbf3fcde 13621 {
ff6122e0 13622 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
bbf3fcde 13623 }
ff6122e0 13624 else
bbf3fcde 13625 {
ff6122e0 13626 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
bbf3fcde 13627 return 1;
13628 }
ff6122e0 13629 break;
bbf3fcde 13630 }
ff6122e0 13631 case ManipAjustPosition_Center:
bbf3fcde 13632 {
ff6122e0 13633 Bnd_Box aBox;
13634 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
13635 {
13636 Bnd_Box anObjBox;
13637 anObjIter.Value()->BoundingBox (anObjBox);
13638 aBox.Add (anObjBox);
13639 }
13640 aBox = aBox.FinitePart();
13641 if (!aBox.IsVoid())
13642 {
13643 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
13644 aPosition.SetLocation (aCenter);
13645 }
13646 break;
bbf3fcde 13647 }
bbf3fcde 13648 }
ff6122e0 13649 aManipulator->SetPosition (aPosition);
13650 }
13651 if (!Precision::IsInfinite (aLocation.X()))
13652 {
13653 if (aVDir.Modulus() <= Precision::Confusion())
13654 {
13655 aVDir = aManipulator->Position().Direction().XYZ();
13656 }
13657 if (anXDir.Modulus() <= Precision::Confusion())
13658 {
13659 anXDir = aManipulator->Position().XDirection().XYZ();
13660 }
13661 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
625e1958 13662 }
13663
13664 // --------------------------------------
13665 // apply transformation using manipulator
13666 // --------------------------------------
13667
ff6122e0 13668 if (aMousePosFrom.x() != IntegerLast())
625e1958 13669 {
ff6122e0 13670 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
625e1958 13671 }
ff6122e0 13672 if (aMousePosTo.x() != IntegerLast())
625e1958 13673 {
ff6122e0 13674 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
625e1958 13675 }
ff6122e0 13676 if (toStopMouseTransform != -1)
625e1958 13677 {
ff6122e0 13678 aManipulator->StopTransform (toStopMouseTransform == 1);
625e1958 13679 }
13680
ff6122e0 13681 if (aTrsf.Form() != gp_Identity)
625e1958 13682 {
ff6122e0 13683 aManipulator->Transform (aTrsf);
625e1958 13684 }
13685
ff6122e0 13686 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
625e1958 13687 {
ff6122e0 13688 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
625e1958 13689 }
625e1958 13690 return 0;
13691}
13692
8e5fb5ea 13693//===============================================================================================
13694//function : VSelectionProperties
13695//purpose :
13696//===============================================================================================
13697static int VSelectionProperties (Draw_Interpretor& theDi,
13698 Standard_Integer theArgsNb,
13699 const char** theArgVec)
13700{
13701 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13702 if (aCtx.IsNull())
13703 {
23fe70ec 13704 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13705 return 1;
13706 }
13707
be3d8cbc 13708 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13709 {
13710 // handle obsolete alias
13711 bool toEnable = true;
13712 if (theArgsNb < 2)
13713 {
13714 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13715 return 0;
13716 }
13717 else if (theArgsNb != 2
dae2a922 13718 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13719 {
23fe70ec 13720 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13721 return 1;
13722 }
13723 if (toEnable != aCtx->ToHilightSelected())
13724 {
13725 aCtx->ClearDetected();
13726 aCtx->SetToHilightSelected (toEnable);
13727 }
13728 return 0;
13729 }
13730
f838dac4 13731 Standard_Boolean toPrint = theArgsNb == 1;
13732 Standard_Boolean toRedraw = Standard_False;
13733 Standard_Integer anArgIter = 1;
13734 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13735 if (anArgIter < theArgsNb)
13736 {
13737 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13738 anArgFirst.LowerCase();
13739 ++anArgIter;
13740 if (anArgFirst == "dynhighlight"
13741 || anArgFirst == "dynhilight"
13742 || anArgFirst == "dynamichighlight"
13743 || anArgFirst == "dynamichilight")
13744 {
13745 aType = Prs3d_TypeOfHighlight_Dynamic;
13746 }
13747 else if (anArgFirst == "localdynhighlight"
13748 || anArgFirst == "localdynhilight"
13749 || anArgFirst == "localdynamichighlight"
13750 || anArgFirst == "localdynamichilight")
13751 {
13752 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13753 }
13754 else if (anArgFirst == "selhighlight"
13755 || anArgFirst == "selhilight"
13756 || anArgFirst == "selectedhighlight"
13757 || anArgFirst == "selectedhilight")
13758 {
13759 aType = Prs3d_TypeOfHighlight_Selected;
13760 }
13761 else if (anArgFirst == "localselhighlight"
13762 || anArgFirst == "localselhilight"
13763 || anArgFirst == "localselectedhighlight"
13764 || anArgFirst == "localselectedhilight")
13765 {
13766 aType = Prs3d_TypeOfHighlight_LocalSelected;
13767 }
13768 else
13769 {
13770 --anArgIter;
13771 }
13772 }
13773 for (; anArgIter < theArgsNb; ++anArgIter)
13774 {
13775 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13776 anArg.LowerCase();
13777 if (anArg == "-help")
13778 {
13779 theDi.PrintHelp (theArgVec[0]);
13780 return 0;
13781 }
13782 else if (anArg == "-print")
13783 {
13784 toPrint = Standard_True;
13785 }
13786 else if (anArg == "-autoactivate")
13787 {
13788 Standard_Boolean toEnable = Standard_True;
13789 if (anArgIter + 1 < theArgsNb
dae2a922 13790 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13791 {
13792 ++anArgIter;
13793 }
13794 aCtx->SetAutoActivateSelection (toEnable);
13795 }
be3d8cbc 13796 else if (anArg == "-automatichighlight"
13797 || anArg == "-automatichilight"
13798 || anArg == "-autohighlight"
13799 || anArg == "-autohilight")
13800 {
13801 Standard_Boolean toEnable = Standard_True;
13802 if (anArgIter + 1 < theArgsNb
dae2a922 13803 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13804 {
13805 ++anArgIter;
13806 }
13807 aCtx->ClearSelected (false);
13808 aCtx->ClearDetected();
13809 aCtx->SetAutomaticHilight (toEnable);
13810 toRedraw = true;
13811 }
13812 else if (anArg == "-highlightselected"
13813 || anArg == "-hilightselected")
13814 {
13815 Standard_Boolean toEnable = Standard_True;
13816 if (anArgIter + 1 < theArgsNb
dae2a922 13817 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13818 {
13819 ++anArgIter;
13820 }
13821 aCtx->ClearDetected();
13822 aCtx->SetToHilightSelected (toEnable);
13823 toRedraw = true;
13824 }
14c4193d 13825 else if (anArg == "-pickstrategy"
13826 || anArg == "-pickingstrategy")
13827 {
13828 if (++anArgIter >= theArgsNb)
13829 {
23fe70ec 13830 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13831 return 1;
13832 }
13833
13834 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13835 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13836 aVal.LowerCase();
13837 if (aVal == "first"
13838 || aVal == "firstaccepted"
13839 || aVal == "firstacceptable")
13840 {
13841 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13842 }
13843 else if (aVal == "topmost"
13844 || aVal == "onlyTopmost")
13845 {
13846 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13847 }
13848 else
13849 {
23fe70ec 13850 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13851 return 1;
13852 }
13853
13854 aCtx->SetPickingStrategy (aStrategy);
13855 }
f838dac4 13856 else if (anArg == "-pixtol"
13857 && anArgIter + 1 < theArgsNb)
13858 {
13859 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13860 }
8c36926a 13861 else if (anArg == "-preferclosest")
13862 {
13863 bool toPreferClosest = true;
13864 if (anArgIter + 1 < theArgsNb
13865 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13866 {
13867 ++anArgIter;
13868 }
13869 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13870 }
13871 else if ((anArg == "-depthtol"
13872 || anArg == "-depthtolerance")
13873 && anArgIter + 1 < theArgsNb)
13874 {
13875 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13876 aTolType.LowerCase();
13877 if (aTolType == "uniform")
13878 {
13879 if (anArgIter + 1 >= theArgsNb)
13880 {
13881 Message::SendFail() << "Syntax error: wrong number of arguments";
13882 return 1;
13883 }
13884 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13885 Draw::Atof (theArgVec[++anArgIter]));
13886 }
13887 else if (aTolType == "uniformpx")
13888 {
13889 if (anArgIter + 1 >= theArgsNb)
13890 {
13891 Message::SendFail() << "Syntax error: wrong number of arguments";
13892 return 1;
13893 }
13894 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13895 Draw::Atof (theArgVec[++anArgIter]));
13896 }
13897 else if (aTolType == "sensfactor")
13898 {
13899 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13900 }
13901 else
13902 {
13903 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13904 return 1;
13905 }
13906 }
f838dac4 13907 else if ((anArg == "-mode"
13908 || anArg == "-dispmode")
13909 && anArgIter + 1 < theArgsNb)
13910 {
13911 if (aType == Prs3d_TypeOfHighlight_None)
13912 {
23fe70ec 13913 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13914 return 1;
13915 }
8e5fb5ea 13916
f838dac4 13917 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13918 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13919 aStyle->SetDisplayMode (aDispMode);
13920 toRedraw = Standard_True;
13921 }
13922 else if (anArg == "-layer"
13923 && anArgIter + 1 < theArgsNb)
13924 {
13925 if (aType == Prs3d_TypeOfHighlight_None)
13926 {
23fe70ec 13927 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13928 return 1;
13929 }
8e5fb5ea 13930
55c8f0f7
BB
13931 ++anArgIter;
13932 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13933 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13934 {
23fe70ec 13935 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13936 return 1;
f838dac4 13937 }
8e5fb5ea 13938
f838dac4 13939 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13940 aStyle->SetZLayer (aNewLayer);
13941 toRedraw = Standard_True;
13942 }
13943 else if (anArg == "-hicolor"
13944 || anArg == "-selcolor"
13945 || anArg == "-color")
13946 {
13947 if (anArg.StartsWith ("-hi"))
13948 {
13949 aType = Prs3d_TypeOfHighlight_Dynamic;
13950 }
13951 else if (anArg.StartsWith ("-sel"))
13952 {
13953 aType = Prs3d_TypeOfHighlight_Selected;
13954 }
13955 else if (aType == Prs3d_TypeOfHighlight_None)
13956 {
23fe70ec 13957 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13958 return 1;
13959 }
8e5fb5ea 13960
f838dac4 13961 Quantity_Color aColor;
dae2a922 13962 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13963 theArgVec + anArgIter + 1,
13964 aColor);
f838dac4 13965 if (aNbParsed == 0)
13966 {
23fe70ec 13967 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13968 return 1;
13969 }
13970 anArgIter += aNbParsed;
8e5fb5ea 13971
f838dac4 13972 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13973 aStyle->SetColor (aColor);
13974 toRedraw = Standard_True;
13975 }
13976 else if ((anArg == "-transp"
13977 || anArg == "-transparency"
13978 || anArg == "-hitransp"
13979 || anArg == "-seltransp"
13980 || anArg == "-hitransplocal"
13981 || anArg == "-seltransplocal")
13982 && anArgIter + 1 < theArgsNb)
13983 {
13984 if (anArg.StartsWith ("-hi"))
13985 {
13986 aType = Prs3d_TypeOfHighlight_Dynamic;
13987 }
13988 else if (anArg.StartsWith ("-sel"))
13989 {
13990 aType = Prs3d_TypeOfHighlight_Selected;
13991 }
13992 else if (aType == Prs3d_TypeOfHighlight_None)
13993 {
23fe70ec 13994 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13995 return 1;
13996 }
8e5fb5ea 13997
f838dac4 13998 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13999 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
14000 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
14001 toRedraw = Standard_True;
14002 }
14003 else if ((anArg == "-mat"
14004 || anArg == "-material")
14005 && anArgIter + 1 < theArgsNb)
14006 {
14007 if (aType == Prs3d_TypeOfHighlight_None)
14008 {
23fe70ec 14009 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 14010 return 1;
14011 }
8e5fb5ea 14012
f838dac4 14013 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
14014 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 14015 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 14016 {
14017 ++anArgIter;
14018 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
14019 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
14020 Graphic3d_MaterialAspect aMat (aMatName);
14021 aMat.SetColor (aStyle->Color());
14022 aMat.SetTransparency (aStyle->Transparency());
14023 anAspect->SetFrontMaterial (aMat);
14024 anAspect->SetInteriorColor (aStyle->Color());
14025 aStyle->SetBasicFillAreaAspect (anAspect);
14026 }
14027 else
14028 {
14029 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
14030 }
14031 toRedraw = Standard_True;
14032 }
14033 else
14034 {
23fe70ec 14035 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 14036 return 1;
f838dac4 14037 }
8e5fb5ea 14038 }
14039
f838dac4 14040 if (toPrint)
8e5fb5ea 14041 {
f838dac4 14042 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
14043 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 14044 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 14045 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
14046 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 14047 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 14048 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
14049 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
14050 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
14051 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
14052 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
14053 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
14054 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
14055 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 14056 }
14057
14058 if (aCtx->NbSelected() != 0 && toRedraw)
14059 {
14060 aCtx->HilightSelected (Standard_True);
14061 }
14062
14063 return 0;
14064}
14065
decdee7d 14066//===============================================================================================
14067//function : VDumpSelectionImage
14068//purpose :
14069//===============================================================================================
14070static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
14071 Standard_Integer theArgsNb,
14072 const char** theArgVec)
14073{
14074 if (theArgsNb < 2)
14075 {
23fe70ec 14076 Message::SendFail() << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'";
decdee7d 14077 return 1;
14078 }
14079
14080 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 14081 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 14082 if (aContext.IsNull())
14083 {
23fe70ec 14084 Message::SendFail ("Error: no active viewer");
decdee7d 14085 return 1;
14086 }
14087
14088 TCollection_AsciiString aFile;
14089 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 14090 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 14091 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 14092 Standard_Integer aPickedIndex = 1;
14093 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
14094 {
14095 TCollection_AsciiString aParam (theArgVec[anArgIter]);
14096 aParam.LowerCase();
14097 if (aParam == "-type")
14098 {
14099 if (++anArgIter >= theArgsNb)
14100 {
23fe70ec 14101 Message::SendFail ("Syntax error: wrong number parameters of flag '-depth'");
decdee7d 14102 return 1;
14103 }
14104
14105 TCollection_AsciiString aValue (theArgVec[anArgIter]);
14106 aValue.LowerCase();
14107 if (aValue == "depth"
14108 || aValue == "normdepth"
14109 || aValue == "normalizeddepth")
14110 {
14111 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 14112 anImgFormat = Image_Format_GrayF;
decdee7d 14113 }
14114 if (aValue == "depthinverted"
14115 || aValue == "normdepthinverted"
14116 || aValue == "normalizeddepthinverted"
14117 || aValue == "inverted")
14118 {
14119 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 14120 anImgFormat = Image_Format_GrayF;
decdee7d 14121 }
14122 else if (aValue == "unnormdepth"
14123 || aValue == "unnormalizeddepth")
14124 {
14125 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 14126 anImgFormat = Image_Format_GrayF;
decdee7d 14127 }
14128 else if (aValue == "objectcolor"
14129 || aValue == "object"
14130 || aValue == "color")
14131 {
14132 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
14133 }
14134 else if (aValue == "entitycolor"
14135 || aValue == "entity")
14136 {
14137 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
14138 }
14139 else if (aValue == "ownercolor"
14140 || aValue == "owner")
14141 {
14142 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
14143 }
14144 else if (aValue == "selectionmodecolor"
14145 || aValue == "selectionmode"
14146 || aValue == "selmodecolor"
14147 || aValue == "selmode")
14148 {
14149 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
14150 }
14151 }
14152 else if (aParam == "-picked"
14153 || aParam == "-pickeddepth"
14154 || aParam == "-pickedindex")
14155 {
14156 if (++anArgIter >= theArgsNb)
14157 {
23fe70ec 14158 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 14159 return 1;
14160 }
14161
14162 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
14163 }
b40cdc2b 14164 else if (anArgIter + 1 < theArgsNb
14165 && aParam == "-xrpose")
14166 {
14167 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
14168 anXRArg.LowerCase();
14169 if (anXRArg == "base")
14170 {
14171 aCustomCam = aView->View()->BaseXRCamera();
14172 }
14173 else if (anXRArg == "head")
14174 {
14175 aCustomCam = aView->View()->PosedXRCamera();
14176 }
14177 else
14178 {
14179 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
14180 return 1;
14181 }
14182 if (aCustomCam.IsNull())
14183 {
14184 Message::SendFail() << "Error: undefined XR pose";
14185 return 0;
14186 }
14187 }
decdee7d 14188 else if (aFile.IsEmpty())
14189 {
14190 aFile = theArgVec[anArgIter];
14191 }
14192 else
14193 {
23fe70ec 14194 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 14195 return 1;
14196 }
14197 }
14198 if (aFile.IsEmpty())
14199 {
23fe70ec 14200 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 14201 return 1;
14202 }
14203
decdee7d 14204 Standard_Integer aWidth = 0, aHeight = 0;
14205 aView->Window()->Size (aWidth, aHeight);
14206
14207 Image_AlienPixMap aPixMap;
14208 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
14209 {
23fe70ec 14210 Message::SendFail ("Error: can't allocate image");
decdee7d 14211 return 1;
14212 }
b40cdc2b 14213
14214 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
14215 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
14216 if (!aCustomCam.IsNull())
14217 {
14218 aView->SetCamera (aCustomCam);
14219 }
decdee7d 14220 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
14221 {
23fe70ec 14222 Message::SendFail ("Error: can't generate selection image");
decdee7d 14223 return 1;
14224 }
b40cdc2b 14225 if (!aCustomCam.IsNull())
14226 {
14227 aView->SetCamera (aCamBack);
14228 }
14229 aView->SetImmediateUpdate (wasImmUpdate);
14230
decdee7d 14231 if (!aPixMap.Save (aFile))
14232 {
23fe70ec 14233 Message::SendFail ("Error: can't save selection image");
decdee7d 14234 return 0;
14235 }
14236 return 0;
14237}
14238
2108d9a2 14239//===============================================================================================
14240//function : VViewCube
14241//purpose :
14242//===============================================================================================
14243static int VViewCube (Draw_Interpretor& ,
14244 Standard_Integer theNbArgs,
14245 const char** theArgVec)
14246{
14247 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
14248 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
14249 if (aContext.IsNull() || aView.IsNull())
14250 {
23fe70ec 14251 Message::SendFail ("Error: no active viewer");
2108d9a2 14252 return 1;
14253 }
14254 else if (theNbArgs < 2)
14255 {
23fe70ec 14256 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 14257 return 1;
14258 }
14259
14260 Handle(AIS_ViewCube) aViewCube;
14261 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
14262 Quantity_Color aColorRgb;
14263 TCollection_AsciiString aName;
14264 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14265 {
14266 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14267 anArg.LowerCase();
14268 if (anUpdateTool.parseRedrawMode (anArg))
14269 {
14270 //
14271 }
14272 else if (aViewCube.IsNull())
14273 {
14274 aName = theArgVec[anArgIter];
14275 if (aName.StartsWith ("-"))
14276 {
23fe70ec 14277 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 14278 return 1;
14279 }
14280 Handle(AIS_InteractiveObject) aPrs;
14281 GetMapOfAIS().Find2 (aName, aPrs);
14282 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
14283 if (aViewCube.IsNull())
14284 {
14285 aViewCube = new AIS_ViewCube();
14286 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
14287 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
14288 aViewCube->SetFixedAnimationLoop (false);
14289 }
14290 }
14291 else if (anArg == "-reset")
14292 {
14293 aViewCube->ResetStyles();
14294 }
14295 else if (anArg == "-color"
14296 || anArg == "-boxcolor"
14297 || anArg == "-boxsidecolor"
14298 || anArg == "-sidecolor"
14299 || anArg == "-boxedgecolor"
14300 || anArg == "-edgecolor"
14301 || anArg == "-boxcornercolor"
14302 || anArg == "-cornercolor"
14303 || anArg == "-innercolor"
0aeb8984 14304 || anArg == "-textcolor"
14305 || anArg == "-xaxistextcolor"
14306 || anArg == "-yaxistextcolor"
14307 || anArg == "-zaxistextcolor")
2108d9a2 14308 {
dae2a922 14309 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
14310 theArgVec + anArgIter + 1,
14311 aColorRgb);
2108d9a2 14312 if (aNbParsed == 0)
14313 {
23fe70ec 14314 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 14315 return 1;
14316 }
14317 anArgIter += aNbParsed;
14318 if (anArg == "-boxcolor")
14319 {
14320 aViewCube->SetBoxColor (aColorRgb);
14321 }
14322 else if (anArg == "-boxsidecolor"
14323 || anArg == "-sidecolor")
14324 {
14325 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
14326 aViewCube->SynchronizeAspects();
14327 }
14328 else if (anArg == "-boxedgecolor"
14329 || anArg == "-edgecolor")
14330 {
14331 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
14332 aViewCube->SynchronizeAspects();
14333 }
14334 else if (anArg == "-boxcornercolor"
14335 || anArg == "-cornercolor")
14336 {
14337 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
14338 aViewCube->SynchronizeAspects();
14339 }
14340 else if (anArg == "-innercolor")
14341 {
14342 aViewCube->SetInnerColor (aColorRgb);
14343 }
14344 else if (anArg == "-textcolor")
14345 {
14346 aViewCube->SetTextColor (aColorRgb);
14347 }
0aeb8984 14348 else if (anArg == "-xaxistextcolor"
14349 || anArg == "-yaxistextcolor"
14350 || anArg == "-zaxistextcolor")
14351 {
14352 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
14353 ? Prs3d_DatumParts_XAxis
14354 : (anArg.Value (2) == 'y'
14355 ? Prs3d_DatumParts_YAxis
14356 : Prs3d_DatumParts_ZAxis);
14357 aViewCube->Attributes()->SetOwnDatumAspects();
14358 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
14359 }
2108d9a2 14360 else
14361 {
14362 aViewCube->SetColor (aColorRgb);
14363 }
14364 }
14365 else if (anArgIter + 1 < theNbArgs
14366 && (anArg == "-transparency"
14367 || anArg == "-boxtransparency"))
14368 {
14369 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
14370 if (aValue < 0.0 || aValue > 1.0)
14371 {
23fe70ec 14372 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 14373 return 1;
14374 }
14375
14376 if (anArg == "-boxtransparency")
14377 {
14378 aViewCube->SetBoxTransparency (aValue);
14379 }
14380 else
14381 {
14382 aViewCube->SetTransparency (aValue);
14383 }
14384 }
14385 else if (anArg == "-axes"
14386 || anArg == "-edges"
14387 || anArg == "-vertices"
14388 || anArg == "-vertexes"
14389 || anArg == "-fixedanimation")
14390 {
14391 bool toShow = true;
14392 if (anArgIter + 1 < theNbArgs
dae2a922 14393 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 14394 {
14395 ++anArgIter;
14396 }
14397 if (anArg == "-fixedanimation")
14398 {
14399 aViewCube->SetFixedAnimationLoop (toShow);
14400 }
14401 else if (anArg == "-axes")
14402 {
14403 aViewCube->SetDrawAxes (toShow);
14404 }
14405 else if (anArg == "-edges")
14406 {
14407 aViewCube->SetDrawEdges (toShow);
14408 }
14409 else
14410 {
14411 aViewCube->SetDrawVertices (toShow);
14412 }
14413 }
14414 else if (anArg == "-yup"
14415 || anArg == "-zup")
14416 {
14417 bool isOn = true;
14418 if (anArgIter + 1 < theNbArgs
dae2a922 14419 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 14420 {
14421 ++anArgIter;
14422 }
14423 if (anArg == "-yup")
14424 {
14425 aViewCube->SetYup (isOn);
14426 }
14427 else
14428 {
14429 aViewCube->SetYup (!isOn);
14430 }
14431 }
14432 else if (anArgIter + 1 < theNbArgs
14433 && anArg == "-font")
14434 {
14435 aViewCube->SetFont (theArgVec[++anArgIter]);
14436 }
14437 else if (anArgIter + 1 < theNbArgs
14438 && anArg == "-fontheight")
14439 {
14440 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
14441 }
14442 else if (anArgIter + 1 < theNbArgs
14443 && (anArg == "-size"
14444 || anArg == "-boxsize"))
14445 {
14446 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
14447 anArg != "-boxsize");
14448 }
14449 else if (anArgIter + 1 < theNbArgs
14450 && (anArg == "-boxfacet"
14451 || anArg == "-boxfacetextension"
14452 || anArg == "-facetextension"
14453 || anArg == "-extension"))
14454 {
14455 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
14456 }
14457 else if (anArgIter + 1 < theNbArgs
14458 && (anArg == "-boxedgegap"
14459 || anArg == "-edgegap"))
14460 {
14461 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
14462 }
14463 else if (anArgIter + 1 < theNbArgs
14464 && (anArg == "-boxedgeminsize"
14465 || anArg == "-edgeminsize"))
14466 {
14467 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
14468 }
14469 else if (anArgIter + 1 < theNbArgs
14470 && (anArg == "-boxcornerminsize"
14471 || anArg == "-cornerminsize"))
14472 {
14473 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
14474 }
14475 else if (anArgIter + 1 < theNbArgs
14476 && anArg == "-axespadding")
14477 {
14478 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
14479 }
14480 else if (anArgIter + 1 < theNbArgs
14481 && anArg == "-roundradius")
14482 {
14483 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
14484 }
14485 else if (anArgIter + 1 < theNbArgs
14486 && anArg == "-duration")
14487 {
14488 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
14489 }
6466cc9e 14490 else if (anArgIter + 1 < theNbArgs
14491 && anArg == "-axesradius")
14492 {
14493 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
14494 }
14495 else if (anArgIter + 1 < theNbArgs
14496 && anArg == "-axesconeradius")
14497 {
14498 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
14499 }
14500 else if (anArgIter + 1 < theNbArgs
14501 && anArg == "-axessphereradius")
14502 {
14503 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
14504 }
2108d9a2 14505 else
14506 {
23fe70ec 14507 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 14508 return 1;
14509 }
14510 }
14511 if (aViewCube.IsNull())
14512 {
23fe70ec 14513 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 14514 return 1;
14515 }
14516
14517 ViewerTest::Display (aName, aViewCube, false);
14518 return 0;
14519}
14520
14b741b0 14521//===============================================================================================
14522//function : VColorConvert
14523//purpose :
14524//===============================================================================================
14525static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14526{
14527 if (theNbArgs != 6)
14528 {
14529 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14530 return 1;
14531 }
14532
14533 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
14534 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
14535 {
14536 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
14537 return 1;
14538 }
14539
14540 const char* aTypeStr = theArgVec[2];
14541 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
14542 if (! strcasecmp (aTypeStr, "srgb"))
14543 {
14544 aType = Quantity_TOC_sRGB;
14545 }
14546 else if (! strcasecmp (aTypeStr, "hls"))
14547 {
14548 aType = Quantity_TOC_HLS;
14549 }
14550 else if (! strcasecmp (aTypeStr, "lab"))
14551 {
14552 aType = Quantity_TOC_CIELab;
14553 }
14554 else if (! strcasecmp (aTypeStr, "lch"))
14555 {
14556 aType = Quantity_TOC_CIELch;
14557 }
14558 else
14559 {
14560 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
14561 return 1;
14562 }
14563
14564 double aC1 = Draw::Atof (theArgVec[3]);
14565 double aC2 = Draw::Atof (theArgVec[4]);
14566 double aC3 = Draw::Atof (theArgVec[5]);
14567
14568 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
14569 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
14570
14571 // print values with 6 decimal digits
14572 char buffer[1024];
14573 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14574 theDI << buffer;
14575
14576 return 0;
14577}
14578
14579//===============================================================================================
14580//function : VColorDiff
14581//purpose :
14582//===============================================================================================
14583static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14584{
14585 if (theNbArgs != 7)
14586 {
14587 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14588 return 1;
14589 }
14590
14591 double aR1 = Draw::Atof (theArgVec[1]);
14592 double aG1 = Draw::Atof (theArgVec[2]);
14593 double aB1 = Draw::Atof (theArgVec[3]);
14594 double aR2 = Draw::Atof (theArgVec[4]);
14595 double aG2 = Draw::Atof (theArgVec[5]);
14596 double aB2 = Draw::Atof (theArgVec[6]);
14597
14598 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14599 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14600
14601 theDI << aColor1.DeltaE2000 (aColor2);
14602
14603 return 0;
14604}
14605
6a2fb7a1 14606//===============================================================================================
4551e1be 14607//function : VSelBvhBuild
6a2fb7a1 14608//purpose :
14609//===============================================================================================
14610static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14611{
14612 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14613 if (aCtx.IsNull())
14614 {
14615 Message::SendFail ("Error: no active viewer");
14616 return 1;
14617 }
14618
14619 if (theNbArgs < 2)
14620 {
14621 Message::SendFail ("Error: command syntax is incorrect, see help");
14622 return 1;
14623 }
14624
14625 Standard_Integer toEnable = -1;
14626 Standard_Integer aThreadsNb = -1;
14627 Standard_Boolean toWait = Standard_False;
14628
14629 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14630 {
14631 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14632 anArg.LowerCase();
14633
14634 if (anArg == "-nbthreads"
14635 && anArgIter + 1 < theNbArgs)
14636 {
14637 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14638 if (aThreadsNb < 1)
14639 {
14640 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14641 }
14642 }
14643 else if (anArg == "-wait")
14644 {
14645 toWait = Standard_True;
14646 }
14647 else if (toEnable == -1)
14648 {
14649 Standard_Boolean toEnableValue = Standard_True;
14650 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14651 {
14652 toEnable = toEnableValue ? 1 : 0;
14653 }
14654 else
14655 {
14656 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14657 return 1;
14658 }
14659 }
14660 else
14661 {
14662 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14663 return 1;
14664 }
14665 }
14666
14667 if (aThreadsNb == -1)
14668 {
14669 aThreadsNb = 1;
14670 }
14671 if (toEnable != -1)
14672 {
14673 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14674 }
14675 if (toWait)
14676 {
14677 aCtx->MainSelector()->WaitForBVHBuild();
14678 }
14679
14680 return 0;
14681}
14682
7fd59977 14683//=======================================================================
14684//function : ViewerCommands
14685//purpose :
14686//=======================================================================
14687
14688void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14689{
14690
14691 const char *group = "ZeViewer";
18d715bd 14692 theCommands.Add("vinit",
fd3f6bd0 14693 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
72ed0644 14694 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]"
fd3f6bd0 14695 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14696 "\n\t\t: [-display displayName]"
14697 #endif
14698 "\n\t\t: Creates new View window with specified name viewName."
14699 "\n\t\t: By default the new view is created in the viewer and in"
14700 "\n\t\t: graphic driver shared with active view."
14701 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14702 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14703 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
14704#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14705 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14706 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14707#endif
fd3f6bd0 14708 "\n\t\t: -left, -top pixel position of left top corner of the window."
4551e1be 14709 "\n\t\t: -width, -height width and height of window respectively."
72ed0644 14710 "\n\t\t: -cloneActive flag to copy camera and dimensions of active view."
fd3f6bd0 14711 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14712 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
72ed0644 14713 "\n\t\t: -virtual create an offscreen window within interactive session"
2e93433e 14714 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14715 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14716 __FILE__,VInit,group);
18d715bd 14717 theCommands.Add("vclose" ,
d0cc1cb7 14718 "[view_id [keep_context=0|1]]\n"
18d715bd 14719 "or vclose ALL - to remove all created views\n"
14720 " - removes view(viewer window) defined by its view_id.\n"
14721 " - keep_context: by default 0; if 1 and the last view is deleted"
14722 " the current context is not removed.",
14723 __FILE__,VClose,group);
14724 theCommands.Add("vactivate" ,
e084dbbc 14725 "vactivate view_id [-noUpdate]"
18d715bd 14726 " - activates view(viewer window) defined by its view_id",
14727 __FILE__,VActivate,group);
14728 theCommands.Add("vviewlist",
14729 "vviewlist [format={tree, long}]"
14730 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14731 " - format: format of result output, if tree the output is a tree view;"
14732 "otherwise it's a list of full view names. By default format = tree",
14733 __FILE__,VViewList,group);
7fd59977 14734 theCommands.Add("vhelp" ,
14735 "vhelp : display help on the viewer commands",
14736 __FILE__,VHelp,group);
fc552d84 14737 theCommands.Add("vviewproj",
14738 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14739 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14740 "\n\t\t: Setup view direction"
14741 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14742 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14743 "\n\t\t: for example '+Z' will show front of the model,"
14744 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14745 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14746 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14747 __FILE__,VViewProj,group);
7fd59977 14748 theCommands.Add("vtop" ,
27af3052 14749 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14750 __FILE__,VViewProj,group);
44b8f2d6 14751 theCommands.Add("vbottom" ,
27af3052 14752 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14753 __FILE__,VViewProj,group);
44b8f2d6 14754 theCommands.Add("vleft" ,
27af3052 14755 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14756 __FILE__,VViewProj,group);
44b8f2d6 14757 theCommands.Add("vright" ,
27af3052 14758 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14759 __FILE__,VViewProj,group);
7fd59977 14760 theCommands.Add("vaxo" ,
27af3052 14761 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14762 __FILE__,VViewProj,group);
44b8f2d6 14763 theCommands.Add("vfront" ,
27af3052 14764 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14765 __FILE__,VViewProj,group);
44b8f2d6 14766 theCommands.Add("vback" ,
27af3052 14767 "vback : Back view. Orientation -X+Z" ,
fc552d84 14768 __FILE__,VViewProj,group);
7fd59977 14769 theCommands.Add("vpick" ,
14770 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14771 VPick,group);
1beb58d7 14772 theCommands.Add("vfit",
14773 "vfit or <F> [-selected] [-noupdate]"
b586500b 14774 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14775 __FILE__,VFit,group);
6262a303 14776 theCommands.Add ("vfitarea",
14777 "vfitarea x1 y1 x2 y2"
14778 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14779 "\n\t\t: Fit view to show area located between two points"
14780 "\n\t\t: given in world 2D or 3D corrdinates.",
14781 __FILE__, VFitArea, group);
197ac94e 14782 theCommands.Add ("vzfit", "vzfit [scale]\n"
14783 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14784 " \"scale\" - specifies factor to scale computed z range.\n",
14785 __FILE__, VZFit, group);
7fd59977 14786 theCommands.Add("vrepaint",
8693dfd0 14787 "vrepaint [-immediate] [-continuous FPS]"
14788 "\n\t\t: force redraw of active View"
14789 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14790 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14791 "\n\t\t: 0 means no continuous rendering,"
14792 "\n\t\t: -1 means non-stop redraws,"
14793 "\n\t\t: >0 specifies target framerate,",
7fd59977 14794 __FILE__,VRepaint,group);
14795 theCommands.Add("vclear",
faea8b40 14796 "vclear : vclear"
14797 "\n\t\t: remove all the object from the viewer",
7fd59977 14798 __FILE__,VClear,group);
293211ae 14799 theCommands.Add (
14800 "vbackground",
14801 "Changes background or some background settings.\n"
14802 "\n"
14803 "Usage:\n"
14804 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14805 " vbackground -imageMode FillType\n"
14806 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14807 " vbackground -gradientMode FillMethod\n"
077a220c 14808 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14809 " vbackground -color Color\n"
14810 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14811 " vbackground -default -color Color\n"
14812 " vbackground -help\n"
14813 "\n"
14814 "Options:\n"
14815 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14816 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14817 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14818 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
4551e1be 14819 " -cubemap (-cmap, -cm): sets environment cubemap as background\n"
077a220c 14820 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14821 " -order (-o): defines order of tiles in one image cubemap\n"
14822 " (has no effect in case of multi image cubemaps)\n"
293211ae 14823 " -color (-col): sets background color\n"
14824 " -default (-def): sets background default gradient or color\n"
14825 " -help (-h): outputs short help message\n"
14826 "\n"
14827 "Arguments:\n"
077a220c 14828 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14829 " or reals within the range [0.0, 1.0]\n"
077a220c 14830 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14831 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14832 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14833 "CORNER4\n"
077a220c 14834 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14835 " ImageFile: a name of the file with the image used as a background\n"
14836 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14837 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14838 __FILE__,
14839 vbackground,
14840 group);
14841 theCommands.Add ("vsetbg",
14842 "Loads image as background."
14843 "\n\t\t: vsetbg ImageFile [FillType]"
14844 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14845 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14846 __FILE__,
14847 vbackground,
14848 group);
14849 theCommands.Add ("vsetbgmode",
14850 "Changes background image fill type."
14851 "\n\t\t: vsetbgmode [-imageMode] FillType"
14852 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14853 __FILE__,
14854 vbackground,
14855 group);
14856 theCommands.Add ("vsetgradientbg",
14857 "Mounts gradient background."
14858 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14859 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14860 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14861 __FILE__,
14862 vbackground,
14863 group);
14864 theCommands.Add ("vsetgrbgmode",
14865 "Changes gradient background fill method."
14866 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14867 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14868 __FILE__,
14869 vbackground,
14870 group);
14871 theCommands.Add ("vsetcolorbg",
14872 "Sets background color."
14873 "\n\t\t: vsetcolorbg [-color] Color."
14874 "\n\t\t: Alias for 'vbackground -color Color'.",
14875 __FILE__,
14876 vbackground,
14877 group);
14878 theCommands.Add ("vsetdefaultbg",
14879 "Sets default viewer background fill color (flat/gradient)."
14880 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14881 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14882 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14883 "\n\t\t: vsetdefaultbg [-color] Color"
14884 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14885 __FILE__,
14886 vbackground,
14887 group);
7fd59977 14888 theCommands.Add("vscale",
14889 "vscale : vscale X Y Z",
14890 __FILE__,VScale,group);
14891 theCommands.Add("vzbufftrihedron",
536d98e2 14892 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14893 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14894 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14895 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14896 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
0aeb8984 14897 "\n\t\t: [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]"
536d98e2 14898 "\n\t\t: Displays a trihedron",
14899 __FILE__,VZBuffTrihedron,group);
7fd59977 14900 theCommands.Add("vrotate",
4af098ba 14901 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14902 "\n : Option -mouseStart starts rotation according to the mouse position"
14903 "\n : Option -mouseMove continues rotation with angle computed"
14904 "\n : from last and new mouse position."
14905 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14906 __FILE__,VRotate,group);
14907 theCommands.Add("vzoom",
14908 "vzoom : vzoom coef",
14909 __FILE__,VZoom,group);
14910 theCommands.Add("vpan",
14911 "vpan : vpan dx dy",
14912 __FILE__,VPan,group);
7fd59977 14913 theCommands.Add("vcolorscale",
4b3d6eb1 14914 "vcolorscale name [-noupdate|-update] [-demo]"
14915 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14916 "\n\t\t: [-font HeightFont=20]"
14917 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14918 "\n\t\t: [-smoothTransition {on|off}=off]"
14919 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14920 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14921 "\n\t\t: [-textpos {left|right|center|none}=right]"
14922 "\n\t\t: [-labelAtBorder {on|off}=on]"
14923 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14924 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14925 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14926 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14927 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14928 "\n\t\t: -demo - displays a color scale with demonstratio values"
14929 "\n\t\t: -colors - set colors for all intervals"
14930 "\n\t\t: -color - set color for specific interval"
14b741b0 14931 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14932 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14933 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14934 "\n\t\t: at border means the value inbetween neighbor intervals,"
14935 "\n\t\t: at center means the center value within current interval"
14936 "\n\t\t: -labels - set labels for all intervals"
14937 "\n\t\t: -freeLabels - same as -labels but does not require"
14938 "\n\t\t: matching the number of intervals"
14939 "\n\t\t: -label - set label for specific interval"
14940 "\n\t\t: -title - set title"
14941 "\n\t\t: -reversed - setup smooth color transition between intervals"
14942 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14943 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14944 __FILE__, VColorScale, group);
7fd59977 14945 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14946 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14947 "\t[-namefont Name] [-valuesfont Name]\n"
14948 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14949 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14950 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14951 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14952 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14953 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14954 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14955 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14956 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14957 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14958 " - Displays or erases graduated trihedron"
14959 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14960 " - namefont - font of axes names. Default: Arial\n"
14961 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14962 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14963 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14964 " - valuesfont - font of axes values. Default: Arial\n"
14965 " - xcolor, ycolor, zcolor - color of axis and values\n"
14966 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14967 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14968 __FILE__,VGraduatedTrihedron,group);
3bffef55 14969 theCommands.Add("vtile" ,
14970 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14971 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14972 "\n\t\t: -totalSize the size of virtual bigger viewport"
14973 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14974 "\n\t\t: -lowerLeft tile offset as lower left corner"
14975 "\n\t\t: -upperLeft tile offset as upper left corner",
14976 __FILE__, VTile, group);
59f45b7c 14977 theCommands.Add("vzlayer",
7c3ef2f7 14978 "vzlayer [layerId]"
1c728f2d 14979 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14980 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14981 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14982 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14983 "\n\t\t: ZLayer list management:"
14984 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14985 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14986 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14987 "\n\t\t: -delete delete z layer"
14988 "\n\t\t: -get print sequence of z layers"
14989 "\n\t\t: -settings print status of z layer settings"
14990 "\n\t\t: -disable disables given setting"
14991 "\n\t\t: -enable enables given setting",
59f45b7c 14992 __FILE__,VZLayer,group);
20637bd2 14993 theCommands.Add("vlayerline",
14994 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14995 __FILE__,VLayerLine,group);
79931835 14996 theCommands.Add("vgrid",
14997 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14998 "\n\t\t: [-step X Y] [-size DX DY]"
14999 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 15000 __FILE__, VGrid, group);
c40b7d58 15001 theCommands.Add ("vpriviledgedplane",
15002 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
15003 "\n\t\t: Ox, Oy, Oz - plane origin"
15004 "\n\t\t: Nx, Ny, Nz - plane normal direction"
15005 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
15006 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
15007 __FILE__, VPriviledgedPlane, group);
f25b82d6 15008 theCommands.Add ("vconvert",
15009 "vconvert v [Mode={window|view}]"
15010 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
15011 "\n\t\t: vconvert x y z [Mode={window|grid}]"
15012 "\n\t\t: window - convert to window coordinates, pixels"
15013 "\n\t\t: view - convert to view projection plane"
15014 "\n\t\t: grid - convert to model coordinates, given on grid"
4551e1be 15015 "\n\t\t: ray - convert projection ray to model coordinates"
f25b82d6 15016 "\n\t\t: - vconvert v window : convert view to window;"
15017 "\n\t\t: - vconvert v view : convert window to view;"
15018 "\n\t\t: - vconvert x y window : convert view to window;"
15019 "\n\t\t: - vconvert x y view : convert window to view;"
15020 "\n\t\t: - vconvert x y : convert window to model;"
15021 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
15022 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
15023 "\n\t\t: - vconvert x y z window : convert model to window;"
15024 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
15025 "\n\t\t: Converts the given coordinates to window/view/model space.",
15026 __FILE__, VConvert, group);
208e6839 15027 theCommands.Add ("vfps",
e084dbbc 15028 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 15029 __FILE__, VFps, group);
58655684 15030 theCommands.Add ("vgldebug",
c87535af 15031 "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
84e84755 15032 "\n\t\t: [-glslCode {off|short|full}] [-extraMsg {0|1}] [{0|1}]"
c87535af 15033 "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
15034 "\n\t\t: Debug context can be requested only on Windows"
15035 "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
15036 "\n\t\t: -sync - request synchronized debug GL context"
15037 "\n\t\t: -glslWarn - log GLSL compiler/linker warnings,"
15038 "\n\t\t: which are suppressed by default,"
84e84755 15039 "\n\t\t: -glslCode - log GLSL program source code,"
15040 "\n\t\t: which are suppressed by default,"
c87535af 15041 "\n\t\t: -extraMsg - log extra diagnostic messages from GL context,"
15042 "\n\t\t: which are suppressed by default",
58655684 15043 __FILE__, VGlDebug, group);
208e6839 15044 theCommands.Add ("vvbo",
58655684 15045 "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
208e6839 15046 __FILE__, VVbo, group);
b5ac8292 15047 theCommands.Add ("vstereo",
f978241f 15048 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 15049 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 15050 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 15051 "\n\t\t: Control stereo output mode."
15052 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
15053 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
15054 "\n\t\t: Available modes for -mode:"
f978241f 15055 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
15056 "\n\t\t: requires driver support."
15057 "\n\t\t: Should be called BEFORE vinit!"
15058 "\n\t\t: anaglyph - Anaglyph glasses"
15059 "\n\t\t: rowInterlaced - row-interlaced display"
15060 "\n\t\t: columnInterlaced - column-interlaced display"
15061 "\n\t\t: chessBoard - chess-board output"
15062 "\n\t\t: sideBySide - horizontal pair"
15063 "\n\t\t: overUnder - vertical pair"
b40cdc2b 15064 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 15065 "\n\t\t: Available Anaglyph filters for -anaglyph:"
15066 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
15067 "\n\t\t: greenMagentaSimple",
b5ac8292 15068 __FILE__, VStereo, group);
a577aaab 15069 theCommands.Add ("vcaps",
ba00aab7 15070 "vcaps [-sRGB {0|1}] [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
faff3767 15071 "\n\t\t: [-compatibleProfile {0|1}] [-compressedTextures {0|1}]"
31174e1a 15072 "\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}] [-opaqueAlpha {0|1}]"
f978241f 15073 "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
8625ef7e 15074 "\n\t\t: [-softMode {0|1}] [-noupdate|-update]"
59515ca6 15075 "\n\t\t: [-noExtensions {0|1}] [-maxVersion Major Minor]"
8625ef7e 15076 "\n\t\t: Modify particular graphic driver options:"
ba00aab7 15077 "\n\t\t: sRGB - enable/disable sRGB rendering"
8625ef7e 15078 "\n\t\t: FFP - use fixed-function pipeline instead of"
15079 "\n\t\t: built-in GLSL programs"
4e1523ef 15080 "\n\t\t: (requires compatible profile)"
2a332745 15081 "\n\t\t: polygonMode - use Polygon Mode instead of built-in GLSL programs"
faff3767 15082 "\n\t\t: compressedTexture - allow uploading of GPU-supported compressed texture formats"
8625ef7e 15083 "\n\t\t: VBO - use Vertex Buffer Object (copy vertex"
15084 "\n\t\t: arrays to GPU memory)"
15085 "\n\t\t: sprite - use textured sprites instead of bitmaps"
f978241f 15086 "\n\t\t: vsync - switch VSync on or off"
31174e1a 15087 "\n\t\t: opaqueAlpha - disable writes in alpha component of color buffer"
56689b27 15088 "\n\t\t: winBuffer - allow using window buffer for rendering"
4e1523ef 15089 "\n\t\t: Context creation options:"
15090 "\n\t\t: softMode - software OpenGL implementation"
15091 "\n\t\t: compatibleProfile - backward-compatible profile"
f978241f 15092 "\n\t\t: quadbuffer - QuadBuffer"
59515ca6 15093 "\n\t\t: noExtensions - disallow usage of extensions"
15094 "\n\t\t: maxVersion - force upper OpenGL version to be used"
8625ef7e 15095 "\n\t\t: Unlike vrenderparams, these parameters control alternative"
15096 "\n\t\t: rendering paths producing the same visual result when"
15097 "\n\t\t: possible."
15098 "\n\t\t: Command is intended for testing old hardware compatibility.",
a577aaab 15099 __FILE__, VCaps, group);
f0430952 15100 theCommands.Add ("vmemgpu",
15101 "vmemgpu [f]: print system-dependent GPU memory information if available;"
15102 " with f option returns free memory in bytes",
15103 __FILE__, VMemGpu, group);
85e096c3 15104 theCommands.Add ("vreadpixel",
ba00aab7 15105 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 15106 " : Read pixel value for active view",
15107 __FILE__, VReadPixel, group);
692613e5 15108 theCommands.Add("diffimage",
fd3f6bd0 15109 "diffimage imageFile1 imageFile2 [diffImageFile]"
15110 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
15111 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
15112 "\n\t\t: Compare two images by content and generate difference image."
15113 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
15114 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 15115 __FILE__, VDiffImage, group);
4754e164 15116 theCommands.Add ("vselect",
e3d4b879 15117 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [-replace|-xor|-add|-remove]\n"
4754e164 15118 "- emulates different types of selection:\n"
15119 "- 1) single click selection\n"
15120 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
15121 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 15122 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
15123 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
15124 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
15125 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
e3d4b879 15126 "- 5) selection scheme replace, xor, add or remove (replace by default)",
4754e164 15127 __FILE__, VSelect, group);
15128 theCommands.Add ("vmoveto",
8a590580 15129 "vmoveto [x y] [-reset]"
15130 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
15131 "\n\t\t: -reset resets current highlighting",
4754e164 15132 __FILE__, VMoveTo, group);
1beb58d7 15133 theCommands.Add ("vviewparams",
15134 "vviewparams [-args] [-scale [s]]"
15135 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
15136 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
15137 "\n\t\t: Manage current view parameters or prints all"
15138 "\n\t\t: current values when called without argument."
15139 "\n\t\t: -scale [s] prints or sets viewport relative scale"
15140 "\n\t\t: -eye [x y z] prints or sets eye location"
15141 "\n\t\t: -at [x y z] prints or sets center of look"
15142 "\n\t\t: -up [x y z] prints or sets direction of up vector"
15143 "\n\t\t: -proj [x y z] prints or sets direction of look"
15144 "\n\t\t: -center x y sets location of center of the screen in pixels"
15145 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
15146 "\n\t\t: or changes the size of its maximum dimension"
15147 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 15148 __FILE__, VViewParams, group);
1beb58d7 15149
2e93433e 15150 theCommands.Add("v2dmode",
15151 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
15152 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
15153 "\n\t\t: mode - switches On/Off rotation mode"
15154 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
15155 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
15156 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
15157 "\n\t\t: View camera position might be changed only by commands.",
15158 __FILE__, V2DMode, group);
15159
1beb58d7 15160 theCommands.Add("vanimation", "Alias for vanim",
15161 __FILE__, VAnimation, group);
15162
15163 theCommands.Add("vanim",
15164 "List existing animations:"
15165 "\n\t\t: vanim"
15166 "\n\t\t: Animation playback:"
15167 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
15168 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
15169 "\n\t\t: -speed playback speed (1.0 is normal speed)"
15170 "\n\t\t: -freeLook skip camera animations"
15171 "\n\t\t: -lockLoop disable any interactions"
15172 "\n\t\t:"
15173 "\n\t\t: Animation definition:"
15174 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
15175 "\n\t\t: [start TimeSec] [duration TimeSec]"
15176 "\n\t\t:"
15177 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
15178 "\n\t\t: specifies nested animations."
15179 "\n\t\t: There is no syntax to explicitly add new animation,"
15180 "\n\t\t: and all non-existing animations within the name will be"
15181 "\n\t\t: implicitly created on first use (including parents)."
15182 "\n\t\t:"
15183 "\n\t\t: Each animation might define the SINGLE action (see below),"
15184 "\n\t\t: like camera transition, object transformation or custom callback."
15185 "\n\t\t: Child animations can be used for defining concurrent actions."
15186 "\n\t\t:"
15187 "\n\t\t: Camera animation:"
15188 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
15189 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
15190 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
15191 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
15192 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
15193 "\n\t\t: -atX camera Center positions pair"
15194 "\n\t\t: -upX camera Up directions pair"
15195 "\n\t\t: -scaleX camera Scale factors pair"
15196 "\n\t\t: Object animation:"
15197 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
15198 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
15199 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
15200 "\n\t\t: -locX object Location points pair (translation)"
15201 "\n\t\t: -rotX object Orientations pair (quaternions)"
15202 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
15203 "\n\t\t: Custom callback:"
15204 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
15205 "\n\t\t: %Pts overall animation presentation timestamp"
15206 "\n\t\t: %LocalPts local animation timestamp"
15207 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 15208 "\n\t\t:"
15209 "\n\t\t: Video recording:"
15210 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
15211 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
15212 "\n\t\t: [-crf Value] [-preset Preset]"
15213 "\n\t\t: -fps video framerate"
15214 "\n\t\t: -format file format, container (matroska, etc.)"
15215 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
15216 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
15217 "\n\t\t: -crf constant rate factor (specific to codec)"
15218 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 15219 __FILE__, VAnimation, group);
15220
4754e164 15221 theCommands.Add("vchangeselected",
dc3fe572 15222 "vchangeselected shape"
4754e164 15223 "- adds to shape to selection or remove one from it",
15224 __FILE__, VChangeSelected, group);
4754e164 15225 theCommands.Add ("vnbselected",
faea8b40 15226 "vnbselected"
15227 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 15228 theCommands.Add ("vcamera",
30a1b24e 15229 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 15230 "\n\t\t: [-persp]"
15231 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
15232 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
15233 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
15234 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 15235 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
15236 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 15237 "\n\t\t: Manages camera parameters."
4551e1be 15238 "\n\t\t: Displays frustum when presentation name PrsName is specified."
6b62b2da 15239 "\n\t\t: Prints current value when option called without argument."
15240 "\n\t\t: Orthographic camera:"
15241 "\n\t\t: -ortho activate orthographic projection"
15242 "\n\t\t: Perspective camera:"
15243 "\n\t\t: -persp activate perspective projection (mono)"
15244 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 15245 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 15246 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 15247 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 15248 "\n\t\t: Stereoscopic camera:"
15249 "\n\t\t: -stereo perspective projection (stereo)"
15250 "\n\t\t: -leftEye perspective projection (left eye)"
15251 "\n\t\t: -rightEye perspective projection (right eye)"
15252 "\n\t\t: -iod intraocular distance value"
15253 "\n\t\t: -iodType distance type, absolute or relative"
15254 "\n\t\t: -zfocus stereographic focus value"
15255 "\n\t\t: -zfocusType focus type, absolute or relative",
15256 __FILE__, VCamera, group);
b5ac8292 15257 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 15258 "- vautozfit [on={1|0}] [scale]\n"
15259 " Prints or changes parameters of automatic z-fit mode:\n"
15260 " \"on\" - turns automatic z-fit on or off\n"
15261 " \"scale\" - specifies factor to scale computed z range.\n",
15262 __FILE__, VAutoZFit, group);
b5ac8292 15263 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
15264 " vzrange - without parameters shows current values\n"
15265 " vzrange [znear] [zfar] - applies provided values to view",
15266 __FILE__,VZRange, group);
4754e164 15267 theCommands.Add("vsetviewsize",
15268 "vsetviewsize size",
15269 __FILE__,VSetViewSize,group);
15270 theCommands.Add("vmoveview",
15271 "vmoveview Dx Dy Dz [Start = 1|0]",
15272 __FILE__,VMoveView,group);
15273 theCommands.Add("vtranslateview",
15274 "vtranslateview Dx Dy Dz [Start = 1|0)]",
15275 __FILE__,VTranslateView,group);
15276 theCommands.Add("vturnview",
15277 "vturnview Ax Ay Az [Start = 1|0]",
15278 __FILE__,VTurnView,group);
269294d6 15279 theCommands.Add("vtextureenv",
15280 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
15281 "or user-defined file and optionally applying texture mapping parameters\n"
15282 " Usage:\n"
15283 " vtextureenv off - disables environment mapping\n"
15284 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
15285 " std_texture = (0..7)\n"
15286 " rep = {clamp|repeat}\n"
15287 " mod = {decal|modulate}\n"
15288 " flt = {nearest|bilinear|trilinear}\n"
15289 " ss, st - scale factors for s and t texture coordinates\n"
15290 " ts, tt - translation for s and t texture coordinates\n"
15291 " rot - texture rotation angle in degrees",
15292 __FILE__, VTextureEnv, group);
1eeef710 15293 theCommands.Add("vhlr",
15294 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
15295 "\n\t\t: Hidden Line Removal algorithm."
15296 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
15297 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 15298 __FILE__,VHLR,group);
1eeef710 15299 theCommands.Add("vhlrtype",
15300 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
15301 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
15302 "\n\t\t: 'algo' - exact HLR algorithm is applied"
15303 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
15304 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 15305 __FILE__,VHLRType,group);
3e05329c 15306 theCommands.Add("vclipplane",
15307 "vclipplane planeName [{0|1}]"
25c35042 15308 "\n\t\t: [-equation1 A B C D]"
15309 "\n\t\t: [-equation2 A B C D]"
15310 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 15311 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 15312 "\n\t\t: [-maxPlanes]"
15313 "\n\t\t: [-capping {0|1}]"
1b661a81 15314 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 15315 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
15316 "\n\t\t: [-texRotate Angle]"
15317 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
15318 "\n\t\t: [-useObjShader {0|1}]"
15319 "\n\t\t: Clipping planes management:"
15320 "\n\t\t: -maxPlanes print plane limit for view"
15321 "\n\t\t: -delete delete plane with given name"
15322 "\n\t\t: {off|on|0|1} turn clipping on/off"
15323 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
15324 "\n\t\t: applied to active View when list is omitted"
15325 "\n\t\t: -equation A B C D change plane equation"
15326 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
15327 "\n\t\t: Capping options:"
15328 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
15329 "\n\t\t: -color R G B set capping color"
1b661a81 15330 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 15331 "\n\t\t: -texName Texture set capping texture"
15332 "\n\t\t: -texScale SX SY set capping tex scale"
15333 "\n\t\t: -texOrigin TX TY set capping tex origin"
15334 "\n\t\t: -texRotate Angle set capping tex rotation"
15335 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
15336 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
15337 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
15338 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
15339 __FILE__, VClipPlane, group);
392ac980 15340 theCommands.Add("vdefaults",
4c513386 15341 "vdefaults [-absDefl value]"
15342 "\n\t\t: [-devCoeff value]"
15343 "\n\t\t: [-angDefl value]"
15344 "\n\t\t: [-autoTriang {off/on | 0/1}]"
15345 , __FILE__, VDefaults, group);
12381341 15346 theCommands.Add("vlight",
816d03ee 15347 "tool to manage light sources, without arguments shows list of lights."
15348 "\n Main commands: "
992ed6b3 15349 "\n '-clear' to clear lights"
2daa5d95 15350 "\n '-{def}aults' to load default lights"
992ed6b3 15351 "\n '-add' <type> to add any light source"
816d03ee 15352 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
15353 "\n 'change' <lightId> to edit light source with specified lightId"
15354 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 15355 "\n -layer Id"
15356 "\n -{pos}ition X Y Z"
15357 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
15358 "\n -color colorName"
15359 "\n -{head}light 0|1"
d84e8669 15360 "\n -castShadows 0|1"
992ed6b3 15361 "\n -{sm}oothness value"
15362 "\n -{int}ensity value"
15363 "\n -{constAtten}uation value"
15364 "\n -{linearAtten}uation value"
15365 "\n -angle angleDeg"
15366 "\n -{spotexp}onent value"
88b312d3 15367 "\n -range value"
992ed6b3 15368 "\n -local|-global"
2daa5d95 15369 "\n -name value"
15370 "\n -display nameOfLight (display light source with specified nameOfLight or its name)"
15371 "\n -showName {1|0} show/hide the name of light source; 1 by default"
15372 "\n -showRange {1|0} show/hide the range of spot/positional light source; 1 by default"
15373 "\n -prsZoomable {1|0} make light presentation zoomable/non-zoomable"
15374 "\n -prsSize {Value} set light presentation size"
15375 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
992ed6b3 15376 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 15377 __FILE__, VLight, group);
67312b79 15378 theCommands.Add("vpbrenv",
15379 "vpbrenv -clear|-generate"
15380 "\n\t\t: Clears or generates PBR environment map of active view."
15381 "\n\t\t: -clear clears PBR environment (fills by white color)"
15382 "\n\t\t: -generate generates PBR environment from current background cubemap",
15383 __FILE__, VPBREnvironment, group);
6b62b2da 15384 theCommands.Add("vraytrace",
15385 "vraytrace [0|1]"
189f85a3 15386 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 15387 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
15388 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
15389 __FILE__, VRenderParams, group);
bc8c79bb 15390 theCommands.Add("vrenderparams",
4c7a3fae 15391 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
15392 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
15393 "\n\t\t: Common parameters:"
15394 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
15395 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1] [-resolution value=72]"
15396 "\n\t\t: [-oit {off|0.0-1.0}=off]"
d84e8669 15397 "\n\t\t: [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]"
4c7a3fae 15398 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
15399 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
15400 "\n\t\t: [-sync {default|views}] [-reset]"
15401 "\n\t\t: -raster Disables GPU ray-tracing."
15402 "\n\t\t: -shadingModel Controls shading model."
15403 "\n\t\t: -msaa Specifies number of samples for MSAA."
15404 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
15405 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
15406 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
15407 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
15408 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
15409 "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result,"
15410 "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)."
d84e8669 15411 "\n\t\t: -shadows Enables/disables shadows rendering."
15412 "\n\t\t: -shadowMapResolution Shadow texture map resolution."
15413 "\n\t\t: -shadowMapBias Shadow map bias."
4c7a3fae 15414 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
15415 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
15416 "\n\t\t: sets state to check structures culled previously."
15417 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
15418 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
15419 "\n\t\t: Diagnostic output (on-screen overlay):"
15420 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
15421 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
15422 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
15423 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
15424 "\n\t\t: -perfUpdateInterval Performance counters update interval."
15425 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
15426 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
15427 "\n\t\t: Ray-Tracing options:"
d84e8669 15428 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]"
4c7a3fae 15429 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
15430 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
15431 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
15432 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
15433 "\n\t\t: [-maxRad {value>0}=30.0]"
15434 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
15435 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
15436 "\n\t\t: -rayTrace Enables GPU ray-tracing."
15437 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
4c7a3fae 15438 "\n\t\t: -reflections Enables/disables specular reflections."
15439 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
15440 "\n\t\t: -gleam Enables/disables transparency shadow effects."
15441 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
15442 "\n\t\t: -env Enables/disables environment map background."
15443 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
15444 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
15445 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
15446 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
15447 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
15448 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
15449 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
15450 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
15451 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
15452 "\n\t\t: -whitePoint White point value for filmic tone mapping."
15453 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
15454 "\n\t\t: PBR environment baking parameters (advanced/debug):"
15455 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
15456 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
15457 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
15458 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
15459 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
15460 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
15461 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
15462 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
15463 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
15464 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
15465 "\n\t\t: Debug options:"
15466 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
15467 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
15468 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
15469 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 15470 __FILE__, VRenderParams, group);
79b544e6 15471 theCommands.Add("vstatprofiler",
15472 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
15473 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 15474 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 15475 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
15476 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
15477 "\n [-noredraw]"
15478 "\n\t\t: Prints rendering statistics."
15479 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
15480 "\n\t\t: else - print all performance counters set previously."
15481 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
15482 __FILE__, VStatProfiler, group);
49e1a5c7 15483 theCommands.Add ("vplace",
15484 "vplace dx dy"
15485 "\n\t\t: Places the point (in pixels) at the center of the window",
15486 __FILE__, VPlace, group);
0717ddc1 15487 theCommands.Add("vxrotate",
15488 "vxrotate",
15489 __FILE__,VXRotate,group);
15490
625e1958 15491 theCommands.Add("vmanipulator",
15492 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
15493 "\n tool to create and manage AIS manipulators."
15494 "\n Options: "
15495 "\n '-attach AISObject' attach manipulator to AISObject"
ff6122e0 15496 "\n '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching"
625e1958 15497 "\n '-adjustSize {0|1}' adjust size when attaching"
15498 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 15499 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
15500 "\n by default it is displayed in all views of the current viewer"
625e1958 15501 "\n '-detach' detach manipulator"
15502 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
15503 "\n '-transform mouse_x mouse_y' - invoke transformation"
15504 "\n '-stopTransform [abort]' - invoke stop of transformation"
15505 "\n '-move x y z' - move attached object"
15506 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
15507 "\n '-scale factor' - scale attached object"
15508 "\n '-autoActivate {0|1}' - set activation on detection"
15509 "\n '-followTranslation {0|1}' - set following translation transform"
15510 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 15511 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 15512 "\n '-gap value' - set gap between sub-parts"
15513 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 15514 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 15515 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
15516 "\n '-size value' - set size of manipulator"
15517 "\n '-zoomable {0|1}' - set zoom persistence",
15518 __FILE__, VManipulator, group);
15519
8e5fb5ea 15520 theCommands.Add("vselprops",
f838dac4 15521 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 15522 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
15523 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 15524 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
15525 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 15526 "\n -pickStrategy {first|topmost} : defines picking strategy"
15527 "\n 'first' to pick first acceptable (default)"
15528 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 15529 "\n -pixTol value : sets up pixel tolerance"
8c36926a 15530 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
15531 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
15532 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 15533 "\n -dispMode dispMode : sets display mode for highlighting"
15534 "\n -layer ZLayer : sets ZLayer for highlighting"
15535 "\n -color {name|r g b} : sets highlight color"
15536 "\n -transp value : sets transparency coefficient for highlight"
15537 "\n -material material : sets highlight material"
8e5fb5ea 15538 "\n -print : prints current state of all mentioned parameters",
15539 __FILE__, VSelectionProperties, group);
be3d8cbc 15540 theCommands.Add ("vhighlightselected",
15541 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
15542 __FILE__, VSelectionProperties, group);
8e5fb5ea 15543
decdee7d 15544 theCommands.Add ("vseldump",
15545 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
b40cdc2b 15546 "\n\t\t: [-xrPose base|head=base]"
decdee7d 15547 "\n\t\t: Generate an image based on detection results:"
15548 "\n\t\t: depth normalized depth values"
15549 "\n\t\t: unnormDepth unnormalized depth values"
15550 "\n\t\t: object color of detected object"
15551 "\n\t\t: owner color of detected owner"
15552 "\n\t\t: selMode color of selection mode"
15553 "\n\t\t: entity color of etected entity",
15554 __FILE__, VDumpSelectionImage, group);
293211ae 15555
2108d9a2 15556 theCommands.Add ("vviewcube",
15557 "vviewcube name"
15558 "\n\t\t: Displays interactive view manipualtion object."
15559 "\n\t\t: Options: "
15560 "\n\t\t: -reset reset geomertical and visual attributes'"
15561 "\n\t\t: -size Size adapted size of View Cube"
15562 "\n\t\t: -boxSize Size box size"
0aeb8984 15563 "\n\t\t: -axes {0|1} show/hide axes (trihedron)"
2108d9a2 15564 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
15565 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
15566 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
15567 "\n\t\t: -color Color color of View Cube"
15568 "\n\t\t: -boxColor Color box color"
15569 "\n\t\t: -boxSideColor Color box sides color"
15570 "\n\t\t: -boxEdgeColor Color box edges color"
15571 "\n\t\t: -boxCornerColor Color box corner color"
15572 "\n\t\t: -textColor Color color of side text of view cube"
15573 "\n\t\t: -innerColor Color inner box color"
15574 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
15575 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
0aeb8984 15576 "\n\t\t: -xAxisTextColor Color color of X axis label"
15577 "\n\t\t: -yAxisTextColor Color color of Y axis label"
15578 "\n\t\t: -zAxisTextColor Color color of Z axis label"
2108d9a2 15579 "\n\t\t: -font Name font name"
15580 "\n\t\t: -fontHeight Value font height"
15581 "\n\t\t: -boxFacetExtension Value box facet extension"
15582 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
15583 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
15584 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15585 "\n\t\t: -axesPadding Value padding between box and arrows"
15586 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15587 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15588 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15589 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15590 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15591 "\n\t\t: -duration Seconds animation duration in seconds",
15592 __FILE__, VViewCube, group);
15593
14b741b0 15594 theCommands.Add("vcolorconvert" ,
15595 "vcolorconvert {from|to} type C1 C2 C2"
15596 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15597 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15598 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15599 __FILE__,VColorConvert,group);
15600 theCommands.Add("vcolordiff" ,
15601 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15602 __FILE__,VColorDiff,group);
6a2fb7a1 15603 theCommands.Add("vselbvhbuild",
15604 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15605 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15606 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15607 "\n\t\t: -wait waits for building all of BVH",
15608 __FILE__,VSelBvhBuild,group);
2108d9a2 15609}