0014673: Provide true support for Unicode symbols
[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>
0a768f56 25#include <AIS_ListOfInteractive.hxx>
26#include <AIS_ListIteratorOfListOfInteractive.hxx>
49582f9d 27#include <AIS_Manipulator.hxx>
2108d9a2 28#include <AIS_ViewCube.hxx>
49582f9d 29#include <AIS_Shape.hxx>
30#include <Aspect_DisplayConnection.hxx>
8a590580 31#include <Aspect_Grid.hxx>
49582f9d 32#include <Aspect_TypeOfLine.hxx>
33#include <Draw.hxx>
34#include <Draw_Appli.hxx>
35#include <Draw_Interpretor.hxx>
08f8a185 36#include <Draw_ProgressIndicator.hxx>
49582f9d 37#include <gp_Dir.hxx>
38#include <gp_Pln.hxx>
39#include <gp_Pnt.hxx>
61b0191c 40#include <Graphic3d_ArrayOfPolylines.hxx>
49582f9d 41#include <Graphic3d_AspectFillArea3d.hxx>
2bd4c032 42#include <Graphic3d_AspectMarker3d.hxx>
49582f9d 43#include <Graphic3d_ClipPlane.hxx>
077a220c 44#include <Graphic3d_CubeMapPacked.hxx>
45#include <Graphic3d_CubeMapSeparate.hxx>
a79f67f8 46#include <Graphic3d_GraduatedTrihedron.hxx>
49582f9d 47#include <Graphic3d_NameOfTextureEnv.hxx>
48#include <Graphic3d_Texture2Dmanual.hxx>
269294d6 49#include <Graphic3d_TextureEnv.hxx>
50#include <Graphic3d_TextureParams.hxx>
51#include <Graphic3d_TypeOfTextureFilter.hxx>
49582f9d 52#include <Image_AlienPixMap.hxx>
53#include <Image_Diff.hxx>
54#include <Image_VideoRecorder.hxx>
7e785937 55#include <Message_ProgressScope.hxx>
56#include <Message_ProgressRange.hxx>
49582f9d 57#include <NCollection_DataMap.hxx>
18d715bd 58#include <NCollection_List.hxx>
d6fbb2ab 59#include <NCollection_LocalArray.hxx>
18d715bd 60#include <NCollection_Vector.hxx>
8693dfd0 61#include <OSD.hxx>
6a2fb7a1 62#include <OSD_Parallel.hxx>
208e6839 63#include <OSD_Timer.hxx>
49582f9d 64#include <OpenGl_GraphicDriver.hxx>
4269bd1b 65#include <Prs3d_ShadingAspect.hxx>
6262338c 66#include <Prs3d_Drawer.hxx>
61b0191c 67#include <Prs3d_LineAspect.hxx>
fd3f6bd0 68#include <Prs3d_Text.hxx>
69#include <Select3D_SensitivePrimitiveArray.hxx>
49582f9d 70#include <TColStd_HSequenceOfAsciiString.hxx>
71#include <TColStd_SequenceOfInteger.hxx>
72#include <TColStd_HSequenceOfReal.hxx>
73#include <TColgp_Array1OfPnt2d.hxx>
74#include <TColStd_MapOfAsciiString.hxx>
75#include <ViewerTest_AutoUpdater.hxx>
08b7a39f 76#include <ViewerTest_ContinuousRedrawer.hxx>
49582f9d 77#include <ViewerTest_EventManager.hxx>
78#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
79#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
80#include <ViewerTest_CmdParser.hxx>
81#include <ViewerTest_V3dView.hxx>
82#include <V3d_AmbientLight.hxx>
83#include <V3d_DirectionalLight.hxx>
84#include <V3d_PositionalLight.hxx>
85#include <V3d_SpotLight.hxx>
7fd59977 86
293211ae 87#include <tcl.h>
88
692613e5 89#include <cstdlib>
25289ec1 90
58655684 91#if defined(_WIN32)
4fe56619 92 #include <WNT_WClass.hxx>
93 #include <WNT_Window.hxx>
d6fbb2ab 94 #include <WNT_HIDSpaceMouse.hxx>
4fe56619 95#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 96 #include <Cocoa_Window.hxx>
7fd59977 97#else
4fe56619 98 #include <Xw_Window.hxx>
99 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
100 #include <X11/Xutil.h>
101 #include <tk.h>
7fd59977 102#endif
103
7fd59977 104//==============================================================================
105// VIEWER GLOBAL VARIABLES
106//==============================================================================
107
108Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 109Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 110
111Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 112extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 113
58655684 114#if defined(_WIN32)
7fd59977 115static Handle(WNT_Window)& VT_GetWindow() {
116 static Handle(WNT_Window) WNTWin;
117 return WNTWin;
118}
4fe56619 119#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 120static Handle(Cocoa_Window)& VT_GetWindow()
121{
122 static Handle(Cocoa_Window) aWindow;
123 return aWindow;
124}
125extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 126extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
127
7fd59977 128#else
7fd59977 129static Handle(Xw_Window)& VT_GetWindow(){
130 static Handle(Xw_Window) XWWin;
131 return XWWin;
132}
7fd59977 133
134static void VProcessEvents(ClientData,int);
135#endif
136
18d715bd 137static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
138{
139 static Handle(Aspect_DisplayConnection) aDisplayConnection;
140 return aDisplayConnection;
141}
142
143static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
144{
145 GetDisplayConnection() = theDisplayConnection;
146}
147
18d715bd 148NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 149static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 150static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
58655684 151static OpenGl_Caps ViewerTest_myDefaultCaps;
18d715bd 152
7fd59977 153static void OSWindowSetup();
154
f42753ed 155static struct
156{
157 Quantity_Color FlatColor;
158 Quantity_Color GradientColor1;
159 Quantity_Color GradientColor2;
160 Aspect_GradientFillMethod FillMethod;
161} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
162
7fd59977 163//==============================================================================
164// EVENT GLOBAL VARIABLES
165//==============================================================================
166
1beb58d7 167Standard_Boolean TheIsAnimating = Standard_False;
7fd59977 168
293211ae 169namespace
170{
171
172 //! Checks if some set is a subset of other set
173 //! @tparam TheSuperSet the type of the superset
174 //! @tparam TheSubSet the type of the subset
175 //! @param theSuperSet the superset
176 //! @param theSubSet the subset to be checked
177 //! @return true if the superset includes subset, or false otherwise
178 template <typename TheSuperSet, typename TheSubSet>
179 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
180 {
181 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
182 }
183
184 //! A variable set of keys for command-line options.
185 //! It includes a set of mandatory keys and a set of all possible keys.
186 class CommandOptionKeyVariableSet
187 {
188 public:
189 //! Default constructor
190 CommandOptionKeyVariableSet()
191 {
192 }
193
194 //! Constructor
195 //! @param theMandatoryKeySet the set of the mandatory option keys
196 //! @param theAdditionalKeySet the set of additional options that could be omitted
197 CommandOptionKeyVariableSet (
198 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
199 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
200 : myMandatoryKeySet (theMandatoryKeySet)
201 {
202 std::set_union (theMandatoryKeySet.begin(),
203 theMandatoryKeySet.end(),
204 theAdditionalKeySet.begin(),
205 theAdditionalKeySet.end(),
206 std::inserter (myFullKeySet, myFullKeySet.begin()));
207 }
208
209 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
210 //! and be contained in the full key set)
211 //! @param theCheckedKeySet the set of option keys to be checked
212 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
213 {
214 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
215 }
216
217 private:
218 //! A set of mandatory command-line option keys
219 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
220
221 //! A full set of command-line option keys (includes mandatory and additional option keys)
222 ViewerTest_CommandOptionKeySet myFullKeySet;
223 };
224
225 //! Gets some code by its name
226 //! @tparam TheCode the type of a code to be found
227 //! @param theCodeNameMap the map from code names to codes
228 //! @param theCodeName the name of a code to be found
229 //! @param theCode the code to be found
230 //! @return true if a code is found, or false otherwise
231 template <typename TheCode>
232 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
233 TCollection_AsciiString theCodeName,
234 TheCode& theCode)
235 {
236 theCodeName.LowerCase();
237 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
238 theCodeName);
239 if (aCodeIterator == theCodeNameMap.end())
240 {
241 return false;
242 }
243 theCode = aCodeIterator->second;
244 return true;
245 }
246
247 // Defines possible commands related to background changing
248 enum BackgroundCommand
249 {
077a220c 250 BackgroundCommand_Main, //!< The main command that manages other commands through options
251 BackgroundCommand_Image, //!< Sets an image as a background
252 BackgroundCommand_ImageMode, //!< Changes a background image mode
253 BackgroundCommand_Gradient, //!< Sets a gradient as a background
254 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
255 BackgroundCommand_Color, //!< Fills background with a specified color
256 BackgroundCommand_Default //!< Sets the background default color or gradient
293211ae 257 };
258
259 //! Map from background command names to its codes
260 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
261
262 //! Creates a map from background command names to its codes
263 //! @return a map from background command names to its codes
264 static BackgroundCommandNameMap createBackgroundCommandNameMap()
265 {
266 BackgroundCommandNameMap aBackgroundCommandNameMap;
077a220c 267 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
268 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
269 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
270 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
271 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
272 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
273 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
293211ae 274 return aBackgroundCommandNameMap;
275 }
276
277 //! Gets a background command by its name
278 //! @param theBackgroundCommandName the name of the background command
279 //! @param theBackgroundCommand the background command to be found
280 //! @return true if a background command is found, or false otherwise
281 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
282 BackgroundCommand& theBackgroundCommand)
283 {
284 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
285 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
286 }
287
288 //! Map from background image fill method names to its codes
289 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
290
291 //! Creates a map from background image fill method names to its codes
292 //! @return a map from background image fill method names to its codes
293 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
294 {
295 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
296 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
297 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
298 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
299 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
300 return aBackgroundImageFillMethodNameMap;
301 }
302
303 //! Gets a background image fill method by its name
304 //! @param theBackgroundImageFillMethodName the name of the background image fill method
305 //! @param theBackgroundImageFillMethod the background image fill method to be found
306 //! @return true if a background image fill method is found, or false otherwise
307 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
308 Aspect_FillMethod& theBackgroundImageFillMethod)
309 {
310 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
311 createBackgroundImageFillMethodNameMap();
312 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
313 theBackgroundImageFillMethodName,
314 theBackgroundImageFillMethod);
315 }
316
317 //! Map from background gradient fill method names to its codes
318 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
319
320 //! Creates a map from background gradient fill method names to its codes
321 //! @return a map from background gradient fill method names to its codes
322 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
323 {
324 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
325 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
326 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
327 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
328 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
329 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
330 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
331 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
332 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
333 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
334 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
335 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
336 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
337 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
338 return aBackgroundGradientFillMethodNameMap;
339 }
340
341 //! Gets a gradient fill method by its name
342 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
343 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
344 //! @return true if a gradient fill method is found, or false otherwise
345 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
346 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
347 {
348 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
349 createBackgroundGradientFillMethodNameMap();
350 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
351 theBackgroundGradientFillMethodName,
352 theBackgroundGradientFillMethod);
353 }
354
355 //! Changes the background in accordance with passed command line options
356 class BackgroundChanger
357 {
358 public:
359 //! Constructor. Prepares the command parser
360 BackgroundChanger()
361 {
362 prepareCommandParser();
363 }
364
365 //! Processes the command line and changes the background
366 //! @param theDrawInterpretor the interpreter of the Draw Harness application
367 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
368 //! @param theCommandLineArguments the array of command line arguments
369 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
370 const Standard_Integer theNumberOfCommandLineArguments,
371 const char* const* const theCommandLineArguments)
372 {
373 const char* const aBackgroundCommandName = theCommandLineArguments[0];
374 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
375 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
376 {
377 return false;
378 }
379 addCommandDescription (aBackgroundCommand);
380 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
381 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
382 }
383
384 private:
385 //! The type of functions that are able to set gradient background filling
386 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
387 const Quantity_Color& /* theColor2 */,
388 const Aspect_GradientFillMethod /* theGradientMode */);
389
390 //! The type of functions that are able to fill a background with a specific color
391 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
392
393 //! the command parser used to parse command line options and its arguments
394 ViewerTest_CmdParser myCommandParser;
395
396 //! the option key for the command that sets an image as a background
397 ViewerTest_CommandOptionKey myImageOptionKey;
398
399 //! the option key for the command that sets a background image fill type
400 ViewerTest_CommandOptionKey myImageModeOptionKey;
401
402 //! the option key for the command that sets a gradient filling for the background
403 ViewerTest_CommandOptionKey myGradientOptionKey;
404
405 //! the option key for the command that sets a background gradient filling method
406 ViewerTest_CommandOptionKey myGradientModeOptionKey;
407
408 //! the option key for the command that fills background with a specific color
409 ViewerTest_CommandOptionKey myColorOptionKey;
410
411 //! the option key for the command that sets default background gradient or color
412 ViewerTest_CommandOptionKey myDefaultOptionKey;
413
077a220c 414 //! the option key for the command that sets an environment cubemap as a background
415 ViewerTest_CommandOptionKey myCubeMapOptionKey;
416
417 //! the option key for the command that defines order of tiles in one image packed cubemap
418 ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
419
420 //! the option key for the command that sets inversion of Z axis for background cubemap
421 ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
422
67312b79 423 //! the option key for the command that allows skip IBL map generation
424 ViewerTest_CommandOptionKey myCubeMapDoNotGenPBREnvOptionKey;
425
293211ae 426 //! the variable set of options that are allowed for the old scenario (without any option passed)
427 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
428
077a220c 429 //! the variable set of options that are allowed for setting an environment cubemap as background
430 CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
431
293211ae 432 //! the variable set of options that are allowed for setting an image as a background
433 CommandOptionKeyVariableSet myImageOptionVariableSet;
434
435 //! the variable set of options that are allowed for setting a background image fill type
436 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
437
438 //! the variable set of options that are allowed for setting a gradient filling for the background
439 CommandOptionKeyVariableSet myGradientOptionVariableSet;
440
441 //! the variable set of options that are allowed for setting a background gradient filling method
442 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
443
444 //! the variable set of options that are allowed for filling a background with a specific color
445 CommandOptionKeyVariableSet myColorOptionVariableSet;
446
447 //! the variable set of options that are allowed for setting a default background gradient
448 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
449
450 //! the variable set of options that are allowed for setting a default background color
451 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
452
453 //! the variable set of options that are allowed for printing help
454 CommandOptionKeyVariableSet myHelpOptionVariableSet;
455
456 //! Adds options to command parser
457 void addOptionsToCommandParser()
458 {
459 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
460 "filename of image used as background");
461 myImageModeOptionKey = myCommandParser.AddOption (
462 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
463 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
464 "sets background gradient starting and ending colors");
465 myGradientModeOptionKey =
466 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
467 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
468 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
469 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
470 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
077a220c 471
472 myCubeMapOptionKey = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
473 myCubeMapOrderOptionKey = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
474 myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
475 "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
67312b79 476 myCubeMapDoNotGenPBREnvOptionKey = myCommandParser.AddOption ("nopbrenv", "whether IBL map generation should be skipped");
293211ae 477 }
478
479 //! Creates option sets used to determine if a passed option set is valid or not
480 void createOptionSets()
481 {
482 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
483 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
484 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
485
077a220c 486 ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
487 aCubeMapOptionSet.insert (myCubeMapOptionKey);
488 ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
489 aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
67312b79 490 aCubeMapAdditionalOptionKeySet.insert (myCubeMapDoNotGenPBREnvOptionKey);
077a220c 491 aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
492 myCubeMapOptionVariableSet = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
493
293211ae 494 ViewerTest_CommandOptionKeySet anImageOptionSet;
495 anImageOptionSet.insert (myImageOptionKey);
496 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
497 anImageModeOptionSet.insert (myImageModeOptionKey);
498 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
499 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
500
501 ViewerTest_CommandOptionKeySet aGradientOptionSet;
502 aGradientOptionSet.insert (myGradientOptionKey);
503 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
504 aGradientModeOptionSet.insert (myGradientModeOptionKey);
505 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
506 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
507
508 ViewerTest_CommandOptionKeySet aColorOptionSet;
509 aColorOptionSet.insert (myColorOptionKey);
510 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
511
512 aGradientOptionSet.insert (myDefaultOptionKey);
513 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
514 aColorOptionSet.insert (myDefaultOptionKey);
515 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
516
517 ViewerTest_CommandOptionKeySet aHelpOptionSet;
518 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
519 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
520 }
521
522 //! Prepares the command parser. Adds options and creates option sets used to determine
523 //! if a passed option set is valid or not
524 void prepareCommandParser()
525 {
526 addOptionsToCommandParser();
527 createOptionSets();
528 }
529
530 //! Adds a command description to the command parser
531 //! @param theBackgroundCommand the key of the command which description is added to the command parser
532 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
533 {
534 std::string aDescription;
535 bool isMainCommand = false;
536 switch (theBackgroundCommand)
537 {
538 case BackgroundCommand_Main:
539 aDescription = "Command: vbackground (changes background or some background settings)";
540 isMainCommand = true;
541 break;
542 case BackgroundCommand_Image:
543 aDescription = "Command: vsetbg (loads image as a background)";
544 break;
545 case BackgroundCommand_ImageMode:
546 aDescription = "Command: vsetbgmode (changes background fill type)";
547 break;
548 case BackgroundCommand_Gradient:
549 aDescription = "Command: vsetgradientbg (mounts gradient background)";
550 break;
551 case BackgroundCommand_GradientMode:
552 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
553 break;
554 case BackgroundCommand_Color:
555 aDescription = "Command: vsetcolorbg (sets color background)";
556 break;
557 case BackgroundCommand_Default:
558 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
559 break;
560 default:
561 return;
562 }
563 if (!isMainCommand)
564 {
565 aDescription += "\nThis command is obsolete. Use vbackground instead.";
566 }
567 myCommandParser.SetDescription (aDescription);
568 }
569
570 //! Check if a viewer is needed to be initialized
571 //! @param theBackgroundCommand the key of the command that changes the background
572 //! @return true if processing was successful, or false otherwise
573 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
574 {
575 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
576 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
577 const bool aViewerIsNotNeeded =
578 (theBackgroundCommand == BackgroundCommand_Default)
579 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
580 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
581 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
582 return !aViewerIsNotNeeded;
583 }
584
585 //! Check if a viewer is initialized
586 //! @param theBackgroundCommandName the name of the command that changes the background
587 //! @param theDrawInterpretor the interpreter of the Draw Harness application
588 //! @return true if a viewer is initialized, or false otherwise
589 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
590 Draw_Interpretor& theDrawInterpretor)
591 {
592 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
593 if (anAISContext.IsNull())
594 {
595 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
596 return false;
597 }
598 return true;
599 }
600
601 //! Processes command options
602 //! @param theBackgroundCommandName the name of the command that changes the background
603 //! @param theBackgroundCommand the key of the command that changes the background
604 //! @param theDrawInterpretor the interpreter of the Draw Harness application
605 //! @return true if processing was successful, or false otherwise
606 bool processCommandOptions (const char* const theBackgroundCommandName,
607 const BackgroundCommand theBackgroundCommand,
608 Draw_Interpretor& theDrawInterpretor) const
609 {
610 if (myCommandParser.HasNoOption())
611 {
612 return printHelp (theBackgroundCommandName, theDrawInterpretor);
613 }
614 if (checkViewerIsNeeded (theBackgroundCommand)
615 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
616 {
617 return false;
618 }
619 if (myCommandParser.HasOnlyUnnamedOption())
620 {
621 return processUnnamedOption (theBackgroundCommand);
622 }
623 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
624 }
625
626 //! Processes the unnamed option
627 //! @param theBackgroundCommand the key of the command that changes the background
628 //! @return true if processing was successful, or false otherwise
629 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
630 {
631 switch (theBackgroundCommand)
632 {
633 case BackgroundCommand_Main:
634 return false;
635 case BackgroundCommand_Image:
636 return processImageUnnamedOption();
637 case BackgroundCommand_ImageMode:
638 return processImageModeUnnamedOption();
639 case BackgroundCommand_Gradient:
640 return processGradientUnnamedOption();
641 case BackgroundCommand_GradientMode:
642 return processGradientModeUnnamedOption();
643 case BackgroundCommand_Color:
644 return processColorUnnamedOption();
645 case BackgroundCommand_Default:
646 return processDefaultUnnamedOption();
647 default:
648 return false;
649 }
650 }
651
652 //! Processes the image unnamed option
653 //! @return true if processing was successful, or false otherwise
654 bool processImageUnnamedOption() const
655 {
656 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
657 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
658 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
659 {
660 return false;
661 }
662 std::string anImageFileName;
663 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
664 {
665 return false;
666 }
667 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
668 if (aNumberOfImageUnnamedOptionArguments == 2)
669 {
670 std::string anImageModeString;
671 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
672 {
673 return false;
674 }
675 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
676 {
677 return false;
678 }
679 }
680 setImage (anImageFileName.c_str(), anImageMode);
681 return true;
682 }
683
684 //! Processes the image mode unnamed option
685 //! @return true if processing was successful, or false otherwise
686 bool processImageModeUnnamedOption() const
687 {
688 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
689 }
690
691 //! Processes the gradient unnamed option
692 //! @param theSetGradient the function used to set a background gradient filling
693 //! @return true if processing was successful, or false otherwise
694 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
695 {
696 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
697 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
698 if (aNumberOfGradientUnnamedOptionArguments < 2)
699 {
700 return false;
701 }
702
703 Standard_Integer anArgumentIndex = 0;
704 Quantity_Color aColor1;
705 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
706 {
707 return false;
708 }
709 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
710 {
711 return false;
712 }
713
714 Quantity_Color aColor2;
715 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
716 {
717 return false;
718 }
719 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
720 {
721 return false;
722 }
723
724 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
725 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
726 {
727 std::string anGradientModeString;
728
729 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
730 anArgumentIndex,
731 anGradientModeString))
732 {
733 return false;
734 }
735 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
736 {
737 return false;
738 }
739 ++anArgumentIndex;
740 }
741 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
742 {
743 return false;
744 }
745 theSetGradient (aColor1, aColor2, aGradientMode);
746 return true;
747 }
748
749 //! Processes the gradient mode unnamed option
750 //! @return true if processing was successful, or false otherwise
751 bool processGradientModeUnnamedOption() const
752 {
753 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
754 }
755
756 //! Processes the color unnamed option
757 //! @param theSetColor the function used to set a background color
758 //! @return true if processing was successful, or false otherwise
759 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
760 {
761 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
762 }
763
764 //! Processes the default back unnamed option
765 //! @return true if processing was successful, or false otherwise
766 bool processDefaultUnnamedOption() const
767 {
768 if (processGradientUnnamedOption (setDefaultGradient))
769 {
770 return true;
771 }
772 return processColorUnnamedOption (setDefaultColor);
773 }
774
775 //! Processes named options
776 //! @param theBackgroundCommandName the name of the command that changes the background
777 //! @param theBackgroundCommand the key of the command that changes the background
778 //! @param theDrawInterpretor the interpreter of the Draw Harness application
779 //! @return true if processing was successful, or false otherwise
780 bool processNamedOptions (const char* const theBackgroundCommandName,
781 const BackgroundCommand theBackgroundCommand,
782 Draw_Interpretor& theDrawInterpretor) const
783 {
784 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
785 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
077a220c 786 if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
787 {
788 return processCubeMapOptionSet();
789 }
293211ae 790 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
791 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
792 {
793 return processImageOptionSet();
794 }
795 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
796 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
797 {
798 return processImageModeOptionSet();
799 }
800 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
801 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
802 {
803 return processGradientOptionSet();
804 }
805 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
806 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
807 {
808 return processGradientModeOptionSet();
809 }
810 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
811 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
812 {
813 return processColorOptionSet();
814 }
815 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
816 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
817 && (theBackgroundCommand == BackgroundCommand_Default)))
818 {
819 return processDefaultGradientOptionSet();
820 }
821 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
822 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
823 {
824 return processDefaultColorOptionSet();
825 }
826 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
827 {
828 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
829 }
830 return false;
831 }
832
077a220c 833 //! Process the cubemap option set in named and unnamed case.
834 //! @return true if processing was successful, or false otherwise
835 bool processCubeMapOptionSet() const
836 {
837 NCollection_Array1<TCollection_AsciiString> aFilePaths;
838
839 if (!processCubeMapOptions (aFilePaths))
840 {
841 return false;
842 }
843
844 Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
845
846 if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
847 {
848 if (!processCubeMapOrderOptions (anOrder))
849 {
850 return false;
851 }
852 }
853
854 bool aZIsInverted = false;
855 if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
856 {
857 if (!processCubeMapInvertedZOptionSet())
858 {
859 return false;
860 }
861 aZIsInverted = true;
862 }
863
67312b79 864 bool aToGenPBREnv = true;
865 if (myCommandParser.HasOption (myCubeMapDoNotGenPBREnvOptionKey))
866 {
867 if (!processCubeMapDoNotGenPBREnvOptionSet())
868 {
869 return false;
870 }
871 aToGenPBREnv = false;
872 }
873
874 setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted, aToGenPBREnv);
077a220c 875 return true;
876 }
877
293211ae 878 //! Processes the image option set
879 //! @return true if processing was successful, or false otherwise
880 bool processImageOptionSet() const
881 {
882 std::string anImageFileName;
883 if (!processImageOption (anImageFileName))
884 {
885 return false;
886 }
887 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
888 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
889 {
890 return false;
891 }
892 setImage (anImageFileName.c_str(), anImageMode);
893 return true;
894 }
895
896 //! Processes the image mode option set
897 //! @return true if processing was successful, or false otherwise
898 bool processImageModeOptionSet() const
899 {
900 return processImageModeOptionSet (myImageModeOptionKey);
901 }
902
903 //! Processes the image mode option set
904 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
905 //! @return true if processing was successful, or false otherwise
906 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
907 {
908 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
909 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
910 {
911 return false;
912 }
913 setImageMode (anImageMode);
914 return true;
915 }
916
917 //! Processes the gradient option set
918 //! @param theSetGradient the function used to set a background gradient filling
919 //! @return true if processing was successful, or false otherwise
920 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
921 {
922 Quantity_Color aColor1;
923 Quantity_Color aColor2;
924 if (!processGradientOption (aColor1, aColor2))
925 {
926 return false;
927 }
928 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
929 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
930 {
931 return false;
932 }
933 theSetGradient (aColor1, aColor2, aGradientMode);
934 return true;
935 }
936
937 //! Processes the gradient mode option set
938 //! @return true if processing was successful, or false otherwise
939 bool processGradientModeOptionSet() const
940 {
941 return processGradientModeOptionSet (myGradientModeOptionKey);
942 }
943
944 //! Processes the gradient mode option set
945 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
946 //! @return true if processing was successful, or false otherwise
947 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
948 {
949 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
950 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
951 {
952 return false;
953 }
954 setGradientMode (aGradientMode);
955 return true;
956 }
957
958 //! Processes the color option set
959 //! @param theSetColor the function used to set a background color
960 //! @return true if processing was successful, or false otherwise
961 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
962 {
963 return processColorOptionSet (myColorOptionKey, theSetColor);
964 }
965
966 //! Processes the default color option set
967 //! @return true if processing was successful, or false otherwise
968 bool processDefaultGradientOptionSet() const
969 {
970 return processGradientOptionSet (setDefaultGradient);
971 }
972
973 //! Processes the default gradient option set
974 //! @return true if processing was successful, or false otherwise
975 bool processDefaultColorOptionSet() const
976 {
977 return processColorOptionSet (setDefaultColor);
978 }
979
980 //! Processes the color option set
981 //! @param theColorOptionKey the key of the option that is interpreted as a color option
982 //! @param theSetColor the function used to set a background color
983 //! @return true if processing was successful, or false otherwise
984 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
985 SetColorFunction* const theSetColor = setColor) const
986 {
987 Quantity_Color aColor;
988 if (!processColorOption (theColorOptionKey, aColor))
989 {
990 return false;
991 }
992 theSetColor (aColor);
993 return true;
994 }
995
996 //! Processes the help option set
997 //! @param theBackgroundCommandName the name of the command that changes the background
998 //! @param theDrawInterpretor the interpreter of the Draw Harness application
999 //! @return true if processing was successful, or false otherwise
1000 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1001 {
1002 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1003 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1004 if (aNumberOfHelpOptionArguments != 0)
1005 {
1006 return false;
1007 }
1008 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1009 }
1010
077a220c 1011 //! Processes the cubemap option
1012 //! @param theFilePaths the array of filenames of cubemap sides
1013 //! @return true if processing was successful, or false otherwise
1014 bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
1015 {
1016 const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
1017
1018 if (aNumberOfCubeMapOptionArguments != 1
1019 && aNumberOfCubeMapOptionArguments != 6)
1020 {
1021 return false;
1022 }
1023
1024 theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
1025
1026 for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
1027 {
1028 std::string aCubeMapFileName;
1029 if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
1030 {
1031 return false;
1032 }
1033 theFilePaths[i] = aCubeMapFileName.c_str();
1034 }
1035
1036 return true;
1037 }
1038
67312b79 1039 //! Processes the inverted z cubemap option
077a220c 1040 //! @return true if processing was successful, or false otherwise
1041 bool processCubeMapInvertedZOptionSet () const
1042 {
1043 const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
1044 myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
1045
1046 if (aNumberOfCubeMapZInversionOptionArguments != 0)
1047 {
1048 return false;
1049 }
1050
1051 return true;
1052 }
1053
67312b79 1054 //! Processes the option allowing to skip IBM maps generation
1055 //! @return true if processing was successful, or false otherwise
1056 bool processCubeMapDoNotGenPBREnvOptionSet() const
1057 {
1058 const Standard_Integer aNumberOfCubeMapDoNotGenPBREnvOptionArguments =
1059 myCommandParser.GetNumberOfOptionArguments(myCubeMapDoNotGenPBREnvOptionKey);
1060
1061 if (aNumberOfCubeMapDoNotGenPBREnvOptionArguments != 0)
1062 {
1063 return false;
1064 }
1065
1066 return true;
1067 }
1068
077a220c 1069 //! Processes the tiles order option
1070 //! @param theOrder the array of indexes if cubemap sides in tile grid
1071 //! @return true if processing was successful, or false otherwise
1072 bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
1073 {
1074 const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
1075 myCubeMapOrderOptionKey);
1076
1077 if (aNumberOfCubeMapOrderOptionArguments != 6)
1078 {
1079 return false;
1080 }
1081
1082
1083 for (unsigned int i = 0; i < 6; ++i)
1084 {
1085 std::string anOrderItem;
1086 if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem))
1087 {
1088 return false;
1089 }
1090
1091 theOrder.Set (Graphic3d_CubeMapSide (i),
1092 static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
1093 }
1094
1095 return theOrder.IsValid();
1096 }
1097
293211ae 1098 //! Processes the image option
1099 //! @param theImageFileName the filename of the image to be used as a background
1100 //! @return true if processing was successful, or false otherwise
1101 bool processImageOption (std::string& theImageFileName) const
1102 {
1103 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1104 myImageOptionKey);
1105 if (aNumberOfImageOptionArguments != 1)
1106 {
1107 return false;
1108 }
1109 std::string anImageFileName;
1110 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1111 {
1112 return false;
1113 }
1114 theImageFileName = anImageFileName;
1115 return true;
1116 }
1117
1118 //! Processes the image mode option
1119 //! @param theImageMode the fill type used for a background image
1120 //! @return true if processing was successful, or false otherwise
1121 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1122 {
1123 return processImageModeOption (myImageModeOptionKey, theImageMode);
1124 }
1125
1126 //! Processes the image mode option
1127 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1128 //! @param theImageMode the fill type used for a background image
1129 //! @return true if processing was successful, or false otherwise
1130 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1131 Aspect_FillMethod& theImageMode) const
1132 {
1133 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1134 }
1135
1136 //! Processes the gradient option
1137 //! @param theColor1 the gradient starting color
1138 //! @param theColor2 the gradient ending color
1139 //! @return true if processing was successful, or false otherwise
1140 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1141 {
1142 Standard_Integer anArgumentIndex = 0;
1143 Quantity_Color aColor1;
1144 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1145 {
1146 return false;
1147 }
1148 Quantity_Color aColor2;
1149 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1150 {
1151 return false;
1152 }
1153 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1154 myGradientOptionKey);
1155 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1156 {
1157 return false;
1158 }
1159 theColor1 = aColor1;
1160 theColor2 = aColor2;
1161 return true;
1162 }
1163
1164 //! Processes the gradient mode option
1165 //! @param theGradientMode the fill method used for a background gradient filling
1166 //! @return true if processing was successful, or false otherwise
1167 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1168 {
1169 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1170 }
1171
1172 //! Processes the gradient mode option
1173 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1174 //! @param theGradientMode the fill method used for a background gradient filling
1175 //! @return true if processing was successful, or false otherwise
1176 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1177 Aspect_GradientFillMethod& theGradientMode) const
1178 {
1179 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1180 }
1181
1182 //! Processes some mode option
1183 //! @tparam TheMode the type of a mode to be processed
1184 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1185 //! @param theMode a mode to be processed
1186 //! @return true if processing was successful, or false otherwise
1187 template <typename TheMode>
1188 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1189 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1190 TheMode& /* theMode */),
1191 TheMode& theMode) const
1192 {
1193 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1194 theModeOptionKey);
1195 if (aNumberOfModeOptionArguments != 1)
1196 {
1197 return false;
1198 }
1199 std::string aModeString;
1200 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1201 {
1202 return false;
1203 }
1204 TheMode aMode = TheMode();
1205 if (!theGetModeByName (aModeString.c_str(), aMode))
1206 {
1207 return false;
1208 }
1209 theMode = aMode;
1210 return true;
1211 }
1212
1213 //! Processes the color option
1214 //! @param theColor a color used for filling a background
1215 //! @return true if processing was successful, or false otherwise
1216 bool processColorOption (Quantity_Color& theColor) const
1217 {
1218 return processColorOption (myColorOptionKey, theColor);
1219 }
1220
1221 //! Processes the color option
1222 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1223 //! @param theColor a color used for filling a background
1224 //! @return true if processing was successful, or false otherwise
1225 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1226 {
1227 Standard_Integer anArgumentIndex = 0;
1228 Quantity_Color aColor;
1229 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1230 {
1231 return false;
1232 }
1233 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1234 theColorOptionKey);
1235 if (anArgumentIndex != aNumberOfColorOptionArguments)
1236 {
1237 return false;
1238 }
1239 theColor = aColor;
1240 return true;
1241 }
1242
1243 //! Prints helping message
1244 //! @param theBackgroundCommandName the name of the command that changes the background
1245 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1246 //! @return true if printing was successful, or false otherwise
1247 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1248 {
1249 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1250 }
1251
077a220c 1252 //! Sets the cubemap as a background
1253 //! @param theFileNames the array of filenames of packed or multifile cubemap
1254 //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
1255 static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
1256 const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default(),
67312b79 1257 bool theZIsInverted = false,
1258 bool theToGenPBREnv = true)
077a220c 1259 {
1260 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
1261 Handle(Graphic3d_CubeMap) aCubeMap;
1262
1263 if (theFileNames.Size() == 1)
1264 aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
1265 else
1266 aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
1267
1268 aCubeMap->SetZInversion (theZIsInverted);
1269
1270 aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
1271 aCubeMap->GetParams()->SetRepeat(Standard_False);
1272 aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
1273
67312b79 1274 aCurrentView->SetBackgroundCubeMap (aCubeMap, theToGenPBREnv, Standard_True);
077a220c 1275 }
1276
293211ae 1277 //! Sets the image as a background
1278 //! @param theImageFileName the filename of the image to be used as a background
1279 //! @param theImageMode the fill type used for a background image
1280 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1281 {
1282 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1283 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1284 }
1285
1286 //! Sets the fill type used for a background image
1287 //! @param theImageMode the fill type used for a background image
1288 static void setImageMode (const Aspect_FillMethod theImageMode)
1289 {
1290 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1291 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1292 }
1293
1294 //! Sets the gradient filling for a background
1295 //! @param theColor1 the gradient starting color
1296 //! @param theColor2 the gradient ending color
1297 //! @param theGradientMode the fill method used for a background gradient filling
1298 static void setGradient (const Quantity_Color& theColor1,
1299 const Quantity_Color& theColor2,
1300 const Aspect_GradientFillMethod theGradientMode)
1301 {
1302 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1303 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1304 }
1305
1306 //! Sets the fill method used for a background gradient filling
1307 //! @param theGradientMode the fill method used for a background gradient filling
1308 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1309 {
1310 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1311 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1312 }
1313
1314 //! Sets the color used for filling a background
1315 //! @param theColor the color used for filling a background
1316 static void setColor (const Quantity_Color& theColor)
1317 {
1318 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1319 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1320 aCurrentView->SetBackgroundColor (theColor);
1321 aCurrentView->Update();
1322 }
1323
1324 //! Sets the gradient filling for a background in a default viewer
1325 //! @param theColor1 the gradient starting color
1326 //! @param theColor2 the gradient ending color
1327 //! @param theGradientMode the fill method used for a background gradient filling
1328 static void setDefaultGradient (const Quantity_Color& theColor1,
1329 const Quantity_Color& theColor2,
1330 const Aspect_GradientFillMethod theGradientMode)
1331 {
1332 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1333 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1334 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1335 setDefaultGradient();
1336 }
1337
1338 //! Sets the color used for filling a background in a default viewer
1339 //! @param theColor the color used for filling a background
1340 static void setDefaultColor (const Quantity_Color& theColor)
1341 {
1342 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1343 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1344 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1345 ViewerTest_DefaultBackground.FlatColor = theColor;
1346 setDefaultGradient();
1347 setDefaultColor();
1348 }
1349
1350 //! Sets the gradient filling for a background in a default viewer.
1351 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1352 static void setDefaultGradient()
1353 {
1354 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1355 anInteractiveContextIterator (ViewerTest_myContexts);
1356 anInteractiveContextIterator.More();
1357 anInteractiveContextIterator.Next())
1358 {
1359 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1360 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1361 ViewerTest_DefaultBackground.GradientColor2,
1362 ViewerTest_DefaultBackground.FillMethod);
1363 }
1364 }
1365
1366 //! Sets the color used for filling a background in a default viewer.
1367 //! The color value is taken from ViewerTest_DefaultBackground structure
1368 static void setDefaultColor()
1369 {
1370 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1371 anInteractiveContextIterator (ViewerTest_myContexts);
1372 anInteractiveContextIterator.More();
1373 anInteractiveContextIterator.Next())
1374 {
1375 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1376 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1377 }
1378 }
1379 };
1380
1381} // namespace
b12e1c7b 1382
7fd59977 1383//==============================================================================
1384
57c28b61 1385#ifdef _WIN32
7fd59977 1386static LRESULT WINAPI ViewerWindowProc(
1387 HWND hwnd,
1388 UINT uMsg,
1389 WPARAM wParam,
1390 LPARAM lParam );
1391static LRESULT WINAPI AdvViewerWindowProc(
1392 HWND hwnd,
1393 UINT uMsg,
1394 WPARAM wParam,
1395 LPARAM lParam );
1396#endif
1397
1398
1399//==============================================================================
1400//function : WClass
1401//purpose :
1402//==============================================================================
1403
1bd04b5a 1404const Handle(WNT_WClass)& ViewerTest::WClass()
7fd59977 1405{
1bd04b5a 1406 static Handle(WNT_WClass) theWClass;
58655684 1407#if defined(_WIN32)
4fe56619 1408 if (theWClass.IsNull())
1409 {
7c65581d 1410 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1411 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1412 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1413 }
1414#endif
1415 return theWClass;
1416}
1417
18d715bd 1418//==============================================================================
1419//function : CreateName
1420//purpose : Create numerical name for new object in theMap
1421//==============================================================================
1422template <typename ObjectType>
1423TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1424 const TCollection_AsciiString& theDefaultString)
1425{
1426 if (theObjectMap.IsEmpty())
1427 return theDefaultString + TCollection_AsciiString(1);
1428
1429 Standard_Integer aNextKey = 1;
1430 Standard_Boolean isFound = Standard_False;
1431 while (!isFound)
1432 {
1433 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1434 // Look for objects with default names
1435 if (theObjectMap.IsBound1(aStringKey))
1436 {
1437 aNextKey++;
1438 }
1439 else
1440 isFound = Standard_True;
1441 }
1442
1443 return theDefaultString + TCollection_AsciiString(aNextKey);
1444}
1445
1446//==============================================================================
1447//structure : ViewerTest_Names
1448//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1449//==============================================================================
1450struct ViewerTest_Names
1451{
1452private:
1453 TCollection_AsciiString myDriverName;
1454 TCollection_AsciiString myViewerName;
1455 TCollection_AsciiString myViewName;
1456
1457public:
1458
1459 const TCollection_AsciiString& GetDriverName () const
1460 {
1461 return myDriverName;
1462 }
1463 void SetDriverName (const TCollection_AsciiString& theDriverName)
1464 {
1465 myDriverName = theDriverName;
1466 }
1467 const TCollection_AsciiString& GetViewerName () const
1468 {
1469 return myViewerName;
1470 }
1471 void SetViewerName (const TCollection_AsciiString& theViewerName)
1472 {
1473 myViewerName = theViewerName;
1474 }
1475 const TCollection_AsciiString& GetViewName () const
1476 {
1477 return myViewName;
1478 }
1479 void SetViewName (const TCollection_AsciiString& theViewName)
1480 {
1481 myViewName = theViewName;
1482 }
1483
1484 //===========================================================================
1485 //function : Constructor for ViewerTest_Names
1486 //purpose : Get view, viewer, driver names from custom string
1487 //===========================================================================
1488
1489 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1490 {
1491 TCollection_AsciiString aName(theInputString);
1492 if (theInputString.IsEmpty())
1493 {
1494 // Get current configuration
1495 if (ViewerTest_myDrivers.IsEmpty())
1496 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1497 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1498 else
1499 myDriverName = ViewerTest_myDrivers.Find2
1500 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1501
1502 if(ViewerTest_myContexts.IsEmpty())
1503 {
1504 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1505 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1506 }
1507 else
c48e2889 1508 {
18d715bd 1509 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1510 }
18d715bd 1511
c48e2889 1512 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1513 }
1514 else
1515 {
1516 // There is at least view name
1517 Standard_Integer aParserNumber = 0;
1518 for (Standard_Integer i = 0; i < 3; ++i)
1519 {
1520 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1521 if(aParserPos != -1)
1522 {
1523 aParserNumber++;
1524 aName.Split(aParserPos-1);
1525 }
1526 else
1527 break;
1528 }
1529 if (aParserNumber == 0)
1530 {
1531 // Only view name
1532 if (!ViewerTest::GetAISContext().IsNull())
1533 {
1534 myDriverName = ViewerTest_myDrivers.Find2
1535 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1536 myViewerName = ViewerTest_myContexts.Find2
1537 (ViewerTest::GetAISContext());
1538 }
1539 else
1540 {
1541 // There is no opened contexts here, need to create names for viewer and driver
1542 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1543 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1544
1545 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1546 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1547 }
1548 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1549 }
1550 else if (aParserNumber == 1)
1551 {
1552 // Here is viewerName/viewName
1553 if (!ViewerTest::GetAISContext().IsNull())
1554 myDriverName = ViewerTest_myDrivers.Find2
1555 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1556 else
1557 {
1558 // There is no opened contexts here, need to create name for driver
1559 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1560 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1561 }
1562 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1563
1564 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1565 }
1566 else
1567 {
1568 //Here is driverName/viewerName/viewName
1569 myDriverName = TCollection_AsciiString(aName);
1570
1571 TCollection_AsciiString aViewerName(theInputString);
1572 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1573 myViewerName = TCollection_AsciiString(aViewerName);
1574
1575 myViewName = TCollection_AsciiString(theInputString);
1576 }
1577 }
1578 }
1579};
1580
1581//==============================================================================
1582//function : FindContextByView
1583//purpose : Find AIS_InteractiveContext by View
1584//==============================================================================
1585
1586Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1587{
1588 Handle(AIS_InteractiveContext) anAISContext;
1589
1590 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1591 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1592 {
1593 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1594 return anIter.Key2();
1595 }
1596 return anAISContext;
1597}
1598
18d715bd 1599//==============================================================================
1600//function : IsWindowOverlapped
1601//purpose : Check if theWindow overlapp another view
1602//==============================================================================
1603
1604Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1605 const Standard_Integer thePxTop,
1606 const Standard_Integer thePxRight,
1607 const Standard_Integer thePxBottom,
1608 TCollection_AsciiString& theViewId)
1609{
1610 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1611 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1612 {
1613 Standard_Integer aTop = 0,
1614 aLeft = 0,
1615 aRight = 0,
1616 aBottom = 0;
1617 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1618 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1619 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1620 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1621 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1622 {
1623 theViewId = anIter.Key1();
1624 return Standard_True;
1625 }
1626 }
1627 return Standard_False;
1628}
1629
1630// Workaround: to create and delete non-orthographic views outside ViewerTest
1631void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1632{
1633 ViewerTest_myViews.UnBind1 (theName);
1634}
1635
1636void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1637 const Handle(V3d_View)& theView)
1638{
1639 ViewerTest_myViews.Bind (theName, theView);
1640}
1641
1642TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1643{
1644 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1645}
8693dfd0 1646
7fd59977 1647//==============================================================================
1648//function : ViewerInit
1649//purpose : Create the window viewer and initialize all the global variable
1650//==============================================================================
1651
18d715bd 1652TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1653 const Standard_Integer thePxTop,
1654 const Standard_Integer thePxWidth,
1655 const Standard_Integer thePxHeight,
9e04ccdc 1656 const TCollection_AsciiString& theViewName,
1657 const TCollection_AsciiString& theDisplayName,
1658 const Handle(V3d_View)& theViewToClone)
7fd59977 1659{
8c3c9904 1660 // Default position and dimension of the viewer window.
4fe56619 1661 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1662 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1663 // The position corresponds to the window's client area, thus some
8c3c9904 1664 // gap is added for window frame to be visible.
1665 Standard_Integer aPxLeft = 20;
1666 Standard_Integer aPxTop = 40;
7fd59977 1667 Standard_Integer aPxWidth = 409;
1668 Standard_Integer aPxHeight = 409;
18d715bd 1669 Standard_Boolean toCreateViewer = Standard_False;
9e04ccdc 1670 if (!theViewToClone.IsNull())
1671 {
1672 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1673 }
18d715bd 1674
58655684 1675 Handle(OpenGl_GraphicDriver) aGraphicDriver;
18d715bd 1676 ViewerTest_Names aViewNames(theViewName);
1677 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
1678 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1679
1680 if (thePxLeft != 0)
1681 aPxLeft = thePxLeft;
1682 if (thePxTop != 0)
1683 aPxTop = thePxTop;
1684 if (thePxWidth != 0)
1685 aPxWidth = thePxWidth;
1686 if (thePxHeight != 0)
7fd59977 1687 aPxHeight = thePxHeight;
4269bd1b 1688
18d715bd 1689 // Get graphic driver (create it or get from another view)
8693dfd0 1690 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1691 if (isNewDriver)
18d715bd 1692 {
1693 // Get connection string
58655684 1694 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 1695 if (!theDisplayName.IsEmpty())
1696 {
1697 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1698 }
18d715bd 1699 else
8693dfd0 1700 {
1701 ::Display* aDispX = NULL;
1702 // create dedicated display connection instead of reusing Tk connection
1703 // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
1704 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1705 Tcl_Interp* aTclInterp = aCommands.Interp();
1706 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1707 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1708 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1709 }
18d715bd 1710 #else
498ce76b 1711 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1712 SetDisplayConnection (new Aspect_DisplayConnection ());
1713 #endif
14cb22a1 1714
1715 if (Draw_VirtualWindows)
1716 {
1717 // don't waste the time waiting for VSync when window is not displayed on the screen
1718 ViewerTest_myDefaultCaps.swapInterval = 0;
1719 // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
1720 //ViewerTest_myDefaultCaps.buffersNoSwap = true;
1721 }
59515ca6 1722 aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection(), false);
58655684 1723 aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
59515ca6 1724 aGraphicDriver->InitContext();
14cb22a1 1725
18d715bd 1726 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1727 toCreateViewer = Standard_True;
1728 }
1729 else
1730 {
58655684 1731 aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
7fd59977 1732 }
1733
18d715bd 1734 //Dispose the window if input parameters are default
1735 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1736 {
18d715bd 1737 Standard_Integer aTop = 0,
1738 aLeft = 0,
1739 aRight = 0,
1740 aBottom = 0,
1741 aScreenWidth = 0,
1742 aScreenHeight = 0;
1743
1744 // Get screen resolution
1745#if defined(_WIN32) || defined(__WIN32__)
1746 RECT aWindowSize;
1747 GetClientRect(GetDesktopWindow(), &aWindowSize);
1748 aScreenHeight = aWindowSize.bottom;
1749 aScreenWidth = aWindowSize.right;
1750#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1751 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1752#else
1753 Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
1754 aScreenWidth = WidthOfScreen(aScreen);
1755 aScreenHeight = HeightOfScreen(aScreen);
1756#endif
1757
1758 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1759
1760 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1761 {
18d715bd 1762 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1763
1764 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1765 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1766 {
1767 if (aBottom + aPxHeight + 40 > aScreenHeight)
1768 {
1769 aPxLeft = 20;
1770 aPxTop = 40;
1771 break;
1772 }
1773 aPxLeft = 20;
1774 aPxTop = aBottom + 40;
1775 }
1776 else
1777 aPxLeft = aRight + 20;
dc3fe572 1778 }
18d715bd 1779 }
1780
1781 // Get viewer name
1782 TCollection_AsciiString aTitle("3D View - ");
1783 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1784
1785 // Change name of current active window
49582f9d 1786 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
18d715bd 1787 {
49582f9d 1788 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
18d715bd 1789 }
1790
1791 // Create viewer
eb4320f2 1792 Handle(V3d_Viewer) a3DViewer;
18d715bd 1793 // If it's the single view, we first look for empty context
1794 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1795 {
1796 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1797 anIter(ViewerTest_myContexts);
1798 if (anIter.More())
1799 ViewerTest::SetAISContext (anIter.Value());
1800 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1801 }
1802 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1803 {
1804 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1805 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1806 }
eb4320f2 1807 else if (a3DViewer.IsNull())
18d715bd 1808 {
1809 toCreateViewer = Standard_True;
6a24c6de 1810 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1811 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1812 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1813 ViewerTest_DefaultBackground.GradientColor2,
1814 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1815 }
1816
1817 // AIS context setup
1818 if (ViewerTest::GetAISContext().IsNull() ||
1819 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1820 {
e79a94b9 1821 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1822 ViewerTest::SetAISContext (aContext);
1823 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1824 }
1825 else
e79a94b9 1826 {
18d715bd 1827 ViewerTest::ResetEventManager();
e79a94b9 1828 }
18d715bd 1829
1830 // Create window
e79a94b9 1831#if defined(_WIN32)
1bd04b5a 1832 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
62e1beed 1833 Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1834 aPxLeft, aPxTop,
1835 aPxWidth, aPxHeight,
1836 Quantity_NOC_BLACK);
d6fbb2ab 1837 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
4fe56619 1838#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e79a94b9 1839 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1840 aPxLeft, aPxTop,
1841 aPxWidth, aPxHeight);
1842 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
7fd59977 1843#else
e79a94b9 1844 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1845 aTitle.ToCString(),
1846 aPxLeft, aPxTop,
1847 aPxWidth, aPxHeight);
7fd59977 1848#endif
18d715bd 1849 VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
7fd59977 1850
d09dda09 1851 // View setup
9e04ccdc 1852 Handle(V3d_View) aView;
1853 if (!theViewToClone.IsNull())
1854 {
2e93433e 1855 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1856 }
1857 else
1858 {
2e93433e 1859 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1860 }
1861
d09dda09 1862 aView->SetWindow (VT_GetWindow());
c3282ec1 1863 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1864
18d715bd 1865 ViewerTest::CurrentView(aView);
1866 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1867
18d715bd 1868 // Setup for X11 or NT
1869 OSWindowSetup();
7fd59977 1870
18d715bd 1871 // Set parameters for V3d_View and V3d_Viewer
1872 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1873 aV3dView->SetComputedMode(Standard_False);
7fd59977 1874
18d715bd 1875 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1876 if (toCreateViewer)
1877 {
7fd59977 1878 a3DViewer->SetDefaultLights();
1879 a3DViewer->SetLightOn();
18d715bd 1880 }
7fd59977 1881
8693dfd0 1882#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1883 if (isNewDriver)
1884 {
1885 ::Display* aDispX = GetDisplayConnection()->GetDisplay();
1886 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1887 }
1888#endif
7fd59977 1889
7fd59977 1890 VT_GetWindow()->Map();
4269bd1b 1891
18d715bd 1892 // Set the handle of created view in the event manager
1893 ViewerTest::ResetEventManager();
1894
4fe56619 1895 ViewerTest::CurrentView()->Redraw();
18d715bd 1896
1897 aView.Nullify();
1898 a3DViewer.Nullify();
18d715bd 1899
1900 return aViewNames.GetViewName();
1901}
1902
4269bd1b 1903//==============================================================================
1904//function : RedrawAllViews
1905//purpose : Redraw all created views
1906//==============================================================================
1907void ViewerTest::RedrawAllViews()
1908{
1909 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1910 for (; aViewIt.More(); aViewIt.Next())
1911 {
1912 const Handle(V3d_View)& aView = aViewIt.Key2();
1913 aView->Redraw();
1914 }
1915}
1916
7fd59977 1917//==============================================================================
1918//function : Vinit
1919//purpose : Create the window viewer and initialize all the global variable
e79a94b9 1920// Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 1921//==============================================================================
1922
18d715bd 1923static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 1924{
e79a94b9 1925 TCollection_AsciiString aViewName, aDisplayName;
1926 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
9e04ccdc 1927 Handle(V3d_View) aCopyFrom;
e79a94b9 1928 TCollection_AsciiString aName, aValue;
2e93433e 1929 int is2dMode = -1;
e79a94b9 1930 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 1931 {
e79a94b9 1932 const TCollection_AsciiString anArg = theArgVec[anArgIt];
1933 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 1934 anArgCase.LowerCase();
1935 if (anArgIt + 1 < theArgsNb
1936 && anArgCase == "-name")
1937 {
1938 aViewName = theArgVec[++anArgIt];
1939 }
1940 else if (anArgIt + 1 < theArgsNb
1941 && (anArgCase == "-left"
1942 || anArgCase == "-l"))
1943 {
1944 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
1945 }
1946 else if (anArgIt + 1 < theArgsNb
1947 && (anArgCase == "-top"
1948 || anArgCase == "-t"))
1949 {
1950 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
1951 }
1952 else if (anArgIt + 1 < theArgsNb
1953 && (anArgCase == "-width"
1954 || anArgCase == "-w"))
1955 {
1956 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
1957 }
1958 else if (anArgIt + 1 < theArgsNb
1959 && (anArgCase == "-height"
1960 || anArgCase == "-h"))
18d715bd 1961 {
fd3f6bd0 1962 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
1963 }
1964 else if (anArgCase == "-exitonclose")
1965 {
49582f9d 1966 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 1967 if (anArgIt + 1 < theArgsNb
dae2a922 1968 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 1969 {
1970 ++anArgIt;
1971 }
1972 }
1973 else if (anArgCase == "-closeonescape"
1974 || anArgCase == "-closeonesc")
1975 {
49582f9d 1976 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 1977 if (anArgIt + 1 < theArgsNb
dae2a922 1978 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 1979 {
1980 ++anArgIt;
1981 }
1982 }
2e93433e 1983 else if (anArgCase == "-2d_mode"
1984 || anArgCase == "-2dmode"
1985 || anArgCase == "-2d")
1986 {
1987 bool toEnable = true;
1988 if (anArgIt + 1 < theArgsNb
dae2a922 1989 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2e93433e 1990 {
1991 ++anArgIt;
1992 }
1993 is2dMode = toEnable ? 1 : 0;
1994 }
fd3f6bd0 1995 else if (anArgIt + 1 < theArgsNb
1996 && (anArgCase == "-disp"
1997 || anArgCase == "-display"))
1998 {
1999 aDisplayName = theArgVec[++anArgIt];
2000 }
9e04ccdc 2001 else if (!ViewerTest::CurrentView().IsNull()
2002 && aCopyFrom.IsNull()
2003 && (anArgCase == "-copy"
2004 || anArgCase == "-clone"
2005 || anArgCase == "-cloneactive"
2006 || anArgCase == "-cloneactiveview"))
2007 {
2008 aCopyFrom = ViewerTest::CurrentView();
2009 }
fd3f6bd0 2010 // old syntax
2011 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2012 {
2013 aName.LowerCase();
2014 if (aName == "name")
18d715bd 2015 {
2016 aViewName = aValue;
2017 }
fd3f6bd0 2018 else if (aName == "l"
2019 || aName == "left")
e79a94b9 2020 {
18d715bd 2021 aPxLeft = aValue.IntegerValue();
e79a94b9 2022 }
fd3f6bd0 2023 else if (aName == "t"
2024 || aName == "top")
e79a94b9 2025 {
18d715bd 2026 aPxTop = aValue.IntegerValue();
e79a94b9 2027 }
fd3f6bd0 2028 else if (aName == "disp"
2029 || aName == "display")
e79a94b9 2030 {
18d715bd 2031 aDisplayName = aValue;
e79a94b9 2032 }
fd3f6bd0 2033 else if (aName == "w"
2034 || aName == "width")
e79a94b9 2035 {
18d715bd 2036 aPxWidth = aValue.IntegerValue();
e79a94b9 2037 }
fd3f6bd0 2038 else if (aName == "h"
2039 || aName == "height")
e79a94b9 2040 {
18d715bd 2041 aPxHeight = aValue.IntegerValue();
e79a94b9 2042 }
18d715bd 2043 else
2044 {
23fe70ec 2045 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2046 return 1;
18d715bd 2047 }
2048 }
e79a94b9 2049 else if (aViewName.IsEmpty())
2050 {
2051 aViewName = anArg;
2052 }
2053 else
2054 {
23fe70ec 2055 Message::SendFail() << "Syntax error: unknown argument " << anArg;
fd3f6bd0 2056 return 1;
e79a94b9 2057 }
18d715bd 2058 }
2059
fd3f6bd0 2060#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2061 if (!aDisplayName.IsEmpty())
2062 {
2063 aDisplayName.Clear();
23fe70ec 2064 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
fd3f6bd0 2065 }
2066#endif
2067
18d715bd 2068 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2069 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2070 {
e79a94b9 2071 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2072 theDi.Eval (aCommand.ToCString());
2e93433e 2073 if (is2dMode != -1)
2074 {
2075 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2076 }
18d715bd 2077 return 0;
2078 }
2079
2080 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
9e04ccdc 2081 aViewName, aDisplayName, aCopyFrom);
2e93433e 2082 if (is2dMode != -1)
2083 {
2084 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2085 }
e79a94b9 2086 theDi << aViewId;
7fd59977 2087 return 0;
2088}
2089
1eeef710 2090//! Parse HLR algo type.
2091static Standard_Boolean parseHlrAlgoType (const char* theName,
2092 Prs3d_TypeOfHLR& theType)
2093{
2094 TCollection_AsciiString aName (theName);
2095 aName.LowerCase();
2096 if (aName == "polyalgo")
2097 {
2098 theType = Prs3d_TOH_PolyAlgo;
2099 }
2100 else if (aName == "algo")
2101 {
2102 theType = Prs3d_TOH_Algo;
2103 }
2104 else
2105 {
2106 return Standard_False;
2107 }
2108 return Standard_True;
2109}
2110
0a768f56 2111//==============================================================================
2112//function : VHLR
2113//purpose : hidden lines removal algorithm
2114//==============================================================================
2115
2116static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2117{
1eeef710 2118 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2119 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2120 if (aView.IsNull())
0a768f56 2121 {
23fe70ec 2122 Message::SendFail ("Error: no active viewer");
0a768f56 2123 return 1;
2124 }
2125
1eeef710 2126 Standard_Boolean hasHlrOnArg = Standard_False;
2127 Standard_Boolean hasShowHiddenArg = Standard_False;
2128 Standard_Boolean isHLROn = Standard_False;
2129 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2130 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2131 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2132 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2133 {
1eeef710 2134 TCollection_AsciiString anArg (argv[anArgIter]);
2135 anArg.LowerCase();
2136 if (anUpdateTool.parseRedrawMode (anArg))
2137 {
2138 continue;
2139 }
2140 else if (anArg == "-showhidden"
2141 && anArgIter + 1 < argc
dae2a922 2142 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1eeef710 2143 {
2144 ++anArgIter;
2145 hasShowHiddenArg = Standard_True;
2146 continue;
2147 }
2148 else if ((anArg == "-type"
2149 || anArg == "-algo"
2150 || anArg == "-algotype")
2151 && anArgIter + 1 < argc
2152 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2153 {
2154 ++anArgIter;
2155 continue;
2156 }
2157 else if (!hasHlrOnArg
dae2a922 2158 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1eeef710 2159 {
2160 hasHlrOnArg = Standard_True;
2161 continue;
2162 }
2163 // old syntax
2164 else if (!hasShowHiddenArg
dae2a922 2165 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1eeef710 2166 {
2167 hasShowHiddenArg = Standard_True;
2168 continue;
2169 }
2170 else
2171 {
23fe70ec 2172 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1eeef710 2173 return 1;
2174 }
0a768f56 2175 }
1eeef710 2176 if (!hasHlrOnArg)
0a768f56 2177 {
1eeef710 2178 di << "HLR: " << aView->ComputedMode() << "\n";
2179 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2180 di << "HlrAlgo: ";
2181 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2182 {
2183 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2184 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2185 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2186 }
2187 anUpdateTool.Invalidate();
2188 return 0;
0a768f56 2189 }
2190
1eeef710 2191 Standard_Boolean toRecompute = Standard_False;
2192 if (aTypeOfHLR != Prs3d_TOH_NotSet
2193 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2194 {
1eeef710 2195 toRecompute = Standard_True;
2196 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2197 }
2198 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2199 {
2200 toRecompute = Standard_True;
2201 if (toShowHidden)
e9224045 2202 {
1eeef710 2203 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2204 }
2205 else
2206 {
1eeef710 2207 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2208 }
1eeef710 2209 }
e9224045 2210
1eeef710 2211 // redisplay shapes
2212 if (aView->ComputedMode() && isHLROn && toRecompute)
2213 {
2214 AIS_ListOfInteractive aListOfShapes;
2215 aCtx->DisplayedObjects (aListOfShapes);
2216 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2217 {
1eeef710 2218 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2219 {
1eeef710 2220 aCtx->Redisplay (aShape, Standard_False);
e9224045 2221 }
2222 }
2223 }
0a768f56 2224
1eeef710 2225 aView->SetComputedMode (isHLROn);
0a768f56 2226 return 0;
2227}
2228
2229//==============================================================================
2230//function : VHLRType
2231//purpose : change type of using HLR algorithm
2232//==============================================================================
2233
1eeef710 2234static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2235{
1eeef710 2236 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2237 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2238 if (aView.IsNull())
0a768f56 2239 {
23fe70ec 2240 Message::SendFail ("Error: no active viewer");
0a768f56 2241 return 1;
2242 }
2243
1eeef710 2244 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2245 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2246 AIS_ListOfInteractive aListOfShapes;
2247 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2248 {
1eeef710 2249 TCollection_AsciiString anArg (argv[anArgIter]);
2250 anArg.LowerCase();
2251 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2252 {
1eeef710 2253 continue;
0a768f56 2254 }
1eeef710 2255 else if ((anArg == "-type"
2256 || anArg == "-algo"
2257 || anArg == "-algotype")
2258 && anArgIter + 1 < argc
2259 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2260 {
2261 ++anArgIter;
2262 continue;
2263 }
2264 // old syntax
2265 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2266 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2267 {
2268 continue;
2269 }
2270 else
0a768f56 2271 {
2272 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2273 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2274 if (!aMap.IsBound2 (aName))
2275 {
23fe70ec 2276 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1eeef710 2277 return 1;
0a768f56 2278 }
1eeef710 2279
2280 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2281 if (aShape.IsNull())
2282 {
23fe70ec 2283 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1eeef710 2284 return 1;
2285 }
2286 aListOfShapes.Append (aShape);
2287 continue;
0a768f56 2288 }
1eeef710 2289 }
2290 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2291 {
23fe70ec 2292 Message::SendFail ("Syntax error: wrong number of arguments");
1eeef710 2293 return 1;
2294 }
2295
2296 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2297 if (isGlobal)
2298 {
2299 aCtx->DisplayedObjects (aListOfShapes);
2300 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2301 }
2302
1eeef710 2303 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2304 {
2305 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2306 if (aShape.IsNull())
2307 {
2308 continue;
2309 }
2310
2311 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2312 && aView->ComputedMode();
2313 if (!isGlobal
2314 || aShape->TypeOfHLR() != aTypeOfHLR)
2315 {
2316 aShape->SetTypeOfHLR (aTypeOfHLR);
2317 }
2318 if (toUpdateShape)
2319 {
2320 aCtx->Redisplay (aShape, Standard_False);
2321 }
2322 }
0a768f56 2323 return 0;
2324}
2325
18d715bd 2326//==============================================================================
2327//function : FindViewIdByWindowHandle
2328//purpose : Find theView Id in the map of views by window handle
2329//==============================================================================
49582f9d 2330#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2331TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
18d715bd 2332{
2333 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2334 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2335 {
49582f9d 2336 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
18d715bd 2337 if (aWindowHandle == theWindowHandle)
2338 return anIter.Key1();
2339 }
2340 return TCollection_AsciiString("");
2341}
2342#endif
2343
e084dbbc 2344//! Make the view active
2345void ActivateView (const TCollection_AsciiString& theViewName,
2346 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2347{
2348 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2349 if (aView.IsNull())
18d715bd 2350 {
e084dbbc 2351 return;
2352 }
18d715bd 2353
e084dbbc 2354 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2355 if (!anAISContext.IsNull())
2356 {
49582f9d 2357 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
e084dbbc 2358 {
49582f9d 2359 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
e084dbbc 2360 }
2361
2362 ViewerTest::CurrentView (aView);
2363 ViewerTest::SetAISContext (anAISContext);
49582f9d 2364 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
1eeef710 2365#if defined(_WIN32)
e084dbbc 2366 VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2367#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e084dbbc 2368 VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2369#else
e084dbbc 2370 VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2371#endif
e084dbbc 2372 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2373 if (theToUpdate)
2374 {
18d715bd 2375 ViewerTest::CurrentView()->Redraw();
2376 }
2377 }
2378}
2379
0e93d9e5 2380//==============================================================================
2381//function : RemoveView
2382//purpose :
2383//==============================================================================
2384void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2385 const Standard_Boolean theToRemoveContext)
2386{
2387 if (!ViewerTest_myViews.IsBound2 (theView))
2388 {
2389 return;
2390 }
2391
2392 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2393 RemoveView (aViewName, theToRemoveContext);
2394}
2395
18d715bd 2396//==============================================================================
2397//function : RemoveView
2398//purpose : Close and remove view from display, clear maps if neccessary
2399//==============================================================================
2400void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2401{
2402 if (!ViewerTest_myViews.IsBound1(theViewName))
2403 {
23fe70ec 2404 Message::SendFail() << "Wrong view name";
18d715bd 2405 return;
2406 }
2407
2408 // Activate another view if it's active now
2409 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2410 {
2411 if (ViewerTest_myViews.Extent() > 1)
2412 {
2413 TCollection_AsciiString aNewViewName;
c48e2889 2414 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2415 anIter.More(); anIter.Next())
2416 {
18d715bd 2417 if (anIter.Key1() != theViewName)
2418 {
2419 aNewViewName = anIter.Key1();
2420 break;
2421 }
c48e2889 2422 }
2423 ActivateView (aNewViewName);
18d715bd 2424 }
2425 else
2426 {
e084dbbc 2427 VT_GetWindow().Nullify();
2428 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2429 if (isContextRemoved)
2430 {
2431 Handle(AIS_InteractiveContext) anEmptyContext;
2432 ViewerTest::SetAISContext(anEmptyContext);
2433 }
2434 }
2435 }
2436
2437 // Delete view
2438 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2439 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2440 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2441 aRedrawer.Stop (aView->Window());
18d715bd 2442
2443 // Remove view resources
18d715bd 2444 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2445 aView->Window()->Unmap();
18d715bd 2446 aView->Remove();
2447
2448#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2449 XFlush (GetDisplayConnection()->GetDisplay());
2450#endif
2451
2452 // Keep context opened only if the closed view is last to avoid
2453 // unused empty contexts
2454 if (!aCurrentContext.IsNull())
2455 {
2456 // Check if there are more difined views in the viewer
f7fc0c03 2457 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
2458 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
18d715bd 2459 {
2460 // Remove driver if there is no viewers that use it
2461 Standard_Boolean isRemoveDriver = Standard_True;
2462 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2463 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2464 {
2465 if (aCurrentContext != anIter.Key2() &&
2466 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2467 {
2468 isRemoveDriver = Standard_False;
2469 break;
2470 }
2471 }
2ec85268 2472
2473 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2474 if(isRemoveDriver)
2475 {
2476 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2477 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 2478 Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
18d715bd 2479 #endif
2480 }
2481
2482 ViewerTest_myContexts.UnBind2(aCurrentContext);
2483 }
2484 }
23fe70ec 2485 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
49582f9d 2486 if (ViewerTest_EventManager::ToExitOnCloseView())
fd3f6bd0 2487 {
2488 Draw_Interprete ("exit");
2489 }
18d715bd 2490}
2491
2492//==============================================================================
2493//function : VClose
2494//purpose : Remove the view defined by its name
2495//==============================================================================
2496
d0cc1cb7 2497static int VClose (Draw_Interpretor& /*theDi*/,
2498 Standard_Integer theArgsNb,
2499 const char** theArgVec)
18d715bd 2500{
18d715bd 2501 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2502 if (theArgsNb > 1)
18d715bd 2503 {
d0cc1cb7 2504 TCollection_AsciiString anArg (theArgVec[1]);
2505 anArg.UpperCase();
2506 if (anArg.IsEqual ("ALL")
2507 || anArg.IsEqual ("*"))
2508 {
2509 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2510 anIter.More(); anIter.Next())
2511 {
2512 aViewList.Append (anIter.Key1());
2513 }
2514 if (aViewList.IsEmpty())
2515 {
2516 std::cout << "No view to close\n";
2517 return 0;
2518 }
2519 }
2520 else
18d715bd 2521 {
d0cc1cb7 2522 ViewerTest_Names aViewName (theArgVec[1]);
2523 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2524 {
23fe70ec 2525 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
d0cc1cb7 2526 return 1;
2527 }
2528 aViewList.Append (aViewName.GetViewName());
18d715bd 2529 }
2530 }
2531 else
2532 {
d0cc1cb7 2533 // close active view
2534 if (ViewerTest::CurrentView().IsNull())
2535 {
23fe70ec 2536 Message::SendFail ("Error: no active view");
d0cc1cb7 2537 return 1;
2538 }
2539 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2540 }
2541
d0cc1cb7 2542 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2543 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2544 anIter.More(); anIter.Next())
2545 {
d0cc1cb7 2546 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2547 }
2548
2549 return 0;
2550}
2551
2552//==============================================================================
2553//function : VActivate
2554//purpose : Activate the view defined by its ID
2555//==============================================================================
2556
2557static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2558{
e084dbbc 2559 if (theArgsNb == 1)
18d715bd 2560 {
2561 theDi.Eval("vviewlist");
2562 return 0;
2563 }
2564
e084dbbc 2565 TCollection_AsciiString aNameString;
2566 Standard_Boolean toUpdate = Standard_True;
2567 Standard_Boolean toActivate = Standard_True;
2568 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2569 {
e084dbbc 2570 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2571 anArg.LowerCase();
2572 if (toUpdate
2573 && anArg == "-noupdate")
2574 {
2575 toUpdate = Standard_False;
2576 }
2577 else if (toActivate
2578 && aNameString.IsEmpty()
2579 && anArg == "none")
2580 {
49582f9d 2581 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
e084dbbc 2582 VT_GetWindow().Nullify();
2583 ViewerTest::CurrentView (Handle(V3d_View)());
2584 ViewerTest::ResetEventManager();
2585 theDi << theArgVec[0] << ": all views are inactive\n";
2586 toActivate = Standard_False;
2587 }
2588 else if (toActivate
2589 && aNameString.IsEmpty())
2590 {
2591 aNameString = theArgVec[anArgIter];
2592 }
2593 else
2594 {
23fe70ec 2595 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
e084dbbc 2596 return 1;
2597 }
18d715bd 2598 }
2599
e084dbbc 2600 if (!toActivate)
2601 {
2602 return 0;
2603 }
2604 else if (aNameString.IsEmpty())
2605 {
23fe70ec 2606 Message::SendFail ("Syntax error: wrong number of arguments");
e084dbbc 2607 return 1;
2608 }
18d715bd 2609
2610 // Check if this view exists in the viewer with the driver
e084dbbc 2611 ViewerTest_Names aViewNames (aNameString);
18d715bd 2612 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2613 {
e084dbbc 2614 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2615 return 1;
2616 }
2617
2618 // Check if it is active already
2619 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2620 {
2621 theDi << theArgVec[0] << ": the view is active already\n";
2622 return 0;
2623 }
2624
e084dbbc 2625 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2626 return 0;
2627}
2628
2629//==============================================================================
2630//function : VViewList
2631//purpose : Print current list of views per viewer and graphic driver ID
2632// shared between viewers
2633//==============================================================================
2634
2635static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2636{
2637 if (theArgsNb > 2)
2638 {
2639 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2640 << "Usage: " << theArgVec[0] << " name";
18d715bd 2641 return 1;
2642 }
2643 if (ViewerTest_myContexts.Size() < 1)
2644 return 0;
2645
18d715bd 2646 Standard_Boolean isTreeView =
29cb310a 2647 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2648
2649 if (isTreeView)
c48e2889 2650 {
18d715bd 2651 theDi << theArgVec[0] <<":\n";
c48e2889 2652 }
18d715bd 2653
c48e2889 2654 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2655 aDriverIter.More(); aDriverIter.Next())
2656 {
2657 if (isTreeView)
2658 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2659
c48e2889 2660 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2661 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2662 {
2663 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2664 {
c48e2889 2665 if (isTreeView)
18d715bd 2666 {
c48e2889 2667 TCollection_AsciiString aContextName(aContextIter.Key1());
2668 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2669 }
18d715bd 2670
c48e2889 2671 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2672 aViewIter.More(); aViewIter.Next())
2673 {
2674 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2675 {
c48e2889 2676 TCollection_AsciiString aViewName(aViewIter.Key1());
2677 if (isTreeView)
18d715bd 2678 {
c48e2889 2679 if (aViewIter.Value() == ViewerTest::CurrentView())
2680 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2681 else
c48e2889 2682 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2683 }
2684 else
2685 {
2686 theDi << aViewName << " ";
18d715bd 2687 }
2688 }
2689 }
2690 }
2691 }
c48e2889 2692 }
18d715bd 2693 return 0;
2694}
2695
7fd59977 2696//==============================================================================
49582f9d 2697//function : GetMousePosition
2698//purpose :
7fd59977 2699//==============================================================================
49582f9d 2700void ViewerTest::GetMousePosition (Standard_Integer& theX,
2701 Standard_Integer& theY)
7fd59977 2702{
49582f9d 2703 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
4fe56619 2704 {
49582f9d 2705 theX = aViewCtrl->LastMousePosition().x();
2706 theY = aViewCtrl->LastMousePosition().y();
4fe56619 2707 }
7fd59977 2708}
2709
44b8f2d6 2710//==============================================================================
fc552d84 2711//function : VViewProj
2712//purpose : Switch view projection
44b8f2d6 2713//==============================================================================
fc552d84 2714static int VViewProj (Draw_Interpretor& ,
2715 Standard_Integer theNbArgs,
2716 const char** theArgVec)
44b8f2d6 2717{
fc552d84 2718 static Standard_Boolean isYup = Standard_False;
2719 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2720 if (aView.IsNull())
44b8f2d6 2721 {
23fe70ec 2722 Message::SendFail ("Error: no active viewer");
44b8f2d6 2723 return 1;
2724 }
2725
fc552d84 2726 TCollection_AsciiString aCmdName (theArgVec[0]);
2727 Standard_Boolean isGeneralCmd = Standard_False;
2728 if (aCmdName == "vfront")
2729 {
2730 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2731 }
2732 else if (aCmdName == "vback")
2733 {
2734 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2735 }
2736 else if (aCmdName == "vtop")
2737 {
2738 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2739 }
2740 else if (aCmdName == "vbottom")
2741 {
2742 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2743 }
2744 else if (aCmdName == "vleft")
2745 {
2746 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2747 }
2748 else if (aCmdName == "vright")
2749 {
2750 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2751 }
2752 else if (aCmdName == "vaxo")
2753 {
2754 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2755 }
2756 else
2757 {
2758 isGeneralCmd = Standard_True;
2759 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2760 {
2761 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
2762 anArgCase.LowerCase();
2763 if (anArgCase == "-zup")
2764 {
2765 isYup = Standard_False;
2766 }
2767 else if (anArgCase == "-yup")
2768 {
2769 isYup = Standard_True;
2770 }
2771 else if (anArgCase == "-front"
2772 || anArgCase == "front"
2773 || anArgCase == "-f"
2774 || anArgCase == "f")
2775 {
2776 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
2777 }
2778 else if (anArgCase == "-back"
2779 || anArgCase == "back"
2780 || anArgCase == "-b"
2781 || anArgCase == "b")
2782 {
2783 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
2784 }
2785 else if (anArgCase == "-top"
2786 || anArgCase == "top"
2787 || anArgCase == "-t"
2788 || anArgCase == "t")
2789 {
2790 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
2791 }
2792 else if (anArgCase == "-bottom"
2793 || anArgCase == "bottom"
2794 || anArgCase == "-bot"
2795 || anArgCase == "bot"
2796 || anArgCase == "-b"
2797 || anArgCase == "b")
2798 {
2799 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
2800 }
2801 else if (anArgCase == "-left"
2802 || anArgCase == "left"
2803 || anArgCase == "-l"
2804 || anArgCase == "l")
2805 {
2806 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
2807 }
2808 else if (anArgCase == "-right"
2809 || anArgCase == "right"
2810 || anArgCase == "-r"
2811 || anArgCase == "r")
2812 {
2813 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
2814 }
2815 else if (anArgCase == "-axoleft"
2816 || anArgCase == "-leftaxo"
2817 || anArgCase == "axoleft"
2818 || anArgCase == "leftaxo")
2819 {
2820 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
2821 }
2822 else if (anArgCase == "-axo"
2823 || anArgCase == "axo"
2824 || anArgCase == "-a"
2825 || anArgCase == "a"
2826 || anArgCase == "-axoright"
2827 || anArgCase == "-rightaxo"
2828 || anArgCase == "axoright"
2829 || anArgCase == "rightaxo")
2830 {
2831 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2832 }
2833 else if (anArgCase == "+x")
2834 {
2835 aView->SetProj (V3d_Xpos, isYup);
2836 }
2837 else if (anArgCase == "-x")
2838 {
2839 aView->SetProj (V3d_Xneg, isYup);
2840 }
2841 else if (anArgCase == "+y")
2842 {
2843 aView->SetProj (V3d_Ypos, isYup);
2844 }
2845 else if (anArgCase == "-y")
2846 {
2847 aView->SetProj (V3d_Yneg, isYup);
2848 }
2849 else if (anArgCase == "+z")
2850 {
2851 aView->SetProj (V3d_Zpos, isYup);
2852 }
2853 else if (anArgCase == "-z")
2854 {
2855 aView->SetProj (V3d_Zneg, isYup);
2856 }
2857 else if (anArgCase == "+x+y+z")
2858 {
2859 aView->SetProj (V3d_XposYposZpos, isYup);
2860 }
2861 else if (anArgCase == "+x+y-z")
2862 {
2863 aView->SetProj (V3d_XposYposZneg, isYup);
2864 }
2865 else if (anArgCase == "+x-y+z")
2866 {
2867 aView->SetProj (V3d_XposYnegZpos, isYup);
2868 }
2869 else if (anArgCase == "+x-y-z")
2870 {
2871 aView->SetProj (V3d_XposYnegZneg, isYup);
2872 }
2873 else if (anArgCase == "-x+y+z")
2874 {
2875 aView->SetProj (V3d_XnegYposZpos, isYup);
2876 }
2877 else if (anArgCase == "-x+y-z")
2878 {
2879 aView->SetProj (V3d_XnegYposZneg, isYup);
2880 }
2881 else if (anArgCase == "-x-y+z")
2882 {
2883 aView->SetProj (V3d_XnegYnegZpos, isYup);
2884 }
2885 else if (anArgCase == "-x-y-z")
2886 {
2887 aView->SetProj (V3d_XnegYnegZneg, isYup);
2888 }
2889 else if (anArgCase == "+x+y")
2890 {
2891 aView->SetProj (V3d_XposYpos, isYup);
2892 }
2893 else if (anArgCase == "+x-y")
2894 {
2895 aView->SetProj (V3d_XposYneg, isYup);
2896 }
2897 else if (anArgCase == "-x+y")
2898 {
2899 aView->SetProj (V3d_XnegYpos, isYup);
2900 }
2901 else if (anArgCase == "-x-y")
2902 {
2903 aView->SetProj (V3d_XnegYneg, isYup);
2904 }
2905 else if (anArgCase == "+x+z")
2906 {
2907 aView->SetProj (V3d_XposZpos, isYup);
2908 }
2909 else if (anArgCase == "+x-z")
2910 {
2911 aView->SetProj (V3d_XposZneg, isYup);
2912 }
2913 else if (anArgCase == "-x+z")
2914 {
2915 aView->SetProj (V3d_XnegZpos, isYup);
2916 }
2917 else if (anArgCase == "-x-z")
2918 {
2919 aView->SetProj (V3d_XnegZneg, isYup);
2920 }
2921 else if (anArgCase == "+y+z")
2922 {
2923 aView->SetProj (V3d_YposZpos, isYup);
2924 }
2925 else if (anArgCase == "+y-z")
2926 {
2927 aView->SetProj (V3d_YposZneg, isYup);
2928 }
2929 else if (anArgCase == "-y+z")
2930 {
2931 aView->SetProj (V3d_YnegZpos, isYup);
2932 }
2933 else if (anArgCase == "-y-z")
2934 {
2935 aView->SetProj (V3d_YnegZneg, isYup);
2936 }
2937 else if (anArgIter + 1 < theNbArgs
2938 && anArgCase == "-frame"
2939 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
2940 {
2941 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
2942 aFrameDef.LowerCase();
2943 gp_Dir aRight, anUp;
2944 if (aFrameDef.Value (2) == aFrameDef.Value (4))
2945 {
23fe70ec 2946 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2947 return 1;
2948 }
44b8f2d6 2949
fc552d84 2950 if (aFrameDef.Value (2) == 'x')
2951 {
2952 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
2953 }
2954 else if (aFrameDef.Value (2) == 'y')
2955 {
2956 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
2957 }
2958 else if (aFrameDef.Value (2) == 'z')
2959 {
2960 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
2961 }
2962 else
2963 {
23fe70ec 2964 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2965 return 1;
2966 }
7fd59977 2967
fc552d84 2968 if (aFrameDef.Value (4) == 'x')
2969 {
2970 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
2971 }
2972 else if (aFrameDef.Value (4) == 'y')
2973 {
2974 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
2975 }
2976 else if (aFrameDef.Value (4) == 'z')
2977 {
2978 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
2979 }
2980 else
2981 {
23fe70ec 2982 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 2983 return 1;
2984 }
44b8f2d6 2985
fc552d84 2986 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
2987 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
2988 const gp_Dir aDir = anUp.Crossed (aRight);
2989 aCamera->SetCenter (gp_Pnt (0, 0, 0));
2990 aCamera->SetDirection (aDir);
2991 aCamera->SetUp (anUp);
2992 aCamera->OrthogonalizeUp();
44b8f2d6 2993
fc552d84 2994 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
2995 aView->Update();
2996 }
2997 else
2998 {
23fe70ec 2999 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fc552d84 3000 return 1;
3001 }
3002 }
3003 }
44b8f2d6 3004
fc552d84 3005 if (!isGeneralCmd
3006 && theNbArgs != 1)
3007 {
23fe70ec 3008 Message::SendFail ("Syntax error: wrong number of arguments");
fc552d84 3009 return 1;
3010 }
3011 return 0;
7fd59977 3012}
3013
3014//==============================================================================
3015//function : VHelp
3016//purpose : Dsiplay help on viewer Keyboead and mouse commands
3017//Draw arg : No args
3018//==============================================================================
3019
3020static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3021{
586db386 3022 di << "=========================\n";
3023 di << "F : FitAll\n";
3024 di << "T : TopView\n";
3025 di << "B : BottomView\n";
3026 di << "R : RightView\n";
3027 di << "L : LeftView\n";
d22962e4 3028 di << "Backspace : AxonometricView\n";
586db386 3029
3030 di << "=========================\n";
d22962e4 3031 di << "W, S : Fly forward/backward\n";
3032 di << "A, D : Slide left/right\n";
3033 di << "Q, E : Bank left/right\n";
3034 di << "-, + : Change flying speed\n";
3035 di << "Arrows : look left/right/up/down\n";
3036 di << "Arrows+Shift : slide left/right/up/down\n";
3037
3038 di << "=========================\n";
3039 di << "S + Ctrl : Shading\n";
3040 di << "W + Ctrl : Wireframe\n";
49582f9d 3041 di << "H : HiddenLineRemoval\n";
586db386 3042 di << "U : Unset display mode\n";
3043 di << "Delete : Remove selection from viewer\n";
3044
3045 di << "=========================\n";
3046 di << "Selection mode \n";
3047 di << "0 : Shape\n";
3048 di << "1 : Vertex\n";
3049 di << "2 : Edge\n";
3050 di << "3 : Wire\n";
3051 di << "4 : Face\n";
3052 di << "5 : Shell\n";
3053 di << "6 : Solid\n";
3054 di << "7 : Compound\n";
3055
3056 di << "=========================\n";
49582f9d 3057 di << "< : Hilight next detected\n";
3058 di << "> : Hilight previous detected\n";
7fd59977 3059
3060 return 0;
3061}
3062
57c28b61 3063#ifdef _WIN32
7fd59977 3064
49582f9d 3065static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
3066 UINT theMsg,
3067 WPARAM wParam,
3068 LPARAM lParam )
7fd59977 3069{
49582f9d 3070 if (ViewerTest_myViews.IsEmpty())
3071 {
3072 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
3073 }
7fd59977 3074
49582f9d 3075 switch (theMsg)
3076 {
18d715bd 3077 case WM_CLOSE:
49582f9d 3078 {
3079 // Delete view from map of views
3080 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
3081 return 0;
3082 }
18d715bd 3083 case WM_ACTIVATE:
49582f9d 3084 {
3085 if (LOWORD(wParam) == WA_CLICKACTIVE
3086 || LOWORD(wParam) == WA_ACTIVE
3087 || ViewerTest::CurrentView().IsNull())
18d715bd 3088 {
3089 // Activate inactive window
49582f9d 3090 if (VT_GetWindow().IsNull()
3091 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
625e1958 3092 {
49582f9d 3093 ActivateView (FindViewIdByWindowHandle (theWinHandle));
625e1958 3094 }
7fd59977 3095 }
7fd59977 3096 break;
49582f9d 3097 }
7fd59977 3098 default:
49582f9d 3099 {
3100 return ViewerWindowProc (theWinHandle, theMsg, wParam, lParam);
7fd59977 3101 }
7fd59977 3102 }
49582f9d 3103 return 0;
7fd59977 3104}
3105
49582f9d 3106static LRESULT WINAPI ViewerWindowProc (HWND theWinHandle,
3107 UINT theMsg,
3108 WPARAM wParam,
3109 LPARAM lParam)
7fd59977 3110{
f978241f 3111 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3112 if (aView.IsNull())
3113 {
49582f9d 3114 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
f978241f 3115 }
7fd59977 3116
49582f9d 3117 switch (theMsg)
3118 {
7fd59977 3119 case WM_PAINT:
49582f9d 3120 {
3121 PAINTSTRUCT aPaint;
3122 BeginPaint(theWinHandle, &aPaint);
3123 EndPaint (theWinHandle, &aPaint);
3124 ViewerTest::CurrentEventManager()->ProcessExpose();
7fd59977 3125 break;
49582f9d 3126 }
7fd59977 3127 case WM_SIZE:
49582f9d 3128 {
3129 ViewerTest::CurrentEventManager()->ProcessConfigure();
7fd59977 3130 break;
49582f9d 3131 }
f978241f 3132 case WM_MOVE:
3133 case WM_MOVING:
3134 case WM_SIZING:
49582f9d 3135 {
f978241f 3136 switch (aView->RenderingParams().StereoMode)
3137 {
3138 case Graphic3d_StereoMode_RowInterlaced:
3139 case Graphic3d_StereoMode_ColumnInterlaced:
3140 case Graphic3d_StereoMode_ChessBoard:
49582f9d 3141 {
3142 // track window moves to reverse stereo pair
3143 aView->MustBeResized();
3144 aView->Update();
f978241f 3145 break;
49582f9d 3146 }
f978241f 3147 default:
3148 break;
3149 }
3150 break;
49582f9d 3151 }
3152 case WM_KEYUP:
7fd59977 3153 case WM_KEYDOWN:
49582f9d 3154 {
3155 const Aspect_VKey aVKey = WNT_Window::VirtualKeyFromNative ((Standard_Integer )wParam);
3156 if (aVKey != Aspect_VKey_UNKNOWN)
4fe56619 3157 {
49582f9d 3158 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3159 if (theMsg == WM_KEYDOWN)
f978241f 3160 {
49582f9d 3161 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
f978241f 3162 }
49582f9d 3163 else
f978241f 3164 {
49582f9d 3165 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
f978241f 3166 }
49582f9d 3167 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
7fd59977 3168 }
3169 break;
49582f9d 3170 }
7fd59977 3171 case WM_LBUTTONUP:
3172 case WM_MBUTTONUP:
3173 case WM_RBUTTONUP:
7fd59977 3174 case WM_LBUTTONDOWN:
3175 case WM_MBUTTONDOWN:
3176 case WM_RBUTTONDOWN:
49582f9d 3177 {
3178 const Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3179 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3180 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3181 switch (theMsg)
7fd59977 3182 {
49582f9d 3183 case WM_LBUTTONUP:
3184 case WM_LBUTTONDOWN:
3185 aButton = Aspect_VKeyMouse_LeftButton;
3186 break;
3187 case WM_MBUTTONUP:
3188 case WM_MBUTTONDOWN:
3189 aButton = Aspect_VKeyMouse_MiddleButton;
3190 break;
3191 case WM_RBUTTONUP:
3192 case WM_RBUTTONDOWN:
3193 aButton = Aspect_VKeyMouse_RightButton;
3194 break;
7fd59977 3195 }
49582f9d 3196 if (theMsg == WM_LBUTTONDOWN
3197 || theMsg == WM_MBUTTONDOWN
3198 || theMsg == WM_RBUTTONDOWN)
f978241f 3199 {
49582f9d 3200 if (aButton == Aspect_VKeyMouse_LeftButton)
f978241f 3201 {
49582f9d 3202 TheIsAnimating = Standard_False;
f978241f 3203 }
49582f9d 3204
3205 SetFocus (theWinHandle);
3206 SetCapture(theWinHandle);
3207 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
f978241f 3208 }
3209 else
3210 {
49582f9d 3211 ReleaseCapture();
3212 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
f978241f 3213 }
49582f9d 3214 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
f978241f 3215 break;
3216 }
49582f9d 3217 case WM_MOUSEWHEEL:
3218 {
3219 const int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
3220 const Standard_Real aDeltaF = Standard_Real(aDelta) / Standard_Real(WHEEL_DELTA);
3221 const Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent (wParam);
3222 Graphic3d_Vec2i aPos (int(short(LOWORD(lParam))), int(short(HIWORD(lParam))));
3223 POINT aCursorPnt = { aPos.x(), aPos.y() };
3224 if (ScreenToClient (theWinHandle, &aCursorPnt))
7fd59977 3225 {
49582f9d 3226 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3227 }
7fd59977 3228
49582f9d 3229 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3230 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
3231 break;
3232 }
3233 case WM_MOUSEMOVE:
3234 {
3235 Graphic3d_Vec2i aPos (LOWORD(lParam), HIWORD(lParam));
3236 Aspect_VKeyMouse aButtons = WNT_Window::MouseButtonsFromEvent (wParam);
3237 Aspect_VKeyFlags aFlags = WNT_Window::MouseKeyFlagsFromEvent(wParam);
7fd59977 3238
49582f9d 3239 // don't make a slide-show from input events - fetch the actual mouse cursor position
3240 CURSORINFO aCursor;
3241 aCursor.cbSize = sizeof(aCursor);
3242 if (::GetCursorInfo (&aCursor) != FALSE)
3243 {
3244 POINT aCursorPnt = { aCursor.ptScreenPos.x, aCursor.ptScreenPos.y };
3245 if (ScreenToClient (theWinHandle, &aCursorPnt))
3246 {
3247 // as we override mouse position, we need overriding also mouse state
3248 aPos.SetValues (aCursorPnt.x, aCursorPnt.y);
3249 aButtons = WNT_Window::MouseButtonsAsync();
3250 aFlags = WNT_Window::MouseKeyFlagsAsync();
3251 }
3252 }
7fd59977 3253
49582f9d 3254 if (VT_GetWindow().IsNull()
3255 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
3256 {
3257 // mouse move events come also for inactive windows
3258 break;
7fd59977 3259 }
7fd59977 3260
49582f9d 3261 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3262 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
3263 break;
3264 }
d6fbb2ab 3265 case WM_INPUT:
3266 {
3267 UINT aSize = 0;
3268 ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, NULL, &aSize, sizeof(RAWINPUTHEADER));
3269 NCollection_LocalArray<BYTE> aRawData (aSize);
3270 if (aSize == 0 || ::GetRawInputData ((HRAWINPUT )lParam, RID_INPUT, aRawData, &aSize, sizeof(RAWINPUTHEADER)) != aSize)
3271 {
3272 break;
3273 }
3274
3275 const RAWINPUT* aRawInput = (RAWINPUT* )(BYTE* )aRawData;
3276 if (aRawInput->header.dwType != RIM_TYPEHID)
3277 {
3278 break;
3279 }
3280
3281 RID_DEVICE_INFO aDevInfo;
3282 aDevInfo.cbSize = sizeof(RID_DEVICE_INFO);
3283 UINT aDevInfoSize = sizeof(RID_DEVICE_INFO);
3284 if (::GetRawInputDeviceInfoW (aRawInput->header.hDevice, RIDI_DEVICEINFO, &aDevInfo, &aDevInfoSize) != sizeof(RID_DEVICE_INFO)
3285 || (aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_LOGITECH
3286 && aDevInfo.hid.dwVendorId != WNT_HIDSpaceMouse::VENDOR_ID_3DCONNEXION))
3287 {
3288 break;
3289 }
3290
3291 WNT_HIDSpaceMouse aSpaceData (aDevInfo.hid.dwProductId, aRawInput->data.hid.bRawData, aRawInput->data.hid.dwSizeHid);
3292 if (ViewerTest::CurrentEventManager()->Update3dMouse (aSpaceData)
3293 && !VT_GetWindow().IsNull())
3294 {
3295 VT_GetWindow()->InvalidateContent();
3296 }
3297 break;
3298 }
7fd59977 3299 default:
49582f9d 3300 {
3301 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
7fd59977 3302 }
49582f9d 3303 }
3304 return 0L;
7fd59977 3305}
3306
7fd59977 3307//==============================================================================
3308//function : ViewerMainLoop
3309//purpose : Get a Event on the view and dispatch it
3310//==============================================================================
3311
49582f9d 3312int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
7fd59977 3313{
49582f9d 3314 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
3315 if (aViewCtrl.IsNull()
3316 || theNbArgs < 4)
3317 {
3318 return 0;
3319 }
7fd59977 3320
49582f9d 3321 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
7fd59977 3322
49582f9d 3323 std::cout << "Start picking\n";
7fd59977 3324
49582f9d 3325 MSG aMsg;
3326 aMsg.wParam = 1;
3327 while (aViewCtrl->ToPickPoint())
3328 {
3329 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
3330 if (GetMessageW (&aMsg, NULL, 0, 0))
3331 {
3332 TranslateMessage (&aMsg);
3333 DispatchMessageW (&aMsg);
7fd59977 3334 }
7fd59977 3335 }
3336
49582f9d 3337 std::cout << "Picking done\n";
3338 return 0;
7fd59977 3339}
3340
4fe56619 3341#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
7fd59977 3342
3343int min( int a, int b )
3344{
3345 if( a<b )
3346 return a;
3347 else
3348 return b;
3349}
3350
3351int max( int a, int b )
3352{
3353 if( a>b )
3354 return a;
3355 else
3356 return b;
3357}
3358
49582f9d 3359int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
4269bd1b 3360{
18d715bd 3361 static XEvent aReport;
49582f9d 3362 const Standard_Boolean toPick = theNbArgs > 0;
3363 if (theNbArgs > 0)
3364 {
3365 if (ViewerTest::CurrentEventManager().IsNull())
3366 {
3367 return 0;
3368 }
3369 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
3370 }
3371
8693dfd0 3372 Display* aDisplay = GetDisplayConnection()->GetDisplay();
18d715bd 3373 XNextEvent (aDisplay, &aReport);
7fd59977 3374
18d715bd 3375 // Handle event for the chosen display connection
8693dfd0 3376 switch (aReport.type)
3377 {
3378 case ClientMessage:
3379 {
3380 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3381 {
3382 // Close the window
3383 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3384 return toPick ? 0 : 1;
3385 }
3386 break;
3387 }
3388 case FocusIn:
3389 {
3390 // Activate inactive view
49582f9d 3391 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3392 if (aWindow != aReport.xfocus.window)
3393 {
3394 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3395 }
3396 break;
3397 }
3398 case Expose:
3399 {
49582f9d 3400 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3401 if (anXWindow == aReport.xexpose.window)
3402 {
49582f9d 3403 ViewerTest::CurrentEventManager()->ProcessExpose();
8693dfd0 3404 }
3405
3406 // remove all the ExposureMask and process them at once
3407 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3408 {
3409 if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
18d715bd 3410 {
8693dfd0 3411 break;
18d715bd 3412 }
8693dfd0 3413 }
3414
3415 break;
3416 }
3417 case ConfigureNotify:
3418 {
3419 // remove all the StructureNotifyMask and process them at once
49582f9d 3420 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3421 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3422 {
3423 if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
3424 {
3425 break;
3426 }
3427 }
3428
3429 if (anXWindow == aReport.xconfigure.window)
3430 {
49582f9d 3431 ViewerTest::CurrentEventManager()->ProcessConfigure();
8693dfd0 3432 }
3433 break;
3434 }
3435 case KeyPress:
49582f9d 3436 case KeyRelease:
8693dfd0 3437 {
49582f9d 3438 XKeyEvent* aKeyEvent = (XKeyEvent* )&aReport;
3439 const KeySym aKeySym = XLookupKeysym (aKeyEvent, 0);
3440 const Aspect_VKey aVKey = Xw_Window::VirtualKeyFromNative (aKeySym);
3441 if (aVKey != Aspect_VKey_UNKNOWN)
8693dfd0 3442 {
49582f9d 3443 const double aTimeStamp = ViewerTest::CurrentEventManager()->EventTime();
3444 if (aReport.type == KeyPress)
7fd59977 3445 {
49582f9d 3446 ViewerTest::CurrentEventManager()->KeyDown (aVKey, aTimeStamp);
7fd59977 3447 }
8693dfd0 3448 else
7fd59977 3449 {
49582f9d 3450 ViewerTest::CurrentEventManager()->KeyUp (aVKey, aTimeStamp);
7fd59977 3451 }
49582f9d 3452 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3453 }
3454 break;
3455 }
49582f9d 3456 case ButtonPress:
8693dfd0 3457 case ButtonRelease:
3458 {
49582f9d 3459 const Graphic3d_Vec2i aPos (aReport.xbutton.x, aReport.xbutton.y);
3460 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3461 Aspect_VKeyMouse aButton = Aspect_VKeyMouse_NONE;
3462 if (aReport.xbutton.button == Button1)
8693dfd0 3463 {
49582f9d 3464 aButton = Aspect_VKeyMouse_LeftButton;
8693dfd0 3465 }
49582f9d 3466 if (aReport.xbutton.button == Button2)
8693dfd0 3467 {
49582f9d 3468 aButton = Aspect_VKeyMouse_MiddleButton;
8693dfd0 3469 }
49582f9d 3470 if (aReport.xbutton.button == Button3)
8693dfd0 3471 {
49582f9d 3472 aButton = Aspect_VKeyMouse_RightButton;
8693dfd0 3473 }
7fd59977 3474
49582f9d 3475 if (aReport.xbutton.state & ControlMask)
8693dfd0 3476 {
49582f9d 3477 aFlags |= Aspect_VKeyFlags_CTRL;
3478 }
3479 if (aReport.xbutton.state & ShiftMask)
3480 {
3481 aFlags |= Aspect_VKeyFlags_SHIFT;
3482 }
3483 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3484 {
3485 aFlags |= Aspect_VKeyFlags_ALT;
8693dfd0 3486 }
7fd59977 3487
49582f9d 3488 if (aReport.xbutton.button == Button4
3489 || aReport.xbutton.button == Button5)
8693dfd0 3490 {
49582f9d 3491 if (aReport.type != ButtonPress)
8693dfd0 3492 {
49582f9d 3493 break;
7fd59977 3494 }
49582f9d 3495
3496 const double aDeltaF = (aReport.xbutton.button == Button4 ? 1.0 : -1.0);
3497 ViewerTest::CurrentEventManager()->UpdateMouseScroll (Aspect_ScrollDelta (aPos, aDeltaF, aFlags));
3498 }
3499 else if (aReport.type == ButtonPress)
3500 {
3501 if (aButton == Aspect_VKeyMouse_LeftButton)
7fd59977 3502 {
49582f9d 3503 TheIsAnimating = Standard_False;
7fd59977 3504 }
49582f9d 3505 ViewerTest::CurrentEventManager()->PressMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3506 }
3507 else
3508 {
49582f9d 3509 ViewerTest::CurrentEventManager()->ReleaseMouseButton (aPos, aButton, aFlags, false);
8693dfd0 3510 }
49582f9d 3511 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3512 break;
3513 }
3514 case MotionNotify:
3515 {
49582f9d 3516 Window anXWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
8693dfd0 3517 if (anXWindow != aReport.xmotion.window)
3518 {
7fd59977 3519 break;
8693dfd0 3520 }
3521
3522 // remove all the ButtonMotionMask and process them at once
3523 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3524 {
3525 if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
7fd59977 3526 {
8693dfd0 3527 break;
3528 }
3529 }
7fd59977 3530
49582f9d 3531 Graphic3d_Vec2i aPos (aReport.xmotion.x, aReport.xmotion.y);
3532 Aspect_VKeyMouse aButtons = Aspect_VKeyMouse_NONE;
3533 Aspect_VKeyFlags aFlags = Aspect_VKeyFlags_NONE;
3534 if ((aReport.xmotion.state & Button1Mask) != 0)
8693dfd0 3535 {
49582f9d 3536 aButtons |= Aspect_VKeyMouse_LeftButton;
3537 }
3538 else if ((aReport.xmotion.state & Button2Mask) != 0)
3539 {
3540 aButtons |= Aspect_VKeyMouse_MiddleButton;
3541 }
3542 else if ((aReport.xmotion.state & Button3Mask) != 0)
3543 {
3544 aButtons |= Aspect_VKeyMouse_RightButton;
3545 }
7fd59977 3546
49582f9d 3547 if (aReport.xmotion.state & ControlMask)
3548 {
3549 aFlags |= Aspect_VKeyFlags_CTRL;
8693dfd0 3550 }
49582f9d 3551 if (aReport.xmotion.state & ShiftMask)
8693dfd0 3552 {
49582f9d 3553 aFlags |= Aspect_VKeyFlags_SHIFT;
8693dfd0 3554 }
49582f9d 3555 if (ViewerTest::CurrentEventManager()->Keys().IsKeyDown (Aspect_VKey_Alt))
3556 {
3557 aFlags |= Aspect_VKeyFlags_ALT;
3558 }
3559
3560 ViewerTest::CurrentEventManager()->UpdateMousePosition (aPos, aButtons, aFlags, false);
3561 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
8693dfd0 3562 break;
3563 }
3564 }
49582f9d 3565 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
7fd59977 3566}
3567
3568//==============================================================================
3569//function : VProcessEvents
8693dfd0 3570//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3571//==============================================================================
8693dfd0 3572static void VProcessEvents (ClientData theDispX, int)
7fd59977 3573{
8693dfd0 3574 Display* aDispX = (Display* )theDispX;
3575 Handle(Aspect_DisplayConnection) aDispConn;
3576 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3577 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3578 {
8693dfd0 3579 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3580 if (aDispConnTmp->GetDisplay() == aDispX)
3581 {
3582 aDispConn = aDispConnTmp;
3583 break;
3584 }
3585 }
3586 if (aDispConn.IsNull())
3587 {
23fe70ec 3588 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
8693dfd0 3589 return;
4269bd1b 3590 }
8693dfd0 3591
3592 // process new events in queue
3593 SetDisplayConnection (aDispConn);
3594 int aNbRemain = 0;
3595 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3596 {
8693dfd0 3597 const int anEventResult = ViewerMainLoop (0, NULL);
3598 if (anEventResult == 0)
18d715bd 3599 {
8693dfd0 3600 return;
3601 }
3602
3603 aNbRemain = XPending (aDispX);
3604 if (++anEventIter >= aNbEventsMax
3605 || aNbRemain <= 0)
3606 {
3607 break;
18d715bd 3608 }
7fd59977 3609 }
4269bd1b 3610
8693dfd0 3611 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3612 // it is possible that new events will arrive to queue before the end of this callback
3613 // so that either this callback should go into an infinite loop (blocking processing of other events)
3614 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3615 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3616 if (aNbRemain != 0)
3617 {
3618 XEvent aDummyEvent;
3619 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3620 aDummyEvent.type = ClientMessage;
3621 aDummyEvent.xclient.format = 32;
3622 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3623 XFlush (aDispX);
3624 }
4269bd1b 3625
8693dfd0 3626 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3627 {
3628 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3629 }
7fd59977 3630}
3631#endif
3632
3633//==============================================================================
3634//function : OSWindowSetup
3635//purpose : Setup for the X11 window to be able to cath the event
3636//==============================================================================
3637
3638
3639static void OSWindowSetup()
3640{
4fe56619 3641#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 3642 // X11
3643
3644 Window window = VT_GetWindow()->XWindow();
18d715bd 3645 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
3646 Display *aDisplay = GetDisplayConnection()->GetDisplay();
3647 XSynchronize(aDisplay, 1);
7fd59977 3648
3649 // X11 : For keyboard on SUN
3650 XWMHints wmhints;
3651 wmhints.flags = InputHint;
3652 wmhints.input = 1;
3653
18d715bd 3654 XSetWMHints( aDisplay, window, &wmhints);
7fd59977 3655
49582f9d 3656 XSelectInput( aDisplay, window, ExposureMask | KeyPressMask | KeyReleaseMask |
7fd59977 3657 ButtonPressMask | ButtonReleaseMask |
3658 StructureNotifyMask |
3659 PointerMotionMask |
3660 Button1MotionMask | Button2MotionMask |
18d715bd 3661 Button3MotionMask | FocusChangeMask
7fd59977 3662 );
18d715bd 3663 Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
3664 XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
7fd59977 3665
18d715bd 3666 XSynchronize(aDisplay, 0);
7fd59977 3667
3668#else
57c28b61 3669 // _WIN32
7fd59977 3670#endif
3671
3672}
3673
7fd59977 3674//==============================================================================
3675//function : VFit
1beb58d7 3676//purpose :
7fd59977 3677//==============================================================================
3678
1beb58d7 3679static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 3680{
1beb58d7 3681 const Handle(V3d_View) aView = ViewerTest::CurrentView();
3682 if (aView.IsNull())
b586500b 3683 {
23fe70ec 3684 Message::SendFail ("Error: no active viewer");
1beb58d7 3685 return 1;
b586500b 3686 }
3687
1beb58d7 3688 Standard_Boolean toFit = Standard_True;
3689 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
3690 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 3691 {
1beb58d7 3692 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 3693 anArg.LowerCase();
1beb58d7 3694 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 3695 {
1beb58d7 3696 continue;
3697 }
3698 else if (anArg == "-selected")
3699 {
3700 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
3701 toFit = Standard_False;
3702 }
3703 else
3704 {
23fe70ec 3705 Message::SendFail() << "Syntax error at '" << anArg << "'";
b586500b 3706 }
3707 }
3708
1beb58d7 3709 if (toFit)
3710 {
3711 aView->FitAll (0.01, Standard_False);
7fd59977 3712 }
3713 return 0;
3714}
3715
6262a303 3716//=======================================================================
3717//function : VFitArea
3718//purpose : Fit view to show area located between two points
3719// : given in world 2D or 3D coordinates.
3720//=======================================================================
3721static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
3722{
3723 Handle(V3d_View) aView = ViewerTest::CurrentView();
3724 if (aView.IsNull())
3725 {
23fe70ec 3726 Message::SendFail ("Error: No active viewer");
6262a303 3727 return 1;
3728 }
3729
3730 // Parse arguments.
3731 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
3732 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
3733
3734 if (theArgNb == 5)
3735 {
3736 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3737 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3738 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
3739 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
3740 }
3741 else if (theArgNb == 7)
3742 {
3743 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
3744 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
3745 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
3746 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
3747 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
3748 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
3749 }
3750 else
3751 {
23fe70ec 3752 Message::SendFail ("Syntax error: Invalid number of arguments");
6262a303 3753 theDI.PrintHelp(theArgVec[0]);
3754 return 1;
3755 }
3756
3757 // Convert model coordinates to view space
3758 Handle(Graphic3d_Camera) aCamera = aView->Camera();
3759 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
3760 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
3761
3762 // Determine fit area
3763 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
3764 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
3765
3766 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
3767
3768 if (aDiagonal < Precision::Confusion())
3769 {
23fe70ec 3770 Message::SendFail ("Error: view area is too small");
6262a303 3771 return 1;
3772 }
3773
3774 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
3775 return 0;
3776}
3777
7fd59977 3778//==============================================================================
3779//function : VZFit
3780//purpose : ZFitall, no DRAW arguments
3781//Draw arg : No args
3782//==============================================================================
197ac94e 3783static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 3784{
197ac94e 3785 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
3786
3787 if (aCurrentView.IsNull())
3788 {
23fe70ec 3789 Message::SendFail ("Error: no active viewer");
197ac94e 3790 return 1;
3791 }
3792
3793 if (theArgsNb == 1)
3794 {
c357e426 3795 aCurrentView->ZFitAll();
197ac94e 3796 aCurrentView->Redraw();
3797 return 0;
3798 }
3799
3800 Standard_Real aScale = 1.0;
3801
3802 if (theArgsNb >= 2)
3803 {
3804 aScale = Draw::Atoi (theArgVec[1]);
3805 }
3806
c357e426 3807 aCurrentView->ZFitAll (aScale);
197ac94e 3808 aCurrentView->Redraw();
7fd59977 3809
197ac94e 3810 return 0;
3811}
7fd59977 3812
197ac94e 3813//==============================================================================
3814//function : VRepaint
3815//purpose :
3816//==============================================================================
56689b27 3817static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 3818{
56689b27 3819 Handle(V3d_View) aView = ViewerTest::CurrentView();
3820 if (aView.IsNull())
3821 {
23fe70ec 3822 Message::SendFail ("Error: no active viewer");
56689b27 3823 return 1;
3824 }
3825
3826 Standard_Boolean isImmediateUpdate = Standard_False;
3827 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3828 {
3829 TCollection_AsciiString anArg (theArgVec[anArgIter]);
3830 anArg.LowerCase();
8693dfd0 3831 if (anArg == "-immediate"
3832 || anArg == "-imm")
56689b27 3833 {
3834 isImmediateUpdate = Standard_True;
3835 if (anArgIter + 1 < theArgNb
dae2a922 3836 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
56689b27 3837 {
3838 ++anArgIter;
3839 }
3840 }
8693dfd0 3841 else if (anArg == "-continuous"
3842 || anArg == "-cont"
3843 || anArg == "-fps"
3844 || anArg == "-framerate")
3845 {
3846 Standard_Real aFps = -1.0;
3847 if (anArgIter + 1 < theArgNb
3848 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
3849 {
3850 aFps = Draw::Atof (theArgVec[++anArgIter]);
3851 }
3852
3853 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
3854 if (Abs (aFps) >= 1.0)
3855 {
3856 aRedrawer.Start (aView->Window(), aFps);
3857 }
3858 else
3859 {
3860 aRedrawer.Stop();
3861 }
3862 }
56689b27 3863 else
3864 {
23fe70ec 3865 Message::SendFail() << "Syntax error at '" << anArg << "'";
8693dfd0 3866 return 1;
56689b27 3867 }
3868 }
3869
3870 if (isImmediateUpdate)
3871 {
3872 aView->RedrawImmediate();
3873 }
3874 else
3875 {
3876 aView->Redraw();
3877 }
3878 return 0;
7fd59977 3879}
3880
7fd59977 3881//==============================================================================
3882//function : VClear
3883//purpose : Remove all the object from the viewer
3884//Draw arg : No args
3885//==============================================================================
3886
3887static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
3888{
3889 Handle(V3d_View) V = ViewerTest::CurrentView();
3890 if(!V.IsNull())
3891 ViewerTest::Clear();
3892 return 0;
3893}
3894
3895//==============================================================================
3896//function : VPick
3897//purpose :
3898//==============================================================================
3899
49582f9d 3900static int VPick (Draw_Interpretor& ,
3901 Standard_Integer theNbArgs,
3902 const char** theArgVec)
3903{
3904 if (ViewerTest::CurrentView().IsNull())
3905 {
3906 return 1;
3907 }
7fd59977 3908
49582f9d 3909 if (theNbArgs < 4)
3910 {
23fe70ec 3911 Message::SendFail ("Syntax error: wrong number of arguments");
49582f9d 3912 return 1;
3913 }
7fd59977 3914
49582f9d 3915 while (ViewerMainLoop (theNbArgs, theArgVec))
3916 {
3917 //
3918 }
7fd59977 3919
49582f9d 3920 return 0;
7fd59977 3921}
3922
293211ae 3923namespace
7fd59977 3924{
7fd59977 3925
293211ae 3926 //! Changes the background
3927 //! @param theDrawInterpretor the interpreter of the Draw Harness application
3928 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
3929 //! @param theCommandLineArguments the array of command line arguments
3930 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
3931 static int vbackground (Draw_Interpretor& theDrawInterpretor,
3932 const Standard_Integer theNumberOfCommandLineArguments,
3933 const char** const theCommandLineArguments)
7fd59977 3934 {
293211ae 3935 if (theNumberOfCommandLineArguments < 1)
7fd59977 3936 {
293211ae 3937 return TCL_ERROR;
7fd59977 3938 }
293211ae 3939 BackgroundChanger aBackgroundChanger;
3940 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
3941 theNumberOfCommandLineArguments,
3942 theCommandLineArguments))
f8b2ed36 3943 {
293211ae 3944 theDrawInterpretor << "Wrong command arguments.\n"
3945 "Type 'help "
3946 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
3947 return TCL_ERROR;
f8b2ed36 3948 }
293211ae 3949 return TCL_OK;
f8b2ed36 3950 }
3951
293211ae 3952} // namespace
f42753ed 3953
7fd59977 3954//==============================================================================
3955//function : VScale
3956//purpose : View Scaling
3957//==============================================================================
3958
3959static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3960{
3961 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3962 if ( V3dView.IsNull() ) return 1;
3963
3964 if ( argc != 4 ) {
586db386 3965 di << argv[0] << "Invalid number of arguments\n";
7fd59977 3966 return 1;
3967 }
91322f44 3968 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 3969 return 0;
3970}
3971//==============================================================================
536d98e2 3972//function : VZBuffTrihedron
3973//purpose :
7fd59977 3974//==============================================================================
3975
536d98e2 3976static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3977 Standard_Integer theArgNb,
3978 const char** theArgVec)
7fd59977 3979{
536d98e2 3980 Handle(V3d_View) aView = ViewerTest::CurrentView();
3981 if (aView.IsNull())
3982 {
23fe70ec 3983 Message::SendFail ("Error: no active viewer");
536d98e2 3984 return 1;
3985 }
7fd59977 3986
536d98e2 3987 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 3988
536d98e2 3989 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3990 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
3991 Quantity_Color aLabelsColor = Quantity_NOC_WHITE;
3992 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3993 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3994 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3995 Standard_Real aScale = 0.1;
3996 Standard_Real aSizeRatio = 0.8;
3997 Standard_Real anArrowDiam = 0.05;
3998 Standard_Integer aNbFacets = 12;
3999 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 4000 {
536d98e2 4001 Standard_CString anArg = theArgVec[anArgIter];
4002 TCollection_AsciiString aFlag (anArg);
4003 aFlag.LowerCase();
4004 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 4005 {
536d98e2 4006 continue;
4007 }
4008 else if (aFlag == "-on")
7c8a8fcc 4009 {
536d98e2 4010 continue;
4011 }
4012 else if (aFlag == "-off")
7c8a8fcc 4013 {
536d98e2 4014 aView->TriedronErase();
4015 return 0;
4016 }
4017 else if (aFlag == "-pos"
4018 || aFlag == "-position"
4019 || aFlag == "-corner")
7c8a8fcc 4020 {
536d98e2 4021 if (++anArgIter >= theArgNb)
4022 {
23fe70ec 4023 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4024 return 1;
4025 }
4026
4027 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
4028 aPosName.LowerCase();
4029 if (aPosName == "center")
4030 {
4031 aPosition = Aspect_TOTP_CENTER;
4032 }
4033 else if (aPosName == "left_lower"
4034 || aPosName == "lower_left"
4035 || aPosName == "leftlower"
4036 || aPosName == "lowerleft")
4037 {
4038 aPosition = Aspect_TOTP_LEFT_LOWER;
4039 }
4040 else if (aPosName == "left_upper"
4041 || aPosName == "upper_left"
4042 || aPosName == "leftupper"
4043 || aPosName == "upperleft")
4044 {
4045 aPosition = Aspect_TOTP_LEFT_UPPER;
4046 }
4047 else if (aPosName == "right_lower"
4048 || aPosName == "lower_right"
4049 || aPosName == "rightlower"
4050 || aPosName == "lowerright")
4051 {
4052 aPosition = Aspect_TOTP_RIGHT_LOWER;
4053 }
4054 else if (aPosName == "right_upper"
4055 || aPosName == "upper_right"
4056 || aPosName == "rightupper"
4057 || aPosName == "upperright")
4058 {
4059 aPosition = Aspect_TOTP_RIGHT_UPPER;
4060 }
4061 else
4062 {
23fe70ec 4063 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
536d98e2 4064 return 1;
4065 }
4066 }
4067 else if (aFlag == "-type")
7c8a8fcc 4068 {
536d98e2 4069 if (++anArgIter >= theArgNb)
4070 {
23fe70ec 4071 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4072 return 1;
4073 }
4074
4075 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
4076 aTypeName.LowerCase();
4077 if (aTypeName == "wireframe"
4078 || aTypeName == "wire")
4079 {
4080 aVisType = V3d_WIREFRAME;
4081 }
4082 else if (aTypeName == "zbuffer"
4083 || aTypeName == "shaded")
4084 {
4085 aVisType = V3d_ZBUFFER;
4086 }
4087 else
4088 {
23fe70ec 4089 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
536d98e2 4090 }
4091 }
4092 else if (aFlag == "-scale")
7c8a8fcc 4093 {
536d98e2 4094 if (++anArgIter >= theArgNb)
4095 {
23fe70ec 4096 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4097 return 1;
4098 }
4099
4100 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 4101 }
536d98e2 4102 else if (aFlag == "-size"
4103 || aFlag == "-sizeratio")
4104 {
4105 if (++anArgIter >= theArgNb)
4106 {
23fe70ec 4107 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4108 return 1;
4109 }
7c8a8fcc 4110
536d98e2 4111 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
4112 }
4113 else if (aFlag == "-arrowdiam"
4114 || aFlag == "-arrowdiameter")
4115 {
4116 if (++anArgIter >= theArgNb)
4117 {
23fe70ec 4118 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4119 return 1;
4120 }
7c8a8fcc 4121
536d98e2 4122 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
4123 }
4124 else if (aFlag == "-nbfacets")
4125 {
4126 if (++anArgIter >= theArgNb)
4127 {
23fe70ec 4128 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4129 return 1;
4130 }
7c8a8fcc 4131
536d98e2 4132 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
4133 }
4134 else if (aFlag == "-colorlabel"
4135 || aFlag == "-colorlabels")
7c8a8fcc 4136 {
dae2a922 4137 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4138 theArgVec + anArgIter + 1,
4139 aLabelsColor);
536d98e2 4140 if (aNbParsed == 0)
4141 {
23fe70ec 4142 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4143 return 1;
4144 }
4145 anArgIter += aNbParsed;
7c8a8fcc 4146 }
536d98e2 4147 else if (aFlag == "-colorarrowx")
7c8a8fcc 4148 {
dae2a922 4149 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4150 theArgVec + anArgIter + 1,
4151 anArrowColorX);
536d98e2 4152 if (aNbParsed == 0)
4153 {
23fe70ec 4154 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4155 return 1;
4156 }
4157 anArgIter += aNbParsed;
4158 }
4159 else if (aFlag == "-colorarrowy")
7c8a8fcc 4160 {
dae2a922 4161 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4162 theArgVec + anArgIter + 1,
4163 anArrowColorY);
536d98e2 4164 if (aNbParsed == 0)
4165 {
23fe70ec 4166 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4167 return 1;
4168 }
4169 anArgIter += aNbParsed;
4170 }
4171 else if (aFlag == "-colorarrowz")
7c8a8fcc 4172 {
dae2a922 4173 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
4174 theArgVec + anArgIter + 1,
4175 anArrowColorZ);
536d98e2 4176 if (aNbParsed == 0)
4177 {
23fe70ec 4178 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
536d98e2 4179 return 1;
4180 }
4181 anArgIter += aNbParsed;
4182 }
4183 else
4184 {
23fe70ec 4185 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
7c8a8fcc 4186 return 1;
4187 }
7c8a8fcc 4188 }
4189
536d98e2 4190 aView->ZBufferTriedronSetup (anArrowColorX.Name(), anArrowColorY.Name(), anArrowColorZ.Name(),
4191 aSizeRatio, anArrowDiam, aNbFacets);
4192 aView->TriedronDisplay (aPosition, aLabelsColor.Name(), aScale, aVisType);
c357e426 4193 aView->ZFitAll();
7fd59977 4194 return 0;
4195}
4196
4197//==============================================================================
4198//function : VRotate
4199//purpose : Camera Rotating
4200//==============================================================================
4201
4af098ba 4202static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4203{
4204 Handle(V3d_View) aView = ViewerTest::CurrentView();
4205 if (aView.IsNull())
4206 {
23fe70ec 4207 Message::SendFail ("Error: no active viewer");
7fd59977 4208 return 1;
4209 }
4210
4af098ba 4211 Standard_Boolean hasFlags = Standard_False;
4212 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4213 {
4214 Standard_CString anArg (theArgVec[anArgIter]);
4215 TCollection_AsciiString aFlag (anArg);
4216 aFlag.LowerCase();
4217 if (aFlag == "-mousestart"
4218 || aFlag == "-mousefrom")
4219 {
4220 hasFlags = Standard_True;
4221 if (anArgIter + 2 >= theArgNb)
4222 {
23fe70ec 4223 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4224 return 1;
4225 }
4226
4227 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4228 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4229 aView->StartRotation (anX, anY);
4230 }
4231 else if (aFlag == "-mousemove")
4232 {
4233 hasFlags = Standard_True;
4234 if (anArgIter + 2 >= theArgNb)
4235 {
23fe70ec 4236 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4237 return 1;
4238 }
4239
4240 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4241 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4242 aView->Rotation (anX, anY);
4243 }
4244 else if (theArgNb != 4
4245 && theArgNb != 7)
4246 {
23fe70ec 4247 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4af098ba 4248 return 1;
4249 }
4250 }
4251
4252 if (hasFlags)
4253 {
7fd59977 4254 return 0;
4af098ba 4255 }
4256 else if (theArgNb == 4)
4257 {
4258 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4259 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4260 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4261 aView->Rotate (anAX, anAY, anAZ);
4262 return 0;
4263 }
4264 else if (theArgNb == 7)
4265 {
4266 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4267 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4268 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4269
4270 Standard_Real anX = Draw::Atof (theArgVec[4]);
4271 Standard_Real anY = Draw::Atof (theArgVec[5]);
4272 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4273
4274 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4275 return 0;
7fd59977 4276 }
4af098ba 4277
23fe70ec 4278 Message::SendFail ("Error: Invalid number of arguments");
4af098ba 4279 return 1;
7fd59977 4280}
4281
4282//==============================================================================
4283//function : VZoom
4284//purpose : View zoom in / out (relative to current zoom)
4285//==============================================================================
4286
4287static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4288 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4289 if ( V3dView.IsNull() ) {
4290 return 1;
4291 }
4292
4293 if ( argc == 2 ) {
91322f44 4294 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4295 if ( coef <= 0.0 ) {
586db386 4296 di << argv[1] << "Invalid value\n";
7fd59977 4297 return 1;
4298 }
91322f44 4299 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4300 return 0;
4301 } else {
586db386 4302 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4303 return 1;
4304 }
4305}
4306
4307//==============================================================================
4308//function : VPan
4309//purpose : View panning (in pixels)
4310//==============================================================================
4311
4312static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4313 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4314 if ( V3dView.IsNull() ) return 1;
4315
4316 if ( argc == 3 ) {
91322f44 4317 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4318 return 0;
4319 } else {
586db386 4320 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4321 return 1;
4322 }
4323}
4324
49e1a5c7 4325//==============================================================================
4326//function : VPlace
4327//purpose : Place the point (in pixels) at the center of the window
4328//==============================================================================
4329static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4330{
4331 Handle(V3d_View) aView = ViewerTest::CurrentView();
4332 if (aView.IsNull())
4333 {
23fe70ec 4334 Message::SendFail ("Error: no active viewer");
49e1a5c7 4335 return 1;
4336 }
4337
4338 if (theArgNb != 3)
4339 {
23fe70ec 4340 Message::SendFail ("Syntax error: wrong number of arguments");
49e1a5c7 4341 return 1;
4342 }
4343
4344 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4345
4346 return 0;
4347}
7fd59977 4348
71215351 4349static int VColorScale (Draw_Interpretor& theDI,
4350 Standard_Integer theArgNb,
4351 const char** theArgVec)
4352{
7fd59977 4353 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4354 Handle(V3d_View) aView = ViewerTest::CurrentView();
4355 if (aContext.IsNull())
4356 {
23fe70ec 4357 Message::SendFail ("Error: no active viewer");
71215351 4358 return 1;
7fd59977 4359 }
24a88697 4360 if (theArgNb <= 1)
4361 {
23fe70ec 4362 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
24a88697 4363 return 1;
4364 }
7fd59977 4365
4b3d6eb1 4366 Handle(AIS_ColorScale) aColorScale;
7a324550 4367 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4368 {
4b3d6eb1 4369 // find existing object
4370 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4371 if (aColorScale.IsNull())
7a324550 4372 {
23fe70ec 4373 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
7a324550 4374 return 1;
4375 }
4376 }
71215351 4377
7a324550 4378 if (theArgNb <= 2)
4379 {
4b3d6eb1 4380 if (aColorScale.IsNull())
4381 {
23fe70ec 4382 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
4b3d6eb1 4383 return 1;
4384 }
4385
7a324550 4386 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4387 << "Min range: " << aColorScale->GetMin() << "\n"
4388 << "Max range: " << aColorScale->GetMax() << "\n"
4389 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4390 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4391 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4392 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4393 << "Label position: ";
4b3d6eb1 4394 switch (aColorScale->GetLabelPosition())
71215351 4395 {
4396 case Aspect_TOCSP_NONE:
4397 theDI << "None\n";
4398 break;
4399 case Aspect_TOCSP_LEFT:
4400 theDI << "Left\n";
4401 break;
4402 case Aspect_TOCSP_RIGHT:
4403 theDI << "Right\n";
4404 break;
4405 case Aspect_TOCSP_CENTER:
4406 theDI << "Center\n";
4407 break;
4408 }
4409 return 0;
4410 }
71215351 4411
4b3d6eb1 4412 if (aColorScale.IsNull())
4413 {
4414 aColorScale = new AIS_ColorScale();
4415 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4416 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4417 }
4418
4419 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4420 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4421 {
4422 Standard_CString anArg = theArgVec[anArgIter];
4423 TCollection_AsciiString aFlag (anArg);
4424 aFlag.LowerCase();
4425 if (anUpdateTool.parseRedrawMode (aFlag))
4426 {
4427 continue;
4428 }
4429 else if (aFlag == "-range")
4430 {
4431 if (anArgIter + 3 >= theArgNb)
4432 {
23fe70ec 4433 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
71215351 4434 return 1;
4435 }
4436
4b3d6eb1 4437 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4438 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4439 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
4440 if (!aRangeMin.IsRealValue()
4441 || !aRangeMax.IsRealValue())
71215351 4442 {
23fe70ec 4443 Message::SendFail ("Syntax error: the range values should be real");
71215351 4444 return 1;
4445 }
4b3d6eb1 4446 else if (!aNbIntervals.IsIntegerValue())
71215351 4447 {
23fe70ec 4448 Message::SendFail ("Syntax error: the number of intervals should be integer");
71215351 4449 return 1;
4450 }
4451
4b3d6eb1 4452 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4453 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4454 }
4455 else if (aFlag == "-font")
4456 {
4457 if (anArgIter + 1 >= theArgNb)
4458 {
23fe70ec 4459 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4460 return 1;
4461 }
51740958 4462 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4463 if (!aFontArg.IsIntegerValue())
71215351 4464 {
23fe70ec 4465 Message::SendFail ("Syntax error: HeightFont value should be integer");
71215351 4466 return 1;
4467 }
4468
4b3d6eb1 4469 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4470 anArgIter += 1;
4471 }
4472 else if (aFlag == "-textpos")
4473 {
4474 if (anArgIter + 1 >= theArgNb)
4475 {
23fe70ec 4476 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4477 return 1;
4478 }
4b3d6eb1 4479
51740958 4480 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4481 aTextPosArg.LowerCase();
4b3d6eb1 4482 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4483 if (aTextPosArg == "none")
71215351 4484 {
4485 aLabPosition = Aspect_TOCSP_NONE;
4486 }
51740958 4487 else if (aTextPosArg == "left")
71215351 4488 {
4489 aLabPosition = Aspect_TOCSP_LEFT;
4490 }
51740958 4491 else if (aTextPosArg == "right")
71215351 4492 {
4493 aLabPosition = Aspect_TOCSP_RIGHT;
4494 }
51740958 4495 else if (aTextPosArg == "center")
71215351 4496 {
4497 aLabPosition = Aspect_TOCSP_CENTER;
4498 }
4499 else
4500 {
23fe70ec 4501 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
71215351 4502 return 1;
4503 }
4b3d6eb1 4504 aColorScale->SetLabelPosition (aLabPosition);
71215351 4505 }
24a88697 4506 else if (aFlag == "-logarithmic"
4507 || aFlag == "-log")
4508 {
4509 if (anArgIter + 1 >= theArgNb)
4510 {
23fe70ec 4511 Message::SendFail() << "Synta error at argument '" << anArg << "'";
24a88697 4512 return 1;
4513 }
4b3d6eb1 4514
24a88697 4515 Standard_Boolean IsLog;
dae2a922 4516 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
24a88697 4517 {
23fe70ec 4518 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
24a88697 4519 return 1;
4520 }
4b3d6eb1 4521 aColorScale->SetLogarithmic (IsLog);
4522 }
4523 else if (aFlag == "-huerange"
4524 || aFlag == "-hue")
4525 {
4526 if (anArgIter + 2 >= theArgNb)
4527 {
23fe70ec 4528 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4529 return 1;
4530 }
4531
4532 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4533 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4534 aColorScale->SetHueRange (aHueMin, aHueMax);
4535 }
4536 else if (aFlag == "-colorrange")
4537 {
4538 Quantity_Color aColorMin, aColorMax;
dae2a922 4539 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4540 theArgVec + (anArgIter + 1),
4541 aColorMin);
4b3d6eb1 4542 anArgIter += aNbParsed1;
dae2a922 4543 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
4544 theArgVec + (anArgIter + 1),
4545 aColorMax);
4b3d6eb1 4546 anArgIter += aNbParsed2;
4547 if (aNbParsed1 == 0
4548 || aNbParsed2 == 0)
4549 {
23fe70ec 4550 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
4b3d6eb1 4551 return 1;
4552 }
4553
4554 aColorScale->SetColorRange (aColorMin, aColorMax);
4555 }
4556 else if (aFlag == "-reversed"
4557 || aFlag == "-inverted"
4558 || aFlag == "-topdown"
4559 || aFlag == "-bottomup")
4560 {
4561 Standard_Boolean toEnable = Standard_True;
4562 if (anArgIter + 1 < theArgNb
dae2a922 4563 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4564 {
4565 ++anArgIter;
4566 }
4567 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4568 }
4569 else if (aFlag == "-smooth"
4570 || aFlag == "-smoothtransition")
4571 {
4572 Standard_Boolean toEnable = Standard_True;
4573 if (anArgIter + 1 < theArgNb
dae2a922 4574 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4575 {
4576 ++anArgIter;
4577 }
4578 aColorScale->SetSmoothTransition (toEnable);
24a88697 4579 }
71215351 4580 else if (aFlag == "-xy")
4581 {
4582 if (anArgIter + 2 >= theArgNb)
4583 {
23fe70ec 4584 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4585 return 1;
4586 }
4587
4b3d6eb1 4588 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4589 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4590 if (!anX.IsIntegerValue()
4591 || !anY.IsIntegerValue())
71215351 4592 {
23fe70ec 4593 Message::SendFail ("Syntax error: coordinates should be integer values");
71215351 4594 return 1;
4595 }
4596
4b3d6eb1 4597 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4598 }
4599 else if (aFlag == "-width"
4b3d6eb1 4600 || aFlag == "-w"
4601 || aFlag == "-breadth")
b4b2ecca 4602 {
4603 if (anArgIter + 1 >= theArgNb)
4604 {
23fe70ec 4605 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4606 return 1;
4607 }
4608
4b3d6eb1 4609 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4610 if (!aBreadth.IsIntegerValue())
b4b2ecca 4611 {
23fe70ec 4612 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4613 return 1;
4614 }
4b3d6eb1 4615 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4616 }
4617 else if (aFlag == "-height"
4618 || aFlag == "-h")
4619 {
4620 if (anArgIter + 1 >= theArgNb)
4621 {
23fe70ec 4622 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b4b2ecca 4623 return 1;
4624 }
4625
4b3d6eb1 4626 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4627 if (!aHeight.IsIntegerValue())
b4b2ecca 4628 {
23fe70ec 4629 Message::SendFail ("Syntax error: a width should be an integer value");
b4b2ecca 4630 return 1;
4631 }
4b3d6eb1 4632 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4633 }
4634 else if (aFlag == "-color")
4635 {
4b3d6eb1 4636 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4637 {
23fe70ec 4638 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
71215351 4639 return 1;
4640 }
4b3d6eb1 4641 else if (anArgIter + 2 >= theArgNb)
71215351 4642 {
23fe70ec 4643 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4644 return 1;
71215351 4645 }
4646
4b3d6eb1 4647 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 4648 if (!anInd.IsIntegerValue())
4649 {
23fe70ec 4650 Message::SendFail ("Syntax error: Index value should be integer");
71215351 4651 return 1;
4652 }
4b3d6eb1 4653 const Standard_Integer anIndex = anInd.IntegerValue();
4654 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 4655 {
23fe70ec 4656 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
71215351 4657 return 1;
4658 }
4659
4b3d6eb1 4660 Quantity_Color aColor;
dae2a922 4661 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4662 theArgVec + (anArgIter + 1),
4663 aColor);
4b3d6eb1 4664 if (aNbParsed == 0)
71215351 4665 {
23fe70ec 4666 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
71215351 4667 return 1;
4668 }
4b3d6eb1 4669 aColorScale->SetIntervalColor (aColor, anIndex);
4670 aColorScale->SetColorType (Aspect_TOCSD_USER);
4671 anArgIter += aNbParsed;
71215351 4672 }
4673 else if (aFlag == "-label")
4674 {
4b3d6eb1 4675 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4676 {
23fe70ec 4677 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
71215351 4678 return 1;
4679 }
4680 else if (anArgIter + 2 >= theArgNb)
4681 {
23fe70ec 4682 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4683 return 1;
4684 }
4685
4686 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 4687 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 4688 {
23fe70ec 4689 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
71215351 4690 return 1;
4691 }
4692
94f16a89 4693 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
4b3d6eb1 4694 aColorScale->SetLabel (aText, anIndex);
4695 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4696 anArgIter += 2;
4697 }
4b3d6eb1 4698 else if (aFlag == "-labelat"
4699 || aFlag == "-labat"
4700 || aFlag == "-labelatborder"
4701 || aFlag == "-labatborder"
4702 || aFlag == "-labelatcenter"
4703 || aFlag == "-labatcenter")
71215351 4704 {
4b3d6eb1 4705 Standard_Boolean toEnable = Standard_True;
4706 if (aFlag == "-labelat"
4707 || aFlag == "-labat")
71215351 4708 {
4b3d6eb1 4709 Standard_Integer aLabAtBorder = -1;
4710 if (++anArgIter >= theArgNb)
71215351 4711 {
4b3d6eb1 4712 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
4713 anAtBorder.LowerCase();
4714 if (anAtBorder == "border")
71215351 4715 {
4b3d6eb1 4716 aLabAtBorder = 1;
71215351 4717 }
4b3d6eb1 4718 else if (anAtBorder == "center")
71215351 4719 {
4b3d6eb1 4720 aLabAtBorder = 0;
71215351 4721 }
71215351 4722 }
4b3d6eb1 4723 if (aLabAtBorder == -1)
4724 {
23fe70ec 4725 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4726 return 1;
4727 }
4728 toEnable = (aLabAtBorder == 1);
4729 }
4730 else if (anArgIter + 1 < theArgNb
dae2a922 4731 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4b3d6eb1 4732 {
4733 ++anArgIter;
71215351 4734 }
4b3d6eb1 4735 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
4736 || aFlag == "-labatcenter"
4737 ? !toEnable
4738 : toEnable);
4739 }
4740 else if (aFlag == "-colors")
4741 {
4742 Aspect_SequenceOfColor aSeq;
4743 for (;;)
4744 {
4745 Quantity_Color aColor;
dae2a922 4746 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
4747 theArgVec + (anArgIter + 1),
4748 aColor);
4b3d6eb1 4749 if (aNbParsed == 0)
4750 {
4751 break;
4752 }
4753 anArgIter += aNbParsed;
4754 aSeq.Append (aColor);
4755 }
4756 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 4757 {
23fe70ec 4758 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4759 << aColorScale->GetNumberOfIntervals() << " intervals";
71215351 4760 return 1;
4761 }
4762
4b3d6eb1 4763 aColorScale->SetColors (aSeq);
4764 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 4765 }
14b741b0 4766 else if (aFlag == "-uniform")
4767 {
4768 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4769 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4770 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4771 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4772 aColorScale->SetColorType (Aspect_TOCSD_USER);
4773 }
4b3d6eb1 4774 else if (aFlag == "-labels"
4775 || aFlag == "-freelabels")
71215351 4776 {
4b3d6eb1 4777 if (anArgIter + 1 >= theArgNb)
4778 {
23fe70ec 4779 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b3d6eb1 4780 return 1;
4781 }
4782
4783 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4784 ? aColorScale->GetNumberOfIntervals() + 1
4785 : aColorScale->GetNumberOfIntervals();
4786 if (aFlag == "-freelabels")
4787 {
4788 ++anArgIter;
4789 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4790 }
4791 if (anArgIter + aNbLabels >= theArgNb)
71215351 4792 {
23fe70ec 4793 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
71215351 4794 return 1;
4795 }
4796
4797 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 4798 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 4799 {
94f16a89 4800 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
71215351 4801 }
4b3d6eb1 4802 aColorScale->SetLabels (aSeq);
4803 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 4804 }
4805 else if (aFlag == "-title")
4806 {
4807 if (anArgIter + 1 >= theArgNb)
4808 {
23fe70ec 4809 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
71215351 4810 return 1;
4811 }
4812
4813 Standard_Boolean isTwoArgs = Standard_False;
4814 if (anArgIter + 2 < theArgNb)
4815 {
4816 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4817 aSecondArg.LowerCase();
4b3d6eb1 4818 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 4819 if (aSecondArg == "none")
4820 {
4b3d6eb1 4821 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 4822 isTwoArgs = Standard_True;
4823 }
4824 else if (aSecondArg == "left")
4825 {
4b3d6eb1 4826 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 4827 isTwoArgs = Standard_True;
4828 }
4829 else if (aSecondArg == "right")
4830 {
4b3d6eb1 4831 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 4832 isTwoArgs = Standard_True;
4833 }
4834 else if (aSecondArg == "center")
4835 {
4b3d6eb1 4836 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 4837 isTwoArgs = Standard_True;
4838 }
4b3d6eb1 4839 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 4840 }
4841
94f16a89 4842 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4843 aColorScale->SetTitle (aTitle);
71215351 4844 if (isTwoArgs)
4845 {
4846 anArgIter += 1;
4847 }
4848 anArgIter += 1;
4849 }
4850 else if (aFlag == "-demoversion"
4851 || aFlag == "-demo")
4852 {
4b3d6eb1 4853 aColorScale->SetPosition (0, 0);
4854 aColorScale->SetTextHeight (16);
4855 aColorScale->SetRange (0.0, 100.0);
4856 aColorScale->SetNumberOfIntervals (10);
4857 aColorScale->SetBreadth (0);
4858 aColorScale->SetHeight (0);
4859 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4860 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4861 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 4862 }
d5514578 4863 else if (aFlag == "-findcolor")
4864 {
4865 if (anArgIter + 1 >= theArgNb)
4866 {
23fe70ec 4867 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
d5514578 4868 return 1;
4869 }
4870
4871 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4872
4873 if (!anArg1.IsRealValue())
4874 {
23fe70ec 4875 Message::SendFail ("Syntax error: the value should be real");
d5514578 4876 return 1;
4877 }
4878
4879 Quantity_Color aColor;
4b3d6eb1 4880 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 4881 theDI << Quantity_Color::StringName (aColor.Name());
4882 return 0;
4883 }
71215351 4884 else
4885 {
23fe70ec 4886 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
71215351 4887 return 1;
4888 }
4889 }
4b3d6eb1 4890
4891 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4892 aView->Window()->Size (aWinWidth, aWinHeight);
4893 if (aColorScale->GetBreadth() == 0)
b4b2ecca 4894 {
4b3d6eb1 4895 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 4896 }
4b3d6eb1 4897 if (aColorScale->GetHeight() == 0)
4898 {
4899 aColorScale->SetHeight (aWinHeight);
4900 }
4901 aColorScale->SetToUpdate();
4902 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 4903 return 0;
4904}
4905
4906//==============================================================================
4907//function : VGraduatedTrihedron
a79f67f8 4908//purpose : Displays or hides a graduated trihedron
7fd59977 4909//==============================================================================
a79f67f8 4910static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4911 Quantity_Color& theColor)
13a22457 4912{
a79f67f8 4913 Quantity_NameOfColor aColorName;
4914 TCollection_AsciiString aVal = theValue;
4915 aVal.UpperCase();
4916 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 4917 {
a79f67f8 4918 return Standard_False;
13a22457 4919 }
a79f67f8 4920 theColor = Quantity_Color (aColorName);
4921 return Standard_True;
13a22457
S
4922}
4923
a79f67f8 4924static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 4925{
a79f67f8 4926 if (theArgNum < 2)
13a22457 4927 {
23fe70ec 4928 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4929 << theArgs[0] <<"' for more information";
4930 return 1;
13a22457 4931 }
7fd59977 4932
a79f67f8 4933 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4934 TCollection_AsciiString aParseKey;
4935 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4936 {
4937 TCollection_AsciiString anArg (theArgs [anArgIt]);
4938
4939 if (anArg.Value (1) == '-' && !anArg.IsRealValue())
4940 {
4941 aParseKey = anArg;
4942 aParseKey.Remove (1);
4943 aParseKey.LowerCase();
4944 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4945 continue;
4946 }
13a22457 4947
a79f67f8 4948 if (aParseKey.IsEmpty())
4949 {
4950 continue;
4951 }
4952
4953 aMapOfArgs(aParseKey)->Append (anArg);
4954 }
4955
4956 // Check parameters
4957 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4958 aMapIt.More(); aMapIt.Next())
7fd59977 4959 {
a79f67f8 4960 const TCollection_AsciiString& aKey = aMapIt.Key();
4961 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4962
4963 // Bool key, without arguments
4964 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4965 && anArgs->IsEmpty())
4966 {
4967 continue;
4968 }
4969
4970 // One argument
4971 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4972 && anArgs->Length() == 1)
4973 {
4974 continue;
4975 }
4976
4977 // On/off arguments
4978 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4979 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 4980 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4981 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 4982 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4983 {
4984 continue;
4985 }
4986
4987 // One string argument
4988 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4989 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
4990 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
4991 {
4992 continue;
4993 }
4994
4995 // One integer argument
4996 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4997 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4998 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4999 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
5000 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
5001 {
5002 continue;
5003 }
5004
5005 // One real argument
5006 if ( aKey.IsEqual ("arrowlength")
5007 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue()))
5008 {
5009 continue;
5010 }
5011
5012 // Two string arguments
5013 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
5014 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
13a22457 5015 {
a79f67f8 5016 continue;
13a22457 5017 }
a79f67f8 5018
5019 TCollection_AsciiString aLowerKey;
5020 aLowerKey = "-";
5021 aLowerKey += aKey;
5022 aLowerKey.LowerCase();
23fe70ec 5023 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
5024 << "Type help for more information";
a79f67f8 5025 return 1;
7fd59977 5026 }
5027
a79f67f8 5028 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5029 if (anAISContext.IsNull())
5030 {
23fe70ec 5031 Message::SendFail ("Error: no active viewer");
a79f67f8 5032 return 1;
5033 }
7fd59977 5034
a79f67f8 5035 Standard_Boolean toDisplay = Standard_True;
5036 Quantity_Color aColor;
5037 Graphic3d_GraduatedTrihedron aTrihedronData;
5038 // Process parameters
5039 Handle(TColStd_HSequenceOfAsciiString) aValues;
5040 if (aMapOfArgs.Find ("off", aValues))
7fd59977 5041 {
a79f67f8 5042 toDisplay = Standard_False;
5043 }
13a22457 5044
a79f67f8 5045 // AXES NAMES
5046 if (aMapOfArgs.Find ("xname", aValues))
5047 {
5048 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
5049 }
5050 if (aMapOfArgs.Find ("yname", aValues))
5051 {
5052 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
5053 }
5054 if (aMapOfArgs.Find ("zname", aValues))
5055 {
5056 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
5057 }
5058 if (aMapOfArgs.Find ("xdrawname", aValues))
5059 {
536d98e2 5060 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5061 }
5062 if (aMapOfArgs.Find ("ydrawname", aValues))
5063 {
536d98e2 5064 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5065 }
5066 if (aMapOfArgs.Find ("zdrawname", aValues))
5067 {
536d98e2 5068 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5069 }
5070 if (aMapOfArgs.Find ("xnameoffset", aValues))
5071 {
5072 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5073 }
5074 if (aMapOfArgs.Find ("ynameoffset", aValues))
5075 {
5076 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5077 }
5078 if (aMapOfArgs.Find ("znameoffset", aValues))
5079 {
5080 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5081 }
13a22457 5082
a79f67f8 5083 // COLORS
5084 if (aMapOfArgs.Find ("xnamecolor", aValues))
5085 {
5086 if (!GetColor (aValues->Value(1), aColor))
13a22457 5087 {
23fe70ec 5088 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
a79f67f8 5089 return 1;
13a22457 5090 }
a79f67f8 5091 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
5092 }
5093 if (aMapOfArgs.Find ("ynamecolor", aValues))
5094 {
5095 if (!GetColor (aValues->Value(1), aColor))
13a22457 5096 {
23fe70ec 5097 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
a79f67f8 5098 return 1;
5099 }
5100 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
5101 }
5102 if (aMapOfArgs.Find ("znamecolor", aValues))
5103 {
5104 if (!GetColor (aValues->Value(1), aColor))
5105 {
23fe70ec 5106 Message::SendFail ("Syntax error: -znamecolor wrong color name");
a79f67f8 5107 return 1;
5108 }
5109 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
5110 }
5111 if (aMapOfArgs.Find ("xcolor", aValues))
5112 {
5113 if (!GetColor (aValues->Value(1), aColor))
5114 {
23fe70ec 5115 Message::SendFail ("Syntax error: -xcolor wrong color name");
a79f67f8 5116 return 1;
5117 }
5118 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
5119 }
5120 if (aMapOfArgs.Find ("ycolor", aValues))
5121 {
5122 if (!GetColor (aValues->Value(1), aColor))
5123 {
23fe70ec 5124 Message::SendFail ("Syntax error: -ycolor wrong color name");
a79f67f8 5125 return 1;
5126 }
5127 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
5128 }
5129 if (aMapOfArgs.Find ("zcolor", aValues))
5130 {
5131 if (!GetColor (aValues->Value(1), aColor))
5132 {
23fe70ec 5133 Message::SendFail ("Syntax error: -zcolor wrong color name");
a79f67f8 5134 return 1;
5135 }
5136 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
5137 }
5138
5139 // TICKMARKS
5140 if (aMapOfArgs.Find ("xticks", aValues))
5141 {
536d98e2 5142 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5143 }
5144 if (aMapOfArgs.Find ("yticks", aValues))
5145 {
536d98e2 5146 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5147 }
5148 if (aMapOfArgs.Find ("zticks", aValues))
5149 {
536d98e2 5150 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5151 }
5152 if (aMapOfArgs.Find ("xticklength", aValues))
5153 {
536d98e2 5154 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5155 }
5156 if (aMapOfArgs.Find ("yticklength", aValues))
5157 {
536d98e2 5158 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5159 }
5160 if (aMapOfArgs.Find ("zticklength", aValues))
5161 {
536d98e2 5162 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5163 }
5164 if (aMapOfArgs.Find ("xdrawticks", aValues))
5165 {
536d98e2 5166 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5167 }
5168 if (aMapOfArgs.Find ("ydrawticks", aValues))
5169 {
536d98e2 5170 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5171 }
5172 if (aMapOfArgs.Find ("zdrawticks", aValues))
5173 {
536d98e2 5174 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5175 }
5176
5177 // VALUES
5178 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5179 {
536d98e2 5180 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5181 }
5182 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5183 {
536d98e2 5184 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5185 }
5186 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5187 {
536d98e2 5188 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5189 }
5190 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5191 {
5192 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5193 }
5194 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5195 {
5196 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5197 }
5198 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5199 {
5200 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5201 }
5202
5203 // ARROWS
5204 if (aMapOfArgs.Find ("arrowlength", aValues))
5205 {
536d98e2 5206 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5207 }
5208
5209 // FONTS
5210 if (aMapOfArgs.Find ("namefont", aValues))
5211 {
5212 aTrihedronData.SetNamesFont (aValues->Value(1));
5213 }
5214 if (aMapOfArgs.Find ("valuesfont", aValues))
5215 {
5216 aTrihedronData.SetValuesFont (aValues->Value(1));
5217 }
5218
536d98e2 5219 if (aMapOfArgs.Find ("drawgrid", aValues))
5220 {
5221 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5222 }
5223 if (aMapOfArgs.Find ("drawaxes", aValues))
5224 {
5225 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5226 }
5227
a79f67f8 5228 // The final step: display of erase trihedron
5229 if (toDisplay)
5230 {
5231 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5232 }
7fd59977 5233 else
a79f67f8 5234 {
5235 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5236 }
7fd59977 5237
5238 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5239 ViewerTest::CurrentView()->Redraw();
13a22457 5240
7fd59977 5241 return 0;
5242}
5243
3bffef55 5244//==============================================================================
5245//function : VTile
5246//purpose :
5247//==============================================================================
5248static int VTile (Draw_Interpretor& theDI,
5249 Standard_Integer theArgNb,
5250 const char** theArgVec)
5251{
5252 Handle(V3d_View) aView = ViewerTest::CurrentView();
5253 if (aView.IsNull())
5254 {
23fe70ec 5255 Message::SendFail ("Error: no active viewer");
3bffef55 5256 return 1;
5257 }
5258
5259 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5260 if (theArgNb < 2)
5261 {
5262 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5263 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5264 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5265 return 0;
5266 }
5267
5268 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5269 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5270 {
5271 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5272 anArg.LowerCase();
5273 if (anArg == "-lowerleft"
5274 || anArg == "-upperleft")
5275 {
5276 if (anArgIter + 3 < theArgNb)
5277 {
23fe70ec 5278 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5279 return 1;
5280 }
5281 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5282 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5283 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5284 }
5285 else if (anArg == "-total"
5286 || anArg == "-totalsize"
5287 || anArg == "-viewsize")
5288 {
5289 if (anArgIter + 3 < theArgNb)
5290 {
23fe70ec 5291 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5292 return 1;
5293 }
5294 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5295 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5296 if (aTile.TotalSize.x() < 1
5297 || aTile.TotalSize.y() < 1)
5298 {
23fe70ec 5299 Message::SendFail ("Error: total size is incorrect");
3bffef55 5300 return 1;
5301 }
5302 }
5303 else if (anArg == "-tilesize")
5304 {
5305 if (anArgIter + 3 < theArgNb)
5306 {
23fe70ec 5307 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
3bffef55 5308 return 1;
5309 }
5310
5311 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5312 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5313 if (aTile.TileSize.x() < 1
5314 || aTile.TileSize.y() < 1)
5315 {
23fe70ec 5316 Message::SendFail ("Error: tile size is incorrect");
3bffef55 5317 return 1;
5318 }
5319 }
5320 else if (anArg == "-unset")
5321 {
5322 aView->Camera()->SetTile (Graphic3d_CameraTile());
5323 aView->Redraw();
5324 return 0;
5325 }
5326 }
5327
5328 if (aTile.TileSize.x() < 1
5329 || aTile.TileSize.y() < 1)
5330 {
23fe70ec 5331 Message::SendFail ("Error: tile size is undefined");
3bffef55 5332 return 1;
5333 }
5334 else if (aTile.TotalSize.x() < 1
5335 || aTile.TotalSize.y() < 1)
5336 {
23fe70ec 5337 Message::SendFail ("Error: total size is undefined");
3bffef55 5338 return 1;
5339 }
5340
5341 aView->Camera()->SetTile (aTile);
5342 aView->Redraw();
5343 return 0;
5344}
5345
7c3ef2f7 5346//! Format ZLayer ID.
5347inline const char* formZLayerId (const Standard_Integer theLayerId)
5348{
5349 switch (theLayerId)
5350 {
5351 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5352 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5353 case Graphic3d_ZLayerId_Top: return "[TOP]";
5354 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5355 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5356 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5357 }
5358 return "";
5359}
5360
5361//! Print the ZLayer information.
5362inline void printZLayerInfo (Draw_Interpretor& theDI,
5363 const Graphic3d_ZLayerSettings& theLayer)
5364{
5365 if (!theLayer.Name().IsEmpty())
5366 {
5367 theDI << " Name: " << theLayer.Name() << "\n";
5368 }
5369 if (theLayer.IsImmediate())
5370 {
5371 theDI << " Immediate: TRUE\n";
5372 }
5373 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5374 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5375 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5376 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5377 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5378 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5379 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5380 {
5381 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5382 }
5383}
5384
59f45b7c 5385//==============================================================================
5386//function : VZLayer
5387//purpose : Test z layer operations for v3d viewer
5388//==============================================================================
7c3ef2f7 5389static int VZLayer (Draw_Interpretor& theDI,
5390 Standard_Integer theArgNb,
5391 const char** theArgVec)
59f45b7c 5392{
7c3ef2f7 5393 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5394 if (aContextAIS.IsNull())
5395 {
23fe70ec 5396 Message::SendFail ("Error: no active viewer");
59f45b7c 5397 return 1;
5398 }
5399
5400 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5401 if (theArgNb < 2)
59f45b7c 5402 {
7c3ef2f7 5403 TColStd_SequenceOfInteger aLayers;
5404 aViewer->GetAllZLayers (aLayers);
5405 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5406 {
5407 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5408 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5409 printZLayerInfo (theDI, aSettings);
5410 }
59f45b7c 5411 return 1;
5412 }
5413
7c3ef2f7 5414 Standard_Integer anArgIter = 1;
5415 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5416 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5417 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5418 {
7c3ef2f7 5419 ++anArgIter;
5420 }
59f45b7c 5421
7c3ef2f7 5422 {
55c8f0f7
BB
5423 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5424 if (aFirstArg.IsIntegerValue())
c5751993 5425 {
7c3ef2f7 5426 ++anArgIter;
55c8f0f7 5427 aLayerId = aFirstArg.IntegerValue();
c5751993 5428 }
7c3ef2f7 5429 else
c5751993 5430 {
55c8f0f7 5431 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5432 {
55c8f0f7 5433 ++anArgIter;
7c3ef2f7 5434 }
c5751993 5435 }
7c3ef2f7 5436 }
c5751993 5437
1c728f2d 5438 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
7c3ef2f7 5439 for (; anArgIter < theArgNb; ++anArgIter)
5440 {
5441 // perform operation
5442 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5443 anArg.LowerCase();
5444 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5445 {
7c3ef2f7 5446 //
c5751993 5447 }
7c3ef2f7 5448 else if (anArg == "-add"
5449 || anArg == "add")
c5751993 5450 {
7c3ef2f7 5451 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5452 if (!aViewer->AddZLayer (aLayerId))
5453 {
23fe70ec 5454 Message::SendFail ("Error: can not add a new z layer");
7c3ef2f7 5455 return 0;
5456 }
5457
5458 theDI << aLayerId;
c5751993 5459 }
1c728f2d 5460 else if (anArg == "-insertbefore"
5461 && anArgIter + 1 < theArgNb
5462 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5463 {
5464 ++anArgIter;
5465 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5466 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5467 {
23fe70ec 5468 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5469 return 0;
5470 }
5471
5472 theDI << aLayerId;
5473 }
5474 else if (anArg == "-insertafter"
5475 && anArgIter + 1 < theArgNb
5476 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
5477 {
5478 ++anArgIter;
5479 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5480 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
5481 {
23fe70ec 5482 Message::SendFail ("Error: can not add a new z layer");
1c728f2d 5483 return 0;
5484 }
5485
5486 theDI << aLayerId;
5487 }
7c3ef2f7 5488 else if (anArg == "-del"
5489 || anArg == "-delete"
5490 || anArg == "del")
c5751993 5491 {
7c3ef2f7 5492 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5493 {
5494 if (++anArgIter >= theArgNb)
5495 {
23fe70ec 5496 Message::SendFail ("Syntax error: id of z layer to remove is missing");
7c3ef2f7 5497 return 1;
5498 }
5499
5500 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5501 }
5502
5503 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5504 || aLayerId == Graphic3d_ZLayerId_Default
5505 || aLayerId == Graphic3d_ZLayerId_Top
5506 || aLayerId == Graphic3d_ZLayerId_Topmost
5507 || aLayerId == Graphic3d_ZLayerId_TopOSD
5508 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5509 {
23fe70ec 5510 Message::SendFail ("Syntax error: standard Z layer can not be removed");
7c3ef2f7 5511 return 1;
5512 }
5513
5514 // move all object displayed in removing layer to default layer
5515 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5516 anObjIter.More(); anObjIter.Next())
5517 {
8f521168 5518 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5519 if (aPrs.IsNull()
5520 || aPrs->ZLayer() != aLayerId)
5521 {
5522 continue;
5523 }
5524 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5525 }
5526
5527 if (!aViewer->RemoveZLayer (aLayerId))
5528 {
23fe70ec 5529 Message::SendFail ("Z layer can not be removed");
7c3ef2f7 5530 }
5531 else
5532 {
5533 theDI << aLayerId << " ";
5534 }
c5751993 5535 }
7c3ef2f7 5536 else if (anArg == "-get"
5537 || anArg == "get")
c5751993 5538 {
7c3ef2f7 5539 TColStd_SequenceOfInteger aLayers;
5540 aViewer->GetAllZLayers (aLayers);
5541 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5542 {
5543 theDI << aLayeriter.Value() << " ";
5544 }
5545
5546 theDI << "\n";
c5751993 5547 }
7c3ef2f7 5548 else if (anArg == "-name")
c5751993 5549 {
7c3ef2f7 5550 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5551 {
23fe70ec 5552 Message::SendFail ("Syntax error: id of Z layer is missing");
c5751993 5553 return 1;
5554 }
5555
7c3ef2f7 5556 if (++anArgIter >= theArgNb)
5557 {
23fe70ec 5558 Message::SendFail ("Syntax error: name is missing");
7c3ef2f7 5559 return 1;
5560 }
c5751993 5561
7c3ef2f7 5562 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5563 aSettings.SetName (theArgVec[anArgIter]);
5564 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5565 }
7c3ef2f7 5566 else if (anArg == "-origin")
c5751993 5567 {
7c3ef2f7 5568 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5569 {
23fe70ec 5570 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5571 return 1;
5572 }
5573
5574 if (anArgIter + 2 >= theArgNb)
5575 {
23fe70ec 5576 Message::SendFail ("Syntax error: origin coordinates are missing");
7c3ef2f7 5577 return 1;
5578 }
5579
5580 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5581 gp_XYZ anOrigin;
5582 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5583 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5584 anOrigin.SetZ (0.0);
5585 if (anArgIter + 3 < theArgNb)
5586 {
5587 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5588 anArgIter += 3;
5589 }
5590 else
5591 {
5592 anArgIter += 2;
5593 }
5594 aSettings.SetOrigin (anOrigin);
5595 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5596 }
4ecf34cc 5597 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5598 && anArgIter + 1 < theArgNb
5599 && (anArg == "-cullingdistance"
5600 || anArg == "-cullingdist"
5601 || anArg == "-culldistance"
5602 || anArg == "-culldist"
5603 || anArg == "-distcull"
5604 || anArg == "-distculling"
5605 || anArg == "-distanceculling"))
5606 {
5607 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5608 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5609 aSettings.SetCullingDistance (aDist);
5610 aViewer->SetZLayerSettings (aLayerId, aSettings);
5611 }
5612 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5613 && anArgIter + 1 < theArgNb
5614 && (anArg == "-cullingsize"
5615 || anArg == "-cullsize"
5616 || anArg == "-sizecull"
5617 || anArg == "-sizeculling"))
5618 {
5619 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5620 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5621 aSettings.SetCullingSize (aSize);
5622 aViewer->SetZLayerSettings (aLayerId, aSettings);
5623 }
7c3ef2f7 5624 else if (anArg == "-settings"
5625 || anArg == "settings")
c5751993 5626 {
7c3ef2f7 5627 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5628 {
5629 if (++anArgIter >= theArgNb)
5630 {
23fe70ec 5631 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5632 return 1;
5633 }
5634
5635 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5636 }
5637
5638 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5639 printZLayerInfo (theDI, aSettings);
c5751993 5640 }
7c3ef2f7 5641 else if (anArg == "-enable"
5642 || anArg == "enable"
5643 || anArg == "-disable"
5644 || anArg == "disable")
83da37b1 5645 {
7c3ef2f7 5646 const Standard_Boolean toEnable = anArg == "-enable"
5647 || anArg == "enable";
5648 if (++anArgIter >= theArgNb)
5649 {
23fe70ec 5650 Message::SendFail ("Syntax error: option name is missing");
7c3ef2f7 5651 return 1;
5652 }
c5751993 5653
7c3ef2f7 5654 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5655 aSubOp.LowerCase();
5656 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5657 {
5658 if (++anArgIter >= theArgNb)
5659 {
23fe70ec 5660 Message::SendFail ("Syntax error: id of Z layer is missing");
7c3ef2f7 5661 return 1;
5662 }
c5751993 5663
7c3ef2f7 5664 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5665 }
c5751993 5666
7c3ef2f7 5667 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5668 if (aSubOp == "depthtest"
5669 || aSubOp == "test")
5670 {
5671 aSettings.SetEnableDepthTest (toEnable);
5672 }
5673 else if (aSubOp == "depthwrite"
5674 || aSubOp == "write")
5675 {
5676 aSettings.SetEnableDepthWrite (toEnable);
5677 }
5678 else if (aSubOp == "depthclear"
5679 || aSubOp == "clear")
5680 {
5681 aSettings.SetClearDepth (toEnable);
5682 }
5683 else if (aSubOp == "depthoffset"
5684 || aSubOp == "offset")
5685 {
5686 Graphic3d_PolygonOffset aParams;
5687 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
5688 if (toEnable)
5689 {
5690 if (anArgIter + 2 >= theArgNb)
5691 {
23fe70ec 5692 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
7c3ef2f7 5693 return 1;
5694 }
c5751993 5695
7c3ef2f7 5696 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5697 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
5698 }
5699 aSettings.SetPolygonOffset (aParams);
5700 }
5701 else if (aSubOp == "positiveoffset"
5702 || aSubOp == "poffset")
5703 {
5704 if (toEnable)
5705 {
5706 aSettings.SetDepthOffsetPositive();
5707 }
5708 else
5709 {
5710 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
5711 }
5712 }
5713 else if (aSubOp == "negativeoffset"
5714 || aSubOp == "noffset")
5715 {
5716 if (toEnable)
5717 {
5718 aSettings.SetDepthOffsetNegative();
5719 }
5720 else
5721 {
5722 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
5723 }
5724 }
5725 else if (aSubOp == "textureenv")
5726 {
5727 aSettings.SetEnvironmentTexture (toEnable);
5728 }
1c728f2d 5729 else if (aSubOp == "raytracing")
5730 {
5731 aSettings.SetRaytracable (toEnable);
5732 }
7c3ef2f7 5733
5734 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5735 }
7c3ef2f7 5736 else
83da37b1 5737 {
23fe70ec 5738 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
7c3ef2f7 5739 return 1;
83da37b1 5740 }
59f45b7c 5741 }
5742
5743 return 0;
5744}
5745
c357e426 5746// The interactive presentation of 2d layer item
5747// for "vlayerline" command it provides a presentation of
5748// line with user-defined linewidth, linetype and transparency.
61b0191c 5749class V3d_LineItem : public AIS_InteractiveObject
20637bd2 5750{
5751public:
5752 // CASCADE RTTI
92efcf78 5753 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 5754
20637bd2 5755 // constructor
5756 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5757 Standard_Real X2, Standard_Real Y2,
20637bd2 5758 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5759 Standard_Real theWidth = 0.5,
5760 Standard_Real theTransp = 1.0);
5761
61b0191c 5762 private:
5763
5764 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
5765 const Handle(Prs3d_Presentation)& thePresentation,
79104795 5766 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 5767
5768 void ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/,
79104795 5769 const Standard_Integer /*aMode*/) Standard_OVERRIDE
5770 {}
20637bd2 5771
5772private:
5773
5774 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 5775 Aspect_TypeOfLine myType;
20637bd2 5776 Standard_Real myWidth;
20637bd2 5777};
5778
20637bd2 5779// default constructor for line item
4fe56619 5780V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 5781 Standard_Real X2, Standard_Real Y2,
20637bd2 5782 Aspect_TypeOfLine theType,
5783 Standard_Real theWidth,
5784 Standard_Real theTransp) :
61b0191c 5785 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5786 myType(theType), myWidth(theWidth)
20637bd2 5787{
61b0191c 5788 SetTransparency (1-theTransp);
20637bd2 5789}
5790
5791// render line
61b0191c 5792void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
5793 const Handle(Prs3d_Presentation)& thePresentation,
5794 const Standard_Integer /*theMode*/)
20637bd2 5795{
61b0191c 5796 thePresentation->Clear();
ba00aab7 5797 Quantity_Color aColor (Quantity_NOC_RED);
61b0191c 5798 Standard_Integer aWidth, aHeight;
5799 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
d6c48921 5800 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
61b0191c 5801 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5802 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5803 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5804 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5805 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5806 aGroup->AddPrimitiveArray (aPrim);
20637bd2 5807}
5808
5809//=============================================================================
5810//function : VLayerLine
5811//purpose : Draws line in the v3d view layer with given attributes: linetype,
5812// : linewidth, transparency coefficient
5813//============================================================================
5814static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5815{
5816 // get the active view
5817 Handle(V3d_View) aView = ViewerTest::CurrentView();
5818 if (aView.IsNull())
5819 {
5820 di << "Call vinit before!\n";
5821 return 1;
5822 }
5823 else if (argc < 5)
5824 {
5825 di << "Use: " << argv[0];
5826 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5827 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5828 di << " 0 - solid \n";
5829 di << " 1 - dashed \n";
5830 di << " 2 - dot \n";
5831 di << " 3 - dashdot\n";
5832 di << " transparency : { 0.0 - 1.0 } \n";
5833 di << " 0.0 - transparent\n";
5834 di << " 1.0 - visible \n";
5835 return 1;
5836 }
5837
61b0191c 5838 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 5839 // get the input params
91322f44 5840 Standard_Real X1 = Draw::Atof(argv[1]);
5841 Standard_Real Y1 = Draw::Atof(argv[2]);
5842 Standard_Real X2 = Draw::Atof(argv[3]);
5843 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 5844
3a4a3962 5845 Standard_Real aWidth = 0.5;
5846 Standard_Real aTransparency = 1.0;
20637bd2 5847
5848 // has width
5849 if (argc > 5)
91322f44 5850 aWidth = Draw::Atof(argv[5]);
20637bd2 5851
3a4a3962 5852 // select appropriate line type
5853 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5854 if (argc > 6
5855 && !ViewerTest::ParseLineType (argv[6], aLineType))
5856 {
23fe70ec 5857 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
3a4a3962 5858 return 1;
5859 }
20637bd2 5860
5861 // has transparency
5862 if (argc > 7)
5863 {
91322f44 5864 aTransparency = Draw::Atof(argv[7]);
4fe56619 5865 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 5866 aTransparency = 1.0;
5867 }
5868
61b0191c 5869 static Handle (V3d_LineItem) aLine;
5870 if (!aLine.IsNull())
25289ec1 5871 {
0577ae8c 5872 aContext->Erase (aLine, Standard_False);
25289ec1 5873 }
61b0191c 5874 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5875 aLineType, aWidth,
5876 aTransparency);
25289ec1 5877
778cd667 5878 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 5879 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5880 aLine->SetToUpdate();
5881 aContext->Display (aLine, Standard_True);
25289ec1 5882
5883 return 0;
5884}
5885
61b0191c 5886
2bd4c032 5887//==============================================================================
5888//function : VGrid
5889//purpose :
5890//==============================================================================
5891
35e08fe8 5892static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 5893 Standard_Integer theArgNb,
5894 const char** theArgVec)
5895{
2bd4c032 5896 Handle(V3d_View) aView = ViewerTest::CurrentView();
5897 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5898 if (aView.IsNull() || aViewer.IsNull())
5899 {
23fe70ec 5900 Message::SendFail ("Error: no active viewer");
2bd4c032 5901 return 1;
5902 }
5903
5904 Aspect_GridType aType = aViewer->GridType();
5905 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 5906 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5907 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5908 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 5909 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 5910 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 5911 {
79931835 5912 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5913 anArg.LowerCase();
5914 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 5915 {
5916 continue;
5917 }
79931835 5918 else if (anArgIter + 1 < theArgNb
5919 && anArg == "-type")
5920 {
5921 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5922 anArgNext.LowerCase();
5923 if (anArgNext == "r"
5924 || anArgNext == "rect"
5925 || anArgNext == "rectangular")
5926 {
5927 aType = Aspect_GT_Rectangular;
5928 }
5929 else if (anArgNext == "c"
5930 || anArgNext == "circ"
5931 || anArgNext == "circular")
5932 {
5933 aType = Aspect_GT_Circular;
5934 }
5935 else
5936 {
23fe70ec 5937 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5938 return 1;
5939 }
5940 }
5941 else if (anArgIter + 1 < theArgNb
5942 && anArg == "-mode")
5943 {
5944 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5945 anArgNext.LowerCase();
5946 if (anArgNext == "l"
5947 || anArgNext == "line"
5948 || anArgNext == "lines")
5949 {
5950 aMode = Aspect_GDM_Lines;
5951 }
5952 else if (anArgNext == "p"
5953 || anArgNext == "point"
5954 || anArgNext == "points")
5955 {
5956 aMode = Aspect_GDM_Points;
5957 }
5958 else
5959 {
23fe70ec 5960 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
79931835 5961 return 1;
5962 }
5963 }
5964 else if (anArgIter + 2 < theArgNb
5965 && (anArg == "-origin"
5966 || anArg == "-orig"))
5967 {
5968 hasOrigin = true;
5969 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5970 Draw::Atof (theArgVec[anArgIter + 2]));
5971 anArgIter += 2;
5972 }
5973 else if (anArgIter + 2 < theArgNb
5974 && anArg == "-step")
5975 {
5976 hasStep = true;
5977 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5978 Draw::Atof (theArgVec[anArgIter + 2]));
5979 if (aNewStepXY.x() <= 0.0
5980 || aNewStepXY.y() <= 0.0)
5981 {
23fe70ec 5982 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 5983 return 1;
5984 }
5985 anArgIter += 2;
5986 }
5987 else if (anArgIter + 1 < theArgNb
5988 && (anArg == "-angle"
5989 || anArg == "-rotangle"
5990 || anArg == "-rotationangle"))
5991 {
5992 hasRotAngle = true;
5993 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5994 }
5995 else if (anArgIter + 1 < theArgNb
5996 && (anArg == "-zoffset"
5997 || anArg == "-dz"))
5998 {
5999 hasZOffset = true;
6000 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
6001 }
6002 else if (anArgIter + 1 < theArgNb
6003 && anArg == "-radius")
6004 {
6005 hasSize = true;
6006 ++anArgIter;
6007 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
6008 if (aNewStepXY.x() <= 0.0)
6009 {
23fe70ec 6010 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
79931835 6011 return 1;
6012 }
6013 }
6014 else if (anArgIter + 2 < theArgNb
6015 && anArg == "-size")
6016 {
6017 hasSize = true;
6018 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6019 Draw::Atof (theArgVec[anArgIter + 2]));
6020 if (aNewStepXY.x() <= 0.0
6021 || aNewStepXY.y() <= 0.0)
6022 {
23fe70ec 6023 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
79931835 6024 return 1;
6025 }
6026 anArgIter += 2;
6027 }
6028 else if (anArg == "r"
6029 || anArg == "rect"
6030 || anArg == "rectangular")
2bd4c032 6031 {
6032 aType = Aspect_GT_Rectangular;
6033 }
79931835 6034 else if (anArg == "c"
6035 || anArg == "circ"
6036 || anArg == "circular")
2bd4c032 6037 {
6038 aType = Aspect_GT_Circular;
6039 }
79931835 6040 else if (anArg == "l"
6041 || anArg == "line"
6042 || anArg == "lines")
2bd4c032 6043 {
6044 aMode = Aspect_GDM_Lines;
6045 }
79931835 6046 else if (anArg == "p"
6047 || anArg == "point"
6048 || anArg == "points")
2bd4c032 6049 {
6050 aMode = Aspect_GDM_Points;
6051 }
79931835 6052 else if (anArgIter + 1 >= theArgNb
6053 && anArg == "off")
2bd4c032 6054 {
6055 aViewer->DeactivateGrid();
6056 return 0;
6057 }
6058 else
6059 {
23fe70ec 6060 Message::SendFail() << "Syntax error at '" << anArg << "'";
79931835 6061 return 1;
2bd4c032 6062 }
6063 }
6064
2bd4c032 6065 if (aType == Aspect_GT_Rectangular)
6066 {
79931835 6067 Graphic3d_Vec2d anOrigXY, aStepXY;
6068 Standard_Real aRotAngle = 0.0;
6069 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6070 if (hasOrigin)
6071 {
6072 anOrigXY = aNewOriginXY;
6073 }
6074 if (hasStep)
6075 {
6076 aStepXY = aNewStepXY;
6077 }
6078 if (hasRotAngle)
6079 {
6080 aRotAngle = aNewRotAngle;
6081 }
6082 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6083 if (hasSize || hasZOffset)
2bd4c032 6084 {
79931835 6085 Graphic3d_Vec3d aSize;
6086 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6087 if (hasSize)
6088 {
6089 aSize.x() = aNewSizeXY.x();
6090 aSize.y() = aNewSizeXY.y();
6091 }
6092 if (hasZOffset)
6093 {
6094 aSize.z() = aNewZOffset;
6095 }
6096 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 6097 }
2bd4c032 6098 }
6099 else if (aType == Aspect_GT_Circular)
6100 {
79931835 6101 Graphic3d_Vec2d anOrigXY;
ee2be2a8 6102 Standard_Real aRadiusStep;
2bd4c032 6103 Standard_Integer aDivisionNumber;
79931835 6104 Standard_Real aRotAngle = 0.0;
6105 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6106 if (hasOrigin)
6107 {
6108 anOrigXY = aNewOriginXY;
6109 }
6110 if (hasStep)
6111 {
6112 aRadiusStep = aNewStepXY[0];
6113 aDivisionNumber = (int )aNewStepXY[1];
6114 if (aDivisionNumber < 1)
6115 {
23fe70ec 6116 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
79931835 6117 return 1;
6118 }
6119 }
6120 if (hasRotAngle)
2bd4c032 6121 {
79931835 6122 aRotAngle = aNewRotAngle;
2bd4c032 6123 }
6124
79931835 6125 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6126 if (hasSize || hasZOffset)
6127 {
6128 Standard_Real aRadius = 0.0, aZOffset = 0.0;
6129 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
6130 if (hasSize)
6131 {
6132 aRadius = aNewSizeXY.x();
6133 if (aNewSizeXY.y() != 0.0)
6134 {
23fe70ec 6135 Message::SendFail ("Syntax error: circular size should be specified as radius");
79931835 6136 return 1;
6137 }
6138 }
6139 if (hasZOffset)
6140 {
6141 aZOffset = aNewZOffset;
6142 }
6143 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6144 }
2bd4c032 6145 }
79931835 6146 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6147 return 0;
6148}
6149
c40b7d58 6150//==============================================================================
6151//function : VPriviledgedPlane
6152//purpose :
6153//==============================================================================
6154
6155static int VPriviledgedPlane (Draw_Interpretor& theDI,
6156 Standard_Integer theArgNb,
6157 const char** theArgVec)
6158{
6159 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6160 {
23fe70ec 6161 Message::SendFail ("Error: wrong number of arguments! See usage:");
c40b7d58 6162 theDI.PrintHelp (theArgVec[0]);
6163 return 1;
6164 }
6165
6166 // get the active viewer
6167 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6168 if (aViewer.IsNull())
6169 {
23fe70ec 6170 Message::SendFail ("Error: no active viewer");
c40b7d58 6171 return 1;
6172 }
6173
6174 if (theArgNb == 1)
6175 {
6176 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6177 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6178 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6179 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6180 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6181 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6182 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6183 return 0;
6184 }
6185
6186 Standard_Integer anArgIdx = 1;
6187 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6188 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6189 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6190 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6191 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6192 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6193
6194 gp_Ax3 aPriviledgedPlane;
6195 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6196 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6197 if (theArgNb > 7)
6198 {
6199 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6200 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6201 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6202 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6203 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6204 }
6205 else
6206 {
6207 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6208 }
6209
6210 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6211
6212 return 0;
6213}
6214
f25b82d6 6215//==============================================================================
6216//function : VConvert
6217//purpose :
6218//==============================================================================
6219
6220static int VConvert (Draw_Interpretor& theDI,
6221 Standard_Integer theArgNb,
6222 const char** theArgVec)
6223{
6224 // get the active view
6225 Handle(V3d_View) aView = ViewerTest::CurrentView();
6226 if (aView.IsNull())
6227 {
23fe70ec 6228 Message::SendFail ("Error: no active viewer");
f25b82d6 6229 return 1;
6230 }
6231
6232 enum { Model, Ray, View, Window, Grid } aMode = Model;
6233
6234 // access coordinate arguments
6235 TColStd_SequenceOfReal aCoord;
6236 Standard_Integer anArgIdx = 1;
6237 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6238 {
6239 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6240 if (!anArg.IsRealValue())
6241 {
6242 break;
6243 }
6244 aCoord.Append (anArg.RealValue());
6245 }
6246
6247 // non-numeric argument too early
6248 if (aCoord.IsEmpty())
6249 {
23fe70ec 6250 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6251 theDI.PrintHelp (theArgVec[0]);
6252 return 1;
6253 }
6254
6255 // collect all other arguments and options
6256 for (; anArgIdx < theArgNb; ++anArgIdx)
6257 {
6258 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6259 anArg.LowerCase();
6260 if (anArg == "window") aMode = Window;
6261 else if (anArg == "view") aMode = View;
6262 else if (anArg == "grid") aMode = Grid;
6263 else if (anArg == "ray") aMode = Ray;
6264 else
6265 {
23fe70ec 6266 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
f25b82d6 6267 theDI.PrintHelp (theArgVec[0]);
6268 return 1;
6269 }
6270 }
6271
6272 // complete input checks
6273 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6274 (aCoord.Length() == 2 && theArgNb > 4) ||
6275 (aCoord.Length() == 3 && theArgNb > 5))
6276 {
23fe70ec 6277 Message::SendFail ("Error: wrong number of arguments! See usage:");
f25b82d6 6278 theDI.PrintHelp (theArgVec[0]);
6279 return 1;
6280 }
6281
6282 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6283 Standard_Integer aXYp[2] = {0, 0};
6284
6285 // convert one-dimensional coordinate
6286 if (aCoord.Length() == 1)
6287 {
6288 switch (aMode)
6289 {
ee2be2a8 6290 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6291 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6292 default:
23fe70ec 6293 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6294 theDI.PrintHelp (theArgVec[0]);
6295 return 1;
6296 }
6297 }
6298
6299 // convert 2D coordinates from projection or view reference space
6300 if (aCoord.Length() == 2)
6301 {
6302 switch (aMode)
6303 {
6304 case Model :
6305 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6306 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6307 return 0;
6308
6309 case View :
6310 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6311 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6312 return 0;
6313
6314 case Window :
ee2be2a8 6315 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6316 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6317 return 0;
6318
6319 case Grid :
6320 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6321 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6322 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6323 return 0;
6324
6325 case Ray :
6326 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6327 (Standard_Integer) aCoord (2),
6328 aXYZ[0], aXYZ[1], aXYZ[2],
6329 aXYZ[3], aXYZ[4], aXYZ[5]);
6330 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6331 return 0;
6332
6333 default:
23fe70ec 6334 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6335 theDI.PrintHelp (theArgVec[0]);
6336 return 1;
6337 }
6338 }
6339
6340 // convert 3D coordinates from view reference space
6341 else if (aCoord.Length() == 3)
6342 {
6343 switch (aMode)
6344 {
6345 case Window :
6346 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6347 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6348 return 0;
6349
6350 case Grid :
6351 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6352 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6353 return 0;
6354
6355 default:
23fe70ec 6356 Message::SendFail ("Error: wrong arguments! See usage:");
f25b82d6 6357 theDI.PrintHelp (theArgVec[0]);
6358 return 1;
6359 }
6360 }
6361
6362 return 0;
6363}
6364
208e6839 6365//==============================================================================
6366//function : VFps
6367//purpose :
6368//==============================================================================
6369
6370static int VFps (Draw_Interpretor& theDI,
6371 Standard_Integer theArgNb,
6372 const char** theArgVec)
6373{
6374 // get the active view
6375 Handle(V3d_View) aView = ViewerTest::CurrentView();
6376 if (aView.IsNull())
6377 {
23fe70ec 6378 Message::SendFail ("Error: no active viewer");
208e6839 6379 return 1;
6380 }
6381
e084dbbc 6382 Standard_Integer aFramesNb = -1;
6383 Standard_Real aDuration = -1.0;
6384 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6385 {
e084dbbc 6386 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6387 anArg.LowerCase();
6388 if (aDuration < 0.0
6389 && anArgIter + 1 < theArgNb
6390 && (anArg == "-duration"
6391 || anArg == "-dur"
6392 || anArg == "-time"))
6393 {
6394 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6395 }
6396 else if (aFramesNb < 0
6397 && anArg.IsIntegerValue())
6398 {
6399 aFramesNb = anArg.IntegerValue();
6400 if (aFramesNb <= 0)
6401 {
23fe70ec 6402 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6403 return 1;
6404 }
6405 }
6406 else
6407 {
23fe70ec 6408 Message::SendFail() << "Syntax error at '" << anArg << "'";
e084dbbc 6409 return 1;
6410 }
6411 }
6412 if (aFramesNb < 0 && aDuration < 0.0)
6413 {
6414 aFramesNb = 100;
208e6839 6415 }
6416
6417 // the time is meaningless for first call
6418 // due to async OpenGl rendering
6419 aView->Redraw();
6420
6421 // redraw view in loop to estimate average values
6422 OSD_Timer aTimer;
6423 aTimer.Start();
e084dbbc 6424 Standard_Integer aFrameIter = 1;
6425 for (;; ++aFrameIter)
208e6839 6426 {
6427 aView->Redraw();
e084dbbc 6428 if ((aFramesNb > 0
6429 && aFrameIter >= aFramesNb)
6430 || (aDuration > 0.0
6431 && aTimer.ElapsedTime() >= aDuration))
6432 {
6433 break;
6434 }
208e6839 6435 }
6436 aTimer.Stop();
6437 Standard_Real aCpu;
6438 const Standard_Real aTime = aTimer.ElapsedTime();
6439 aTimer.OSD_Chronometer::Show (aCpu);
6440
e084dbbc 6441 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6442 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6443
6444 // return statistics
6445 theDI << "FPS: " << aFpsAver << "\n"
6446 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6447
8c820969 6448 // compute additional statistics in ray-tracing mode
e084dbbc 6449 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6450 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6451 {
e084dbbc 6452 Graphic3d_Vec2i aWinSize (0, 0);
6453 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6454
6455 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6456 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6457 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6458 }
6459
208e6839 6460 return 0;
6461}
6462
84e84755 6463//! Auxiliary function for parsing glsl dump level argument.
6464static Standard_Boolean parseGlslSourceFlag (Standard_CString theArg,
6465 OpenGl_ShaderProgramDumpLevel& theGlslDumpLevel)
6466{
6467 TCollection_AsciiString aTypeStr (theArg);
6468 aTypeStr.LowerCase();
6469 if (aTypeStr == "off"
6470 || aTypeStr == "0")
6471 {
6472 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6473 }
6474 else if (aTypeStr == "short")
6475 {
6476 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Short;
6477 }
6478 else if (aTypeStr == "full"
6479 || aTypeStr == "1")
6480 {
6481 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6482 }
6483 else
6484 {
6485 return Standard_False;
6486 }
6487 return Standard_True;
6488}
6489
58655684 6490//==============================================================================
6491//function : VGlDebug
6492//purpose :
6493//==============================================================================
6494
6495static int VGlDebug (Draw_Interpretor& theDI,
6496 Standard_Integer theArgNb,
6497 const char** theArgVec)
6498{
aaf512f1 6499 Handle(OpenGl_GraphicDriver) aDriver;
6500 Handle(V3d_View) aView = ViewerTest::CurrentView();
6501 if (!aView.IsNull())
6502 {
6503 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
6504 }
c87535af 6505 OpenGl_Caps* aDefCaps = &ViewerTest_myDefaultCaps;
6506 OpenGl_Caps* aCaps = !aDriver.IsNull() ? &aDriver->ChangeOptions() : NULL;
6507
58655684 6508 if (theArgNb < 2)
6509 {
c87535af 6510 TCollection_AsciiString aDebActive, aSyncActive;
6511 if (aCaps == NULL)
58655684 6512 {
c87535af 6513 aCaps = aDefCaps;
6514 }
6515 else
6516 {
6517 Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )::glGetString (GL_EXTENSIONS),
6518 "GL_ARB_debug_output");
6519 aDebActive = isActive ? " (active)" : " (inactive)";
6520 if (isActive)
6521 {
6522 // GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
6523 aSyncActive = ::glIsEnabled (0x8242) == GL_TRUE ? " (active)" : " (inactive)";
6524 }
58655684 6525 }
6526
84e84755 6527 TCollection_AsciiString aGlslCodeDebugStatus = TCollection_AsciiString()
6528 + "glslSourceCode: "
6529 + (aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Off
6530 ? "Off"
6531 : aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short
6532 ? "Short"
6533 : "Full")
6534 + "\n";
6535 theDI << "debug: " << (aCaps->contextDebug ? "1" : "0") << aDebActive << "\n"
6536 << "sync: " << (aCaps->contextSyncDebug ? "1" : "0") << aSyncActive << "\n"
6537 << "glslWarn: " << (aCaps->glslWarnings ? "1" : "0") << "\n"
6538 << aGlslCodeDebugStatus
6539 << "extraMsg: " << (aCaps->suppressExtraMsg ? "0" : "1") << "\n";
58655684 6540 return 0;
6541 }
6542
c87535af 6543 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
aaf512f1 6544 {
c87535af 6545 Standard_CString anArg = theArgVec[anArgIter];
6546 TCollection_AsciiString anArgCase (anArg);
6547 anArgCase.LowerCase();
6548 Standard_Boolean toEnableDebug = Standard_True;
6549 if (anArgCase == "-glsl"
6550 || anArgCase == "-glslwarn"
6551 || anArgCase == "-glslwarns"
6552 || anArgCase == "-glslwarnings")
6553 {
6554 Standard_Boolean toShowWarns = Standard_True;
6555 if (++anArgIter < theArgNb
dae2a922 6556 && !Draw::ParseOnOff (theArgVec[anArgIter], toShowWarns))
c87535af 6557 {
6558 --anArgIter;
6559 }
6560 aDefCaps->glslWarnings = toShowWarns;
6561 if (aCaps != NULL)
6562 {
6563 aCaps->glslWarnings = toShowWarns;
6564 }
6565 }
6566 else if (anArgCase == "-extra"
6567 || anArgCase == "-extramsg"
6568 || anArgCase == "-extramessages")
6569 {
6570 Standard_Boolean toShow = Standard_True;
6571 if (++anArgIter < theArgNb
dae2a922 6572 && !Draw::ParseOnOff (theArgVec[anArgIter], toShow))
c87535af 6573 {
6574 --anArgIter;
6575 }
6576 aDefCaps->suppressExtraMsg = !toShow;
6577 if (aCaps != NULL)
6578 {
6579 aCaps->suppressExtraMsg = !toShow;
6580 }
6581 }
6582 else if (anArgCase == "-noextra"
6583 || anArgCase == "-noextramsg"
6584 || anArgCase == "-noextramessages")
6585 {
6586 Standard_Boolean toSuppress = Standard_True;
6587 if (++anArgIter < theArgNb
dae2a922 6588 && !Draw::ParseOnOff (theArgVec[anArgIter], toSuppress))
c87535af 6589 {
6590 --anArgIter;
6591 }
6592 aDefCaps->suppressExtraMsg = toSuppress;
6593 if (aCaps != NULL)
6594 {
6595 aCaps->suppressExtraMsg = toSuppress;
6596 }
6597 }
6598 else if (anArgCase == "-sync")
6599 {
6600 Standard_Boolean toSync = Standard_True;
6601 if (++anArgIter < theArgNb
dae2a922 6602 && !Draw::ParseOnOff (theArgVec[anArgIter], toSync))
c87535af 6603 {
6604 --anArgIter;
6605 }
6606 aDefCaps->contextSyncDebug = toSync;
6607 if (toSync)
6608 {
6609 aDefCaps->contextDebug = Standard_True;
6610 }
6611 }
84e84755 6612 else if (anArgCase == "-glslsourcecode"
6613 || anArgCase == "-glslcode")
6614 {
6615 OpenGl_ShaderProgramDumpLevel aGslsDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6616 if (++anArgIter < theArgNb
6617 && !parseGlslSourceFlag (theArgVec[anArgIter], aGslsDumpLevel))
6618 {
6619 --anArgIter;
6620 }
6621 aDefCaps->glslDumpLevel = aGslsDumpLevel;
6622 if (aCaps != NULL)
6623 {
6624 aCaps->glslDumpLevel = aGslsDumpLevel;
6625 }
6626 }
c87535af 6627 else if (anArgCase == "-debug")
6628 {
6629 if (++anArgIter < theArgNb
dae2a922 6630 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnableDebug))
c87535af 6631 {
6632 --anArgIter;
6633 }
6634 aDefCaps->contextDebug = toEnableDebug;
6635 }
dae2a922 6636 else if (Draw::ParseOnOff (anArg, toEnableDebug)
c87535af 6637 && (anArgIter + 1 == theArgNb))
6638 {
6639 // simple alias to turn on almost everything
6640 aDefCaps->contextDebug = toEnableDebug;
6641 aDefCaps->contextSyncDebug = toEnableDebug;
6642 aDefCaps->glslWarnings = toEnableDebug;
3b4c6945 6643 if (!toEnableDebug)
6644 {
6645 aDefCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6646 }
84e84755 6647 aDefCaps->suppressExtraMsg = !toEnableDebug;
6648 if (aCaps != NULL)
6649 {
6650 aCaps->contextDebug = toEnableDebug;
6651 aCaps->contextSyncDebug = toEnableDebug;
6652 aCaps->glslWarnings = toEnableDebug;
3b4c6945 6653 if (!toEnableDebug)
6654 {
6655 aCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6656 }
84e84755 6657 aCaps->suppressExtraMsg = !toEnableDebug;
6658 }
c87535af 6659 }
6660 else
6661 {
23fe70ec 6662 Message::SendFail() << "Syntax error at '" << anArg << "'";
c87535af 6663 return 1;
6664 }
aaf512f1 6665 }
6666
58655684 6667 return 0;
6668}
208e6839 6669
6670//==============================================================================
6671//function : VVbo
6672//purpose :
6673//==============================================================================
6674
58655684 6675static int VVbo (Draw_Interpretor& theDI,
208e6839 6676 Standard_Integer theArgNb,
6677 const char** theArgVec)
6678{
58655684 6679 const Standard_Boolean toSet = (theArgNb > 1);
6680 const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
6681 if (toSet)
208e6839 6682 {
58655684 6683 ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
208e6839 6684 }
6685
58655684 6686 // get the context
6687 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6688 if (aContextAIS.IsNull())
208e6839 6689 {
58655684 6690 if (!toSet)
6691 {
23fe70ec 6692 Message::SendFail ("Error: no active viewer");
58655684 6693 }
208e6839 6694 return 1;
6695 }
58655684 6696 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
6697 if (!aDriver.IsNull())
208e6839 6698 {
58655684 6699 if (!toSet)
6700 {
6701 theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
6702 }
6703 else
6704 {
6705 aDriver->ChangeOptions().vboDisable = toUseVbo;
6706 }
208e6839 6707 }
6708
208e6839 6709 return 0;
6710}
6711
a577aaab 6712//==============================================================================
6713//function : VCaps
6714//purpose :
6715//==============================================================================
6716
6717static int VCaps (Draw_Interpretor& theDI,
6718 Standard_Integer theArgNb,
6719 const char** theArgVec)
6720{
6721 OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
6722 Handle(OpenGl_GraphicDriver) aDriver;
8625ef7e 6723 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6724 if (!aContext.IsNull())
a577aaab 6725 {
8625ef7e 6726 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
a577aaab 6727 aCaps = &aDriver->ChangeOptions();
6728 }
6729
6730 if (theArgNb < 2)
6731 {
ba00aab7 6732 theDI << "sRGB: " << (aCaps->sRGBDisable ? "0" : "1") << "\n";
a577aaab 6733 theDI << "VBO: " << (aCaps->vboDisable ? "0" : "1") << "\n";
6734 theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
abe46077 6735 theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
8625ef7e 6736 theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
2a332745 6737 theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
f978241f 6738 theDI << "VSync: " << aCaps->swapInterval << "\n";
4e1523ef 6739 theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
f978241f 6740 theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
56689b27 6741 theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n";
59515ca6 6742 theDI << "NoExt:" << (aCaps->contextNoExtensions ? "1" : "0") << "\n";
6743 theDI << "MaxVersion:" << aCaps->contextMajorVersionUpper << "." << aCaps->contextMinorVersionUpper << "\n";
faff3767 6744 theDI << "CompressTextures: " << (aCaps->compressedTexturesDisable ? "0" : "1") << "\n";
a577aaab 6745 return 0;
6746 }
6747
8625ef7e 6748 ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
a577aaab 6749 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
6750 {
8625ef7e 6751 Standard_CString anArg = theArgVec[anArgIter];
6752 TCollection_AsciiString anArgCase (anArg);
6753 anArgCase.LowerCase();
6754 if (anUpdateTool.parseRedrawMode (anArg))
6755 {
6756 continue;
6757 }
f978241f 6758 else if (anArgCase == "-vsync"
6759 || anArgCase == "-swapinterval")
6760 {
6761 Standard_Boolean toEnable = Standard_True;
6762 if (++anArgIter < theArgNb
dae2a922 6763 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 6764 {
6765 --anArgIter;
6766 }
6767 aCaps->swapInterval = toEnable;
6768 }
8625ef7e 6769 else if (anArgCase == "-ffp")
6770 {
6771 Standard_Boolean toEnable = Standard_True;
6772 if (++anArgIter < theArgNb
dae2a922 6773 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6774 {
6775 --anArgIter;
6776 }
6777 aCaps->ffpEnable = toEnable;
6778 }
2a332745 6779 else if (anArgCase == "-polygonmode")
6780 {
6781 Standard_Boolean toEnable = Standard_True;
6782 if (++anArgIter < theArgNb
dae2a922 6783 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
2a332745 6784 {
6785 --anArgIter;
6786 }
6787 aCaps->usePolygonMode = toEnable;
6788 }
ba00aab7 6789 else if (anArgCase == "-srgb")
6790 {
6791 Standard_Boolean toEnable = Standard_True;
6792 if (++anArgIter < theArgNb
dae2a922 6793 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
ba00aab7 6794 {
6795 --anArgIter;
6796 }
6797 aCaps->sRGBDisable = !toEnable;
6798 }
faff3767 6799 else if (anArgCase == "-compressedtextures")
6800 {
6801 Standard_Boolean toEnable = Standard_True;
6802 if (++anArgIter < theArgNb
dae2a922 6803 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
faff3767 6804 {
6805 --anArgIter;
6806 }
6807 aCaps->compressedTexturesDisable = !toEnable;
6808 }
8625ef7e 6809 else if (anArgCase == "-vbo")
a577aaab 6810 {
8625ef7e 6811 Standard_Boolean toEnable = Standard_True;
6812 if (++anArgIter < theArgNb
dae2a922 6813 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6814 {
6815 --anArgIter;
6816 }
6817 aCaps->vboDisable = !toEnable;
a577aaab 6818 }
8625ef7e 6819 else if (anArgCase == "-sprite"
6820 || anArgCase == "-sprites")
a577aaab 6821 {
8625ef7e 6822 Standard_Boolean toEnable = Standard_True;
6823 if (++anArgIter < theArgNb
dae2a922 6824 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6825 {
6826 --anArgIter;
6827 }
6828 aCaps->pntSpritesDisable = !toEnable;
a577aaab 6829 }
8625ef7e 6830 else if (anArgCase == "-softmode")
abe46077 6831 {
8625ef7e 6832 Standard_Boolean toEnable = Standard_True;
6833 if (++anArgIter < theArgNb
dae2a922 6834 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6835 {
6836 --anArgIter;
6837 }
6838 aCaps->contextNoAccel = toEnable;
6839 }
56689b27 6840 else if (anArgCase == "-winbuffer"
6841 || anArgCase == "-windowbuffer"
6842 || anArgCase == "-usewinbuffer"
6843 || anArgCase == "-usewindowbuffer"
6844 || anArgCase == "-usesystembuffer")
6845 {
6846 Standard_Boolean toEnable = Standard_True;
6847 if (++anArgIter < theArgNb
dae2a922 6848 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
56689b27 6849 {
6850 --anArgIter;
6851 }
6852 aCaps->useSystemBuffer = toEnable;
6853 }
8625ef7e 6854 else if (anArgCase == "-accel"
6855 || anArgCase == "-acceleration")
6856 {
6857 Standard_Boolean toEnable = Standard_True;
6858 if (++anArgIter < theArgNb
dae2a922 6859 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 6860 {
6861 --anArgIter;
6862 }
6863 aCaps->contextNoAccel = !toEnable;
abe46077 6864 }
4e1523ef 6865 else if (anArgCase == "-compat"
6866 || anArgCase == "-compatprofile"
6867 || anArgCase == "-compatible"
6868 || anArgCase == "-compatibleprofile")
6869 {
6870 Standard_Boolean toEnable = Standard_True;
6871 if (++anArgIter < theArgNb
dae2a922 6872 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 6873 {
6874 --anArgIter;
6875 }
6876 aCaps->contextCompatible = toEnable;
6877 if (!aCaps->contextCompatible)
6878 {
6879 aCaps->ffpEnable = Standard_False;
6880 }
6881 }
6882 else if (anArgCase == "-core"
6883 || anArgCase == "-coreprofile")
6884 {
6885 Standard_Boolean toEnable = Standard_True;
6886 if (++anArgIter < theArgNb
dae2a922 6887 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 6888 {
6889 --anArgIter;
6890 }
6891 aCaps->contextCompatible = !toEnable;
6892 if (!aCaps->contextCompatible)
6893 {
6894 aCaps->ffpEnable = Standard_False;
6895 }
6896 }
f978241f 6897 else if (anArgCase == "-stereo"
6898 || anArgCase == "-quadbuffer")
6899 {
6900 Standard_Boolean toEnable = Standard_True;
6901 if (++anArgIter < theArgNb
dae2a922 6902 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 6903 {
6904 --anArgIter;
6905 }
6906 aCaps->contextStereo = toEnable;
6907 }
59515ca6 6908 else if (anArgCase == "-noext"
6909 || anArgCase == "-noextensions"
6910 || anArgCase == "-noextension")
6911 {
6912 Standard_Boolean toDisable = Standard_True;
6913 if (++anArgIter < theArgNb
dae2a922 6914 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
59515ca6 6915 {
6916 --anArgIter;
6917 }
6918 aCaps->contextNoExtensions = toDisable;
6919 }
6920 else if (anArgCase == "-maxversion"
6921 || anArgCase == "-upperversion"
6922 || anArgCase == "-limitversion")
6923 {
6924 Standard_Integer aVer[2] = { -2, -1 };
6925 for (Standard_Integer aValIter = 0; aValIter < 2; ++aValIter)
6926 {
6927 if (anArgIter + 1 < theArgNb)
6928 {
6929 const TCollection_AsciiString aStr (theArgVec[anArgIter + 1]);
6930 if (aStr.IsIntegerValue())
6931 {
6932 aVer[aValIter] = aStr.IntegerValue();
6933 ++anArgIter;
6934 }
6935 }
6936 }
6937 if (aVer[0] < -1
6938 || aVer[1] < -1)
6939 {
23fe70ec 6940 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
59515ca6 6941 return 1;
6942 }
6943 aCaps->contextMajorVersionUpper = aVer[0];
6944 aCaps->contextMinorVersionUpper = aVer[1];
6945 }
a577aaab 6946 else
6947 {
23fe70ec 6948 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
8625ef7e 6949 return 1;
a577aaab 6950 }
6951 }
6952 if (aCaps != &ViewerTest_myDefaultCaps)
6953 {
6954 ViewerTest_myDefaultCaps = *aCaps;
6955 }
6956 return 0;
6957}
6958
f0430952 6959//==============================================================================
6960//function : VMemGpu
6961//purpose :
6962//==============================================================================
6963
6964static int VMemGpu (Draw_Interpretor& theDI,
6965 Standard_Integer theArgNb,
6966 const char** theArgVec)
6967{
6968 // get the context
6969 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
6970 if (aContextAIS.IsNull())
6971 {
23fe70ec 6972 Message::SendFail ("Error: no active viewer");
f0430952 6973 return 1;
6974 }
6975
dc3fe572 6976 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 6977 if (aDriver.IsNull())
6978 {
23fe70ec 6979 Message::SendFail ("Error: graphic driver not available");
f0430952 6980 return 1;
6981 }
6982
6983 Standard_Size aFreeBytes = 0;
6984 TCollection_AsciiString anInfo;
6985 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
6986 {
23fe70ec 6987 Message::SendFail ("Error: information not available");
f0430952 6988 return 1;
6989 }
6990
6991 if (theArgNb > 1 && *theArgVec[1] == 'f')
6992 {
6993 theDI << Standard_Real (aFreeBytes);
6994 }
6995 else
6996 {
6997 theDI << anInfo;
6998 }
6999
7000 return 0;
7001}
7002
85e096c3 7003// ==============================================================================
7004// function : VReadPixel
7005// purpose :
7006// ==============================================================================
7007static int VReadPixel (Draw_Interpretor& theDI,
7008 Standard_Integer theArgNb,
7009 const char** theArgVec)
7010{
7011 // get the active view
7012 Handle(V3d_View) aView = ViewerTest::CurrentView();
7013 if (aView.IsNull())
7014 {
23fe70ec 7015 Message::SendFail ("Error: no active viewer");
85e096c3 7016 return 1;
7017 }
7018 else if (theArgNb < 3)
7019 {
23fe70ec 7020 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
7021 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
85e096c3 7022 return 1;
7023 }
7024
dc858f4c 7025 Image_Format aFormat = Image_Format_RGBA;
7026 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 7027
85e096c3 7028 Standard_Integer aWidth, aHeight;
7029 aView->Window()->Size (aWidth, aHeight);
91322f44 7030 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
7031 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 7032 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
7033 {
23fe70ec 7034 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
85e096c3 7035 return 1;
7036 }
7037
ba00aab7 7038 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
85e096c3 7039 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
7040 {
dc858f4c 7041 TCollection_AsciiString aParam (theArgVec[anIter]);
7042 aParam.LowerCase();
55c8f0f7 7043 if (aParam == "-rgb"
ba00aab7 7044 || aParam == "rgb"
7045 || aParam == "-srgb"
7046 || aParam == "srgb")
85e096c3 7047 {
dc858f4c 7048 aFormat = Image_Format_RGB;
692613e5 7049 aBufferType = Graphic3d_BT_RGB;
ba00aab7 7050 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
85e096c3 7051 }
55c8f0f7
BB
7052 else if (aParam == "-hls"
7053 || aParam == "hls")
85e096c3 7054 {
dc858f4c 7055 aFormat = Image_Format_RGB;
692613e5 7056 aBufferType = Graphic3d_BT_RGB;
85e096c3 7057 toShowHls = Standard_True;
7058 }
55c8f0f7
BB
7059 else if (aParam == "-rgbf"
7060 || aParam == "rgbf")
85e096c3 7061 {
dc858f4c 7062 aFormat = Image_Format_RGBF;
692613e5 7063 aBufferType = Graphic3d_BT_RGB;
85e096c3 7064 }
55c8f0f7 7065 else if (aParam == "-rgba"
ba00aab7 7066 || aParam == "rgba"
7067 || aParam == "-srgba"
7068 || aParam == "srgba")
85e096c3 7069 {
dc858f4c 7070 aFormat = Image_Format_RGBA;
692613e5 7071 aBufferType = Graphic3d_BT_RGBA;
ba00aab7 7072 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
85e096c3 7073 }
55c8f0f7
BB
7074 else if (aParam == "-rgbaf"
7075 || aParam == "rgbaf")
85e096c3 7076 {
dc858f4c 7077 aFormat = Image_Format_RGBAF;
692613e5 7078 aBufferType = Graphic3d_BT_RGBA;
85e096c3 7079 }
55c8f0f7
BB
7080 else if (aParam == "-depth"
7081 || aParam == "depth")
85e096c3 7082 {
dc858f4c 7083 aFormat = Image_Format_GrayF;
692613e5 7084 aBufferType = Graphic3d_BT_Depth;
85e096c3 7085 }
55c8f0f7
BB
7086 else if (aParam == "-name"
7087 || aParam == "name")
85e096c3 7088 {
7089 toShowName = Standard_True;
7090 }
9196ea9d 7091 else if (aParam == "-hex"
7092 || aParam == "hex")
7093 {
7094 toShowHex = Standard_True;
7095 }
55c8f0f7
BB
7096 else
7097 {
23fe70ec 7098 Message::SendFail() << "Syntax error at '" << aParam << "'";
9196ea9d 7099 return 1;
55c8f0f7 7100 }
85e096c3 7101 }
7102
692613e5 7103 Image_PixMap anImage;
7104 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
7105 {
23fe70ec 7106 Message::SendFail ("Error: image allocation failed");
692613e5 7107 return 1;
7108 }
7109 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 7110 {
23fe70ec 7111 Message::SendFail ("Error: image dump failed");
85e096c3 7112 return 1;
7113 }
7114
68beaa3c 7115 // redirect possible warning messages that could have been added by ToPixMap
7116 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
7117 // contaminate result of the command
7118 Standard_CString aWarnLog = theDI.Result();
7119 if (aWarnLog != NULL && aWarnLog[0] != '\0')
7120 {
7121 std::cout << aWarnLog << std::endl;
7122 }
7123 theDI.Reset();
7124
ba00aab7 7125 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
85e096c3 7126 if (toShowName)
7127 {
692613e5 7128 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 7129 {
e958a649 7130 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 7131 }
7132 else
7133 {
e958a649 7134 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 7135 }
7136 }
9196ea9d 7137 else if (toShowHex)
7138 {
7139 if (aBufferType == Graphic3d_BT_RGBA)
7140 {
7141 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
7142 }
7143 else
7144 {
7145 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
7146 }
7147 }
85e096c3 7148 else
7149 {
7150 switch (aBufferType)
7151 {
7152 default:
692613e5 7153 case Graphic3d_BT_RGB:
85e096c3 7154 {
7155 if (toShowHls)
7156 {
e958a649 7157 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 7158 }
ba00aab7 7159 else if (toShow_sRGB)
7160 {
7161 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
7162 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
7163 }
85e096c3 7164 else
7165 {
e958a649 7166 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 7167 }
7168 break;
7169 }
692613e5 7170 case Graphic3d_BT_RGBA:
85e096c3 7171 {
ba00aab7 7172 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
7173 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
85e096c3 7174 break;
7175 }
692613e5 7176 case Graphic3d_BT_Depth:
85e096c3 7177 {
e958a649 7178 theDI << aColor.GetRGB().Red();
85e096c3 7179 break;
7180 }
7181 }
7182 }
7183
7184 return 0;
7185}
7186
fd3f6bd0 7187//! Auxiliary presentation for an image plane.
7188class ViewerTest_ImagePrs : public AIS_InteractiveObject
7189{
7190public:
7191 //! Main constructor.
7192 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
7193 const Standard_Real theWidth,
7194 const Standard_Real theHeight,
7195 const TCollection_AsciiString& theLabel)
7196 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
7197 {
7198 SetDisplayMode (0);
7199 SetHilightMode (1);
7200 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
7201 {
7202 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
7203 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
7204 Graphic3d_MaterialAspect aMat;
7205 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
61168418 7206 aMat.SetAmbientColor (Quantity_NOC_BLACK);
7207 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
7208 aMat.SetSpecularColor (Quantity_NOC_BLACK);
7209 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
fd3f6bd0 7210 aFillAspect->SetFrontMaterial (aMat);
7211 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
7212 aFillAspect->SetTextureMapOn();
7213 }
7214 {
7215 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
7216 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
7217 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
7218 myDrawer->SetTextAspect (aTextAspect);
7219 }
7220 {
7221 const gp_Dir aNorm (0.0, 0.0, 1.0);
7222 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
7223 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
7224 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
7225 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
7226 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
7227 myTris->AddEdge (1);
7228 myTris->AddEdge (2);
7229 myTris->AddEdge (3);
7230 myTris->AddEdge (3);
7231 myTris->AddEdge (2);
7232 myTris->AddEdge (4);
7233
7234 myRect = new Graphic3d_ArrayOfPolylines (4);
7235 myRect->AddVertex (myTris->Vertice (1));
7236 myRect->AddVertex (myTris->Vertice (3));
7237 myRect->AddVertex (myTris->Vertice (4));
7238 myRect->AddVertex (myTris->Vertice (2));
7239 }
7240 }
7241
7242 //! Returns TRUE for accepted display modes.
7243 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
7244
7245 //! Compute presentation.
7246 virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& , const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) Standard_OVERRIDE
7247 {
7248 switch (theMode)
7249 {
7250 case 0:
7251 {
7252 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7253 aGroup->AddPrimitiveArray (myTris);
7254 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
7255 aGroup->AddPrimitiveArray (myRect);
7256 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7257 return;
7258 }
7259 case 1:
7260 {
7261 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
7262 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7263 aGroup->AddPrimitiveArray (myRect);
7264 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7265 return;
7266 }
7267 }
7268 }
7269
7270 //! Compute selection.
7271 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
7272 {
7273 if (theMode == 0)
7274 {
7275 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
7276 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
7277 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
7278 theSel->Add (aSensitive);
7279 }
7280 }
7281
7282private:
7283 Handle(Graphic3d_ArrayOfTriangles) myTris;
7284 Handle(Graphic3d_ArrayOfPolylines) myRect;
7285 TCollection_AsciiString myLabel;
7286 Standard_Real myWidth;
7287 Standard_Real myHeight;
7288};
7289
692613e5 7290//==============================================================================
7291//function : VDiffImage
7292//purpose : The draw-command compares two images.
7293//==============================================================================
7294
7295static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
7296{
fd3f6bd0 7297 if (theArgNb < 3)
692613e5 7298 {
23fe70ec 7299 Message::SendFail ("Syntax error: not enough arguments");
692613e5 7300 return 1;
7301 }
7302
fd3f6bd0 7303 Standard_Integer anArgIter = 1;
7304 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
7305 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
7306 TCollection_AsciiString aDiffImagePath;
7307 Standard_Real aTolColor = -1.0;
7308 Standard_Integer toBlackWhite = -1;
7309 Standard_Integer isBorderFilterOn = -1;
7310 Standard_Boolean isOldSyntax = Standard_False;
7311 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
7312 for (; anArgIter < theArgNb; ++anArgIter)
7313 {
7314 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7315 anArg.LowerCase();
7316 if (anArgIter + 1 < theArgNb
7317 && (anArg == "-toleranceofcolor"
7318 || anArg == "-tolerancecolor"
7319 || anArg == "-tolerance"
7320 || anArg == "-toler"))
7321 {
7322 aTolColor = Atof (theArgVec[++anArgIter]);
7323 if (aTolColor < 0.0 || aTolColor > 1.0)
7324 {
23fe70ec 7325 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7326 return 1;
7327 }
7328 }
7329 else if (anArg == "-blackwhite")
7330 {
7331 Standard_Boolean toEnable = Standard_True;
7332 if (anArgIter + 1 < theArgNb
dae2a922 7333 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7334 {
7335 ++anArgIter;
7336 }
7337 toBlackWhite = toEnable ? 1 : 0;
7338 }
7339 else if (anArg == "-borderfilter")
7340 {
7341 Standard_Boolean toEnable = Standard_True;
7342 if (anArgIter + 1 < theArgNb
dae2a922 7343 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
fd3f6bd0 7344 {
7345 ++anArgIter;
7346 }
7347 isBorderFilterOn = toEnable ? 1 : 0;
7348 }
7349 else if (anArg == "-exitonclose")
7350 {
49582f9d 7351 ViewerTest_EventManager::ToExitOnCloseView() = true;
fd3f6bd0 7352 if (anArgIter + 1 < theArgNb
dae2a922 7353 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
fd3f6bd0 7354 {
7355 ++anArgIter;
7356 }
7357 }
7358 else if (anArg == "-closeonescape"
7359 || anArg == "-closeonesc")
7360 {
49582f9d 7361 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
fd3f6bd0 7362 if (anArgIter + 1 < theArgNb
dae2a922 7363 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
fd3f6bd0 7364 {
7365 ++anArgIter;
7366 }
7367 }
7368 else if (anArgIter + 3 < theArgNb
7369 && anArg == "-display")
7370 {
7371 aViewName = theArgVec[++anArgIter];
7372 aPrsNameRef = theArgVec[++anArgIter];
7373 aPrsNameNew = theArgVec[++anArgIter];
7374 if (anArgIter + 1 < theArgNb
7375 && *theArgVec[anArgIter + 1] != '-')
7376 {
7377 aPrsNameDiff = theArgVec[++anArgIter];
7378 }
7379 }
7380 else if (aTolColor < 0.0
7381 && anArg.IsRealValue())
7382 {
7383 isOldSyntax = Standard_True;
7384 aTolColor = anArg.RealValue();
7385 if (aTolColor < 0.0 || aTolColor > 1.0)
7386 {
23fe70ec 7387 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
fd3f6bd0 7388 return 1;
7389 }
7390 }
7391 else if (isOldSyntax
7392 && toBlackWhite == -1
7393 && (anArg == "0" || anArg == "1"))
7394 {
7395 toBlackWhite = anArg == "1" ? 1 : 0;
7396 }
7397 else if (isOldSyntax
7398 && isBorderFilterOn == -1
7399 && (anArg == "0" || anArg == "1"))
7400 {
7401 isBorderFilterOn = anArg == "1" ? 1 : 0;
7402 }
7403 else if (aDiffImagePath.IsEmpty())
7404 {
7405 aDiffImagePath = theArgVec[anArgIter];
7406 }
7407 else
7408 {
23fe70ec 7409 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
fd3f6bd0 7410 return 1;
7411 }
7412 }
692613e5 7413
fd3f6bd0 7414 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
7415 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
7416 if (!anImgRef->Load (anImgPathRef))
7417 {
23fe70ec 7418 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
fd3f6bd0 7419 return 1;
7420 }
7421 if (!anImgNew->Load (anImgPathNew))
7422 {
23fe70ec 7423 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
fd3f6bd0 7424 return 1;
7425 }
692613e5 7426
7427 // compare the images
7428 Image_Diff aComparer;
fd3f6bd0 7429 Standard_Integer aDiffColorsNb = -1;
7430 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 7431 {
fd3f6bd0 7432 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
7433 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
7434 aDiffColorsNb = aComparer.Compare();
7435 theDI << aDiffColorsNb << "\n";
692613e5 7436 }
7437
692613e5 7438 // save image of difference
fd3f6bd0 7439 Handle(Image_AlienPixMap) aDiff;
7440 if (aDiffColorsNb > 0
7441 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
7442 {
7443 aDiff = new Image_AlienPixMap();
7444 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
7445 {
23fe70ec 7446 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
fd3f6bd0 7447 return 1;
7448 }
7449 aComparer.SaveDiffImage (*aDiff);
7450 if (!aDiffImagePath.IsEmpty()
7451 && !aDiff->Save (aDiffImagePath))
7452 {
23fe70ec 7453 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
fd3f6bd0 7454 return 1;
7455 }
7456 }
7457
7458 if (aViewName.IsEmpty())
7459 {
7460 return 0;
7461 }
7462
7463 ViewerTest_Names aViewNames (aViewName);
7464 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
7465 {
7466 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
7467 theDI.Eval (aCommand.ToCString());
7468 }
7469
7470 Standard_Integer aPxLeft = 0;
7471 Standard_Integer aPxTop = 0;
7472 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
7473 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
7474 ? int(anImgRef->SizeY() * 2)
7475 : int(anImgRef->SizeY());
7476 TCollection_AsciiString aDisplayName;
9e04ccdc 7477 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
7478 aViewName, aDisplayName);
fd3f6bd0 7479
7480 Standard_Real aRatio = anImgRef->Ratio();
7481 Standard_Real aSizeX = 1.0;
7482 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 7483 {
fd3f6bd0 7484 OSD_Path aPath (anImgPathRef);
7485 TCollection_AsciiString aLabelRef;
7486 if (!aPath.Name().IsEmpty())
7487 {
7488 aLabelRef = aPath.Name() + aPath.Extension();
7489 }
7490 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
7491
7492 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
7493 gp_Trsf aTrsfRef;
7494 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
7495 anImgRefPrs->SetLocalTransformation (aTrsfRef);
7496 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 7497 }
fd3f6bd0 7498 {
7499 OSD_Path aPath (anImgPathNew);
7500 TCollection_AsciiString aLabelNew;
7501 if (!aPath.Name().IsEmpty())
7502 {
7503 aLabelNew = aPath.Name() + aPath.Extension();
7504 }
7505 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 7506
fd3f6bd0 7507 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
7508 gp_Trsf aTrsfRef;
7509 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
7510 anImgNewPrs->SetLocalTransformation (aTrsfRef);
7511 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
7512 }
7513 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
7514 if (!aDiff.IsNull())
7515 {
7516 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
7517 gp_Trsf aTrsfDiff;
7518 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
7519 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
7520 }
7521 if (!aPrsNameDiff.IsEmpty())
7522 {
7523 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
7524 }
7525 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
7526 ViewerTest::CurrentView()->FitAll();
692613e5 7527 return 0;
7528}
7529
4754e164 7530//=======================================================================
7531//function : VSelect
7532//purpose : Emulates different types of selection by mouse:
7533// 1) single click selection
7534// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
7535// 3) selection with polygon having corners at
dc3fe572 7536// pixel positions (x1,y1),...,(xn,yn)
4754e164 7537// 4) any of these selections with shift button pressed
7538//=======================================================================
49582f9d 7539static Standard_Integer VSelect (Draw_Interpretor& ,
7540 Standard_Integer theNbArgs,
7541 const char** theArgVec)
4754e164 7542{
49582f9d 7543 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
7544 if (aCtx.IsNull())
4754e164 7545 {
23fe70ec 7546 Message::SendFail ("Error: no active viewer");
4754e164 7547 return 1;
7548 }
2157d6ac 7549
49582f9d 7550 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
7551 bool isShiftSelection = false, toAllowOverlap = false;
7552 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2157d6ac 7553 {
49582f9d 7554 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7555 anArg.LowerCase();
7556 if (anArg == "-allowoverlap")
7557 {
7558 toAllowOverlap = true;
7559 if (anArgIter + 1 < theNbArgs
dae2a922 7560 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
49582f9d 7561 {
7562 ++anArgIter;
7563 }
7564 }
7565 else if (anArgIter + 1 < theNbArgs
7566 && anArg.IsIntegerValue()
7567 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
2157d6ac 7568 {
49582f9d 7569 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
7570 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
7571 }
7572 else if (anArgIter + 1 == theNbArgs
7573 && anArg.IsIntegerValue())
7574 {
7575 isShiftSelection = anArg.IntegerValue() == 1;
7576 }
7577 else
7578 {
23fe70ec 7579 Message::SendFail() << "Syntax error at '" << anArg << "'";
2157d6ac 7580 return 1;
7581 }
49582f9d 7582 }
a24a7821 7583
49582f9d 7584 if (toAllowOverlap)
7585 {
7586 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
2157d6ac 7587 }
7588
4754e164 7589 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
49582f9d 7590 if (aPnts.IsEmpty())
4754e164 7591 {
49582f9d 7592 if (isShiftSelection)
7593 {
7594 aCtx->ShiftSelect (false);
7595 }
4754e164 7596 else
49582f9d 7597 {
7598 aCtx->Select (false);
7599 }
7600 aCtx->CurrentViewer()->Invalidate();
4754e164 7601 }
49582f9d 7602 else if (aPnts.Length() == 2)
4754e164 7603 {
49582f9d 7604 if (toAllowOverlap
7605 && aPnts.First().y() < aPnts.Last().y())
7606 {
7607 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7608 }
7609 else if (!toAllowOverlap
7610 && aPnts.First().y() > aPnts.Last().y())
7611 {
7612 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
7613 }
7614 aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
4754e164 7615 }
7616 else
7617 {
49582f9d 7618 aCurrentEventManager->SelectInViewer (aPnts, isShiftSelection);
4754e164 7619 }
49582f9d 7620 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
4754e164 7621 return 0;
7622}
7623
7624//=======================================================================
7625//function : VMoveTo
dc3fe572 7626//purpose : Emulates cursor movement to defined pixel position
4754e164 7627//=======================================================================
1e756cb9 7628static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7629 Standard_Integer theNbArgs,
7630 const char** theArgVec)
4754e164 7631{
8a590580 7632 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7633 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7634 if (aContext.IsNull())
4754e164 7635 {
23fe70ec 7636 Message::SendFail ("Error: no active viewer");
4754e164 7637 return 1;
7638 }
7639
8a590580 7640 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7641 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7642 {
8a590580 7643 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7644 anArgStr.LowerCase();
7645 if (anArgStr == "-reset"
7646 || anArgStr == "-clear")
7647 {
7648 if (anArgIter + 1 < theNbArgs)
7649 {
23fe70ec 7650 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
8a590580 7651 return 1;
7652 }
7653
7654 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->Grid()->IsActive()
7655 && aContext->CurrentViewer()->GridEcho();
7656 if (toEchoGrid)
7657 {
7658 aContext->CurrentViewer()->HideGridEcho (aView);
7659 }
7660 if (aContext->ClearDetected() || toEchoGrid)
7661 {
7662 aContext->CurrentViewer()->RedrawImmediate();
7663 }
7664 return 0;
7665 }
7666 else if (aMousePos.x() == IntegerLast()
7667 && anArgStr.IsIntegerValue())
7668 {
7669 aMousePos.x() = anArgStr.IntegerValue();
7670 }
7671 else if (aMousePos.y() == IntegerLast()
7672 && anArgStr.IsIntegerValue())
7673 {
7674 aMousePos.y() = anArgStr.IntegerValue();
7675 }
7676 else
7677 {
23fe70ec 7678 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8a590580 7679 return 1;
7680 }
7681 }
7682
7683 if (aMousePos.x() == IntegerLast()
7684 || aMousePos.y() == IntegerLast())
7685 {
23fe70ec 7686 Message::SendFail ("Syntax error: wrong number of arguments");
4754e164 7687 return 1;
7688 }
8a590580 7689
49582f9d 7690 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
7691 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
7692 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
7693
1e756cb9 7694 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7695 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7696 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7697 {
7698 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7699 {
7700 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7701 break;
7702 }
7703 }
7704 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7705 return 0;
7706}
7707
1beb58d7 7708namespace
7709{
7710 //! Global map storing all animations registered in ViewerTest.
7711 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7712
7713 //! The animation calling the Draw Harness command.
7714 class ViewerTest_AnimationProc : public AIS_Animation
7715 {
7716 public:
7717
7718 //! Main constructor.
7719 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7720 Draw_Interpretor* theDI,
7721 const TCollection_AsciiString& theCommand)
7722 : AIS_Animation (theAnimationName),
7723 myDrawInter(theDI),
7724 myCommand (theCommand)
7725 {
7726 //
7727 }
7728
7729 protected:
7730
7731 //! Evaluate the command.
7732 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7733 {
7734 TCollection_AsciiString aCmd = myCommand;
7735 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7736 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7737 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7738 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7739 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7740 myDrawInter->Eval (aCmd.ToCString());
7741 }
7742
7743 //! Find the keyword in the command and replace it with value.
7744 //! @return the position of the keyword to pass value
7745 void replace (TCollection_AsciiString& theCmd,
7746 const TCollection_AsciiString& theKey,
7747 const TCollection_AsciiString& theVal)
7748 {
7749 TCollection_AsciiString aCmd (theCmd);
7750 aCmd.LowerCase();
7751 const Standard_Integer aPos = aCmd.Search (theKey);
7752 if (aPos == -1)
7753 {
7754 return;
7755 }
7756
7757 TCollection_AsciiString aPart1, aPart2;
7758 Standard_Integer aPart1To = aPos - 1;
7759 if (aPart1To >= 1
7760 && aPart1To <= theCmd.Length())
7761 {
7762 aPart1 = theCmd.SubString (1, aPart1To);
7763 }
7764
7765 Standard_Integer aPart2From = aPos + theKey.Length();
7766 if (aPart2From >= 1
7767 && aPart2From <= theCmd.Length())
7768 {
7769 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7770 }
7771
7772 theCmd = aPart1 + theVal + aPart2;
7773 }
7774
7775 protected:
7776
7777 Draw_Interpretor* myDrawInter;
7778 TCollection_AsciiString myCommand;
7779
7780 };
7781
7782 //! Replace the animation with the new one.
7783 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7784 Handle(AIS_Animation)& theAnimation,
7785 const Handle(AIS_Animation)& theAnimationNew)
7786 {
7787 theAnimationNew->CopyFrom (theAnimation);
7788 if (!theParentAnimation.IsNull())
7789 {
7790 theParentAnimation->Replace (theAnimation, theAnimationNew);
7791 }
7792 else
7793 {
7794 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
7795 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
7796 }
7797 theAnimation = theAnimationNew;
7798 }
7799
7800 //! Parse the point.
7801 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
7802 {
7803 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
7804 if (!anXYZ[0].IsRealValue()
7805 || !anXYZ[1].IsRealValue()
7806 || !anXYZ[2].IsRealValue())
7807 {
7808 return Standard_False;
7809 }
7810
7811 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
7812 return Standard_True;
7813 }
7814
7815 //! Parse the quaternion.
7816 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
7817 {
7818 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
7819 if (!anXYZW[0].IsRealValue()
7820 || !anXYZW[1].IsRealValue()
7821 || !anXYZW[2].IsRealValue()
7822 || !anXYZW[3].IsRealValue())
7823 {
7824 return Standard_False;
7825 }
7826
7827 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
7828 return Standard_True;
7829 }
7830
08f8a185 7831 //! Auxiliary class for flipping image upside-down.
7832 class ImageFlipper
7833 {
7834 public:
7835
7836 //! Empty constructor.
7837 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
7838
7839 //! Perform flipping.
7840 Standard_Boolean FlipY (Image_PixMap& theImage)
7841 {
7842 if (theImage.IsEmpty()
7843 || theImage.SizeX() == 0
7844 || theImage.SizeY() == 0)
7845 {
7846 return Standard_False;
7847 }
7848
7849 const Standard_Size aRowSize = theImage.SizeRowBytes();
7850 if (myTmp.Size() < aRowSize
7851 && !myTmp.Allocate (aRowSize))
7852 {
7853 return Standard_False;
7854 }
7855
7856 // for odd height middle row should be left as is
7857 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
7858 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
7859 {
7860 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
7861 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
7862 memcpy (myTmp.ChangeData(), aTop, aRowSize);
7863 memcpy (aTop, aBot, aRowSize);
7864 memcpy (aBot, myTmp.Data(), aRowSize);
7865 }
7866 return Standard_True;
7867 }
7868
7869 private:
7870 NCollection_Buffer myTmp;
7871 };
7872
1beb58d7 7873}
7874
197ac94e 7875//=================================================================================================
4754e164 7876//function : VViewParams
dc3fe572 7877//purpose : Gets or sets AIS View characteristics
197ac94e 7878//=================================================================================================
7879static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 7880{
1beb58d7 7881 Handle(V3d_View) aView = ViewerTest::CurrentView();
7882 if (aView.IsNull())
4754e164 7883 {
23fe70ec 7884 Message::SendFail ("Error: no active viewer");
4754e164 7885 return 1;
7886 }
197ac94e 7887
1beb58d7 7888 Standard_Boolean toSetProj = Standard_False;
7889 Standard_Boolean toSetUp = Standard_False;
7890 Standard_Boolean toSetAt = Standard_False;
7891 Standard_Boolean toSetEye = Standard_False;
7892 Standard_Boolean toSetScale = Standard_False;
7893 Standard_Boolean toSetSize = Standard_False;
7894 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 7895 Standard_Real aViewScale = aView->Scale();
7896 Standard_Real aViewSize = 1.0;
1beb58d7 7897 Graphic3d_Vec2i aCenter2d;
7898 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
7899 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
7900 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
7901 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
7902 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
197ac94e 7903 if (theArgsNb == 1)
4754e164 7904 {
197ac94e 7905 // print all of the available view parameters
1beb58d7 7906 char aText[4096];
7907 Sprintf (aText,
7908 "Scale: %g\n"
7909 "Proj: %12g %12g %12g\n"
7910 "Up: %12g %12g %12g\n"
7911 "At: %12g %12g %12g\n"
7912 "Eye: %12g %12g %12g\n",
7913 aViewScale,
7914 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7915 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7916 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
7917 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7918 theDi << aText;
197ac94e 7919 return 0;
4754e164 7920 }
197ac94e 7921
1beb58d7 7922 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7923 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 7924 {
1beb58d7 7925 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7926 anArg.LowerCase();
7927 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 7928 {
197ac94e 7929 continue;
7930 }
1beb58d7 7931 else if (anArg == "-cmd"
7932 || anArg == "-command"
7933 || anArg == "-args")
7934 {
7935 char aText[4096];
7936 Sprintf (aText,
7937 "-scale %g "
7938 "-proj %g %g %g "
7939 "-up %g %g %g "
7940 "-at %g %g %g\n",
7941 aViewScale,
7942 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
7943 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
7944 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7945 theDi << aText;
7946 }
7947 else if (anArg == "-scale"
7948 || anArg == "-size")
7949 {
7950 if (anArgIter + 1 < theArgsNb
7951 && *theArgVec[anArgIter + 1] != '-')
7952 {
7953 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
7954 if (aValueArg.IsRealValue())
7955 {
7956 ++anArgIter;
7957 if (anArg == "-scale")
7958 {
7959 toSetScale = Standard_True;
7960 aViewScale = aValueArg.RealValue();
7961 }
7962 else if (anArg == "-size")
7963 {
7964 toSetSize = Standard_True;
7965 aViewSize = aValueArg.RealValue();
7966 }
7967 continue;
7968 }
7969 }
7970 if (anArg == "-scale")
7971 {
7972 theDi << "Scale: " << aView->Scale() << "\n";
7973 }
7974 else if (anArg == "-size")
7975 {
7976 Graphic3d_Vec2d aSizeXY;
7977 aView->Size (aSizeXY.x(), aSizeXY.y());
7978 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7979 }
7980 }
7981 else if (anArg == "-eye"
7982 || anArg == "-at"
7983 || anArg == "-up"
7984 || anArg == "-proj")
7985 {
7986 if (anArgIter + 3 < theArgsNb)
7987 {
7988 gp_XYZ anXYZ;
7989 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7990 {
7991 anArgIter += 3;
7992 if (anArg == "-eye")
7993 {
7994 toSetEye = Standard_True;
7995 aViewEye = anXYZ;
7996 }
7997 else if (anArg == "-at")
7998 {
7999 toSetAt = Standard_True;
8000 aViewAt = anXYZ;
8001 }
8002 else if (anArg == "-up")
8003 {
8004 toSetUp = Standard_True;
8005 aViewUp = anXYZ;
8006 }
8007 else if (anArg == "-proj")
8008 {
8009 toSetProj = Standard_True;
8010 aViewProj = anXYZ;
8011 }
8012 continue;
8013 }
8014 }
197ac94e 8015
1beb58d7 8016 if (anArg == "-eye")
8017 {
8018 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
8019 }
8020 else if (anArg == "-at")
8021 {
8022 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
8023 }
8024 else if (anArg == "-up")
8025 {
8026 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
8027 }
8028 else if (anArg == "-proj")
8029 {
8030 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
8031 }
8032 }
8033 else if (anArg == "-center")
3dfe95cd 8034 {
1beb58d7 8035 if (anArgIter + 2 < theArgsNb)
8036 {
8037 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
8038 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
8039 if (anX.IsIntegerValue()
8040 && anY.IsIntegerValue())
8041 {
8042 toSetCenter2d = Standard_True;
8043 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
8044 }
8045 }
8046 }
8047 else
8048 {
23fe70ec 8049 Message::SendFail() << "Syntax error at '" << anArg << "'";
3dfe95cd 8050 return 1;
8051 }
1beb58d7 8052 }
3dfe95cd 8053
1beb58d7 8054 // change view parameters in proper order
8055 if (toSetScale)
8056 {
8057 aView->SetScale (aViewScale);
8058 }
8059 if (toSetSize)
8060 {
8061 aView->SetSize (aViewSize);
8062 }
8063 if (toSetEye)
8064 {
8065 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
8066 }
8067 if (toSetAt)
8068 {
8069 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8070 }
8071 if (toSetProj)
8072 {
8073 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
8074 }
8075 if (toSetUp)
8076 {
8077 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
8078 }
8079 if (toSetCenter2d)
8080 {
8081 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 8082 }
8083
1beb58d7 8084 return 0;
8085}
197ac94e 8086
2e93433e 8087//==============================================================================
8088//function : V2DMode
8089//purpose :
8090//==============================================================================
8091static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
8092{
8093 bool is2dMode = true;
8094 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
8095 if (aV3dView.IsNull())
8096 {
23fe70ec 8097 Message::SendFail ("Error: no active viewer");
2e93433e 8098 return 1;
8099 }
8100 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
8101 {
8102 const TCollection_AsciiString anArg = theArgVec[anArgIt];
8103 TCollection_AsciiString anArgCase = anArg;
8104 anArgCase.LowerCase();
8105 if (anArgIt + 1 < theArgsNb
8106 && anArgCase == "-name")
8107 {
8108 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
8109 TCollection_AsciiString aViewName = aViewNames.GetViewName();
8110 if (!ViewerTest_myViews.IsBound1 (aViewName))
8111 {
23fe70ec 8112 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
2e93433e 8113 return 1;
8114 }
8115 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
8116 }
8117 else if (anArgCase == "-mode")
8118 {
8119 if (anArgIt + 1 < theArgsNb
dae2a922 8120 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
2e93433e 8121 {
8122 ++anArgIt;
8123 }
8124 }
dae2a922 8125 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
2e93433e 8126 {
8127 //
8128 }
8129 else
8130 {
23fe70ec 8131 Message::SendFail() << "Syntax error: unknown argument " << anArg;
2e93433e 8132 return 1;
8133 }
8134 }
8135
8136 aV3dView->SetView2DMode (is2dMode);
8137 return 0;
8138}
8139
1beb58d7 8140//==============================================================================
8141//function : VAnimation
8142//purpose :
8143//==============================================================================
8144static Standard_Integer VAnimation (Draw_Interpretor& theDI,
8145 Standard_Integer theArgNb,
8146 const char** theArgVec)
8147{
8148 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
8149 if (theArgNb < 2)
4754e164 8150 {
1beb58d7 8151 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
8152 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
8153 {
8154 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8155 }
1beb58d7 8156 return 0;
8157 }
8158 if (aCtx.IsNull())
8159 {
23fe70ec 8160 Message::SendFail ("Error: no active viewer");
1beb58d7 8161 return 1;
4754e164 8162 }
197ac94e 8163
1beb58d7 8164 Standard_Integer anArgIter = 1;
8165 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
8166 if (aNameArg.IsEmpty())
8167 {
23fe70ec 8168 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 8169 return 1;
8170 }
8171
8172 TCollection_AsciiString aNameArgLower = aNameArg;
8173 aNameArgLower.LowerCase();
8174 if (aNameArgLower == "-reset"
8175 || aNameArgLower == "-clear")
8176 {
8177 ViewerTest_AnimationTimelineMap.Clear();
8178 return 0;
8179 }
8180 else if (aNameArg.Value (1) == '-')
8181 {
23fe70ec 8182 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
1beb58d7 8183 return 1;
8184 }
197ac94e 8185
1beb58d7 8186 const char* aNameSplitter = "/";
8187 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
8188 if (aSplitPos == -1)
197ac94e 8189 {
1beb58d7 8190 aNameSplitter = ".";
8191 aSplitPos = aNameArg.Search (aNameSplitter);
8192 }
8193
8194 // find existing or create a new animation by specified name within syntax "parent.child".
8195 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
8196 for (; !aNameArg.IsEmpty();)
8197 {
8198 TCollection_AsciiString aNameParent;
8199 if (aSplitPos != -1)
197ac94e 8200 {
1beb58d7 8201 if (aSplitPos == aNameArg.Length())
8202 {
23fe70ec 8203 Message::SendFail ("Syntax error: animation name is not defined");
1beb58d7 8204 return 1;
8205 }
8206
8207 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
8208 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
8209
8210 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 8211 }
8212 else
8213 {
1beb58d7 8214 aNameParent = aNameArg;
8215 aNameArg.Clear();
197ac94e 8216 }
1beb58d7 8217
8218 if (anAnimation.IsNull())
3dfe95cd 8219 {
1beb58d7 8220 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
8221 {
8222 anAnimation = new AIS_Animation (aNameParent);
8223 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
8224 }
8225 aRootAnimation = anAnimation;
3dfe95cd 8226 }
8227 else
8228 {
1beb58d7 8229 aParentAnimation = anAnimation;
8230 anAnimation = aParentAnimation->Find (aNameParent);
8231 if (anAnimation.IsNull())
8232 {
8233 anAnimation = new AIS_Animation (aNameParent);
8234 aParentAnimation->Add (anAnimation);
8235 }
3dfe95cd 8236 }
8237 }
1beb58d7 8238
8239 if (anArgIter >= theArgNb)
197ac94e 8240 {
1beb58d7 8241 // just print the list of children
8242 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 8243 {
1beb58d7 8244 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8245 }
1beb58d7 8246 return 0;
197ac94e 8247 }
1beb58d7 8248
bf7b2ceb 8249 // animation parameters
1beb58d7 8250 Standard_Boolean toPlay = Standard_False;
8251 Standard_Real aPlaySpeed = 1.0;
8252 Standard_Real aPlayStartTime = anAnimation->StartPts();
8253 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 8254 Standard_Boolean isFreeCamera = Standard_False;
8255 Standard_Boolean isLockLoop = Standard_False;
08f8a185 8256
8257 // video recording parameters
8258 TCollection_AsciiString aRecFile;
8259 Image_VideoParams aRecParams;
8260
1beb58d7 8261 Handle(V3d_View) aView = ViewerTest::CurrentView();
8262 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 8263 {
1beb58d7 8264 TCollection_AsciiString anArg (theArgVec[anArgIter]);
8265 anArg.LowerCase();
bf7b2ceb 8266 // general options
1beb58d7 8267 if (anArg == "-reset"
8268 || anArg == "-clear")
197ac94e 8269 {
1beb58d7 8270 anAnimation->Clear();
8271 }
8272 else if (anArg == "-remove"
8273 || anArg == "-del"
8274 || anArg == "-delete")
8275 {
8276 if (!aParentAnimation.IsNull())
8277 {
8278 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
8279 }
8280 else
8281 {
8282 aParentAnimation->Remove (anAnimation);
8283 }
8284 }
bf7b2ceb 8285 // playback options
1beb58d7 8286 else if (anArg == "-play")
8287 {
8288 toPlay = Standard_True;
8289 if (++anArgIter < theArgNb)
8290 {
8291 if (*theArgVec[anArgIter] == '-')
8292 {
8293 --anArgIter;
8294 continue;
8295 }
8296 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
8297
8298 if (++anArgIter < theArgNb)
8299 {
8300 if (*theArgVec[anArgIter] == '-')
8301 {
8302 --anArgIter;
8303 continue;
8304 }
8305 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8306 }
8307 }
8308 }
8309 else if (anArg == "-resume")
8310 {
8311 toPlay = Standard_True;
8312 aPlayStartTime = anAnimation->ElapsedTime();
8313 if (++anArgIter < theArgNb)
8314 {
8315 if (*theArgVec[anArgIter] == '-')
8316 {
8317 --anArgIter;
8318 continue;
8319 }
8320
8321 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8322 }
8323 }
8324 else if (anArg == "-playspeed"
8325 || anArg == "-speed")
8326 {
8327 if (++anArgIter >= theArgNb)
8328 {
23fe70ec 8329 Message::SendFail() << "Syntax error at " << anArg << "";
1beb58d7 8330 return 1;
8331 }
8332 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8333 }
8334 else if (anArg == "-lock"
8335 || anArg == "-lockloop"
8336 || anArg == "-playlockloop")
8337 {
8338 isLockLoop = Standard_True;
8339 }
8340 else if (anArg == "-freecamera"
8341 || anArg == "-playfreecamera"
8342 || anArg == "-freelook")
8343 {
8344 isFreeCamera = Standard_True;
8345 }
08f8a185 8346 // video recodring options
8347 else if (anArg == "-rec"
8348 || anArg == "-record")
8349 {
8350 if (++anArgIter >= theArgNb)
8351 {
23fe70ec 8352 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8353 return 1;
8354 }
8355
8356 aRecFile = theArgVec[anArgIter];
8357 if (aRecParams.FpsNum <= 0)
8358 {
8359 aRecParams.FpsNum = 24;
8360 }
8361
8362 if (anArgIter + 2 < theArgNb
8363 && *theArgVec[anArgIter + 1] != '-'
8364 && *theArgVec[anArgIter + 2] != '-')
8365 {
8366 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8367 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8368 if (aWidthArg .IsIntegerValue()
8369 && aHeightArg.IsIntegerValue())
8370 {
8371 aRecParams.Width = aWidthArg .IntegerValue();
8372 aRecParams.Height = aHeightArg.IntegerValue();
8373 anArgIter += 2;
8374 }
8375 }
8376 }
1beb58d7 8377 else if (anArg == "-fps")
8378 {
8379 if (++anArgIter >= theArgNb)
8380 {
23fe70ec 8381 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8382 return 1;
8383 }
bf7b2ceb 8384
8385 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8386 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8387 if (aSplitIndex == 0)
8388 {
08f8a185 8389 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 8390 }
8391 else
8392 {
8393 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8394 aFpsArg.Split (aFpsArg.Length() - 1);
8395 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 8396 aRecParams.FpsNum = aNumStr.IntegerValue();
8397 aRecParams.FpsDen = aDenStr.IntegerValue();
8398 if (aRecParams.FpsDen < 1)
bf7b2ceb 8399 {
23fe70ec 8400 Message::SendFail() << "Syntax error at " << anArg;
bf7b2ceb 8401 return 1;
8402 }
8403 }
1beb58d7 8404 }
08f8a185 8405 else if (anArg == "-format")
8406 {
8407 if (++anArgIter >= theArgNb)
8408 {
23fe70ec 8409 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8410 return 1;
8411 }
8412 aRecParams.Format = theArgVec[anArgIter];
8413 }
8414 else if (anArg == "-pix_fmt"
8415 || anArg == "-pixfmt"
8416 || anArg == "-pixelformat")
8417 {
8418 if (++anArgIter >= theArgNb)
8419 {
23fe70ec 8420 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8421 return 1;
8422 }
8423 aRecParams.PixelFormat = theArgVec[anArgIter];
8424 }
8425 else if (anArg == "-codec"
8426 || anArg == "-vcodec"
8427 || anArg == "-videocodec")
8428 {
8429 if (++anArgIter >= theArgNb)
8430 {
23fe70ec 8431 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8432 return 1;
8433 }
8434 aRecParams.VideoCodec = theArgVec[anArgIter];
8435 }
8436 else if (anArg == "-crf"
8437 || anArg == "-preset"
8438 || anArg == "-qp")
8439 {
8440 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8441 if (++anArgIter >= theArgNb)
8442 {
23fe70ec 8443 Message::SendFail() << "Syntax error at " << anArg;
08f8a185 8444 return 1;
8445 }
8446
8447 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8448 }
bf7b2ceb 8449 // animation definition options
1beb58d7 8450 else if (anArg == "-start"
8451 || anArg == "-starttime"
8452 || anArg == "-startpts")
8453 {
8454 if (++anArgIter >= theArgNb)
8455 {
23fe70ec 8456 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8457 return 1;
8458 }
8459
8460 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8461 aRootAnimation->UpdateTotalDuration();
8462 }
8463 else if (anArg == "-end"
8464 || anArg == "-endtime"
8465 || anArg == "-endpts")
8466 {
8467 if (++anArgIter >= theArgNb)
8468 {
23fe70ec 8469 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8470 return 1;
8471 }
8472
8473 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8474 aRootAnimation->UpdateTotalDuration();
8475 }
8476 else if (anArg == "-dur"
8477 || anArg == "-duration")
8478 {
8479 if (++anArgIter >= theArgNb)
8480 {
23fe70ec 8481 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8482 return 1;
8483 }
8484
8485 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8486 aRootAnimation->UpdateTotalDuration();
8487 }
8488 else if (anArg == "-command"
8489 || anArg == "-cmd"
8490 || anArg == "-invoke"
8491 || anArg == "-eval"
8492 || anArg == "-proc")
8493 {
8494 if (++anArgIter >= theArgNb)
8495 {
23fe70ec 8496 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8497 return 1;
8498 }
8499
8500 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8501 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8502 }
8503 else if (anArg == "-objecttrsf"
8504 || anArg == "-objectransformation"
8505 || anArg == "-objtransformation"
8506 || anArg == "-objtrsf"
8507 || anArg == "-object"
8508 || anArg == "-obj")
8509 {
8510 if (++anArgIter >= theArgNb)
8511 {
23fe70ec 8512 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8513 return 1;
8514 }
8515
8516 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8517 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8518 Handle(AIS_InteractiveObject) anObject;
8519 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8520 {
23fe70ec 8521 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
1beb58d7 8522 return 1;
8523 }
8524
1beb58d7 8525 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8526 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8527 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8528 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8529 Standard_Boolean isTrsfSet = Standard_False;
8530 Standard_Integer aTrsfArgIter = anArgIter + 1;
8531 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8532 {
8533 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8534 aTrsfArg.LowerCase();
8535 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8536 if (aTrsfArg.StartsWith ("-rotation")
8537 || aTrsfArg.StartsWith ("-rot"))
8538 {
8539 isTrsfSet = Standard_True;
8540 if (aTrsfArgIter + 4 >= theArgNb
8541 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8542 {
23fe70ec 8543 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8544 return 1;
8545 }
8546 aTrsfArgIter += 4;
8547 }
8548 else if (aTrsfArg.StartsWith ("-location")
8549 || aTrsfArg.StartsWith ("-loc"))
8550 {
8551 isTrsfSet = Standard_True;
8552 if (aTrsfArgIter + 3 >= theArgNb
8553 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8554 {
23fe70ec 8555 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8556 return 1;
8557 }
8558 aTrsfArgIter += 3;
8559 }
8560 else if (aTrsfArg.StartsWith ("-scale"))
8561 {
8562 isTrsfSet = Standard_True;
8563 if (++aTrsfArgIter >= theArgNb)
8564 {
23fe70ec 8565 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8566 return 1;
8567 }
8568
8569 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
8570 if (!aScaleStr.IsRealValue())
8571 {
23fe70ec 8572 Message::SendFail() << "Syntax error at " << aTrsfArg;
1beb58d7 8573 return 1;
8574 }
8575 aScales[anIndex] = aScaleStr.RealValue();
8576 }
8577 else
8578 {
8579 anArgIter = aTrsfArgIter - 1;
8580 break;
8581 }
8582 }
8583 if (!isTrsfSet)
8584 {
23fe70ec 8585 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8586 return 1;
8587 }
8588 else if (aTrsfArgIter >= theArgNb)
8589 {
8590 anArgIter = theArgNb;
8591 }
8592
8593 aTrsfs[0].SetRotation (aRotQuats[0]);
8594 aTrsfs[1].SetRotation (aRotQuats[1]);
8595 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8596 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8597 aTrsfs[0].SetScaleFactor (aScales[0]);
8598 aTrsfs[1].SetScaleFactor (aScales[1]);
8599
8600 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8601 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8602 }
8603 else if (anArg == "-viewtrsf"
8604 || anArg == "-view")
8605 {
8606 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8607 if (aCamAnimation.IsNull())
8608 {
8609 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8610 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8611 }
8612
8613 Handle(Graphic3d_Camera) aCams[2] =
8614 {
8615 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8616 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8617 };
8618
8619 Standard_Boolean isTrsfSet = Standard_False;
8620 Standard_Integer aViewArgIter = anArgIter + 1;
8621 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8622 {
8623 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8624 aViewArg.LowerCase();
8625 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8626 if (aViewArg.StartsWith ("-scale"))
8627 {
8628 isTrsfSet = Standard_True;
8629 if (++aViewArgIter >= theArgNb)
8630 {
23fe70ec 8631 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8632 return 1;
8633 }
8634
8635 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
8636 if (!aScaleStr.IsRealValue())
8637 {
23fe70ec 8638 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8639 return 1;
8640 }
8641 Standard_Real aScale = aScaleStr.RealValue();
8642 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8643 aCams[anIndex]->SetScale (aScale);
8644 }
8645 else if (aViewArg.StartsWith ("-eye")
8646 || aViewArg.StartsWith ("-center")
8647 || aViewArg.StartsWith ("-at")
8648 || aViewArg.StartsWith ("-up"))
8649 {
8650 isTrsfSet = Standard_True;
8651 gp_XYZ anXYZ;
8652 if (aViewArgIter + 3 >= theArgNb
8653 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8654 {
23fe70ec 8655 Message::SendFail() << "Syntax error at " << aViewArg;
1beb58d7 8656 return 1;
8657 }
8658 aViewArgIter += 3;
8659
8660 if (aViewArg.StartsWith ("-eye"))
8661 {
8662 aCams[anIndex]->SetEye (anXYZ);
8663 }
8664 else if (aViewArg.StartsWith ("-center")
8665 || aViewArg.StartsWith ("-at"))
8666 {
8667 aCams[anIndex]->SetCenter (anXYZ);
8668 }
8669 else if (aViewArg.StartsWith ("-up"))
8670 {
8671 aCams[anIndex]->SetUp (anXYZ);
8672 }
8673 }
8674 else
8675 {
8676 anArgIter = aViewArgIter - 1;
8677 break;
8678 }
8679 }
8680 if (!isTrsfSet)
8681 {
23fe70ec 8682 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8683 return 1;
8684 }
8685 else if (aViewArgIter >= theArgNb)
8686 {
8687 anArgIter = theArgNb;
8688 }
8689
8690 aCamAnimation->SetCameraStart(aCams[0]);
8691 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8692 }
8693 else
8694 {
23fe70ec 8695 Message::SendFail() << "Syntax error at " << anArg;
1beb58d7 8696 return 1;
197ac94e 8697 }
8698 }
1beb58d7 8699
08f8a185 8700 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8701 {
1beb58d7 8702 return 0;
8703 }
8704
8705 // Start animation timeline and process frame updating.
8706 TheIsAnimating = Standard_True;
8707 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8708 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8709 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8710 if (isFreeCamera)
8711 {
8712 aView->Camera()->Copy (aCameraBack);
8713 }
8714
8715 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8716 if (aRecParams.FpsNum <= 0)
1beb58d7 8717 {
8718 while (!anAnimation->IsStopped())
197ac94e 8719 {
1beb58d7 8720 aCameraBack->Copy (aView->Camera());
8721 const Standard_Real aPts = anAnimation->UpdateTimer();
8722 if (isFreeCamera)
8723 {
8724 aView->Camera()->Copy (aCameraBack);
8725 }
8726
8727 if (aPts >= anUpperPts)
8728 {
8729 anAnimation->Pause();
8730 break;
8731 }
8732
8733 if (aView->IsInvalidated())
8734 {
8735 aView->Redraw();
8736 }
8737 else
8738 {
8739 aView->RedrawImmediate();
8740 }
8741
8742 if (!isLockLoop)
8743 {
8744 // handle user events
8745 theDI.Eval ("after 1 set waiter 1");
8746 theDI.Eval ("vwait waiter");
8747 }
8748 if (!TheIsAnimating)
8749 {
8750 anAnimation->Pause();
8751 theDI << aPts;
8752 break;
8753 }
8754 }
8755
8756 if (aView->IsInvalidated())
8757 {
8758 aView->Redraw();
197ac94e 8759 }
8760 else
8761 {
1beb58d7 8762 aView->RedrawImmediate();
197ac94e 8763 }
8764 }
1beb58d7 8765 else
197ac94e 8766 {
bf7b2ceb 8767 OSD_Timer aPerfTimer;
8768 aPerfTimer.Start();
1beb58d7 8769
08f8a185 8770 Handle(Image_VideoRecorder) aRecorder;
8771 ImageFlipper aFlipper;
8772 Handle(Draw_ProgressIndicator) aProgress;
8773 if (!aRecFile.IsEmpty())
8774 {
8775 if (aRecParams.Width <= 0
8776 || aRecParams.Height <= 0)
8777 {
8778 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8779 }
8780
8781 aRecorder = new Image_VideoRecorder();
8782 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8783 {
23fe70ec 8784 Message::SendFail ("Error: failed to open video file for recording");
08f8a185 8785 return 0;
8786 }
8787
8788 aProgress = new Draw_ProgressIndicator (theDI, 1);
8789 }
8790
1beb58d7 8791 // Manage frame-rated animation here
8792 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 8793 int64_t aNbFrames = 0;
7e785937 8794 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
8795 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
08f8a185 8796 Standard_Integer aSecondsProgress = 0;
7e785937 8797 for (; aPts <= anUpperPts && aPS.More();)
197ac94e 8798 {
08f8a185 8799 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 8800 aPts = aPlayStartTime + aRecPts;
8801 ++aNbFrames;
1beb58d7 8802 if (!anAnimation->Update (aPts))
8803 {
8804 break;
8805 }
8806
08f8a185 8807 if (!aRecorder.IsNull())
8808 {
8809 V3d_ImageDumpOptions aDumpParams;
8810 aDumpParams.Width = aRecParams.Width;
8811 aDumpParams.Height = aRecParams.Height;
8812 aDumpParams.BufferType = Graphic3d_BT_RGBA;
8813 aDumpParams.StereoOptions = V3d_SDO_MONO;
8814 aDumpParams.ToAdjustAspect = Standard_True;
8815 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
8816 {
23fe70ec 8817 Message::SendFail ("Error: view dump is failed");
08f8a185 8818 return 0;
8819 }
8820 aFlipper.FlipY (aRecorder->ChangeFrame());
8821 if (!aRecorder->PushFrame())
8822 {
8823 return 0;
8824 }
8825 }
8826 else
8827 {
8828 aView->Redraw();
8829 }
8830
8831 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
8832 {
7e785937 8833 aPS.Next();
08f8a185 8834 ++aSecondsProgress;
8835 }
197ac94e 8836 }
bf7b2ceb 8837
8838 aPerfTimer.Stop();
1beb58d7 8839 anAnimation->Stop();
bf7b2ceb 8840 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
8841 theDI << "Average FPS: " << aRecFps << "\n"
8842 << "Nb. Frames: " << Standard_Real(aNbFrames);
8843
8844 aView->Redraw();
197ac94e 8845 }
8846
1beb58d7 8847 aView->SetImmediateUpdate (wasImmediateUpdate);
8848 TheIsAnimating = Standard_False;
4754e164 8849 return 0;
8850}
8851
1beb58d7 8852
4754e164 8853//=======================================================================
8854//function : VChangeSelected
dc3fe572 8855//purpose : Adds the shape to selection or remove one from it
4754e164 8856//=======================================================================
8857static Standard_Integer VChangeSelected (Draw_Interpretor& di,
8858 Standard_Integer argc,
8859 const char ** argv)
8860{
8861 if(argc != 2)
8862 {
8863 di<<"Usage : " << argv[0] << " shape \n";
8864 return 1;
8865 }
8866 //get AIS_Shape:
4754e164 8867 TCollection_AsciiString aName(argv[1]);
8868 Handle(AIS_InteractiveObject) anAISObject;
8f521168 8869 if (!GetMapOfAIS().Find2 (aName, anAISObject)
8870 || anAISObject.IsNull())
4754e164 8871 {
8872 di<<"Use 'vdisplay' before";
8873 return 1;
8874 }
4754e164 8875
8f521168 8876 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 8877 return 0;
8878}
8879
4754e164 8880//=======================================================================
8881//function : VNbSelected
dc3fe572 8882//purpose : Returns number of selected objects
4754e164 8883//=======================================================================
8884static Standard_Integer VNbSelected (Draw_Interpretor& di,
8885 Standard_Integer argc,
8886 const char ** argv)
8887{
8888 if(argc != 1)
8889 {
8890 di << "Usage : " << argv[0] << "\n";
8891 return 1;
8892 }
8893 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8894 if(aContext.IsNull())
8895 {
8896 di << "use 'vinit' command before " << argv[0] << "\n";
8897 return 1;
8898 }
8899 di << aContext->NbSelected() << "\n";
8900 return 0;
8901}
8902
4754e164 8903//=======================================================================
8904//function : VPurgeDisplay
dc3fe572 8905//purpose : Switches altialiasing on or off
4754e164 8906//=======================================================================
8907static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
8908 Standard_Integer argc,
8909 const char ** argv)
8910{
eb4320f2 8911 if (argc > 1)
4754e164 8912 {
eb4320f2 8913 di << "Usage : " << argv[0] << "\n";
4754e164 8914 return 1;
8915 }
4754e164 8916 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8917 if (aContext.IsNull())
8918 {
8919 di << "use 'vinit' command before " << argv[0] << "\n";
8920 return 1;
8921 }
404c8936 8922
eb4320f2 8923 di << aContext->PurgeDisplay() << "\n";
4754e164 8924 return 0;
8925}
8926
8927//=======================================================================
8928//function : VSetViewSize
8929//purpose :
8930//=======================================================================
8931static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8932 Standard_Integer argc,
8933 const char ** argv)
8934{
8935 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8936 if(aContext.IsNull())
8937 {
8938 di << "use 'vinit' command before " << argv[0] << "\n";
8939 return 1;
8940 }
8941 if(argc != 2)
8942 {
8943 di<<"Usage : " << argv[0] << " Size\n";
8944 return 1;
8945 }
6b62b2da 8946 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 8947 if (aSize <= 0.)
8948 {
8949 di<<"Bad Size value : " << aSize << "\n";
8950 return 1;
8951 }
8952
8953 Handle(V3d_View) aView = ViewerTest::CurrentView();
8954 aView->SetSize(aSize);
8955 return 0;
8956}
8957
8958//=======================================================================
8959//function : VMoveView
8960//purpose :
8961//=======================================================================
8962static Standard_Integer VMoveView (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 < 4 || argc > 5)
8973 {
8974 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8975 return 1;
8976 }
6b62b2da 8977 Standard_Real Dx = Draw::Atof (argv[1]);
8978 Standard_Real Dy = Draw::Atof (argv[2]);
8979 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 8980 Standard_Boolean aStart = Standard_True;
8981 if (argc == 5)
8982 {
6b62b2da 8983 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 8984 }
8985
8986 Handle(V3d_View) aView = ViewerTest::CurrentView();
8987 aView->Move(Dx,Dy,Dz,aStart);
8988 return 0;
8989}
8990
8991//=======================================================================
8992//function : VTranslateView
8993//purpose :
8994//=======================================================================
8995static Standard_Integer VTranslateView (Draw_Interpretor& di,
8996 Standard_Integer argc,
8997 const char ** argv)
8998{
8999 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9000 if(aContext.IsNull())
9001 {
9002 di << "use 'vinit' command before " << argv[0] << "\n";
9003 return 1;
9004 }
9005 if(argc < 4 || argc > 5)
9006 {
9007 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9008 return 1;
9009 }
6b62b2da 9010 Standard_Real Dx = Draw::Atof (argv[1]);
9011 Standard_Real Dy = Draw::Atof (argv[2]);
9012 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 9013 Standard_Boolean aStart = Standard_True;
dc3fe572 9014 if (argc == 5)
4754e164 9015 {
6b62b2da 9016 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9017 }
9018
9019 Handle(V3d_View) aView = ViewerTest::CurrentView();
9020 aView->Translate(Dx,Dy,Dz,aStart);
9021 return 0;
9022}
9023
9024//=======================================================================
9025//function : VTurnView
9026//purpose :
9027//=======================================================================
9028static Standard_Integer VTurnView (Draw_Interpretor& di,
9029 Standard_Integer argc,
9030 const char ** argv)
9031{
9032 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9033 if(aContext.IsNull()) {
9034 di << "use 'vinit' command before " << argv[0] << "\n";
9035 return 1;
9036 }
9037 if(argc < 4 || argc > 5){
9038 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
9039 return 1;
9040 }
6b62b2da 9041 Standard_Real Ax = Draw::Atof (argv[1]);
9042 Standard_Real Ay = Draw::Atof (argv[2]);
9043 Standard_Real Az = 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->Turn(Ax,Ay,Az,aStart);
9052 return 0;
9053}
9054
269294d6 9055//==============================================================================
9056//function : VTextureEnv
9057//purpose : ENables or disables environment mapping
9058//==============================================================================
9059class OCC_TextureEnv : public Graphic3d_TextureEnv
9060{
9061public:
9062 OCC_TextureEnv(const Standard_CString FileName);
9063 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
9064 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
9065 const Standard_Boolean theModulateFlag,
9066 const Graphic3d_TypeOfTextureFilter theFilter,
9067 const Standard_ShortReal theXScale,
9068 const Standard_ShortReal theYScale,
9069 const Standard_ShortReal theXShift,
9070 const Standard_ShortReal theYShift,
9071 const Standard_ShortReal theAngle);
68858c7d 9072 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 9073};
a3f6f591 9074DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 9075
269294d6 9076OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
9077 : Graphic3d_TextureEnv(theFileName)
9078{
9079}
9080
9081OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
9082 : Graphic3d_TextureEnv(theTexId)
9083{
9084}
9085
9086void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
9087 const Standard_Boolean theModulateFlag,
9088 const Graphic3d_TypeOfTextureFilter theFilter,
9089 const Standard_ShortReal theXScale,
9090 const Standard_ShortReal theYScale,
9091 const Standard_ShortReal theXShift,
9092 const Standard_ShortReal theYShift,
9093 const Standard_ShortReal theAngle)
9094{
9095 myParams->SetRepeat (theRepeatFlag);
9096 myParams->SetModulate (theModulateFlag);
9097 myParams->SetFilter (theFilter);
9098 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
9099 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
9100 myParams->SetRotation (theAngle);
9101}
9102
35e08fe8 9103static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 9104{
9105 // get the active view
9106 Handle(V3d_View) aView = ViewerTest::CurrentView();
9107 if (aView.IsNull())
9108 {
23fe70ec 9109 Message::SendFail ("Error: no active viewer");
269294d6 9110 return 1;
9111 }
9112
9113 // Checking the input arguments
9114 Standard_Boolean anEnableFlag = Standard_False;
9115 Standard_Boolean isOk = theArgNb >= 2;
9116 if (isOk)
9117 {
9118 TCollection_AsciiString anEnableOpt(theArgVec[1]);
9119 anEnableFlag = anEnableOpt.IsEqual("on");
9120 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
9121 }
9122 if (anEnableFlag)
9123 {
9124 isOk = (theArgNb == 3 || theArgNb == 11);
9125 if (isOk)
9126 {
9127 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9128 isOk = (!aTextureOpt.IsIntegerValue() ||
9129 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
9130
9131 if (isOk && theArgNb == 11)
9132 {
9133 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
9134 aModulateOpt(theArgVec[4]),
9135 aFilterOpt (theArgVec[5]),
9136 aSScaleOpt (theArgVec[6]),
9137 aTScaleOpt (theArgVec[7]),
9138 aSTransOpt (theArgVec[8]),
9139 aTTransOpt (theArgVec[9]),
9140 anAngleOpt (theArgVec[10]);
9141 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
9142 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
9143 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
9144 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
9145 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
9146 anAngleOpt.IsRealValue());
9147 }
9148 }
9149 }
9150
9151 if (!isOk)
9152 {
23fe70ec 9153 Message::SendFail() << "Usage:\n"
9154 << theArgVec[0] << " off\n"
9155 << 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 9156 return 1;
9157 }
9158
9159 if (anEnableFlag)
9160 {
9161 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9162 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
9163 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
9164 new OCC_TextureEnv(theArgVec[2]);
9165
9166 if (theArgNb == 11)
9167 {
9168 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
9169 aTexEnv->SetTextureParameters(
9170 aRepeatOpt. IsEqual("repeat"),
9171 aModulateOpt.IsEqual("modulate"),
9172 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
9173 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
9174 Graphic3d_TOTF_TRILINEAR,
9175 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
9176 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
9177 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
9178 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
9179 (Standard_ShortReal)Draw::Atof(theArgVec[10])
9180 );
9181 }
9182 aView->SetTextureEnv(aTexEnv);
269294d6 9183 }
9184 else // Disabling environment mapping
9185 {
269294d6 9186 Handle(Graphic3d_TextureEnv) aTexture;
9187 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
9188 }
9189
9190 aView->Redraw();
9191 return 0;
9192}
9193
3e05329c 9194namespace
9195{
9196 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
9197
9198 //! Remove registered clipping plane from all views and objects.
9199 static void removePlane (MapOfPlanes& theRegPlanes,
9200 const TCollection_AsciiString& theName)
9201 {
9202 Handle(Graphic3d_ClipPlane) aClipPlane;
9203 if (!theRegPlanes.Find (theName, aClipPlane))
9204 {
23fe70ec 9205 Message::SendWarning ("Warning: no such plane");
3e05329c 9206 return;
9207 }
9208
9209 theRegPlanes.UnBind (theName);
9210 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
9211 anIObjIt.More(); anIObjIt.Next())
9212 {
8f521168 9213 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 9214 aPrs->RemoveClipPlane (aClipPlane);
9215 }
9216
9217 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
9218 aViewIt.More(); aViewIt.Next())
9219 {
9220 const Handle(V3d_View)& aView = aViewIt.Key2();
9221 aView->RemoveClipPlane(aClipPlane);
9222 }
9223
9224 ViewerTest::RedrawAllViews();
9225 }
9226}
9227
4269bd1b 9228//===============================================================================================
9229//function : VClipPlane
9230//purpose :
9231//===============================================================================================
9232static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9233{
9234 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 9235 static MapOfPlanes aRegPlanes;
9236
9237 if (theArgsNb < 2)
9238 {
3e05329c 9239 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
9240 {
9241 theDi << aPlaneIter.Key() << " ";
9242 }
9243 return 0;
4269bd1b 9244 }
9245
9246 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 9247 aCommand.LowerCase();
9248 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
9249 if (anActiveView.IsNull())
9250 {
23fe70ec 9251 Message::SendFail ("Error: no active viewer");
3e05329c 9252 return 1;
9253 }
4269bd1b 9254
9255 // print maximum number of planes for current viewer
3e05329c 9256 if (aCommand == "-maxplanes"
9257 || aCommand == "maxplanes")
4269bd1b 9258 {
3e05329c 9259 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
9260 << " plane slots provided by driver.\n";
4269bd1b 9261 return 0;
9262 }
9263
9264 // create / delete plane instance
3e05329c 9265 if (aCommand == "-create"
9266 || aCommand == "create"
9267 || aCommand == "-delete"
9268 || aCommand == "delete"
9269 || aCommand == "-clone"
9270 || aCommand == "clone")
4269bd1b 9271 {
9272 if (theArgsNb < 3)
9273 {
23fe70ec 9274 Message::SendFail ("Syntax error: plane name is required");
4269bd1b 9275 return 1;
9276 }
9277
3e05329c 9278 Standard_Boolean toCreate = aCommand == "-create"
9279 || aCommand == "create";
9280 Standard_Boolean toClone = aCommand == "-clone"
9281 || aCommand == "clone";
9282 Standard_Boolean toDelete = aCommand == "-delete"
9283 || aCommand == "delete";
4269bd1b 9284 TCollection_AsciiString aPlane (theArgVec[2]);
9285
9286 if (toCreate)
9287 {
9288 if (aRegPlanes.IsBound (aPlane))
9289 {
3e05329c 9290 std::cout << "Warning: existing plane has been overridden.\n";
9291 toDelete = true;
9292 }
9293 else
9294 {
9295 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9296 return 0;
4269bd1b 9297 }
4269bd1b 9298 }
9299 else if (toClone) // toClone
9300 {
9301 if (!aRegPlanes.IsBound (aPlane))
9302 {
23fe70ec 9303 Message::SendFail ("Error: no such plane");
4269bd1b 9304 return 1;
9305 }
3e05329c 9306 else if (theArgsNb < 4)
4269bd1b 9307 {
23fe70ec 9308 Message::SendFail ("Syntax error: enter name for new plane");
4269bd1b 9309 return 1;
9310 }
9311
9312 TCollection_AsciiString aClone (theArgVec[3]);
9313 if (aRegPlanes.IsBound (aClone))
9314 {
23fe70ec 9315 Message::SendFail ("Error: plane name is in use");
4269bd1b 9316 return 1;
9317 }
9318
9319 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
9320
9321 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 9322 return 0;
4269bd1b 9323 }
4269bd1b 9324
3e05329c 9325 if (toDelete)
9326 {
9327 if (aPlane == "ALL"
9328 || aPlane == "all"
9329 || aPlane == "*")
4269bd1b 9330 {
3e05329c 9331 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
9332 {
9333 aPlane = aPlaneIter.Key();
9334 removePlane (aRegPlanes, aPlane);
9335 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
9336 }
4269bd1b 9337 }
3e05329c 9338 else
4269bd1b 9339 {
3e05329c 9340 removePlane (aRegPlanes, aPlane);
4269bd1b 9341 }
4269bd1b 9342 }
9343
3e05329c 9344 if (toCreate)
9345 {
9346 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9347 }
4269bd1b 9348 return 0;
9349 }
9350
9351 // set / unset plane command
3e05329c 9352 if (aCommand == "set"
9353 || aCommand == "unset")
4269bd1b 9354 {
3e05329c 9355 if (theArgsNb < 5)
4269bd1b 9356 {
23fe70ec 9357 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9358 return 1;
9359 }
9360
3e05329c 9361 // redirect to new syntax
9362 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
9363 anArgVec.SetValue (1, theArgVec[0]);
9364 anArgVec.SetValue (2, theArgVec[2]);
9365 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
9366 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 9367 {
3e05329c 9368 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 9369 }
9370
3e05329c 9371 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 9372 }
9373
9374 // change plane command
3e05329c 9375 TCollection_AsciiString aPlaneName;
9376 Handle(Graphic3d_ClipPlane) aClipPlane;
9377 Standard_Integer anArgIter = 0;
9378 if (aCommand == "-change"
9379 || aCommand == "change")
4269bd1b 9380 {
3e05329c 9381 // old syntax support
9382 if (theArgsNb < 3)
4269bd1b 9383 {
23fe70ec 9384 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9385 return 1;
9386 }
9387
3e05329c 9388 anArgIter = 3;
9389 aPlaneName = theArgVec[2];
9390 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 9391 {
23fe70ec 9392 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
4269bd1b 9393 return 1;
9394 }
3e05329c 9395 }
9396 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9397 {
9398 anArgIter = 2;
9399 aPlaneName = theArgVec[1];
9400 }
9401 else
9402 {
9403 anArgIter = 2;
9404 aPlaneName = theArgVec[1];
9405 aClipPlane = new Graphic3d_ClipPlane();
9406 aRegPlanes.Bind (aPlaneName, aClipPlane);
9407 theDi << "Created new plane " << aPlaneName << ".\n";
9408 }
4269bd1b 9409
3e05329c 9410 if (theArgsNb - anArgIter < 1)
9411 {
23fe70ec 9412 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9413 return 1;
9414 }
4269bd1b 9415
3e05329c 9416 for (; anArgIter < theArgsNb; ++anArgIter)
9417 {
9418 const char** aChangeArgs = theArgVec + anArgIter;
9419 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9420 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9421 aChangeArg.LowerCase();
4269bd1b 9422
3e05329c 9423 Standard_Boolean toEnable = Standard_True;
dae2a922 9424 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 9425 {
3e05329c 9426 aClipPlane->SetOn (toEnable);
4269bd1b 9427 }
25c35042 9428 else if (aChangeArg.StartsWith ("-equation")
9429 || aChangeArg.StartsWith ("equation"))
4269bd1b 9430 {
3e05329c 9431 if (aNbChangeArgs < 5)
4269bd1b 9432 {
23fe70ec 9433 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9434 return 1;
9435 }
9436
25c35042 9437 Standard_Integer aSubIndex = 1;
9438 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9439 if (aPrefixLen < aChangeArg.Length())
9440 {
9441 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9442 if (!aSubStr.IsIntegerValue()
9443 || aSubStr.IntegerValue() <= 0)
9444 {
23fe70ec 9445 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
25c35042 9446 return 1;
9447 }
9448 aSubIndex = aSubStr.IntegerValue();
9449 }
9450
9451 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9452 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9453 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9454 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9455 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9456 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9457 {
9458 if (aSubPln->ChainNextPlane().IsNull())
9459 {
9460 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9461 }
9462 aSubPln = aSubPln->ChainNextPlane();
9463 }
9464 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9465 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9466 anArgIter += 4;
4269bd1b 9467 }
25c35042 9468 else if ((aChangeArg == "-boxinterior"
9469 || aChangeArg == "-boxint"
9470 || aChangeArg == "-box")
9471 && aNbChangeArgs >= 7)
9472 {
9473 Graphic3d_BndBox3d aBndBox;
9474 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9475 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9476 anArgIter += 6;
9477
9478 Standard_Integer aNbSubPlanes = 6;
9479 const Graphic3d_Vec3d aDirArray[6] =
9480 {
9481 Graphic3d_Vec3d (-1, 0, 0),
9482 Graphic3d_Vec3d ( 1, 0, 0),
9483 Graphic3d_Vec3d ( 0,-1, 0),
9484 Graphic3d_Vec3d ( 0, 1, 0),
9485 Graphic3d_Vec3d ( 0, 0,-1),
9486 Graphic3d_Vec3d ( 0, 0, 1),
9487 };
9488 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9489 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9490 {
9491 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9492 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9493 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9494 if (aSubPlaneIter + 1 == aNbSubPlanes)
9495 {
9496 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9497 }
9498 else
9499 {
9500 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9501 }
9502 aSubPln = aSubPln->ChainNextPlane();
9503 }
9504 }
3e05329c 9505 else if (aChangeArg == "-capping"
9506 || aChangeArg == "capping")
4269bd1b 9507 {
3e05329c 9508 if (aNbChangeArgs < 2)
4269bd1b 9509 {
23fe70ec 9510 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9511 return 1;
9512 }
9513
dae2a922 9514 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9515 {
3e05329c 9516 aClipPlane->SetCapping (toEnable);
9517 anArgIter += 1;
9518 }
9519 else
9520 {
9521 // just skip otherwise (old syntax)
9522 }
9523 }
9524 else if (aChangeArg == "-useobjectmaterial"
9525 || aChangeArg == "-useobjectmat"
9526 || aChangeArg == "-useobjmat"
9527 || aChangeArg == "-useobjmaterial")
9528 {
9529 if (aNbChangeArgs < 2)
9530 {
23fe70ec 9531 Message::SendFail ("Syntax error: need more arguments");
4269bd1b 9532 return 1;
9533 }
9534
dae2a922 9535 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9536 {
3e05329c 9537 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9538 anArgIter += 1;
4269bd1b 9539 }
3e05329c 9540 }
9541 else if (aChangeArg == "-useobjecttexture"
9542 || aChangeArg == "-useobjecttex"
9543 || aChangeArg == "-useobjtexture"
9544 || aChangeArg == "-useobjtex")
9545 {
9546 if (aNbChangeArgs < 2)
4269bd1b 9547 {
23fe70ec 9548 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9549 return 1;
9550 }
4269bd1b 9551
dae2a922 9552 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9553 {
9554 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9555 anArgIter += 1;
9556 }
9557 }
9558 else if (aChangeArg == "-useobjectshader"
9559 || aChangeArg == "-useobjshader")
9560 {
9561 if (aNbChangeArgs < 2)
9562 {
23fe70ec 9563 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9564 return 1;
9565 }
4269bd1b 9566
dae2a922 9567 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
3e05329c 9568 {
9569 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9570 anArgIter += 1;
4269bd1b 9571 }
3e05329c 9572 }
9573 else if (aChangeArg == "-color"
9574 || aChangeArg == "color")
9575 {
9576 Quantity_Color aColor;
dae2a922 9577 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
9578 aChangeArgs + 1,
9579 aColor);
3e05329c 9580 if (aNbParsed == 0)
4269bd1b 9581 {
23fe70ec 9582 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9583 return 1;
9584 }
61168418 9585 aClipPlane->SetCappingColor (aColor);
3e05329c 9586 anArgIter += aNbParsed;
9587 }
61168418 9588 else if (aNbChangeArgs >= 1
9589 && (aChangeArg == "-material"
9590 || aChangeArg == "material"))
9591 {
9592 ++anArgIter;
9593 Graphic3d_NameOfMaterial aMatName;
9594 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
9595 {
23fe70ec 9596 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
61168418 9597 return 1;
9598 }
9599 aClipPlane->SetCappingMaterial (aMatName);
9600 }
1b661a81 9601 else if ((aChangeArg == "-transparency"
9602 || aChangeArg == "-transp")
9603 && aNbChangeArgs >= 2)
9604 {
9605 TCollection_AsciiString aValStr (aChangeArgs[1]);
9606 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
9607 if (aValStr.IsRealValue())
9608 {
9609 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9610 aMat.SetTransparency ((float )aValStr.RealValue());
9611 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9612 aClipPlane->SetCappingMaterial (aMat);
9613 }
9614 else
9615 {
9616 aValStr.LowerCase();
9617 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9618 if (aValStr == "opaque")
9619 {
9620 aMode = Graphic3d_AlphaMode_Opaque;
9621 }
9622 else if (aValStr == "mask")
9623 {
9624 aMode = Graphic3d_AlphaMode_Mask;
9625 }
9626 else if (aValStr == "blend")
9627 {
9628 aMode = Graphic3d_AlphaMode_Blend;
9629 }
9630 else if (aValStr == "blendauto")
9631 {
9632 aMode = Graphic3d_AlphaMode_BlendAuto;
9633 }
9634 else
9635 {
23fe70ec 9636 Message::SendFail() << "Syntax error at '" << aValStr << "'";
1b661a81 9637 return 1;
9638 }
9639 anAspect->SetAlphaMode (aMode);
9640 aClipPlane->SetCappingAspect (anAspect);
9641 }
9642 anArgIter += 1;
9643 }
3e05329c 9644 else if (aChangeArg == "-texname"
9645 || aChangeArg == "texname")
9646 {
9647 if (aNbChangeArgs < 2)
9648 {
23fe70ec 9649 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9650 return 1;
9651 }
4269bd1b 9652
3e05329c 9653 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9654 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9655 if (!aTexture->IsDone())
9656 {
9657 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9658 }
3e05329c 9659 else
4269bd1b 9660 {
3e05329c 9661 aTexture->EnableModulate();
9662 aTexture->EnableRepeat();
9663 aClipPlane->SetCappingTexture (aTexture);
9664 }
9665 anArgIter += 1;
9666 }
9667 else if (aChangeArg == "-texscale"
9668 || aChangeArg == "texscale")
9669 {
9670 if (aClipPlane->CappingTexture().IsNull())
9671 {
23fe70ec 9672 Message::SendFail ("Error: no texture is set");
3e05329c 9673 return 1;
9674 }
4269bd1b 9675
3e05329c 9676 if (aNbChangeArgs < 3)
9677 {
23fe70ec 9678 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9679 return 1;
9680 }
4269bd1b 9681
3e05329c 9682 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9683 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9684 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9685 anArgIter += 2;
9686 }
9687 else if (aChangeArg == "-texorigin"
9688 || aChangeArg == "texorigin") // texture origin
9689 {
9690 if (aClipPlane->CappingTexture().IsNull())
9691 {
23fe70ec 9692 Message::SendFail ("Error: no texture is set");
3e05329c 9693 return 1;
9694 }
4269bd1b 9695
3e05329c 9696 if (aNbChangeArgs < 3)
9697 {
23fe70ec 9698 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9699 return 1;
4269bd1b 9700 }
3e05329c 9701
9702 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9703 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9704
9705 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9706 anArgIter += 2;
9707 }
9708 else if (aChangeArg == "-texrotate"
9709 || aChangeArg == "texrotate") // texture rotation
9710 {
9711 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9712 {
23fe70ec 9713 Message::SendFail ("Error: no texture is set");
3e05329c 9714 return 1;
9715 }
4269bd1b 9716
3e05329c 9717 if (aNbChangeArgs < 2)
9718 {
23fe70ec 9719 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9720 return 1;
9721 }
4269bd1b 9722
3e05329c 9723 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9724 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9725 anArgIter += 1;
9726 }
9727 else if (aChangeArg == "-hatch"
9728 || aChangeArg == "hatch")
9729 {
9730 if (aNbChangeArgs < 2)
9731 {
23fe70ec 9732 Message::SendFail ("Syntax error: need more arguments");
3e05329c 9733 return 1;
9734 }
4269bd1b 9735
3e05329c 9736 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9737 aHatchStr.LowerCase();
9738 if (aHatchStr == "on")
9739 {
9740 aClipPlane->SetCappingHatchOn();
9741 }
9742 else if (aHatchStr == "off")
9743 {
9744 aClipPlane->SetCappingHatchOff();
4269bd1b 9745 }
3e05329c 9746 else
4269bd1b 9747 {
3e05329c 9748 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9749 }
9750 anArgIter += 1;
9751 }
9752 else if (aChangeArg == "-delete"
9753 || aChangeArg == "delete")
9754 {
9755 removePlane (aRegPlanes, aPlaneName);
9756 return 0;
9757 }
9758 else if (aChangeArg == "-set"
32ca7711 9759 || aChangeArg == "-unset"
9760 || aChangeArg == "-setoverrideglobal")
3e05329c 9761 {
9762 // set / unset plane command
32ca7711 9763 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9764 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9765 Standard_Integer anIt = 1;
9766 for (; anIt < aNbChangeArgs; ++anIt)
9767 {
9768 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9769 if (anEntityName.IsEmpty()
9770 || anEntityName.Value (1) == '-')
4269bd1b 9771 {
3e05329c 9772 break;
4269bd1b 9773 }
32ca7711 9774 else if (!toOverrideGlobal
9775 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9776 {
3e05329c 9777 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9778 if (toSet)
9779 {
9780 aView->AddClipPlane (aClipPlane);
9781 }
9782 else
9783 {
9784 aView->RemoveClipPlane (aClipPlane);
9785 }
9786 continue;
4269bd1b 9787 }
3e05329c 9788 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9789 {
8f521168 9790 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9791 if (toSet)
9792 {
9793 aIObj->AddClipPlane (aClipPlane);
9794 }
9795 else
9796 {
9797 aIObj->RemoveClipPlane (aClipPlane);
9798 }
32ca7711 9799 if (!aIObj->ClipPlanes().IsNull())
9800 {
9801 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
9802 }
4269bd1b 9803 }
3e05329c 9804 else
4269bd1b 9805 {
23fe70ec 9806 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
3e05329c 9807 return 1;
4269bd1b 9808 }
3e05329c 9809 }
9810
9811 if (anIt == 1)
9812 {
9813 // apply to active view
9814 if (toSet)
4269bd1b 9815 {
3e05329c 9816 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 9817 }
9818 else
9819 {
3e05329c 9820 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 9821 }
9822 }
3e05329c 9823 else
9824 {
9825 anArgIter = anArgIter + anIt - 1;
9826 }
9827 }
9828 else
9829 {
23fe70ec 9830 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
3e05329c 9831 return 1;
4269bd1b 9832 }
4269bd1b 9833 }
9834
3e05329c 9835 ViewerTest::RedrawAllViews();
9836 return 0;
4269bd1b 9837}
9838
b5ac8292 9839//===============================================================================================
9840//function : VZRange
9841//purpose :
9842//===============================================================================================
9843static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9844{
197ac94e 9845 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9846
9847 if (aCurrentView.IsNull())
b5ac8292 9848 {
23fe70ec 9849 Message::SendFail ("Error: no active viewer");
b5ac8292 9850 return 1;
9851 }
9852
197ac94e 9853 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 9854
9855 if (theArgsNb < 2)
9856 {
9857 theDi << "ZNear: " << aCamera->ZNear() << "\n";
9858 theDi << "ZFar: " << aCamera->ZFar() << "\n";
9859 return 0;
9860 }
9861
9862 if (theArgsNb == 3)
9863 {
6b62b2da 9864 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
9865 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 9866
9867 if (aNewZNear >= aNewZFar)
9868 {
23fe70ec 9869 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
197ac94e 9870 return 1;
9871 }
9872
9873 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
9874 {
23fe70ec 9875 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
197ac94e 9876 return 1;
9877 }
9878
9879 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 9880 }
9881 else
9882 {
23fe70ec 9883 Message::SendFail ("Syntax error: wrong command arguments");
b5ac8292 9884 return 1;
9885 }
9886
197ac94e 9887 aCurrentView->Redraw();
9888
b5ac8292 9889 return 0;
9890}
9891
9892//===============================================================================================
9893//function : VAutoZFit
9894//purpose :
9895//===============================================================================================
9896static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9897{
197ac94e 9898 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
9899
9900 if (aCurrentView.IsNull())
b5ac8292 9901 {
23fe70ec 9902 Message::SendFail ("Error: no active viewer");
b5ac8292 9903 return 1;
9904 }
9905
c357e426 9906 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 9907
9908 if (theArgsNb > 3)
b5ac8292 9909 {
23fe70ec 9910 Message::SendFail ("Syntax error: wrong command arguments");
197ac94e 9911 return 1;
b5ac8292 9912 }
9913
197ac94e 9914 if (theArgsNb < 2)
b5ac8292 9915 {
586db386 9916 theDi << "Auto z-fit mode: \n"
c357e426 9917 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 9918 << "Scale: " << aScale << "\n";
9919 return 0;
b5ac8292 9920 }
197ac94e 9921
9922 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9923
9924 if (theArgsNb >= 3)
b5ac8292 9925 {
197ac94e 9926 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 9927 }
9928
c357e426 9929 aCurrentView->SetAutoZFitMode (isOn, aScale);
197ac94e 9930 aCurrentView->Redraw();
b5ac8292 9931 return 0;
9932}
9933
6b62b2da 9934//! Auxiliary function to print projection type
9935inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9936{
9937 switch (theProjType)
9938 {
9939 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9940 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9941 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9942 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9943 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9944 }
9945 return "UNKNOWN";
9946}
9947
b5ac8292 9948//===============================================================================================
6b62b2da 9949//function : VCamera
b5ac8292 9950//purpose :
9951//===============================================================================================
6b62b2da 9952static int VCamera (Draw_Interpretor& theDI,
9953 Standard_Integer theArgsNb,
9954 const char** theArgVec)
b5ac8292 9955{
6b62b2da 9956 Handle(V3d_View) aView = ViewerTest::CurrentView();
9957 if (aView.IsNull())
b5ac8292 9958 {
23fe70ec 9959 Message::SendFail ("Error: no active viewer");
b5ac8292 9960 return 1;
9961 }
9962
6b62b2da 9963 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9964 if (theArgsNb < 2)
b5ac8292 9965 {
6b62b2da 9966 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9967 theDI << "FOVy: " << aCamera->FOVy() << "\n";
b40cdc2b 9968 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9969 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
6b62b2da 9970 theDI << "Distance: " << aCamera->Distance() << "\n";
9971 theDI << "IOD: " << aCamera->IOD() << "\n";
9972 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9973 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9974 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
9975 return 0;
b5ac8292 9976 }
9977
30a1b24e 9978 TCollection_AsciiString aPrsName;
6b62b2da 9979 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 9980 {
6b62b2da 9981 Standard_CString anArg = theArgVec[anArgIter];
9982 TCollection_AsciiString anArgCase (anArg);
9983 anArgCase.LowerCase();
9984 if (anArgCase == "-proj"
9985 || anArgCase == "-projection"
9986 || anArgCase == "-projtype"
9987 || anArgCase == "-projectiontype")
9988 {
9989 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9990 }
9991 else if (anArgCase == "-ortho"
9992 || anArgCase == "-orthographic")
b5ac8292 9993 {
9994 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 9995 }
9996 else if (anArgCase == "-persp"
9997 || anArgCase == "-perspective"
9998 || anArgCase == "-perspmono"
9999 || anArgCase == "-perspectivemono"
10000 || anArgCase == "-mono")
b5ac8292 10001 {
10002 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10003 }
6b62b2da 10004 else if (anArgCase == "-stereo"
10005 || anArgCase == "-stereoscopic"
10006 || anArgCase == "-perspstereo"
10007 || anArgCase == "-perspectivestereo")
10008 {
10009 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10010 }
10011 else if (anArgCase == "-left"
10012 || anArgCase == "-lefteye"
10013 || anArgCase == "-monoleft"
10014 || anArgCase == "-monolefteye"
10015 || anArgCase == "-perpsleft"
10016 || anArgCase == "-perpslefteye")
b5ac8292 10017 {
10018 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
10019 }
6b62b2da 10020 else if (anArgCase == "-right"
10021 || anArgCase == "-righteye"
10022 || anArgCase == "-monoright"
10023 || anArgCase == "-monorighteye"
10024 || anArgCase == "-perpsright")
b5ac8292 10025 {
10026 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
10027 }
6b62b2da 10028 else if (anArgCase == "-dist"
10029 || anArgCase == "-distance")
b5ac8292 10030 {
6b62b2da 10031 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10032 if (anArgValue != NULL
10033 && *anArgValue != '-')
10034 {
10035 ++anArgIter;
10036 aCamera->SetDistance (Draw::Atof (anArgValue));
10037 continue;
10038 }
10039 theDI << aCamera->Distance() << " ";
b5ac8292 10040 }
6b62b2da 10041 else if (anArgCase == "-iod")
b5ac8292 10042 {
6b62b2da 10043 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10044 if (anArgValue != NULL
10045 && *anArgValue != '-')
10046 {
10047 ++anArgIter;
10048 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
10049 continue;
10050 }
10051 theDI << aCamera->IOD() << " ";
b5ac8292 10052 }
6b62b2da 10053 else if (anArgCase == "-iodtype")
b5ac8292 10054 {
6b62b2da 10055 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10056 TCollection_AsciiString anValueCase (anArgValue);
10057 anValueCase.LowerCase();
10058 if (anValueCase == "abs"
10059 || anValueCase == "absolute")
10060 {
10061 ++anArgIter;
10062 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
10063 continue;
10064 }
10065 else if (anValueCase == "rel"
10066 || anValueCase == "relative")
10067 {
10068 ++anArgIter;
10069 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
10070 continue;
10071 }
10072 else if (*anArgValue != '-')
10073 {
23fe70ec 10074 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
6b62b2da 10075 return 1;
10076 }
10077 switch (aCamera->GetIODType())
10078 {
10079 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
10080 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
10081 }
b5ac8292 10082 }
6b62b2da 10083 else if (anArgCase == "-zfocus")
b5ac8292 10084 {
6b62b2da 10085 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10086 if (anArgValue != NULL
10087 && *anArgValue != '-')
10088 {
10089 ++anArgIter;
10090 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
10091 continue;
10092 }
10093 theDI << aCamera->ZFocus() << " ";
b5ac8292 10094 }
6b62b2da 10095 else if (anArgCase == "-zfocustype")
b5ac8292 10096 {
6b62b2da 10097 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10098 TCollection_AsciiString anValueCase (anArgValue);
10099 anValueCase.LowerCase();
10100 if (anValueCase == "abs"
10101 || anValueCase == "absolute")
10102 {
10103 ++anArgIter;
10104 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
10105 continue;
10106 }
10107 else if (anValueCase == "rel"
10108 || anValueCase == "relative")
10109 {
10110 ++anArgIter;
10111 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
10112 continue;
10113 }
10114 else if (*anArgValue != '-')
10115 {
23fe70ec 10116 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
6b62b2da 10117 return 1;
10118 }
10119 switch (aCamera->ZFocusType())
10120 {
10121 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
10122 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
10123 }
10124 }
b40cdc2b 10125 else if (anArgCase == "-lockzup"
10126 || anArgCase == "-turntable")
10127 {
10128 bool toLockUp = true;
10129 if (++anArgIter < theArgsNb
dae2a922 10130 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
b40cdc2b 10131 {
10132 --anArgIter;
10133 }
10134 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
10135 }
6b62b2da 10136 else if (anArgCase == "-fov"
b40cdc2b 10137 || anArgCase == "-fovy"
10138 || anArgCase == "-fovx"
10139 || anArgCase == "-fov2d")
b5ac8292 10140 {
6b62b2da 10141 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10142 if (anArgValue != NULL
10143 && *anArgValue != '-')
10144 {
10145 ++anArgIter;
b40cdc2b 10146 if (anArgCase == "-fov2d")
10147 {
10148 aCamera->SetFOV2d (Draw::Atof (anArgValue));
10149 }
10150 else if (anArgCase == "-fovx")
10151 {
10152 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
10153 }
10154 else
10155 {
10156 aCamera->SetFOVy (Draw::Atof (anArgValue));
10157 }
6b62b2da 10158 continue;
10159 }
b40cdc2b 10160 if (anArgCase == "-fov2d")
10161 {
10162 theDI << aCamera->FOV2d() << " ";
10163 }
10164 else if (anArgCase == "-fovx")
10165 {
10166 theDI << aCamera->FOVx() << " ";
10167 }
10168 else
10169 {
10170 theDI << aCamera->FOVy() << " ";
10171 }
10172 }
10173 else if (anArgIter + 1 < theArgsNb
10174 && anArgCase == "-xrpose")
10175 {
10176 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
10177 anXRArg.LowerCase();
10178 if (anXRArg == "base")
10179 {
10180 aCamera = aView->View()->BaseXRCamera();
10181 }
10182 else if (anXRArg == "head")
10183 {
10184 aCamera = aView->View()->PosedXRCamera();
10185 }
10186 else
10187 {
10188 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
10189 return 1;
10190 }
10191 if (aCamera.IsNull())
10192 {
10193 Message::SendFail() << "Error: undefined XR pose";
10194 return 0;
10195 }
10196 if (aView->AutoZFitMode())
10197 {
10198 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
10199 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
10200 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
10201 }
b5ac8292 10202 }
30a1b24e 10203 else if (aPrsName.IsEmpty()
10204 && !anArgCase.StartsWith ("-"))
10205 {
10206 aPrsName = anArg;
10207 }
b5ac8292 10208 else
10209 {
23fe70ec 10210 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
b5ac8292 10211 return 1;
10212 }
10213 }
b5ac8292 10214
30a1b24e 10215 if (aPrsName.IsEmpty()
10216 || theArgsNb > 2)
10217 {
30a1b24e 10218 aView->Redraw();
10219 }
10220
10221 if (!aPrsName.IsEmpty())
10222 {
10223 Handle(AIS_CameraFrustum) aCameraFrustum;
10224 if (GetMapOfAIS().IsBound2 (aPrsName))
10225 {
10226 // find existing object
10227 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
10228 if (aCameraFrustum.IsNull())
10229 {
23fe70ec 10230 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
30a1b24e 10231 return 1;
10232 }
10233 }
10234
10235 if (aCameraFrustum.IsNull())
10236 {
10237 aCameraFrustum = new AIS_CameraFrustum();
10238 }
10239 else
10240 {
10241 // not include displayed object of old camera frustum in the new one.
10242 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
10243 aView->ZFitAll();
10244 }
b40cdc2b 10245 aCameraFrustum->SetCameraFrustum (aCamera);
30a1b24e 10246
10247 ViewerTest::Display (aPrsName, aCameraFrustum);
10248 }
b5ac8292 10249
10250 return 0;
10251}
10252
f978241f 10253//! Parse stereo output mode
10254inline Standard_Boolean parseStereoMode (Standard_CString theArg,
10255 Graphic3d_StereoMode& theMode)
10256{
10257 TCollection_AsciiString aFlag (theArg);
10258 aFlag.LowerCase();
10259 if (aFlag == "quadbuffer")
10260 {
10261 theMode = Graphic3d_StereoMode_QuadBuffer;
10262 }
10263 else if (aFlag == "anaglyph")
10264 {
10265 theMode = Graphic3d_StereoMode_Anaglyph;
10266 }
10267 else if (aFlag == "row"
10268 || aFlag == "rowinterlaced")
10269 {
10270 theMode = Graphic3d_StereoMode_RowInterlaced;
10271 }
10272 else if (aFlag == "col"
10273 || aFlag == "colinterlaced"
10274 || aFlag == "columninterlaced")
10275 {
10276 theMode = Graphic3d_StereoMode_ColumnInterlaced;
10277 }
10278 else if (aFlag == "chess"
10279 || aFlag == "chessboard")
10280 {
10281 theMode = Graphic3d_StereoMode_ChessBoard;
10282 }
10283 else if (aFlag == "sbs"
10284 || aFlag == "sidebyside")
10285 {
10286 theMode = Graphic3d_StereoMode_SideBySide;
10287 }
10288 else if (aFlag == "ou"
10289 || aFlag == "overunder")
10290 {
10291 theMode = Graphic3d_StereoMode_OverUnder;
10292 }
10293 else if (aFlag == "pageflip"
10294 || aFlag == "softpageflip")
10295 {
10296 theMode = Graphic3d_StereoMode_SoftPageFlip;
10297 }
b40cdc2b 10298 else if (aFlag == "openvr"
10299 || aFlag == "vr")
10300 {
10301 theMode = Graphic3d_StereoMode_OpenVR;
10302 }
f978241f 10303 else
10304 {
10305 return Standard_False;
10306 }
10307 return Standard_True;
10308}
10309
10310//! Parse anaglyph filter
10311inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
10312 Graphic3d_RenderingParams::Anaglyph& theFilter)
10313{
10314 TCollection_AsciiString aFlag (theArg);
10315 aFlag.LowerCase();
10316 if (aFlag == "redcyansimple")
10317 {
10318 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10319 }
10320 else if (aFlag == "redcyan"
10321 || aFlag == "redcyanoptimized")
10322 {
10323 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
10324 }
10325 else if (aFlag == "yellowbluesimple")
10326 {
10327 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
10328 }
10329 else if (aFlag == "yellowblue"
10330 || aFlag == "yellowblueoptimized")
10331 {
10332 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
10333 }
10334 else if (aFlag == "greenmagenta"
10335 || aFlag == "greenmagentasimple")
10336 {
10337 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
10338 }
10339 else
10340 {
10341 return Standard_False;
10342 }
10343 return Standard_True;
10344}
10345
b5ac8292 10346//==============================================================================
10347//function : VStereo
10348//purpose :
10349//==============================================================================
10350
10351static int VStereo (Draw_Interpretor& theDI,
10352 Standard_Integer theArgNb,
10353 const char** theArgVec)
10354{
f978241f 10355 Handle(V3d_View) aView = ViewerTest::CurrentView();
b5ac8292 10356 if (theArgNb < 2)
10357 {
b5ac8292 10358 if (aView.IsNull())
10359 {
23fe70ec 10360 Message::SendFail ("Error: no active viewer");
b5ac8292 10361 return 0;
10362 }
10363
10364 Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
10365 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 10366 if (isActive)
10367 {
10368 TCollection_AsciiString aMode;
10369 switch (aView->RenderingParams().StereoMode)
10370 {
10371 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10372 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10373 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10374 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10375 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10376 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10377 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
b40cdc2b 10378 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
bf02aa7d 10379 case Graphic3d_StereoMode_Anaglyph :
10380 aMode = "anaglyph";
10381 switch (aView->RenderingParams().AnaglyphFilter)
10382 {
10383 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10384 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10385 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10386 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10387 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10388 default: break;
10389 }
10390 default: break;
10391 }
10392 theDI << "Mode " << aMode << "\n";
10393 }
b5ac8292 10394 return 0;
10395 }
10396
f978241f 10397 Handle(Graphic3d_Camera) aCamera;
10398 Graphic3d_RenderingParams* aParams = NULL;
10399 Graphic3d_StereoMode aMode = Graphic3d_StereoMode_QuadBuffer;
10400 if (!aView.IsNull())
10401 {
10402 aParams = &aView->ChangeRenderingParams();
10403 aMode = aParams->StereoMode;
10404 aCamera = aView->Camera();
10405 }
10406
10407 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10408 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10409 {
10410 Standard_CString anArg = theArgVec[anArgIter];
10411 TCollection_AsciiString aFlag (anArg);
10412 aFlag.LowerCase();
10413 if (anUpdateTool.parseRedrawMode (aFlag))
10414 {
10415 continue;
10416 }
10417 else if (aFlag == "0"
10418 || aFlag == "off")
10419 {
10420 if (++anArgIter < theArgNb)
10421 {
23fe70ec 10422 Message::SendFail ("Error: wrong number of arguments");
f978241f 10423 return 1;
10424 }
10425
10426 if (!aCamera.IsNull()
10427 && aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
10428 {
10429 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10430 }
10431 ViewerTest_myDefaultCaps.contextStereo = Standard_False;
10432 return 0;
10433 }
10434 else if (aFlag == "1"
10435 || aFlag == "on")
10436 {
10437 if (++anArgIter < theArgNb)
10438 {
23fe70ec 10439 Message::SendFail ("Error: wrong number of arguments");
f978241f 10440 return 1;
10441 }
10442
10443 if (!aCamera.IsNull())
10444 {
10445 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10446 }
10447 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
b40cdc2b 10448 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
10449 {
10450 return 0;
10451 }
f978241f 10452 }
10453 else if (aFlag == "-reverse"
10454 || aFlag == "-reversed"
10455 || aFlag == "-swap")
10456 {
10457 Standard_Boolean toEnable = Standard_True;
10458 if (++anArgIter < theArgNb
dae2a922 10459 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10460 {
10461 --anArgIter;
10462 }
10463 aParams->ToReverseStereo = toEnable;
10464 }
10465 else if (aFlag == "-noreverse"
10466 || aFlag == "-noswap")
10467 {
10468 Standard_Boolean toDisable = Standard_True;
10469 if (++anArgIter < theArgNb
dae2a922 10470 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10471 {
10472 --anArgIter;
10473 }
10474 aParams->ToReverseStereo = !toDisable;
10475 }
10476 else if (aFlag == "-mode"
10477 || aFlag == "-stereomode")
10478 {
10479 if (++anArgIter >= theArgNb
10480 || !parseStereoMode (theArgVec[anArgIter], aMode))
10481 {
23fe70ec 10482 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10483 return 1;
10484 }
10485
10486 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10487 {
10488 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10489 }
10490 }
10491 else if (aFlag == "-anaglyph"
10492 || aFlag == "-anaglyphfilter")
10493 {
10494 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10495 if (++anArgIter >= theArgNb
10496 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10497 {
23fe70ec 10498 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10499 return 1;
10500 }
10501
10502 aMode = Graphic3d_StereoMode_Anaglyph;
10503 aParams->AnaglyphFilter = aFilter;
10504 }
10505 else if (parseStereoMode (anArg, aMode)) // short syntax
10506 {
10507 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10508 {
10509 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10510 }
10511 }
b40cdc2b 10512 else if (anArgIter + 1 < theArgNb
10513 && aFlag == "-hmdfov2d")
10514 {
10515 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
10516 if (aParams->HmdFov2d < 10.0f
10517 || aParams->HmdFov2d > 180.0f)
10518 {
10519 Message::SendFail() << "Error: FOV is out of range";
10520 return 1;
10521 }
10522 }
10523 else if (aFlag == "-mirror"
10524 || aFlag == "-mirrorcomposer")
10525 {
10526 Standard_Boolean toEnable = Standard_True;
10527 if (++anArgIter < theArgNb
dae2a922 10528 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b40cdc2b 10529 {
10530 --anArgIter;
10531 }
10532 aParams->ToMirrorComposer = toEnable;
10533 }
10534 else if (anArgIter + 1 < theArgNb
10535 && (aFlag == "-unitfactor"
10536 || aFlag == "-unitscale"))
10537 {
10538 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
10539 }
f978241f 10540 else
10541 {
23fe70ec 10542 Message::SendFail() << "Syntax error at '" << anArg << "'";
f978241f 10543 return 1;
10544 }
10545 }
10546
10547 if (!aView.IsNull())
10548 {
10549 aParams->StereoMode = aMode;
10550 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
b40cdc2b 10551 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
10552 {
10553 // initiate implicit continuous rendering
10554 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
10555 }
f978241f 10556 }
b5ac8292 10557 return 0;
10558}
10559
392ac980 10560//===============================================================================================
10561//function : VDefaults
10562//purpose :
10563//===============================================================================================
10564static int VDefaults (Draw_Interpretor& theDi,
10565 Standard_Integer theArgsNb,
10566 const char** theArgVec)
10567{
10568 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10569 if (aCtx.IsNull())
10570 {
23fe70ec 10571 Message::SendFail ("Error: no active viewer");
392ac980 10572 return 1;
10573 }
10574
10575 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10576 if (theArgsNb < 2)
10577 {
10578 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10579 {
10580 theDi << "DeflType: relative\n"
10581 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10582 }
10583 else
10584 {
10585 theDi << "DeflType: absolute\n"
10586 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10587 }
67441d0c 10588 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
4c513386 10589 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10590 return 0;
10591 }
10592
10593 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10594 {
10595 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10596 anArg.UpperCase();
10597 if (anArg == "-ABSDEFL"
10598 || anArg == "-ABSOLUTEDEFLECTION"
10599 || anArg == "-DEFL"
10600 || anArg == "-DEFLECTION")
392ac980 10601 {
4c513386 10602 if (++anArgIter >= theArgsNb)
10603 {
23fe70ec 10604 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10605 return 1;
10606 }
392ac980 10607 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10608 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10609 }
4c513386 10610 else if (anArg == "-RELDEFL"
10611 || anArg == "-RELATIVEDEFLECTION"
10612 || anArg == "-DEVCOEFF"
10613 || anArg == "-DEVIATIONCOEFF"
10614 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10615 {
4c513386 10616 if (++anArgIter >= theArgsNb)
10617 {
23fe70ec 10618 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10619 return 1;
10620 }
392ac980 10621 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10622 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10623 }
4c513386 10624 else if (anArg == "-ANGDEFL"
10625 || anArg == "-ANGULARDEFL"
10626 || anArg == "-ANGULARDEFLECTION")
392ac980 10627 {
4c513386 10628 if (++anArgIter >= theArgsNb)
10629 {
23fe70ec 10630 Message::SendFail() << "Syntax error at " << anArg;
4c513386 10631 return 1;
10632 }
67441d0c 10633 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
4c513386 10634 }
385c43e7 10635 else if (anArg == "-AUTOTR"
10636 || anArg == "-AUTOTRIANG"
10637 || anArg == "-AUTOTRIANGULATION")
4c513386 10638 {
14c7f553 10639 ++anArgIter;
10640 bool toTurnOn = true;
10641 if (anArgIter >= theArgsNb
dae2a922 10642 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
4c513386 10643 {
23fe70ec 10644 Message::SendFail() << "Syntax error at '" << anArg << "'";
4c513386 10645 return 1;
10646 }
14c7f553 10647 aDefParams->SetAutoTriangulation (toTurnOn);
392ac980 10648 }
10649 else
10650 {
23fe70ec 10651 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14c7f553 10652 return 1;
392ac980 10653 }
10654 }
10655
10656 return 0;
10657}
10658
12381341 10659//! Auxiliary method
10660inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10661 const Graphic3d_ZLayerId theLayer,
12381341 10662 const Standard_Boolean theIsGlobal)
10663{
10664 if (theLightNew.IsNull())
10665 {
10666 return;
10667 }
10668
992ed6b3 10669 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10670 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10671 {
992ed6b3 10672 aViewer->AddLight (theLightNew);
10673 if (theIsGlobal)
10674 {
10675 aViewer->SetLightOn (theLightNew);
10676 }
10677 else
10678 {
10679 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10680 }
12381341 10681 }
10682 else
10683 {
992ed6b3 10684 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10685 if (aSettings.Lights().IsNull())
10686 {
10687 aSettings.SetLights (new Graphic3d_LightSet());
10688 }
10689 aSettings.Lights()->Add (theLightNew);
10690 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10691 }
10692}
10693
10694//! Auxiliary method
10695inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10696{
10697 TCollection_AsciiString anArgNextCase (theArgNext);
10698 anArgNextCase.UpperCase();
10699 if (anArgNextCase.Length() > 5
10700 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10701 {
10702 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10703 }
10704 else
10705 {
10706 return theArgNext.IntegerValue();
10707 }
10708}
10709
10710//===============================================================================================
10711//function : VLight
10712//purpose :
10713//===============================================================================================
10714static int VLight (Draw_Interpretor& theDi,
10715 Standard_Integer theArgsNb,
10716 const char** theArgVec)
10717{
10718 Handle(V3d_View) aView = ViewerTest::CurrentView();
10719 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10720 if (aView.IsNull()
10721 || aViewer.IsNull())
10722 {
23fe70ec 10723 Message::SendFail ("Error: no active viewer");
12381341 10724 return 1;
10725 }
10726
ee2be2a8 10727 Standard_Real anXYZ[3] = {};
10728 Standard_Real anAtten[2] = {};
12381341 10729 if (theArgsNb < 2)
10730 {
10731 // print lights info
10732 Standard_Integer aLightId = 0;
6a24c6de 10733 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10734 {
6a24c6de 10735 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10736 const Quantity_Color aColor = aLight->Color();
992ed6b3 10737 theDi << "Light #" << aLightId
10738 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10739 << " [" << aLight->GetId() << "]" << "\n";
12381341 10740 switch (aLight->Type())
10741 {
10742 case V3d_AMBIENT:
10743 {
189f85a3 10744 theDi << " Type: Ambient\n";
10745 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10746 break;
10747 }
10748 case V3d_DIRECTIONAL:
10749 {
189f85a3 10750 theDi << " Type: Directional\n";
10751 theDi << " Intensity: " << aLight->Intensity() << "\n";
10752 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10753 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10754 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10755 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10756 break;
10757 }
10758 case V3d_POSITIONAL:
10759 {
189f85a3 10760 theDi << " Type: Positional\n";
10761 theDi << " Intensity: " << aLight->Intensity() << "\n";
10762 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10763 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10764 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10765 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10766 aLight->Attenuation (anAtten[0], anAtten[1]);
10767 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
88b312d3 10768 theDi << " Range: " << aLight->Range() << "\n";
12381341 10769 break;
10770 }
10771 case V3d_SPOT:
10772 {
189f85a3 10773 theDi << " Type: Spot\n";
10774 theDi << " Intensity: " << aLight->Intensity() << "\n";
10775 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10776 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10777 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10778 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10779 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10780 aLight->Attenuation (anAtten[0], anAtten[1]);
10781 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10782 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10783 theDi << " Exponent: " << aLight->Concentration() << "\n";
88b312d3 10784 theDi << " Range: " << aLight->Range() << "\n";
12381341 10785 break;
10786 }
10787 default:
10788 {
189f85a3 10789 theDi << " Type: UNKNOWN\n";
12381341 10790 break;
10791 }
10792 }
992ed6b3 10793 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10794 }
10795 }
10796
10797 Handle(V3d_Light) aLightNew;
10798 Handle(V3d_Light) aLightOld;
992ed6b3 10799 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10800 Standard_Boolean isGlobal = Standard_True;
10801 Standard_Boolean toCreate = Standard_False;
761d8807 10802 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10803 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10804 {
992ed6b3 10805 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10806
10807 TCollection_AsciiString aName, aValue;
10808 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10809 TCollection_AsciiString anArgCase (anArg);
10810 anArgCase.UpperCase();
761d8807 10811 if (anUpdateTool.parseRedrawMode (anArg))
10812 {
10813 continue;
10814 }
10815
12381341 10816 if (anArgCase.IsEqual ("NEW")
10817 || anArgCase.IsEqual ("ADD")
992ed6b3 10818 || anArgCase.IsEqual ("CREATE")
10819 || anArgCase.IsEqual ("-NEW")
10820 || anArgCase.IsEqual ("-ADD")
10821 || anArgCase.IsEqual ("-CREATE"))
12381341 10822 {
10823 toCreate = Standard_True;
10824 }
992ed6b3 10825 else if (anArgCase.IsEqual ("-LAYER")
10826 || anArgCase.IsEqual ("-ZLAYER"))
10827 {
10828 if (++anArgIt >= theArgsNb)
10829 {
23fe70ec 10830 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10831 return 1;
10832 }
10833
10834 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10835 aValStr.LowerCase();
10836 if (aValStr == "default"
10837 || aValStr == "def")
10838 {
10839 aLayer = Graphic3d_ZLayerId_Default;
10840 }
10841 else if (aValStr == "top")
10842 {
10843 aLayer = Graphic3d_ZLayerId_Top;
10844 }
10845 else if (aValStr == "topmost")
10846 {
10847 aLayer = Graphic3d_ZLayerId_Topmost;
10848 }
10849 else if (aValStr == "toposd"
10850 || aValStr == "osd")
10851 {
10852 aLayer = Graphic3d_ZLayerId_TopOSD;
10853 }
10854 else if (aValStr == "botosd"
10855 || aValStr == "bottom")
10856 {
10857 aLayer = Graphic3d_ZLayerId_BotOSD;
10858 }
10859 else if (aValStr.IsIntegerValue())
10860 {
10861 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10862 }
10863 else
10864 {
23fe70ec 10865 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
992ed6b3 10866 return 1;
10867 }
10868 }
12381341 10869 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10870 || anArgCase.IsEqual ("GLOBAL")
10871 || anArgCase.IsEqual ("-GLOB")
10872 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10873 {
10874 isGlobal = Standard_True;
10875 }
10876 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10877 || anArgCase.IsEqual ("LOCAL")
10878 || anArgCase.IsEqual ("-LOC")
10879 || anArgCase.IsEqual ("-LOCAL"))
12381341 10880 {
10881 isGlobal = Standard_False;
10882 }
4fe9ad57 10883 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10884 || anArgCase.IsEqual ("DEFAULTS")
10885 || anArgCase.IsEqual ("-DEF")
10886 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10887 {
10888 toCreate = Standard_False;
10889 aViewer->SetDefaultLights();
10890 }
10891 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10892 || anArgCase.IsEqual ("CLEAR")
10893 || anArgCase.IsEqual ("-CLR")
10894 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10895 {
10896 toCreate = Standard_False;
992ed6b3 10897
10898 TColStd_SequenceOfInteger aLayers;
10899 aViewer->GetAllZLayers (aLayers);
10900 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 10901 {
992ed6b3 10902 if (aLayeriter.Value() == aLayer
10903 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10904 {
10905 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10906 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10907 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10908 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10909 {
10910 break;
10911 }
10912 }
10913 }
10914
10915 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10916 {
10917 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10918 {
10919 Handle(V3d_Light) aLight = aLightIter.Value();
10920 aViewer->DelLight (aLight);
10921 aLightIter = aView->ActiveLightIterator();
10922 }
4fe9ad57 10923 }
10924 }
12381341 10925 else if (anArgCase.IsEqual ("AMB")
10926 || anArgCase.IsEqual ("AMBIENT")
10927 || anArgCase.IsEqual ("AMBLIGHT"))
10928 {
12381341 10929 if (!toCreate)
10930 {
23fe70ec 10931 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10932 return 1;
10933 }
992ed6b3 10934
10935 addLight (aLightNew, aLayer, isGlobal);
12381341 10936 toCreate = Standard_False;
992ed6b3 10937 aLightNew = new V3d_AmbientLight();
12381341 10938 }
10939 else if (anArgCase.IsEqual ("DIRECTIONAL")
10940 || anArgCase.IsEqual ("DIRLIGHT"))
10941 {
12381341 10942 if (!toCreate)
10943 {
23fe70ec 10944 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10945 return 1;
10946 }
992ed6b3 10947
10948 addLight (aLightNew, aLayer, isGlobal);
12381341 10949 toCreate = Standard_False;
992ed6b3 10950 aLightNew = new V3d_DirectionalLight();
12381341 10951 }
10952 else if (anArgCase.IsEqual ("SPOT")
10953 || anArgCase.IsEqual ("SPOTLIGHT"))
10954 {
12381341 10955 if (!toCreate)
10956 {
23fe70ec 10957 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10958 return 1;
10959 }
992ed6b3 10960
10961 addLight (aLightNew, aLayer, isGlobal);
12381341 10962 toCreate = Standard_False;
992ed6b3 10963 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10964 }
10965 else if (anArgCase.IsEqual ("POSLIGHT")
10966 || anArgCase.IsEqual ("POSITIONAL"))
10967 {
12381341 10968 if (!toCreate)
10969 {
23fe70ec 10970 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10971 return 1;
10972 }
992ed6b3 10973
10974 addLight (aLightNew, aLayer, isGlobal);
12381341 10975 toCreate = Standard_False;
992ed6b3 10976 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 10977 }
992ed6b3 10978 else if (anArgCase.IsEqual ("CHANGE")
10979 || anArgCase.IsEqual ("-CHANGE"))
12381341 10980 {
12381341 10981 if (++anArgIt >= theArgsNb)
10982 {
23fe70ec 10983 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 10984 return 1;
10985 }
10986
992ed6b3 10987 addLight (aLightNew, aLayer, isGlobal);
10988 aLightNew.Nullify();
12381341 10989 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
10990 Standard_Integer aLightIt = 0;
6a24c6de 10991 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 10992 {
10993 if (aLightIt == aLightId)
10994 {
6a24c6de 10995 aLightOld = aLightIter.Value();
12381341 10996 break;
10997 }
10998 }
10999
11000 if (aLightOld.IsNull())
11001 {
23fe70ec 11002 Message::SendFail() << "Error: Light " << theArgVec[anArgIt] << " is undefined";
12381341 11003 return 1;
11004 }
11005 }
11006 else if (anArgCase.IsEqual ("DEL")
992ed6b3 11007 || anArgCase.IsEqual ("DELETE")
11008 || anArgCase.IsEqual ("-DEL")
11009 || anArgCase.IsEqual ("-DELETE"))
12381341 11010 {
11011 Handle(V3d_Light) aLightDel;
11012 if (++anArgIt >= theArgsNb)
11013 {
23fe70ec 11014 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11015 return 1;
11016 }
11017
11018 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
11019 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
11020 Standard_Integer aLightIt = 0;
6a24c6de 11021 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 11022 {
6a24c6de 11023 aLightDel = aLightIter.Value();
12381341 11024 if (aLightIt == aLightDelId)
11025 {
11026 break;
11027 }
11028 }
992ed6b3 11029 if (aLightDel.IsNull())
11030 {
11031 continue;
11032 }
11033
11034 TColStd_SequenceOfInteger aLayers;
11035 aViewer->GetAllZLayers (aLayers);
11036 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
11037 {
11038 if (aLayeriter.Value() == aLayer
11039 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
11040 {
11041 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
11042 if (!aSettings.Lights().IsNull())
11043 {
11044 aSettings.Lights()->Remove (aLightDel);
11045 if (aSettings.Lights()->IsEmpty())
11046 {
11047 aSettings.SetLights (Handle(Graphic3d_LightSet)());
11048 }
11049 }
11050 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
11051 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
11052 {
11053 break;
11054 }
11055 }
11056 }
11057
11058 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 11059 {
11060 aViewer->DelLight (aLightDel);
11061 }
11062 }
11063 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 11064 || anArgCase.IsEqual ("COLOUR")
11065 || anArgCase.IsEqual ("-COLOR")
11066 || anArgCase.IsEqual ("-COLOUR"))
12381341 11067 {
dae2a922 11068 Quantity_Color aColor;
11069 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
11070 theArgVec + anArgIt + 1,
11071 aColor);
11072 anArgIt += aNbParsed;
11073 if (aNbParsed == 0
992ed6b3 11074 || aLightCurr.IsNull())
12381341 11075 {
23fe70ec 11076 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11077 return 1;
11078 }
992ed6b3 11079 aLightCurr->SetColor (aColor);
12381341 11080 }
11081 else if (anArgCase.IsEqual ("POS")
992ed6b3 11082 || anArgCase.IsEqual ("POSITION")
11083 || anArgCase.IsEqual ("-POS")
11084 || anArgCase.IsEqual ("-POSITION"))
12381341 11085 {
992ed6b3 11086 if ((anArgIt + 3) >= theArgsNb
11087 || aLightCurr.IsNull()
11088 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11089 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11090 {
23fe70ec 11091 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11092 return 1;
11093 }
11094
11095 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11096 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11097 anXYZ[2] = Atof (theArgVec[++anArgIt]);
992ed6b3 11098 aLightCurr->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
12381341 11099 }
11100 else if (anArgCase.IsEqual ("DIR")
992ed6b3 11101 || anArgCase.IsEqual ("DIRECTION")
11102 || anArgCase.IsEqual ("-DIR")
11103 || anArgCase.IsEqual ("-DIRECTION"))
12381341 11104 {
992ed6b3 11105 if ((anArgIt + 3) >= theArgsNb
11106 || aLightCurr.IsNull()
11107 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
11108 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11109 {
23fe70ec 11110 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11111 return 1;
11112 }
11113
11114 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11115 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11116 anXYZ[2] = Atof (theArgVec[++anArgIt]);
992ed6b3 11117 aLightCurr->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
12381341 11118 }
189f85a3 11119 else if (anArgCase.IsEqual ("SM")
992ed6b3 11120 || anArgCase.IsEqual ("SMOOTHNESS")
11121 || anArgCase.IsEqual ("-SM")
11122 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 11123 {
992ed6b3 11124 if (++anArgIt >= theArgsNb
11125 || aLightCurr.IsNull())
189f85a3 11126 {
23fe70ec 11127 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 11128 return 1;
11129 }
11130
992ed6b3 11131 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11132 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 11133 {
11134 aLightCurr->SetIntensity (1.f);
11135 }
992ed6b3 11136 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 11137 {
11138 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
11139 }
11140 else
11141 {
11142 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
11143 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
11144 }
11145
992ed6b3 11146 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 11147 {
992ed6b3 11148 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 11149 }
992ed6b3 11150 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 11151 {
992ed6b3 11152 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 11153 }
11154 }
11155 else if (anArgCase.IsEqual ("INT")
992ed6b3 11156 || anArgCase.IsEqual ("INTENSITY")
11157 || anArgCase.IsEqual ("-INT")
11158 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 11159 {
992ed6b3 11160 if (++anArgIt >= theArgsNb
11161 || aLightCurr.IsNull())
189f85a3 11162 {
23fe70ec 11163 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
189f85a3 11164 return 1;
11165 }
11166
992ed6b3 11167 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11168 aLightCurr->SetIntensity (aIntensity);
189f85a3 11169 }
4fe9ad57 11170 else if (anArgCase.IsEqual ("ANG")
992ed6b3 11171 || anArgCase.IsEqual ("ANGLE")
11172 || anArgCase.IsEqual ("-ANG")
11173 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 11174 {
992ed6b3 11175 if (++anArgIt >= theArgsNb
11176 || aLightCurr.IsNull()
11177 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 11178 {
23fe70ec 11179 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4fe9ad57 11180 return 1;
11181 }
11182
992ed6b3 11183 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11184 aLightCurr->SetAngle (Standard_ShortReal (anAngle / 180.0 * M_PI));
4fe9ad57 11185 }
12381341 11186 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 11187 || anArgCase.IsEqual ("CONSTATTENUATION")
11188 || anArgCase.IsEqual ("-CONSTATTEN")
11189 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 11190 {
992ed6b3 11191 if (++anArgIt >= theArgsNb
11192 || aLightCurr.IsNull()
11193 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11194 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11195 {
23fe70ec 11196 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11197 return 1;
11198 }
11199
992ed6b3 11200 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11201 anAtten[0] = Atof (theArgVec[anArgIt]);
11202 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11203 }
11204 else if (anArgCase.IsEqual ("LINATTEN")
11205 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 11206 || anArgCase.IsEqual ("LINEARATTENUATION")
11207 || anArgCase.IsEqual ("-LINATTEN")
11208 || anArgCase.IsEqual ("-LINEARATTEN")
11209 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 11210 {
992ed6b3 11211 if (++anArgIt >= theArgsNb
11212 || aLightCurr.IsNull()
11213 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11214 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11215 {
23fe70ec 11216 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11217 return 1;
11218 }
11219
992ed6b3 11220 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11221 anAtten[1] = Atof (theArgVec[anArgIt]);
11222 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11223 }
11224 else if (anArgCase.IsEqual ("EXP")
11225 || anArgCase.IsEqual ("EXPONENT")
11226 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 11227 || anArgCase.IsEqual ("SPOTEXPONENT")
11228 || anArgCase.IsEqual ("-EXP")
11229 || anArgCase.IsEqual ("-EXPONENT")
11230 || anArgCase.IsEqual ("-SPOTEXP")
11231 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 11232 {
992ed6b3 11233 if (++anArgIt >= theArgsNb
11234 || aLightCurr.IsNull()
11235 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 11236 {
23fe70ec 11237 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11238 return 1;
11239 }
11240
992ed6b3 11241 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 11242 }
88b312d3 11243 else if (anArgCase.IsEqual("RANGE")
11244 || anArgCase.IsEqual("-RANGE"))
11245 {
11246 if (++anArgIt >= theArgsNb
11247 || aLightCurr.IsNull()
11248 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT
11249 || aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
11250 {
23fe70ec 11251 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
88b312d3 11252 return 1;
11253 }
11254
11255 aLightCurr->SetRange ((Standard_ShortReal)Atof (theArgVec[anArgIt]));
11256 }
12381341 11257 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 11258 || anArgCase.IsEqual ("HEADLIGHT")
11259 || anArgCase.IsEqual ("-HEAD")
11260 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 11261 {
992ed6b3 11262 if (aLightCurr.IsNull()
11263 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 11264 {
23fe70ec 11265 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12381341 11266 return 1;
11267 }
11268
992ed6b3 11269 Standard_Boolean isHeadLight = Standard_True;
11270 if (anArgIt + 1 < theArgsNb
dae2a922 11271 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 11272 {
992ed6b3 11273 ++anArgIt;
12381341 11274 }
992ed6b3 11275 aLightCurr->SetHeadlight (isHeadLight);
12381341 11276 }
11277 else
11278 {
23fe70ec 11279 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
12381341 11280 }
11281 }
11282
992ed6b3 11283 addLight (aLightNew, aLayer, isGlobal);
12381341 11284 return 0;
11285}
11286
67312b79 11287//===============================================================================================
11288//function : VPBREnvironment
11289//purpose :
11290//===============================================================================================
11291static int VPBREnvironment (Draw_Interpretor&,
11292 Standard_Integer theArgsNb,
11293 const char** theArgVec)
11294{
11295 if (theArgsNb > 2)
11296 {
23fe70ec 11297 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
67312b79 11298 return 1;
11299 }
11300
11301 Handle(V3d_View) aView = ViewerTest::CurrentView();
11302 if (aView.IsNull())
11303 {
23fe70ec 11304 Message::SendFail ("Error: no active viewer");
67312b79 11305 return 1;
11306 }
11307
11308 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
11309 anArg.LowerCase();
11310
11311 if (anArg == "-generate"
11312 || anArg == "-gen")
11313 {
11314 aView->GeneratePBREnvironment (Standard_True);
11315 }
11316 else if (anArg == "-clear")
11317 {
11318 aView->ClearPBREnvironment (Standard_True);
11319 }
11320 else
11321 {
23fe70ec 11322 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
67312b79 11323 return 1;
11324 }
11325
11326 return 0;
11327}
11328
15669413 11329//! Read Graphic3d_RenderingParams::PerfCounters flag.
11330static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11331 Standard_Boolean& theToReset,
11332 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11333 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11334{
11335 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11336 TCollection_AsciiString aVal = theValue;
11337 Standard_Boolean toReverse = Standard_False;
11338 if (aVal == "none")
11339 {
11340 theToReset = Standard_True;
11341 return Standard_True;
11342 }
11343 else if (aVal.StartsWith ("-"))
11344 {
11345 toReverse = Standard_True;
11346 aVal = aVal.SubString (2, aVal.Length());
11347 }
11348 else if (aVal.StartsWith ("no"))
11349 {
11350 toReverse = Standard_True;
11351 aVal = aVal.SubString (3, aVal.Length());
11352 }
11353 else if (aVal.StartsWith ("+"))
11354 {
11355 aVal = aVal.SubString (2, aVal.Length());
11356 }
11357 else
11358 {
11359 theToReset = Standard_True;
11360 }
11361
11362 if ( aVal == "fps"
11363 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11364 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11365 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11366 else if (aVal == "structs"
11367 || aVal == "structures"
11368 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11369 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11370 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11371 else if (aVal == "tris"
11372 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11373 else if (aVal == "pnts"
11374 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
b9f43ad1 11375 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
15669413 11376 else if (aVal == "mem"
11377 || aVal == "gpumem"
11378 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11379 else if (aVal == "skipimmediate"
11380 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11381 else if (aVal == "frametime"
11382 || aVal == "frametimers"
11383 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11384 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11385 else if (aVal == "extended"
11386 || aVal == "verbose"
11387 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11388 else if (aVal == "full"
11389 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11390 else
11391 {
11392 return Standard_False;
11393 }
11394
11395 if (toReverse)
11396 {
11397 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11398 }
11399 else
11400 {
11401 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11402 }
11403 return Standard_True;
11404}
11405
11406//! Read Graphic3d_RenderingParams::PerfCounters flags.
11407static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11408 Graphic3d_RenderingParams::PerfCounters& theFlags)
11409{
11410 TCollection_AsciiString aValue = theValue;
11411 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11412 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11413 Standard_Boolean toReset = Standard_False;
11414 for (;;)
11415 {
11416 Standard_Integer aSplitPos = aValue.Search ("|");
11417 if (aSplitPos <= 0)
11418 {
11419 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11420 {
11421 return Standard_False;
11422 }
11423 if (toReset)
11424 {
11425 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11426 }
11427 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11428 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11429 return Standard_True;
11430 }
11431
11432 if (aSplitPos > 1)
11433 {
11434 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11435 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11436 {
11437 return Standard_False;
11438 }
11439 }
11440 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11441 }
11442}
11443
e276548b 11444//=======================================================================
bc8c79bb 11445//function : VRenderParams
11446//purpose : Enables/disables rendering features
e276548b 11447//=======================================================================
11448
bc8c79bb 11449static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11450 Standard_Integer theArgNb,
11451 const char** theArgVec)
e276548b 11452{
7ae4a307 11453 Handle(V3d_View) aView = ViewerTest::CurrentView();
11454 if (aView.IsNull())
e276548b 11455 {
23fe70ec 11456 Message::SendFail ("Error: no active viewer");
e276548b 11457 return 1;
11458 }
bc8c79bb 11459
11460 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11461 TCollection_AsciiString aCmdName (theArgVec[0]);
11462 aCmdName.LowerCase();
11463 if (aCmdName == "vraytrace")
11464 {
11465 if (theArgNb == 1)
11466 {
11467 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11468 return 0;
11469 }
11470 else if (theArgNb == 2)
11471 {
11472 TCollection_AsciiString aValue (theArgVec[1]);
11473 aValue.LowerCase();
11474 if (aValue == "on"
11475 || aValue == "1")
11476 {
11477 aParams.Method = Graphic3d_RM_RAYTRACING;
11478 aView->Redraw();
11479 return 0;
11480 }
11481 else if (aValue == "off"
11482 || aValue == "0")
11483 {
11484 aParams.Method = Graphic3d_RM_RASTERIZATION;
11485 aView->Redraw();
11486 return 0;
11487 }
11488 else
11489 {
23fe70ec 11490 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
6b62b2da 11491 return 1;
11492 }
11493 }
11494 else
11495 {
23fe70ec 11496 Message::SendFail ("Syntax error: wrong number of arguments");
6b62b2da 11497 return 1;
11498 }
11499 }
bc8c79bb 11500
11501 if (theArgNb < 2)
e276548b 11502 {
bc8c79bb 11503 theDI << "renderMode: ";
11504 switch (aParams.Method)
11505 {
11506 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11507 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11508 }
11509 theDI << "\n";
a1073ae2 11510 theDI << "transparency: ";
11511 switch (aParams.TransparencyMethod)
11512 {
11513 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11514 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11515 << TCollection_AsciiString (aParams.OitDepthFactor); break;
11516 }
11517 theDI << "\n";
b4327ba8 11518 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11519 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11520 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11521 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11522 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
11523 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11524 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11525 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11526 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11527 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11528 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11529 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11530 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11531 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11532 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11533 theDI << "shadingModel: ";
11534 switch (aView->ShadingModel())
11535 {
67312b79 11536 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11537 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11538 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11539 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11540 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
11541 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
11542 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 11543 }
15669413 11544 {
11545 theDI << "perfCounters:";
11546 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11547 {
11548 theDI << " fps";
11549 }
11550 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11551 {
11552 theDI << " cpu";
11553 }
11554 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11555 {
11556 theDI << " structs";
11557 }
11558 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11559 {
11560 theDI << " groups";
11561 }
11562 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11563 {
11564 theDI << " arrays";
11565 }
11566 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11567 {
11568 theDI << " tris";
11569 }
b9f43ad1 11570 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
11571 {
11572 theDI << " lines";
11573 }
15669413 11574 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11575 {
11576 theDI << " pnts";
11577 }
11578 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11579 {
11580 theDI << " gpumem";
11581 }
5e30547b 11582 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11583 {
11584 theDI << " frameTime";
11585 }
11586 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11587 {
11588 theDI << " skipimmediate";
11589 }
15669413 11590 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11591 {
11592 theDI << " none";
11593 }
11594 theDI << "\n";
11595 }
f88457e6 11596 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11597 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11598 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11599 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11600 "noUpdate") << "\n";
8625ef7e 11601 theDI << "\n";
bc8c79bb 11602 return 0;
e276548b 11603 }
11604
4c7a3fae 11605 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
8625ef7e 11606 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11607 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11608 {
bc8c79bb 11609 Standard_CString anArg (theArgVec[anArgIter]);
11610 TCollection_AsciiString aFlag (anArg);
11611 aFlag.LowerCase();
8625ef7e 11612 if (anUpdateTool.parseRedrawMode (aFlag))
11613 {
11614 continue;
11615 }
11616 else if (aFlag == "-echo"
11617 || aFlag == "-print")
e276548b 11618 {
bc8c79bb 11619 toPrint = Standard_True;
8625ef7e 11620 anUpdateTool.Invalidate();
e276548b 11621 }
4c7a3fae 11622 else if (aFlag == "-reset")
11623 {
11624 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
11625 }
11626 else if (aFlag == "-sync"
11627 && (anArgIter + 1 < theArgNb))
11628 {
11629 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
11630 aSyncFlag.LowerCase();
11631 if (aSyncFlag == "default"
11632 || aSyncFlag == "defaults"
11633 || aSyncFlag == "viewer")
11634 {
11635 toSyncDefaults = true;
11636 }
11637 else if (aSyncFlag == "allviews"
11638 || aSyncFlag == "views")
11639 {
11640 toSyncAllViews = true;
11641 }
11642 else
11643 {
11644 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11645 return 1;
11646 }
11647 }
bc8c79bb 11648 else if (aFlag == "-mode"
11649 || aFlag == "-rendermode"
11650 || aFlag == "-render_mode")
e276548b 11651 {
bc8c79bb 11652 if (toPrint)
11653 {
11654 switch (aParams.Method)
11655 {
11656 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11657 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11658 }
11659 continue;
11660 }
e276548b 11661 else
bc8c79bb 11662 {
23fe70ec 11663 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11664 return 1;
11665 }
11666 }
11667 else if (aFlag == "-ray"
11668 || aFlag == "-raytrace")
11669 {
11670 if (toPrint)
11671 {
11672 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11673 continue;
11674 }
11675
4c7a3fae 11676 bool isRayTrace = true;
11677 if (anArgIter + 1 < theArgNb
dae2a922 11678 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
4c7a3fae 11679 {
11680 ++anArgIter;
11681 }
11682 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
e276548b 11683 }
bc8c79bb 11684 else if (aFlag == "-rast"
11685 || aFlag == "-raster"
11686 || aFlag == "-rasterization")
e276548b 11687 {
bc8c79bb 11688 if (toPrint)
11689 {
11690 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11691 continue;
11692 }
11693
4c7a3fae 11694 bool isRaster = true;
11695 if (anArgIter + 1 < theArgNb
dae2a922 11696 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
4c7a3fae 11697 {
11698 ++anArgIter;
11699 }
11700 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
bc8c79bb 11701 }
3c4b62a4 11702 else if (aFlag == "-msaa")
11703 {
11704 if (toPrint)
11705 {
11706 theDI << aParams.NbMsaaSamples << " ";
11707 continue;
11708 }
11709 else if (++anArgIter >= theArgNb)
11710 {
23fe70ec 11711 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3c4b62a4 11712 return 1;
11713 }
11714
11715 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11716 if (aNbSamples < 0)
11717 {
23fe70ec 11718 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
3c4b62a4 11719 return 1;
11720 }
11721 else
11722 {
11723 aParams.NbMsaaSamples = aNbSamples;
11724 }
11725 }
2a332745 11726 else if (aFlag == "-linefeather"
11727 || aFlag == "-edgefeather"
11728 || aFlag == "-feather")
11729 {
11730 if (toPrint)
11731 {
11732 theDI << " " << aParams.LineFeather << " ";
11733 continue;
11734 }
11735 else if (++anArgIter >= theArgNb)
11736 {
23fe70ec 11737 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
2a332745 11738 return 1;
11739 }
11740
11741 TCollection_AsciiString aParam = theArgVec[anArgIter];
11742 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11743 if (aFeather <= 0.0f)
11744 {
23fe70ec 11745 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
2a332745 11746 return 1;
11747 }
11748 aParams.LineFeather = aFeather;
11749 }
a1073ae2 11750 else if (aFlag == "-oit")
11751 {
11752 if (toPrint)
11753 {
11754 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11755 {
11756 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11757 }
11758 else
11759 {
11760 theDI << "off" << " ";
11761 }
11762 continue;
11763 }
11764 else if (++anArgIter >= theArgNb)
11765 {
23fe70ec 11766 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11767 return 1;
11768 }
11769
11770 TCollection_AsciiString aParam = theArgVec[anArgIter];
11771 aParam.LowerCase();
11772 if (aParam.IsRealValue())
11773 {
11774 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11775 if (aWeight < 0.f || aWeight > 1.f)
11776 {
23fe70ec 11777 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
a1073ae2 11778 return 1;
11779 }
11780
11781 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11782 aParams.OitDepthFactor = aWeight;
11783 }
11784 else if (aParam == "off")
11785 {
11786 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11787 }
11788 else
11789 {
23fe70ec 11790 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
a1073ae2 11791 return 1;
11792 }
11793 }
f88457e6 11794 else if (aFlag == "-depthprepass")
11795 {
11796 if (toPrint)
11797 {
11798 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11799 continue;
11800 }
11801 aParams.ToEnableDepthPrepass = Standard_True;
11802 if (anArgIter + 1 < theArgNb
dae2a922 11803 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
f88457e6 11804 {
11805 ++anArgIter;
11806 }
11807 }
c40eb6b9 11808 else if (aFlag == "-samplealphatocoverage"
11809 || aFlag == "-alphatocoverage")
11810 {
11811 if (toPrint)
11812 {
11813 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11814 continue;
11815 }
11816 aParams.ToEnableAlphaToCoverage = Standard_True;
11817 if (anArgIter + 1 < theArgNb
dae2a922 11818 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
c40eb6b9 11819 {
11820 ++anArgIter;
11821 }
11822 }
56689b27 11823 else if (aFlag == "-rendscale"
11824 || aFlag == "-renderscale"
11825 || aFlag == "-renderresolutionscale")
11826 {
11827 if (toPrint)
11828 {
11829 theDI << aParams.RenderResolutionScale << " ";
11830 continue;
11831 }
11832 else if (++anArgIter >= theArgNb)
11833 {
23fe70ec 11834 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
56689b27 11835 return 1;
11836 }
11837
11838 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11839 if (aScale < 0.01)
11840 {
23fe70ec 11841 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
56689b27 11842 return 1;
11843 }
11844 else
11845 {
11846 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11847 }
11848 }
bc8c79bb 11849 else if (aFlag == "-raydepth"
11850 || aFlag == "-ray_depth")
11851 {
11852 if (toPrint)
11853 {
11854 theDI << aParams.RaytracingDepth << " ";
11855 continue;
11856 }
11857 else if (++anArgIter >= theArgNb)
11858 {
23fe70ec 11859 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
bc8c79bb 11860 return 1;
11861 }
11862
11863 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
189f85a3 11864
11865 // We allow RaytracingDepth be more than 10 in case of GI enabled
11866 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
bc8c79bb 11867 {
23fe70ec 11868 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
bc8c79bb 11869 return 1;
11870 }
e276548b 11871 else
bc8c79bb 11872 {
11873 aParams.RaytracingDepth = aDepth;
11874 }
11875 }
11876 else if (aFlag == "-shad"
11877 || aFlag == "-shadows")
11878 {
11879 if (toPrint)
11880 {
11881 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11882 continue;
11883 }
11884
11885 Standard_Boolean toEnable = Standard_True;
11886 if (++anArgIter < theArgNb
dae2a922 11887 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11888 {
11889 --anArgIter;
11890 }
11891 aParams.IsShadowEnabled = toEnable;
11892 }
11893 else if (aFlag == "-refl"
11894 || aFlag == "-reflections")
11895 {
11896 if (toPrint)
11897 {
11898 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11899 continue;
11900 }
11901
11902 Standard_Boolean toEnable = Standard_True;
11903 if (++anArgIter < theArgNb
dae2a922 11904 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11905 {
11906 --anArgIter;
11907 }
11908 aParams.IsReflectionEnabled = toEnable;
11909 }
11910 else if (aFlag == "-fsaa")
11911 {
11912 if (toPrint)
11913 {
11914 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11915 continue;
11916 }
11917
11918 Standard_Boolean toEnable = Standard_True;
11919 if (++anArgIter < theArgNb
dae2a922 11920 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11921 {
11922 --anArgIter;
11923 }
11924 aParams.IsAntialiasingEnabled = toEnable;
11925 }
11926 else if (aFlag == "-gleam")
11927 {
11928 if (toPrint)
11929 {
11930 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11931 continue;
11932 }
11933
11934 Standard_Boolean toEnable = Standard_True;
11935 if (++anArgIter < theArgNb
dae2a922 11936 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
bc8c79bb 11937 {
11938 --anArgIter;
11939 }
11940 aParams.IsTransparentShadowEnabled = toEnable;
e276548b 11941 }
189f85a3 11942 else if (aFlag == "-gi")
11943 {
11944 if (toPrint)
11945 {
11946 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11947 continue;
11948 }
11949
11950 Standard_Boolean toEnable = Standard_True;
11951 if (++anArgIter < theArgNb
dae2a922 11952 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 11953 {
11954 --anArgIter;
11955 }
11956 aParams.IsGlobalIlluminationEnabled = toEnable;
11957 if (!toEnable)
11958 {
11959 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11960 }
11961 }
8c820969 11962 else if (aFlag == "-blockedrng"
11963 || aFlag == "-brng")
11964 {
11965 if (toPrint)
11966 {
11967 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11968 continue;
11969 }
11970
11971 Standard_Boolean toEnable = Standard_True;
11972 if (++anArgIter < theArgNb
dae2a922 11973 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
8c820969 11974 {
11975 --anArgIter;
11976 }
11977 aParams.CoherentPathTracingMode = toEnable;
11978 }
b09447ed 11979 else if (aFlag == "-maxrad")
11980 {
11981 if (toPrint)
11982 {
11983 theDI << aParams.RadianceClampingValue << " ";
11984 continue;
11985 }
11986 else if (++anArgIter >= theArgNb)
11987 {
23fe70ec 11988 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11989 return 1;
11990 }
11991
11992 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11993 if (!aMaxRadStr.IsRealValue())
11994 {
23fe70ec 11995 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b09447ed 11996 return 1;
11997 }
11998
11999 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
12000 if (aMaxRadiance <= 0.0)
12001 {
23fe70ec 12002 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
b09447ed 12003 return 1;
12004 }
12005 else
12006 {
12007 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
12008 }
12009 }
3a9b5dc8 12010 else if (aFlag == "-iss")
12011 {
12012 if (toPrint)
12013 {
12014 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
12015 continue;
12016 }
12017
12018 Standard_Boolean toEnable = Standard_True;
12019 if (++anArgIter < theArgNb
dae2a922 12020 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12021 {
12022 --anArgIter;
12023 }
12024 aParams.AdaptiveScreenSampling = toEnable;
12025 }
e084dbbc 12026 else if (aFlag == "-issatomic")
12027 {
12028 if (toPrint)
12029 {
12030 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
12031 continue;
12032 }
12033
12034 Standard_Boolean toEnable = Standard_True;
12035 if (++anArgIter < theArgNb
dae2a922 12036 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
e084dbbc 12037 {
12038 --anArgIter;
12039 }
12040 aParams.AdaptiveScreenSamplingAtomic = toEnable;
12041 }
3a9b5dc8 12042 else if (aFlag == "-issd")
12043 {
12044 if (toPrint)
12045 {
12046 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
12047 continue;
12048 }
12049
12050 Standard_Boolean toEnable = Standard_True;
12051 if (++anArgIter < theArgNb
dae2a922 12052 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
3a9b5dc8 12053 {
12054 --anArgIter;
12055 }
12056 aParams.ShowSamplingTiles = toEnable;
12057 }
66d1cdc6 12058 else if (aFlag == "-tilesize")
12059 {
12060 if (toPrint)
12061 {
12062 theDI << aParams.RayTracingTileSize << " ";
12063 continue;
12064 }
12065 else if (++anArgIter >= theArgNb)
12066 {
23fe70ec 12067 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
66d1cdc6 12068 return 1;
12069 }
12070
12071 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12072 if (aTileSize < 1)
12073 {
23fe70ec 12074 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
66d1cdc6 12075 return 1;
12076 }
12077 aParams.RayTracingTileSize = aTileSize;
12078 }
4eaaf9d8 12079 else if (aFlag == "-nbtiles")
12080 {
12081 if (toPrint)
12082 {
12083 theDI << aParams.NbRayTracingTiles << " ";
12084 continue;
12085 }
12086 else if (++anArgIter >= theArgNb)
12087 {
23fe70ec 12088 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4eaaf9d8 12089 return 1;
12090 }
12091
12092 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12093 if (aNbTiles < -1)
4eaaf9d8 12094 {
23fe70ec 12095 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
4eaaf9d8 12096 return 1;
12097 }
66d1cdc6 12098 else if (aNbTiles > 0
12099 && (aNbTiles < 64
12100 || aNbTiles > 1024))
4eaaf9d8 12101 {
23fe70ec 12102 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
4eaaf9d8 12103 }
66d1cdc6 12104 aParams.NbRayTracingTiles = aNbTiles;
4eaaf9d8 12105 }
189f85a3 12106 else if (aFlag == "-env")
12107 {
12108 if (toPrint)
12109 {
12110 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
12111 continue;
12112 }
12113
12114 Standard_Boolean toEnable = Standard_True;
12115 if (++anArgIter < theArgNb
dae2a922 12116 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12117 {
12118 --anArgIter;
12119 }
12120 aParams.UseEnvironmentMapBackground = toEnable;
12121 }
78607702 12122 else if (aFlag == "-ignorenormalmap")
12123 {
12124 if (toPrint)
12125 {
12126 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
12127 continue;
12128 }
12129
12130 Standard_Boolean toEnable = Standard_True;
12131 if (++anArgIter < theArgNb
dae2a922 12132 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
78607702 12133 {
12134 --anArgIter;
12135 }
12136 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
12137 }
b4327ba8 12138 else if (aFlag == "-twoside")
12139 {
12140 if (toPrint)
12141 {
12142 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12143 continue;
12144 }
12145
12146 Standard_Boolean toEnable = Standard_True;
12147 if (++anArgIter < theArgNb
dae2a922 12148 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
b4327ba8 12149 {
12150 --anArgIter;
12151 }
12152 aParams.TwoSidedBsdfModels = toEnable;
12153 }
8625ef7e 12154 else if (aFlag == "-shademodel"
12155 || aFlag == "-shadingmodel"
12156 || aFlag == "-shading")
12157 {
12158 if (toPrint)
12159 {
12160 switch (aView->ShadingModel())
12161 {
67312b79 12162 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12163 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12164 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12165 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12166 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
12167 case Graphic3d_TOSM_PBR: theDI << "pbr"; break;
12168 case Graphic3d_TOSM_PBR_FACET: theDI << "pbr_facet"; break;
8625ef7e 12169 }
12170 continue;
12171 }
12172
12173 if (++anArgIter >= theArgNb)
12174 {
23fe70ec 12175 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
8625ef7e 12176 }
12177
dc89236f 12178 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12179 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12180 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12181 {
dc89236f 12182 aView->SetShadingModel (aModel);
8625ef7e 12183 }
12184 else
12185 {
23fe70ec 12186 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
8625ef7e 12187 return 1;
12188 }
12189 }
67312b79 12190 else if (aFlag == "-pbrenvpow2size"
12191 || aFlag == "-pbrenvp2s"
12192 || aFlag == "-pep2s")
12193 {
12194 if (++anArgIter >= theArgNb)
12195 {
23fe70ec 12196 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12197 return 1;
12198 }
12199
12200 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
12201 if (aPbrEnvPow2Size < 1)
12202 {
23fe70ec 12203 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
67312b79 12204 return 1;
12205 }
12206 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
12207 }
12208 else if (aFlag == "-pbrenvspecmaplevelsnumber"
12209 || aFlag == "-pbrenvspecmapnblevels"
12210 || aFlag == "-pbrenvspecmaplevels"
12211 || aFlag == "-pbrenvsmln"
12212 || aFlag == "-pesmln")
12213 {
12214 if (++anArgIter >= theArgNb)
12215 {
23fe70ec 12216 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12217 return 1;
12218 }
12219
12220 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
12221 if (aPbrEnvSpecMapNbLevels < 2)
12222 {
23fe70ec 12223 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
67312b79 12224 return 1;
12225 }
12226 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
12227 }
12228 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
12229 || aFlag == "-pbrenvbakingdiffsamples"
12230 || aFlag == "-pbrenvbdsn")
12231 {
12232 if (++anArgIter >= theArgNb)
12233 {
23fe70ec 12234 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12235 return 1;
12236 }
12237
12238 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
12239 if (aPbrEnvBakingDiffNbSamples < 1)
12240 {
23fe70ec 12241 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environtment has to be greater or equal 1");
67312b79 12242 return 1;
12243 }
12244 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
12245 }
12246 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
12247 || aFlag == "-pbrenvbakingspecsamples"
12248 || aFlag == "-pbrenvbssn")
12249 {
12250 if (++anArgIter >= theArgNb)
12251 {
23fe70ec 12252 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12253 return 1;
12254 }
12255
12256 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
12257 if (aPbrEnvBakingSpecNbSamples < 1)
12258 {
23fe70ec 12259 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environtment has to be greater or equal 1");
67312b79 12260 return 1;
12261 }
12262 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
12263 }
12264 else if (aFlag == "-pbrenvbakingprobability"
12265 || aFlag == "-pbrenvbp")
12266 {
12267 if (++anArgIter >= theArgNb)
12268 {
23fe70ec 12269 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
67312b79 12270 return 1;
12271 }
12272 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
12273 if (aPbrEnvBakingProbability < 0.f
12274 || aPbrEnvBakingProbability > 1.f)
12275 {
23fe70ec 12276 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environtment has to be in range of [0, 1]");
67312b79 12277 return 1;
12278 }
12279 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
12280 }
4b1c8733 12281 else if (aFlag == "-resolution")
12282 {
12283 if (++anArgIter >= theArgNb)
12284 {
23fe70ec 12285 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4b1c8733 12286 return 1;
12287 }
12288
12289 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12290 if (aResolution.IsIntegerValue())
12291 {
12292 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12293 }
12294 else
12295 {
23fe70ec 12296 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
4b1c8733 12297 return 1;
12298 }
12299 }
d877e610 12300 else if (aFlag == "-rebuildglsl"
12301 || aFlag == "-rebuild")
12302 {
12303 if (toPrint)
12304 {
12305 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12306 continue;
12307 }
12308
12309 Standard_Boolean toEnable = Standard_True;
12310 if (++anArgIter < theArgNb
dae2a922 12311 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
d877e610 12312 {
12313 --anArgIter;
12314 }
12315 aParams.RebuildRayTracingShaders = toEnable;
12316 }
b27ab03d 12317 else if (aFlag == "-focal")
12318 {
12319 if (++anArgIter >= theArgNb)
12320 {
23fe70ec 12321 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12322 return 1;
12323 }
12324
12325 TCollection_AsciiString aParam (theArgVec[anArgIter]);
12326 if (aParam.IsRealValue())
12327 {
12328 float aFocalDist = static_cast<float> (aParam.RealValue());
12329 if (aFocalDist < 0)
12330 {
23fe70ec 12331 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12332 return 1;
12333 }
12334 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12335 }
12336 else
12337 {
23fe70ec 12338 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12339 return 1;
12340 }
12341 }
12342 else if (aFlag == "-aperture")
12343 {
12344 if (++anArgIter >= theArgNb)
12345 {
23fe70ec 12346 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
b27ab03d 12347 return 1;
12348 }
12349
12350 TCollection_AsciiString aParam(theArgVec[anArgIter]);
12351 if (aParam.IsRealValue())
12352 {
12353 float aApertureSize = static_cast<float> (aParam.RealValue());
12354 if (aApertureSize < 0)
12355 {
23fe70ec 12356 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
b27ab03d 12357 return 1;
12358 }
12359 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12360 }
12361 else
12362 {
23fe70ec 12363 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
b27ab03d 12364 return 1;
12365 }
12366 }
eb85ed36 12367 else if (aFlag == "-exposure")
12368 {
12369 if (++anArgIter >= theArgNb)
12370 {
23fe70ec 12371 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12372 return 1;
12373 }
12374
12375 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
12376 if (anExposure.IsRealValue())
12377 {
12378 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12379 }
12380 else
12381 {
23fe70ec 12382 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12383 return 1;
12384 }
12385 }
12386 else if (aFlag == "-whitepoint")
12387 {
12388 if (++anArgIter >= theArgNb)
12389 {
23fe70ec 12390 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12391 return 1;
12392 }
12393
12394 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
12395 if (aWhitePoint.IsRealValue())
12396 {
12397 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12398 }
12399 else
12400 {
23fe70ec 12401 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12402 return 1;
12403 }
12404 }
12405 else if (aFlag == "-tonemapping")
12406 {
12407 if (++anArgIter >= theArgNb)
12408 {
23fe70ec 12409 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
eb85ed36 12410 return 1;
12411 }
12412
12413 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12414 aMode.LowerCase();
12415
12416 if (aMode == "disabled")
12417 {
12418 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12419 }
12420 else if (aMode == "filmic")
12421 {
12422 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12423 }
12424 else
12425 {
23fe70ec 12426 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
eb85ed36 12427 return 1;
12428 }
12429 }
15669413 12430 else if (aFlag == "-performancestats"
12431 || aFlag == "-performancecounters"
12432 || aFlag == "-perfstats"
12433 || aFlag == "-perfcounters"
12434 || aFlag == "-stats")
12435 {
12436 if (++anArgIter >= theArgNb)
12437 {
23fe70ec 12438 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12439 return 1;
12440 }
12441
12442 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12443 aFlagsStr.LowerCase();
12444 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12445 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12446 {
23fe70ec 12447 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12448 return 1;
12449 }
12450 aView->ChangeRenderingParams().CollectedStats = aFlags;
12451 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12452 }
12453 else if (aFlag == "-perfupdateinterval"
12454 || aFlag == "-statsupdateinterval")
12455 {
12456 if (++anArgIter >= theArgNb)
12457 {
23fe70ec 12458 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
15669413 12459 return 1;
12460 }
12461 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12462 }
5e30547b 12463 else if (aFlag == "-perfchart"
12464 || aFlag == "-statschart")
12465 {
12466 if (++anArgIter >= theArgNb)
12467 {
23fe70ec 12468 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12469 return 1;
12470 }
12471 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12472 }
12473 else if (aFlag == "-perfchartmax"
12474 || aFlag == "-statschartmax")
12475 {
12476 if (++anArgIter >= theArgNb)
12477 {
23fe70ec 12478 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
5e30547b 12479 return 1;
12480 }
12481 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12482 }
0e3025bc 12483 else if (aFlag == "-frustumculling"
12484 || aFlag == "-culling")
12485 {
12486 if (toPrint)
12487 {
12488 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12489 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12490 "noUpdate") << " ";
12491 continue;
12492 }
12493
12494 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12495 if (++anArgIter < theArgNb)
12496 {
12497 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12498 aStateStr.LowerCase();
12499 bool toEnable = true;
dae2a922 12500 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
0e3025bc 12501 {
12502 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12503 }
12504 else if (aStateStr == "noupdate"
12505 || aStateStr == "freeze")
12506 {
12507 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12508 }
12509 else
12510 {
12511 --anArgIter;
12512 }
12513 }
12514 aParams.FrustumCullingState = aState;
12515 }
e276548b 12516 else
12517 {
23fe70ec 12518 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
bc8c79bb 12519 return 1;
e276548b 12520 }
12521 }
189f85a3 12522
4c7a3fae 12523 // set current view parameters as defaults
12524 if (toSyncDefaults)
12525 {
12526 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12527 }
12528 if (toSyncAllViews)
12529 {
12530 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12531 {
12532 aViewIter.Value()->ChangeRenderingParams() = aParams;
12533 }
12534 }
189f85a3 12535 return 0;
12536}
12537
79b544e6 12538//=======================================================================
12539//function : searchInfo
12540//purpose :
12541//=======================================================================
12542inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12543 const TCollection_AsciiString& theKey)
12544{
12545 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12546 {
12547 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12548 {
12549 return anIter.Value();
12550 }
12551 }
12552 return TCollection_AsciiString();
12553}
12554
12555//=======================================================================
12556//function : VStatProfiler
12557//purpose :
12558//=======================================================================
12559static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12560 Standard_Integer theArgNb,
12561 const char** theArgVec)
12562{
12563 Handle(V3d_View) aView = ViewerTest::CurrentView();
12564 if (aView.IsNull())
12565 {
23fe70ec 12566 Message::SendFail ("Error: no active viewer");
79b544e6 12567 return 1;
12568 }
12569
12570 Standard_Boolean toRedraw = Standard_True;
12571 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12572 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12573 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12574 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12575 {
12576 Standard_CString anArg (theArgVec[anArgIter]);
12577 TCollection_AsciiString aFlag (anArg);
12578 aFlag.LowerCase();
12579 if (aFlag == "-noredraw")
12580 {
12581 toRedraw = Standard_False;
12582 }
12583 else
12584 {
12585 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12586 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12587 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12588 else if (aFlag == "alllayers"
12589 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12590 else if (aFlag == "allstructs"
a2803f37 12591 || aFlag == "allstructures"
12592 || aFlag == "structs"
12593 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
79b544e6 12594 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12595 else if (aFlag == "allarrays"
12596 || aFlag == "fillarrays"
12597 || aFlag == "linearrays"
12598 || aFlag == "pointarrays"
12599 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12600 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
b9f43ad1 12601 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
79b544e6 12602 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12603 else if (aFlag == "geommem"
12604 || aFlag == "texturemem"
12605 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12606 else if (aFlag == "elapsedframe"
12607 || aFlag == "cpuframeaverage"
12608 || aFlag == "cpupickingaverage"
12609 || aFlag == "cpucullingaverage"
12610 || aFlag == "cpudynaverage"
12611 || aFlag == "cpuframemax"
12612 || aFlag == "cpupickingmax"
12613 || aFlag == "cpucullingmax"
12614 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12615 else
12616 {
23fe70ec 12617 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
79b544e6 12618 continue;
12619 }
12620
12621 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12622 }
12623 }
12624
12625 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12626 {
12627 aView->ChangeRenderingParams().CollectedStats =
12628 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12629
12630 if (toRedraw)
12631 {
12632 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12633 aView->Redraw();
12634 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12635 }
12636
12637 TColStd_IndexedDataMapOfStringString aDict;
12638 aView->StatisticInformation (aDict);
12639
12640 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12641
12642 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12643 {
12644 Standard_CString anArg(theArgVec[anArgIter]);
12645 TCollection_AsciiString aFlag(anArg);
12646 aFlag.LowerCase();
12647 if (aFlag == "fps")
12648 {
12649 theDI << searchInfo (aDict, "FPS") << " ";
12650 }
12651 else if (aFlag == "cpu")
12652 {
12653 theDI << searchInfo (aDict, "CPU FPS") << " ";
12654 }
12655 else if (aFlag == "alllayers")
12656 {
12657 theDI << searchInfo (aDict, "Layers") << " ";
12658 }
12659 else if (aFlag == "layers")
12660 {
12661 theDI << searchInfo (aDict, "Rendered layers") << " ";
12662 }
a2803f37 12663 else if (aFlag == "allstructs"
12664 || aFlag == "allstructures")
79b544e6 12665 {
12666 theDI << searchInfo (aDict, "Structs") << " ";
12667 }
a2803f37 12668 else if (aFlag == "structs"
12669 || aFlag == "structures")
79b544e6 12670 {
a2803f37 12671 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12672 if (aRend.IsEmpty()) // all structures rendered
12673 {
12674 aRend = searchInfo (aDict, "Structs");
12675 }
12676 theDI << aRend << " ";
79b544e6 12677 }
12678 else if (aFlag == "groups")
12679 {
12680 theDI << searchInfo (aDict, "Rendered groups") << " ";
12681 }
12682 else if (aFlag == "allarrays")
12683 {
12684 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12685 }
12686 else if (aFlag == "fillarrays")
12687 {
12688 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12689 }
12690 else if (aFlag == "linearrays")
12691 {
12692 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12693 }
12694 else if (aFlag == "pointarrays")
12695 {
12696 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12697 }
12698 else if (aFlag == "textarrays")
12699 {
12700 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12701 }
12702 else if (aFlag == "triangles")
12703 {
12704 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12705 }
12706 else if (aFlag == "points")
12707 {
12708 theDI << searchInfo (aDict, "Rendered points") << " ";
12709 }
12710 else if (aFlag == "geommem")
12711 {
12712 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12713 }
12714 else if (aFlag == "texturemem")
12715 {
12716 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12717 }
12718 else if (aFlag == "framemem")
12719 {
12720 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12721 }
12722 else if (aFlag == "elapsedframe")
12723 {
12724 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12725 }
12726 else if (aFlag == "cpuframe_average")
12727 {
12728 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12729 }
12730 else if (aFlag == "cpupicking_average")
12731 {
12732 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12733 }
12734 else if (aFlag == "cpuculling_average")
12735 {
12736 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12737 }
12738 else if (aFlag == "cpudyn_average")
12739 {
12740 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12741 }
12742 else if (aFlag == "cpuframe_max")
12743 {
12744 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12745 }
12746 else if (aFlag == "cpupicking_max")
12747 {
12748 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12749 }
12750 else if (aFlag == "cpuculling_max")
12751 {
12752 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12753 }
12754 else if (aFlag == "cpudyn_max")
12755 {
12756 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12757 }
12758 }
12759 }
12760 else
12761 {
12762 if (toRedraw)
12763 {
12764 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12765 aView->Redraw();
12766 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12767 }
12768 theDI << "Statistic info:\n" << aView->StatisticInformation();
12769 }
12770 return 0;
12771}
12772
0717ddc1 12773//=======================================================================
12774//function : VXRotate
12775//purpose :
12776//=======================================================================
12777static Standard_Integer VXRotate (Draw_Interpretor& di,
12778 Standard_Integer argc,
12779 const char ** argv)
12780{
12781 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12782 if (aContext.IsNull())
12783 {
586db386 12784 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12785 return 1;
12786 }
8693dfd0 12787
0717ddc1 12788 if (argc != 3)
12789 {
586db386 12790 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12791 return 1;
12792 }
12793
12794 TCollection_AsciiString aName (argv[1]);
12795 Standard_Real anAngle = Draw::Atof (argv[2]);
12796
12797 // find object
12798 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12799 Handle(AIS_InteractiveObject) anIObj;
8f521168 12800 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12801 {
586db386 12802 di << "Use 'vdisplay' before\n";
0717ddc1 12803 return 1;
12804 }
0717ddc1 12805
8f521168 12806 gp_Trsf aTransform;
12807 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12808 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12809
8f521168 12810 aContext->SetLocation (anIObj, aTransform);
12811 aContext->UpdateCurrentViewer();
0717ddc1 12812 return 0;
12813}
12814
625e1958 12815//===============================================================================================
12816//function : VManipulator
12817//purpose :
12818//===============================================================================================
12819static int VManipulator (Draw_Interpretor& theDi,
12820 Standard_Integer theArgsNb,
12821 const char** theArgVec)
12822{
bbf3fcde 12823 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
625e1958 12824 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
bbf3fcde 12825 if (aCurrentView.IsNull()
625e1958 12826 || aViewer.IsNull())
12827 {
23fe70ec 12828 Message::SendFail ("Error: no active viewer");
625e1958 12829 return 1;
12830 }
12831
12832 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12833 Standard_Integer anArgIter = 1;
12834 for (; anArgIter < theArgsNb; ++anArgIter)
12835 {
12836 anUpdateTool.parseRedrawMode (theArgVec[anArgIter]);
12837 }
12838
12839 ViewerTest_CmdParser aCmd;
293211ae 12840 aCmd.SetDescription ("Manages manipulator for interactive objects:");
625e1958 12841 aCmd.AddOption ("attach", "... object - attach manipulator to an object");
12842 aCmd.AddOption ("adjustPosition", "... {0|1} - adjust position when attaching");
12843 aCmd.AddOption ("adjustSize", "... {0|1} - adjust size when attaching ");
12844 aCmd.AddOption ("enableModes", "... {0|1} - enable modes when attaching ");
bbf3fcde 12845 aCmd.AddOption ("view", "... {active | [view name]} - define view in which manipulator will be displayed, 'all' by default");
625e1958 12846 aCmd.AddOption ("detach", "... - detach manipulator");
12847
12848 aCmd.AddOption ("startTransform", "... mouse_x mouse_y - invoke start transformation");
12849 aCmd.AddOption ("transform", "... mouse_x mouse_y - invoke transformation");
12850 aCmd.AddOption ("stopTransform", "... [abort] - invoke stop transformation");
12851
12852 aCmd.AddOption ("move", "... x y z - move object");
12853 aCmd.AddOption ("rotate", "... x y z dx dy dz angle - rotate object");
12854 aCmd.AddOption ("scale", "... factor - scale object");
12855
12856 aCmd.AddOption ("autoActivate", "... {0|1} - set activation on detection");
12857 aCmd.AddOption ("followTranslation", "... {0|1} - set following translation transform");
12858 aCmd.AddOption ("followRotation", "... {0|1} - set following rotation transform");
f522ce50 12859 aCmd.AddOption ("followDragging", "... {0|1} - set following dragging transform");
625e1958 12860 aCmd.AddOption ("gap", "... value - set gap between sub-parts");
12861 aCmd.AddOption ("part", "... axis mode {0|1} - set visual part");
84b904bc 12862 aCmd.AddOption ("parts", "... all axes mode {0|1} - set visual part");
625e1958 12863 aCmd.AddOption ("pos", "... x y z [nx ny nz [xx xy xz]] - set position of manipulator");
12864 aCmd.AddOption ("size", "... size - set size of manipulator");
12865 aCmd.AddOption ("zoomable", "... {0|1} - set zoom persistence");
12866
12867 aCmd.Parse (theArgsNb, theArgVec);
12868
12869 if (aCmd.HasOption ("help"))
12870 {
12871 theDi.PrintHelp (theArgVec[0]);
12872 return 0;
12873 }
12874
12875 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12876
293211ae 12877 TCollection_AsciiString aName (aCmd.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0).c_str());
625e1958 12878
12879 if (aName.IsEmpty())
12880 {
23fe70ec 12881 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
625e1958 12882 return 1;
12883 }
12884
12885 // ----------------------------------
12886 // detach existing manipulator object
12887 // ----------------------------------
12888
12889 if (aCmd.HasOption ("detach"))
12890 {
12891 if (!aMapAIS.IsBound2 (aName))
12892 {
23fe70ec 12893 Message::SendFail() << "Syntax error: could not find \"" << aName << "\" AIS object";
625e1958 12894 return 1;
12895 }
12896
12897 Handle(AIS_Manipulator) aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12898 if (aManipulator.IsNull())
12899 {
23fe70ec 12900 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
625e1958 12901 return 1;
12902 }
12903
12904 aManipulator->Detach();
12905 aMapAIS.UnBind2 (aName);
0577ae8c 12906 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_True);
625e1958 12907
12908 return 0;
12909 }
12910
12911 // -----------------------------------------------
12912 // find or create manipulator if it does not exist
12913 // -----------------------------------------------
12914
12915 Handle(AIS_Manipulator) aManipulator;
12916 if (!aMapAIS.IsBound2 (aName))
12917 {
12918 std::cout << theArgVec[0] << ": AIS object \"" << aName << "\" has been created.\n";
12919
8b037fe4 12920 aManipulator = new AIS_Manipulator();
49582f9d 12921 aManipulator->SetModeActivationOnDetection (true);
625e1958 12922 aMapAIS.Bind (aManipulator, aName);
12923 }
12924 else
12925 {
12926 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12927 if (aManipulator.IsNull())
12928 {
23fe70ec 12929 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
625e1958 12930 return 1;
12931 }
12932 }
12933
12934 // -----------------------------------------
12935 // change properties of manipulator instance
12936 // -----------------------------------------
12937
12938 if (aCmd.HasOption ("autoActivate", 1, Standard_True))
12939 {
12940 aManipulator->SetModeActivationOnDetection (aCmd.ArgBool ("autoActivate"));
12941 }
12942 if (aCmd.HasOption ("followTranslation", 1, Standard_True))
12943 {
12944 aManipulator->ChangeTransformBehavior().SetFollowTranslation (aCmd.ArgBool ("followTranslation"));
12945 }
12946 if (aCmd.HasOption ("followRotation", 1, Standard_True))
12947 {
12948 aManipulator->ChangeTransformBehavior().SetFollowRotation (aCmd.ArgBool ("followRotation"));
12949 }
f522ce50 12950 if (aCmd.HasOption("followDragging", 1, Standard_True))
12951 {
12952 aManipulator->ChangeTransformBehavior().SetFollowDragging(aCmd.ArgBool("followDragging"));
12953 }
625e1958 12954 if (aCmd.HasOption ("gap", 1, Standard_True))
12955 {
12956 aManipulator->SetGap (aCmd.ArgFloat ("gap"));
12957 }
12958 if (aCmd.HasOption ("part", 3, Standard_True))
12959 {
12960 Standard_Integer anAxis = aCmd.ArgInt ("part", 0);
12961 Standard_Integer aMode = aCmd.ArgInt ("part", 1);
12962 Standard_Boolean aOnOff = aCmd.ArgBool ("part", 2);
f522ce50 12963 if (aMode < 1 || aMode > 4)
625e1958 12964 {
23fe70ec 12965 Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
625e1958 12966 return 1;
12967 }
12968
12969 aManipulator->SetPart (anAxis, static_cast<AIS_ManipulatorMode> (aMode), aOnOff);
12970 }
84b904bc 12971 if (aCmd.HasOption("parts", 2, Standard_True))
12972 {
12973 Standard_Integer aMode = aCmd.ArgInt("parts", 0);
12974 Standard_Boolean aOnOff = aCmd.ArgBool("parts", 1);
12975 if (aMode < 1 || aMode > 4)
12976 {
23fe70ec 12977 Message::SendFail ("Syntax error: mode value should be in range [1, 4]");
84b904bc 12978 return 1;
12979 }
12980
12981 aManipulator->SetPart(static_cast<AIS_ManipulatorMode>(aMode), aOnOff);
12982 }
625e1958 12983 if (aCmd.HasOption ("pos", 3, Standard_True))
12984 {
12985 gp_Pnt aLocation = aCmd.ArgPnt ("pos", 0);
12986 gp_Dir aVDir = aCmd.HasOption ("pos", 6) ? gp_Dir (aCmd.ArgVec ("pos", 3)) : aManipulator->Position().Direction();
12987 gp_Dir aXDir = aCmd.HasOption ("pos", 9) ? gp_Dir (aCmd.ArgVec ("pos", 6)) : aManipulator->Position().XDirection();
12988
12989 aManipulator->SetPosition (gp_Ax2 (aLocation, aVDir, aXDir));
12990 }
12991 if (aCmd.HasOption ("size", 1, Standard_True))
12992 {
12993 aManipulator->SetSize (aCmd.ArgFloat ("size"));
12994 }
12995 if (aCmd.HasOption ("zoomable", 1, Standard_True))
12996 {
12997 aManipulator->SetZoomPersistence (!aCmd.ArgBool ("zoomable"));
12998
12999 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
13000 {
13001 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
13002 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
13003 }
13004 }
13005
13006 // ---------------------------------------------------
13007 // attach, detach or access manipulator from an object
13008 // ---------------------------------------------------
13009
13010 if (aCmd.HasOption ("attach"))
13011 {
13012 // Find an object and attach manipulator to it
13013 if (!aCmd.HasOption ("attach", 1, Standard_True))
13014 {
13015 return 1;
13016 }
13017
13018 TCollection_AsciiString anObjName (aCmd.Arg ("attach", 0).c_str());
8f521168 13019 Handle(AIS_InteractiveObject) anObject;
13020 if (!aMapAIS.Find2 (anObjName, anObject))
625e1958 13021 {
23fe70ec 13022 Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" does not exist";
625e1958 13023 return 1;
13024 }
13025
8b037fe4 13026 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS);
13027 anIter.More(); anIter.Next())
625e1958 13028 {
8b037fe4 13029 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
13030 if (!aManip.IsNull()
13031 && aManip->IsAttached()
13032 && aManip->Object() == anObject)
625e1958 13033 {
23fe70ec 13034 Message::SendFail() << "Syntax error: AIS object \"" << anObjName << "\" already has manipulator";
625e1958 13035 return 1;
13036 }
13037 }
13038
13039 AIS_Manipulator::OptionsForAttach anOptions;
13040 if (aCmd.HasOption ("adjustPosition", 1, Standard_True))
13041 {
13042 anOptions.SetAdjustPosition (aCmd.ArgBool ("adjustPosition"));
13043 }
13044 if (aCmd.HasOption ("adjustSize", 1, Standard_True))
13045 {
13046 anOptions.SetAdjustSize (aCmd.ArgBool ("adjustSize"));
13047 }
13048 if (aCmd.HasOption ("enableModes", 1, Standard_True))
13049 {
13050 anOptions.SetEnableModes (aCmd.ArgBool ("enableModes"));
13051 }
13052
13053 aManipulator->Attach (anObject, anOptions);
bbf3fcde 13054
13055 // Check view option
13056 if (aCmd.HasOption ("view"))
13057 {
13058 if (!aCmd.HasOption ("view", 1, Standard_True))
13059 {
13060 return 1;
13061 }
13062 TCollection_AsciiString aViewString (aCmd.Arg ("view", 0).c_str());
13063 Handle(V3d_View) aView;
13064 if (aViewString.IsEqual ("active"))
13065 {
13066 aView = ViewerTest::CurrentView();
13067 }
13068 else // Check view name
13069 {
13070 ViewerTest_Names aViewNames (aViewString);
13071 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
13072 {
23fe70ec 13073 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
bbf3fcde 13074 return 1;
13075 }
13076 aView = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
13077 if (aView.IsNull())
13078 {
23fe70ec 13079 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
bbf3fcde 13080 return 1;
13081 }
13082 }
13083 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
13084 anIter (ViewerTest_myViews); anIter.More(); anIter.Next())
13085 {
13086 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), Standard_False);
13087 }
13088 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aView, Standard_True);
13089 }
625e1958 13090 }
13091
13092 // --------------------------------------
13093 // apply transformation using manipulator
13094 // --------------------------------------
13095
13096 if (aCmd.HasOption ("startTransform", 2, Standard_True))
13097 {
13098 aManipulator->StartTransform (aCmd.ArgInt ("startTransform", 0), aCmd.ArgInt ("startTransform", 1), ViewerTest::CurrentView());
13099 }
13100 if (aCmd.HasOption ("transform", 2, Standard_True))
13101 {
13102 aManipulator->Transform (aCmd.ArgInt ("transform", 0), aCmd.ArgInt ("transform", 1), ViewerTest::CurrentView());
13103 }
13104 if (aCmd.HasOption ("stopTransform"))
13105 {
13106 Standard_Boolean toApply = !aCmd.HasOption ("stopTransform", 1) || (aCmd.Arg ("stopTransform", 0) != "abort");
13107
13108 aManipulator->StopTransform (toApply);
13109 }
13110
13111 gp_Trsf aT;
13112 if (aCmd.HasOption ("move", 3, Standard_True))
13113 {
13114 aT.SetTranslationPart (aCmd.ArgVec ("move"));
13115 }
13116 if (aCmd.HasOption ("rotate", 7, Standard_True))
13117 {
13118 aT.SetRotation (gp_Ax1 (aCmd.ArgPnt ("rotate", 0), aCmd.ArgVec ("rotate", 3)), aCmd.ArgDouble ("rotate", 6));
13119 }
13120 if (aCmd.HasOption ("scale", 1))
13121 {
13122 aT.SetScale (gp_Pnt(), aCmd.ArgDouble("scale"));
13123 }
13124
13125 if (aT.Form() != gp_Identity)
13126 {
13127 aManipulator->Transform (aT);
13128 }
13129
0577ae8c 13130 ViewerTest::GetAISContext()->Redisplay (aManipulator, Standard_True);
625e1958 13131
13132 return 0;
13133}
13134
8e5fb5ea 13135//===============================================================================================
13136//function : VSelectionProperties
13137//purpose :
13138//===============================================================================================
13139static int VSelectionProperties (Draw_Interpretor& theDi,
13140 Standard_Integer theArgsNb,
13141 const char** theArgVec)
13142{
13143 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13144 if (aCtx.IsNull())
13145 {
23fe70ec 13146 Message::SendFail ("Error: no active viewer");
8e5fb5ea 13147 return 1;
13148 }
13149
be3d8cbc 13150 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13151 {
13152 // handle obsolete alias
13153 bool toEnable = true;
13154 if (theArgsNb < 2)
13155 {
13156 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13157 return 0;
13158 }
13159 else if (theArgsNb != 2
dae2a922 13160 || !Draw::ParseOnOff (theArgVec[1], toEnable))
be3d8cbc 13161 {
23fe70ec 13162 Message::SendFail ("Syntax error: wrong number of parameters");
be3d8cbc 13163 return 1;
13164 }
13165 if (toEnable != aCtx->ToHilightSelected())
13166 {
13167 aCtx->ClearDetected();
13168 aCtx->SetToHilightSelected (toEnable);
13169 }
13170 return 0;
13171 }
13172
f838dac4 13173 Standard_Boolean toPrint = theArgsNb == 1;
13174 Standard_Boolean toRedraw = Standard_False;
13175 Standard_Integer anArgIter = 1;
13176 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13177 if (anArgIter < theArgsNb)
13178 {
13179 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13180 anArgFirst.LowerCase();
13181 ++anArgIter;
13182 if (anArgFirst == "dynhighlight"
13183 || anArgFirst == "dynhilight"
13184 || anArgFirst == "dynamichighlight"
13185 || anArgFirst == "dynamichilight")
13186 {
13187 aType = Prs3d_TypeOfHighlight_Dynamic;
13188 }
13189 else if (anArgFirst == "localdynhighlight"
13190 || anArgFirst == "localdynhilight"
13191 || anArgFirst == "localdynamichighlight"
13192 || anArgFirst == "localdynamichilight")
13193 {
13194 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13195 }
13196 else if (anArgFirst == "selhighlight"
13197 || anArgFirst == "selhilight"
13198 || anArgFirst == "selectedhighlight"
13199 || anArgFirst == "selectedhilight")
13200 {
13201 aType = Prs3d_TypeOfHighlight_Selected;
13202 }
13203 else if (anArgFirst == "localselhighlight"
13204 || anArgFirst == "localselhilight"
13205 || anArgFirst == "localselectedhighlight"
13206 || anArgFirst == "localselectedhilight")
13207 {
13208 aType = Prs3d_TypeOfHighlight_LocalSelected;
13209 }
13210 else
13211 {
13212 --anArgIter;
13213 }
13214 }
13215 for (; anArgIter < theArgsNb; ++anArgIter)
13216 {
13217 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13218 anArg.LowerCase();
13219 if (anArg == "-help")
13220 {
13221 theDi.PrintHelp (theArgVec[0]);
13222 return 0;
13223 }
13224 else if (anArg == "-print")
13225 {
13226 toPrint = Standard_True;
13227 }
13228 else if (anArg == "-autoactivate")
13229 {
13230 Standard_Boolean toEnable = Standard_True;
13231 if (anArgIter + 1 < theArgsNb
dae2a922 13232 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
f838dac4 13233 {
13234 ++anArgIter;
13235 }
13236 aCtx->SetAutoActivateSelection (toEnable);
13237 }
be3d8cbc 13238 else if (anArg == "-automatichighlight"
13239 || anArg == "-automatichilight"
13240 || anArg == "-autohighlight"
13241 || anArg == "-autohilight")
13242 {
13243 Standard_Boolean toEnable = Standard_True;
13244 if (anArgIter + 1 < theArgsNb
dae2a922 13245 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13246 {
13247 ++anArgIter;
13248 }
13249 aCtx->ClearSelected (false);
13250 aCtx->ClearDetected();
13251 aCtx->SetAutomaticHilight (toEnable);
13252 toRedraw = true;
13253 }
13254 else if (anArg == "-highlightselected"
13255 || anArg == "-hilightselected")
13256 {
13257 Standard_Boolean toEnable = Standard_True;
13258 if (anArgIter + 1 < theArgsNb
dae2a922 13259 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
be3d8cbc 13260 {
13261 ++anArgIter;
13262 }
13263 aCtx->ClearDetected();
13264 aCtx->SetToHilightSelected (toEnable);
13265 toRedraw = true;
13266 }
14c4193d 13267 else if (anArg == "-pickstrategy"
13268 || anArg == "-pickingstrategy")
13269 {
13270 if (++anArgIter >= theArgsNb)
13271 {
23fe70ec 13272 Message::SendFail ("Syntax error: type of highlighting is undefined");
14c4193d 13273 return 1;
13274 }
13275
13276 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13277 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13278 aVal.LowerCase();
13279 if (aVal == "first"
13280 || aVal == "firstaccepted"
13281 || aVal == "firstacceptable")
13282 {
13283 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13284 }
13285 else if (aVal == "topmost"
13286 || aVal == "onlyTopmost")
13287 {
13288 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13289 }
13290 else
13291 {
23fe70ec 13292 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
14c4193d 13293 return 1;
13294 }
13295
13296 aCtx->SetPickingStrategy (aStrategy);
13297 }
f838dac4 13298 else if (anArg == "-pixtol"
13299 && anArgIter + 1 < theArgsNb)
13300 {
13301 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13302 }
8c36926a 13303 else if (anArg == "-preferclosest")
13304 {
13305 bool toPreferClosest = true;
13306 if (anArgIter + 1 < theArgsNb
13307 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13308 {
13309 ++anArgIter;
13310 }
13311 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13312 }
13313 else if ((anArg == "-depthtol"
13314 || anArg == "-depthtolerance")
13315 && anArgIter + 1 < theArgsNb)
13316 {
13317 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13318 aTolType.LowerCase();
13319 if (aTolType == "uniform")
13320 {
13321 if (anArgIter + 1 >= theArgsNb)
13322 {
13323 Message::SendFail() << "Syntax error: wrong number of arguments";
13324 return 1;
13325 }
13326 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13327 Draw::Atof (theArgVec[++anArgIter]));
13328 }
13329 else if (aTolType == "uniformpx")
13330 {
13331 if (anArgIter + 1 >= theArgsNb)
13332 {
13333 Message::SendFail() << "Syntax error: wrong number of arguments";
13334 return 1;
13335 }
13336 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13337 Draw::Atof (theArgVec[++anArgIter]));
13338 }
13339 else if (aTolType == "sensfactor")
13340 {
13341 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13342 }
13343 else
13344 {
13345 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13346 return 1;
13347 }
13348 }
f838dac4 13349 else if ((anArg == "-mode"
13350 || anArg == "-dispmode")
13351 && anArgIter + 1 < theArgsNb)
13352 {
13353 if (aType == Prs3d_TypeOfHighlight_None)
13354 {
23fe70ec 13355 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13356 return 1;
13357 }
8e5fb5ea 13358
f838dac4 13359 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13360 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13361 aStyle->SetDisplayMode (aDispMode);
13362 toRedraw = Standard_True;
13363 }
13364 else if (anArg == "-layer"
13365 && anArgIter + 1 < theArgsNb)
13366 {
13367 if (aType == Prs3d_TypeOfHighlight_None)
13368 {
23fe70ec 13369 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13370 return 1;
13371 }
8e5fb5ea 13372
55c8f0f7
BB
13373 ++anArgIter;
13374 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13375 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13376 {
23fe70ec 13377 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
55c8f0f7 13378 return 1;
f838dac4 13379 }
8e5fb5ea 13380
f838dac4 13381 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13382 aStyle->SetZLayer (aNewLayer);
13383 toRedraw = Standard_True;
13384 }
13385 else if (anArg == "-hicolor"
13386 || anArg == "-selcolor"
13387 || anArg == "-color")
13388 {
13389 if (anArg.StartsWith ("-hi"))
13390 {
13391 aType = Prs3d_TypeOfHighlight_Dynamic;
13392 }
13393 else if (anArg.StartsWith ("-sel"))
13394 {
13395 aType = Prs3d_TypeOfHighlight_Selected;
13396 }
13397 else if (aType == Prs3d_TypeOfHighlight_None)
13398 {
23fe70ec 13399 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13400 return 1;
13401 }
8e5fb5ea 13402
f838dac4 13403 Quantity_Color aColor;
dae2a922 13404 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13405 theArgVec + anArgIter + 1,
13406 aColor);
f838dac4 13407 if (aNbParsed == 0)
13408 {
23fe70ec 13409 Message::SendFail ("Syntax error: need more arguments");
f838dac4 13410 return 1;
13411 }
13412 anArgIter += aNbParsed;
8e5fb5ea 13413
f838dac4 13414 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13415 aStyle->SetColor (aColor);
13416 toRedraw = Standard_True;
13417 }
13418 else if ((anArg == "-transp"
13419 || anArg == "-transparency"
13420 || anArg == "-hitransp"
13421 || anArg == "-seltransp"
13422 || anArg == "-hitransplocal"
13423 || anArg == "-seltransplocal")
13424 && anArgIter + 1 < theArgsNb)
13425 {
13426 if (anArg.StartsWith ("-hi"))
13427 {
13428 aType = Prs3d_TypeOfHighlight_Dynamic;
13429 }
13430 else if (anArg.StartsWith ("-sel"))
13431 {
13432 aType = Prs3d_TypeOfHighlight_Selected;
13433 }
13434 else if (aType == Prs3d_TypeOfHighlight_None)
13435 {
23fe70ec 13436 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13437 return 1;
13438 }
8e5fb5ea 13439
f838dac4 13440 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13441 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13442 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13443 toRedraw = Standard_True;
13444 }
13445 else if ((anArg == "-mat"
13446 || anArg == "-material")
13447 && anArgIter + 1 < theArgsNb)
13448 {
13449 if (aType == Prs3d_TypeOfHighlight_None)
13450 {
23fe70ec 13451 Message::SendFail ("Syntax error: type of highlighting is undefined");
f838dac4 13452 return 1;
13453 }
8e5fb5ea 13454
f838dac4 13455 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13456 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
a966542b 13457 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
f838dac4 13458 {
13459 ++anArgIter;
13460 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13461 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13462 Graphic3d_MaterialAspect aMat (aMatName);
13463 aMat.SetColor (aStyle->Color());
13464 aMat.SetTransparency (aStyle->Transparency());
13465 anAspect->SetFrontMaterial (aMat);
13466 anAspect->SetInteriorColor (aStyle->Color());
13467 aStyle->SetBasicFillAreaAspect (anAspect);
13468 }
13469 else
13470 {
13471 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13472 }
13473 toRedraw = Standard_True;
13474 }
13475 else
13476 {
23fe70ec 13477 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
8c36926a 13478 return 1;
f838dac4 13479 }
8e5fb5ea 13480 }
13481
f838dac4 13482 if (toPrint)
8e5fb5ea 13483 {
f838dac4 13484 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13485 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13486 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13487 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13488 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13489 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13490 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13491 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13492 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13493 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13494 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13495 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13496 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13497 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13498 }
13499
13500 if (aCtx->NbSelected() != 0 && toRedraw)
13501 {
13502 aCtx->HilightSelected (Standard_True);
13503 }
13504
13505 return 0;
13506}
13507
decdee7d 13508//===============================================================================================
13509//function : VDumpSelectionImage
13510//purpose :
13511//===============================================================================================
13512static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13513 Standard_Integer theArgsNb,
13514 const char** theArgVec)
13515{
13516 if (theArgsNb < 2)
13517 {
23fe70ec 13518 Message::SendFail() << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'";
decdee7d 13519 return 1;
13520 }
13521
13522 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
b40cdc2b 13523 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
decdee7d 13524 if (aContext.IsNull())
13525 {
23fe70ec 13526 Message::SendFail ("Error: no active viewer");
decdee7d 13527 return 1;
13528 }
13529
13530 TCollection_AsciiString aFile;
13531 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
b40cdc2b 13532 Handle(Graphic3d_Camera) aCustomCam;
dc858f4c 13533 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13534 Standard_Integer aPickedIndex = 1;
13535 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13536 {
13537 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13538 aParam.LowerCase();
13539 if (aParam == "-type")
13540 {
13541 if (++anArgIter >= theArgsNb)
13542 {
23fe70ec 13543 Message::SendFail ("Syntax error: wrong number parameters of flag '-depth'");
decdee7d 13544 return 1;
13545 }
13546
13547 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13548 aValue.LowerCase();
13549 if (aValue == "depth"
13550 || aValue == "normdepth"
13551 || aValue == "normalizeddepth")
13552 {
13553 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13554 anImgFormat = Image_Format_GrayF;
decdee7d 13555 }
13556 if (aValue == "depthinverted"
13557 || aValue == "normdepthinverted"
13558 || aValue == "normalizeddepthinverted"
13559 || aValue == "inverted")
13560 {
13561 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13562 anImgFormat = Image_Format_GrayF;
decdee7d 13563 }
13564 else if (aValue == "unnormdepth"
13565 || aValue == "unnormalizeddepth")
13566 {
13567 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13568 anImgFormat = Image_Format_GrayF;
decdee7d 13569 }
13570 else if (aValue == "objectcolor"
13571 || aValue == "object"
13572 || aValue == "color")
13573 {
13574 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13575 }
13576 else if (aValue == "entitycolor"
13577 || aValue == "entity")
13578 {
13579 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13580 }
13581 else if (aValue == "ownercolor"
13582 || aValue == "owner")
13583 {
13584 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13585 }
13586 else if (aValue == "selectionmodecolor"
13587 || aValue == "selectionmode"
13588 || aValue == "selmodecolor"
13589 || aValue == "selmode")
13590 {
13591 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13592 }
13593 }
13594 else if (aParam == "-picked"
13595 || aParam == "-pickeddepth"
13596 || aParam == "-pickedindex")
13597 {
13598 if (++anArgIter >= theArgsNb)
13599 {
23fe70ec 13600 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
decdee7d 13601 return 1;
13602 }
13603
13604 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13605 }
b40cdc2b 13606 else if (anArgIter + 1 < theArgsNb
13607 && aParam == "-xrpose")
13608 {
13609 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13610 anXRArg.LowerCase();
13611 if (anXRArg == "base")
13612 {
13613 aCustomCam = aView->View()->BaseXRCamera();
13614 }
13615 else if (anXRArg == "head")
13616 {
13617 aCustomCam = aView->View()->PosedXRCamera();
13618 }
13619 else
13620 {
13621 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13622 return 1;
13623 }
13624 if (aCustomCam.IsNull())
13625 {
13626 Message::SendFail() << "Error: undefined XR pose";
13627 return 0;
13628 }
13629 }
decdee7d 13630 else if (aFile.IsEmpty())
13631 {
13632 aFile = theArgVec[anArgIter];
13633 }
13634 else
13635 {
23fe70ec 13636 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
decdee7d 13637 return 1;
13638 }
13639 }
13640 if (aFile.IsEmpty())
13641 {
23fe70ec 13642 Message::SendFail ("Syntax error: image file name is missing");
decdee7d 13643 return 1;
13644 }
13645
decdee7d 13646 Standard_Integer aWidth = 0, aHeight = 0;
13647 aView->Window()->Size (aWidth, aHeight);
13648
13649 Image_AlienPixMap aPixMap;
13650 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13651 {
23fe70ec 13652 Message::SendFail ("Error: can't allocate image");
decdee7d 13653 return 1;
13654 }
b40cdc2b 13655
13656 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13657 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13658 if (!aCustomCam.IsNull())
13659 {
13660 aView->SetCamera (aCustomCam);
13661 }
decdee7d 13662 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13663 {
23fe70ec 13664 Message::SendFail ("Error: can't generate selection image");
decdee7d 13665 return 1;
13666 }
b40cdc2b 13667 if (!aCustomCam.IsNull())
13668 {
13669 aView->SetCamera (aCamBack);
13670 }
13671 aView->SetImmediateUpdate (wasImmUpdate);
13672
decdee7d 13673 if (!aPixMap.Save (aFile))
13674 {
23fe70ec 13675 Message::SendFail ("Error: can't save selection image");
decdee7d 13676 return 0;
13677 }
13678 return 0;
13679}
13680
2108d9a2 13681//===============================================================================================
13682//function : VViewCube
13683//purpose :
13684//===============================================================================================
13685static int VViewCube (Draw_Interpretor& ,
13686 Standard_Integer theNbArgs,
13687 const char** theArgVec)
13688{
13689 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13690 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13691 if (aContext.IsNull() || aView.IsNull())
13692 {
23fe70ec 13693 Message::SendFail ("Error: no active viewer");
2108d9a2 13694 return 1;
13695 }
13696 else if (theNbArgs < 2)
13697 {
23fe70ec 13698 Message::SendFail ("Syntax error: wrong number arguments");
2108d9a2 13699 return 1;
13700 }
13701
13702 Handle(AIS_ViewCube) aViewCube;
13703 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13704 Quantity_Color aColorRgb;
13705 TCollection_AsciiString aName;
13706 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13707 {
13708 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13709 anArg.LowerCase();
13710 if (anUpdateTool.parseRedrawMode (anArg))
13711 {
13712 //
13713 }
13714 else if (aViewCube.IsNull())
13715 {
13716 aName = theArgVec[anArgIter];
13717 if (aName.StartsWith ("-"))
13718 {
23fe70ec 13719 Message::SendFail ("Syntax error: object name should be specified");
2108d9a2 13720 return 1;
13721 }
13722 Handle(AIS_InteractiveObject) aPrs;
13723 GetMapOfAIS().Find2 (aName, aPrs);
13724 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13725 if (aViewCube.IsNull())
13726 {
13727 aViewCube = new AIS_ViewCube();
13728 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13729 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13730 aViewCube->SetFixedAnimationLoop (false);
13731 }
13732 }
13733 else if (anArg == "-reset")
13734 {
13735 aViewCube->ResetStyles();
13736 }
13737 else if (anArg == "-color"
13738 || anArg == "-boxcolor"
13739 || anArg == "-boxsidecolor"
13740 || anArg == "-sidecolor"
13741 || anArg == "-boxedgecolor"
13742 || anArg == "-edgecolor"
13743 || anArg == "-boxcornercolor"
13744 || anArg == "-cornercolor"
13745 || anArg == "-innercolor"
13746 || anArg == "-textcolor")
13747 {
dae2a922 13748 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13749 theArgVec + anArgIter + 1,
13750 aColorRgb);
2108d9a2 13751 if (aNbParsed == 0)
13752 {
23fe70ec 13753 Message::SendFail() << "Syntax error at '" << anArg << "'";
2108d9a2 13754 return 1;
13755 }
13756 anArgIter += aNbParsed;
13757 if (anArg == "-boxcolor")
13758 {
13759 aViewCube->SetBoxColor (aColorRgb);
13760 }
13761 else if (anArg == "-boxsidecolor"
13762 || anArg == "-sidecolor")
13763 {
13764 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13765 aViewCube->SynchronizeAspects();
13766 }
13767 else if (anArg == "-boxedgecolor"
13768 || anArg == "-edgecolor")
13769 {
13770 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13771 aViewCube->SynchronizeAspects();
13772 }
13773 else if (anArg == "-boxcornercolor"
13774 || anArg == "-cornercolor")
13775 {
13776 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13777 aViewCube->SynchronizeAspects();
13778 }
13779 else if (anArg == "-innercolor")
13780 {
13781 aViewCube->SetInnerColor (aColorRgb);
13782 }
13783 else if (anArg == "-textcolor")
13784 {
13785 aViewCube->SetTextColor (aColorRgb);
13786 }
13787 else
13788 {
13789 aViewCube->SetColor (aColorRgb);
13790 }
13791 }
13792 else if (anArgIter + 1 < theNbArgs
13793 && (anArg == "-transparency"
13794 || anArg == "-boxtransparency"))
13795 {
13796 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13797 if (aValue < 0.0 || aValue > 1.0)
13798 {
23fe70ec 13799 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
2108d9a2 13800 return 1;
13801 }
13802
13803 if (anArg == "-boxtransparency")
13804 {
13805 aViewCube->SetBoxTransparency (aValue);
13806 }
13807 else
13808 {
13809 aViewCube->SetTransparency (aValue);
13810 }
13811 }
13812 else if (anArg == "-axes"
13813 || anArg == "-edges"
13814 || anArg == "-vertices"
13815 || anArg == "-vertexes"
13816 || anArg == "-fixedanimation")
13817 {
13818 bool toShow = true;
13819 if (anArgIter + 1 < theNbArgs
dae2a922 13820 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
2108d9a2 13821 {
13822 ++anArgIter;
13823 }
13824 if (anArg == "-fixedanimation")
13825 {
13826 aViewCube->SetFixedAnimationLoop (toShow);
13827 }
13828 else if (anArg == "-axes")
13829 {
13830 aViewCube->SetDrawAxes (toShow);
13831 }
13832 else if (anArg == "-edges")
13833 {
13834 aViewCube->SetDrawEdges (toShow);
13835 }
13836 else
13837 {
13838 aViewCube->SetDrawVertices (toShow);
13839 }
13840 }
13841 else if (anArg == "-yup"
13842 || anArg == "-zup")
13843 {
13844 bool isOn = true;
13845 if (anArgIter + 1 < theNbArgs
dae2a922 13846 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
2108d9a2 13847 {
13848 ++anArgIter;
13849 }
13850 if (anArg == "-yup")
13851 {
13852 aViewCube->SetYup (isOn);
13853 }
13854 else
13855 {
13856 aViewCube->SetYup (!isOn);
13857 }
13858 }
13859 else if (anArgIter + 1 < theNbArgs
13860 && anArg == "-font")
13861 {
13862 aViewCube->SetFont (theArgVec[++anArgIter]);
13863 }
13864 else if (anArgIter + 1 < theNbArgs
13865 && anArg == "-fontheight")
13866 {
13867 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13868 }
13869 else if (anArgIter + 1 < theNbArgs
13870 && (anArg == "-size"
13871 || anArg == "-boxsize"))
13872 {
13873 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13874 anArg != "-boxsize");
13875 }
13876 else if (anArgIter + 1 < theNbArgs
13877 && (anArg == "-boxfacet"
13878 || anArg == "-boxfacetextension"
13879 || anArg == "-facetextension"
13880 || anArg == "-extension"))
13881 {
13882 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13883 }
13884 else if (anArgIter + 1 < theNbArgs
13885 && (anArg == "-boxedgegap"
13886 || anArg == "-edgegap"))
13887 {
13888 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13889 }
13890 else if (anArgIter + 1 < theNbArgs
13891 && (anArg == "-boxedgeminsize"
13892 || anArg == "-edgeminsize"))
13893 {
13894 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
13895 }
13896 else if (anArgIter + 1 < theNbArgs
13897 && (anArg == "-boxcornerminsize"
13898 || anArg == "-cornerminsize"))
13899 {
13900 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
13901 }
13902 else if (anArgIter + 1 < theNbArgs
13903 && anArg == "-axespadding")
13904 {
13905 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
13906 }
13907 else if (anArgIter + 1 < theNbArgs
13908 && anArg == "-roundradius")
13909 {
13910 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
13911 }
13912 else if (anArgIter + 1 < theNbArgs
13913 && anArg == "-duration")
13914 {
13915 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
13916 }
6466cc9e 13917 else if (anArgIter + 1 < theNbArgs
13918 && anArg == "-axesradius")
13919 {
13920 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
13921 }
13922 else if (anArgIter + 1 < theNbArgs
13923 && anArg == "-axesconeradius")
13924 {
13925 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
13926 }
13927 else if (anArgIter + 1 < theNbArgs
13928 && anArg == "-axessphereradius")
13929 {
13930 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
13931 }
2108d9a2 13932 else
13933 {
23fe70ec 13934 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
2108d9a2 13935 return 1;
13936 }
13937 }
13938 if (aViewCube.IsNull())
13939 {
23fe70ec 13940 Message::SendFail ("Syntax error: wrong number of arguments");
2108d9a2 13941 return 1;
13942 }
13943
13944 ViewerTest::Display (aName, aViewCube, false);
13945 return 0;
13946}
13947
14b741b0 13948//===============================================================================================
13949//function : VColorConvert
13950//purpose :
13951//===============================================================================================
13952static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13953{
13954 if (theNbArgs != 6)
13955 {
13956 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13957 return 1;
13958 }
13959
13960 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
13961 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
13962 {
13963 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
13964 return 1;
13965 }
13966
13967 const char* aTypeStr = theArgVec[2];
13968 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
13969 if (! strcasecmp (aTypeStr, "srgb"))
13970 {
13971 aType = Quantity_TOC_sRGB;
13972 }
13973 else if (! strcasecmp (aTypeStr, "hls"))
13974 {
13975 aType = Quantity_TOC_HLS;
13976 }
13977 else if (! strcasecmp (aTypeStr, "lab"))
13978 {
13979 aType = Quantity_TOC_CIELab;
13980 }
13981 else if (! strcasecmp (aTypeStr, "lch"))
13982 {
13983 aType = Quantity_TOC_CIELch;
13984 }
13985 else
13986 {
13987 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
13988 return 1;
13989 }
13990
13991 double aC1 = Draw::Atof (theArgVec[3]);
13992 double aC2 = Draw::Atof (theArgVec[4]);
13993 double aC3 = Draw::Atof (theArgVec[5]);
13994
13995 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
13996 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
13997
13998 // print values with 6 decimal digits
13999 char buffer[1024];
14000 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
14001 theDI << buffer;
14002
14003 return 0;
14004}
14005
14006//===============================================================================================
14007//function : VColorDiff
14008//purpose :
14009//===============================================================================================
14010static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
14011{
14012 if (theNbArgs != 7)
14013 {
14014 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
14015 return 1;
14016 }
14017
14018 double aR1 = Draw::Atof (theArgVec[1]);
14019 double aG1 = Draw::Atof (theArgVec[2]);
14020 double aB1 = Draw::Atof (theArgVec[3]);
14021 double aR2 = Draw::Atof (theArgVec[4]);
14022 double aG2 = Draw::Atof (theArgVec[5]);
14023 double aB2 = Draw::Atof (theArgVec[6]);
14024
14025 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
14026 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
14027
14028 theDI << aColor1.DeltaE2000 (aColor2);
14029
14030 return 0;
14031}
14032
6a2fb7a1 14033//===============================================================================================
14034//function : VBVHPrebuid
14035//purpose :
14036//===============================================================================================
14037static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
14038{
14039 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
14040 if (aCtx.IsNull())
14041 {
14042 Message::SendFail ("Error: no active viewer");
14043 return 1;
14044 }
14045
14046 if (theNbArgs < 2)
14047 {
14048 Message::SendFail ("Error: command syntax is incorrect, see help");
14049 return 1;
14050 }
14051
14052 Standard_Integer toEnable = -1;
14053 Standard_Integer aThreadsNb = -1;
14054 Standard_Boolean toWait = Standard_False;
14055
14056 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
14057 {
14058 TCollection_AsciiString anArg (theArgVec[anArgIter]);
14059 anArg.LowerCase();
14060
14061 if (anArg == "-nbthreads"
14062 && anArgIter + 1 < theNbArgs)
14063 {
14064 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
14065 if (aThreadsNb < 1)
14066 {
14067 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
14068 }
14069 }
14070 else if (anArg == "-wait")
14071 {
14072 toWait = Standard_True;
14073 }
14074 else if (toEnable == -1)
14075 {
14076 Standard_Boolean toEnableValue = Standard_True;
14077 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
14078 {
14079 toEnable = toEnableValue ? 1 : 0;
14080 }
14081 else
14082 {
14083 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14084 return 1;
14085 }
14086 }
14087 else
14088 {
14089 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
14090 return 1;
14091 }
14092 }
14093
14094 if (aThreadsNb == -1)
14095 {
14096 aThreadsNb = 1;
14097 }
14098 if (toEnable != -1)
14099 {
14100 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
14101 }
14102 if (toWait)
14103 {
14104 aCtx->MainSelector()->WaitForBVHBuild();
14105 }
14106
14107 return 0;
14108}
14109
7fd59977 14110//=======================================================================
14111//function : ViewerCommands
14112//purpose :
14113//=======================================================================
14114
14115void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14116{
14117
14118 const char *group = "ZeViewer";
18d715bd 14119 theCommands.Add("vinit",
fd3f6bd0 14120 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
2e93433e 14121 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-2d_mode {on|off}=off]"
fd3f6bd0 14122 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14123 "\n\t\t: [-display displayName]"
14124 #endif
14125 "\n\t\t: Creates new View window with specified name viewName."
14126 "\n\t\t: By default the new view is created in the viewer and in"
14127 "\n\t\t: graphic driver shared with active view."
14128 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
14129 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
14130 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
14131#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
14132 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
14133 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 14134#endif
fd3f6bd0 14135 "\n\t\t: -left, -top pixel position of left top corner of the window."
14136 "\n\t\t: -width, -height width and heigth of window respectively."
9e04ccdc 14137 "\n\t\t: -cloneActive floag to copy camera and dimensions of active view."
fd3f6bd0 14138 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
14139 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
2e93433e 14140 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 14141 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 14142 __FILE__,VInit,group);
18d715bd 14143 theCommands.Add("vclose" ,
d0cc1cb7 14144 "[view_id [keep_context=0|1]]\n"
18d715bd 14145 "or vclose ALL - to remove all created views\n"
14146 " - removes view(viewer window) defined by its view_id.\n"
14147 " - keep_context: by default 0; if 1 and the last view is deleted"
14148 " the current context is not removed.",
14149 __FILE__,VClose,group);
14150 theCommands.Add("vactivate" ,
e084dbbc 14151 "vactivate view_id [-noUpdate]"
18d715bd 14152 " - activates view(viewer window) defined by its view_id",
14153 __FILE__,VActivate,group);
14154 theCommands.Add("vviewlist",
14155 "vviewlist [format={tree, long}]"
14156 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
14157 " - format: format of result output, if tree the output is a tree view;"
14158 "otherwise it's a list of full view names. By default format = tree",
14159 __FILE__,VViewList,group);
7fd59977 14160 theCommands.Add("vhelp" ,
14161 "vhelp : display help on the viewer commands",
14162 __FILE__,VHelp,group);
fc552d84 14163 theCommands.Add("vviewproj",
14164 "vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
14165 "\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
14166 "\n\t\t: Setup view direction"
14167 "\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
14168 "\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
14169 "\n\t\t: for example '+Z' will show front of the model,"
14170 "\n\t\t: '-X-Y+Z' will define left axonometrical view."
14171 "\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
14172 "\n\t\t: for example '+X+Z' will show front of the model with Z-up."
14173 __FILE__,VViewProj,group);
7fd59977 14174 theCommands.Add("vtop" ,
27af3052 14175 "vtop or <T> : Top view. Orientation +X+Y" ,
fc552d84 14176 __FILE__,VViewProj,group);
44b8f2d6 14177 theCommands.Add("vbottom" ,
27af3052 14178 "vbottom : Bottom view. Orientation +X-Y" ,
fc552d84 14179 __FILE__,VViewProj,group);
44b8f2d6 14180 theCommands.Add("vleft" ,
27af3052 14181 "vleft : Left view. Orientation -Y+Z" ,
fc552d84 14182 __FILE__,VViewProj,group);
44b8f2d6 14183 theCommands.Add("vright" ,
27af3052 14184 "vright : Right view. Orientation +Y+Z" ,
fc552d84 14185 __FILE__,VViewProj,group);
7fd59977 14186 theCommands.Add("vaxo" ,
27af3052 14187 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
fc552d84 14188 __FILE__,VViewProj,group);
44b8f2d6 14189 theCommands.Add("vfront" ,
27af3052 14190 "vfront : Front view. Orientation +X+Z" ,
fc552d84 14191 __FILE__,VViewProj,group);
44b8f2d6 14192 theCommands.Add("vback" ,
27af3052 14193 "vback : Back view. Orientation -X+Z" ,
fc552d84 14194 __FILE__,VViewProj,group);
7fd59977 14195 theCommands.Add("vpick" ,
14196 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
14197 VPick,group);
1beb58d7 14198 theCommands.Add("vfit",
14199 "vfit or <F> [-selected] [-noupdate]"
b586500b 14200 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 14201 __FILE__,VFit,group);
6262a303 14202 theCommands.Add ("vfitarea",
14203 "vfitarea x1 y1 x2 y2"
14204 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
14205 "\n\t\t: Fit view to show area located between two points"
14206 "\n\t\t: given in world 2D or 3D corrdinates.",
14207 __FILE__, VFitArea, group);
197ac94e 14208 theCommands.Add ("vzfit", "vzfit [scale]\n"
14209 " Matches Z near, Z far view volume planes to the displayed objects.\n"
14210 " \"scale\" - specifies factor to scale computed z range.\n",
14211 __FILE__, VZFit, group);
7fd59977 14212 theCommands.Add("vrepaint",
8693dfd0 14213 "vrepaint [-immediate] [-continuous FPS]"
14214 "\n\t\t: force redraw of active View"
14215 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
14216 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
14217 "\n\t\t: 0 means no continuous rendering,"
14218 "\n\t\t: -1 means non-stop redraws,"
14219 "\n\t\t: >0 specifies target framerate,",
7fd59977 14220 __FILE__,VRepaint,group);
14221 theCommands.Add("vclear",
faea8b40 14222 "vclear : vclear"
14223 "\n\t\t: remove all the object from the viewer",
7fd59977 14224 __FILE__,VClear,group);
293211ae 14225 theCommands.Add (
14226 "vbackground",
14227 "Changes background or some background settings.\n"
14228 "\n"
14229 "Usage:\n"
14230 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
14231 " vbackground -imageMode FillType\n"
14232 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
14233 " vbackground -gradientMode FillMethod\n"
077a220c 14234 " vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
293211ae 14235 " vbackground -color Color\n"
14236 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
14237 " vbackground -default -color Color\n"
14238 " vbackground -help\n"
14239 "\n"
14240 "Options:\n"
14241 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
14242 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
14243 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
14244 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
077a220c 14245 " -cubemap (-cmap, -cm): sets environmet cubemap as background\n"
14246 " -invertedz (-invz, -iz): sets inversion of Z axis for background cubemap rendering\n"
14247 " -order (-o): defines order of tiles in one image cubemap\n"
14248 " (has no effect in case of multi image cubemaps)\n"
293211ae 14249 " -color (-col): sets background color\n"
14250 " -default (-def): sets background default gradient or color\n"
14251 " -help (-h): outputs short help message\n"
14252 "\n"
14253 "Arguments:\n"
077a220c 14254 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
293211ae 14255 " or reals within the range [0.0, 1.0]\n"
077a220c 14256 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
14257 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
14258 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
293211ae 14259 "CORNER4\n"
077a220c 14260 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
14261 " ImageFile: a name of the file with the image used as a background\n"
14262 " CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
14263 " TileIndexi: a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
293211ae 14264 __FILE__,
14265 vbackground,
14266 group);
14267 theCommands.Add ("vsetbg",
14268 "Loads image as background."
14269 "\n\t\t: vsetbg ImageFile [FillType]"
14270 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
14271 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
14272 __FILE__,
14273 vbackground,
14274 group);
14275 theCommands.Add ("vsetbgmode",
14276 "Changes background image fill type."
14277 "\n\t\t: vsetbgmode [-imageMode] FillType"
14278 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
14279 __FILE__,
14280 vbackground,
14281 group);
14282 theCommands.Add ("vsetgradientbg",
14283 "Mounts gradient background."
14284 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
14285 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14286 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
14287 __FILE__,
14288 vbackground,
14289 group);
14290 theCommands.Add ("vsetgrbgmode",
14291 "Changes gradient background fill method."
14292 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
14293 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
14294 __FILE__,
14295 vbackground,
14296 group);
14297 theCommands.Add ("vsetcolorbg",
14298 "Sets background color."
14299 "\n\t\t: vsetcolorbg [-color] Color."
14300 "\n\t\t: Alias for 'vbackground -color Color'.",
14301 __FILE__,
14302 vbackground,
14303 group);
14304 theCommands.Add ("vsetdefaultbg",
14305 "Sets default viewer background fill color (flat/gradient)."
14306 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
14307 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
14308 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
14309 "\n\t\t: vsetdefaultbg [-color] Color"
14310 "\n\t\t: Alias for 'vbackground -default -color Color'.",
14311 __FILE__,
14312 vbackground,
14313 group);
7fd59977 14314 theCommands.Add("vscale",
14315 "vscale : vscale X Y Z",
14316 __FILE__,VScale,group);
14317 theCommands.Add("vzbufftrihedron",
536d98e2 14318 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
14319 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
14320 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
14321 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
14322 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
14323 "\n\t\t: Displays a trihedron",
14324 __FILE__,VZBuffTrihedron,group);
7fd59977 14325 theCommands.Add("vrotate",
4af098ba 14326 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
14327 "\n : Option -mouseStart starts rotation according to the mouse position"
14328 "\n : Option -mouseMove continues rotation with angle computed"
14329 "\n : from last and new mouse position."
14330 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 14331 __FILE__,VRotate,group);
14332 theCommands.Add("vzoom",
14333 "vzoom : vzoom coef",
14334 __FILE__,VZoom,group);
14335 theCommands.Add("vpan",
14336 "vpan : vpan dx dy",
14337 __FILE__,VPan,group);
7fd59977 14338 theCommands.Add("vcolorscale",
4b3d6eb1 14339 "vcolorscale name [-noupdate|-update] [-demo]"
14340 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
14341 "\n\t\t: [-font HeightFont=20]"
14342 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
14343 "\n\t\t: [-smoothTransition {on|off}=off]"
14344 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
14345 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
14346 "\n\t\t: [-textpos {left|right|center|none}=right]"
14347 "\n\t\t: [-labelAtBorder {on|off}=on]"
14348 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
14349 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
14350 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
14351 "\n\t\t: [-xy Left=0 Bottom=0]"
14b741b0 14352 "\n\t\t: [-uniform lightness hue_from hue_to]"
4b3d6eb1 14353 "\n\t\t: -demo - displays a color scale with demonstratio values"
14354 "\n\t\t: -colors - set colors for all intervals"
14355 "\n\t\t: -color - set color for specific interval"
14b741b0 14356 "\n\t\t: -uniform - generate colors with the same lightness"
4b3d6eb1 14357 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
14358 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
14359 "\n\t\t: at border means the value inbetween neighbor intervals,"
14360 "\n\t\t: at center means the center value within current interval"
14361 "\n\t\t: -labels - set labels for all intervals"
14362 "\n\t\t: -freeLabels - same as -labels but does not require"
14363 "\n\t\t: matching the number of intervals"
14364 "\n\t\t: -label - set label for specific interval"
14365 "\n\t\t: -title - set title"
14366 "\n\t\t: -reversed - setup smooth color transition between intervals"
14367 "\n\t\t: -smoothTransition - swap colorscale direction"
14b741b0 14368 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values",
4b3d6eb1 14369 __FILE__, VColorScale, group);
7fd59977 14370 theCommands.Add("vgraduatedtrihedron",
a79f67f8 14371 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
14372 "\t[-namefont Name] [-valuesfont Name]\n"
14373 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
14374 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
14375 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
14376 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
14377 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
14378 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
14379 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
14380 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
14381 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 14382 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 14383 " - Displays or erases graduated trihedron"
14384 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
14385 " - namefont - font of axes names. Default: Arial\n"
14386 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
14387 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
14388 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
14389 " - valuesfont - font of axes values. Default: Arial\n"
14390 " - xcolor, ycolor, zcolor - color of axis and values\n"
14391 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
14392 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 14393 __FILE__,VGraduatedTrihedron,group);
3bffef55 14394 theCommands.Add("vtile" ,
14395 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
14396 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
14397 "\n\t\t: -totalSize the size of virtual bigger viewport"
14398 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
14399 "\n\t\t: -lowerLeft tile offset as lower left corner"
14400 "\n\t\t: -upperLeft tile offset as upper left corner",
14401 __FILE__, VTile, group);
59f45b7c 14402 theCommands.Add("vzlayer",
7c3ef2f7 14403 "vzlayer [layerId]"
1c728f2d 14404 "\n\t\t: [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]"
4ecf34cc 14405 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 14406 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
1c728f2d 14407 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]"
7c3ef2f7 14408 "\n\t\t: ZLayer list management:"
14409 "\n\t\t: -add add new z layer to viewer and print its id"
1c728f2d 14410 "\n\t\t: -insertBefore add new z layer and insert it before existing one"
14411 "\n\t\t: -insertAfter add new z layer and insert it after existing one"
7c3ef2f7 14412 "\n\t\t: -delete delete z layer"
14413 "\n\t\t: -get print sequence of z layers"
14414 "\n\t\t: -settings print status of z layer settings"
14415 "\n\t\t: -disable disables given setting"
14416 "\n\t\t: -enable enables given setting",
59f45b7c 14417 __FILE__,VZLayer,group);
20637bd2 14418 theCommands.Add("vlayerline",
14419 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
14420 __FILE__,VLayerLine,group);
79931835 14421 theCommands.Add("vgrid",
14422 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
14423 "\n\t\t: [-step X Y] [-size DX DY]"
14424 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 14425 __FILE__, VGrid, group);
c40b7d58 14426 theCommands.Add ("vpriviledgedplane",
14427 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
14428 "\n\t\t: Ox, Oy, Oz - plane origin"
14429 "\n\t\t: Nx, Ny, Nz - plane normal direction"
14430 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
14431 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
14432 __FILE__, VPriviledgedPlane, group);
f25b82d6 14433 theCommands.Add ("vconvert",
14434 "vconvert v [Mode={window|view}]"
14435 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
14436 "\n\t\t: vconvert x y z [Mode={window|grid}]"
14437 "\n\t\t: window - convert to window coordinates, pixels"
14438 "\n\t\t: view - convert to view projection plane"
14439 "\n\t\t: grid - convert to model coordinates, given on grid"
14440 "\n\t\t: ray - convert projection ray to model coordiantes"
14441 "\n\t\t: - vconvert v window : convert view to window;"
14442 "\n\t\t: - vconvert v view : convert window to view;"
14443 "\n\t\t: - vconvert x y window : convert view to window;"
14444 "\n\t\t: - vconvert x y view : convert window to view;"
14445 "\n\t\t: - vconvert x y : convert window to model;"
14446 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
14447 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
14448 "\n\t\t: - vconvert x y z window : convert model to window;"
14449 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
14450 "\n\t\t: Converts the given coordinates to window/view/model space.",
14451 __FILE__, VConvert, group);
208e6839 14452 theCommands.Add ("vfps",
e084dbbc 14453 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 14454 __FILE__, VFps, group);
58655684 14455 theCommands.Add ("vgldebug",
c87535af 14456 "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
84e84755 14457 "\n\t\t: [-glslCode {off|short|full}] [-extraMsg {0|1}] [{0|1}]"
c87535af 14458 "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
14459 "\n\t\t: Debug context can be requested only on Windows"
14460 "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
14461 "\n\t\t: -sync - request synchronized debug GL context"
14462 "\n\t\t: -glslWarn - log GLSL compiler/linker warnings,"
14463 "\n\t\t: which are suppressed by default,"
84e84755 14464 "\n\t\t: -glslCode - log GLSL program source code,"
14465 "\n\t\t: which are suppressed by default,"
c87535af 14466 "\n\t\t: -extraMsg - log extra diagnostic messages from GL context,"
14467 "\n\t\t: which are suppressed by default",
58655684 14468 __FILE__, VGlDebug, group);
208e6839 14469 theCommands.Add ("vvbo",
58655684 14470 "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
208e6839 14471 __FILE__, VVbo, group);
b5ac8292 14472 theCommands.Add ("vstereo",
f978241f 14473 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
b40cdc2b 14474 "\n\t\t: [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]"
f978241f 14475 "\n\t\t: [-anaglyph Filter]"
b40cdc2b 14476 "\n\t\t: Control stereo output mode."
14477 "\n\t\t: When -mirrorComposer is specified, VR rendered frame will be mirrored in window (debug)."
14478 "\n\t\t: Parameter -unitFactor specifies meters scale factor for mapping VR input."
14479 "\n\t\t: Available modes for -mode:"
f978241f 14480 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
14481 "\n\t\t: requires driver support."
14482 "\n\t\t: Should be called BEFORE vinit!"
14483 "\n\t\t: anaglyph - Anaglyph glasses"
14484 "\n\t\t: rowInterlaced - row-interlaced display"
14485 "\n\t\t: columnInterlaced - column-interlaced display"
14486 "\n\t\t: chessBoard - chess-board output"
14487 "\n\t\t: sideBySide - horizontal pair"
14488 "\n\t\t: overUnder - vertical pair"
b40cdc2b 14489 "\n\t\t: openVR - OpenVR (HMD)"
f978241f 14490 "\n\t\t: Available Anaglyph filters for -anaglyph:"
14491 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
14492 "\n\t\t: greenMagentaSimple",
b5ac8292 14493 __FILE__, VStereo, group);
a577aaab 14494 theCommands.Add ("vcaps",
ba00aab7 14495 "vcaps [-sRGB {0|1}] [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
faff3767 14496 "\n\t\t: [-compatibleProfile {0|1}] [-compressedTextures {0|1}]"
56689b27 14497 "\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}]"
f978241f 14498 "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
8625ef7e 14499 "\n\t\t: [-softMode {0|1}] [-noupdate|-update]"
59515ca6 14500 "\n\t\t: [-noExtensions {0|1}] [-maxVersion Major Minor]"
8625ef7e 14501 "\n\t\t: Modify particular graphic driver options:"
ba00aab7 14502 "\n\t\t: sRGB - enable/disable sRGB rendering"
8625ef7e 14503 "\n\t\t: FFP - use fixed-function pipeline instead of"
14504 "\n\t\t: built-in GLSL programs"
4e1523ef 14505 "\n\t\t: (requires compatible profile)"
2a332745 14506 "\n\t\t: polygonMode - use Polygon Mode instead of built-in GLSL programs"
faff3767 14507 "\n\t\t: compressedTexture - allow uploading of GPU-supported compressed texture formats"
8625ef7e 14508 "\n\t\t: VBO - use Vertex Buffer Object (copy vertex"
14509 "\n\t\t: arrays to GPU memory)"
14510 "\n\t\t: sprite - use textured sprites instead of bitmaps"
f978241f 14511 "\n\t\t: vsync - switch VSync on or off"
56689b27 14512 "\n\t\t: winBuffer - allow using window buffer for rendering"
4e1523ef 14513 "\n\t\t: Context creation options:"
14514 "\n\t\t: softMode - software OpenGL implementation"
14515 "\n\t\t: compatibleProfile - backward-compatible profile"
f978241f 14516 "\n\t\t: quadbuffer - QuadBuffer"
59515ca6 14517 "\n\t\t: noExtensions - disallow usage of extensions"
14518 "\n\t\t: maxVersion - force upper OpenGL version to be used"
8625ef7e 14519 "\n\t\t: Unlike vrenderparams, these parameters control alternative"
14520 "\n\t\t: rendering paths producing the same visual result when"
14521 "\n\t\t: possible."
14522 "\n\t\t: Command is intended for testing old hardware compatibility.",
a577aaab 14523 __FILE__, VCaps, group);
f0430952 14524 theCommands.Add ("vmemgpu",
14525 "vmemgpu [f]: print system-dependent GPU memory information if available;"
14526 " with f option returns free memory in bytes",
14527 __FILE__, VMemGpu, group);
85e096c3 14528 theCommands.Add ("vreadpixel",
ba00aab7 14529 "vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]"
85e096c3 14530 " : Read pixel value for active view",
14531 __FILE__, VReadPixel, group);
692613e5 14532 theCommands.Add("diffimage",
fd3f6bd0 14533 "diffimage imageFile1 imageFile2 [diffImageFile]"
14534 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
14535 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
14536 "\n\t\t: Compare two images by content and generate difference image."
14537 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
14538 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 14539 __FILE__, VDiffImage, group);
4754e164 14540 theCommands.Add ("vselect",
2157d6ac 14541 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [shift_selection = 0|1]\n"
4754e164 14542 "- emulates different types of selection:\n"
14543 "- 1) single click selection\n"
14544 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
14545 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
a24a7821 14546 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.\n"
14547 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined \n"
14548 " rectangle or polygon will be detected, otherwise algorithm will chose only fully included sensitives.\n"
14549 " Default behavior is to detect only full inclusion. (partial inclusion - overlap - is not allowed by default)\n"
2157d6ac 14550 "- 5) any of these selections with shift button pressed",
4754e164 14551 __FILE__, VSelect, group);
14552 theCommands.Add ("vmoveto",
8a590580 14553 "vmoveto [x y] [-reset]"
14554 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
14555 "\n\t\t: -reset resets current highlighting",
4754e164 14556 __FILE__, VMoveTo, group);
1beb58d7 14557 theCommands.Add ("vviewparams",
14558 "vviewparams [-args] [-scale [s]]"
14559 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
14560 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
14561 "\n\t\t: Manage current view parameters or prints all"
14562 "\n\t\t: current values when called without argument."
14563 "\n\t\t: -scale [s] prints or sets viewport relative scale"
14564 "\n\t\t: -eye [x y z] prints or sets eye location"
14565 "\n\t\t: -at [x y z] prints or sets center of look"
14566 "\n\t\t: -up [x y z] prints or sets direction of up vector"
14567 "\n\t\t: -proj [x y z] prints or sets direction of look"
14568 "\n\t\t: -center x y sets location of center of the screen in pixels"
14569 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
14570 "\n\t\t: or changes the size of its maximum dimension"
14571 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 14572 __FILE__, VViewParams, group);
1beb58d7 14573
2e93433e 14574 theCommands.Add("v2dmode",
14575 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
14576 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
14577 "\n\t\t: mode - switches On/Off rotation mode"
14578 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
14579 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
14580 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
14581 "\n\t\t: View camera position might be changed only by commands.",
14582 __FILE__, V2DMode, group);
14583
1beb58d7 14584 theCommands.Add("vanimation", "Alias for vanim",
14585 __FILE__, VAnimation, group);
14586
14587 theCommands.Add("vanim",
14588 "List existing animations:"
14589 "\n\t\t: vanim"
14590 "\n\t\t: Animation playback:"
14591 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
14592 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
14593 "\n\t\t: -speed playback speed (1.0 is normal speed)"
14594 "\n\t\t: -freeLook skip camera animations"
14595 "\n\t\t: -lockLoop disable any interactions"
14596 "\n\t\t:"
14597 "\n\t\t: Animation definition:"
14598 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
14599 "\n\t\t: [start TimeSec] [duration TimeSec]"
14600 "\n\t\t:"
14601 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
14602 "\n\t\t: specifies nested animations."
14603 "\n\t\t: There is no syntax to explicitly add new animation,"
14604 "\n\t\t: and all non-existing animations within the name will be"
14605 "\n\t\t: implicitly created on first use (including parents)."
14606 "\n\t\t:"
14607 "\n\t\t: Each animation might define the SINGLE action (see below),"
14608 "\n\t\t: like camera transition, object transformation or custom callback."
14609 "\n\t\t: Child animations can be used for defining concurrent actions."
14610 "\n\t\t:"
14611 "\n\t\t: Camera animation:"
14612 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
14613 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
14614 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
14615 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14616 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
14617 "\n\t\t: -atX camera Center positions pair"
14618 "\n\t\t: -upX camera Up directions pair"
14619 "\n\t\t: -scaleX camera Scale factors pair"
14620 "\n\t\t: Object animation:"
14621 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
14622 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
14623 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
14624 "\n\t\t: -locX object Location points pair (translation)"
14625 "\n\t\t: -rotX object Orientations pair (quaternions)"
14626 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
14627 "\n\t\t: Custom callback:"
14628 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
14629 "\n\t\t: %Pts overall animation presentation timestamp"
14630 "\n\t\t: %LocalPts local animation timestamp"
14631 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 14632 "\n\t\t:"
14633 "\n\t\t: Video recording:"
14634 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
14635 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
14636 "\n\t\t: [-crf Value] [-preset Preset]"
14637 "\n\t\t: -fps video framerate"
14638 "\n\t\t: -format file format, container (matroska, etc.)"
14639 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
14640 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
14641 "\n\t\t: -crf constant rate factor (specific to codec)"
14642 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 14643 __FILE__, VAnimation, group);
14644
4754e164 14645 theCommands.Add("vchangeselected",
dc3fe572 14646 "vchangeselected shape"
4754e164 14647 "- adds to shape to selection or remove one from it",
14648 __FILE__, VChangeSelected, group);
4754e164 14649 theCommands.Add ("vnbselected",
faea8b40 14650 "vnbselected"
14651 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14652 theCommands.Add ("vcamera",
30a1b24e 14653 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14654 "\n\t\t: [-persp]"
14655 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14656 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14657 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14658 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
b40cdc2b 14659 "\n\t\t: [-fov2d [Angle]] [-lockZup {0|1}]"
14660 "\n\t\t: [-xrPose base|head=base]"
30a1b24e 14661 "\n\t\t: Manages camera parameters."
14662 "\n\t\t: Displays frustum when presntation name PrsName is specified."
6b62b2da 14663 "\n\t\t: Prints current value when option called without argument."
14664 "\n\t\t: Orthographic camera:"
14665 "\n\t\t: -ortho activate orthographic projection"
14666 "\n\t\t: Perspective camera:"
14667 "\n\t\t: -persp activate perspective projection (mono)"
14668 "\n\t\t: -fovy field of view in y axis, in degrees"
b40cdc2b 14669 "\n\t\t: -fov2d field of view limit for 2d on-screen elements"
6b62b2da 14670 "\n\t\t: -distance distance of eye from camera center"
b40cdc2b 14671 "\n\t\t: -lockZup lock Z up (tunrtable mode)"
6b62b2da 14672 "\n\t\t: Stereoscopic camera:"
14673 "\n\t\t: -stereo perspective projection (stereo)"
14674 "\n\t\t: -leftEye perspective projection (left eye)"
14675 "\n\t\t: -rightEye perspective projection (right eye)"
14676 "\n\t\t: -iod intraocular distance value"
14677 "\n\t\t: -iodType distance type, absolute or relative"
14678 "\n\t\t: -zfocus stereographic focus value"
14679 "\n\t\t: -zfocusType focus type, absolute or relative",
14680 __FILE__, VCamera, group);
b5ac8292 14681 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14682 "- vautozfit [on={1|0}] [scale]\n"
14683 " Prints or changes parameters of automatic z-fit mode:\n"
14684 " \"on\" - turns automatic z-fit on or off\n"
14685 " \"scale\" - specifies factor to scale computed z range.\n",
14686 __FILE__, VAutoZFit, group);
b5ac8292 14687 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14688 " vzrange - without parameters shows current values\n"
14689 " vzrange [znear] [zfar] - applies provided values to view",
14690 __FILE__,VZRange, group);
4754e164 14691 theCommands.Add ("vpurgedisplay",
eb4320f2 14692 "vpurgedisplay"
4754e164 14693 "- removes structures which don't belong to objects displayed in neutral point",
14694 __FILE__, VPurgeDisplay, group);
14695 theCommands.Add("vsetviewsize",
14696 "vsetviewsize size",
14697 __FILE__,VSetViewSize,group);
14698 theCommands.Add("vmoveview",
14699 "vmoveview Dx Dy Dz [Start = 1|0]",
14700 __FILE__,VMoveView,group);
14701 theCommands.Add("vtranslateview",
14702 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14703 __FILE__,VTranslateView,group);
14704 theCommands.Add("vturnview",
14705 "vturnview Ax Ay Az [Start = 1|0]",
14706 __FILE__,VTurnView,group);
269294d6 14707 theCommands.Add("vtextureenv",
14708 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14709 "or user-defined file and optionally applying texture mapping parameters\n"
14710 " Usage:\n"
14711 " vtextureenv off - disables environment mapping\n"
14712 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14713 " std_texture = (0..7)\n"
14714 " rep = {clamp|repeat}\n"
14715 " mod = {decal|modulate}\n"
14716 " flt = {nearest|bilinear|trilinear}\n"
14717 " ss, st - scale factors for s and t texture coordinates\n"
14718 " ts, tt - translation for s and t texture coordinates\n"
14719 " rot - texture rotation angle in degrees",
14720 __FILE__, VTextureEnv, group);
1eeef710 14721 theCommands.Add("vhlr",
14722 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14723 "\n\t\t: Hidden Line Removal algorithm."
14724 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14725 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 14726 __FILE__,VHLR,group);
1eeef710 14727 theCommands.Add("vhlrtype",
14728 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14729 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14730 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14731 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14732 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 14733 __FILE__,VHLRType,group);
3e05329c 14734 theCommands.Add("vclipplane",
14735 "vclipplane planeName [{0|1}]"
25c35042 14736 "\n\t\t: [-equation1 A B C D]"
14737 "\n\t\t: [-equation2 A B C D]"
14738 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 14739 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 14740 "\n\t\t: [-maxPlanes]"
14741 "\n\t\t: [-capping {0|1}]"
1b661a81 14742 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 14743 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14744 "\n\t\t: [-texRotate Angle]"
14745 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14746 "\n\t\t: [-useObjShader {0|1}]"
14747 "\n\t\t: Clipping planes management:"
14748 "\n\t\t: -maxPlanes print plane limit for view"
14749 "\n\t\t: -delete delete plane with given name"
14750 "\n\t\t: {off|on|0|1} turn clipping on/off"
14751 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14752 "\n\t\t: applied to active View when list is omitted"
14753 "\n\t\t: -equation A B C D change plane equation"
14754 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14755 "\n\t\t: Capping options:"
14756 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14757 "\n\t\t: -color R G B set capping color"
1b661a81 14758 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 14759 "\n\t\t: -texName Texture set capping texture"
14760 "\n\t\t: -texScale SX SY set capping tex scale"
14761 "\n\t\t: -texOrigin TX TY set capping tex origin"
14762 "\n\t\t: -texRotate Angle set capping tex rotation"
14763 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14764 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14765 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14766 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14767 __FILE__, VClipPlane, group);
392ac980 14768 theCommands.Add("vdefaults",
4c513386 14769 "vdefaults [-absDefl value]"
14770 "\n\t\t: [-devCoeff value]"
14771 "\n\t\t: [-angDefl value]"
14772 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14773 , __FILE__, VDefaults, group);
12381341 14774 theCommands.Add("vlight",
816d03ee 14775 "tool to manage light sources, without arguments shows list of lights."
14776 "\n Main commands: "
992ed6b3 14777 "\n '-clear' to clear lights"
14778 "\n '-{def}aults' to load deafault lights"
14779 "\n '-add' <type> to add any light source"
816d03ee 14780 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
14781 "\n 'change' <lightId> to edit light source with specified lightId"
14782 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 14783 "\n -layer Id"
14784 "\n -{pos}ition X Y Z"
14785 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
14786 "\n -color colorName"
14787 "\n -{head}light 0|1"
14788 "\n -{sm}oothness value"
14789 "\n -{int}ensity value"
14790 "\n -{constAtten}uation value"
14791 "\n -{linearAtten}uation value"
14792 "\n -angle angleDeg"
14793 "\n -{spotexp}onent value"
88b312d3 14794 "\n -range value"
992ed6b3 14795 "\n -local|-global"
14796 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
14797 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 14798 __FILE__, VLight, group);
67312b79 14799 theCommands.Add("vpbrenv",
14800 "vpbrenv -clear|-generate"
14801 "\n\t\t: Clears or generates PBR environment map of active view."
14802 "\n\t\t: -clear clears PBR environment (fills by white color)"
14803 "\n\t\t: -generate generates PBR environment from current background cubemap",
14804 __FILE__, VPBREnvironment, group);
6b62b2da 14805 theCommands.Add("vraytrace",
14806 "vraytrace [0|1]"
189f85a3 14807 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 14808 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
14809 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
14810 __FILE__, VRenderParams, group);
bc8c79bb 14811 theCommands.Add("vrenderparams",
4c7a3fae 14812 "\n\t\t: Manages rendering parameters, affecting visual appearance, quality and performance."
14813 "\n\t\t: Should be applied taking into account GPU hardware capabilities and performance."
14814 "\n\t\t: Common parameters:"
14815 "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]"
14816 "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1] [-resolution value=72]"
14817 "\n\t\t: [-oit {off|0.0-1.0}=off]"
14818 "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]"
14819 "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]"
14820 "\n\t\t: [-sync {default|views}] [-reset]"
14821 "\n\t\t: -raster Disables GPU ray-tracing."
14822 "\n\t\t: -shadingModel Controls shading model."
14823 "\n\t\t: -msaa Specifies number of samples for MSAA."
14824 "\n\t\t: -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA)."
14825 "\n\t\t: -resolution Sets new pixels density (PPI) used as text scaling factor."
14826 "\n\t\t: -lineFeather Sets line feather factor while displaying mesh edges."
14827 "\n\t\t: -alphaToCoverage Enables/disables alpha to coverage (needs MSAA)."
14828 "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;"
14829 "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result,"
14830 "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)."
14831 "\n\t\t: -depthPrePass Enables/disables depth pre-pass."
14832 "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or"
14833 "\n\t\t: sets state to check structures culled previously."
14834 "\n\t\t: -sync Sets active View parameters as Viewer defaults / to other Views."
14835 "\n\t\t: -reset Resets active View parameters to Viewer defaults."
14836 "\n\t\t: Diagnostic output (on-screen overlay):"
14837 "\n\t\t: vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points"
14838 "\n\t\t: |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]"
14839 "\n\t\t: [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]"
14840 "\n\t\t: -perfCounters Show/hide performance counters (flags can be combined)."
14841 "\n\t\t: -perfUpdateInterval Performance counters update interval."
14842 "\n\t\t: -perfChart Show frame timers chart limited by specified number of frames."
14843 "\n\t\t: -perfChartMax Maximum time in seconds with the chart."
14844 "\n\t\t: Ray-Tracing options:"
14845 "\n\t\t: vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-shadows {on|off}=on] [-reflections {on|off}=off]"
14846 "\n\t\t: [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]"
14847 "\n\t\t: [-gi {on|off}=off] [-brng {on|off}=off]"
14848 "\n\t\t: [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]"
14849 "\n\t\t: [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]"
14850 "\n\t\t: [-maxRad {value>0}=30.0]"
14851 "\n\t\t: [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]"
14852 "\n\t\t: [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]"
14853 "\n\t\t: -rayTrace Enables GPU ray-tracing."
14854 "\n\t\t: -rayDepth Defines maximum ray-tracing depth."
14855 "\n\t\t: -shadows Enables/disables shadows rendering."
14856 "\n\t\t: -reflections Enables/disables specular reflections."
14857 "\n\t\t: -fsaa Enables/disables adaptive anti-aliasing."
14858 "\n\t\t: -gleam Enables/disables transparency shadow effects."
14859 "\n\t\t: -gi Enables/disables global illumination effects (Path-Tracing)."
14860 "\n\t\t: -env Enables/disables environment map background."
14861 "\n\t\t: -ignoreNormalMap Enables/disables normal map ignoring during path tracing."
14862 "\n\t\t: -twoSide Enables/disables two-sided BSDF models (PT mode)."
14863 "\n\t\t: -iss Enables/disables adaptive screen sampling (PT mode)."
14864 "\n\t\t: -maxRad Value used for clamping radiance estimation (PT mode)."
14865 "\n\t\t: -tileSize Specifies size of screen tiles in ISS mode (32 by default)."
14866 "\n\t\t: -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default)."
14867 "\n\t\t: -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF)."
14868 "\n\t\t: -focal Focal distance of perspective camera for depth-of-field effect."
14869 "\n\t\t: -exposure Exposure value for tone mapping (0.0 value disables the effect)."
14870 "\n\t\t: -whitePoint White point value for filmic tone mapping."
14871 "\n\t\t: -toneMapping Tone mapping mode (disabled, filmic)."
14872 "\n\t\t: PBR environment baking parameters (advanced/debug):"
14873 "\n\t\t: vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]"
14874 "\n\t\t: [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]"
14875 "\n\t\t: -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size)."
14876 "\n\t\t: -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map."
14877 "\n\t\t: -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during"
14878 "\n\t\t: diffuse IBL map's sherical harmonics calculation."
14879 "\n\t\t: -pbrEnvBSSN Controls maximum number of samples per mipmap level"
14880 "\n\t\t: in Monte-Carlo integration during specular IBL maps generation."
14881 "\n\t\t: -pbrEnvBP Controls strength of samples number reducing"
14882 "\n\t\t: during specular IBL maps generation (1 disables reducing)."
14883 "\n\t\t: Debug options:"
14884 "\n\t\t: vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]"
14885 "\n\t\t: -issd Shows screen sampling distribution in ISS mode."
14886 "\n\t\t: -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging)."
14887 "\n\t\t: -brng Enables/disables blocked RNG (fast coherent PT).",
bc8c79bb 14888 __FILE__, VRenderParams, group);
79b544e6 14889 theCommands.Add("vstatprofiler",
14890 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
14891 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
a2803f37 14892 "\n |triangles|points|geomMem|textureMem|frameMem"
79b544e6 14893 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
14894 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
14895 "\n [-noredraw]"
14896 "\n\t\t: Prints rendering statistics."
14897 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
14898 "\n\t\t: else - print all performance counters set previously."
14899 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
14900 __FILE__, VStatProfiler, group);
49e1a5c7 14901 theCommands.Add ("vplace",
14902 "vplace dx dy"
14903 "\n\t\t: Places the point (in pixels) at the center of the window",
14904 __FILE__, VPlace, group);
0717ddc1 14905 theCommands.Add("vxrotate",
14906 "vxrotate",
14907 __FILE__,VXRotate,group);
14908
625e1958 14909 theCommands.Add("vmanipulator",
14910 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
14911 "\n tool to create and manage AIS manipulators."
14912 "\n Options: "
14913 "\n '-attach AISObject' attach manipulator to AISObject"
14914 "\n '-adjustPosition {0|1}' adjust position when attaching"
14915 "\n '-adjustSize {0|1}' adjust size when attaching"
14916 "\n '-enableModes {0|1}' enable modes when attaching"
bbf3fcde 14917 "\n '-view {active | [name of view]}' display manipulator only in defined view,"
14918 "\n by default it is displayed in all views of the current viewer"
625e1958 14919 "\n '-detach' detach manipulator"
14920 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
14921 "\n '-transform mouse_x mouse_y' - invoke transformation"
14922 "\n '-stopTransform [abort]' - invoke stop of transformation"
14923 "\n '-move x y z' - move attached object"
14924 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
14925 "\n '-scale factor' - scale attached object"
14926 "\n '-autoActivate {0|1}' - set activation on detection"
14927 "\n '-followTranslation {0|1}' - set following translation transform"
14928 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 14929 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 14930 "\n '-gap value' - set gap between sub-parts"
14931 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 14932 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 14933 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
14934 "\n '-size value' - set size of manipulator"
14935 "\n '-zoomable {0|1}' - set zoom persistence",
14936 __FILE__, VManipulator, group);
14937
8e5fb5ea 14938 theCommands.Add("vselprops",
f838dac4 14939 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 14940 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
14941 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 14942 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
14943 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 14944 "\n -pickStrategy {first|topmost} : defines picking strategy"
14945 "\n 'first' to pick first acceptable (default)"
14946 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 14947 "\n -pixTol value : sets up pixel tolerance"
8c36926a 14948 "\n -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth"
14949 "\n -depthTol {sensfactor} : use sensitive factor for sorting results by depth"
14950 "\n -preferClosest {0|1} : sets if depth should take precedence over priority while sorting results"
f838dac4 14951 "\n -dispMode dispMode : sets display mode for highlighting"
14952 "\n -layer ZLayer : sets ZLayer for highlighting"
14953 "\n -color {name|r g b} : sets highlight color"
14954 "\n -transp value : sets transparency coefficient for highlight"
14955 "\n -material material : sets highlight material"
8e5fb5ea 14956 "\n -print : prints current state of all mentioned parameters",
14957 __FILE__, VSelectionProperties, group);
be3d8cbc 14958 theCommands.Add ("vhighlightselected",
14959 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
14960 __FILE__, VSelectionProperties, group);
8e5fb5ea 14961
decdee7d 14962 theCommands.Add ("vseldump",
14963 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
b40cdc2b 14964 "\n\t\t: [-xrPose base|head=base]"
decdee7d 14965 "\n\t\t: Generate an image based on detection results:"
14966 "\n\t\t: depth normalized depth values"
14967 "\n\t\t: unnormDepth unnormalized depth values"
14968 "\n\t\t: object color of detected object"
14969 "\n\t\t: owner color of detected owner"
14970 "\n\t\t: selMode color of selection mode"
14971 "\n\t\t: entity color of etected entity",
14972 __FILE__, VDumpSelectionImage, group);
293211ae 14973
2108d9a2 14974 theCommands.Add ("vviewcube",
14975 "vviewcube name"
14976 "\n\t\t: Displays interactive view manipualtion object."
14977 "\n\t\t: Options: "
14978 "\n\t\t: -reset reset geomertical and visual attributes'"
14979 "\n\t\t: -size Size adapted size of View Cube"
14980 "\n\t\t: -boxSize Size box size"
14981 "\n\t\t: -axes {0|1 } show/hide axes (trihedron)"
14982 "\n\t\t: -edges {0|1} show/hide edges of View Cube"
14983 "\n\t\t: -vertices {0|1} show/hide vertices of View Cube"
14984 "\n\t\t: -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation"
14985 "\n\t\t: -color Color color of View Cube"
14986 "\n\t\t: -boxColor Color box color"
14987 "\n\t\t: -boxSideColor Color box sides color"
14988 "\n\t\t: -boxEdgeColor Color box edges color"
14989 "\n\t\t: -boxCornerColor Color box corner color"
14990 "\n\t\t: -textColor Color color of side text of view cube"
14991 "\n\t\t: -innerColor Color inner box color"
14992 "\n\t\t: -transparency Value transparency of object within [0, 1] range"
14993 "\n\t\t: -boxTransparency Value transparency of box within [0, 1] range"
14994 "\n\t\t: -font Name font name"
14995 "\n\t\t: -fontHeight Value font height"
14996 "\n\t\t: -boxFacetExtension Value box facet extension"
14997 "\n\t\t: -boxEdgeGap Value gap between box edges and box sides"
14998 "\n\t\t: -boxEdgeMinSize Value minimal box edge size"
14999 "\n\t\t: -boxCornerMinSize Value minimal box corner size"
15000 "\n\t\t: -axesPadding Value padding between box and arrows"
15001 "\n\t\t: -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range"
6466cc9e 15002 "\n\t\t: -axesRadius Value radius of axes of the trihedron"
15003 "\n\t\t: -axesConeRadius Value radius of the cone (arrow) of the trihedron"
15004 "\n\t\t: -axesSphereRadius Value radius of the sphere (central point) of trihedron"
2108d9a2 15005 "\n\t\t: -fixedanimation {0|1} uninterruptible animation loop"
15006 "\n\t\t: -duration Seconds animation duration in seconds",
15007 __FILE__, VViewCube, group);
15008
14b741b0 15009 theCommands.Add("vcolorconvert" ,
15010 "vcolorconvert {from|to} type C1 C2 C2"
15011 "\n\t\t: vcolorconvert from type C1 C2 C2: Converts color from specified color space to linear RGB"
15012 "\n\t\t: vcolorconvert to type R G B: Converts linear RGB color to specified color space"
15013 "\n\t\t: type can be sRGB, HLS, Lab, or Lch",
15014 __FILE__,VColorConvert,group);
15015 theCommands.Add("vcolordiff" ,
15016 "vcolordiff R1 G1 B1 R2 G2 B2: returns CIEDE2000 color difference between two RGB colors",
15017 __FILE__,VColorDiff,group);
6a2fb7a1 15018 theCommands.Add("vselbvhbuild",
15019 "vselbvhbuild [{0|1}] [-nbThreads value] [-wait]"
15020 "\n\t\t: Turns on/off prebuilding of BVH within background thread(s)"
15021 "\n\t\t: -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1)"
15022 "\n\t\t: -wait waits for building all of BVH",
15023 __FILE__,VSelBvhBuild,group);
2108d9a2 15024}