0030592: Draw Harness, ViewerTest - provide vbackground command unifying vsetbg,...
[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>
1beb58d7 18
19#include <AIS_Animation.hxx>
20#include <AIS_AnimationCamera.hxx>
21#include <AIS_AnimationObject.hxx>
30a1b24e 22#include <AIS_CameraFrustum.hxx>
7a324550 23#include <AIS_ColorScale.hxx>
625e1958 24#include <AIS_Manipulator.hxx>
b12e1c7b 25#include <AIS_RubberBand.hxx>
0a768f56 26#include <AIS_Shape.hxx>
0a768f56 27#include <AIS_InteractiveObject.hxx>
28#include <AIS_ListOfInteractive.hxx>
29#include <AIS_ListIteratorOfListOfInteractive.hxx>
8a590580 30#include <Aspect_Grid.hxx>
0a768f56 31#include <DBRep.hxx>
08f8a185 32#include <Draw_ProgressIndicator.hxx>
61b0191c 33#include <Graphic3d_ArrayOfPolylines.hxx>
2bd4c032 34#include <Graphic3d_AspectMarker3d.hxx>
269294d6 35#include <Graphic3d_NameOfTextureEnv.hxx>
a79f67f8 36#include <Graphic3d_GraduatedTrihedron.hxx>
269294d6 37#include <Graphic3d_TextureEnv.hxx>
38#include <Graphic3d_TextureParams.hxx>
39#include <Graphic3d_TypeOfTextureFilter.hxx>
4269bd1b 40#include <Graphic3d_AspectFillArea3d.hxx>
7fd59977 41#include <ViewerTest.hxx>
8625ef7e 42#include <ViewerTest_AutoUpdater.hxx>
7fd59977 43#include <ViewerTest_EventManager.hxx>
4754e164 44#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
4269bd1b 45#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
625e1958 46#include <ViewerTest_CmdParser.hxx>
12381341 47#include <V3d_AmbientLight.hxx>
48#include <V3d_DirectionalLight.hxx>
12381341 49#include <V3d_PositionalLight.hxx>
50#include <V3d_SpotLight.hxx>
08f8a185 51#include <Message_ProgressSentry.hxx>
18d715bd 52#include <NCollection_DoubleMap.hxx>
53#include <NCollection_List.hxx>
54#include <NCollection_Vector.hxx>
7fd59977 55#include <AIS_InteractiveContext.hxx>
56#include <Draw_Interpretor.hxx>
57#include <Draw.hxx>
58#include <Draw_Appli.hxx>
692613e5 59#include <Image_AlienPixMap.hxx>
08f8a185 60#include <Image_VideoRecorder.hxx>
58655684 61#include <OpenGl_GraphicDriver.hxx>
8693dfd0 62#include <OSD.hxx>
208e6839 63#include <OSD_Timer.hxx>
900f7229 64#include <TColStd_HSequenceOfAsciiString.hxx>
59f45b7c 65#include <TColStd_SequenceOfInteger.hxx>
4754e164 66#include <TColStd_HSequenceOfReal.hxx>
67#include <TColgp_Array1OfPnt2d.hxx>
197ac94e 68#include <TColStd_MapOfAsciiString.hxx>
20637bd2 69#include <Aspect_TypeOfLine.hxx>
692613e5 70#include <Image_Diff.hxx>
dc3fe572 71#include <Aspect_DisplayConnection.hxx>
4269bd1b 72#include <gp_Pnt.hxx>
73#include <gp_Dir.hxx>
74#include <gp_Pln.hxx>
75#include <PrsMgr_PresentableObject.hxx>
76#include <Graphic3d_ClipPlane.hxx>
77#include <NCollection_DataMap.hxx>
78#include <Graphic3d_Texture2Dmanual.hxx>
79#include <Prs3d_ShadingAspect.hxx>
6262338c 80#include <Prs3d_Drawer.hxx>
61b0191c 81#include <Prs3d_LineAspect.hxx>
82#include <Prs3d_Root.hxx>
fd3f6bd0 83#include <Prs3d_Text.hxx>
84#include <Select3D_SensitivePrimitiveArray.hxx>
7fd59977 85
293211ae 86#include <tcl.h>
87
57c28b61 88#ifdef _WIN32
25289ec1 89#undef DrawText
90#endif
91
692613e5 92#include <cstdlib>
25289ec1 93
58655684 94#if defined(_WIN32)
4fe56619 95 #include <WNT_WClass.hxx>
96 #include <WNT_Window.hxx>
4fe56619 97#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 98 #include <Cocoa_Window.hxx>
7fd59977 99#else
4fe56619 100 #include <Xw_Window.hxx>
101 #include <X11/Xlib.h> /* contains some dangerous #defines such as Status, True etc. */
102 #include <X11/Xutil.h>
103 #include <tk.h>
7fd59977 104#endif
105
b514beda 106// Auxiliary definitions
107static const char THE_KEY_DELETE = 127;
fd3f6bd0 108static const char THE_KEY_ESCAPE = 27;
7fd59977 109
110//==============================================================================
111// VIEWER GLOBAL VARIABLES
112//==============================================================================
113
114Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
b514beda 115Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
7fd59977 116
117Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
4754e164 118extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
7fd59977 119
b514beda 120extern int VErase (Draw_Interpretor& theDI,
121 Standard_Integer theArgNb,
122 const char** theArgVec);
123
58655684 124#if defined(_WIN32)
7fd59977 125static Handle(WNT_Window)& VT_GetWindow() {
126 static Handle(WNT_Window) WNTWin;
127 return WNTWin;
128}
4fe56619 129#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
4fe56619 130static Handle(Cocoa_Window)& VT_GetWindow()
131{
132 static Handle(Cocoa_Window) aWindow;
133 return aWindow;
134}
135extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
18d715bd 136extern void SetCocoaWindowTitle (const Handle(Cocoa_Window)& theWindow, Standard_CString theTitle);
137extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
138
7fd59977 139#else
7fd59977 140static Handle(Xw_Window)& VT_GetWindow(){
141 static Handle(Xw_Window) XWWin;
142 return XWWin;
143}
7fd59977 144
145static void VProcessEvents(ClientData,int);
146#endif
147
18d715bd 148static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
149{
150 static Handle(Aspect_DisplayConnection) aDisplayConnection;
151 return aDisplayConnection;
152}
153
154static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
155{
156 GetDisplayConnection() = theDisplayConnection;
157}
158
58655684 159#if defined(_WIN32) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
18d715bd 160Aspect_Handle GetWindowHandle(const Handle(Aspect_Window)& theWindow)
dc3fe572 161{
0ebaa4db 162 Aspect_Handle aWindowHandle = (Aspect_Handle)NULL;
58655684 163#if defined(_WIN32)
18d715bd 164 const Handle (WNT_Window) aWindow = Handle(WNT_Window)::DownCast (theWindow);
165 if (!aWindow.IsNull())
166 return aWindow->HWindow();
167#elif (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
168 const Handle (Xw_Window) aWindow = Handle(Xw_Window)::DownCast (theWindow);
169 if (!aWindow.IsNull())
170 return aWindow->XWindow();
171#endif
172 return aWindowHandle;
dc3fe572 173}
18d715bd 174#endif
dc3fe572 175
2e93433e 176//! Setting additional flag to store 2D mode of the View to avoid scene rotation by mouse/key events
177class ViewerTest_V3dView : public V3d_View
178{
179 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_V3dView, V3d_View)
180public:
181 //! Initializes the view.
182 ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType = V3d_ORTHOGRAPHIC,
183 bool theIs2dMode = false)
184 : V3d_View (theViewer, theType), myIs2dMode (theIs2dMode) {}
185
186 //! Initializes the view by copying.
187 ViewerTest_V3dView (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
188 : V3d_View (theViewer, theView), myIs2dMode (false)
189 {
190 if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (theView))
191 {
192 myIs2dMode = aV3dView->IsViewIn2DMode();
193 }
194 }
195
196 //! Returns true if 2D mode is set for the view
197 bool IsViewIn2DMode() const { return myIs2dMode; }
198
199 //! Sets 2D mode for the view
200 void SetView2DMode (bool the2dMode) { myIs2dMode = the2dMode; }
201
202public:
203
204 //! Returns true if active view in 2D mode.
205 static bool IsCurrentViewIn2DMode()
206 {
207 if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
208 {
209 return aV3dView->IsViewIn2DMode();
210 }
211 return false;
212 }
213
214 //! Set if active view in 2D mode.
215 static void SetCurrentView2DMode (bool theIs2d)
216 {
217 if (Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView()))
218 {
219 aV3dView->SetView2DMode (theIs2d);
220 }
221 }
222
223private:
224
225 Standard_Boolean myIs2dMode; //!< 2D mode flag
226
227};
228
18d715bd 229NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
58655684 230static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
18d715bd 231static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
58655684 232static OpenGl_Caps ViewerTest_myDefaultCaps;
18d715bd 233
7fd59977 234static void OSWindowSetup();
235
f42753ed 236static struct
237{
238 Quantity_Color FlatColor;
239 Quantity_Color GradientColor1;
240 Quantity_Color GradientColor2;
241 Aspect_GradientFillMethod FillMethod;
242} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GFM_NONE };
243
7fd59977 244//==============================================================================
245// EVENT GLOBAL VARIABLES
246//==============================================================================
247
248static int Start_Rot = 0;
1eeef710 249Standard_Boolean HasHlrOnBeforeRotation = Standard_False;
4fe56619 250int X_Motion = 0; // Current cursor position
251int Y_Motion = 0;
252int X_ButtonPress = 0; // Last ButtonPress position
253int Y_ButtonPress = 0;
254Standard_Boolean IsDragged = Standard_False;
8abada55 255Standard_Boolean DragFirst = Standard_False;
1beb58d7 256Standard_Boolean TheIsAnimating = Standard_False;
fd3f6bd0 257Standard_Boolean Draw_ToExitOnCloseView = Standard_False;
258Standard_Boolean Draw_ToCloseViewOnEsc = Standard_False;
7fd59977 259
293211ae 260namespace
261{
262
263 //! Checks if some set is a subset of other set
264 //! @tparam TheSuperSet the type of the superset
265 //! @tparam TheSubSet the type of the subset
266 //! @param theSuperSet the superset
267 //! @param theSubSet the subset to be checked
268 //! @return true if the superset includes subset, or false otherwise
269 template <typename TheSuperSet, typename TheSubSet>
270 static bool includes (const TheSuperSet& theSuperSet, const TheSubSet& theSubSet)
271 {
272 return std::includes (theSuperSet.begin(), theSuperSet.end(), theSubSet.begin(), theSubSet.end());
273 }
274
275 //! A variable set of keys for command-line options.
276 //! It includes a set of mandatory keys and a set of all possible keys.
277 class CommandOptionKeyVariableSet
278 {
279 public:
280 //! Default constructor
281 CommandOptionKeyVariableSet()
282 {
283 }
284
285 //! Constructor
286 //! @param theMandatoryKeySet the set of the mandatory option keys
287 //! @param theAdditionalKeySet the set of additional options that could be omitted
288 CommandOptionKeyVariableSet (
289 const ViewerTest_CommandOptionKeySet& theMandatoryKeySet,
290 const ViewerTest_CommandOptionKeySet& theAdditionalKeySet = ViewerTest_CommandOptionKeySet())
291 : myMandatoryKeySet (theMandatoryKeySet)
292 {
293 std::set_union (theMandatoryKeySet.begin(),
294 theMandatoryKeySet.end(),
295 theAdditionalKeySet.begin(),
296 theAdditionalKeySet.end(),
297 std::inserter (myFullKeySet, myFullKeySet.begin()));
298 }
299
300 //! Checks if the set of option keys fits to the current variable set (it must contain all mandatory keys
301 //! and be contained in the full key set)
302 //! @param theCheckedKeySet the set of option keys to be checked
303 bool IsInSet (const ViewerTest_CommandOptionKeySet& theCheckedKeySet) const
304 {
305 return includes (theCheckedKeySet, myMandatoryKeySet) && includes (myFullKeySet, theCheckedKeySet);
306 }
307
308 private:
309 //! A set of mandatory command-line option keys
310 ViewerTest_CommandOptionKeySet myMandatoryKeySet;
311
312 //! A full set of command-line option keys (includes mandatory and additional option keys)
313 ViewerTest_CommandOptionKeySet myFullKeySet;
314 };
315
316 //! Gets some code by its name
317 //! @tparam TheCode the type of a code to be found
318 //! @param theCodeNameMap the map from code names to codes
319 //! @param theCodeName the name of a code to be found
320 //! @param theCode the code to be found
321 //! @return true if a code is found, or false otherwise
322 template <typename TheCode>
323 static bool getSomeCodeByName (const std::map<TCollection_AsciiString, TheCode>& theCodeNameMap,
324 TCollection_AsciiString theCodeName,
325 TheCode& theCode)
326 {
327 theCodeName.LowerCase();
328 const typename std::map<TCollection_AsciiString, TheCode>::const_iterator aCodeIterator = theCodeNameMap.find (
329 theCodeName);
330 if (aCodeIterator == theCodeNameMap.end())
331 {
332 return false;
333 }
334 theCode = aCodeIterator->second;
335 return true;
336 }
337
338 // Defines possible commands related to background changing
339 enum BackgroundCommand
340 {
341 BackgroundCommand_Main, //!< The main command that manages other commands through options
342 BackgroundCommand_Image, //!< Sets an image as a background
343 BackgroundCommand_ImageMode, //!< Changes a background image mode
344 BackgroundCommand_Gradient, //!< Sets a gradient as a background
345 BackgroundCommand_GradientMode, //!< Changes a background gradient mode
346 BackgroundCommand_Color, //!< Fills background with a specified color
347 BackgroundCommand_Default //!< Sets the background default color or gradient
348 };
349
350 //! Map from background command names to its codes
351 typedef std::map<TCollection_AsciiString, BackgroundCommand> BackgroundCommandNameMap;
352
353 //! Creates a map from background command names to its codes
354 //! @return a map from background command names to its codes
355 static BackgroundCommandNameMap createBackgroundCommandNameMap()
356 {
357 BackgroundCommandNameMap aBackgroundCommandNameMap;
358 aBackgroundCommandNameMap["vbackground"] = BackgroundCommand_Main;
359 aBackgroundCommandNameMap["vsetbg"] = BackgroundCommand_Image;
360 aBackgroundCommandNameMap["vsetbgmode"] = BackgroundCommand_ImageMode;
361 aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
362 aBackgroundCommandNameMap["vsetgrbgmode"] = BackgroundCommand_GradientMode;
363 aBackgroundCommandNameMap["vsetcolorbg"] = BackgroundCommand_Color;
364 aBackgroundCommandNameMap["vsetdefaultbg"] = BackgroundCommand_Default;
365 return aBackgroundCommandNameMap;
366 }
367
368 //! Gets a background command by its name
369 //! @param theBackgroundCommandName the name of the background command
370 //! @param theBackgroundCommand the background command to be found
371 //! @return true if a background command is found, or false otherwise
372 static bool getBackgroundCommandByName (const TCollection_AsciiString& theBackgroundCommandName,
373 BackgroundCommand& theBackgroundCommand)
374 {
375 static const BackgroundCommandNameMap THE_BACKGROUND_COMMAND_NAME_MAP = createBackgroundCommandNameMap();
376 return getSomeCodeByName (THE_BACKGROUND_COMMAND_NAME_MAP, theBackgroundCommandName, theBackgroundCommand);
377 }
378
379 //! Map from background image fill method names to its codes
380 typedef std::map<TCollection_AsciiString, Aspect_FillMethod> BackgroundImageFillMethodNameMap;
381
382 //! Creates a map from background image fill method names to its codes
383 //! @return a map from background image fill method names to its codes
384 static BackgroundImageFillMethodNameMap createBackgroundImageFillMethodNameMap()
385 {
386 BackgroundImageFillMethodNameMap aBackgroundImageFillMethodNameMap;
387 aBackgroundImageFillMethodNameMap["none"] = Aspect_FM_NONE;
388 aBackgroundImageFillMethodNameMap["centered"] = Aspect_FM_CENTERED;
389 aBackgroundImageFillMethodNameMap["tiled"] = Aspect_FM_TILED;
390 aBackgroundImageFillMethodNameMap["stretch"] = Aspect_FM_STRETCH;
391 return aBackgroundImageFillMethodNameMap;
392 }
393
394 //! Gets a background image fill method by its name
395 //! @param theBackgroundImageFillMethodName the name of the background image fill method
396 //! @param theBackgroundImageFillMethod the background image fill method to be found
397 //! @return true if a background image fill method is found, or false otherwise
398 static bool getBackgroundImageFillMethodByName (const TCollection_AsciiString& theBackgroundImageFillMethodName,
399 Aspect_FillMethod& theBackgroundImageFillMethod)
400 {
401 static const BackgroundImageFillMethodNameMap THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP =
402 createBackgroundImageFillMethodNameMap();
403 return getSomeCodeByName (THE_BACKGROUND_IMAGE_FILL_METHOD_NAME_MAP,
404 theBackgroundImageFillMethodName,
405 theBackgroundImageFillMethod);
406 }
407
408 //! Map from background gradient fill method names to its codes
409 typedef std::map<TCollection_AsciiString, Aspect_GradientFillMethod> BackgroundGradientFillMethodNameMap;
410
411 //! Creates a map from background gradient fill method names to its codes
412 //! @return a map from background gradient fill method names to its codes
413 static BackgroundGradientFillMethodNameMap createBackgroundGradientFillMethodNameMap()
414 {
415 BackgroundGradientFillMethodNameMap aBackgroundGradientFillMethodNameMap;
416 aBackgroundGradientFillMethodNameMap["none"] = Aspect_GFM_NONE;
417 aBackgroundGradientFillMethodNameMap["hor"] = Aspect_GFM_HOR;
418 aBackgroundGradientFillMethodNameMap["horizontal"] = Aspect_GFM_HOR;
419 aBackgroundGradientFillMethodNameMap["ver"] = Aspect_GFM_VER;
420 aBackgroundGradientFillMethodNameMap["vertical"] = Aspect_GFM_VER;
421 aBackgroundGradientFillMethodNameMap["diag1"] = Aspect_GFM_DIAG1;
422 aBackgroundGradientFillMethodNameMap["diagonal1"] = Aspect_GFM_DIAG1;
423 aBackgroundGradientFillMethodNameMap["diag2"] = Aspect_GFM_DIAG2;
424 aBackgroundGradientFillMethodNameMap["diagonal2"] = Aspect_GFM_DIAG2;
425 aBackgroundGradientFillMethodNameMap["corner1"] = Aspect_GFM_CORNER1;
426 aBackgroundGradientFillMethodNameMap["corner2"] = Aspect_GFM_CORNER2;
427 aBackgroundGradientFillMethodNameMap["corner3"] = Aspect_GFM_CORNER3;
428 aBackgroundGradientFillMethodNameMap["corner4"] = Aspect_GFM_CORNER4;
429 return aBackgroundGradientFillMethodNameMap;
430 }
431
432 //! Gets a gradient fill method by its name
433 //! @param theBackgroundGradientFillMethodName the name of the gradient fill method
434 //! @param theBackgroundGradientFillMethod the gradient fill method to be found
435 //! @return true if a gradient fill method is found, or false otherwise
436 static bool getBackgroundGradientFillMethodByName (const TCollection_AsciiString& theBackgroundGradientFillMethodName,
437 Aspect_GradientFillMethod& theBackgroundGradientFillMethod)
438 {
439 static const BackgroundGradientFillMethodNameMap THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP =
440 createBackgroundGradientFillMethodNameMap();
441 return getSomeCodeByName (THE_BACKGROUND_GRADIENT_FILL_METHOD_NAME_MAP,
442 theBackgroundGradientFillMethodName,
443 theBackgroundGradientFillMethod);
444 }
445
446 //! Changes the background in accordance with passed command line options
447 class BackgroundChanger
448 {
449 public:
450 //! Constructor. Prepares the command parser
451 BackgroundChanger()
452 {
453 prepareCommandParser();
454 }
455
456 //! Processes the command line and changes the background
457 //! @param theDrawInterpretor the interpreter of the Draw Harness application
458 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
459 //! @param theCommandLineArguments the array of command line arguments
460 bool ProcessCommandLine (Draw_Interpretor& theDrawInterpretor,
461 const Standard_Integer theNumberOfCommandLineArguments,
462 const char* const* const theCommandLineArguments)
463 {
464 const char* const aBackgroundCommandName = theCommandLineArguments[0];
465 BackgroundCommand aBackgroundCommand = BackgroundCommand_Main;
466 if (!getBackgroundCommandByName (aBackgroundCommandName, aBackgroundCommand))
467 {
468 return false;
469 }
470 addCommandDescription (aBackgroundCommand);
471 myCommandParser.Parse (theNumberOfCommandLineArguments, theCommandLineArguments);
472 return processCommandOptions (aBackgroundCommandName, aBackgroundCommand, theDrawInterpretor);
473 }
474
475 private:
476 //! The type of functions that are able to set gradient background filling
477 typedef void SetGradientFunction (const Quantity_Color& /* theColor1 */,
478 const Quantity_Color& /* theColor2 */,
479 const Aspect_GradientFillMethod /* theGradientMode */);
480
481 //! The type of functions that are able to fill a background with a specific color
482 typedef void SetColorFunction (const Quantity_Color& /* theColor */);
483
484 //! the command parser used to parse command line options and its arguments
485 ViewerTest_CmdParser myCommandParser;
486
487 //! the option key for the command that sets an image as a background
488 ViewerTest_CommandOptionKey myImageOptionKey;
489
490 //! the option key for the command that sets a background image fill type
491 ViewerTest_CommandOptionKey myImageModeOptionKey;
492
493 //! the option key for the command that sets a gradient filling for the background
494 ViewerTest_CommandOptionKey myGradientOptionKey;
495
496 //! the option key for the command that sets a background gradient filling method
497 ViewerTest_CommandOptionKey myGradientModeOptionKey;
498
499 //! the option key for the command that fills background with a specific color
500 ViewerTest_CommandOptionKey myColorOptionKey;
501
502 //! the option key for the command that sets default background gradient or color
503 ViewerTest_CommandOptionKey myDefaultOptionKey;
504
505 //! the variable set of options that are allowed for the old scenario (without any option passed)
506 CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
507
508 //! the variable set of options that are allowed for setting an image as a background
509 CommandOptionKeyVariableSet myImageOptionVariableSet;
510
511 //! the variable set of options that are allowed for setting a background image fill type
512 CommandOptionKeyVariableSet myImageModeOptionVariableSet;
513
514 //! the variable set of options that are allowed for setting a gradient filling for the background
515 CommandOptionKeyVariableSet myGradientOptionVariableSet;
516
517 //! the variable set of options that are allowed for setting a background gradient filling method
518 CommandOptionKeyVariableSet myGradientModeOptionVariableSet;
519
520 //! the variable set of options that are allowed for filling a background with a specific color
521 CommandOptionKeyVariableSet myColorOptionVariableSet;
522
523 //! the variable set of options that are allowed for setting a default background gradient
524 CommandOptionKeyVariableSet myDefaultGradientOptionVariableSet;
525
526 //! the variable set of options that are allowed for setting a default background color
527 CommandOptionKeyVariableSet myDefaultColorOptionVariableSet;
528
529 //! the variable set of options that are allowed for printing help
530 CommandOptionKeyVariableSet myHelpOptionVariableSet;
531
532 //! Adds options to command parser
533 void addOptionsToCommandParser()
534 {
535 myImageOptionKey = myCommandParser.AddOption ("imageFile|image|imgFile|img",
536 "filename of image used as background");
537 myImageModeOptionKey = myCommandParser.AddOption (
538 "imageMode|imgMode", "image fill type, should be one of CENTERED, TILED, STRETCH, NONE");
539 myGradientOptionKey = myCommandParser.AddOption ("gradient|grad|gr",
540 "sets background gradient starting and ending colors");
541 myGradientModeOptionKey =
542 myCommandParser.AddOption ("gradientMode|gradMode|gradMd|grMode|grMd",
543 "gradient fill method, should be one of NONE, HOR[IZONTAL], VER[TICAL], "
544 "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
545 myColorOptionKey = myCommandParser.AddOption ("color|col", "background color");
546 myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
547 }
548
549 //! Creates option sets used to determine if a passed option set is valid or not
550 void createOptionSets()
551 {
552 ViewerTest_CommandOptionKeySet anUnnamedOptionSet;
553 anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
554 myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
555
556 ViewerTest_CommandOptionKeySet anImageOptionSet;
557 anImageOptionSet.insert (myImageOptionKey);
558 ViewerTest_CommandOptionKeySet anImageModeOptionSet;
559 anImageModeOptionSet.insert (myImageModeOptionKey);
560 myImageOptionVariableSet = CommandOptionKeyVariableSet (anImageOptionSet, anImageModeOptionSet);
561 myImageModeOptionVariableSet = CommandOptionKeyVariableSet (anImageModeOptionSet);
562
563 ViewerTest_CommandOptionKeySet aGradientOptionSet;
564 aGradientOptionSet.insert (myGradientOptionKey);
565 ViewerTest_CommandOptionKeySet aGradientModeOptionSet;
566 aGradientModeOptionSet.insert (myGradientModeOptionKey);
567 myGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
568 myGradientModeOptionVariableSet = CommandOptionKeyVariableSet (aGradientModeOptionSet);
569
570 ViewerTest_CommandOptionKeySet aColorOptionSet;
571 aColorOptionSet.insert (myColorOptionKey);
572 myColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
573
574 aGradientOptionSet.insert (myDefaultOptionKey);
575 myDefaultGradientOptionVariableSet = CommandOptionKeyVariableSet (aGradientOptionSet, aGradientModeOptionSet);
576 aColorOptionSet.insert (myDefaultOptionKey);
577 myDefaultColorOptionVariableSet = CommandOptionKeyVariableSet (aColorOptionSet);
578
579 ViewerTest_CommandOptionKeySet aHelpOptionSet;
580 aHelpOptionSet.insert (ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
581 myHelpOptionVariableSet = CommandOptionKeyVariableSet (aHelpOptionSet);
582 }
583
584 //! Prepares the command parser. Adds options and creates option sets used to determine
585 //! if a passed option set is valid or not
586 void prepareCommandParser()
587 {
588 addOptionsToCommandParser();
589 createOptionSets();
590 }
591
592 //! Adds a command description to the command parser
593 //! @param theBackgroundCommand the key of the command which description is added to the command parser
594 void addCommandDescription (const BackgroundCommand theBackgroundCommand)
595 {
596 std::string aDescription;
597 bool isMainCommand = false;
598 switch (theBackgroundCommand)
599 {
600 case BackgroundCommand_Main:
601 aDescription = "Command: vbackground (changes background or some background settings)";
602 isMainCommand = true;
603 break;
604 case BackgroundCommand_Image:
605 aDescription = "Command: vsetbg (loads image as a background)";
606 break;
607 case BackgroundCommand_ImageMode:
608 aDescription = "Command: vsetbgmode (changes background fill type)";
609 break;
610 case BackgroundCommand_Gradient:
611 aDescription = "Command: vsetgradientbg (mounts gradient background)";
612 break;
613 case BackgroundCommand_GradientMode:
614 aDescription = "Command: vsetgradientbgmode (changes gradient background fill method)";
615 break;
616 case BackgroundCommand_Color:
617 aDescription = "Command: vsetcolorbg (sets color background)";
618 break;
619 case BackgroundCommand_Default:
620 aDescription = "Command: vsetdefaultbg (sets default viewer background gradient or fill color)";
621 break;
622 default:
623 return;
624 }
625 if (!isMainCommand)
626 {
627 aDescription += "\nThis command is obsolete. Use vbackground instead.";
628 }
629 myCommandParser.SetDescription (aDescription);
630 }
631
632 //! Check if a viewer is needed to be initialized
633 //! @param theBackgroundCommand the key of the command that changes the background
634 //! @return true if processing was successful, or false otherwise
635 bool checkViewerIsNeeded (const BackgroundCommand theBackgroundCommand) const
636 {
637 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
638 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
639 const bool aViewerIsNotNeeded =
640 (theBackgroundCommand == BackgroundCommand_Default)
641 || (myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
642 || (myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
643 || myHelpOptionVariableSet.IsInSet (aUsedOptions);
644 return !aViewerIsNotNeeded;
645 }
646
647 //! Check if a viewer is initialized
648 //! @param theBackgroundCommandName the name of the command that changes the background
649 //! @param theDrawInterpretor the interpreter of the Draw Harness application
650 //! @return true if a viewer is initialized, or false otherwise
651 static bool checkViewerIsInitialized (const char* const theBackgroundCommandName,
652 Draw_Interpretor& theDrawInterpretor)
653 {
654 const Handle (AIS_InteractiveContext)& anAISContext = ViewerTest::GetAISContext();
655 if (anAISContext.IsNull())
656 {
657 theDrawInterpretor << "Use 'vinit' command before executing '" << theBackgroundCommandName << "' command.\n";
658 return false;
659 }
660 return true;
661 }
662
663 //! Processes command options
664 //! @param theBackgroundCommandName the name of the command that changes the background
665 //! @param theBackgroundCommand the key of the command that changes the background
666 //! @param theDrawInterpretor the interpreter of the Draw Harness application
667 //! @return true if processing was successful, or false otherwise
668 bool processCommandOptions (const char* const theBackgroundCommandName,
669 const BackgroundCommand theBackgroundCommand,
670 Draw_Interpretor& theDrawInterpretor) const
671 {
672 if (myCommandParser.HasNoOption())
673 {
674 return printHelp (theBackgroundCommandName, theDrawInterpretor);
675 }
676 if (checkViewerIsNeeded (theBackgroundCommand)
677 && !checkViewerIsInitialized (theBackgroundCommandName, theDrawInterpretor))
678 {
679 return false;
680 }
681 if (myCommandParser.HasOnlyUnnamedOption())
682 {
683 return processUnnamedOption (theBackgroundCommand);
684 }
685 return processNamedOptions (theBackgroundCommandName, theBackgroundCommand, theDrawInterpretor);
686 }
687
688 //! Processes the unnamed option
689 //! @param theBackgroundCommand the key of the command that changes the background
690 //! @return true if processing was successful, or false otherwise
691 bool processUnnamedOption (const BackgroundCommand theBackgroundCommand) const
692 {
693 switch (theBackgroundCommand)
694 {
695 case BackgroundCommand_Main:
696 return false;
697 case BackgroundCommand_Image:
698 return processImageUnnamedOption();
699 case BackgroundCommand_ImageMode:
700 return processImageModeUnnamedOption();
701 case BackgroundCommand_Gradient:
702 return processGradientUnnamedOption();
703 case BackgroundCommand_GradientMode:
704 return processGradientModeUnnamedOption();
705 case BackgroundCommand_Color:
706 return processColorUnnamedOption();
707 case BackgroundCommand_Default:
708 return processDefaultUnnamedOption();
709 default:
710 return false;
711 }
712 }
713
714 //! Processes the image unnamed option
715 //! @return true if processing was successful, or false otherwise
716 bool processImageUnnamedOption() const
717 {
718 const std::size_t aNumberOfImageUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
719 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
720 if ((aNumberOfImageUnnamedOptionArguments != 1) && (aNumberOfImageUnnamedOptionArguments != 2))
721 {
722 return false;
723 }
724 std::string anImageFileName;
725 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0, anImageFileName))
726 {
727 return false;
728 }
729 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
730 if (aNumberOfImageUnnamedOptionArguments == 2)
731 {
732 std::string anImageModeString;
733 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 1, anImageModeString))
734 {
735 return false;
736 }
737 if (!getBackgroundImageFillMethodByName (anImageModeString.c_str(), anImageMode))
738 {
739 return false;
740 }
741 }
742 setImage (anImageFileName.c_str(), anImageMode);
743 return true;
744 }
745
746 //! Processes the image mode unnamed option
747 //! @return true if processing was successful, or false otherwise
748 bool processImageModeUnnamedOption() const
749 {
750 return processImageModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
751 }
752
753 //! Processes the gradient unnamed option
754 //! @param theSetGradient the function used to set a background gradient filling
755 //! @return true if processing was successful, or false otherwise
756 bool processGradientUnnamedOption (SetGradientFunction* const theSetGradient = setGradient) const
757 {
758 const Standard_Integer aNumberOfGradientUnnamedOptionArguments = myCommandParser.GetNumberOfOptionArguments (
759 ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
760 if (aNumberOfGradientUnnamedOptionArguments < 2)
761 {
762 return false;
763 }
764
765 Standard_Integer anArgumentIndex = 0;
766 Quantity_Color aColor1;
767 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor1))
768 {
769 return false;
770 }
771 if (anArgumentIndex >= aNumberOfGradientUnnamedOptionArguments)
772 {
773 return false;
774 }
775
776 Quantity_Color aColor2;
777 if (!myCommandParser.ArgColor (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, anArgumentIndex, aColor2))
778 {
779 return false;
780 }
781 if (anArgumentIndex > aNumberOfGradientUnnamedOptionArguments)
782 {
783 return false;
784 }
785
786 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
787 if (anArgumentIndex == aNumberOfGradientUnnamedOptionArguments - 1)
788 {
789 std::string anGradientModeString;
790
791 if (!myCommandParser.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY,
792 anArgumentIndex,
793 anGradientModeString))
794 {
795 return false;
796 }
797 if (!getBackgroundGradientFillMethodByName (anGradientModeString.c_str(), aGradientMode))
798 {
799 return false;
800 }
801 ++anArgumentIndex;
802 }
803 if (anArgumentIndex != aNumberOfGradientUnnamedOptionArguments)
804 {
805 return false;
806 }
807 theSetGradient (aColor1, aColor2, aGradientMode);
808 return true;
809 }
810
811 //! Processes the gradient mode unnamed option
812 //! @return true if processing was successful, or false otherwise
813 bool processGradientModeUnnamedOption() const
814 {
815 return processGradientModeOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
816 }
817
818 //! Processes the color unnamed option
819 //! @param theSetColor the function used to set a background color
820 //! @return true if processing was successful, or false otherwise
821 bool processColorUnnamedOption (SetColorFunction* const theSetColor = setColor) const
822 {
823 return processColorOptionSet (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, theSetColor);
824 }
825
826 //! Processes the default back unnamed option
827 //! @return true if processing was successful, or false otherwise
828 bool processDefaultUnnamedOption() const
829 {
830 if (processGradientUnnamedOption (setDefaultGradient))
831 {
832 return true;
833 }
834 return processColorUnnamedOption (setDefaultColor);
835 }
836
837 //! Processes named options
838 //! @param theBackgroundCommandName the name of the command that changes the background
839 //! @param theBackgroundCommand the key of the command that changes the background
840 //! @param theDrawInterpretor the interpreter of the Draw Harness application
841 //! @return true if processing was successful, or false otherwise
842 bool processNamedOptions (const char* const theBackgroundCommandName,
843 const BackgroundCommand theBackgroundCommand,
844 Draw_Interpretor& theDrawInterpretor) const
845 {
846 const bool isMain = (theBackgroundCommand == BackgroundCommand_Main);
847 const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
848 if (myImageOptionVariableSet.IsInSet (aUsedOptions)
849 && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
850 {
851 return processImageOptionSet();
852 }
853 if (myImageModeOptionVariableSet.IsInSet (aUsedOptions)
854 && (isMain || (theBackgroundCommand == BackgroundCommand_ImageMode)))
855 {
856 return processImageModeOptionSet();
857 }
858 if (myGradientOptionVariableSet.IsInSet (aUsedOptions)
859 && (isMain || (theBackgroundCommand == BackgroundCommand_Gradient)))
860 {
861 return processGradientOptionSet();
862 }
863 if (myGradientModeOptionVariableSet.IsInSet (aUsedOptions)
864 && (isMain || (theBackgroundCommand == BackgroundCommand_GradientMode)))
865 {
866 return processGradientModeOptionSet();
867 }
868 if (myColorOptionVariableSet.IsInSet (aUsedOptions)
869 && (isMain || (theBackgroundCommand == BackgroundCommand_Color)))
870 {
871 return processColorOptionSet();
872 }
873 if ((myDefaultGradientOptionVariableSet.IsInSet (aUsedOptions) && isMain)
874 || (myGradientOptionVariableSet.IsInSet (aUsedOptions)
875 && (theBackgroundCommand == BackgroundCommand_Default)))
876 {
877 return processDefaultGradientOptionSet();
878 }
879 if ((myDefaultColorOptionVariableSet.IsInSet (aUsedOptions) && isMain)
880 || (myColorOptionVariableSet.IsInSet (aUsedOptions) && (theBackgroundCommand == BackgroundCommand_Default)))
881 {
882 return processDefaultColorOptionSet();
883 }
884 if (myHelpOptionVariableSet.IsInSet (aUsedOptions))
885 {
886 return processHelpOptionSet (theBackgroundCommandName, theDrawInterpretor);
887 }
888 return false;
889 }
890
891 //! Processes the image option set
892 //! @return true if processing was successful, or false otherwise
893 bool processImageOptionSet() const
894 {
895 std::string anImageFileName;
896 if (!processImageOption (anImageFileName))
897 {
898 return false;
899 }
900 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
901 if (myCommandParser.HasOption (myImageModeOptionKey) && !processImageModeOption (anImageMode))
902 {
903 return false;
904 }
905 setImage (anImageFileName.c_str(), anImageMode);
906 return true;
907 }
908
909 //! Processes the image mode option set
910 //! @return true if processing was successful, or false otherwise
911 bool processImageModeOptionSet() const
912 {
913 return processImageModeOptionSet (myImageModeOptionKey);
914 }
915
916 //! Processes the image mode option set
917 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
918 //! @return true if processing was successful, or false otherwise
919 bool processImageModeOptionSet (const ViewerTest_CommandOptionKey theImageModeOptionKey) const
920 {
921 Aspect_FillMethod anImageMode = Aspect_FM_NONE;
922 if (!processImageModeOption (theImageModeOptionKey, anImageMode))
923 {
924 return false;
925 }
926 setImageMode (anImageMode);
927 return true;
928 }
929
930 //! Processes the gradient option set
931 //! @param theSetGradient the function used to set a background gradient filling
932 //! @return true if processing was successful, or false otherwise
933 bool processGradientOptionSet (SetGradientFunction* const theSetGradient = setGradient) const
934 {
935 Quantity_Color aColor1;
936 Quantity_Color aColor2;
937 if (!processGradientOption (aColor1, aColor2))
938 {
939 return false;
940 }
941 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_HOR;
942 if (myCommandParser.HasOption (myGradientModeOptionKey) && !processGradientModeOption (aGradientMode))
943 {
944 return false;
945 }
946 theSetGradient (aColor1, aColor2, aGradientMode);
947 return true;
948 }
949
950 //! Processes the gradient mode option set
951 //! @return true if processing was successful, or false otherwise
952 bool processGradientModeOptionSet() const
953 {
954 return processGradientModeOptionSet (myGradientModeOptionKey);
955 }
956
957 //! Processes the gradient mode option set
958 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
959 //! @return true if processing was successful, or false otherwise
960 bool processGradientModeOptionSet (const ViewerTest_CommandOptionKey theGradientModeOptionKey) const
961 {
962 Aspect_GradientFillMethod aGradientMode = Aspect_GFM_NONE;
963 if (!processGradientModeOption (theGradientModeOptionKey, aGradientMode))
964 {
965 return false;
966 }
967 setGradientMode (aGradientMode);
968 return true;
969 }
970
971 //! Processes the color option set
972 //! @param theSetColor the function used to set a background color
973 //! @return true if processing was successful, or false otherwise
974 bool processColorOptionSet (SetColorFunction* const theSetColor = setColor) const
975 {
976 return processColorOptionSet (myColorOptionKey, theSetColor);
977 }
978
979 //! Processes the default color option set
980 //! @return true if processing was successful, or false otherwise
981 bool processDefaultGradientOptionSet() const
982 {
983 return processGradientOptionSet (setDefaultGradient);
984 }
985
986 //! Processes the default gradient option set
987 //! @return true if processing was successful, or false otherwise
988 bool processDefaultColorOptionSet() const
989 {
990 return processColorOptionSet (setDefaultColor);
991 }
992
993 //! Processes the color option set
994 //! @param theColorOptionKey the key of the option that is interpreted as a color option
995 //! @param theSetColor the function used to set a background color
996 //! @return true if processing was successful, or false otherwise
997 bool processColorOptionSet (const ViewerTest_CommandOptionKey theColorOptionKey,
998 SetColorFunction* const theSetColor = setColor) const
999 {
1000 Quantity_Color aColor;
1001 if (!processColorOption (theColorOptionKey, aColor))
1002 {
1003 return false;
1004 }
1005 theSetColor (aColor);
1006 return true;
1007 }
1008
1009 //! Processes the help option set
1010 //! @param theBackgroundCommandName the name of the command that changes the background
1011 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1012 //! @return true if processing was successful, or false otherwise
1013 bool processHelpOptionSet (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor) const
1014 {
1015 const Standard_Integer aNumberOfHelpOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1016 ViewerTest_CmdParser::THE_HELP_COMMAND_OPTION_KEY);
1017 if (aNumberOfHelpOptionArguments != 0)
1018 {
1019 return false;
1020 }
1021 return printHelp (theBackgroundCommandName, theDrawInterpretor);
1022 }
1023
1024 //! Processes the image option
1025 //! @param theImageFileName the filename of the image to be used as a background
1026 //! @return true if processing was successful, or false otherwise
1027 bool processImageOption (std::string& theImageFileName) const
1028 {
1029 const Standard_Integer aNumberOfImageOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1030 myImageOptionKey);
1031 if (aNumberOfImageOptionArguments != 1)
1032 {
1033 return false;
1034 }
1035 std::string anImageFileName;
1036 if (!myCommandParser.Arg (myImageOptionKey, 0, anImageFileName))
1037 {
1038 return false;
1039 }
1040 theImageFileName = anImageFileName;
1041 return true;
1042 }
1043
1044 //! Processes the image mode option
1045 //! @param theImageMode the fill type used for a background image
1046 //! @return true if processing was successful, or false otherwise
1047 bool processImageModeOption (Aspect_FillMethod& theImageMode) const
1048 {
1049 return processImageModeOption (myImageModeOptionKey, theImageMode);
1050 }
1051
1052 //! Processes the image mode option
1053 //! @param theImageModeOptionKey the key of the option that is interpreted as an image mode option
1054 //! @param theImageMode the fill type used for a background image
1055 //! @return true if processing was successful, or false otherwise
1056 bool processImageModeOption (const ViewerTest_CommandOptionKey theImageModeOptionKey,
1057 Aspect_FillMethod& theImageMode) const
1058 {
1059 return processModeOption (theImageModeOptionKey, getBackgroundImageFillMethodByName, theImageMode);
1060 }
1061
1062 //! Processes the gradient option
1063 //! @param theColor1 the gradient starting color
1064 //! @param theColor2 the gradient ending color
1065 //! @return true if processing was successful, or false otherwise
1066 bool processGradientOption (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1067 {
1068 Standard_Integer anArgumentIndex = 0;
1069 Quantity_Color aColor1;
1070 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor1))
1071 {
1072 return false;
1073 }
1074 Quantity_Color aColor2;
1075 if (!myCommandParser.ArgColor (myGradientOptionKey, anArgumentIndex, aColor2))
1076 {
1077 return false;
1078 }
1079 const Standard_Integer aNumberOfGradientOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1080 myGradientOptionKey);
1081 if (anArgumentIndex != aNumberOfGradientOptionArguments)
1082 {
1083 return false;
1084 }
1085 theColor1 = aColor1;
1086 theColor2 = aColor2;
1087 return true;
1088 }
1089
1090 //! Processes the gradient mode option
1091 //! @param theGradientMode the fill method used for a background gradient filling
1092 //! @return true if processing was successful, or false otherwise
1093 bool processGradientModeOption (Aspect_GradientFillMethod& theGradientMode) const
1094 {
1095 return processGradientModeOption (myGradientModeOptionKey, theGradientMode);
1096 }
1097
1098 //! Processes the gradient mode option
1099 //! @param theGradientModeOptionKey the key of the option that is interpreted as a gradient mode option
1100 //! @param theGradientMode the fill method used for a background gradient filling
1101 //! @return true if processing was successful, or false otherwise
1102 bool processGradientModeOption (const ViewerTest_CommandOptionKey theGradientModeOptionKey,
1103 Aspect_GradientFillMethod& theGradientMode) const
1104 {
1105 return processModeOption (theGradientModeOptionKey, getBackgroundGradientFillMethodByName, theGradientMode);
1106 }
1107
1108 //! Processes some mode option
1109 //! @tparam TheMode the type of a mode to be processed
1110 //! @param theModeOptionKey the key of the option that is interpreted as a mode option
1111 //! @param theMode a mode to be processed
1112 //! @return true if processing was successful, or false otherwise
1113 template <typename TheMode>
1114 bool processModeOption (const ViewerTest_CommandOptionKey theModeOptionKey,
1115 bool (*const theGetModeByName) (const TCollection_AsciiString& /* theModeName */,
1116 TheMode& /* theMode */),
1117 TheMode& theMode) const
1118 {
1119 const Standard_Integer aNumberOfModeOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1120 theModeOptionKey);
1121 if (aNumberOfModeOptionArguments != 1)
1122 {
1123 return false;
1124 }
1125 std::string aModeString;
1126 if (!myCommandParser.Arg (theModeOptionKey, 0, aModeString))
1127 {
1128 return false;
1129 }
1130 TheMode aMode = TheMode();
1131 if (!theGetModeByName (aModeString.c_str(), aMode))
1132 {
1133 return false;
1134 }
1135 theMode = aMode;
1136 return true;
1137 }
1138
1139 //! Processes the color option
1140 //! @param theColor a color used for filling a background
1141 //! @return true if processing was successful, or false otherwise
1142 bool processColorOption (Quantity_Color& theColor) const
1143 {
1144 return processColorOption (myColorOptionKey, theColor);
1145 }
1146
1147 //! Processes the color option
1148 //! @param theColorOptionKey the key of the option that is interpreted as a color option
1149 //! @param theColor a color used for filling a background
1150 //! @return true if processing was successful, or false otherwise
1151 bool processColorOption (const ViewerTest_CommandOptionKey theColorOptionKey, Quantity_Color& theColor) const
1152 {
1153 Standard_Integer anArgumentIndex = 0;
1154 Quantity_Color aColor;
1155 if (!myCommandParser.ArgColor (theColorOptionKey, anArgumentIndex, aColor))
1156 {
1157 return false;
1158 }
1159 const Standard_Integer aNumberOfColorOptionArguments = myCommandParser.GetNumberOfOptionArguments (
1160 theColorOptionKey);
1161 if (anArgumentIndex != aNumberOfColorOptionArguments)
1162 {
1163 return false;
1164 }
1165 theColor = aColor;
1166 return true;
1167 }
1168
1169 //! Prints helping message
1170 //! @param theBackgroundCommandName the name of the command that changes the background
1171 //! @param theDrawInterpretor the interpreter of the Draw Harness application
1172 //! @return true if printing was successful, or false otherwise
1173 static bool printHelp (const char* const theBackgroundCommandName, Draw_Interpretor& theDrawInterpretor)
1174 {
1175 return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
1176 }
1177
1178 //! Sets the image as a background
1179 //! @param theImageFileName the filename of the image to be used as a background
1180 //! @param theImageMode the fill type used for a background image
1181 static void setImage (const Standard_CString theImageFileName, const Aspect_FillMethod theImageMode)
1182 {
1183 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1184 aCurrentView->SetBackgroundImage (theImageFileName, theImageMode, Standard_True);
1185 }
1186
1187 //! Sets the fill type used for a background image
1188 //! @param theImageMode the fill type used for a background image
1189 static void setImageMode (const Aspect_FillMethod theImageMode)
1190 {
1191 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1192 aCurrentView->SetBgImageStyle (theImageMode, Standard_True);
1193 }
1194
1195 //! Sets the gradient filling for a background
1196 //! @param theColor1 the gradient starting color
1197 //! @param theColor2 the gradient ending color
1198 //! @param theGradientMode the fill method used for a background gradient filling
1199 static void setGradient (const Quantity_Color& theColor1,
1200 const Quantity_Color& theColor2,
1201 const Aspect_GradientFillMethod theGradientMode)
1202 {
1203 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1204 aCurrentView->SetBgGradientColors (theColor1, theColor2, theGradientMode, Standard_True);
1205 }
1206
1207 //! Sets the fill method used for a background gradient filling
1208 //! @param theGradientMode the fill method used for a background gradient filling
1209 static void setGradientMode (const Aspect_GradientFillMethod theGradientMode)
1210 {
1211 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1212 aCurrentView->SetBgGradientStyle (theGradientMode, Standard_True);
1213 }
1214
1215 //! Sets the color used for filling a background
1216 //! @param theColor the color used for filling a background
1217 static void setColor (const Quantity_Color& theColor)
1218 {
1219 const Handle (V3d_View)& aCurrentView = ViewerTest::CurrentView();
1220 aCurrentView->SetBgGradientStyle (Aspect_GFM_NONE);
1221 aCurrentView->SetBackgroundColor (theColor);
1222 aCurrentView->Update();
1223 }
1224
1225 //! Sets the gradient filling for a background in a default viewer
1226 //! @param theColor1 the gradient starting color
1227 //! @param theColor2 the gradient ending color
1228 //! @param theGradientMode the fill method used for a background gradient filling
1229 static void setDefaultGradient (const Quantity_Color& theColor1,
1230 const Quantity_Color& theColor2,
1231 const Aspect_GradientFillMethod theGradientMode)
1232 {
1233 ViewerTest_DefaultBackground.GradientColor1 = theColor1;
1234 ViewerTest_DefaultBackground.GradientColor2 = theColor2;
1235 ViewerTest_DefaultBackground.FillMethod = theGradientMode;
1236 setDefaultGradient();
1237 }
1238
1239 //! Sets the color used for filling a background in a default viewer
1240 //! @param theColor the color used for filling a background
1241 static void setDefaultColor (const Quantity_Color& theColor)
1242 {
1243 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
1244 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
1245 ViewerTest_DefaultBackground.FillMethod = Aspect_GFM_NONE;
1246 ViewerTest_DefaultBackground.FlatColor = theColor;
1247 setDefaultGradient();
1248 setDefaultColor();
1249 }
1250
1251 //! Sets the gradient filling for a background in a default viewer.
1252 //! Gradient settings are taken from ViewerTest_DefaultBackground structure
1253 static void setDefaultGradient()
1254 {
1255 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1256 anInteractiveContextIterator (ViewerTest_myContexts);
1257 anInteractiveContextIterator.More();
1258 anInteractiveContextIterator.Next())
1259 {
1260 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1261 aViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1262 ViewerTest_DefaultBackground.GradientColor2,
1263 ViewerTest_DefaultBackground.FillMethod);
1264 }
1265 }
1266
1267 //! Sets the color used for filling a background in a default viewer.
1268 //! The color value is taken from ViewerTest_DefaultBackground structure
1269 static void setDefaultColor()
1270 {
1271 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator
1272 anInteractiveContextIterator (ViewerTest_myContexts);
1273 anInteractiveContextIterator.More();
1274 anInteractiveContextIterator.Next())
1275 {
1276 const Handle (V3d_Viewer)& aViewer = anInteractiveContextIterator.Value()->CurrentViewer();
1277 aViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1278 }
1279 }
1280 };
1281
1282} // namespace
b12e1c7b 1283
1284Standard_EXPORT const Handle(AIS_RubberBand)& GetRubberBand()
1285{
1286 static Handle(AIS_RubberBand) aBand;
1287 if (aBand.IsNull())
1288 {
69adb9ce 1289 aBand = new AIS_RubberBand (Quantity_NOC_LIGHTBLUE, Aspect_TOL_SOLID, Quantity_NOC_LIGHTBLUE, 0.4, 1.0);
1290 aBand->SetDisplayMode (0);
b12e1c7b 1291 }
1292 return aBand;
1293}
1294
625e1958 1295typedef NCollection_Map<AIS_Manipulator*> ViewerTest_MapOfAISManipulators;
1296
1297Standard_EXPORT ViewerTest_MapOfAISManipulators& GetMapOfAISManipulators()
1298{
1299 static ViewerTest_MapOfAISManipulators aMap;
1300 return aMap;
1301}
1302
1303Standard_EXPORT Handle(AIS_Manipulator) GetActiveAISManipulator()
1304{
1305 ViewerTest_MapOfAISManipulators::Iterator anIt (GetMapOfAISManipulators());
1306 for (; anIt.More(); anIt.Next())
1307 {
1308 if (anIt.Value()->HasActiveMode())
1309 {
1310 return anIt.Value();
1311 }
1312 }
1313 return NULL;
1314}
1315
7fd59977 1316//==============================================================================
1317
57c28b61 1318#ifdef _WIN32
7fd59977 1319static LRESULT WINAPI ViewerWindowProc(
1320 HWND hwnd,
1321 UINT uMsg,
1322 WPARAM wParam,
1323 LPARAM lParam );
1324static LRESULT WINAPI AdvViewerWindowProc(
1325 HWND hwnd,
1326 UINT uMsg,
1327 WPARAM wParam,
1328 LPARAM lParam );
1329#endif
1330
1331
1332//==============================================================================
1333//function : WClass
1334//purpose :
1335//==============================================================================
1336
ad03c234 1337const Handle(Standard_Transient)& ViewerTest::WClass()
7fd59977 1338{
ad03c234 1339 static Handle(Standard_Transient) theWClass;
58655684 1340#if defined(_WIN32)
4fe56619 1341 if (theWClass.IsNull())
1342 {
7c65581d 1343 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
ad03c234 1344 CS_VREDRAW | CS_HREDRAW, 0, 0,
c85a994a 1345 ::LoadCursor (NULL, IDC_ARROW));
7fd59977 1346 }
1347#endif
1348 return theWClass;
1349}
1350
18d715bd 1351//==============================================================================
1352//function : CreateName
1353//purpose : Create numerical name for new object in theMap
1354//==============================================================================
1355template <typename ObjectType>
1356TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
1357 const TCollection_AsciiString& theDefaultString)
1358{
1359 if (theObjectMap.IsEmpty())
1360 return theDefaultString + TCollection_AsciiString(1);
1361
1362 Standard_Integer aNextKey = 1;
1363 Standard_Boolean isFound = Standard_False;
1364 while (!isFound)
1365 {
1366 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
1367 // Look for objects with default names
1368 if (theObjectMap.IsBound1(aStringKey))
1369 {
1370 aNextKey++;
1371 }
1372 else
1373 isFound = Standard_True;
1374 }
1375
1376 return theDefaultString + TCollection_AsciiString(aNextKey);
1377}
1378
1379//==============================================================================
1380//structure : ViewerTest_Names
1381//purpose : Allow to operate with full view name: driverName/viewerName/viewName
1382//==============================================================================
1383struct ViewerTest_Names
1384{
1385private:
1386 TCollection_AsciiString myDriverName;
1387 TCollection_AsciiString myViewerName;
1388 TCollection_AsciiString myViewName;
1389
1390public:
1391
1392 const TCollection_AsciiString& GetDriverName () const
1393 {
1394 return myDriverName;
1395 }
1396 void SetDriverName (const TCollection_AsciiString& theDriverName)
1397 {
1398 myDriverName = theDriverName;
1399 }
1400 const TCollection_AsciiString& GetViewerName () const
1401 {
1402 return myViewerName;
1403 }
1404 void SetViewerName (const TCollection_AsciiString& theViewerName)
1405 {
1406 myViewerName = theViewerName;
1407 }
1408 const TCollection_AsciiString& GetViewName () const
1409 {
1410 return myViewName;
1411 }
1412 void SetViewName (const TCollection_AsciiString& theViewName)
1413 {
1414 myViewName = theViewName;
1415 }
1416
1417 //===========================================================================
1418 //function : Constructor for ViewerTest_Names
1419 //purpose : Get view, viewer, driver names from custom string
1420 //===========================================================================
1421
1422 ViewerTest_Names (const TCollection_AsciiString& theInputString)
1423 {
1424 TCollection_AsciiString aName(theInputString);
1425 if (theInputString.IsEmpty())
1426 {
1427 // Get current configuration
1428 if (ViewerTest_myDrivers.IsEmpty())
1429 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1430 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1431 else
1432 myDriverName = ViewerTest_myDrivers.Find2
1433 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1434
1435 if(ViewerTest_myContexts.IsEmpty())
1436 {
1437 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1438 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1439 }
1440 else
c48e2889 1441 {
18d715bd 1442 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
c48e2889 1443 }
18d715bd 1444
c48e2889 1445 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
18d715bd 1446 }
1447 else
1448 {
1449 // There is at least view name
1450 Standard_Integer aParserNumber = 0;
1451 for (Standard_Integer i = 0; i < 3; ++i)
1452 {
1453 Standard_Integer aParserPos = aName.SearchFromEnd("/");
1454 if(aParserPos != -1)
1455 {
1456 aParserNumber++;
1457 aName.Split(aParserPos-1);
1458 }
1459 else
1460 break;
1461 }
1462 if (aParserNumber == 0)
1463 {
1464 // Only view name
1465 if (!ViewerTest::GetAISContext().IsNull())
1466 {
1467 myDriverName = ViewerTest_myDrivers.Find2
1468 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1469 myViewerName = ViewerTest_myContexts.Find2
1470 (ViewerTest::GetAISContext());
1471 }
1472 else
1473 {
1474 // There is no opened contexts here, need to create names for viewer and driver
1475 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1476 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1477
1478 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
1479 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
1480 }
1481 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
1482 }
1483 else if (aParserNumber == 1)
1484 {
1485 // Here is viewerName/viewName
1486 if (!ViewerTest::GetAISContext().IsNull())
1487 myDriverName = ViewerTest_myDrivers.Find2
1488 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
1489 else
1490 {
1491 // There is no opened contexts here, need to create name for driver
1492 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
1493 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
1494 }
1495 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
1496
1497 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
1498 }
1499 else
1500 {
1501 //Here is driverName/viewerName/viewName
1502 myDriverName = TCollection_AsciiString(aName);
1503
1504 TCollection_AsciiString aViewerName(theInputString);
1505 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
1506 myViewerName = TCollection_AsciiString(aViewerName);
1507
1508 myViewName = TCollection_AsciiString(theInputString);
1509 }
1510 }
1511 }
1512};
1513
1514//==============================================================================
1515//function : FindContextByView
1516//purpose : Find AIS_InteractiveContext by View
1517//==============================================================================
1518
1519Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
1520{
1521 Handle(AIS_InteractiveContext) anAISContext;
1522
1523 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1524 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
1525 {
1526 if (anIter.Value()->CurrentViewer() == theView->Viewer())
1527 return anIter.Key2();
1528 }
1529 return anAISContext;
1530}
1531
1532
1533//==============================================================================
1534//function : SetWindowTitle
1535//purpose : Set window title
1536//==============================================================================
1537
1538void SetWindowTitle (const Handle(Aspect_Window)& theWindow,
1539 Standard_CString theTitle)
1540{
58655684 1541#if defined(_WIN32)
ad03c234 1542 const TCollection_ExtendedString theTitleW (theTitle);
1543 SetWindowTextW ((HWND )Handle(WNT_Window)::DownCast(theWindow)->HWindow(), theTitleW.ToWideString());
18d715bd 1544#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1545 SetCocoaWindowTitle (Handle(Cocoa_Window)::DownCast(theWindow), theTitle);
1546#else
1547 if(GetDisplayConnection()->GetDisplay())
1548 {
1549 Window aWindow =
1550 Handle(Xw_Window)::DownCast(theWindow)->XWindow();
1551 XStoreName (GetDisplayConnection()->GetDisplay(), aWindow , theTitle);
1552 }
1553#endif
1554}
1555
1556//==============================================================================
1557//function : IsWindowOverlapped
1558//purpose : Check if theWindow overlapp another view
1559//==============================================================================
1560
1561Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
1562 const Standard_Integer thePxTop,
1563 const Standard_Integer thePxRight,
1564 const Standard_Integer thePxBottom,
1565 TCollection_AsciiString& theViewId)
1566{
1567 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
1568 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1569 {
1570 Standard_Integer aTop = 0,
1571 aLeft = 0,
1572 aRight = 0,
1573 aBottom = 0;
1574 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
1575 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1576 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
1577 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
1578 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
1579 {
1580 theViewId = anIter.Key1();
1581 return Standard_True;
1582 }
1583 }
1584 return Standard_False;
1585}
1586
1587// Workaround: to create and delete non-orthographic views outside ViewerTest
1588void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
1589{
1590 ViewerTest_myViews.UnBind1 (theName);
1591}
1592
1593void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
1594 const Handle(V3d_View)& theView)
1595{
1596 ViewerTest_myViews.Bind (theName, theView);
1597}
1598
1599TCollection_AsciiString ViewerTest::GetCurrentViewName ()
1600{
1601 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
1602}
8693dfd0 1603
1604//! Auxiliary tool performing continuous redraws of specified window.
1605class ViewerTest_ContinuousRedrawer
1606{
1607public:
1608 //! Return global instance.
1609 static ViewerTest_ContinuousRedrawer& Instance()
1610 {
1611 static ViewerTest_ContinuousRedrawer aRedrawer;
1612 return aRedrawer;
1613 }
1614public:
1615
1616 //! Destructor.
1617 ~ViewerTest_ContinuousRedrawer()
1618 {
1619 Stop();
1620 }
1621
1622 //! Start thread.
1623 void Start (const Handle(Aspect_Window)& theWindow,
1624 Standard_Real theTargetFps)
1625 {
1626 if (myWindow != theWindow
1627 || myTargetFps != theTargetFps)
1628 {
1629 Stop();
1630 myWindow = theWindow;
1631 myTargetFps = theTargetFps;
1632 }
1633 if (myThread.GetId() == 0)
1634 {
1635 myToStop = false;
1636 myThread.Run (this);
1637 }
1638 }
1639
1640 //! Stop thread.
1641 void Stop (const Handle(Aspect_Window)& theWindow = NULL)
1642 {
1643 if (!theWindow.IsNull()
1644 && myWindow != theWindow)
1645 {
1646 return;
1647 }
1648
1649 {
1650 Standard_Mutex::Sentry aLock (myMutex);
1651 myToStop = true;
1652 }
1653 myThread.Wait();
1654 myToStop = false;
1655 myWindow.Nullify();
1656 }
1657
1658private:
1659
1660 //! Thread loop.
1661 void doThreadLoop()
1662 {
1663 Handle(Aspect_DisplayConnection) aDisp = new Aspect_DisplayConnection();
1664 OSD_Timer aTimer;
1665 aTimer.Start();
1666 Standard_Real aTimeOld = 0.0;
1667 const Standard_Real aTargetDur = myTargetFps > 0.0 ? 1.0 / myTargetFps : -1.0;
1668 for (;;)
1669 {
1670 {
1671 Standard_Mutex::Sentry aLock (myMutex);
1672 if (myToStop)
1673 {
1674 return;
1675 }
1676 }
1677 if (myTargetFps > 0.0)
1678 {
1679 const Standard_Real aTimeNew = aTimer.ElapsedTime();
1680 const Standard_Real aDuration = aTimeNew - aTimeOld;
1681 if (aDuration >= aTargetDur)
1682 {
1683 myWindow->InvalidateContent (aDisp);
1684 aTimeOld = aTimeNew;
1685 }
1686 }
1687 else
1688 {
1689 myWindow->InvalidateContent (aDisp);
1690 }
1691
1692 OSD::MilliSecSleep (1);
1693 }
1694 }
1695
1696 //! Thread creation callback.
1697 static Standard_Address doThreadWrapper (Standard_Address theData)
1698 {
1699 ViewerTest_ContinuousRedrawer* aThis = (ViewerTest_ContinuousRedrawer* )theData;
1700 aThis->doThreadLoop();
1701 return 0;
1702 }
1703
1704 //! Empty constructor.
1705 ViewerTest_ContinuousRedrawer()
1706 : myThread (doThreadWrapper),
1707 myTargetFps (0.0),
1708 myToStop (false) {}
1709
1710private:
1711 Handle(Aspect_Window) myWindow;
1712 OSD_Thread myThread;
1713 Standard_Mutex myMutex;
1714 Standard_Real myTargetFps;
1715 volatile bool myToStop;
1716};
1717
7fd59977 1718//==============================================================================
1719//function : ViewerInit
1720//purpose : Create the window viewer and initialize all the global variable
1721//==============================================================================
1722
18d715bd 1723TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
1724 const Standard_Integer thePxTop,
1725 const Standard_Integer thePxWidth,
1726 const Standard_Integer thePxHeight,
9e04ccdc 1727 const TCollection_AsciiString& theViewName,
1728 const TCollection_AsciiString& theDisplayName,
1729 const Handle(V3d_View)& theViewToClone)
7fd59977 1730{
8c3c9904 1731 // Default position and dimension of the viewer window.
4fe56619 1732 // Note that left top corner is set to be sufficiently small to have
8c3c9904 1733 // window fit in the small screens (actual for remote desktops, see #23003).
4fe56619 1734 // The position corresponds to the window's client area, thus some
8c3c9904 1735 // gap is added for window frame to be visible.
1736 Standard_Integer aPxLeft = 20;
1737 Standard_Integer aPxTop = 40;
7fd59977 1738 Standard_Integer aPxWidth = 409;
1739 Standard_Integer aPxHeight = 409;
18d715bd 1740 Standard_Boolean toCreateViewer = Standard_False;
9e04ccdc 1741 if (!theViewToClone.IsNull())
1742 {
1743 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
1744 }
18d715bd 1745
58655684 1746 Handle(OpenGl_GraphicDriver) aGraphicDriver;
18d715bd 1747 ViewerTest_Names aViewNames(theViewName);
1748 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName ()))
1749 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
1750
1751 if (thePxLeft != 0)
1752 aPxLeft = thePxLeft;
1753 if (thePxTop != 0)
1754 aPxTop = thePxTop;
1755 if (thePxWidth != 0)
1756 aPxWidth = thePxWidth;
1757 if (thePxHeight != 0)
7fd59977 1758 aPxHeight = thePxHeight;
4269bd1b 1759
18d715bd 1760 // Get graphic driver (create it or get from another view)
8693dfd0 1761 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
1762 if (isNewDriver)
18d715bd 1763 {
1764 // Get connection string
58655684 1765 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 1766 if (!theDisplayName.IsEmpty())
1767 {
1768 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
1769 }
18d715bd 1770 else
8693dfd0 1771 {
1772 ::Display* aDispX = NULL;
1773 // create dedicated display connection instead of reusing Tk connection
1774 // so that to procede events independently through VProcessEvents()/ViewerMainLoop() callbacks
1775 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
1776 Tcl_Interp* aTclInterp = aCommands.Interp();
1777 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
1778 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
1779 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
1780 }
18d715bd 1781 #else
498ce76b 1782 (void)theDisplayName; // avoid warning on unused argument
18d715bd 1783 SetDisplayConnection (new Aspect_DisplayConnection ());
1784 #endif
14cb22a1 1785
1786 if (Draw_VirtualWindows)
1787 {
1788 // don't waste the time waiting for VSync when window is not displayed on the screen
1789 ViewerTest_myDefaultCaps.swapInterval = 0;
1790 // alternatively we can disable buffer swap at all, but this might be inappropriate for testing
1791 //ViewerTest_myDefaultCaps.buffersNoSwap = true;
1792 }
65993a95 1793 aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
58655684 1794 aGraphicDriver->ChangeOptions() = ViewerTest_myDefaultCaps;
14cb22a1 1795
18d715bd 1796 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
1797 toCreateViewer = Standard_True;
1798 }
1799 else
1800 {
58655684 1801 aGraphicDriver = Handle(OpenGl_GraphicDriver)::DownCast (ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName()));
7fd59977 1802 }
1803
18d715bd 1804 //Dispose the window if input parameters are default
1805 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
7fd59977 1806 {
18d715bd 1807 Standard_Integer aTop = 0,
1808 aLeft = 0,
1809 aRight = 0,
1810 aBottom = 0,
1811 aScreenWidth = 0,
1812 aScreenHeight = 0;
1813
1814 // Get screen resolution
1815#if defined(_WIN32) || defined(__WIN32__)
1816 RECT aWindowSize;
1817 GetClientRect(GetDesktopWindow(), &aWindowSize);
1818 aScreenHeight = aWindowSize.bottom;
1819 aScreenWidth = aWindowSize.right;
1820#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1821 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
1822#else
1823 Screen *aScreen = DefaultScreenOfDisplay(GetDisplayConnection()->GetDisplay());
1824 aScreenWidth = WidthOfScreen(aScreen);
1825 aScreenHeight = HeightOfScreen(aScreen);
1826#endif
1827
1828 TCollection_AsciiString anOverlappedViewId("");
773f53f1 1829
1830 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
dc3fe572 1831 {
18d715bd 1832 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
1833
1834 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
1835 && aRight + 2*aPxWidth + 40 > aScreenWidth)
1836 {
1837 if (aBottom + aPxHeight + 40 > aScreenHeight)
1838 {
1839 aPxLeft = 20;
1840 aPxTop = 40;
1841 break;
1842 }
1843 aPxLeft = 20;
1844 aPxTop = aBottom + 40;
1845 }
1846 else
1847 aPxLeft = aRight + 20;
dc3fe572 1848 }
18d715bd 1849 }
1850
1851 // Get viewer name
1852 TCollection_AsciiString aTitle("3D View - ");
1853 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
1854
1855 // Change name of current active window
1856 if (!ViewerTest::CurrentView().IsNull())
1857 {
51740958 1858 TCollection_AsciiString anActiveWindowTitle("3D View - ");
1859 anActiveWindowTitle = anActiveWindowTitle
18d715bd 1860 + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
51740958 1861 SetWindowTitle (ViewerTest::CurrentView()->Window(), anActiveWindowTitle.ToCString());
18d715bd 1862 }
1863
1864 // Create viewer
eb4320f2 1865 Handle(V3d_Viewer) a3DViewer;
18d715bd 1866 // If it's the single view, we first look for empty context
1867 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
1868 {
1869 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1870 anIter(ViewerTest_myContexts);
1871 if (anIter.More())
1872 ViewerTest::SetAISContext (anIter.Value());
1873 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1874 }
1875 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
1876 {
1877 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
1878 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
18d715bd 1879 }
eb4320f2 1880 else if (a3DViewer.IsNull())
18d715bd 1881 {
1882 toCreateViewer = Standard_True;
6a24c6de 1883 a3DViewer = new V3d_Viewer(aGraphicDriver);
f42753ed 1884 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
1885 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
1886 ViewerTest_DefaultBackground.GradientColor2,
1887 ViewerTest_DefaultBackground.FillMethod);
18d715bd 1888 }
1889
1890 // AIS context setup
1891 if (ViewerTest::GetAISContext().IsNull() ||
1892 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
1893 {
e79a94b9 1894 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
18d715bd 1895 ViewerTest::SetAISContext (aContext);
1896 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
1897 }
1898 else
e79a94b9 1899 {
18d715bd 1900 ViewerTest::ResetEventManager();
e79a94b9 1901 }
18d715bd 1902
1903 // Create window
e79a94b9 1904#if defined(_WIN32)
1905 VT_GetWindow() = new WNT_Window (aTitle.ToCString(),
1906 Handle(WNT_WClass)::DownCast (WClass()),
62e1beed 1907 Draw_VirtualWindows ? WS_POPUP : WS_OVERLAPPEDWINDOW,
e79a94b9 1908 aPxLeft, aPxTop,
1909 aPxWidth, aPxHeight,
1910 Quantity_NOC_BLACK);
4fe56619 1911#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e79a94b9 1912 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
1913 aPxLeft, aPxTop,
1914 aPxWidth, aPxHeight);
1915 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
7fd59977 1916#else
e79a94b9 1917 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
1918 aTitle.ToCString(),
1919 aPxLeft, aPxTop,
1920 aPxWidth, aPxHeight);
7fd59977 1921#endif
18d715bd 1922 VT_GetWindow()->SetVirtual (Draw_VirtualWindows);
7fd59977 1923
d09dda09 1924 // View setup
9e04ccdc 1925 Handle(V3d_View) aView;
1926 if (!theViewToClone.IsNull())
1927 {
2e93433e 1928 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
9e04ccdc 1929 }
1930 else
1931 {
2e93433e 1932 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
9e04ccdc 1933 }
1934
d09dda09 1935 aView->SetWindow (VT_GetWindow());
c3282ec1 1936 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
4269bd1b 1937
18d715bd 1938 ViewerTest::CurrentView(aView);
1939 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
7fd59977 1940
18d715bd 1941 // Setup for X11 or NT
1942 OSWindowSetup();
7fd59977 1943
18d715bd 1944 // Set parameters for V3d_View and V3d_Viewer
1945 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
1946 aV3dView->SetComputedMode(Standard_False);
7fd59977 1947
18d715bd 1948 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
1949 if (toCreateViewer)
1950 {
7fd59977 1951 a3DViewer->SetDefaultLights();
1952 a3DViewer->SetLightOn();
18d715bd 1953 }
7fd59977 1954
8693dfd0 1955#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
1956 if (isNewDriver)
1957 {
1958 ::Display* aDispX = GetDisplayConnection()->GetDisplay();
1959 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
1960 }
1961#endif
7fd59977 1962
7fd59977 1963 VT_GetWindow()->Map();
4269bd1b 1964
18d715bd 1965 // Set the handle of created view in the event manager
1966 ViewerTest::ResetEventManager();
1967
4fe56619 1968 ViewerTest::CurrentView()->Redraw();
18d715bd 1969
1970 aView.Nullify();
1971 a3DViewer.Nullify();
18d715bd 1972
1973 return aViewNames.GetViewName();
1974}
1975
4269bd1b 1976//==============================================================================
1977//function : RedrawAllViews
1978//purpose : Redraw all created views
1979//==============================================================================
1980void ViewerTest::RedrawAllViews()
1981{
1982 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
1983 for (; aViewIt.More(); aViewIt.Next())
1984 {
1985 const Handle(V3d_View)& aView = aViewIt.Key2();
1986 aView->Redraw();
1987 }
1988}
1989
7fd59977 1990//==============================================================================
1991//function : Vinit
1992//purpose : Create the window viewer and initialize all the global variable
e79a94b9 1993// Use Tk_CreateFileHandler on UNIX to catch the X11 Viewer event
7fd59977 1994//==============================================================================
1995
18d715bd 1996static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 1997{
e79a94b9 1998 TCollection_AsciiString aViewName, aDisplayName;
1999 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
9e04ccdc 2000 Handle(V3d_View) aCopyFrom;
e79a94b9 2001 TCollection_AsciiString aName, aValue;
2e93433e 2002 int is2dMode = -1;
e79a94b9 2003 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
18d715bd 2004 {
e79a94b9 2005 const TCollection_AsciiString anArg = theArgVec[anArgIt];
2006 TCollection_AsciiString anArgCase = anArg;
fd3f6bd0 2007 anArgCase.LowerCase();
2008 if (anArgIt + 1 < theArgsNb
2009 && anArgCase == "-name")
2010 {
2011 aViewName = theArgVec[++anArgIt];
2012 }
2013 else if (anArgIt + 1 < theArgsNb
2014 && (anArgCase == "-left"
2015 || anArgCase == "-l"))
2016 {
2017 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
2018 }
2019 else if (anArgIt + 1 < theArgsNb
2020 && (anArgCase == "-top"
2021 || anArgCase == "-t"))
2022 {
2023 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
2024 }
2025 else if (anArgIt + 1 < theArgsNb
2026 && (anArgCase == "-width"
2027 || anArgCase == "-w"))
2028 {
2029 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
2030 }
2031 else if (anArgIt + 1 < theArgsNb
2032 && (anArgCase == "-height"
2033 || anArgCase == "-h"))
18d715bd 2034 {
fd3f6bd0 2035 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
2036 }
2037 else if (anArgCase == "-exitonclose")
2038 {
2039 Draw_ToExitOnCloseView = true;
2040 if (anArgIt + 1 < theArgsNb
2041 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToExitOnCloseView))
2042 {
2043 ++anArgIt;
2044 }
2045 }
2046 else if (anArgCase == "-closeonescape"
2047 || anArgCase == "-closeonesc")
2048 {
2049 Draw_ToCloseViewOnEsc = true;
2050 if (anArgIt + 1 < theArgsNb
2051 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], Draw_ToCloseViewOnEsc))
2052 {
2053 ++anArgIt;
2054 }
2055 }
2e93433e 2056 else if (anArgCase == "-2d_mode"
2057 || anArgCase == "-2dmode"
2058 || anArgCase == "-2d")
2059 {
2060 bool toEnable = true;
2061 if (anArgIt + 1 < theArgsNb
2062 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
2063 {
2064 ++anArgIt;
2065 }
2066 is2dMode = toEnable ? 1 : 0;
2067 }
fd3f6bd0 2068 else if (anArgIt + 1 < theArgsNb
2069 && (anArgCase == "-disp"
2070 || anArgCase == "-display"))
2071 {
2072 aDisplayName = theArgVec[++anArgIt];
2073 }
9e04ccdc 2074 else if (!ViewerTest::CurrentView().IsNull()
2075 && aCopyFrom.IsNull()
2076 && (anArgCase == "-copy"
2077 || anArgCase == "-clone"
2078 || anArgCase == "-cloneactive"
2079 || anArgCase == "-cloneactiveview"))
2080 {
2081 aCopyFrom = ViewerTest::CurrentView();
2082 }
fd3f6bd0 2083 // old syntax
2084 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
2085 {
2086 aName.LowerCase();
2087 if (aName == "name")
18d715bd 2088 {
2089 aViewName = aValue;
2090 }
fd3f6bd0 2091 else if (aName == "l"
2092 || aName == "left")
e79a94b9 2093 {
18d715bd 2094 aPxLeft = aValue.IntegerValue();
e79a94b9 2095 }
fd3f6bd0 2096 else if (aName == "t"
2097 || aName == "top")
e79a94b9 2098 {
18d715bd 2099 aPxTop = aValue.IntegerValue();
e79a94b9 2100 }
fd3f6bd0 2101 else if (aName == "disp"
2102 || aName == "display")
e79a94b9 2103 {
18d715bd 2104 aDisplayName = aValue;
e79a94b9 2105 }
fd3f6bd0 2106 else if (aName == "w"
2107 || aName == "width")
e79a94b9 2108 {
18d715bd 2109 aPxWidth = aValue.IntegerValue();
e79a94b9 2110 }
fd3f6bd0 2111 else if (aName == "h"
2112 || aName == "height")
e79a94b9 2113 {
18d715bd 2114 aPxHeight = aValue.IntegerValue();
e79a94b9 2115 }
18d715bd 2116 else
2117 {
fd3f6bd0 2118 std::cout << "Syntax error: unknown argument " << anArg << ".\n";
2119 return 1;
18d715bd 2120 }
2121 }
e79a94b9 2122 else if (aViewName.IsEmpty())
2123 {
2124 aViewName = anArg;
2125 }
2126 else
2127 {
fd3f6bd0 2128 std::cout << "Syntax error: unknown argument " << anArg << ".\n";
2129 return 1;
e79a94b9 2130 }
18d715bd 2131 }
2132
fd3f6bd0 2133#if defined(_WIN32) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
2134 if (!aDisplayName.IsEmpty())
2135 {
2136 aDisplayName.Clear();
2137 std::cout << "Warning: display parameter will be ignored.\n";
2138 }
2139#endif
2140
18d715bd 2141 ViewerTest_Names aViewNames (aViewName);
e79a94b9 2142 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
18d715bd 2143 {
e79a94b9 2144 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
2145 theDi.Eval (aCommand.ToCString());
2e93433e 2146 if (is2dMode != -1)
2147 {
2148 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2149 }
18d715bd 2150 return 0;
2151 }
2152
2153 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
9e04ccdc 2154 aViewName, aDisplayName, aCopyFrom);
2e93433e 2155 if (is2dMode != -1)
2156 {
2157 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
2158 }
e79a94b9 2159 theDi << aViewId;
7fd59977 2160 return 0;
2161}
2162
1eeef710 2163//! Parse HLR algo type.
2164static Standard_Boolean parseHlrAlgoType (const char* theName,
2165 Prs3d_TypeOfHLR& theType)
2166{
2167 TCollection_AsciiString aName (theName);
2168 aName.LowerCase();
2169 if (aName == "polyalgo")
2170 {
2171 theType = Prs3d_TOH_PolyAlgo;
2172 }
2173 else if (aName == "algo")
2174 {
2175 theType = Prs3d_TOH_Algo;
2176 }
2177 else
2178 {
2179 return Standard_False;
2180 }
2181 return Standard_True;
2182}
2183
0a768f56 2184//==============================================================================
2185//function : VHLR
2186//purpose : hidden lines removal algorithm
2187//==============================================================================
2188
2189static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2190{
1eeef710 2191 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2192 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2193 if (aView.IsNull())
0a768f56 2194 {
1eeef710 2195 std::cerr << "Error: No opened viewer!\n";
0a768f56 2196 return 1;
2197 }
2198
1eeef710 2199 Standard_Boolean hasHlrOnArg = Standard_False;
2200 Standard_Boolean hasShowHiddenArg = Standard_False;
2201 Standard_Boolean isHLROn = Standard_False;
2202 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
2203 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2204 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2205 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2206 {
1eeef710 2207 TCollection_AsciiString anArg (argv[anArgIter]);
2208 anArg.LowerCase();
2209 if (anUpdateTool.parseRedrawMode (anArg))
2210 {
2211 continue;
2212 }
2213 else if (anArg == "-showhidden"
2214 && anArgIter + 1 < argc
2215 && ViewerTest::ParseOnOff (argv[anArgIter + 1], toShowHidden))
2216 {
2217 ++anArgIter;
2218 hasShowHiddenArg = Standard_True;
2219 continue;
2220 }
2221 else if ((anArg == "-type"
2222 || anArg == "-algo"
2223 || anArg == "-algotype")
2224 && anArgIter + 1 < argc
2225 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2226 {
2227 ++anArgIter;
2228 continue;
2229 }
2230 else if (!hasHlrOnArg
2231 && ViewerTest::ParseOnOff (argv[anArgIter], isHLROn))
2232 {
2233 hasHlrOnArg = Standard_True;
2234 continue;
2235 }
2236 // old syntax
2237 else if (!hasShowHiddenArg
2238 && ViewerTest::ParseOnOff(argv[anArgIter], toShowHidden))
2239 {
2240 hasShowHiddenArg = Standard_True;
2241 continue;
2242 }
2243 else
2244 {
2245 std::cout << "Syntax error at '" << argv[anArgIter] << "'\n";
2246 return 1;
2247 }
0a768f56 2248 }
1eeef710 2249 if (!hasHlrOnArg)
0a768f56 2250 {
1eeef710 2251 di << "HLR: " << aView->ComputedMode() << "\n";
2252 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
2253 di << "HlrAlgo: ";
2254 switch (aCtx->DefaultDrawer()->TypeOfHLR())
2255 {
2256 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
2257 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
2258 case Prs3d_TOH_Algo: di << "Algo\n"; break;
2259 }
2260 anUpdateTool.Invalidate();
2261 return 0;
0a768f56 2262 }
2263
1eeef710 2264 Standard_Boolean toRecompute = Standard_False;
2265 if (aTypeOfHLR != Prs3d_TOH_NotSet
2266 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
e9224045 2267 {
1eeef710 2268 toRecompute = Standard_True;
2269 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
2270 }
2271 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
2272 {
2273 toRecompute = Standard_True;
2274 if (toShowHidden)
e9224045 2275 {
1eeef710 2276 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
e9224045 2277 }
2278 else
2279 {
1eeef710 2280 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
e9224045 2281 }
1eeef710 2282 }
e9224045 2283
1eeef710 2284 // redisplay shapes
2285 if (aView->ComputedMode() && isHLROn && toRecompute)
2286 {
2287 AIS_ListOfInteractive aListOfShapes;
2288 aCtx->DisplayedObjects (aListOfShapes);
2289 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
e9224045 2290 {
1eeef710 2291 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
e9224045 2292 {
1eeef710 2293 aCtx->Redisplay (aShape, Standard_False);
e9224045 2294 }
2295 }
2296 }
0a768f56 2297
1eeef710 2298 aView->SetComputedMode (isHLROn);
0a768f56 2299 return 0;
2300}
2301
2302//==============================================================================
2303//function : VHLRType
2304//purpose : change type of using HLR algorithm
2305//==============================================================================
2306
1eeef710 2307static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
0a768f56 2308{
1eeef710 2309 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2310 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2311 if (aView.IsNull())
0a768f56 2312 {
1eeef710 2313 std::cerr << "Error: No opened viewer!\n";
0a768f56 2314 return 1;
2315 }
2316
1eeef710 2317 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
2318 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2319 AIS_ListOfInteractive aListOfShapes;
2320 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
0a768f56 2321 {
1eeef710 2322 TCollection_AsciiString anArg (argv[anArgIter]);
2323 anArg.LowerCase();
2324 if (anUpdateTool.parseRedrawMode (anArg))
0a768f56 2325 {
1eeef710 2326 continue;
0a768f56 2327 }
1eeef710 2328 else if ((anArg == "-type"
2329 || anArg == "-algo"
2330 || anArg == "-algotype")
2331 && anArgIter + 1 < argc
2332 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
2333 {
2334 ++anArgIter;
2335 continue;
2336 }
2337 // old syntax
2338 else if (aTypeOfHLR == Prs3d_TOH_NotSet
2339 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
2340 {
2341 continue;
2342 }
2343 else
0a768f56 2344 {
2345 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1eeef710 2346 TCollection_AsciiString aName (argv[anArgIter]);
0a768f56 2347 if (!aMap.IsBound2 (aName))
2348 {
1eeef710 2349 std::cout << "Syntax error: Wrong shape name '" << aName << "'.\n";
2350 return 1;
0a768f56 2351 }
1eeef710 2352
2353 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
2354 if (aShape.IsNull())
2355 {
2356 std::cout << "Syntax error: '" << aName << "' is not a shape presentation.\n";
2357 return 1;
2358 }
2359 aListOfShapes.Append (aShape);
2360 continue;
0a768f56 2361 }
1eeef710 2362 }
2363 if (aTypeOfHLR == Prs3d_TOH_NotSet)
2364 {
2365 std::cout << "Syntax error: wrong number of arguments!\n";
2366 return 1;
2367 }
2368
2369 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
2370 if (isGlobal)
2371 {
2372 aCtx->DisplayedObjects (aListOfShapes);
2373 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
0a768f56 2374 }
2375
1eeef710 2376 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
2377 {
2378 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2379 if (aShape.IsNull())
2380 {
2381 continue;
2382 }
2383
2384 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
2385 && aView->ComputedMode();
2386 if (!isGlobal
2387 || aShape->TypeOfHLR() != aTypeOfHLR)
2388 {
2389 aShape->SetTypeOfHLR (aTypeOfHLR);
2390 }
2391 if (toUpdateShape)
2392 {
2393 aCtx->Redisplay (aShape, Standard_False);
2394 }
2395 }
0a768f56 2396 return 0;
2397}
2398
18d715bd 2399//==============================================================================
2400//function : FindViewIdByWindowHandle
2401//purpose : Find theView Id in the map of views by window handle
2402//==============================================================================
2403#if defined(_WIN32) || defined(__WIN32__) || (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2404TCollection_AsciiString FindViewIdByWindowHandle(const Aspect_Handle theWindowHandle)
2405{
2406 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
2407 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
2408 {
2409 Aspect_Handle aWindowHandle = GetWindowHandle(anIter.Value()->Window());
2410 if (aWindowHandle == theWindowHandle)
2411 return anIter.Key1();
2412 }
2413 return TCollection_AsciiString("");
2414}
2415#endif
2416
e084dbbc 2417//! Make the view active
2418void ActivateView (const TCollection_AsciiString& theViewName,
2419 Standard_Boolean theToUpdate = Standard_True)
18d715bd 2420{
2421 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
e084dbbc 2422 if (aView.IsNull())
18d715bd 2423 {
e084dbbc 2424 return;
2425 }
18d715bd 2426
e084dbbc 2427 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
2428 if (!anAISContext.IsNull())
2429 {
2430 if (!ViewerTest::CurrentView().IsNull())
2431 {
2432 TCollection_AsciiString aTitle("3D View - ");
2433 aTitle = aTitle + ViewerTest_myViews.Find2 (ViewerTest::CurrentView());
18d715bd 2434 SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
e084dbbc 2435 }
2436
2437 ViewerTest::CurrentView (aView);
2438 ViewerTest::SetAISContext (anAISContext);
2439 TCollection_AsciiString aTitle = TCollection_AsciiString("3D View - ") + theViewName + "(*)";
2440 SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
1eeef710 2441#if defined(_WIN32)
e084dbbc 2442 VT_GetWindow() = Handle(WNT_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2443#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
e084dbbc 2444 VT_GetWindow() = Handle(Cocoa_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2445#else
e084dbbc 2446 VT_GetWindow() = Handle(Xw_Window)::DownCast(ViewerTest::CurrentView()->Window());
18d715bd 2447#endif
e084dbbc 2448 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
2449 if (theToUpdate)
2450 {
18d715bd 2451 ViewerTest::CurrentView()->Redraw();
2452 }
2453 }
2454}
2455
0e93d9e5 2456//==============================================================================
2457//function : RemoveView
2458//purpose :
2459//==============================================================================
2460void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
2461 const Standard_Boolean theToRemoveContext)
2462{
2463 if (!ViewerTest_myViews.IsBound2 (theView))
2464 {
2465 return;
2466 }
2467
2468 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
2469 RemoveView (aViewName, theToRemoveContext);
2470}
2471
18d715bd 2472//==============================================================================
2473//function : RemoveView
2474//purpose : Close and remove view from display, clear maps if neccessary
2475//==============================================================================
2476void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
2477{
2478 if (!ViewerTest_myViews.IsBound1(theViewName))
2479 {
2480 cout << "Wrong view name\n";
2481 return;
2482 }
2483
2484 // Activate another view if it's active now
2485 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
2486 {
2487 if (ViewerTest_myViews.Extent() > 1)
2488 {
2489 TCollection_AsciiString aNewViewName;
c48e2889 2490 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2491 anIter.More(); anIter.Next())
2492 {
18d715bd 2493 if (anIter.Key1() != theViewName)
2494 {
2495 aNewViewName = anIter.Key1();
2496 break;
2497 }
c48e2889 2498 }
2499 ActivateView (aNewViewName);
18d715bd 2500 }
2501 else
2502 {
e084dbbc 2503 VT_GetWindow().Nullify();
2504 ViewerTest::CurrentView (Handle(V3d_View)());
18d715bd 2505 if (isContextRemoved)
2506 {
2507 Handle(AIS_InteractiveContext) anEmptyContext;
2508 ViewerTest::SetAISContext(anEmptyContext);
2509 }
2510 }
2511 }
2512
2513 // Delete view
2514 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
2515 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
8693dfd0 2516 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2517 aRedrawer.Stop (aView->Window());
18d715bd 2518
2519 // Remove view resources
18d715bd 2520 ViewerTest_myViews.UnBind1(theViewName);
851dacdb 2521 aView->Window()->Unmap();
18d715bd 2522 aView->Remove();
2523
2524#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
2525 XFlush (GetDisplayConnection()->GetDisplay());
2526#endif
2527
2528 // Keep context opened only if the closed view is last to avoid
2529 // unused empty contexts
2530 if (!aCurrentContext.IsNull())
2531 {
2532 // Check if there are more difined views in the viewer
2533 aCurrentContext->CurrentViewer()->InitDefinedViews();
2534 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1) && !aCurrentContext->CurrentViewer()->MoreDefinedViews())
2535 {
2536 // Remove driver if there is no viewers that use it
2537 Standard_Boolean isRemoveDriver = Standard_True;
2538 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2539 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
2540 {
2541 if (aCurrentContext != anIter.Key2() &&
2542 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
2543 {
2544 isRemoveDriver = Standard_False;
2545 break;
2546 }
2547 }
2ec85268 2548
2549 aCurrentContext->RemoveAll (Standard_False);
18d715bd 2550 if(isRemoveDriver)
2551 {
2552 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
2553 #if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
8693dfd0 2554 Tcl_DeleteFileHandler (XConnectionNumber (aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplay()));
18d715bd 2555 #endif
2556 }
2557
2558 ViewerTest_myContexts.UnBind2(aCurrentContext);
2559 }
2560 }
2561 cout << "3D View - " << theViewName << " was deleted.\n";
fd3f6bd0 2562 if (Draw_ToExitOnCloseView)
2563 {
2564 Draw_Interprete ("exit");
2565 }
18d715bd 2566}
2567
2568//==============================================================================
2569//function : VClose
2570//purpose : Remove the view defined by its name
2571//==============================================================================
2572
d0cc1cb7 2573static int VClose (Draw_Interpretor& /*theDi*/,
2574 Standard_Integer theArgsNb,
2575 const char** theArgVec)
18d715bd 2576{
18d715bd 2577 NCollection_List<TCollection_AsciiString> aViewList;
d0cc1cb7 2578 if (theArgsNb > 1)
18d715bd 2579 {
d0cc1cb7 2580 TCollection_AsciiString anArg (theArgVec[1]);
2581 anArg.UpperCase();
2582 if (anArg.IsEqual ("ALL")
2583 || anArg.IsEqual ("*"))
2584 {
2585 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
2586 anIter.More(); anIter.Next())
2587 {
2588 aViewList.Append (anIter.Key1());
2589 }
2590 if (aViewList.IsEmpty())
2591 {
2592 std::cout << "No view to close\n";
2593 return 0;
2594 }
2595 }
2596 else
18d715bd 2597 {
d0cc1cb7 2598 ViewerTest_Names aViewName (theArgVec[1]);
2599 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
2600 {
2601 std::cerr << "The view with name '" << theArgVec[1] << "' does not exist\n";
2602 return 1;
2603 }
2604 aViewList.Append (aViewName.GetViewName());
18d715bd 2605 }
2606 }
2607 else
2608 {
d0cc1cb7 2609 // close active view
2610 if (ViewerTest::CurrentView().IsNull())
2611 {
2612 std::cerr << "No active view!\n";
2613 return 1;
2614 }
2615 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
18d715bd 2616 }
2617
d0cc1cb7 2618 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
18d715bd 2619 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
2620 anIter.More(); anIter.Next())
2621 {
d0cc1cb7 2622 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
18d715bd 2623 }
2624
2625 return 0;
2626}
2627
2628//==============================================================================
2629//function : VActivate
2630//purpose : Activate the view defined by its ID
2631//==============================================================================
2632
2633static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2634{
e084dbbc 2635 if (theArgsNb == 1)
18d715bd 2636 {
2637 theDi.Eval("vviewlist");
2638 return 0;
2639 }
2640
e084dbbc 2641 TCollection_AsciiString aNameString;
2642 Standard_Boolean toUpdate = Standard_True;
2643 Standard_Boolean toActivate = Standard_True;
2644 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
18d715bd 2645 {
e084dbbc 2646 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2647 anArg.LowerCase();
2648 if (toUpdate
2649 && anArg == "-noupdate")
2650 {
2651 toUpdate = Standard_False;
2652 }
2653 else if (toActivate
2654 && aNameString.IsEmpty()
2655 && anArg == "none")
2656 {
2657 TCollection_AsciiString aTitle("3D View - ");
2658 aTitle = aTitle + ViewerTest_myViews.Find2(ViewerTest::CurrentView());
2659 SetWindowTitle (ViewerTest::CurrentView()->Window(), aTitle.ToCString());
2660 VT_GetWindow().Nullify();
2661 ViewerTest::CurrentView (Handle(V3d_View)());
2662 ViewerTest::ResetEventManager();
2663 theDi << theArgVec[0] << ": all views are inactive\n";
2664 toActivate = Standard_False;
2665 }
2666 else if (toActivate
2667 && aNameString.IsEmpty())
2668 {
2669 aNameString = theArgVec[anArgIter];
2670 }
2671 else
2672 {
2673 std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
2674 return 1;
2675 }
18d715bd 2676 }
2677
e084dbbc 2678 if (!toActivate)
2679 {
2680 return 0;
2681 }
2682 else if (aNameString.IsEmpty())
2683 {
2684 std::cout << "Syntax error: wrong number of arguments\n";
2685 return 1;
2686 }
18d715bd 2687
2688 // Check if this view exists in the viewer with the driver
e084dbbc 2689 ViewerTest_Names aViewNames (aNameString);
18d715bd 2690 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
2691 {
e084dbbc 2692 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
18d715bd 2693 return 1;
2694 }
2695
2696 // Check if it is active already
2697 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
2698 {
2699 theDi << theArgVec[0] << ": the view is active already\n";
2700 return 0;
2701 }
2702
e084dbbc 2703 ActivateView (aViewNames.GetViewName(), toUpdate);
18d715bd 2704 return 0;
2705}
2706
2707//==============================================================================
2708//function : VViewList
2709//purpose : Print current list of views per viewer and graphic driver ID
2710// shared between viewers
2711//==============================================================================
2712
2713static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
2714{
2715 if (theArgsNb > 2)
2716 {
2717 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
29cb310a 2718 << "Usage: " << theArgVec[0] << " name";
18d715bd 2719 return 1;
2720 }
2721 if (ViewerTest_myContexts.Size() < 1)
2722 return 0;
2723
18d715bd 2724 Standard_Boolean isTreeView =
29cb310a 2725 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
18d715bd 2726
2727 if (isTreeView)
c48e2889 2728 {
18d715bd 2729 theDi << theArgVec[0] <<":\n";
c48e2889 2730 }
18d715bd 2731
c48e2889 2732 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
2733 aDriverIter.More(); aDriverIter.Next())
2734 {
2735 if (isTreeView)
2736 theDi << aDriverIter.Key1() << ":\n";
18d715bd 2737
c48e2889 2738 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
2739 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
2740 {
2741 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
18d715bd 2742 {
c48e2889 2743 if (isTreeView)
18d715bd 2744 {
c48e2889 2745 TCollection_AsciiString aContextName(aContextIter.Key1());
2746 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
2747 }
18d715bd 2748
c48e2889 2749 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
2750 aViewIter.More(); aViewIter.Next())
2751 {
2752 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
18d715bd 2753 {
c48e2889 2754 TCollection_AsciiString aViewName(aViewIter.Key1());
2755 if (isTreeView)
18d715bd 2756 {
c48e2889 2757 if (aViewIter.Value() == ViewerTest::CurrentView())
2758 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
18d715bd 2759 else
c48e2889 2760 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
2761 }
2762 else
2763 {
2764 theDi << aViewName << " ";
18d715bd 2765 }
2766 }
2767 }
2768 }
2769 }
c48e2889 2770 }
18d715bd 2771 return 0;
2772}
2773
7fd59977 2774//==============================================================================
4fe56619 2775//function : VT_ProcessKeyPress
7fd59977 2776//purpose : Handle KeyPress event from a CString
2777//==============================================================================
4fe56619 2778void VT_ProcessKeyPress (const char* buf_ret)
7fd59977 2779{
2780 //cout << "KeyPress" << endl;
2781 const Handle(V3d_View) aView = ViewerTest::CurrentView();
7fd59977 2782 // Letter in alphabetic order
2783
2e93433e 2784 if (!strcasecmp (buf_ret, "A")
2785 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2786 {
7fd59977 2787 // AXO
2788 aView->SetProj(V3d_XposYnegZpos);
2789 }
2e93433e 2790 else if (!strcasecmp (buf_ret, "D")
2791 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2792 {
7fd59977 2793 // Reset
2794 aView->Reset();
2795 }
b514beda 2796 else if (!strcasecmp (buf_ret, "F"))
2797 {
b586500b 2798 if (ViewerTest::GetAISContext()->NbSelected() > 0)
2799 {
2800 ViewerTest::GetAISContext()->FitSelected (aView);
2801 }
2802 else
2803 {
2804 // FitAll
2805 aView->FitAll();
2806 }
7fd59977 2807 }
b514beda 2808 else if (!strcasecmp (buf_ret, "H"))
2809 {
7fd59977 2810 // HLR
1eeef710 2811 std::cout << "HLR" << std::endl;
de75ed09 2812 aView->SetComputedMode (!aView->ComputedMode());
1eeef710 2813 aView->Redraw();
7fd59977 2814 }
b514beda 2815 else if (!strcasecmp (buf_ret, "P"))
2816 {
0a768f56 2817 // Type of HLR
2818 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2819 if (aContext->DefaultDrawer()->TypeOfHLR() == Prs3d_TOH_Algo)
2820 aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_PolyAlgo);
2821 else
2822 aContext->DefaultDrawer()->SetTypeOfHLR(Prs3d_TOH_Algo);
c3282ec1 2823 if (aContext->NbSelected()==0)
0a768f56 2824 {
2825 AIS_ListOfInteractive aListOfShapes;
2826 aContext->DisplayedObjects(aListOfShapes);
2827 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes);
2828 anIter.More(); anIter.Next())
2829 {
2830 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
2831 if (aShape.IsNull())
2832 continue;
2833 if (aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
2834 aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
2835 else
2836 aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
36132a2e 2837 aContext->Redisplay (aShape, Standard_False);
0a768f56 2838 }
2839 }
2840 else
2841 {
c3282ec1 2842 for (aContext->InitSelected();aContext->MoreSelected();aContext->NextSelected())
0a768f56 2843 {
c3282ec1 2844 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aContext->SelectedInteractive());
0a768f56 2845 if (aShape.IsNull())
2846 continue;
2847 if(aShape->TypeOfHLR() == Prs3d_TOH_PolyAlgo)
2848 aShape->SetTypeOfHLR (Prs3d_TOH_Algo);
2849 else
2850 aShape->SetTypeOfHLR (Prs3d_TOH_PolyAlgo);
36132a2e 2851 aContext->Redisplay (aShape, Standard_False);
0a768f56 2852 }
2853 }
2854
2855 aContext->UpdateCurrentViewer();
4269bd1b 2856
0a768f56 2857 }
b514beda 2858 else if (!strcasecmp (buf_ret, "S"))
2859 {
2860 std::cout << "setup Shaded display mode" << std::endl;
4fe56619 2861
7fd59977 2862 Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
c3282ec1 2863 if(Ctx->NbSelected()==0)
0577ae8c 2864 Ctx->SetDisplayMode (AIS_Shaded, Standard_True);
7fd59977 2865 else{
c3282ec1 2866 for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
2867 Ctx->SetDisplayMode(Ctx->SelectedInteractive(),1,Standard_False);
7fd59977 2868 Ctx->UpdateCurrentViewer();
2869 }
2870 }
b514beda 2871 else if (!strcasecmp (buf_ret, "U"))
2872 {
41811896 2873 // Unset display mode
b514beda 2874 std::cout << "reset display mode to defaults" << std::endl;
4fe56619 2875
7fd59977 2876 Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
c3282ec1 2877 if(Ctx->NbSelected()==0)
0577ae8c 2878 Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
7fd59977 2879 else{
c3282ec1 2880 for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
2881 Ctx->UnsetDisplayMode(Ctx->SelectedInteractive(),Standard_False);
7fd59977 2882 Ctx->UpdateCurrentViewer();
2883 }
2884
2885 }
2e93433e 2886 else if (!strcasecmp (buf_ret, "T")
2887 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2888 {
7fd59977 2889 // Top
2890 aView->SetProj(V3d_Zpos);
2891 }
2e93433e 2892 else if (!strcasecmp (buf_ret, "B")
2893 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2894 {
41811896 2895 // Bottom
7fd59977 2896 aView->SetProj(V3d_Zneg);
2897 }
2e93433e 2898 else if (!strcasecmp (buf_ret, "L")
2899 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2900 {
41811896 2901 // Left
7fd59977 2902 aView->SetProj(V3d_Xneg);
2903 }
2e93433e 2904 else if (!strcasecmp (buf_ret, "R")
2905 && !ViewerTest_V3dView::IsCurrentViewIn2DMode())
b514beda 2906 {
41811896 2907 // Right
7fd59977 2908 aView->SetProj(V3d_Xpos);
2909 }
b514beda 2910 else if (!strcasecmp (buf_ret, "W"))
2911 {
2912 std::cout << "setup WireFrame display mode" << std::endl;
7fd59977 2913 Handle(AIS_InteractiveContext) Ctx = ViewerTest::GetAISContext();
c3282ec1 2914 if(Ctx->NbSelected()==0)
0577ae8c 2915 Ctx->SetDisplayMode (AIS_WireFrame, Standard_True);
7fd59977 2916 else{
c3282ec1 2917 for(Ctx->InitSelected();Ctx->MoreSelected();Ctx->NextSelected())
2918 Ctx->SetDisplayMode(Ctx->SelectedInteractive(),0,Standard_False);
7fd59977 2919 Ctx->UpdateCurrentViewer();
2920 }
2921 }
b514beda 2922 else if (!strcasecmp (buf_ret, ","))
2923 {
7fd59977 2924 ViewerTest::GetAISContext()->HilightNextDetected(ViewerTest::CurrentView());
7fd59977 2925 }
b514beda 2926 else if (!strcasecmp (buf_ret, "."))
2927 {
7fd59977 2928 ViewerTest::GetAISContext()->HilightPreviousDetected(ViewerTest::CurrentView());
2929 }
f978241f 2930 else if (!strcasecmp (buf_ret, "/"))
2931 {
2932 Handle(Graphic3d_Camera) aCamera = aView->Camera();
2933 if (aCamera->IsStereo())
2934 {
2935 aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() - 0.01);
2936 aView->Redraw();
2937 }
2938 }
2939 else if (!strcasecmp (buf_ret, "*"))
2940 {
2941 Handle(Graphic3d_Camera) aCamera = aView->Camera();
2942 if (aCamera->IsStereo())
2943 {
2944 aCamera->SetIOD (aCamera->GetIODType(), aCamera->IOD() + 0.01);
2945 aView->Redraw();
2946 }
2947 }
b514beda 2948 else if (*buf_ret == THE_KEY_DELETE)
2949 {
2950 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2951 if (!aCtx.IsNull()
b514beda 2952 && aCtx->NbSelected() > 0)
2953 {
2954 Draw_Interprete ("verase");
2955 }
2956 }
fd3f6bd0 2957 else if (*buf_ret == THE_KEY_ESCAPE)
2958 {
2959 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
2960 if (!aCtx.IsNull()
2961 && Draw_ToCloseViewOnEsc)
2962 {
2963 Draw_Interprete (Draw_ToExitOnCloseView ? "exit" : "vclose");
2964 }
2965 }
b514beda 2966 else
2967 {
2968 // Number
8c088c52 2969 const Standard_Integer aSelMode = Draw::Atoi(buf_ret);
2970 if (aSelMode >= 0 && aSelMode <= 7)
2971 {
2972 bool toEnable = true;
2973 if (const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext())
2974 {
2975 AIS_ListOfInteractive aPrsList;
2976 aCtx->DisplayedObjects (aPrsList);
2977 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next())
2978 {
2979 TColStd_ListOfInteger aModes;
2980 aCtx->ActivatedModes (aPrsIter.Value(), aModes);
2981 for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next())
2982 {
2983 if (aModeIter.Value() == aSelMode)
2984 {
2985 toEnable = false;
2986 }
2987 }
2988 }
2989 }
2990 TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0");
2991 Draw_Interprete (aCmd.ToCString());
2992 }
7fd59977 2993 }
2994}
2995
2996//==============================================================================
4fe56619 2997//function : VT_ProcessExpose
7fd59977 2998//purpose : Redraw the View on an Expose Event
2999//==============================================================================
4fe56619 3000void VT_ProcessExpose()
3001{
3002 Handle(V3d_View) aView3d = ViewerTest::CurrentView();
3003 if (!aView3d.IsNull())
3004 {
3005 aView3d->Redraw();
3006 }
7fd59977 3007}
3008
3009//==============================================================================
4fe56619 3010//function : VT_ProcessConfigure
7fd59977 3011//purpose : Resize the View on an Configure Event
3012//==============================================================================
4fe56619 3013void VT_ProcessConfigure()
7fd59977 3014{
4fe56619 3015 Handle(V3d_View) aView3d = ViewerTest::CurrentView();
3016 if (aView3d.IsNull())
3017 {
3018 return;
3019 }
3020
3021 aView3d->MustBeResized();
3022 aView3d->Update();
3023 aView3d->Redraw();
7fd59977 3024}
3025
3026//==============================================================================
4fe56619 3027//function : VT_ProcessButton1Press
7fd59977 3028//purpose : Picking
3029//==============================================================================
e79a94b9 3030Standard_Boolean VT_ProcessButton1Press (Standard_Integer ,
3031 const char** theArgVec,
3032 Standard_Boolean theToPick,
3033 Standard_Boolean theIsShift)
7fd59977 3034{
1beb58d7 3035 if (TheIsAnimating)
3036 {
3037 TheIsAnimating = Standard_False;
3038 return Standard_False;
3039 }
3040
e79a94b9 3041 if (theToPick)
3042 {
7fd59977 3043 Standard_Real X, Y, Z;
e79a94b9 3044 ViewerTest::CurrentView()->Convert (X_Motion, Y_Motion, X, Y, Z);
7fd59977 3045
e79a94b9 3046 Draw::Set (theArgVec[1], X);
3047 Draw::Set (theArgVec[2], Y);
3048 Draw::Set (theArgVec[3], Z);
3049 }
7fd59977 3050
e79a94b9 3051 if (theIsShift)
3052 {
3053 ViewerTest::CurrentEventManager()->ShiftSelect();
3054 }
7fd59977 3055 else
e79a94b9 3056 {
3057 ViewerTest::CurrentEventManager()->Select();
3058 }
7fd59977 3059
e79a94b9 3060 return Standard_False;
7fd59977 3061}
3062
3063//==============================================================================
4fe56619 3064//function : VT_ProcessButton1Release
3065//purpose : End selecting
7fd59977 3066//==============================================================================
4fe56619 3067void VT_ProcessButton1Release (Standard_Boolean theIsShift)
3068{
3069 if (IsDragged)
3070 {
3071 IsDragged = Standard_False;
3072 Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
3073 if (theIsShift)
3074 {
2157d6ac 3075 EM->ShiftSelect (X_ButtonPress, Y_ButtonPress,
3076 X_Motion, Y_Motion);
4fe56619 3077 }
3078 else
3079 {
2157d6ac 3080 EM->Select (X_ButtonPress, Y_ButtonPress,
3081 X_Motion, Y_Motion);
4fe56619 3082 }
3083 }
3084}
7fd59977 3085
4fe56619 3086//==============================================================================
3087//function : VT_ProcessButton3Press
3088//purpose : Start Rotation
3089//==============================================================================
3090void VT_ProcessButton3Press()
3091{
2e93433e 3092 if (ViewerTest_V3dView::IsCurrentViewIn2DMode())
3093 {
3094 return;
3095 }
3096
7fd59977 3097 Start_Rot = 1;
1eeef710 3098 HasHlrOnBeforeRotation = ViewerTest::CurrentView()->ComputedMode();
3099 if (HasHlrOnBeforeRotation)
de75ed09 3100 {
3101 ViewerTest::CurrentView()->SetComputedMode (Standard_False);
3102 }
7fd59977 3103 ViewerTest::CurrentView()->StartRotation( X_ButtonPress, Y_ButtonPress );
7fd59977 3104}
4fe56619 3105
7fd59977 3106//==============================================================================
4fe56619 3107//function : VT_ProcessButton3Release
3108//purpose : End rotation
7fd59977 3109//==============================================================================
4fe56619 3110void VT_ProcessButton3Release()
3111{
3112 if (Start_Rot)
3113 {
7fd59977 3114 Start_Rot = 0;
1eeef710 3115 if (HasHlrOnBeforeRotation)
de75ed09 3116 {
1eeef710 3117 HasHlrOnBeforeRotation = Standard_False;
de75ed09 3118 ViewerTest::CurrentView()->SetComputedMode (Standard_True);
1eeef710 3119 ViewerTest::CurrentView()->Redraw();
de75ed09 3120 }
7fd59977 3121 }
7fd59977 3122}
3123
7fd59977 3124//==============================================================================
3125//function : ProcessControlButton1Motion
3126//purpose : Zoom
3127//==============================================================================
3128
900f7229 3129#if defined(_WIN32) || ! defined(__APPLE__) || defined(MACOSX_USE_GLX)
7fd59977 3130static void ProcessControlButton1Motion()
3131{
3132 ViewerTest::CurrentView()->Zoom( X_ButtonPress, Y_ButtonPress, X_Motion, Y_Motion);
3133
3134 X_ButtonPress = X_Motion;
3135 Y_ButtonPress = Y_Motion;
3136}
900f7229 3137#endif
7fd59977 3138
3139//==============================================================================
4fe56619 3140//function : VT_ProcessControlButton2Motion
3141//purpose : Panning
7fd59977 3142//==============================================================================
4fe56619 3143void VT_ProcessControlButton2Motion()
7fd59977 3144{
197ac94e 3145 Standard_Integer aDx = X_Motion - X_ButtonPress;
3146 Standard_Integer aDy = Y_Motion - Y_ButtonPress;
7fd59977 3147
197ac94e 3148 aDy = -aDy; // Xwindow Y axis is from top to Bottom
7fd59977 3149
197ac94e 3150 ViewerTest::CurrentView()->Pan (aDx, aDy);
7fd59977 3151
3152 X_ButtonPress = X_Motion;
3153 Y_ButtonPress = Y_Motion;
3154}
3155
3156//==============================================================================
4fe56619 3157//function : VT_ProcessControlButton3Motion
7fd59977 3158//purpose : Rotation
3159//==============================================================================
4fe56619 3160void VT_ProcessControlButton3Motion()
7fd59977 3161{
4fe56619 3162 if (Start_Rot)
3163 {
3164 ViewerTest::CurrentView()->Rotation (X_Motion, Y_Motion);
3165 }
7fd59977 3166}
3167
3168//==============================================================================
4fe56619 3169//function : VT_ProcessMotion
3170//purpose :
7fd59977 3171//==============================================================================
4fe56619 3172void VT_ProcessMotion()
7fd59977 3173{
3174 //pre-hilights detected objects at mouse position
3175
3176 Handle(ViewerTest_EventManager) EM = ViewerTest::CurrentEventManager();
3177 EM->MoveTo(X_Motion, Y_Motion);
3178}
3179
3180
3181void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
3182{
3183 Xpix = X_Motion;Ypix=Y_Motion;
3184}
3185
44b8f2d6 3186//==============================================================================
3187//function : ViewProject: implements VAxo, VTop, VLeft, ...
3188//purpose : Switches to an axonometric, top, left and other views
3189//==============================================================================
3190
3191static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
3192{
4fe56619 3193 if ( ViewerTest::CurrentView().IsNull() )
44b8f2d6 3194 {
586db386 3195 di<<"Call vinit before this command, please\n";
44b8f2d6 3196 return 1;
3197 }
3198
3199 ViewerTest::CurrentView()->SetProj(ori);
3200 return 0;
3201}
3202
7fd59977 3203//==============================================================================
3204//function : VAxo
3205//purpose : Switch to an Axonometric view
3206//Draw arg : No args
3207//==============================================================================
3208
3209static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
44b8f2d6 3210{
3211 return ViewProject(di, V3d_XposYnegZpos);
7fd59977 3212}
3213
3214//==============================================================================
3215//function : VTop
3216//purpose : Switch to a Top View
3217//Draw arg : No args
3218//==============================================================================
3219
3220static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
3221{
44b8f2d6 3222 return ViewProject(di, V3d_Zpos);
3223}
7fd59977 3224
44b8f2d6 3225//==============================================================================
3226//function : VBottom
3227//purpose : Switch to a Bottom View
3228//Draw arg : No args
3229//==============================================================================
7fd59977 3230
44b8f2d6 3231static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
3232{
3233 return ViewProject(di, V3d_Zneg);
3234}
7fd59977 3235
44b8f2d6 3236//==============================================================================
3237//function : VLeft
3238//purpose : Switch to a Left View
3239//Draw arg : No args
3240//==============================================================================
3241
3242static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
3243{
27af3052 3244 return ViewProject(di, V3d_Xneg);
44b8f2d6 3245}
3246
3247//==============================================================================
3248//function : VRight
3249//purpose : Switch to a Right View
3250//Draw arg : No args
3251//==============================================================================
3252
3253static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
3254{
27af3052 3255 return ViewProject(di, V3d_Xpos);
44b8f2d6 3256}
7fd59977 3257
44b8f2d6 3258//==============================================================================
3259//function : VFront
3260//purpose : Switch to a Front View
3261//Draw arg : No args
3262//==============================================================================
3263
3264static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
3265{
27af3052 3266 return ViewProject(di, V3d_Yneg);
44b8f2d6 3267}
3268
3269//==============================================================================
3270//function : VBack
3271//purpose : Switch to a Back View
3272//Draw arg : No args
3273//==============================================================================
3274
3275static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
3276{
27af3052 3277 return ViewProject(di, V3d_Ypos);
7fd59977 3278}
3279
3280//==============================================================================
3281//function : VHelp
3282//purpose : Dsiplay help on viewer Keyboead and mouse commands
3283//Draw arg : No args
3284//==============================================================================
3285
3286static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
3287{
3288
586db386 3289 di << "Q : Quit the application\n";
3290
3291 di << "=========================\n";
3292 di << "F : FitAll\n";
3293 di << "T : TopView\n";
3294 di << "B : BottomView\n";
3295 di << "R : RightView\n";
3296 di << "L : LeftView\n";
3297 di << "A : AxonometricView\n";
3298 di << "D : ResetView\n";
3299
3300 di << "=========================\n";
3301 di << "S : Shading\n";
3302 di << "W : Wireframe\n";
3303 di << "H : HidelLineRemoval\n";
3304 di << "U : Unset display mode\n";
3305 di << "Delete : Remove selection from viewer\n";
3306
3307 di << "=========================\n";
3308 di << "Selection mode \n";
3309 di << "0 : Shape\n";
3310 di << "1 : Vertex\n";
3311 di << "2 : Edge\n";
3312 di << "3 : Wire\n";
3313 di << "4 : Face\n";
3314 di << "5 : Shell\n";
3315 di << "6 : Solid\n";
3316 di << "7 : Compound\n";
3317
3318 di << "=========================\n";
3319 di << "Z : Switch Z clipping On/Off\n";
3320 di << ", : Hilight next detected\n";
3321 di << ". : Hilight previous detected\n";
7fd59977 3322
3323 return 0;
3324}
3325
57c28b61 3326#ifdef _WIN32
7fd59977 3327
3328static Standard_Boolean Ppick = 0;
3329static Standard_Integer Pargc = 0;
3330static const char** Pargv = NULL;
3331
3332
3333static LRESULT WINAPI AdvViewerWindowProc( HWND hwnd,
3334 UINT Msg,
3335 WPARAM wParam,
3336 LPARAM lParam )
3337{
18d715bd 3338 if (!ViewerTest_myViews.IsEmpty()) {
7fd59977 3339
3340 WPARAM fwKeys = wParam;
3341
3342 switch( Msg ) {
18d715bd 3343 case WM_CLOSE:
3344 {
3345 // Delete view from map of views
3346 ViewerTest::RemoveView(FindViewIdByWindowHandle(hwnd));
3347 return 0;
3348 }
3349 break;
3350 case WM_ACTIVATE:
3351 if(LOWORD(wParam) == WA_CLICKACTIVE || LOWORD(wParam) == WA_ACTIVE
3352 || ViewerTest::CurrentView().IsNull())
3353 {
3354 // Activate inactive window
3355 if(GetWindowHandle(VT_GetWindow()) != hwnd)
3356 {
3357 ActivateView (FindViewIdByWindowHandle(hwnd));
3358 }
3359 }
3360 break;
625e1958 3361
7fd59977 3362 case WM_LBUTTONUP:
625e1958 3363 if (IsDragged && !DragFirst)
7fd59977 3364 {
625e1958 3365 if (!GetActiveAISManipulator().IsNull())
3366 {
3367 GetActiveAISManipulator()->StopTransform();
0577ae8c 3368 ViewerTest::GetAISContext()->ClearSelected (Standard_True);
625e1958 3369 }
3370
b12e1c7b 3371 if (ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
3372 {
3373 ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
3374 ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
3375 }
3376
dde68833 3377 VT_ProcessButton1Release ((fwKeys & MK_SHIFT) != 0);
7fd59977 3378 }
8abada55 3379 IsDragged = Standard_False;
7fd59977 3380 return ViewerWindowProc( hwnd, Msg, wParam, lParam );
3381
625e1958 3382 case WM_RBUTTONUP:
3383 if (IsDragged && !DragFirst)
3384 {
3385 if (!GetActiveAISManipulator().IsNull())
3386 {
3387 GetActiveAISManipulator()->StopTransform (Standard_False);
0577ae8c 3388 ViewerTest::GetAISContext()->ClearSelected (Standard_True);
625e1958 3389 }
3390 IsDragged = Standard_False;
3391 }
3392 return ViewerWindowProc (hwnd, Msg, wParam, lParam);
3393
7fd59977 3394 case WM_LBUTTONDOWN:
625e1958 3395 if (!GetActiveAISManipulator().IsNull())
3396 {
3397 IsDragged = ( fwKeys == MK_LBUTTON );
3398 }
3399 else
3400 {
3401 IsDragged = ( fwKeys == MK_LBUTTON || fwKeys == ( MK_LBUTTON | MK_SHIFT ) );
3402 }
3403
3404 if (IsDragged)
7fd59977 3405 {
7fd59977 3406 DragFirst = Standard_True;
4fe56619 3407 X_ButtonPress = LOWORD(lParam);
3408 Y_ButtonPress = HIWORD(lParam);
7fd59977 3409 }
3410 return ViewerWindowProc( hwnd, Msg, wParam, lParam );
3411
7fd59977 3412 case WM_MOUSEMOVE:
b12e1c7b 3413 if (IsDragged)
7fd59977 3414 {
b12e1c7b 3415 X_Motion = LOWORD (lParam);
3416 Y_Motion = HIWORD (lParam);
625e1958 3417 if (!GetActiveAISManipulator().IsNull())
b12e1c7b 3418 {
625e1958 3419 if (DragFirst)
3420 {
3421 GetActiveAISManipulator()->StartTransform (X_ButtonPress, Y_ButtonPress, ViewerTest::CurrentView());
3422 }
3423 else
3424 {
3425 GetActiveAISManipulator()->Transform (X_Motion, Y_Motion, ViewerTest::CurrentView());
3426 ViewerTest::GetAISContext()->CurrentViewer()->Redraw();
3427 }
69adb9ce 3428 }
625e1958 3429 else
69adb9ce 3430 {
625e1958 3431 bool toRedraw = false;
3432 if (!DragFirst && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
3433 {
3434 ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
3435 toRedraw = true;
3436 }
3437
3438 RECT aRect;
3439 if (GetClientRect (hwnd, &aRect))
3440 {
3441 int aHeight = aRect.bottom - aRect.top;
3442 GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
68dcee02 3443 ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
625e1958 3444 toRedraw = true;
3445 }
3446 if (toRedraw)
3447 {
3448 ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
3449 }
b12e1c7b 3450 }
625e1958 3451
3452 DragFirst = Standard_False;
7fd59977 3453 }
3454 else
3455 return ViewerWindowProc( hwnd, Msg, wParam, lParam );
3456 break;
3457
3458 default:
3459 return ViewerWindowProc( hwnd, Msg, wParam, lParam );
3460 }
3461 return 0;
3462 }
3463 return ViewerWindowProc( hwnd, Msg, wParam, lParam );
3464}
3465
3466
3467static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
3468 UINT Msg,
3469 WPARAM wParam,
3470 LPARAM lParam )
3471{
7fd59977 3472 static int Up = 1;
f978241f 3473 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
3474 if (aView.IsNull())
3475 {
ad03c234 3476 return DefWindowProcW (hwnd, Msg, wParam, lParam);
f978241f 3477 }
7fd59977 3478
7fd59977 3479 PAINTSTRUCT ps;
3480
3481 switch( Msg ) {
7fd59977 3482 case WM_PAINT:
7fd59977 3483 BeginPaint(hwnd, &ps);
3484 EndPaint(hwnd, &ps);
4fe56619 3485 VT_ProcessExpose();
7fd59977 3486 break;
3487
3488 case WM_SIZE:
4fe56619 3489 VT_ProcessConfigure();
7fd59977 3490 break;
f978241f 3491 case WM_MOVE:
3492 case WM_MOVING:
3493 case WM_SIZING:
3494 switch (aView->RenderingParams().StereoMode)
3495 {
3496 case Graphic3d_StereoMode_RowInterlaced:
3497 case Graphic3d_StereoMode_ColumnInterlaced:
3498 case Graphic3d_StereoMode_ChessBoard:
3499 VT_ProcessConfigure(); // track window moves to reverse stereo pair
3500 break;
3501 default:
3502 break;
3503 }
3504 break;
7fd59977 3505
3506 case WM_KEYDOWN:
4fe56619 3507 if ((wParam != VK_SHIFT) && (wParam != VK_CONTROL))
3508 {
7fd59977 3509 char c[2];
3510 c[0] = (char) wParam;
3511 c[1] = '\0';
b514beda 3512 if (wParam == VK_DELETE)
3513 {
3514 c[0] = THE_KEY_DELETE;
3515 }
fd3f6bd0 3516 else if (wParam == VK_ESCAPE)
3517 {
3518 c[0] = THE_KEY_ESCAPE;
3519 }
4ca4bbe8 3520 // comma
3521 else if (wParam == VK_OEM_COMMA)
3522 {
3523 c[0] = ',';
3524 }
3525 // dot
3526 else if (wParam == VK_OEM_PERIOD)
3527 {
3528 c[0] = '.';
3529 }
f978241f 3530 else if (wParam == VK_DIVIDE)
3531 {
3532 c[0] = '/';
3533 }
3534 // dot
3535 else if (wParam == VK_MULTIPLY)
3536 {
3537 c[0] = '*';
3538 }
4fe56619 3539 VT_ProcessKeyPress (c);
7fd59977 3540 }
3541 break;
3542
3543 case WM_LBUTTONUP:
3544 case WM_MBUTTONUP:
3545 case WM_RBUTTONUP:
7fd59977 3546 Up = 1;
4fe56619 3547 VT_ProcessButton3Release();
7fd59977 3548 break;
3549
3550 case WM_LBUTTONDOWN:
3551 case WM_MBUTTONDOWN:
3552 case WM_RBUTTONDOWN:
3553 {
7fd59977 3554 WPARAM fwKeys = wParam;
3555
3556 Up = 0;
3557
3558 X_ButtonPress = LOWORD(lParam);
3559 Y_ButtonPress = HIWORD(lParam);
3560
4fe56619 3561 if (Msg == WM_LBUTTONDOWN)
3562 {
dde68833 3563 if ((fwKeys & MK_CONTROL) != 0)
4fe56619 3564 {
dde68833 3565 Ppick = VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
4fe56619 3566 }
3567 else
3568 {
dde68833 3569 VT_ProcessButton1Press (Pargc, Pargv, Ppick, (fwKeys & MK_SHIFT) != 0);
4fe56619 3570 }
7fd59977 3571 }
4fe56619 3572 else if (Msg == WM_RBUTTONDOWN)
3573 {
7fd59977 3574 // Start rotation
4fe56619 3575 VT_ProcessButton3Press();
7fd59977 3576 }
3577 }
3578 break;
3579
f978241f 3580 case WM_MOUSEWHEEL:
3581 {
3582 int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
3583 if (wParam & MK_CONTROL)
3584 {
3585 if (aView->Camera()->IsStereo())
3586 {
3587 Standard_Real aFocus = aView->Camera()->ZFocus() + (aDelta > 0 ? 0.05 : -0.05);
3588 if (aFocus > 0.2
3589 && aFocus < 2.0)
3590 {
3591 aView->Camera()->SetZFocus (aView->Camera()->ZFocusType(), aFocus);
3592 aView->Redraw();
3593 }
3594 }
3595 }
3596 else
3597 {
3598 aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
3599 }
3600 break;
3601 }
3602
7fd59977 3603 case WM_MOUSEMOVE:
3604 {
3605 //cout << "\t WM_MOUSEMOVE" << endl;
3606 WPARAM fwKeys = wParam;
3607 X_Motion = LOWORD(lParam);
3608 Y_Motion = HIWORD(lParam);
3609
3610 if ( Up &&
dde68833 3611 (fwKeys & ( MK_LBUTTON|MK_MBUTTON|MK_RBUTTON )) != 0 )
3612 {
7fd59977 3613 Up = 0;
3614 X_ButtonPress = LOWORD(lParam);
3615 Y_ButtonPress = HIWORD(lParam);
3616
dde68833 3617 if ((fwKeys & MK_RBUTTON) != 0) {
7fd59977 3618 // Start rotation
4fe56619 3619 VT_ProcessButton3Press();
7fd59977 3620 }
3621 }
3622
dde68833 3623 if ((fwKeys & MK_CONTROL) != 0)
3624 {
3625 if ((fwKeys & MK_LBUTTON) != 0)
3626 {
7fd59977 3627 ProcessControlButton1Motion();
3628 }
dde68833 3629 else if ((fwKeys & MK_MBUTTON) != 0
3630 || ((fwKeys & MK_LBUTTON) != 0
3631 && (fwKeys & MK_RBUTTON) != 0))
3632 {
3633 VT_ProcessControlButton2Motion();
3634 }
3635 else if ((fwKeys & MK_RBUTTON) != 0)
3636 {
4fe56619 3637 VT_ProcessControlButton3Motion();
7fd59977 3638 }
3639 }
08398024 3640 else if (GetWindowHandle (VT_GetWindow()) == hwnd)
3641 {
89a929ea 3642 VT_ProcessMotion();
08398024 3643 }
7fd59977 3644 }
3645 break;
3646
3647 default:
ad03c234 3648 return DefWindowProcW (hwnd, Msg, wParam, lParam);
7fd59977 3649 }
3650 return 0L;
7fd59977 3651}
3652
7fd59977 3653//==============================================================================
3654//function : ViewerMainLoop
3655//purpose : Get a Event on the view and dispatch it
3656//==============================================================================
3657
3658
8263fcd3 3659int ViewerMainLoop(Standard_Integer argc, const char** argv)
7fd59977 3660{
7fd59977 3661 Ppick = (argc > 0)? 1 : 0;
3662 Pargc = argc;
3663 Pargv = argv;
3664
3665 if ( Ppick ) {
3666 MSG msg;
3667 msg.wParam = 1;
3668
3669 cout << "Start picking" << endl;
3670
7fd59977 3671 while ( Ppick == 1 ) {
4fe56619 3672 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
ad03c234 3673 if (GetMessageW (&msg, NULL, 0, 0))
3674 {
3675 TranslateMessage (&msg);
3676 DispatchMessageW (&msg);
7fd59977 3677 }
3678 }
3679
3680 cout << "Picking done" << endl;
3681 }
3682
3683 return Ppick;
3684}
3685
4fe56619 3686#elif !defined(__APPLE__) || defined(MACOSX_USE_GLX)
7fd59977 3687
3688int min( int a, int b )
3689{
3690 if( a<b )
3691 return a;
3692 else
3693 return b;
3694}
3695
3696int max( int a, int b )
3697{
3698 if( a>b )
3699 return a;
3700 else
3701 return b;
3702}
3703
8693dfd0 3704int ViewerMainLoop (Standard_Integer argc, const char** argv)
4269bd1b 3705{
18d715bd 3706 static XEvent aReport;
8693dfd0 3707 const Standard_Boolean toPick = argc > 0;
3708 Standard_Boolean toPickMore = toPick;
3709 Display* aDisplay = GetDisplayConnection()->GetDisplay();
18d715bd 3710 XNextEvent (aDisplay, &aReport);
7fd59977 3711
18d715bd 3712 // Handle event for the chosen display connection
8693dfd0 3713 switch (aReport.type)
3714 {
3715 case ClientMessage:
3716 {
3717 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
3718 {
3719 // Close the window
3720 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
3721 return toPick ? 0 : 1;
3722 }
3723 break;
3724 }
3725 case FocusIn:
3726 {
3727 // Activate inactive view
3728 Window aWindow = GetWindowHandle(VT_GetWindow());
3729 if (aWindow != aReport.xfocus.window)
3730 {
3731 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
3732 }
3733 break;
3734 }
3735 case Expose:
3736 {
3737 Window anXWindow = GetWindowHandle (VT_GetWindow());
3738 if (anXWindow == aReport.xexpose.window)
3739 {
3740 VT_ProcessExpose();
3741 }
3742
3743 // remove all the ExposureMask and process them at once
3744 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3745 {
3746 if (!XCheckWindowEvent (aDisplay, anXWindow, ExposureMask, &aReport))
18d715bd 3747 {
8693dfd0 3748 break;
18d715bd 3749 }
8693dfd0 3750 }
3751
3752 break;
3753 }
3754 case ConfigureNotify:
3755 {
3756 // remove all the StructureNotifyMask and process them at once
3757 Window anXWindow = GetWindowHandle (VT_GetWindow());
3758 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3759 {
3760 if (!XCheckWindowEvent (aDisplay, anXWindow, StructureNotifyMask, &aReport))
3761 {
3762 break;
3763 }
3764 }
3765
3766 if (anXWindow == aReport.xconfigure.window)
3767 {
3768 VT_ProcessConfigure();
3769 }
3770 break;
3771 }
3772 case KeyPress:
3773 {
3774 KeySym aKeySym;
3775 char aKeyBuf[11];
3776 XComposeStatus status_in_out;
3777 int aKeyLen = XLookupString ((XKeyEvent* )&aReport, (char* )aKeyBuf, 10, &aKeySym, &status_in_out);
3778 aKeyBuf[aKeyLen] = '\0';
3779 if (aKeyLen != 0)
18d715bd 3780 {
8693dfd0 3781 VT_ProcessKeyPress (aKeyBuf);
18d715bd 3782 }
3783 break;
8693dfd0 3784 }
3785 case ButtonPress:
3786 {
3787 X_ButtonPress = aReport.xbutton.x;
3788 Y_ButtonPress = aReport.xbutton.y;
3789 if (aReport.xbutton.button == Button1)
3790 {
3791 if (aReport.xbutton.state & ControlMask)
7fd59977 3792 {
8693dfd0 3793 toPickMore = VT_ProcessButton1Press (argc, argv, toPick, (aReport.xbutton.state & ShiftMask) != 0);
7fd59977 3794 }
8693dfd0 3795 else
7fd59977 3796 {
8693dfd0 3797 IsDragged = Standard_True;
3798 DragFirst = Standard_True;
7fd59977 3799 }
8693dfd0 3800 }
3801 else if (aReport.xbutton.button == Button3)
3802 {
3803 // Start rotation
3804 VT_ProcessButton3Press();
3805 }
3806 break;
3807 }
3808 case ButtonRelease:
3809 {
3810 if (!IsDragged)
3811 {
3812 VT_ProcessButton3Release();
7fd59977 3813 break;
8693dfd0 3814 }
7fd59977 3815
8693dfd0 3816 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3817 if (aContext.IsNull())
3818 {
3819 std::cout << "Error: No active view.\n";
3820 return 0;
3821 }
7fd59977 3822
8693dfd0 3823 if (!DragFirst
3824 && aContext->IsDisplayed (GetRubberBand()))
3825 {
3826 aContext->Remove (GetRubberBand(), Standard_False);
3827 aContext->CurrentViewer()->RedrawImmediate();
3828 }
7fd59977 3829
8693dfd0 3830 if (aReport.xbutton.button != Button1)
3831 {
3832 break;
3833 }
7fd59977 3834
8693dfd0 3835 const Standard_Boolean isShiftPressed = (aReport.xbutton.state & ShiftMask) != 0;
3836 if (DragFirst)
3837 {
3838 if (isShiftPressed)
3839 {
3840 aContext->ShiftSelect (Standard_True);
7fd59977 3841 }
8693dfd0 3842 else
7fd59977 3843 {
8693dfd0 3844 aContext->Select (Standard_True);
7fd59977 3845 }
8693dfd0 3846 }
3847 else
3848 {
3849 if (isShiftPressed)
3850 {
3851 aContext->ShiftSelect (Min (X_ButtonPress, X_Motion), Min (Y_ButtonPress, Y_Motion),
3852 Max (X_ButtonPress, X_Motion), Max (Y_ButtonPress, Y_Motion),
3853 ViewerTest::CurrentView(), Standard_True);
3854 }
3855 else
3856 {
3857 aContext->Select (Min (X_ButtonPress, X_Motion), Min(Y_ButtonPress, Y_Motion),
3858 Max (X_ButtonPress, X_Motion), Max(Y_ButtonPress, Y_Motion),
3859 ViewerTest::CurrentView(), Standard_True);
3860 }
3861 }
3862 IsDragged = Standard_False;
3863 break;
3864 }
3865 case MotionNotify:
3866 {
3867 Window anXWindow = GetWindowHandle (VT_GetWindow());
3868 if (anXWindow != aReport.xmotion.window)
3869 {
7fd59977 3870 break;
8693dfd0 3871 }
3872
3873 // remove all the ButtonMotionMask and process them at once
3874 for (int aNbMaxEvents = XPending (aDisplay); aNbMaxEvents > 0; --aNbMaxEvents)
3875 {
3876 if (!XCheckWindowEvent (aDisplay, anXWindow, ButtonMotionMask | PointerMotionMask, &aReport))
7fd59977 3877 {
8693dfd0 3878 break;
3879 }
3880 }
7fd59977 3881
8693dfd0 3882 if (IsDragged)
3883 {
3884 if (!DragFirst
3885 && ViewerTest::GetAISContext()->IsDisplayed (GetRubberBand()))
3886 {
3887 ViewerTest::GetAISContext()->Remove (GetRubberBand(), Standard_False);
3888 }
7fd59977 3889
8693dfd0 3890 X_Motion = aReport.xmotion.x;
3891 Y_Motion = aReport.xmotion.y;
3892 DragFirst = Standard_False;
7fd59977 3893
8693dfd0 3894 Window aWindow = GetWindowHandle(VT_GetWindow());
3895 Window aRoot;
3896 int anX, anY;
3897 unsigned int aWidth, aHeight, aBorderWidth, aDepth;
3898 XGetGeometry (aDisplay, aWindow, &aRoot, &anX, &anY, &aWidth, &aHeight, &aBorderWidth, &aDepth);
3899 GetRubberBand()->SetRectangle (X_ButtonPress, aHeight - Y_ButtonPress, X_Motion, aHeight - Y_Motion);
3900 ViewerTest::GetAISContext()->Display (GetRubberBand(), 0, -1, Standard_False, AIS_DS_Displayed);
3901 ViewerTest::GetAISContext()->CurrentViewer()->RedrawImmediate();
3902 }
3903 else
3904 {
3905 X_Motion = aReport.xmotion.x;
3906 Y_Motion = aReport.xmotion.y;
3907 if ((aReport.xmotion.state & ControlMask) != 0)
7fd59977 3908 {
8693dfd0 3909 if ((aReport.xmotion.state & Button1Mask) != 0)
08398024 3910 {
8693dfd0 3911 ProcessControlButton1Motion();
08398024 3912 }
8693dfd0 3913 else if ((aReport.xmotion.state & Button2Mask) != 0)
7fd59977 3914 {
8693dfd0 3915 VT_ProcessControlButton2Motion();
7fd59977 3916 }
8693dfd0 3917 else if ((aReport.xmotion.state & Button3Mask) != 0)
7fd59977 3918 {
8693dfd0 3919 VT_ProcessControlButton3Motion();
7fd59977 3920 }
3921 }
8693dfd0 3922 else
3923 {
3924 VT_ProcessMotion();
3925 }
3926 }
3927 break;
3928 }
3929 }
3930 return (!toPick || toPickMore) ? 1 : 0;
7fd59977 3931}
3932
3933//==============================================================================
3934//function : VProcessEvents
8693dfd0 3935//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
7fd59977 3936//==============================================================================
8693dfd0 3937static void VProcessEvents (ClientData theDispX, int)
7fd59977 3938{
8693dfd0 3939 Display* aDispX = (Display* )theDispX;
3940 Handle(Aspect_DisplayConnection) aDispConn;
3941 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
3942 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
18d715bd 3943 {
8693dfd0 3944 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
3945 if (aDispConnTmp->GetDisplay() == aDispX)
3946 {
3947 aDispConn = aDispConnTmp;
3948 break;
3949 }
3950 }
3951 if (aDispConn.IsNull())
3952 {
3953 std::cerr << "Error: ViewerTest is unable processing messages for unknown X Display\n";
3954 return;
4269bd1b 3955 }
8693dfd0 3956
3957 // process new events in queue
3958 SetDisplayConnection (aDispConn);
3959 int aNbRemain = 0;
3960 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
18d715bd 3961 {
8693dfd0 3962 const int anEventResult = ViewerMainLoop (0, NULL);
3963 if (anEventResult == 0)
18d715bd 3964 {
8693dfd0 3965 return;
3966 }
3967
3968 aNbRemain = XPending (aDispX);
3969 if (++anEventIter >= aNbEventsMax
3970 || aNbRemain <= 0)
3971 {
3972 break;
18d715bd 3973 }
7fd59977 3974 }
4269bd1b 3975
8693dfd0 3976 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
3977 // it is possible that new events will arrive to queue before the end of this callback
3978 // so that either this callback should go into an infinite loop (blocking processing of other events)
3979 // or to keep unprocessed events till the next queue update (which can arrive not soon).
3980 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
3981 if (aNbRemain != 0)
3982 {
3983 XEvent aDummyEvent;
3984 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
3985 aDummyEvent.type = ClientMessage;
3986 aDummyEvent.xclient.format = 32;
3987 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
3988 XFlush (aDispX);
3989 }
4269bd1b 3990
8693dfd0 3991 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
3992 {
3993 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
3994 }
7fd59977 3995}
3996#endif
3997
3998//==============================================================================
3999//function : OSWindowSetup
4000//purpose : Setup for the X11 window to be able to cath the event
4001//==============================================================================
4002
4003
4004static void OSWindowSetup()
4005{
4fe56619 4006#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
7fd59977 4007 // X11
4008
4009 Window window = VT_GetWindow()->XWindow();
18d715bd 4010 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
4011 Display *aDisplay = GetDisplayConnection()->GetDisplay();
4012 XSynchronize(aDisplay, 1);
7fd59977 4013
4014 // X11 : For keyboard on SUN
4015 XWMHints wmhints;
4016 wmhints.flags = InputHint;
4017 wmhints.input = 1;
4018
18d715bd 4019 XSetWMHints( aDisplay, window, &wmhints);
7fd59977 4020
18d715bd 4021 XSelectInput( aDisplay, window, ExposureMask | KeyPressMask |
7fd59977 4022 ButtonPressMask | ButtonReleaseMask |
4023 StructureNotifyMask |
4024 PointerMotionMask |
4025 Button1MotionMask | Button2MotionMask |
18d715bd 4026 Button3MotionMask | FocusChangeMask
7fd59977 4027 );
18d715bd 4028 Atom aDeleteWindowAtom = GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW);
4029 XSetWMProtocols(aDisplay, window, &aDeleteWindowAtom, 1);
7fd59977 4030
18d715bd 4031 XSynchronize(aDisplay, 0);
7fd59977 4032
4033#else
57c28b61 4034 // _WIN32
7fd59977 4035#endif
4036
4037}
4038
7fd59977 4039//==============================================================================
4040//function : VFit
1beb58d7 4041//purpose :
7fd59977 4042//==============================================================================
4043
1beb58d7 4044static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
7fd59977 4045{
1beb58d7 4046 const Handle(V3d_View) aView = ViewerTest::CurrentView();
4047 if (aView.IsNull())
b586500b 4048 {
1beb58d7 4049 std::cout << "Error: no active viewer!\n";
4050 return 1;
b586500b 4051 }
4052
1beb58d7 4053 Standard_Boolean toFit = Standard_True;
4054 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
4055 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
b586500b 4056 {
1beb58d7 4057 TCollection_AsciiString anArg (theArgv[anArgIter]);
b586500b 4058 anArg.LowerCase();
1beb58d7 4059 if (anUpdateTool.parseRedrawMode (anArg))
b586500b 4060 {
1beb58d7 4061 continue;
4062 }
4063 else if (anArg == "-selected")
4064 {
4065 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
4066 toFit = Standard_False;
4067 }
4068 else
4069 {
4070 std::cout << "Syntax error at '" << anArg << "'\n";
b586500b 4071 }
4072 }
4073
1beb58d7 4074 if (toFit)
4075 {
4076 aView->FitAll (0.01, Standard_False);
7fd59977 4077 }
4078 return 0;
4079}
4080
6262a303 4081//=======================================================================
4082//function : VFitArea
4083//purpose : Fit view to show area located between two points
4084// : given in world 2D or 3D coordinates.
4085//=======================================================================
4086static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
4087{
4088 Handle(V3d_View) aView = ViewerTest::CurrentView();
4089 if (aView.IsNull())
4090 {
4091 std::cerr << theArgVec[0] << "Error: No active view.\n";
4092 return 1;
4093 }
4094
4095 // Parse arguments.
4096 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
4097 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
4098
4099 if (theArgNb == 5)
4100 {
4101 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
4102 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
4103 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
4104 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
4105 }
4106 else if (theArgNb == 7)
4107 {
4108 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
4109 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
4110 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
4111 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
4112 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
4113 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
4114 }
4115 else
4116 {
4117 std::cerr << theArgVec[0] << "Error: Invalid number of arguments.\n";
4118 theDI.PrintHelp(theArgVec[0]);
4119 return 1;
4120 }
4121
4122 // Convert model coordinates to view space
4123 Handle(Graphic3d_Camera) aCamera = aView->Camera();
4124 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
4125 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
4126
4127 // Determine fit area
4128 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
4129 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
4130
4131 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
4132
4133 if (aDiagonal < Precision::Confusion())
4134 {
4135 std::cerr << theArgVec[0] << "Error: view area is too small.\n";
4136 return 1;
4137 }
4138
4139 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
4140 return 0;
4141}
4142
7fd59977 4143//==============================================================================
4144//function : VZFit
4145//purpose : ZFitall, no DRAW arguments
4146//Draw arg : No args
4147//==============================================================================
197ac94e 4148static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
7fd59977 4149{
197ac94e 4150 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
4151
4152 if (aCurrentView.IsNull())
4153 {
4154 std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
4155 return 1;
4156 }
4157
4158 if (theArgsNb == 1)
4159 {
c357e426 4160 aCurrentView->ZFitAll();
197ac94e 4161 aCurrentView->Redraw();
4162 return 0;
4163 }
4164
4165 Standard_Real aScale = 1.0;
4166
4167 if (theArgsNb >= 2)
4168 {
4169 aScale = Draw::Atoi (theArgVec[1]);
4170 }
4171
c357e426 4172 aCurrentView->ZFitAll (aScale);
197ac94e 4173 aCurrentView->Redraw();
7fd59977 4174
197ac94e 4175 return 0;
4176}
7fd59977 4177
197ac94e 4178//==============================================================================
4179//function : VRepaint
4180//purpose :
4181//==============================================================================
56689b27 4182static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
7fd59977 4183{
56689b27 4184 Handle(V3d_View) aView = ViewerTest::CurrentView();
4185 if (aView.IsNull())
4186 {
4187 std::cout << "Error: no active viewer!\n";
4188 return 1;
4189 }
4190
4191 Standard_Boolean isImmediateUpdate = Standard_False;
4192 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4193 {
4194 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4195 anArg.LowerCase();
8693dfd0 4196 if (anArg == "-immediate"
4197 || anArg == "-imm")
56689b27 4198 {
4199 isImmediateUpdate = Standard_True;
4200 if (anArgIter + 1 < theArgNb
4201 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
4202 {
4203 ++anArgIter;
4204 }
4205 }
8693dfd0 4206 else if (anArg == "-continuous"
4207 || anArg == "-cont"
4208 || anArg == "-fps"
4209 || anArg == "-framerate")
4210 {
4211 Standard_Real aFps = -1.0;
4212 if (anArgIter + 1 < theArgNb
4213 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
4214 {
4215 aFps = Draw::Atof (theArgVec[++anArgIter]);
4216 }
4217
4218 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
4219 if (Abs (aFps) >= 1.0)
4220 {
4221 aRedrawer.Start (aView->Window(), aFps);
4222 }
4223 else
4224 {
4225 aRedrawer.Stop();
4226 }
4227 }
56689b27 4228 else
4229 {
4230 std::cout << "Syntax error at '" << anArg << "'\n";
8693dfd0 4231 return 1;
56689b27 4232 }
4233 }
4234
4235 if (isImmediateUpdate)
4236 {
4237 aView->RedrawImmediate();
4238 }
4239 else
4240 {
4241 aView->Redraw();
4242 }
4243 return 0;
7fd59977 4244}
4245
7fd59977 4246//==============================================================================
4247//function : VClear
4248//purpose : Remove all the object from the viewer
4249//Draw arg : No args
4250//==============================================================================
4251
4252static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
4253{
4254 Handle(V3d_View) V = ViewerTest::CurrentView();
4255 if(!V.IsNull())
4256 ViewerTest::Clear();
4257 return 0;
4258}
4259
4260//==============================================================================
4261//function : VPick
4262//purpose :
4263//==============================================================================
4264
4265static int VPick(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4266{ if (ViewerTest::CurrentView().IsNull() ) return 1;
4267
4268if ( argc < 4 ) {
586db386 4269 di << argv[0] << "Invalid number of arguments\n";
7fd59977 4270 return 1;
4271}
4272
4273while (ViewerMainLoop( argc, argv)) {
4274}
4275
4276return 0;
4277}
4278
293211ae 4279namespace
7fd59977 4280{
7fd59977 4281
293211ae 4282 //! Changes the background
4283 //! @param theDrawInterpretor the interpreter of the Draw Harness application
4284 //! @param theNumberOfCommandLineArguments the number of passed command line arguments
4285 //! @param theCommandLineArguments the array of command line arguments
4286 //! @return TCL_OK if changing was successful, or TCL_ERROR otherwise
4287 static int vbackground (Draw_Interpretor& theDrawInterpretor,
4288 const Standard_Integer theNumberOfCommandLineArguments,
4289 const char** const theCommandLineArguments)
7fd59977 4290 {
293211ae 4291 if (theNumberOfCommandLineArguments < 1)
7fd59977 4292 {
293211ae 4293 return TCL_ERROR;
7fd59977 4294 }
293211ae 4295 BackgroundChanger aBackgroundChanger;
4296 if (!aBackgroundChanger.ProcessCommandLine (theDrawInterpretor,
4297 theNumberOfCommandLineArguments,
4298 theCommandLineArguments))
f8b2ed36 4299 {
293211ae 4300 theDrawInterpretor << "Wrong command arguments.\n"
4301 "Type 'help "
4302 << theCommandLineArguments[0] << "' for information about command options and its arguments.\n";
4303 return TCL_ERROR;
f8b2ed36 4304 }
293211ae 4305 return TCL_OK;
f8b2ed36 4306 }
4307
293211ae 4308} // namespace
f42753ed 4309
7fd59977 4310//==============================================================================
4311//function : VScale
4312//purpose : View Scaling
4313//==============================================================================
4314
4315static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4316{
4317 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4318 if ( V3dView.IsNull() ) return 1;
4319
4320 if ( argc != 4 ) {
586db386 4321 di << argv[0] << "Invalid number of arguments\n";
7fd59977 4322 return 1;
4323 }
91322f44 4324 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
7fd59977 4325 return 0;
4326}
4327//==============================================================================
536d98e2 4328//function : VZBuffTrihedron
4329//purpose :
7fd59977 4330//==============================================================================
4331
536d98e2 4332static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
4333 Standard_Integer theArgNb,
4334 const char** theArgVec)
7fd59977 4335{
536d98e2 4336 Handle(V3d_View) aView = ViewerTest::CurrentView();
4337 if (aView.IsNull())
4338 {
4339 std::cout << "Error: no active viewer!\n";
4340 return 1;
4341 }
7fd59977 4342
536d98e2 4343 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
7c8a8fcc 4344
536d98e2 4345 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
4346 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
4347 Quantity_Color aLabelsColor = Quantity_NOC_WHITE;
4348 Quantity_Color anArrowColorX = Quantity_NOC_RED;
4349 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
4350 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
4351 Standard_Real aScale = 0.1;
4352 Standard_Real aSizeRatio = 0.8;
4353 Standard_Real anArrowDiam = 0.05;
4354 Standard_Integer aNbFacets = 12;
4355 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7c8a8fcc 4356 {
536d98e2 4357 Standard_CString anArg = theArgVec[anArgIter];
4358 TCollection_AsciiString aFlag (anArg);
4359 aFlag.LowerCase();
4360 if (anUpdateTool.parseRedrawMode (aFlag))
7c8a8fcc 4361 {
536d98e2 4362 continue;
4363 }
4364 else if (aFlag == "-on")
7c8a8fcc 4365 {
536d98e2 4366 continue;
4367 }
4368 else if (aFlag == "-off")
7c8a8fcc 4369 {
536d98e2 4370 aView->TriedronErase();
4371 return 0;
4372 }
4373 else if (aFlag == "-pos"
4374 || aFlag == "-position"
4375 || aFlag == "-corner")
7c8a8fcc 4376 {
536d98e2 4377 if (++anArgIter >= theArgNb)
4378 {
4379 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4380 return 1;
4381 }
4382
4383 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
4384 aPosName.LowerCase();
4385 if (aPosName == "center")
4386 {
4387 aPosition = Aspect_TOTP_CENTER;
4388 }
4389 else if (aPosName == "left_lower"
4390 || aPosName == "lower_left"
4391 || aPosName == "leftlower"
4392 || aPosName == "lowerleft")
4393 {
4394 aPosition = Aspect_TOTP_LEFT_LOWER;
4395 }
4396 else if (aPosName == "left_upper"
4397 || aPosName == "upper_left"
4398 || aPosName == "leftupper"
4399 || aPosName == "upperleft")
4400 {
4401 aPosition = Aspect_TOTP_LEFT_UPPER;
4402 }
4403 else if (aPosName == "right_lower"
4404 || aPosName == "lower_right"
4405 || aPosName == "rightlower"
4406 || aPosName == "lowerright")
4407 {
4408 aPosition = Aspect_TOTP_RIGHT_LOWER;
4409 }
4410 else if (aPosName == "right_upper"
4411 || aPosName == "upper_right"
4412 || aPosName == "rightupper"
4413 || aPosName == "upperright")
4414 {
4415 aPosition = Aspect_TOTP_RIGHT_UPPER;
4416 }
4417 else
4418 {
4419 std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'\n";
4420 return 1;
4421 }
4422 }
4423 else if (aFlag == "-type")
7c8a8fcc 4424 {
536d98e2 4425 if (++anArgIter >= theArgNb)
4426 {
4427 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4428 return 1;
4429 }
4430
4431 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
4432 aTypeName.LowerCase();
4433 if (aTypeName == "wireframe"
4434 || aTypeName == "wire")
4435 {
4436 aVisType = V3d_WIREFRAME;
4437 }
4438 else if (aTypeName == "zbuffer"
4439 || aTypeName == "shaded")
4440 {
4441 aVisType = V3d_ZBUFFER;
4442 }
4443 else
4444 {
4445 std::cerr << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'\n";
4446 }
4447 }
4448 else if (aFlag == "-scale")
7c8a8fcc 4449 {
536d98e2 4450 if (++anArgIter >= theArgNb)
4451 {
4452 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4453 return 1;
4454 }
4455
4456 aScale = Draw::Atof (theArgVec[anArgIter]);
7c8a8fcc 4457 }
536d98e2 4458 else if (aFlag == "-size"
4459 || aFlag == "-sizeratio")
4460 {
4461 if (++anArgIter >= theArgNb)
4462 {
4463 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4464 return 1;
4465 }
7c8a8fcc 4466
536d98e2 4467 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
4468 }
4469 else if (aFlag == "-arrowdiam"
4470 || aFlag == "-arrowdiameter")
4471 {
4472 if (++anArgIter >= theArgNb)
4473 {
4474 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4475 return 1;
4476 }
7c8a8fcc 4477
536d98e2 4478 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
4479 }
4480 else if (aFlag == "-nbfacets")
4481 {
4482 if (++anArgIter >= theArgNb)
4483 {
4484 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4485 return 1;
4486 }
7c8a8fcc 4487
536d98e2 4488 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
4489 }
4490 else if (aFlag == "-colorlabel"
4491 || aFlag == "-colorlabels")
7c8a8fcc 4492 {
536d98e2 4493 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4494 theArgVec + anArgIter + 1,
4495 aLabelsColor);
4496 if (aNbParsed == 0)
4497 {
4498 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4499 return 1;
4500 }
4501 anArgIter += aNbParsed;
7c8a8fcc 4502 }
536d98e2 4503 else if (aFlag == "-colorarrowx")
7c8a8fcc 4504 {
536d98e2 4505 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4506 theArgVec + anArgIter + 1,
4507 anArrowColorX);
4508 if (aNbParsed == 0)
4509 {
4510 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4511 return 1;
4512 }
4513 anArgIter += aNbParsed;
4514 }
4515 else if (aFlag == "-colorarrowy")
7c8a8fcc 4516 {
536d98e2 4517 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4518 theArgVec + anArgIter + 1,
4519 anArrowColorY);
4520 if (aNbParsed == 0)
4521 {
4522 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4523 return 1;
4524 }
4525 anArgIter += aNbParsed;
4526 }
4527 else if (aFlag == "-colorarrowz")
7c8a8fcc 4528 {
536d98e2 4529 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - anArgIter - 1,
4530 theArgVec + anArgIter + 1,
4531 anArrowColorZ);
4532 if (aNbParsed == 0)
4533 {
4534 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4535 return 1;
4536 }
4537 anArgIter += aNbParsed;
4538 }
4539 else
4540 {
4541 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
7c8a8fcc 4542 return 1;
4543 }
7c8a8fcc 4544 }
4545
536d98e2 4546 aView->ZBufferTriedronSetup (anArrowColorX.Name(), anArrowColorY.Name(), anArrowColorZ.Name(),
4547 aSizeRatio, anArrowDiam, aNbFacets);
4548 aView->TriedronDisplay (aPosition, aLabelsColor.Name(), aScale, aVisType);
c357e426 4549 aView->ZFitAll();
7fd59977 4550 return 0;
4551}
4552
4553//==============================================================================
4554//function : VRotate
4555//purpose : Camera Rotating
4556//==============================================================================
4557
4af098ba 4558static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
4559{
4560 Handle(V3d_View) aView = ViewerTest::CurrentView();
4561 if (aView.IsNull())
4562 {
4563 std::cout << "No active view!\n";
7fd59977 4564 return 1;
4565 }
4566
4af098ba 4567 Standard_Boolean hasFlags = Standard_False;
4568 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4569 {
4570 Standard_CString anArg (theArgVec[anArgIter]);
4571 TCollection_AsciiString aFlag (anArg);
4572 aFlag.LowerCase();
4573 if (aFlag == "-mousestart"
4574 || aFlag == "-mousefrom")
4575 {
4576 hasFlags = Standard_True;
4577 if (anArgIter + 2 >= theArgNb)
4578 {
4579 std::cout << "Error: wrong syntax at '" << anArg << "'\n";
4580 return 1;
4581 }
4582
4583 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4584 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4585 aView->StartRotation (anX, anY);
4586 }
4587 else if (aFlag == "-mousemove")
4588 {
4589 hasFlags = Standard_True;
4590 if (anArgIter + 2 >= theArgNb)
4591 {
4592 std::cout << "Error: wrong syntax at '" << anArg << "'\n";
4593 return 1;
4594 }
4595
4596 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
4597 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
4598 aView->Rotation (anX, anY);
4599 }
4600 else if (theArgNb != 4
4601 && theArgNb != 7)
4602 {
4603 std::cout << "Error: wrong syntax at '" << anArg << "'\n";
4604 return 1;
4605 }
4606 }
4607
4608 if (hasFlags)
4609 {
7fd59977 4610 return 0;
4af098ba 4611 }
4612 else if (theArgNb == 4)
4613 {
4614 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4615 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4616 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4617 aView->Rotate (anAX, anAY, anAZ);
4618 return 0;
4619 }
4620 else if (theArgNb == 7)
4621 {
4622 Standard_Real anAX = Draw::Atof (theArgVec[1]);
4623 Standard_Real anAY = Draw::Atof (theArgVec[2]);
4624 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
4625
4626 Standard_Real anX = Draw::Atof (theArgVec[4]);
4627 Standard_Real anY = Draw::Atof (theArgVec[5]);
4628 Standard_Real anZ = Draw::Atof (theArgVec[6]);
4629
4630 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
7fd59977 4631 return 0;
7fd59977 4632 }
4af098ba 4633
4634 std::cout << "Error: Invalid number of arguments\n";
4635 return 1;
7fd59977 4636}
4637
4638//==============================================================================
4639//function : VZoom
4640//purpose : View zoom in / out (relative to current zoom)
4641//==============================================================================
4642
4643static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4644 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4645 if ( V3dView.IsNull() ) {
4646 return 1;
4647 }
4648
4649 if ( argc == 2 ) {
91322f44 4650 Standard_Real coef = Draw::Atof(argv[1]);
7fd59977 4651 if ( coef <= 0.0 ) {
586db386 4652 di << argv[1] << "Invalid value\n";
7fd59977 4653 return 1;
4654 }
91322f44 4655 V3dView->SetZoom( Draw::Atof(argv[1]) );
7fd59977 4656 return 0;
4657 } else {
586db386 4658 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4659 return 1;
4660 }
4661}
4662
4663//==============================================================================
4664//function : VPan
4665//purpose : View panning (in pixels)
4666//==============================================================================
4667
4668static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
4669 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
4670 if ( V3dView.IsNull() ) return 1;
4671
4672 if ( argc == 3 ) {
91322f44 4673 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
7fd59977 4674 return 0;
4675 } else {
586db386 4676 di << argv[0] << " Invalid number of arguments\n";
7fd59977 4677 return 1;
4678 }
4679}
4680
49e1a5c7 4681//==============================================================================
4682//function : VPlace
4683//purpose : Place the point (in pixels) at the center of the window
4684//==============================================================================
4685static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
4686{
4687 Handle(V3d_View) aView = ViewerTest::CurrentView();
4688 if (aView.IsNull())
4689 {
4690 std::cerr << theArgs[0] << "Error: no active view." << std::endl;
4691 return 1;
4692 }
4693
4694 if (theArgNb != 3)
4695 {
4696 std::cerr << theArgs[0] << "Error: invalid number of arguments." << std::endl;
4697 return 1;
4698 }
4699
4700 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
4701
4702 return 0;
4703}
7fd59977 4704
71215351 4705static int VColorScale (Draw_Interpretor& theDI,
4706 Standard_Integer theArgNb,
4707 const char** theArgVec)
4708{
7fd59977 4709 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
71215351 4710 Handle(V3d_View) aView = ViewerTest::CurrentView();
4711 if (aContext.IsNull())
4712 {
4713 std::cout << "Error: no active view!\n";
4714 return 1;
7fd59977 4715 }
24a88697 4716 if (theArgNb <= 1)
4717 {
4718 std::cout << "Error: wrong syntax at command '" << theArgVec[0] << "'!\n";
4719 return 1;
4720 }
7fd59977 4721
4b3d6eb1 4722 Handle(AIS_ColorScale) aColorScale;
7a324550 4723 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
71215351 4724 {
4b3d6eb1 4725 // find existing object
4726 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
4727 if (aColorScale.IsNull())
7a324550 4728 {
4729 std::cout << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale!\n";
4730 return 1;
4731 }
4732 }
71215351 4733
7a324550 4734 if (theArgNb <= 2)
4735 {
4b3d6eb1 4736 if (aColorScale.IsNull())
4737 {
4738 std::cout << "Syntax error: colorscale with a given name does not exist.\n";
4739 return 1;
4740 }
4741
7a324550 4742 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
4b3d6eb1 4743 << "Min range: " << aColorScale->GetMin() << "\n"
4744 << "Max range: " << aColorScale->GetMax() << "\n"
4745 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
4746 << "Text height: " << aColorScale->GetTextHeight() << "\n"
4747 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
4748 << "Color scale title: " << aColorScale->GetTitle() << "\n"
71215351 4749 << "Label position: ";
4b3d6eb1 4750 switch (aColorScale->GetLabelPosition())
71215351 4751 {
4752 case Aspect_TOCSP_NONE:
4753 theDI << "None\n";
4754 break;
4755 case Aspect_TOCSP_LEFT:
4756 theDI << "Left\n";
4757 break;
4758 case Aspect_TOCSP_RIGHT:
4759 theDI << "Right\n";
4760 break;
4761 case Aspect_TOCSP_CENTER:
4762 theDI << "Center\n";
4763 break;
4764 }
4765 return 0;
4766 }
71215351 4767
4b3d6eb1 4768 if (aColorScale.IsNull())
4769 {
4770 aColorScale = new AIS_ColorScale();
4771 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4772 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4773 }
4774
4775 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
7a324550 4776 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
71215351 4777 {
4778 Standard_CString anArg = theArgVec[anArgIter];
4779 TCollection_AsciiString aFlag (anArg);
4780 aFlag.LowerCase();
4781 if (anUpdateTool.parseRedrawMode (aFlag))
4782 {
4783 continue;
4784 }
4785 else if (aFlag == "-range")
4786 {
4787 if (anArgIter + 3 >= theArgNb)
4788 {
4789 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4790 return 1;
4791 }
4792
4b3d6eb1 4793 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
4794 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
4795 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
4796 if (!aRangeMin.IsRealValue()
4797 || !aRangeMax.IsRealValue())
71215351 4798 {
4b3d6eb1 4799 std::cout << "Error: the range values should be real!\n";
71215351 4800 return 1;
4801 }
4b3d6eb1 4802 else if (!aNbIntervals.IsIntegerValue())
71215351 4803 {
4804 std::cout << "Error: the number of intervals should be integer!\n";
4805 return 1;
4806 }
4807
4b3d6eb1 4808 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
4809 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
71215351 4810 }
4811 else if (aFlag == "-font")
4812 {
4813 if (anArgIter + 1 >= theArgNb)
4814 {
4815 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4816 return 1;
4817 }
51740958 4818 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
4819 if (!aFontArg.IsIntegerValue())
71215351 4820 {
4821 std::cout << "Error: HeightFont value should be integer!\n";
4822 return 1;
4823 }
4824
4b3d6eb1 4825 aColorScale->SetTextHeight (aFontArg.IntegerValue());
71215351 4826 anArgIter += 1;
4827 }
4828 else if (aFlag == "-textpos")
4829 {
4830 if (anArgIter + 1 >= theArgNb)
4831 {
4832 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4833 return 1;
4834 }
4b3d6eb1 4835
51740958 4836 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
4837 aTextPosArg.LowerCase();
4b3d6eb1 4838 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
51740958 4839 if (aTextPosArg == "none")
71215351 4840 {
4841 aLabPosition = Aspect_TOCSP_NONE;
4842 }
51740958 4843 else if (aTextPosArg == "left")
71215351 4844 {
4845 aLabPosition = Aspect_TOCSP_LEFT;
4846 }
51740958 4847 else if (aTextPosArg == "right")
71215351 4848 {
4849 aLabPosition = Aspect_TOCSP_RIGHT;
4850 }
51740958 4851 else if (aTextPosArg == "center")
71215351 4852 {
4853 aLabPosition = Aspect_TOCSP_CENTER;
4854 }
4855 else
4856 {
51740958 4857 std::cout << "Error: unknown position '" << aTextPosArg << "'!\n";
71215351 4858 return 1;
4859 }
4b3d6eb1 4860 aColorScale->SetLabelPosition (aLabPosition);
71215351 4861 }
24a88697 4862 else if (aFlag == "-logarithmic"
4863 || aFlag == "-log")
4864 {
4865 if (anArgIter + 1 >= theArgNb)
4866 {
4867 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4868 return 1;
4869 }
4b3d6eb1 4870
24a88697 4871 Standard_Boolean IsLog;
4872 if (!ViewerTest::ParseOnOff(theArgVec[++anArgIter], IsLog))
4873 {
4874 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4875 return 1;
4876 }
4b3d6eb1 4877 aColorScale->SetLogarithmic (IsLog);
4878 }
4879 else if (aFlag == "-huerange"
4880 || aFlag == "-hue")
4881 {
4882 if (anArgIter + 2 >= theArgNb)
4883 {
4884 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4885 return 1;
4886 }
4887
4888 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
4889 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
4890 aColorScale->SetHueRange (aHueMin, aHueMax);
4891 }
4892 else if (aFlag == "-colorrange")
4893 {
4894 Quantity_Color aColorMin, aColorMax;
4895 Standard_Integer aNbParsed1 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4896 theArgVec + (anArgIter + 1),
4897 aColorMin);
4898 anArgIter += aNbParsed1;
4899 Standard_Integer aNbParsed2 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
4900 theArgVec + (anArgIter + 1),
4901 aColorMax);
4902 anArgIter += aNbParsed2;
4903 if (aNbParsed1 == 0
4904 || aNbParsed2 == 0)
4905 {
4906 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
4907 return 1;
4908 }
4909
4910 aColorScale->SetColorRange (aColorMin, aColorMax);
4911 }
4912 else if (aFlag == "-reversed"
4913 || aFlag == "-inverted"
4914 || aFlag == "-topdown"
4915 || aFlag == "-bottomup")
4916 {
4917 Standard_Boolean toEnable = Standard_True;
4918 if (anArgIter + 1 < theArgNb
4919 && ViewerTest::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
4920 {
4921 ++anArgIter;
4922 }
4923 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
4924 }
4925 else if (aFlag == "-smooth"
4926 || aFlag == "-smoothtransition")
4927 {
4928 Standard_Boolean toEnable = Standard_True;
4929 if (anArgIter + 1 < theArgNb
4930 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
4931 {
4932 ++anArgIter;
4933 }
4934 aColorScale->SetSmoothTransition (toEnable);
24a88697 4935 }
71215351 4936 else if (aFlag == "-xy")
4937 {
4938 if (anArgIter + 2 >= theArgNb)
4939 {
4940 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4941 return 1;
4942 }
4943
4b3d6eb1 4944 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
4945 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
4946 if (!anX.IsIntegerValue()
4947 || !anY.IsIntegerValue())
71215351 4948 {
b4b2ecca 4949 std::cout << "Error: coordinates should be integer values!\n";
71215351 4950 return 1;
4951 }
4952
4b3d6eb1 4953 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
b4b2ecca 4954 }
4955 else if (aFlag == "-width"
4b3d6eb1 4956 || aFlag == "-w"
4957 || aFlag == "-breadth")
b4b2ecca 4958 {
4959 if (anArgIter + 1 >= theArgNb)
4960 {
4961 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4962 return 1;
4963 }
4964
4b3d6eb1 4965 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
4966 if (!aBreadth.IsIntegerValue())
b4b2ecca 4967 {
4968 std::cout << "Error: a width should be an integer value!\n";
4969 return 1;
4970 }
4b3d6eb1 4971 aColorScale->SetBreadth (aBreadth.IntegerValue());
b4b2ecca 4972 }
4973 else if (aFlag == "-height"
4974 || aFlag == "-h")
4975 {
4976 if (anArgIter + 1 >= theArgNb)
4977 {
4978 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
4979 return 1;
4980 }
4981
4b3d6eb1 4982 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
4983 if (!aHeight.IsIntegerValue())
b4b2ecca 4984 {
4985 std::cout << "Error: a width should be an integer value!\n";
4986 return 1;
4987 }
4b3d6eb1 4988 aColorScale->SetHeight (aHeight.IntegerValue());
71215351 4989 }
4990 else if (aFlag == "-color")
4991 {
4b3d6eb1 4992 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 4993 {
4994 std::cout << "Error: wrong color type! Call -colors before to set user-specified colors!\n";
4995 return 1;
4996 }
4b3d6eb1 4997 else if (anArgIter + 2 >= theArgNb)
71215351 4998 {
4b3d6eb1 4999 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
5000 return 1;
71215351 5001 }
5002
4b3d6eb1 5003 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
71215351 5004 if (!anInd.IsIntegerValue())
5005 {
5006 std::cout << "Error: Index value should be integer!\n";
5007 return 1;
5008 }
4b3d6eb1 5009 const Standard_Integer anIndex = anInd.IntegerValue();
5010 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
71215351 5011 {
4b3d6eb1 5012 std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() <<"!\n";
71215351 5013 return 1;
5014 }
5015
4b3d6eb1 5016 Quantity_Color aColor;
5017 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
5018 theArgVec + (anArgIter + 1),
5019 aColor);
5020 if (aNbParsed == 0)
71215351 5021 {
4b3d6eb1 5022 std::cerr << "Error: wrong syntax at '" << anArg << "'\n";
71215351 5023 return 1;
5024 }
4b3d6eb1 5025 aColorScale->SetIntervalColor (aColor, anIndex);
5026 aColorScale->SetColorType (Aspect_TOCSD_USER);
5027 anArgIter += aNbParsed;
71215351 5028 }
5029 else if (aFlag == "-label")
5030 {
4b3d6eb1 5031 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
71215351 5032 {
5033 std::cout << "Error: wrong label type! Call -labels before to set user-specified labels!\n";
5034 return 1;
5035 }
5036 else if (anArgIter + 2 >= theArgNb)
5037 {
5038 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
5039 return 1;
5040 }
5041
5042 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
4b3d6eb1 5043 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
71215351 5044 {
4b3d6eb1 5045 std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() + 1 <<"!\n";
71215351 5046 return 1;
5047 }
5048
5049 TCollection_ExtendedString aText (theArgVec[anArgIter + 2]);
4b3d6eb1 5050 aColorScale->SetLabel (aText, anIndex);
5051 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 5052 anArgIter += 2;
5053 }
4b3d6eb1 5054 else if (aFlag == "-labelat"
5055 || aFlag == "-labat"
5056 || aFlag == "-labelatborder"
5057 || aFlag == "-labatborder"
5058 || aFlag == "-labelatcenter"
5059 || aFlag == "-labatcenter")
71215351 5060 {
4b3d6eb1 5061 Standard_Boolean toEnable = Standard_True;
5062 if (aFlag == "-labelat"
5063 || aFlag == "-labat")
71215351 5064 {
4b3d6eb1 5065 Standard_Integer aLabAtBorder = -1;
5066 if (++anArgIter >= theArgNb)
71215351 5067 {
4b3d6eb1 5068 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
5069 anAtBorder.LowerCase();
5070 if (anAtBorder == "border")
71215351 5071 {
4b3d6eb1 5072 aLabAtBorder = 1;
71215351 5073 }
4b3d6eb1 5074 else if (anAtBorder == "center")
71215351 5075 {
4b3d6eb1 5076 aLabAtBorder = 0;
71215351 5077 }
71215351 5078 }
4b3d6eb1 5079 if (aLabAtBorder == -1)
5080 {
5081 std::cout << "Syntax error at argument '" << anArg << "'!\n";
5082 return 1;
5083 }
5084 toEnable = (aLabAtBorder == 1);
5085 }
5086 else if (anArgIter + 1 < theArgNb
5087 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
5088 {
5089 ++anArgIter;
71215351 5090 }
4b3d6eb1 5091 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
5092 || aFlag == "-labatcenter"
5093 ? !toEnable
5094 : toEnable);
5095 }
5096 else if (aFlag == "-colors")
5097 {
5098 Aspect_SequenceOfColor aSeq;
5099 for (;;)
5100 {
5101 Quantity_Color aColor;
5102 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1),
5103 theArgVec + (anArgIter + 1),
5104 aColor);
5105 if (aNbParsed == 0)
5106 {
5107 break;
5108 }
5109 anArgIter += aNbParsed;
5110 aSeq.Append (aColor);
5111 }
5112 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
71215351 5113 {
5114 std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4b3d6eb1 5115 << aColorScale->GetNumberOfIntervals() << " intervals\n";
71215351 5116 return 1;
5117 }
5118
4b3d6eb1 5119 aColorScale->SetColors (aSeq);
5120 aColorScale->SetColorType (Aspect_TOCSD_USER);
71215351 5121 }
4b3d6eb1 5122 else if (aFlag == "-labels"
5123 || aFlag == "-freelabels")
71215351 5124 {
4b3d6eb1 5125 if (anArgIter + 1 >= theArgNb)
5126 {
5127 std::cout << "Syntax error at argument '" << anArg << "'!\n";
5128 return 1;
5129 }
5130
5131 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
5132 ? aColorScale->GetNumberOfIntervals() + 1
5133 : aColorScale->GetNumberOfIntervals();
5134 if (aFlag == "-freelabels")
5135 {
5136 ++anArgIter;
5137 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
5138 }
5139 if (anArgIter + aNbLabels >= theArgNb)
71215351 5140 {
4b3d6eb1 5141 std::cout << "Error: not enough arguments! " << aNbLabels << " text labels are expected.\n";
71215351 5142 return 1;
5143 }
5144
5145 TColStd_SequenceOfExtendedString aSeq;
4b3d6eb1 5146 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
71215351 5147 {
4b3d6eb1 5148 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter]));
71215351 5149 }
4b3d6eb1 5150 aColorScale->SetLabels (aSeq);
5151 aColorScale->SetLabelType (Aspect_TOCSD_USER);
71215351 5152 }
5153 else if (aFlag == "-title")
5154 {
5155 if (anArgIter + 1 >= theArgNb)
5156 {
5157 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
5158 return 1;
5159 }
5160
5161 Standard_Boolean isTwoArgs = Standard_False;
5162 if (anArgIter + 2 < theArgNb)
5163 {
5164 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
5165 aSecondArg.LowerCase();
4b3d6eb1 5166 Standard_DISABLE_DEPRECATION_WARNINGS
71215351 5167 if (aSecondArg == "none")
5168 {
4b3d6eb1 5169 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
71215351 5170 isTwoArgs = Standard_True;
5171 }
5172 else if (aSecondArg == "left")
5173 {
4b3d6eb1 5174 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
71215351 5175 isTwoArgs = Standard_True;
5176 }
5177 else if (aSecondArg == "right")
5178 {
4b3d6eb1 5179 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
71215351 5180 isTwoArgs = Standard_True;
5181 }
5182 else if (aSecondArg == "center")
5183 {
4b3d6eb1 5184 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
71215351 5185 isTwoArgs = Standard_True;
5186 }
4b3d6eb1 5187 Standard_ENABLE_DEPRECATION_WARNINGS
71215351 5188 }
5189
4b3d6eb1 5190 aColorScale->SetTitle (theArgVec[anArgIter + 1]);
71215351 5191 if (isTwoArgs)
5192 {
5193 anArgIter += 1;
5194 }
5195 anArgIter += 1;
5196 }
5197 else if (aFlag == "-demoversion"
5198 || aFlag == "-demo")
5199 {
4b3d6eb1 5200 aColorScale->SetPosition (0, 0);
5201 aColorScale->SetTextHeight (16);
5202 aColorScale->SetRange (0.0, 100.0);
5203 aColorScale->SetNumberOfIntervals (10);
5204 aColorScale->SetBreadth (0);
5205 aColorScale->SetHeight (0);
5206 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
5207 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
5208 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
71215351 5209 }
d5514578 5210 else if (aFlag == "-findcolor")
5211 {
5212 if (anArgIter + 1 >= theArgNb)
5213 {
5214 std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n";
5215 return 1;
5216 }
5217
5218 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
5219
5220 if (!anArg1.IsRealValue())
5221 {
5222 std::cout << "Error: the value should be real!\n";
5223 return 1;
5224 }
5225
5226 Quantity_Color aColor;
4b3d6eb1 5227 aColorScale->FindColor (anArg1.RealValue(), aColor);
d5514578 5228 theDI << Quantity_Color::StringName (aColor.Name());
5229 return 0;
5230 }
71215351 5231 else
5232 {
5233 std::cout << "Error: wrong syntax at " << anArg << " - unknown argument!\n";
5234 return 1;
5235 }
5236 }
4b3d6eb1 5237
5238 Standard_Integer aWinWidth = 0, aWinHeight = 0;
5239 aView->Window()->Size (aWinWidth, aWinHeight);
5240 if (aColorScale->GetBreadth() == 0)
b4b2ecca 5241 {
4b3d6eb1 5242 aColorScale->SetBreadth (aWinWidth);
b4b2ecca 5243 }
4b3d6eb1 5244 if (aColorScale->GetHeight() == 0)
5245 {
5246 aColorScale->SetHeight (aWinHeight);
5247 }
5248 aColorScale->SetToUpdate();
5249 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
7fd59977 5250 return 0;
5251}
5252
5253//==============================================================================
5254//function : VGraduatedTrihedron
a79f67f8 5255//purpose : Displays or hides a graduated trihedron
7fd59977 5256//==============================================================================
a79f67f8 5257static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
5258 Quantity_Color& theColor)
13a22457 5259{
a79f67f8 5260 Quantity_NameOfColor aColorName;
5261 TCollection_AsciiString aVal = theValue;
5262 aVal.UpperCase();
5263 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
13a22457 5264 {
a79f67f8 5265 return Standard_False;
13a22457 5266 }
a79f67f8 5267 theColor = Quantity_Color (aColorName);
5268 return Standard_True;
13a22457
S
5269}
5270
a79f67f8 5271static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
7fd59977 5272{
a79f67f8 5273 if (theArgNum < 2)
13a22457 5274 {
a79f67f8 5275 std::cout << theArgs[0] << " error: wrong number of parameters. Type 'help"
5276 << theArgs[0] <<"' for more information.\n";
5277 return 1; //TCL_ERROR
13a22457 5278 }
7fd59977 5279
a79f67f8 5280 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
5281 TCollection_AsciiString aParseKey;
5282 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
5283 {
5284 TCollection_AsciiString anArg (theArgs [anArgIt]);
5285
5286 if (anArg.Value (1) == '-' && !anArg.IsRealValue())
5287 {
5288 aParseKey = anArg;
5289 aParseKey.Remove (1);
5290 aParseKey.LowerCase();
5291 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
5292 continue;
5293 }
13a22457 5294
a79f67f8 5295 if (aParseKey.IsEmpty())
5296 {
5297 continue;
5298 }
5299
5300 aMapOfArgs(aParseKey)->Append (anArg);
5301 }
5302
5303 // Check parameters
5304 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
5305 aMapIt.More(); aMapIt.Next())
7fd59977 5306 {
a79f67f8 5307 const TCollection_AsciiString& aKey = aMapIt.Key();
5308 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
5309
5310 // Bool key, without arguments
5311 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
5312 && anArgs->IsEmpty())
5313 {
5314 continue;
5315 }
5316
5317 // One argument
5318 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
5319 && anArgs->Length() == 1)
5320 {
5321 continue;
5322 }
5323
5324 // On/off arguments
5325 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
5326 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
536d98e2 5327 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
5328 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
a79f67f8 5329 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
5330 {
5331 continue;
5332 }
5333
5334 // One string argument
5335 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
5336 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
5337 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
5338 {
5339 continue;
5340 }
5341
5342 // One integer argument
5343 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
5344 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
5345 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
5346 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
5347 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
5348 {
5349 continue;
5350 }
5351
5352 // One real argument
5353 if ( aKey.IsEqual ("arrowlength")
5354 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue()))
5355 {
5356 continue;
5357 }
5358
5359 // Two string arguments
5360 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
5361 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue())
13a22457 5362 {
a79f67f8 5363 continue;
13a22457 5364 }
a79f67f8 5365
5366 TCollection_AsciiString aLowerKey;
5367 aLowerKey = "-";
5368 aLowerKey += aKey;
5369 aLowerKey.LowerCase();
5370 std::cout << theArgs[0] << ": " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n";
5371 std::cout << "Type help for more information.\n";
5372 return 1;
7fd59977 5373 }
5374
a79f67f8 5375 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5376 if (anAISContext.IsNull())
5377 {
586db386 5378 std::cout << theArgs[0] << ": please use 'vinit' command to initialize view.\n";
a79f67f8 5379 return 1;
5380 }
7fd59977 5381
a79f67f8 5382 Standard_Boolean toDisplay = Standard_True;
5383 Quantity_Color aColor;
5384 Graphic3d_GraduatedTrihedron aTrihedronData;
5385 // Process parameters
5386 Handle(TColStd_HSequenceOfAsciiString) aValues;
5387 if (aMapOfArgs.Find ("off", aValues))
7fd59977 5388 {
a79f67f8 5389 toDisplay = Standard_False;
5390 }
13a22457 5391
a79f67f8 5392 // AXES NAMES
5393 if (aMapOfArgs.Find ("xname", aValues))
5394 {
5395 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
5396 }
5397 if (aMapOfArgs.Find ("yname", aValues))
5398 {
5399 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
5400 }
5401 if (aMapOfArgs.Find ("zname", aValues))
5402 {
5403 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
5404 }
5405 if (aMapOfArgs.Find ("xdrawname", aValues))
5406 {
536d98e2 5407 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5408 }
5409 if (aMapOfArgs.Find ("ydrawname", aValues))
5410 {
536d98e2 5411 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5412 }
5413 if (aMapOfArgs.Find ("zdrawname", aValues))
5414 {
536d98e2 5415 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
a79f67f8 5416 }
5417 if (aMapOfArgs.Find ("xnameoffset", aValues))
5418 {
5419 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5420 }
5421 if (aMapOfArgs.Find ("ynameoffset", aValues))
5422 {
5423 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5424 }
5425 if (aMapOfArgs.Find ("znameoffset", aValues))
5426 {
5427 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
5428 }
13a22457 5429
a79f67f8 5430 // COLORS
5431 if (aMapOfArgs.Find ("xnamecolor", aValues))
5432 {
5433 if (!GetColor (aValues->Value(1), aColor))
13a22457 5434 {
a79f67f8 5435 std::cout << theArgs[0] << "error: -xnamecolor wrong color name.\n";
5436 return 1;
13a22457 5437 }
a79f67f8 5438 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
5439 }
5440 if (aMapOfArgs.Find ("ynamecolor", aValues))
5441 {
5442 if (!GetColor (aValues->Value(1), aColor))
13a22457 5443 {
a79f67f8 5444 std::cout << theArgs[0] << "error: -ynamecolor wrong color name.\n";
5445 return 1;
5446 }
5447 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
5448 }
5449 if (aMapOfArgs.Find ("znamecolor", aValues))
5450 {
5451 if (!GetColor (aValues->Value(1), aColor))
5452 {
5453 std::cout << theArgs[0] << "error: -znamecolor wrong color name.\n";
5454 return 1;
5455 }
5456 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
5457 }
5458 if (aMapOfArgs.Find ("xcolor", aValues))
5459 {
5460 if (!GetColor (aValues->Value(1), aColor))
5461 {
5462 std::cout << theArgs[0] << "error: -xcolor wrong color name.\n";
5463 return 1;
5464 }
5465 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
5466 }
5467 if (aMapOfArgs.Find ("ycolor", aValues))
5468 {
5469 if (!GetColor (aValues->Value(1), aColor))
5470 {
5471 std::cout << theArgs[0] << "error: -ycolor wrong color name.\n";
5472 return 1;
5473 }
5474 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
5475 }
5476 if (aMapOfArgs.Find ("zcolor", aValues))
5477 {
5478 if (!GetColor (aValues->Value(1), aColor))
5479 {
5480 std::cout << theArgs[0] << "error: -zcolor wrong color name.\n";
5481 return 1;
5482 }
5483 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
5484 }
5485
5486 // TICKMARKS
5487 if (aMapOfArgs.Find ("xticks", aValues))
5488 {
536d98e2 5489 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5490 }
5491 if (aMapOfArgs.Find ("yticks", aValues))
5492 {
536d98e2 5493 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5494 }
5495 if (aMapOfArgs.Find ("zticks", aValues))
5496 {
536d98e2 5497 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
a79f67f8 5498 }
5499 if (aMapOfArgs.Find ("xticklength", aValues))
5500 {
536d98e2 5501 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5502 }
5503 if (aMapOfArgs.Find ("yticklength", aValues))
5504 {
536d98e2 5505 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5506 }
5507 if (aMapOfArgs.Find ("zticklength", aValues))
5508 {
536d98e2 5509 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
a79f67f8 5510 }
5511 if (aMapOfArgs.Find ("xdrawticks", aValues))
5512 {
536d98e2 5513 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5514 }
5515 if (aMapOfArgs.Find ("ydrawticks", aValues))
5516 {
536d98e2 5517 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5518 }
5519 if (aMapOfArgs.Find ("zdrawticks", aValues))
5520 {
536d98e2 5521 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
a79f67f8 5522 }
5523
5524 // VALUES
5525 if (aMapOfArgs.Find ("xdrawvalues", aValues))
5526 {
536d98e2 5527 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5528 }
5529 if (aMapOfArgs.Find ("ydrawvalues", aValues))
5530 {
536d98e2 5531 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5532 }
5533 if (aMapOfArgs.Find ("zdrawvalues", aValues))
5534 {
536d98e2 5535 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
a79f67f8 5536 }
5537 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
5538 {
5539 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5540 }
5541 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
5542 {
5543 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5544 }
5545 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
5546 {
5547 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
5548 }
5549
5550 // ARROWS
5551 if (aMapOfArgs.Find ("arrowlength", aValues))
5552 {
536d98e2 5553 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
a79f67f8 5554 }
5555
5556 // FONTS
5557 if (aMapOfArgs.Find ("namefont", aValues))
5558 {
5559 aTrihedronData.SetNamesFont (aValues->Value(1));
5560 }
5561 if (aMapOfArgs.Find ("valuesfont", aValues))
5562 {
5563 aTrihedronData.SetValuesFont (aValues->Value(1));
5564 }
5565
536d98e2 5566 if (aMapOfArgs.Find ("drawgrid", aValues))
5567 {
5568 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
5569 }
5570 if (aMapOfArgs.Find ("drawaxes", aValues))
5571 {
5572 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
5573 }
5574
a79f67f8 5575 // The final step: display of erase trihedron
5576 if (toDisplay)
5577 {
5578 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
13a22457 5579 }
7fd59977 5580 else
a79f67f8 5581 {
5582 ViewerTest::CurrentView()->GraduatedTrihedronErase();
5583 }
7fd59977 5584
5585 ViewerTest::GetAISContext()->UpdateCurrentViewer();
a79f67f8 5586 ViewerTest::CurrentView()->Redraw();
13a22457 5587
7fd59977 5588 return 0;
5589}
5590
3bffef55 5591//==============================================================================
5592//function : VTile
5593//purpose :
5594//==============================================================================
5595static int VTile (Draw_Interpretor& theDI,
5596 Standard_Integer theArgNb,
5597 const char** theArgVec)
5598{
5599 Handle(V3d_View) aView = ViewerTest::CurrentView();
5600 if (aView.IsNull())
5601 {
5602 std::cerr << "Error: no active viewer.\n";
5603 return 1;
5604 }
5605
5606 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
5607 if (theArgNb < 2)
5608 {
5609 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
5610 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
5611 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
5612 return 0;
5613 }
5614
5615 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
5616 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5617 {
5618 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5619 anArg.LowerCase();
5620 if (anArg == "-lowerleft"
5621 || anArg == "-upperleft")
5622 {
5623 if (anArgIter + 3 < theArgNb)
5624 {
5625 std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
5626 return 1;
5627 }
5628 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
5629 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5630 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5631 }
5632 else if (anArg == "-total"
5633 || anArg == "-totalsize"
5634 || anArg == "-viewsize")
5635 {
5636 if (anArgIter + 3 < theArgNb)
5637 {
5638 std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
5639 return 1;
5640 }
5641 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5642 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5643 if (aTile.TotalSize.x() < 1
5644 || aTile.TotalSize.y() < 1)
5645 {
5646 std::cerr << "Error: total size is incorrect.\n";
5647 return 1;
5648 }
5649 }
5650 else if (anArg == "-tilesize")
5651 {
5652 if (anArgIter + 3 < theArgNb)
5653 {
5654 std::cerr << "Syntax error at '" << theArgVec[anArgIter] << "'.\n";
5655 return 1;
5656 }
5657
5658 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
5659 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
5660 if (aTile.TileSize.x() < 1
5661 || aTile.TileSize.y() < 1)
5662 {
5663 std::cerr << "Error: tile size is incorrect.\n";
5664 return 1;
5665 }
5666 }
5667 else if (anArg == "-unset")
5668 {
5669 aView->Camera()->SetTile (Graphic3d_CameraTile());
5670 aView->Redraw();
5671 return 0;
5672 }
5673 }
5674
5675 if (aTile.TileSize.x() < 1
5676 || aTile.TileSize.y() < 1)
5677 {
5678 std::cerr << "Error: tile size is undefined.\n";
5679 return 1;
5680 }
5681 else if (aTile.TotalSize.x() < 1
5682 || aTile.TotalSize.y() < 1)
5683 {
5684 std::cerr << "Error: total size is undefined.\n";
5685 return 1;
5686 }
5687
5688 aView->Camera()->SetTile (aTile);
5689 aView->Redraw();
5690 return 0;
5691}
5692
7c3ef2f7 5693//! Format ZLayer ID.
5694inline const char* formZLayerId (const Standard_Integer theLayerId)
5695{
5696 switch (theLayerId)
5697 {
5698 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
5699 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
5700 case Graphic3d_ZLayerId_Top: return "[TOP]";
5701 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
5702 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
5703 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
5704 }
5705 return "";
5706}
5707
5708//! Print the ZLayer information.
5709inline void printZLayerInfo (Draw_Interpretor& theDI,
5710 const Graphic3d_ZLayerSettings& theLayer)
5711{
5712 if (!theLayer.Name().IsEmpty())
5713 {
5714 theDI << " Name: " << theLayer.Name() << "\n";
5715 }
5716 if (theLayer.IsImmediate())
5717 {
5718 theDI << " Immediate: TRUE\n";
5719 }
5720 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4ecf34cc 5721 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
5722 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
7c3ef2f7 5723 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
5724 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
5725 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
5726 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
5727 {
5728 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
5729 }
5730}
5731
59f45b7c 5732//==============================================================================
5733//function : VZLayer
5734//purpose : Test z layer operations for v3d viewer
5735//==============================================================================
7c3ef2f7 5736static int VZLayer (Draw_Interpretor& theDI,
5737 Standard_Integer theArgNb,
5738 const char** theArgVec)
59f45b7c 5739{
7c3ef2f7 5740 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
59f45b7c 5741 if (aContextAIS.IsNull())
5742 {
7c3ef2f7 5743 std::cout << "No active viewer!\n";
59f45b7c 5744 return 1;
5745 }
5746
5747 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
7c3ef2f7 5748 if (theArgNb < 2)
59f45b7c 5749 {
7c3ef2f7 5750 TColStd_SequenceOfInteger aLayers;
5751 aViewer->GetAllZLayers (aLayers);
5752 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5753 {
5754 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
5755 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
5756 printZLayerInfo (theDI, aSettings);
5757 }
59f45b7c 5758 return 1;
5759 }
5760
7c3ef2f7 5761 Standard_Integer anArgIter = 1;
5762 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5763 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
5764 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
59f45b7c 5765 {
7c3ef2f7 5766 ++anArgIter;
5767 }
59f45b7c 5768
7c3ef2f7 5769 {
55c8f0f7
BB
5770 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
5771 if (aFirstArg.IsIntegerValue())
c5751993 5772 {
7c3ef2f7 5773 ++anArgIter;
55c8f0f7 5774 aLayerId = aFirstArg.IntegerValue();
c5751993 5775 }
7c3ef2f7 5776 else
c5751993 5777 {
55c8f0f7 5778 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
7c3ef2f7 5779 {
55c8f0f7 5780 ++anArgIter;
7c3ef2f7 5781 }
c5751993 5782 }
7c3ef2f7 5783 }
c5751993 5784
7c3ef2f7 5785 for (; anArgIter < theArgNb; ++anArgIter)
5786 {
5787 // perform operation
5788 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5789 anArg.LowerCase();
5790 if (anUpdateTool.parseRedrawMode (anArg))
c5751993 5791 {
7c3ef2f7 5792 //
c5751993 5793 }
7c3ef2f7 5794 else if (anArg == "-add"
5795 || anArg == "add")
c5751993 5796 {
7c3ef2f7 5797 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
5798 if (!aViewer->AddZLayer (aLayerId))
5799 {
5800 std::cout << "Error: can not add a new z layer!\n";
5801 return 0;
5802 }
5803
5804 theDI << aLayerId;
c5751993 5805 }
7c3ef2f7 5806 else if (anArg == "-del"
5807 || anArg == "-delete"
5808 || anArg == "del")
c5751993 5809 {
7c3ef2f7 5810 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5811 {
5812 if (++anArgIter >= theArgNb)
5813 {
5814 std::cout << "Syntax error: id of z layer to remove is missing\n";
5815 return 1;
5816 }
5817
5818 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5819 }
5820
5821 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
5822 || aLayerId == Graphic3d_ZLayerId_Default
5823 || aLayerId == Graphic3d_ZLayerId_Top
5824 || aLayerId == Graphic3d_ZLayerId_Topmost
5825 || aLayerId == Graphic3d_ZLayerId_TopOSD
5826 || aLayerId == Graphic3d_ZLayerId_BotOSD)
5827 {
5828 std::cout << "Syntax error: standard Z layer can not be removed\n";
5829 return 1;
5830 }
5831
5832 // move all object displayed in removing layer to default layer
5833 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
5834 anObjIter.More(); anObjIter.Next())
5835 {
8f521168 5836 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
7c3ef2f7 5837 if (aPrs.IsNull()
5838 || aPrs->ZLayer() != aLayerId)
5839 {
5840 continue;
5841 }
5842 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
5843 }
5844
5845 if (!aViewer->RemoveZLayer (aLayerId))
5846 {
5847 std::cout << "Z layer can not be removed!\n";
5848 }
5849 else
5850 {
5851 theDI << aLayerId << " ";
5852 }
c5751993 5853 }
7c3ef2f7 5854 else if (anArg == "-get"
5855 || anArg == "get")
c5751993 5856 {
7c3ef2f7 5857 TColStd_SequenceOfInteger aLayers;
5858 aViewer->GetAllZLayers (aLayers);
5859 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
5860 {
5861 theDI << aLayeriter.Value() << " ";
5862 }
5863
5864 theDI << "\n";
c5751993 5865 }
7c3ef2f7 5866 else if (anArg == "-name")
c5751993 5867 {
7c3ef2f7 5868 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
c5751993 5869 {
7c3ef2f7 5870 std::cout << "Syntax error: id of Z layer is missing\n";
c5751993 5871 return 1;
5872 }
5873
7c3ef2f7 5874 if (++anArgIter >= theArgNb)
5875 {
5876 std::cout << "Syntax error: name is missing\n";
5877 return 1;
5878 }
c5751993 5879
7c3ef2f7 5880 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5881 aSettings.SetName (theArgVec[anArgIter]);
5882 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5883 }
7c3ef2f7 5884 else if (anArg == "-origin")
c5751993 5885 {
7c3ef2f7 5886 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5887 {
5888 std::cout << "Syntax error: id of Z layer is missing\n";
5889 return 1;
5890 }
5891
5892 if (anArgIter + 2 >= theArgNb)
5893 {
5894 std::cout << "Syntax error: origin coordinates are missing\n";
5895 return 1;
5896 }
5897
5898 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5899 gp_XYZ anOrigin;
5900 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
5901 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
5902 anOrigin.SetZ (0.0);
5903 if (anArgIter + 3 < theArgNb)
5904 {
5905 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
5906 anArgIter += 3;
5907 }
5908 else
5909 {
5910 anArgIter += 2;
5911 }
5912 aSettings.SetOrigin (anOrigin);
5913 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 5914 }
4ecf34cc 5915 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5916 && anArgIter + 1 < theArgNb
5917 && (anArg == "-cullingdistance"
5918 || anArg == "-cullingdist"
5919 || anArg == "-culldistance"
5920 || anArg == "-culldist"
5921 || anArg == "-distcull"
5922 || anArg == "-distculling"
5923 || anArg == "-distanceculling"))
5924 {
5925 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5926 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
5927 aSettings.SetCullingDistance (aDist);
5928 aViewer->SetZLayerSettings (aLayerId, aSettings);
5929 }
5930 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
5931 && anArgIter + 1 < theArgNb
5932 && (anArg == "-cullingsize"
5933 || anArg == "-cullsize"
5934 || anArg == "-sizecull"
5935 || anArg == "-sizeculling"))
5936 {
5937 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5938 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
5939 aSettings.SetCullingSize (aSize);
5940 aViewer->SetZLayerSettings (aLayerId, aSettings);
5941 }
7c3ef2f7 5942 else if (anArg == "-settings"
5943 || anArg == "settings")
c5751993 5944 {
7c3ef2f7 5945 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5946 {
5947 if (++anArgIter >= theArgNb)
5948 {
5949 std::cout << "Syntax error: id of Z layer is missing\n";
5950 return 1;
5951 }
5952
5953 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5954 }
5955
5956 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5957 printZLayerInfo (theDI, aSettings);
c5751993 5958 }
7c3ef2f7 5959 else if (anArg == "-enable"
5960 || anArg == "enable"
5961 || anArg == "-disable"
5962 || anArg == "disable")
83da37b1 5963 {
7c3ef2f7 5964 const Standard_Boolean toEnable = anArg == "-enable"
5965 || anArg == "enable";
5966 if (++anArgIter >= theArgNb)
5967 {
5968 std::cout << "Syntax error: option name is missing\n";
5969 return 1;
5970 }
c5751993 5971
7c3ef2f7 5972 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
5973 aSubOp.LowerCase();
5974 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
5975 {
5976 if (++anArgIter >= theArgNb)
5977 {
5978 std::cout << "Syntax error: id of Z layer is missing\n";
5979 return 1;
5980 }
c5751993 5981
7c3ef2f7 5982 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
5983 }
c5751993 5984
7c3ef2f7 5985 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
5986 if (aSubOp == "depthtest"
5987 || aSubOp == "test")
5988 {
5989 aSettings.SetEnableDepthTest (toEnable);
5990 }
5991 else if (aSubOp == "depthwrite"
5992 || aSubOp == "write")
5993 {
5994 aSettings.SetEnableDepthWrite (toEnable);
5995 }
5996 else if (aSubOp == "depthclear"
5997 || aSubOp == "clear")
5998 {
5999 aSettings.SetClearDepth (toEnable);
6000 }
6001 else if (aSubOp == "depthoffset"
6002 || aSubOp == "offset")
6003 {
6004 Graphic3d_PolygonOffset aParams;
6005 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
6006 if (toEnable)
6007 {
6008 if (anArgIter + 2 >= theArgNb)
6009 {
6010 std::cout << "Syntax error: factor and units values for depth offset are missing\n";
6011 return 1;
6012 }
c5751993 6013
7c3ef2f7 6014 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
6015 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
6016 }
6017 aSettings.SetPolygonOffset (aParams);
6018 }
6019 else if (aSubOp == "positiveoffset"
6020 || aSubOp == "poffset")
6021 {
6022 if (toEnable)
6023 {
6024 aSettings.SetDepthOffsetPositive();
6025 }
6026 else
6027 {
6028 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
6029 }
6030 }
6031 else if (aSubOp == "negativeoffset"
6032 || aSubOp == "noffset")
6033 {
6034 if (toEnable)
6035 {
6036 aSettings.SetDepthOffsetNegative();
6037 }
6038 else
6039 {
6040 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
6041 }
6042 }
6043 else if (aSubOp == "textureenv")
6044 {
6045 aSettings.SetEnvironmentTexture (toEnable);
6046 }
6047
6048 aViewer->SetZLayerSettings (aLayerId, aSettings);
c5751993 6049 }
7c3ef2f7 6050 else
83da37b1 6051 {
7c3ef2f7 6052 std::cout << "Syntax error: unknown option " << theArgVec[anArgIter] << "\n";
6053 return 1;
83da37b1 6054 }
59f45b7c 6055 }
6056
6057 return 0;
6058}
6059
c357e426 6060// The interactive presentation of 2d layer item
6061// for "vlayerline" command it provides a presentation of
6062// line with user-defined linewidth, linetype and transparency.
61b0191c 6063class V3d_LineItem : public AIS_InteractiveObject
20637bd2 6064{
6065public:
6066 // CASCADE RTTI
92efcf78 6067 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4fe56619 6068
20637bd2 6069 // constructor
6070 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
6071 Standard_Real X2, Standard_Real Y2,
20637bd2 6072 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
6073 Standard_Real theWidth = 0.5,
6074 Standard_Real theTransp = 1.0);
6075
61b0191c 6076 private:
6077
6078 void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
6079 const Handle(Prs3d_Presentation)& thePresentation,
79104795 6080 const Standard_Integer theMode) Standard_OVERRIDE;
61b0191c 6081
6082 void ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/,
79104795 6083 const Standard_Integer /*aMode*/) Standard_OVERRIDE
6084 {}
20637bd2 6085
6086private:
6087
6088 Standard_Real myX1, myY1, myX2, myY2;
eafb234b 6089 Aspect_TypeOfLine myType;
20637bd2 6090 Standard_Real myWidth;
20637bd2 6091};
6092
20637bd2 6093// default constructor for line item
4fe56619 6094V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
20637bd2 6095 Standard_Real X2, Standard_Real Y2,
20637bd2 6096 Aspect_TypeOfLine theType,
6097 Standard_Real theWidth,
6098 Standard_Real theTransp) :
61b0191c 6099 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
6100 myType(theType), myWidth(theWidth)
20637bd2 6101{
61b0191c 6102 SetTransparency (1-theTransp);
20637bd2 6103}
6104
6105// render line
61b0191c 6106void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
6107 const Handle(Prs3d_Presentation)& thePresentation,
6108 const Standard_Integer /*theMode*/)
20637bd2 6109{
61b0191c 6110 thePresentation->Clear();
6111 Quantity_Color aColor (1.0, 0, 0, Quantity_TOC_RGB);
6112 Standard_Integer aWidth, aHeight;
6113 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
6114 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
6115 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
6116 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
6117 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
6118 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
6119 aGroup->SetPrimitivesAspect (anAspect->Aspect());
6120 aGroup->AddPrimitiveArray (aPrim);
20637bd2 6121}
6122
6123//=============================================================================
6124//function : VLayerLine
6125//purpose : Draws line in the v3d view layer with given attributes: linetype,
6126// : linewidth, transparency coefficient
6127//============================================================================
6128static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
6129{
6130 // get the active view
6131 Handle(V3d_View) aView = ViewerTest::CurrentView();
6132 if (aView.IsNull())
6133 {
6134 di << "Call vinit before!\n";
6135 return 1;
6136 }
6137 else if (argc < 5)
6138 {
6139 di << "Use: " << argv[0];
6140 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
6141 di << " linetype : { 0 | 1 | 2 | 3 } \n";
6142 di << " 0 - solid \n";
6143 di << " 1 - dashed \n";
6144 di << " 2 - dot \n";
6145 di << " 3 - dashdot\n";
6146 di << " transparency : { 0.0 - 1.0 } \n";
6147 di << " 0.0 - transparent\n";
6148 di << " 1.0 - visible \n";
6149 return 1;
6150 }
6151
61b0191c 6152 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
20637bd2 6153 // get the input params
91322f44 6154 Standard_Real X1 = Draw::Atof(argv[1]);
6155 Standard_Real Y1 = Draw::Atof(argv[2]);
6156 Standard_Real X2 = Draw::Atof(argv[3]);
6157 Standard_Real Y2 = Draw::Atof(argv[4]);
20637bd2 6158
3a4a3962 6159 Standard_Real aWidth = 0.5;
6160 Standard_Real aTransparency = 1.0;
20637bd2 6161
6162 // has width
6163 if (argc > 5)
91322f44 6164 aWidth = Draw::Atof(argv[5]);
20637bd2 6165
3a4a3962 6166 // select appropriate line type
6167 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
6168 if (argc > 6
6169 && !ViewerTest::ParseLineType (argv[6], aLineType))
6170 {
6171 std::cout << "Syntax error: unknown line type '" << argv[6] << "'\n";
6172 return 1;
6173 }
20637bd2 6174
6175 // has transparency
6176 if (argc > 7)
6177 {
91322f44 6178 aTransparency = Draw::Atof(argv[7]);
4fe56619 6179 if (aTransparency < 0 || aTransparency > 1.0)
20637bd2 6180 aTransparency = 1.0;
6181 }
6182
61b0191c 6183 static Handle (V3d_LineItem) aLine;
6184 if (!aLine.IsNull())
25289ec1 6185 {
0577ae8c 6186 aContext->Erase (aLine, Standard_False);
25289ec1 6187 }
61b0191c 6188 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
6189 aLineType, aWidth,
6190 aTransparency);
25289ec1 6191
778cd667 6192 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
61b0191c 6193 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
6194 aLine->SetToUpdate();
6195 aContext->Display (aLine, Standard_True);
25289ec1 6196
6197 return 0;
6198}
6199
61b0191c 6200
2bd4c032 6201//==============================================================================
6202//function : VGrid
6203//purpose :
6204//==============================================================================
6205
35e08fe8 6206static int VGrid (Draw_Interpretor& /*theDI*/,
2bd4c032 6207 Standard_Integer theArgNb,
6208 const char** theArgVec)
6209{
2bd4c032 6210 Handle(V3d_View) aView = ViewerTest::CurrentView();
6211 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6212 if (aView.IsNull() || aViewer.IsNull())
6213 {
79931835 6214 std::cerr << "Error: no active view\n";
2bd4c032 6215 return 1;
6216 }
6217
6218 Aspect_GridType aType = aViewer->GridType();
6219 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
79931835 6220 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
6221 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
6222 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
224f48fa 6223 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
79931835 6224 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2bd4c032 6225 {
79931835 6226 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6227 anArg.LowerCase();
6228 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
224f48fa 6229 {
6230 continue;
6231 }
79931835 6232 else if (anArgIter + 1 < theArgNb
6233 && anArg == "-type")
6234 {
6235 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6236 anArgNext.LowerCase();
6237 if (anArgNext == "r"
6238 || anArgNext == "rect"
6239 || anArgNext == "rectangular")
6240 {
6241 aType = Aspect_GT_Rectangular;
6242 }
6243 else if (anArgNext == "c"
6244 || anArgNext == "circ"
6245 || anArgNext == "circular")
6246 {
6247 aType = Aspect_GT_Circular;
6248 }
6249 else
6250 {
6251 std::cout << "Syntax error at '" << anArgNext << "'\n";
6252 return 1;
6253 }
6254 }
6255 else if (anArgIter + 1 < theArgNb
6256 && anArg == "-mode")
6257 {
6258 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6259 anArgNext.LowerCase();
6260 if (anArgNext == "l"
6261 || anArgNext == "line"
6262 || anArgNext == "lines")
6263 {
6264 aMode = Aspect_GDM_Lines;
6265 }
6266 else if (anArgNext == "p"
6267 || anArgNext == "point"
6268 || anArgNext == "points")
6269 {
6270 aMode = Aspect_GDM_Points;
6271 }
6272 else
6273 {
6274 std::cout << "Syntax error at '" << anArgNext << "'\n";
6275 return 1;
6276 }
6277 }
6278 else if (anArgIter + 2 < theArgNb
6279 && (anArg == "-origin"
6280 || anArg == "-orig"))
6281 {
6282 hasOrigin = true;
6283 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6284 Draw::Atof (theArgVec[anArgIter + 2]));
6285 anArgIter += 2;
6286 }
6287 else if (anArgIter + 2 < theArgNb
6288 && anArg == "-step")
6289 {
6290 hasStep = true;
6291 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6292 Draw::Atof (theArgVec[anArgIter + 2]));
6293 if (aNewStepXY.x() <= 0.0
6294 || aNewStepXY.y() <= 0.0)
6295 {
6296 std::cout << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'\n";
6297 return 1;
6298 }
6299 anArgIter += 2;
6300 }
6301 else if (anArgIter + 1 < theArgNb
6302 && (anArg == "-angle"
6303 || anArg == "-rotangle"
6304 || anArg == "-rotationangle"))
6305 {
6306 hasRotAngle = true;
6307 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
6308 }
6309 else if (anArgIter + 1 < theArgNb
6310 && (anArg == "-zoffset"
6311 || anArg == "-dz"))
6312 {
6313 hasZOffset = true;
6314 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
6315 }
6316 else if (anArgIter + 1 < theArgNb
6317 && anArg == "-radius")
6318 {
6319 hasSize = true;
6320 ++anArgIter;
6321 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
6322 if (aNewStepXY.x() <= 0.0)
6323 {
6324 std::cout << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'\n";
6325 return 1;
6326 }
6327 }
6328 else if (anArgIter + 2 < theArgNb
6329 && anArg == "-size")
6330 {
6331 hasSize = true;
6332 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
6333 Draw::Atof (theArgVec[anArgIter + 2]));
6334 if (aNewStepXY.x() <= 0.0
6335 || aNewStepXY.y() <= 0.0)
6336 {
6337 std::cout << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'\n";
6338 return 1;
6339 }
6340 anArgIter += 2;
6341 }
6342 else if (anArg == "r"
6343 || anArg == "rect"
6344 || anArg == "rectangular")
2bd4c032 6345 {
6346 aType = Aspect_GT_Rectangular;
6347 }
79931835 6348 else if (anArg == "c"
6349 || anArg == "circ"
6350 || anArg == "circular")
2bd4c032 6351 {
6352 aType = Aspect_GT_Circular;
6353 }
79931835 6354 else if (anArg == "l"
6355 || anArg == "line"
6356 || anArg == "lines")
2bd4c032 6357 {
6358 aMode = Aspect_GDM_Lines;
6359 }
79931835 6360 else if (anArg == "p"
6361 || anArg == "point"
6362 || anArg == "points")
2bd4c032 6363 {
6364 aMode = Aspect_GDM_Points;
6365 }
79931835 6366 else if (anArgIter + 1 >= theArgNb
6367 && anArg == "off")
2bd4c032 6368 {
6369 aViewer->DeactivateGrid();
6370 return 0;
6371 }
6372 else
6373 {
79931835 6374 std::cout << "Syntax error at '" << anArg << "'\n";
6375 return 1;
2bd4c032 6376 }
6377 }
6378
2bd4c032 6379 if (aType == Aspect_GT_Rectangular)
6380 {
79931835 6381 Graphic3d_Vec2d anOrigXY, aStepXY;
6382 Standard_Real aRotAngle = 0.0;
6383 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6384 if (hasOrigin)
6385 {
6386 anOrigXY = aNewOriginXY;
6387 }
6388 if (hasStep)
6389 {
6390 aStepXY = aNewStepXY;
6391 }
6392 if (hasRotAngle)
6393 {
6394 aRotAngle = aNewRotAngle;
6395 }
6396 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
6397 if (hasSize || hasZOffset)
2bd4c032 6398 {
79931835 6399 Graphic3d_Vec3d aSize;
6400 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
6401 if (hasSize)
6402 {
6403 aSize.x() = aNewSizeXY.x();
6404 aSize.y() = aNewSizeXY.y();
6405 }
6406 if (hasZOffset)
6407 {
6408 aSize.z() = aNewZOffset;
6409 }
6410 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
2bd4c032 6411 }
2bd4c032 6412 }
6413 else if (aType == Aspect_GT_Circular)
6414 {
79931835 6415 Graphic3d_Vec2d anOrigXY;
ee2be2a8 6416 Standard_Real aRadiusStep;
2bd4c032 6417 Standard_Integer aDivisionNumber;
79931835 6418 Standard_Real aRotAngle = 0.0;
6419 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6420 if (hasOrigin)
6421 {
6422 anOrigXY = aNewOriginXY;
6423 }
6424 if (hasStep)
6425 {
6426 aRadiusStep = aNewStepXY[0];
6427 aDivisionNumber = (int )aNewStepXY[1];
6428 if (aDivisionNumber < 1)
6429 {
6430 std::cout << "Syntax error: invalid division number '" << aNewStepXY[1] << "'\n";
6431 return 1;
6432 }
6433 }
6434 if (hasRotAngle)
2bd4c032 6435 {
79931835 6436 aRotAngle = aNewRotAngle;
2bd4c032 6437 }
6438
79931835 6439 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
6440 if (hasSize || hasZOffset)
6441 {
6442 Standard_Real aRadius = 0.0, aZOffset = 0.0;
6443 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
6444 if (hasSize)
6445 {
6446 aRadius = aNewSizeXY.x();
6447 if (aNewSizeXY.y() != 0.0)
6448 {
6449 std::cout << "Syntax error: circular size should be specified as radius\n";
6450 return 1;
6451 }
6452 }
6453 if (hasZOffset)
6454 {
6455 aZOffset = aNewZOffset;
6456 }
6457 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
6458 }
2bd4c032 6459 }
79931835 6460 aViewer->ActivateGrid (aType, aMode);
2bd4c032 6461 return 0;
6462}
6463
c40b7d58 6464//==============================================================================
6465//function : VPriviledgedPlane
6466//purpose :
6467//==============================================================================
6468
6469static int VPriviledgedPlane (Draw_Interpretor& theDI,
6470 Standard_Integer theArgNb,
6471 const char** theArgVec)
6472{
6473 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
6474 {
6475 std::cerr << "Error: wrong number of arguments! See usage:\n";
6476 theDI.PrintHelp (theArgVec[0]);
6477 return 1;
6478 }
6479
6480 // get the active viewer
6481 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
6482 if (aViewer.IsNull())
6483 {
6484 std::cerr << "Error: no active viewer. Please call vinit.\n";
6485 return 1;
6486 }
6487
6488 if (theArgNb == 1)
6489 {
6490 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
6491 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
6492 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
6493 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
6494 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
6495 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
6496 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
6497 return 0;
6498 }
6499
6500 Standard_Integer anArgIdx = 1;
6501 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
6502 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
6503 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
6504 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
6505 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
6506 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
6507
6508 gp_Ax3 aPriviledgedPlane;
6509 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
6510 gp_Dir aNorm (aNormX, aNormY, aNormZ);
6511 if (theArgNb > 7)
6512 {
6513 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
6514 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
6515 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
6516 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
6517 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
6518 }
6519 else
6520 {
6521 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
6522 }
6523
6524 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
6525
6526 return 0;
6527}
6528
f25b82d6 6529//==============================================================================
6530//function : VConvert
6531//purpose :
6532//==============================================================================
6533
6534static int VConvert (Draw_Interpretor& theDI,
6535 Standard_Integer theArgNb,
6536 const char** theArgVec)
6537{
6538 // get the active view
6539 Handle(V3d_View) aView = ViewerTest::CurrentView();
6540 if (aView.IsNull())
6541 {
c40b7d58 6542 std::cerr << "Error: no active view. Please call vinit.\n";
f25b82d6 6543 return 1;
6544 }
6545
6546 enum { Model, Ray, View, Window, Grid } aMode = Model;
6547
6548 // access coordinate arguments
6549 TColStd_SequenceOfReal aCoord;
6550 Standard_Integer anArgIdx = 1;
6551 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
6552 {
6553 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6554 if (!anArg.IsRealValue())
6555 {
6556 break;
6557 }
6558 aCoord.Append (anArg.RealValue());
6559 }
6560
6561 // non-numeric argument too early
6562 if (aCoord.IsEmpty())
6563 {
6564 std::cerr << "Error: wrong number of arguments! See usage:\n";
6565 theDI.PrintHelp (theArgVec[0]);
6566 return 1;
6567 }
6568
6569 // collect all other arguments and options
6570 for (; anArgIdx < theArgNb; ++anArgIdx)
6571 {
6572 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
6573 anArg.LowerCase();
6574 if (anArg == "window") aMode = Window;
6575 else if (anArg == "view") aMode = View;
6576 else if (anArg == "grid") aMode = Grid;
6577 else if (anArg == "ray") aMode = Ray;
6578 else
6579 {
6580 std::cerr << "Error: wrong argument " << anArg << "! See usage:\n";
6581 theDI.PrintHelp (theArgVec[0]);
6582 return 1;
6583 }
6584 }
6585
6586 // complete input checks
6587 if ((aCoord.Length() == 1 && theArgNb > 3) ||
6588 (aCoord.Length() == 2 && theArgNb > 4) ||
6589 (aCoord.Length() == 3 && theArgNb > 5))
6590 {
6591 std::cerr << "Error: wrong number of arguments! See usage:\n";
6592 theDI.PrintHelp (theArgVec[0]);
6593 return 1;
6594 }
6595
6596 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
6597 Standard_Integer aXYp[2] = {0, 0};
6598
6599 // convert one-dimensional coordinate
6600 if (aCoord.Length() == 1)
6601 {
6602 switch (aMode)
6603 {
ee2be2a8 6604 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
6605 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
f25b82d6 6606 default:
6607 std::cerr << "Error: wrong arguments! See usage:\n";
6608 theDI.PrintHelp (theArgVec[0]);
6609 return 1;
6610 }
6611 }
6612
6613 // convert 2D coordinates from projection or view reference space
6614 if (aCoord.Length() == 2)
6615 {
6616 switch (aMode)
6617 {
6618 case Model :
6619 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6620 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6621 return 0;
6622
6623 case View :
6624 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
6625 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
6626 return 0;
6627
6628 case Window :
ee2be2a8 6629 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
f25b82d6 6630 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6631 return 0;
6632
6633 case Grid :
6634 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
6635 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
6636 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6637 return 0;
6638
6639 case Ray :
6640 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
6641 (Standard_Integer) aCoord (2),
6642 aXYZ[0], aXYZ[1], aXYZ[2],
6643 aXYZ[3], aXYZ[4], aXYZ[5]);
6644 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
6645 return 0;
6646
6647 default:
6648 std::cerr << "Error: wrong arguments! See usage:\n";
6649 theDI.PrintHelp (theArgVec[0]);
6650 return 1;
6651 }
6652 }
6653
6654 // convert 3D coordinates from view reference space
6655 else if (aCoord.Length() == 3)
6656 {
6657 switch (aMode)
6658 {
6659 case Window :
6660 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
6661 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
6662 return 0;
6663
6664 case Grid :
6665 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
6666 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
6667 return 0;
6668
6669 default:
6670 std::cerr << "Error: wrong arguments! See usage:\n";
6671 theDI.PrintHelp (theArgVec[0]);
6672 return 1;
6673 }
6674 }
6675
6676 return 0;
6677}
6678
208e6839 6679//==============================================================================
6680//function : VFps
6681//purpose :
6682//==============================================================================
6683
6684static int VFps (Draw_Interpretor& theDI,
6685 Standard_Integer theArgNb,
6686 const char** theArgVec)
6687{
6688 // get the active view
6689 Handle(V3d_View) aView = ViewerTest::CurrentView();
6690 if (aView.IsNull())
6691 {
6692 std::cerr << "No active view. Please call vinit.\n";
6693 return 1;
6694 }
6695
e084dbbc 6696 Standard_Integer aFramesNb = -1;
6697 Standard_Real aDuration = -1.0;
6698 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
208e6839 6699 {
e084dbbc 6700 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6701 anArg.LowerCase();
6702 if (aDuration < 0.0
6703 && anArgIter + 1 < theArgNb
6704 && (anArg == "-duration"
6705 || anArg == "-dur"
6706 || anArg == "-time"))
6707 {
6708 aDuration = Draw::Atof (theArgVec[++anArgIter]);
6709 }
6710 else if (aFramesNb < 0
6711 && anArg.IsIntegerValue())
6712 {
6713 aFramesNb = anArg.IntegerValue();
6714 if (aFramesNb <= 0)
6715 {
6716 std::cerr << "Syntax error at '" << anArg << "'\n";
6717 return 1;
6718 }
6719 }
6720 else
6721 {
6722 std::cerr << "Syntax error at '" << anArg << "'\n";
6723 return 1;
6724 }
6725 }
6726 if (aFramesNb < 0 && aDuration < 0.0)
6727 {
6728 aFramesNb = 100;
208e6839 6729 }
6730
6731 // the time is meaningless for first call
6732 // due to async OpenGl rendering
6733 aView->Redraw();
6734
6735 // redraw view in loop to estimate average values
6736 OSD_Timer aTimer;
6737 aTimer.Start();
e084dbbc 6738 Standard_Integer aFrameIter = 1;
6739 for (;; ++aFrameIter)
208e6839 6740 {
6741 aView->Redraw();
e084dbbc 6742 if ((aFramesNb > 0
6743 && aFrameIter >= aFramesNb)
6744 || (aDuration > 0.0
6745 && aTimer.ElapsedTime() >= aDuration))
6746 {
6747 break;
6748 }
208e6839 6749 }
6750 aTimer.Stop();
6751 Standard_Real aCpu;
6752 const Standard_Real aTime = aTimer.ElapsedTime();
6753 aTimer.OSD_Chronometer::Show (aCpu);
6754
e084dbbc 6755 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
6756 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
208e6839 6757
6758 // return statistics
6759 theDI << "FPS: " << aFpsAver << "\n"
6760 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
6761
8c820969 6762 // compute additional statistics in ray-tracing mode
e084dbbc 6763 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
8c820969 6764 if (aParams.Method == Graphic3d_RM_RAYTRACING)
6765 {
e084dbbc 6766 Graphic3d_Vec2i aWinSize (0, 0);
6767 aView->Window()->Size (aWinSize.x(), aWinSize.y());
8c820969 6768
6769 // 1 shadow ray and 1 secondary ray pew each bounce
e084dbbc 6770 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
8c820969 6771 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
6772 }
6773
208e6839 6774 return 0;
6775}
6776
84e84755 6777//! Auxiliary function for parsing glsl dump level argument.
6778static Standard_Boolean parseGlslSourceFlag (Standard_CString theArg,
6779 OpenGl_ShaderProgramDumpLevel& theGlslDumpLevel)
6780{
6781 TCollection_AsciiString aTypeStr (theArg);
6782 aTypeStr.LowerCase();
6783 if (aTypeStr == "off"
6784 || aTypeStr == "0")
6785 {
6786 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6787 }
6788 else if (aTypeStr == "short")
6789 {
6790 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Short;
6791 }
6792 else if (aTypeStr == "full"
6793 || aTypeStr == "1")
6794 {
6795 theGlslDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6796 }
6797 else
6798 {
6799 return Standard_False;
6800 }
6801 return Standard_True;
6802}
6803
58655684 6804//==============================================================================
6805//function : VGlDebug
6806//purpose :
6807//==============================================================================
6808
6809static int VGlDebug (Draw_Interpretor& theDI,
6810 Standard_Integer theArgNb,
6811 const char** theArgVec)
6812{
aaf512f1 6813 Handle(OpenGl_GraphicDriver) aDriver;
6814 Handle(V3d_View) aView = ViewerTest::CurrentView();
6815 if (!aView.IsNull())
6816 {
6817 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aView->Viewer()->Driver());
6818 }
c87535af 6819 OpenGl_Caps* aDefCaps = &ViewerTest_myDefaultCaps;
6820 OpenGl_Caps* aCaps = !aDriver.IsNull() ? &aDriver->ChangeOptions() : NULL;
6821
58655684 6822 if (theArgNb < 2)
6823 {
c87535af 6824 TCollection_AsciiString aDebActive, aSyncActive;
6825 if (aCaps == NULL)
58655684 6826 {
c87535af 6827 aCaps = aDefCaps;
6828 }
6829 else
6830 {
6831 Standard_Boolean isActive = OpenGl_Context::CheckExtension ((const char* )::glGetString (GL_EXTENSIONS),
6832 "GL_ARB_debug_output");
6833 aDebActive = isActive ? " (active)" : " (inactive)";
6834 if (isActive)
6835 {
6836 // GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
6837 aSyncActive = ::glIsEnabled (0x8242) == GL_TRUE ? " (active)" : " (inactive)";
6838 }
58655684 6839 }
6840
84e84755 6841 TCollection_AsciiString aGlslCodeDebugStatus = TCollection_AsciiString()
6842 + "glslSourceCode: "
6843 + (aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Off
6844 ? "Off"
6845 : aCaps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short
6846 ? "Short"
6847 : "Full")
6848 + "\n";
6849 theDI << "debug: " << (aCaps->contextDebug ? "1" : "0") << aDebActive << "\n"
6850 << "sync: " << (aCaps->contextSyncDebug ? "1" : "0") << aSyncActive << "\n"
6851 << "glslWarn: " << (aCaps->glslWarnings ? "1" : "0") << "\n"
6852 << aGlslCodeDebugStatus
6853 << "extraMsg: " << (aCaps->suppressExtraMsg ? "0" : "1") << "\n";
58655684 6854 return 0;
6855 }
6856
c87535af 6857 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
aaf512f1 6858 {
c87535af 6859 Standard_CString anArg = theArgVec[anArgIter];
6860 TCollection_AsciiString anArgCase (anArg);
6861 anArgCase.LowerCase();
6862 Standard_Boolean toEnableDebug = Standard_True;
6863 if (anArgCase == "-glsl"
6864 || anArgCase == "-glslwarn"
6865 || anArgCase == "-glslwarns"
6866 || anArgCase == "-glslwarnings")
6867 {
6868 Standard_Boolean toShowWarns = Standard_True;
6869 if (++anArgIter < theArgNb
a5565a3c 6870 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toShowWarns))
c87535af 6871 {
6872 --anArgIter;
6873 }
6874 aDefCaps->glslWarnings = toShowWarns;
6875 if (aCaps != NULL)
6876 {
6877 aCaps->glslWarnings = toShowWarns;
6878 }
6879 }
6880 else if (anArgCase == "-extra"
6881 || anArgCase == "-extramsg"
6882 || anArgCase == "-extramessages")
6883 {
6884 Standard_Boolean toShow = Standard_True;
6885 if (++anArgIter < theArgNb
a5565a3c 6886 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toShow))
c87535af 6887 {
6888 --anArgIter;
6889 }
6890 aDefCaps->suppressExtraMsg = !toShow;
6891 if (aCaps != NULL)
6892 {
6893 aCaps->suppressExtraMsg = !toShow;
6894 }
6895 }
6896 else if (anArgCase == "-noextra"
6897 || anArgCase == "-noextramsg"
6898 || anArgCase == "-noextramessages")
6899 {
6900 Standard_Boolean toSuppress = Standard_True;
6901 if (++anArgIter < theArgNb
a5565a3c 6902 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toSuppress))
c87535af 6903 {
6904 --anArgIter;
6905 }
6906 aDefCaps->suppressExtraMsg = toSuppress;
6907 if (aCaps != NULL)
6908 {
6909 aCaps->suppressExtraMsg = toSuppress;
6910 }
6911 }
6912 else if (anArgCase == "-sync")
6913 {
6914 Standard_Boolean toSync = Standard_True;
6915 if (++anArgIter < theArgNb
a5565a3c 6916 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toSync))
c87535af 6917 {
6918 --anArgIter;
6919 }
6920 aDefCaps->contextSyncDebug = toSync;
6921 if (toSync)
6922 {
6923 aDefCaps->contextDebug = Standard_True;
6924 }
6925 }
84e84755 6926 else if (anArgCase == "-glslsourcecode"
6927 || anArgCase == "-glslcode")
6928 {
6929 OpenGl_ShaderProgramDumpLevel aGslsDumpLevel = OpenGl_ShaderProgramDumpLevel_Full;
6930 if (++anArgIter < theArgNb
6931 && !parseGlslSourceFlag (theArgVec[anArgIter], aGslsDumpLevel))
6932 {
6933 --anArgIter;
6934 }
6935 aDefCaps->glslDumpLevel = aGslsDumpLevel;
6936 if (aCaps != NULL)
6937 {
6938 aCaps->glslDumpLevel = aGslsDumpLevel;
6939 }
6940 }
c87535af 6941 else if (anArgCase == "-debug")
6942 {
6943 if (++anArgIter < theArgNb
a5565a3c 6944 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnableDebug))
c87535af 6945 {
6946 --anArgIter;
6947 }
6948 aDefCaps->contextDebug = toEnableDebug;
6949 }
a5565a3c 6950 else if (ViewerTest::ParseOnOff (anArg, toEnableDebug)
c87535af 6951 && (anArgIter + 1 == theArgNb))
6952 {
6953 // simple alias to turn on almost everything
6954 aDefCaps->contextDebug = toEnableDebug;
6955 aDefCaps->contextSyncDebug = toEnableDebug;
6956 aDefCaps->glslWarnings = toEnableDebug;
3b4c6945 6957 if (!toEnableDebug)
6958 {
6959 aDefCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6960 }
84e84755 6961 aDefCaps->suppressExtraMsg = !toEnableDebug;
6962 if (aCaps != NULL)
6963 {
6964 aCaps->contextDebug = toEnableDebug;
6965 aCaps->contextSyncDebug = toEnableDebug;
6966 aCaps->glslWarnings = toEnableDebug;
3b4c6945 6967 if (!toEnableDebug)
6968 {
6969 aCaps->glslDumpLevel = OpenGl_ShaderProgramDumpLevel_Off;
6970 }
84e84755 6971 aCaps->suppressExtraMsg = !toEnableDebug;
6972 }
c87535af 6973 }
6974 else
6975 {
6976 std::cout << "Error: wrong syntax at '" << anArg << "'\n";
6977 return 1;
6978 }
aaf512f1 6979 }
6980
58655684 6981 return 0;
6982}
208e6839 6983
6984//==============================================================================
6985//function : VVbo
6986//purpose :
6987//==============================================================================
6988
58655684 6989static int VVbo (Draw_Interpretor& theDI,
208e6839 6990 Standard_Integer theArgNb,
6991 const char** theArgVec)
6992{
58655684 6993 const Standard_Boolean toSet = (theArgNb > 1);
6994 const Standard_Boolean toUseVbo = toSet ? (Draw::Atoi (theArgVec[1]) == 0) : 1;
6995 if (toSet)
208e6839 6996 {
58655684 6997 ViewerTest_myDefaultCaps.vboDisable = toUseVbo;
208e6839 6998 }
6999
58655684 7000 // get the context
7001 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
7002 if (aContextAIS.IsNull())
208e6839 7003 {
58655684 7004 if (!toSet)
7005 {
7006 std::cerr << "No active view!\n";
7007 }
208e6839 7008 return 1;
7009 }
58655684 7010 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Driver());
7011 if (!aDriver.IsNull())
208e6839 7012 {
58655684 7013 if (!toSet)
7014 {
7015 theDI << (aDriver->Options().vboDisable ? "0" : "1") << "\n";
7016 }
7017 else
7018 {
7019 aDriver->ChangeOptions().vboDisable = toUseVbo;
7020 }
208e6839 7021 }
7022
208e6839 7023 return 0;
7024}
7025
a577aaab 7026//==============================================================================
7027//function : VCaps
7028//purpose :
7029//==============================================================================
7030
7031static int VCaps (Draw_Interpretor& theDI,
7032 Standard_Integer theArgNb,
7033 const char** theArgVec)
7034{
7035 OpenGl_Caps* aCaps = &ViewerTest_myDefaultCaps;
7036 Handle(OpenGl_GraphicDriver) aDriver;
8625ef7e 7037 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7038 if (!aContext.IsNull())
a577aaab 7039 {
8625ef7e 7040 aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Driver());
a577aaab 7041 aCaps = &aDriver->ChangeOptions();
7042 }
7043
7044 if (theArgNb < 2)
7045 {
7046 theDI << "VBO: " << (aCaps->vboDisable ? "0" : "1") << "\n";
7047 theDI << "Sprites: " << (aCaps->pntSpritesDisable ? "0" : "1") << "\n";
abe46077 7048 theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
8625ef7e 7049 theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
2a332745 7050 theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
f978241f 7051 theDI << "VSync: " << aCaps->swapInterval << "\n";
4e1523ef 7052 theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
f978241f 7053 theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
56689b27 7054 theDI << "WinBuffer: " << (aCaps->useSystemBuffer ? "1" : "0") << "\n";
a577aaab 7055 return 0;
7056 }
7057
8625ef7e 7058 ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
a577aaab 7059 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
7060 {
8625ef7e 7061 Standard_CString anArg = theArgVec[anArgIter];
7062 TCollection_AsciiString anArgCase (anArg);
7063 anArgCase.LowerCase();
7064 if (anUpdateTool.parseRedrawMode (anArg))
7065 {
7066 continue;
7067 }
f978241f 7068 else if (anArgCase == "-vsync"
7069 || anArgCase == "-swapinterval")
7070 {
7071 Standard_Boolean toEnable = Standard_True;
7072 if (++anArgIter < theArgNb
a5565a3c 7073 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 7074 {
7075 --anArgIter;
7076 }
7077 aCaps->swapInterval = toEnable;
7078 }
8625ef7e 7079 else if (anArgCase == "-ffp")
7080 {
7081 Standard_Boolean toEnable = Standard_True;
7082 if (++anArgIter < theArgNb
a5565a3c 7083 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 7084 {
7085 --anArgIter;
7086 }
7087 aCaps->ffpEnable = toEnable;
7088 }
2a332745 7089 else if (anArgCase == "-polygonmode")
7090 {
7091 Standard_Boolean toEnable = Standard_True;
7092 if (++anArgIter < theArgNb
7093 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
7094 {
7095 --anArgIter;
7096 }
7097 aCaps->usePolygonMode = toEnable;
7098 }
8625ef7e 7099 else if (anArgCase == "-vbo")
a577aaab 7100 {
8625ef7e 7101 Standard_Boolean toEnable = Standard_True;
7102 if (++anArgIter < theArgNb
a5565a3c 7103 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 7104 {
7105 --anArgIter;
7106 }
7107 aCaps->vboDisable = !toEnable;
a577aaab 7108 }
8625ef7e 7109 else if (anArgCase == "-sprite"
7110 || anArgCase == "-sprites")
a577aaab 7111 {
8625ef7e 7112 Standard_Boolean toEnable = Standard_True;
7113 if (++anArgIter < theArgNb
a5565a3c 7114 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 7115 {
7116 --anArgIter;
7117 }
7118 aCaps->pntSpritesDisable = !toEnable;
a577aaab 7119 }
8625ef7e 7120 else if (anArgCase == "-softmode")
abe46077 7121 {
8625ef7e 7122 Standard_Boolean toEnable = Standard_True;
7123 if (++anArgIter < theArgNb
a5565a3c 7124 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 7125 {
7126 --anArgIter;
7127 }
7128 aCaps->contextNoAccel = toEnable;
7129 }
56689b27 7130 else if (anArgCase == "-winbuffer"
7131 || anArgCase == "-windowbuffer"
7132 || anArgCase == "-usewinbuffer"
7133 || anArgCase == "-usewindowbuffer"
7134 || anArgCase == "-usesystembuffer")
7135 {
7136 Standard_Boolean toEnable = Standard_True;
7137 if (++anArgIter < theArgNb
7138 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
7139 {
7140 --anArgIter;
7141 }
7142 aCaps->useSystemBuffer = toEnable;
7143 }
8625ef7e 7144 else if (anArgCase == "-accel"
7145 || anArgCase == "-acceleration")
7146 {
7147 Standard_Boolean toEnable = Standard_True;
7148 if (++anArgIter < theArgNb
a5565a3c 7149 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
8625ef7e 7150 {
7151 --anArgIter;
7152 }
7153 aCaps->contextNoAccel = !toEnable;
abe46077 7154 }
4e1523ef 7155 else if (anArgCase == "-compat"
7156 || anArgCase == "-compatprofile"
7157 || anArgCase == "-compatible"
7158 || anArgCase == "-compatibleprofile")
7159 {
7160 Standard_Boolean toEnable = Standard_True;
7161 if (++anArgIter < theArgNb
a5565a3c 7162 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 7163 {
7164 --anArgIter;
7165 }
7166 aCaps->contextCompatible = toEnable;
7167 if (!aCaps->contextCompatible)
7168 {
7169 aCaps->ffpEnable = Standard_False;
7170 }
7171 }
7172 else if (anArgCase == "-core"
7173 || anArgCase == "-coreprofile")
7174 {
7175 Standard_Boolean toEnable = Standard_True;
7176 if (++anArgIter < theArgNb
a5565a3c 7177 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
4e1523ef 7178 {
7179 --anArgIter;
7180 }
7181 aCaps->contextCompatible = !toEnable;
7182 if (!aCaps->contextCompatible)
7183 {
7184 aCaps->ffpEnable = Standard_False;
7185 }
7186 }
f978241f 7187 else if (anArgCase == "-stereo"
7188 || anArgCase == "-quadbuffer")
7189 {
7190 Standard_Boolean toEnable = Standard_True;
7191 if (++anArgIter < theArgNb
a5565a3c 7192 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 7193 {
7194 --anArgIter;
7195 }
7196 aCaps->contextStereo = toEnable;
7197 }
a577aaab 7198 else
7199 {
8625ef7e 7200 std::cout << "Error: unknown argument '" << anArg << "'\n";
7201 return 1;
a577aaab 7202 }
7203 }
7204 if (aCaps != &ViewerTest_myDefaultCaps)
7205 {
7206 ViewerTest_myDefaultCaps = *aCaps;
7207 }
7208 return 0;
7209}
7210
f0430952 7211//==============================================================================
7212//function : VMemGpu
7213//purpose :
7214//==============================================================================
7215
7216static int VMemGpu (Draw_Interpretor& theDI,
7217 Standard_Integer theArgNb,
7218 const char** theArgVec)
7219{
7220 // get the context
7221 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
7222 if (aContextAIS.IsNull())
7223 {
7224 std::cerr << "No active view. Please call vinit.\n";
7225 return 1;
7226 }
7227
dc3fe572 7228 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
f0430952 7229 if (aDriver.IsNull())
7230 {
7231 std::cerr << "Graphic driver not available.\n";
7232 return 1;
7233 }
7234
7235 Standard_Size aFreeBytes = 0;
7236 TCollection_AsciiString anInfo;
7237 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
7238 {
7239 std::cerr << "Information not available.\n";
7240 return 1;
7241 }
7242
7243 if (theArgNb > 1 && *theArgVec[1] == 'f')
7244 {
7245 theDI << Standard_Real (aFreeBytes);
7246 }
7247 else
7248 {
7249 theDI << anInfo;
7250 }
7251
7252 return 0;
7253}
7254
85e096c3 7255// ==============================================================================
7256// function : VReadPixel
7257// purpose :
7258// ==============================================================================
7259static int VReadPixel (Draw_Interpretor& theDI,
7260 Standard_Integer theArgNb,
7261 const char** theArgVec)
7262{
7263 // get the active view
7264 Handle(V3d_View) aView = ViewerTest::CurrentView();
7265 if (aView.IsNull())
7266 {
7267 std::cerr << "No active view. Please call vinit.\n";
7268 return 1;
7269 }
7270 else if (theArgNb < 3)
7271 {
7272 std::cerr << "Usage : " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]\n";
7273 return 1;
7274 }
7275
dc858f4c 7276 Image_Format aFormat = Image_Format_RGBA;
7277 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
692613e5 7278
85e096c3 7279 Standard_Integer aWidth, aHeight;
7280 aView->Window()->Size (aWidth, aHeight);
91322f44 7281 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
7282 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
85e096c3 7283 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
7284 {
7285 std::cerr << "Pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")\n";
7286 return 1;
7287 }
7288
7289 Standard_Boolean toShowName = Standard_False;
7290 Standard_Boolean toShowHls = Standard_False;
7291 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
7292 {
dc858f4c 7293 TCollection_AsciiString aParam (theArgVec[anIter]);
7294 aParam.LowerCase();
55c8f0f7
BB
7295 if (aParam == "-rgb"
7296 || aParam == "rgb")
85e096c3 7297 {
dc858f4c 7298 aFormat = Image_Format_RGB;
692613e5 7299 aBufferType = Graphic3d_BT_RGB;
85e096c3 7300 }
55c8f0f7
BB
7301 else if (aParam == "-hls"
7302 || aParam == "hls")
85e096c3 7303 {
dc858f4c 7304 aFormat = Image_Format_RGB;
692613e5 7305 aBufferType = Graphic3d_BT_RGB;
85e096c3 7306 toShowHls = Standard_True;
7307 }
55c8f0f7
BB
7308 else if (aParam == "-rgbf"
7309 || aParam == "rgbf")
85e096c3 7310 {
dc858f4c 7311 aFormat = Image_Format_RGBF;
692613e5 7312 aBufferType = Graphic3d_BT_RGB;
85e096c3 7313 }
55c8f0f7
BB
7314 else if (aParam == "-rgba"
7315 || aParam == "rgba")
85e096c3 7316 {
dc858f4c 7317 aFormat = Image_Format_RGBA;
692613e5 7318 aBufferType = Graphic3d_BT_RGBA;
85e096c3 7319 }
55c8f0f7
BB
7320 else if (aParam == "-rgbaf"
7321 || aParam == "rgbaf")
85e096c3 7322 {
dc858f4c 7323 aFormat = Image_Format_RGBAF;
692613e5 7324 aBufferType = Graphic3d_BT_RGBA;
85e096c3 7325 }
55c8f0f7
BB
7326 else if (aParam == "-depth"
7327 || aParam == "depth")
85e096c3 7328 {
dc858f4c 7329 aFormat = Image_Format_GrayF;
692613e5 7330 aBufferType = Graphic3d_BT_Depth;
85e096c3 7331 }
55c8f0f7
BB
7332 else if (aParam == "-name"
7333 || aParam == "name")
85e096c3 7334 {
7335 toShowName = Standard_True;
7336 }
55c8f0f7
BB
7337 else
7338 {
7339 std::cout << "Syntax error at '" << aParam << "'\n";
7340 }
85e096c3 7341 }
7342
692613e5 7343 Image_PixMap anImage;
7344 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
7345 {
7346 std::cerr << "Image allocation failed\n";
7347 return 1;
7348 }
7349 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
85e096c3 7350 {
7351 std::cerr << "Image dump failed\n";
7352 return 1;
7353 }
7354
68beaa3c 7355 // redirect possible warning messages that could have been added by ToPixMap
7356 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
7357 // contaminate result of the command
7358 Standard_CString aWarnLog = theDI.Result();
7359 if (aWarnLog != NULL && aWarnLog[0] != '\0')
7360 {
7361 std::cout << aWarnLog << std::endl;
7362 }
7363 theDI.Reset();
7364
e958a649 7365 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY);
85e096c3 7366 if (toShowName)
7367 {
692613e5 7368 if (aBufferType == Graphic3d_BT_RGBA)
85e096c3 7369 {
e958a649 7370 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
85e096c3 7371 }
7372 else
7373 {
e958a649 7374 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
85e096c3 7375 }
7376 }
7377 else
7378 {
7379 switch (aBufferType)
7380 {
7381 default:
692613e5 7382 case Graphic3d_BT_RGB:
85e096c3 7383 {
7384 if (toShowHls)
7385 {
e958a649 7386 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
85e096c3 7387 }
7388 else
7389 {
e958a649 7390 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
85e096c3 7391 }
7392 break;
7393 }
692613e5 7394 case Graphic3d_BT_RGBA:
85e096c3 7395 {
e958a649 7396 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue() << " " << aColor.Alpha();
85e096c3 7397 break;
7398 }
692613e5 7399 case Graphic3d_BT_Depth:
85e096c3 7400 {
e958a649 7401 theDI << aColor.GetRGB().Red();
85e096c3 7402 break;
7403 }
7404 }
7405 }
7406
7407 return 0;
7408}
7409
fd3f6bd0 7410//! Auxiliary presentation for an image plane.
7411class ViewerTest_ImagePrs : public AIS_InteractiveObject
7412{
7413public:
7414 //! Main constructor.
7415 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
7416 const Standard_Real theWidth,
7417 const Standard_Real theHeight,
7418 const TCollection_AsciiString& theLabel)
7419 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
7420 {
7421 SetDisplayMode (0);
7422 SetHilightMode (1);
7423 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
7424 {
7425 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
7426 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
7427 Graphic3d_MaterialAspect aMat;
7428 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
7429 aMat.SetAmbient (1.0);
7430 aMat.SetDiffuse (1.0);
7431 aMat.SetSpecular (1.0);
7432 aMat.SetEmissive (1.0);
7433 aMat.SetReflectionModeOn (Graphic3d_TOR_AMBIENT);
7434 aMat.SetReflectionModeOn (Graphic3d_TOR_DIFFUSE);
7435 aMat.SetReflectionModeOn (Graphic3d_TOR_SPECULAR);
7436 aMat.SetReflectionModeOn (Graphic3d_TOR_EMISSION);
7437 aMat.SetAmbientColor (Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB));
7438 aMat.SetDiffuseColor (Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB));
7439 aMat.SetSpecularColor (Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB));
7440 aMat.SetEmissiveColor (Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB));
7441 aFillAspect->SetFrontMaterial (aMat);
7442 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
7443 aFillAspect->SetTextureMapOn();
7444 }
7445 {
7446 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
7447 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
7448 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
7449 myDrawer->SetTextAspect (aTextAspect);
7450 }
7451 {
7452 const gp_Dir aNorm (0.0, 0.0, 1.0);
7453 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
7454 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
7455 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
7456 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
7457 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
7458 myTris->AddEdge (1);
7459 myTris->AddEdge (2);
7460 myTris->AddEdge (3);
7461 myTris->AddEdge (3);
7462 myTris->AddEdge (2);
7463 myTris->AddEdge (4);
7464
7465 myRect = new Graphic3d_ArrayOfPolylines (4);
7466 myRect->AddVertex (myTris->Vertice (1));
7467 myRect->AddVertex (myTris->Vertice (3));
7468 myRect->AddVertex (myTris->Vertice (4));
7469 myRect->AddVertex (myTris->Vertice (2));
7470 }
7471 }
7472
7473 //! Returns TRUE for accepted display modes.
7474 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
7475
7476 //! Compute presentation.
7477 virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& , const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) Standard_OVERRIDE
7478 {
7479 switch (theMode)
7480 {
7481 case 0:
7482 {
7483 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7484 aGroup->AddPrimitiveArray (myTris);
7485 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
7486 aGroup->AddPrimitiveArray (myRect);
7487 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7488 return;
7489 }
7490 case 1:
7491 {
7492 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
7493 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
7494 aGroup->AddPrimitiveArray (myRect);
7495 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
7496 return;
7497 }
7498 }
7499 }
7500
7501 //! Compute selection.
7502 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
7503 {
7504 if (theMode == 0)
7505 {
7506 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
7507 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
7508 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
7509 theSel->Add (aSensitive);
7510 }
7511 }
7512
7513private:
7514 Handle(Graphic3d_ArrayOfTriangles) myTris;
7515 Handle(Graphic3d_ArrayOfPolylines) myRect;
7516 TCollection_AsciiString myLabel;
7517 Standard_Real myWidth;
7518 Standard_Real myHeight;
7519};
7520
692613e5 7521//==============================================================================
7522//function : VDiffImage
7523//purpose : The draw-command compares two images.
7524//==============================================================================
7525
7526static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
7527{
fd3f6bd0 7528 if (theArgNb < 3)
692613e5 7529 {
fd3f6bd0 7530 std::cout << "Syntax error: not enough arguments.\n";
692613e5 7531 return 1;
7532 }
7533
fd3f6bd0 7534 Standard_Integer anArgIter = 1;
7535 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
7536 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
7537 TCollection_AsciiString aDiffImagePath;
7538 Standard_Real aTolColor = -1.0;
7539 Standard_Integer toBlackWhite = -1;
7540 Standard_Integer isBorderFilterOn = -1;
7541 Standard_Boolean isOldSyntax = Standard_False;
7542 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
7543 for (; anArgIter < theArgNb; ++anArgIter)
7544 {
7545 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7546 anArg.LowerCase();
7547 if (anArgIter + 1 < theArgNb
7548 && (anArg == "-toleranceofcolor"
7549 || anArg == "-tolerancecolor"
7550 || anArg == "-tolerance"
7551 || anArg == "-toler"))
7552 {
7553 aTolColor = Atof (theArgVec[++anArgIter]);
7554 if (aTolColor < 0.0 || aTolColor > 1.0)
7555 {
7556 std::cout << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'\n";
7557 return 1;
7558 }
7559 }
7560 else if (anArg == "-blackwhite")
7561 {
7562 Standard_Boolean toEnable = Standard_True;
7563 if (anArgIter + 1 < theArgNb
7564 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
7565 {
7566 ++anArgIter;
7567 }
7568 toBlackWhite = toEnable ? 1 : 0;
7569 }
7570 else if (anArg == "-borderfilter")
7571 {
7572 Standard_Boolean toEnable = Standard_True;
7573 if (anArgIter + 1 < theArgNb
7574 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
7575 {
7576 ++anArgIter;
7577 }
7578 isBorderFilterOn = toEnable ? 1 : 0;
7579 }
7580 else if (anArg == "-exitonclose")
7581 {
7582 Draw_ToExitOnCloseView = true;
7583 if (anArgIter + 1 < theArgNb
7584 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], Draw_ToExitOnCloseView))
7585 {
7586 ++anArgIter;
7587 }
7588 }
7589 else if (anArg == "-closeonescape"
7590 || anArg == "-closeonesc")
7591 {
7592 Draw_ToCloseViewOnEsc = true;
7593 if (anArgIter + 1 < theArgNb
7594 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], Draw_ToCloseViewOnEsc))
7595 {
7596 ++anArgIter;
7597 }
7598 }
7599 else if (anArgIter + 3 < theArgNb
7600 && anArg == "-display")
7601 {
7602 aViewName = theArgVec[++anArgIter];
7603 aPrsNameRef = theArgVec[++anArgIter];
7604 aPrsNameNew = theArgVec[++anArgIter];
7605 if (anArgIter + 1 < theArgNb
7606 && *theArgVec[anArgIter + 1] != '-')
7607 {
7608 aPrsNameDiff = theArgVec[++anArgIter];
7609 }
7610 }
7611 else if (aTolColor < 0.0
7612 && anArg.IsRealValue())
7613 {
7614 isOldSyntax = Standard_True;
7615 aTolColor = anArg.RealValue();
7616 if (aTolColor < 0.0 || aTolColor > 1.0)
7617 {
7618 std::cout << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'\n";
7619 return 1;
7620 }
7621 }
7622 else if (isOldSyntax
7623 && toBlackWhite == -1
7624 && (anArg == "0" || anArg == "1"))
7625 {
7626 toBlackWhite = anArg == "1" ? 1 : 0;
7627 }
7628 else if (isOldSyntax
7629 && isBorderFilterOn == -1
7630 && (anArg == "0" || anArg == "1"))
7631 {
7632 isBorderFilterOn = anArg == "1" ? 1 : 0;
7633 }
7634 else if (aDiffImagePath.IsEmpty())
7635 {
7636 aDiffImagePath = theArgVec[anArgIter];
7637 }
7638 else
7639 {
7640 std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
7641 return 1;
7642 }
7643 }
692613e5 7644
fd3f6bd0 7645 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
7646 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
7647 if (!anImgRef->Load (anImgPathRef))
7648 {
7649 std::cout << "Error: image file '" << anImgPathRef << "' cannot be read\n";
7650 return 1;
7651 }
7652 if (!anImgNew->Load (anImgPathNew))
7653 {
7654 std::cout << "Error: image file '" << anImgPathNew << "' cannot be read\n";
7655 return 1;
7656 }
692613e5 7657
7658 // compare the images
7659 Image_Diff aComparer;
fd3f6bd0 7660 Standard_Integer aDiffColorsNb = -1;
7661 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
692613e5 7662 {
fd3f6bd0 7663 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
7664 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
7665 aDiffColorsNb = aComparer.Compare();
7666 theDI << aDiffColorsNb << "\n";
692613e5 7667 }
7668
692613e5 7669 // save image of difference
fd3f6bd0 7670 Handle(Image_AlienPixMap) aDiff;
7671 if (aDiffColorsNb > 0
7672 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
7673 {
7674 aDiff = new Image_AlienPixMap();
7675 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
7676 {
7677 std::cout << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY() << "\n";
7678 return 1;
7679 }
7680 aComparer.SaveDiffImage (*aDiff);
7681 if (!aDiffImagePath.IsEmpty()
7682 && !aDiff->Save (aDiffImagePath))
7683 {
7684 std::cout << "Error: diff image file '" << aDiffImagePath << "' cannot be written\n";
7685 return 1;
7686 }
7687 }
7688
7689 if (aViewName.IsEmpty())
7690 {
7691 return 0;
7692 }
7693
7694 ViewerTest_Names aViewNames (aViewName);
7695 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
7696 {
7697 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
7698 theDI.Eval (aCommand.ToCString());
7699 }
7700
7701 Standard_Integer aPxLeft = 0;
7702 Standard_Integer aPxTop = 0;
7703 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
7704 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
7705 ? int(anImgRef->SizeY() * 2)
7706 : int(anImgRef->SizeY());
7707 TCollection_AsciiString aDisplayName;
9e04ccdc 7708 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
7709 aViewName, aDisplayName);
fd3f6bd0 7710
7711 Standard_Real aRatio = anImgRef->Ratio();
7712 Standard_Real aSizeX = 1.0;
7713 Standard_Real aSizeY = aSizeX / aRatio;
692613e5 7714 {
fd3f6bd0 7715 OSD_Path aPath (anImgPathRef);
7716 TCollection_AsciiString aLabelRef;
7717 if (!aPath.Name().IsEmpty())
7718 {
7719 aLabelRef = aPath.Name() + aPath.Extension();
7720 }
7721 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
7722
7723 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
7724 gp_Trsf aTrsfRef;
7725 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
7726 anImgRefPrs->SetLocalTransformation (aTrsfRef);
7727 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
692613e5 7728 }
fd3f6bd0 7729 {
7730 OSD_Path aPath (anImgPathNew);
7731 TCollection_AsciiString aLabelNew;
7732 if (!aPath.Name().IsEmpty())
7733 {
7734 aLabelNew = aPath.Name() + aPath.Extension();
7735 }
7736 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
692613e5 7737
fd3f6bd0 7738 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
7739 gp_Trsf aTrsfRef;
7740 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
7741 anImgNewPrs->SetLocalTransformation (aTrsfRef);
7742 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
7743 }
7744 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
7745 if (!aDiff.IsNull())
7746 {
7747 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
7748 gp_Trsf aTrsfDiff;
7749 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
7750 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
7751 }
7752 if (!aPrsNameDiff.IsEmpty())
7753 {
7754 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
7755 }
7756 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
7757 ViewerTest::CurrentView()->FitAll();
692613e5 7758 return 0;
7759}
7760
4754e164 7761//=======================================================================
7762//function : VSelect
7763//purpose : Emulates different types of selection by mouse:
7764// 1) single click selection
7765// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
7766// 3) selection with polygon having corners at
dc3fe572 7767// pixel positions (x1,y1),...,(xn,yn)
4754e164 7768// 4) any of these selections with shift button pressed
7769//=======================================================================
7770static Standard_Integer VSelect (Draw_Interpretor& di,
7771 Standard_Integer argc,
7772 const char ** argv)
7773{
dc3fe572 7774 if(argc < 3)
4754e164 7775 {
586db386 7776 di << "Usage : " << argv[0] << " x1 y1 [x2 y2 [... xn yn]] [shift_selection = 1|0]\n";
4754e164 7777 return 1;
7778 }
7779
7780 Handle(AIS_InteractiveContext) myAIScontext = ViewerTest::GetAISContext();
dc3fe572 7781 if(myAIScontext.IsNull())
4754e164 7782 {
7783 di << "use 'vinit' command before " << argv[0] << "\n";
7784 return 1;
7785 }
2157d6ac 7786
7787 const Standard_Boolean isShiftSelection = (argc > 3 && !(argc % 2) && (atoi (argv[argc - 1]) == 1));
7788 Standard_Integer aCoordsNb = isShiftSelection ? argc - 2 : argc - 1;
7789 TCollection_AsciiString anArg;
7790 anArg = isShiftSelection ? argv[argc - 3] : argv[argc - 2];
7791 anArg.LowerCase();
7792 if (anArg == "-allowoverlap")
7793 {
7794 Standard_Boolean isValidated = isShiftSelection ? argc == 8
7795 : argc == 7;
7796 if (!isValidated)
7797 {
7798 di << "Wrong number of arguments! -allowoverlap key is applied only for rectangle selection";
7799 return 1;
7800 }
7801
7802 Standard_Integer isToAllow = isShiftSelection ? Draw::Atoi(argv[argc - 2]) : Draw::Atoi(argv[argc - 1]);
dde68833 7803 myAIScontext->MainSelector()->AllowOverlapDetection (isToAllow != 0);
2157d6ac 7804 aCoordsNb -= 2;
7805 }
7806
4754e164 7807 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
7808 aCurrentEventManager->MoveTo(atoi(argv[1]),atoi(argv[2]));
2157d6ac 7809 if(aCoordsNb == 2)
4754e164 7810 {
7811 if(isShiftSelection)
7812 aCurrentEventManager->ShiftSelect();
7813 else
7814 aCurrentEventManager->Select();
7815 }
2157d6ac 7816 else if(aCoordsNb == 4)
4754e164 7817 {
7818 if(isShiftSelection)
2157d6ac 7819 aCurrentEventManager->ShiftSelect (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
4754e164 7820 else
2157d6ac 7821 aCurrentEventManager->Select (atoi (argv[1]), atoi (argv[2]), atoi (argv[3]), atoi (argv[4]), Standard_False);
4754e164 7822 }
7823 else
7824 {
2157d6ac 7825 TColgp_Array1OfPnt2d aPolyline (1,aCoordsNb / 2);
4754e164 7826
2157d6ac 7827 for(Standard_Integer i=1;i<=aCoordsNb / 2;++i)
4754e164 7828 aPolyline.SetValue(i,gp_Pnt2d(atoi(argv[2*i-1]),atoi(argv[2*i])));
7829
7830 if(isShiftSelection)
7831 aCurrentEventManager->ShiftSelect(aPolyline);
7832 else
7833 aCurrentEventManager->Select(aPolyline);
7834 }
7835 return 0;
7836}
7837
7838//=======================================================================
7839//function : VMoveTo
dc3fe572 7840//purpose : Emulates cursor movement to defined pixel position
4754e164 7841//=======================================================================
1e756cb9 7842static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
8a590580 7843 Standard_Integer theNbArgs,
7844 const char** theArgVec)
4754e164 7845{
8a590580 7846 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
7847 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
7848 if (aContext.IsNull())
4754e164 7849 {
8a590580 7850 std::cout << "Error: no active View\n";
4754e164 7851 return 1;
7852 }
7853
8a590580 7854 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
7855 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4754e164 7856 {
8a590580 7857 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
7858 anArgStr.LowerCase();
7859 if (anArgStr == "-reset"
7860 || anArgStr == "-clear")
7861 {
7862 if (anArgIter + 1 < theNbArgs)
7863 {
7864 std::cout << "Syntax error at '" << theArgVec[anArgIter + 1] << "'\n";
7865 return 1;
7866 }
7867
7868 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->Grid()->IsActive()
7869 && aContext->CurrentViewer()->GridEcho();
7870 if (toEchoGrid)
7871 {
7872 aContext->CurrentViewer()->HideGridEcho (aView);
7873 }
7874 if (aContext->ClearDetected() || toEchoGrid)
7875 {
7876 aContext->CurrentViewer()->RedrawImmediate();
7877 }
7878 return 0;
7879 }
7880 else if (aMousePos.x() == IntegerLast()
7881 && anArgStr.IsIntegerValue())
7882 {
7883 aMousePos.x() = anArgStr.IntegerValue();
7884 }
7885 else if (aMousePos.y() == IntegerLast()
7886 && anArgStr.IsIntegerValue())
7887 {
7888 aMousePos.y() = anArgStr.IntegerValue();
7889 }
7890 else
7891 {
7892 std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
7893 return 1;
7894 }
7895 }
7896
7897 if (aMousePos.x() == IntegerLast()
7898 || aMousePos.y() == IntegerLast())
7899 {
7900 std::cout << "Syntax error: wrong number of arguments\n";
4754e164 7901 return 1;
7902 }
8a590580 7903
7904 ViewerTest::CurrentEventManager()->MoveTo (aMousePos.x(), aMousePos.y());
1e756cb9 7905 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
7906 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
7907 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
7908 {
7909 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
7910 {
7911 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
7912 break;
7913 }
7914 }
7915 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
4754e164 7916 return 0;
7917}
7918
1beb58d7 7919namespace
7920{
7921 //! Global map storing all animations registered in ViewerTest.
7922 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
7923
7924 //! The animation calling the Draw Harness command.
7925 class ViewerTest_AnimationProc : public AIS_Animation
7926 {
7927 public:
7928
7929 //! Main constructor.
7930 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
7931 Draw_Interpretor* theDI,
7932 const TCollection_AsciiString& theCommand)
7933 : AIS_Animation (theAnimationName),
7934 myDrawInter(theDI),
7935 myCommand (theCommand)
7936 {
7937 //
7938 }
7939
7940 protected:
7941
7942 //! Evaluate the command.
7943 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
7944 {
7945 TCollection_AsciiString aCmd = myCommand;
7946 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
7947 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
7948 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
7949 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
7950 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
7951 myDrawInter->Eval (aCmd.ToCString());
7952 }
7953
7954 //! Find the keyword in the command and replace it with value.
7955 //! @return the position of the keyword to pass value
7956 void replace (TCollection_AsciiString& theCmd,
7957 const TCollection_AsciiString& theKey,
7958 const TCollection_AsciiString& theVal)
7959 {
7960 TCollection_AsciiString aCmd (theCmd);
7961 aCmd.LowerCase();
7962 const Standard_Integer aPos = aCmd.Search (theKey);
7963 if (aPos == -1)
7964 {
7965 return;
7966 }
7967
7968 TCollection_AsciiString aPart1, aPart2;
7969 Standard_Integer aPart1To = aPos - 1;
7970 if (aPart1To >= 1
7971 && aPart1To <= theCmd.Length())
7972 {
7973 aPart1 = theCmd.SubString (1, aPart1To);
7974 }
7975
7976 Standard_Integer aPart2From = aPos + theKey.Length();
7977 if (aPart2From >= 1
7978 && aPart2From <= theCmd.Length())
7979 {
7980 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
7981 }
7982
7983 theCmd = aPart1 + theVal + aPart2;
7984 }
7985
7986 protected:
7987
7988 Draw_Interpretor* myDrawInter;
7989 TCollection_AsciiString myCommand;
7990
7991 };
7992
7993 //! Replace the animation with the new one.
7994 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
7995 Handle(AIS_Animation)& theAnimation,
7996 const Handle(AIS_Animation)& theAnimationNew)
7997 {
7998 theAnimationNew->CopyFrom (theAnimation);
7999 if (!theParentAnimation.IsNull())
8000 {
8001 theParentAnimation->Replace (theAnimation, theAnimationNew);
8002 }
8003 else
8004 {
8005 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
8006 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
8007 }
8008 theAnimation = theAnimationNew;
8009 }
8010
8011 //! Parse the point.
8012 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
8013 {
8014 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
8015 if (!anXYZ[0].IsRealValue()
8016 || !anXYZ[1].IsRealValue()
8017 || !anXYZ[2].IsRealValue())
8018 {
8019 return Standard_False;
8020 }
8021
8022 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
8023 return Standard_True;
8024 }
8025
8026 //! Parse the quaternion.
8027 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
8028 {
8029 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
8030 if (!anXYZW[0].IsRealValue()
8031 || !anXYZW[1].IsRealValue()
8032 || !anXYZW[2].IsRealValue()
8033 || !anXYZW[3].IsRealValue())
8034 {
8035 return Standard_False;
8036 }
8037
8038 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
8039 return Standard_True;
8040 }
8041
08f8a185 8042 //! Auxiliary class for flipping image upside-down.
8043 class ImageFlipper
8044 {
8045 public:
8046
8047 //! Empty constructor.
8048 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
8049
8050 //! Perform flipping.
8051 Standard_Boolean FlipY (Image_PixMap& theImage)
8052 {
8053 if (theImage.IsEmpty()
8054 || theImage.SizeX() == 0
8055 || theImage.SizeY() == 0)
8056 {
8057 return Standard_False;
8058 }
8059
8060 const Standard_Size aRowSize = theImage.SizeRowBytes();
8061 if (myTmp.Size() < aRowSize
8062 && !myTmp.Allocate (aRowSize))
8063 {
8064 return Standard_False;
8065 }
8066
8067 // for odd height middle row should be left as is
8068 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
8069 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
8070 {
8071 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
8072 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
8073 memcpy (myTmp.ChangeData(), aTop, aRowSize);
8074 memcpy (aTop, aBot, aRowSize);
8075 memcpy (aBot, myTmp.Data(), aRowSize);
8076 }
8077 return Standard_True;
8078 }
8079
8080 private:
8081 NCollection_Buffer myTmp;
8082 };
8083
1beb58d7 8084}
8085
197ac94e 8086//=================================================================================================
4754e164 8087//function : VViewParams
dc3fe572 8088//purpose : Gets or sets AIS View characteristics
197ac94e 8089//=================================================================================================
8090static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
4754e164 8091{
1beb58d7 8092 Handle(V3d_View) aView = ViewerTest::CurrentView();
8093 if (aView.IsNull())
4754e164 8094 {
197ac94e 8095 std::cout << theArgVec[0] << ": please initialize or activate view.\n";
4754e164 8096 return 1;
8097 }
197ac94e 8098
1beb58d7 8099 Standard_Boolean toSetProj = Standard_False;
8100 Standard_Boolean toSetUp = Standard_False;
8101 Standard_Boolean toSetAt = Standard_False;
8102 Standard_Boolean toSetEye = Standard_False;
8103 Standard_Boolean toSetScale = Standard_False;
8104 Standard_Boolean toSetSize = Standard_False;
8105 Standard_Boolean toSetCenter2d = Standard_False;
ee2be2a8 8106 Standard_Real aViewScale = aView->Scale();
8107 Standard_Real aViewSize = 1.0;
1beb58d7 8108 Graphic3d_Vec2i aCenter2d;
8109 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
8110 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
8111 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
8112 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
8113 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
197ac94e 8114 if (theArgsNb == 1)
4754e164 8115 {
197ac94e 8116 // print all of the available view parameters
1beb58d7 8117 char aText[4096];
8118 Sprintf (aText,
8119 "Scale: %g\n"
8120 "Proj: %12g %12g %12g\n"
8121 "Up: %12g %12g %12g\n"
8122 "At: %12g %12g %12g\n"
8123 "Eye: %12g %12g %12g\n",
8124 aViewScale,
8125 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
8126 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
8127 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
8128 aViewEye.X(), aViewEye.Y(), aViewEye.Z());
8129 theDi << aText;
197ac94e 8130 return 0;
4754e164 8131 }
197ac94e 8132
1beb58d7 8133 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
8134 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
197ac94e 8135 {
1beb58d7 8136 TCollection_AsciiString anArg (theArgVec[anArgIter]);
8137 anArg.LowerCase();
8138 if (anUpdateTool.parseRedrawMode (anArg))
197ac94e 8139 {
197ac94e 8140 continue;
8141 }
1beb58d7 8142 else if (anArg == "-cmd"
8143 || anArg == "-command"
8144 || anArg == "-args")
8145 {
8146 char aText[4096];
8147 Sprintf (aText,
8148 "-scale %g "
8149 "-proj %g %g %g "
8150 "-up %g %g %g "
8151 "-at %g %g %g\n",
8152 aViewScale,
8153 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
8154 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
8155 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8156 theDi << aText;
8157 }
8158 else if (anArg == "-scale"
8159 || anArg == "-size")
8160 {
8161 if (anArgIter + 1 < theArgsNb
8162 && *theArgVec[anArgIter + 1] != '-')
8163 {
8164 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
8165 if (aValueArg.IsRealValue())
8166 {
8167 ++anArgIter;
8168 if (anArg == "-scale")
8169 {
8170 toSetScale = Standard_True;
8171 aViewScale = aValueArg.RealValue();
8172 }
8173 else if (anArg == "-size")
8174 {
8175 toSetSize = Standard_True;
8176 aViewSize = aValueArg.RealValue();
8177 }
8178 continue;
8179 }
8180 }
8181 if (anArg == "-scale")
8182 {
8183 theDi << "Scale: " << aView->Scale() << "\n";
8184 }
8185 else if (anArg == "-size")
8186 {
8187 Graphic3d_Vec2d aSizeXY;
8188 aView->Size (aSizeXY.x(), aSizeXY.y());
8189 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
8190 }
8191 }
8192 else if (anArg == "-eye"
8193 || anArg == "-at"
8194 || anArg == "-up"
8195 || anArg == "-proj")
8196 {
8197 if (anArgIter + 3 < theArgsNb)
8198 {
8199 gp_XYZ anXYZ;
8200 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
8201 {
8202 anArgIter += 3;
8203 if (anArg == "-eye")
8204 {
8205 toSetEye = Standard_True;
8206 aViewEye = anXYZ;
8207 }
8208 else if (anArg == "-at")
8209 {
8210 toSetAt = Standard_True;
8211 aViewAt = anXYZ;
8212 }
8213 else if (anArg == "-up")
8214 {
8215 toSetUp = Standard_True;
8216 aViewUp = anXYZ;
8217 }
8218 else if (anArg == "-proj")
8219 {
8220 toSetProj = Standard_True;
8221 aViewProj = anXYZ;
8222 }
8223 continue;
8224 }
8225 }
197ac94e 8226
1beb58d7 8227 if (anArg == "-eye")
8228 {
8229 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
8230 }
8231 else if (anArg == "-at")
8232 {
8233 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
8234 }
8235 else if (anArg == "-up")
8236 {
8237 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
8238 }
8239 else if (anArg == "-proj")
8240 {
8241 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
8242 }
8243 }
8244 else if (anArg == "-center")
3dfe95cd 8245 {
1beb58d7 8246 if (anArgIter + 2 < theArgsNb)
8247 {
8248 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
8249 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
8250 if (anX.IsIntegerValue()
8251 && anY.IsIntegerValue())
8252 {
8253 toSetCenter2d = Standard_True;
8254 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
8255 }
8256 }
8257 }
8258 else
8259 {
8260 std::cout << "Syntax error at '" << anArg << "'\n";
3dfe95cd 8261 return 1;
8262 }
1beb58d7 8263 }
3dfe95cd 8264
1beb58d7 8265 // change view parameters in proper order
8266 if (toSetScale)
8267 {
8268 aView->SetScale (aViewScale);
8269 }
8270 if (toSetSize)
8271 {
8272 aView->SetSize (aViewSize);
8273 }
8274 if (toSetEye)
8275 {
8276 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
8277 }
8278 if (toSetAt)
8279 {
8280 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
8281 }
8282 if (toSetProj)
8283 {
8284 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
8285 }
8286 if (toSetUp)
8287 {
8288 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
8289 }
8290 if (toSetCenter2d)
8291 {
8292 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
197ac94e 8293 }
8294
1beb58d7 8295 return 0;
8296}
197ac94e 8297
2e93433e 8298//==============================================================================
8299//function : V2DMode
8300//purpose :
8301//==============================================================================
8302static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
8303{
8304 bool is2dMode = true;
8305 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
8306 if (aV3dView.IsNull())
8307 {
8308 std::cout << "Error: no active view.\n";
8309 return 1;
8310 }
8311 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
8312 {
8313 const TCollection_AsciiString anArg = theArgVec[anArgIt];
8314 TCollection_AsciiString anArgCase = anArg;
8315 anArgCase.LowerCase();
8316 if (anArgIt + 1 < theArgsNb
8317 && anArgCase == "-name")
8318 {
8319 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
8320 TCollection_AsciiString aViewName = aViewNames.GetViewName();
8321 if (!ViewerTest_myViews.IsBound1 (aViewName))
8322 {
8323 std::cout << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'.\n";
8324 return 1;
8325 }
8326 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
8327 }
8328 else if (anArgCase == "-mode")
8329 {
8330 if (anArgIt + 1 < theArgsNb
8331 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
8332 {
8333 ++anArgIt;
8334 }
8335 }
8336 else if (ViewerTest::ParseOnOff (theArgVec[anArgIt], is2dMode))
8337 {
8338 //
8339 }
8340 else
8341 {
8342 std::cout << "Syntax error: unknown argument " << anArg << ".\n";
8343 return 1;
8344 }
8345 }
8346
8347 aV3dView->SetView2DMode (is2dMode);
8348 return 0;
8349}
8350
1beb58d7 8351//==============================================================================
8352//function : VAnimation
8353//purpose :
8354//==============================================================================
8355static Standard_Integer VAnimation (Draw_Interpretor& theDI,
8356 Standard_Integer theArgNb,
8357 const char** theArgVec)
8358{
8359 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
8360 if (theArgNb < 2)
4754e164 8361 {
1beb58d7 8362 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
8363 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
8364 {
8365 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8366 }
1beb58d7 8367 return 0;
8368 }
8369 if (aCtx.IsNull())
8370 {
8371 std::cout << "Error: no active view\n";
8372 return 1;
4754e164 8373 }
197ac94e 8374
1beb58d7 8375 Standard_Integer anArgIter = 1;
8376 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
8377 if (aNameArg.IsEmpty())
8378 {
8379 std::cout << "Syntax error: animation name is not defined.\n";
8380 return 1;
8381 }
8382
8383 TCollection_AsciiString aNameArgLower = aNameArg;
8384 aNameArgLower.LowerCase();
8385 if (aNameArgLower == "-reset"
8386 || aNameArgLower == "-clear")
8387 {
8388 ViewerTest_AnimationTimelineMap.Clear();
8389 return 0;
8390 }
8391 else if (aNameArg.Value (1) == '-')
8392 {
8393 std::cout << "Syntax error: invalid animation name '" << aNameArg << "'.\n";
8394 return 1;
8395 }
197ac94e 8396
1beb58d7 8397 const char* aNameSplitter = "/";
8398 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
8399 if (aSplitPos == -1)
197ac94e 8400 {
1beb58d7 8401 aNameSplitter = ".";
8402 aSplitPos = aNameArg.Search (aNameSplitter);
8403 }
8404
8405 // find existing or create a new animation by specified name within syntax "parent.child".
8406 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
8407 for (; !aNameArg.IsEmpty();)
8408 {
8409 TCollection_AsciiString aNameParent;
8410 if (aSplitPos != -1)
197ac94e 8411 {
1beb58d7 8412 if (aSplitPos == aNameArg.Length())
8413 {
8414 std::cout << "Syntax error: animation name is not defined.\n";
8415 return 1;
8416 }
8417
8418 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
8419 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
8420
8421 aSplitPos = aNameArg.Search (aNameSplitter);
197ac94e 8422 }
8423 else
8424 {
1beb58d7 8425 aNameParent = aNameArg;
8426 aNameArg.Clear();
197ac94e 8427 }
1beb58d7 8428
8429 if (anAnimation.IsNull())
3dfe95cd 8430 {
1beb58d7 8431 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
8432 {
8433 anAnimation = new AIS_Animation (aNameParent);
8434 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
8435 }
8436 aRootAnimation = anAnimation;
3dfe95cd 8437 }
8438 else
8439 {
1beb58d7 8440 aParentAnimation = anAnimation;
8441 anAnimation = aParentAnimation->Find (aNameParent);
8442 if (anAnimation.IsNull())
8443 {
8444 anAnimation = new AIS_Animation (aNameParent);
8445 aParentAnimation->Add (anAnimation);
8446 }
3dfe95cd 8447 }
8448 }
1beb58d7 8449
8450 if (anArgIter >= theArgNb)
197ac94e 8451 {
1beb58d7 8452 // just print the list of children
8453 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
197ac94e 8454 {
1beb58d7 8455 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
197ac94e 8456 }
1beb58d7 8457 return 0;
197ac94e 8458 }
1beb58d7 8459
bf7b2ceb 8460 // animation parameters
1beb58d7 8461 Standard_Boolean toPlay = Standard_False;
8462 Standard_Real aPlaySpeed = 1.0;
8463 Standard_Real aPlayStartTime = anAnimation->StartPts();
8464 Standard_Real aPlayDuration = anAnimation->Duration();
1beb58d7 8465 Standard_Boolean isFreeCamera = Standard_False;
8466 Standard_Boolean isLockLoop = Standard_False;
08f8a185 8467
8468 // video recording parameters
8469 TCollection_AsciiString aRecFile;
8470 Image_VideoParams aRecParams;
8471
1beb58d7 8472 Handle(V3d_View) aView = ViewerTest::CurrentView();
8473 for (; anArgIter < theArgNb; ++anArgIter)
197ac94e 8474 {
1beb58d7 8475 TCollection_AsciiString anArg (theArgVec[anArgIter]);
8476 anArg.LowerCase();
bf7b2ceb 8477 // general options
1beb58d7 8478 if (anArg == "-reset"
8479 || anArg == "-clear")
197ac94e 8480 {
1beb58d7 8481 anAnimation->Clear();
8482 }
8483 else if (anArg == "-remove"
8484 || anArg == "-del"
8485 || anArg == "-delete")
8486 {
8487 if (!aParentAnimation.IsNull())
8488 {
8489 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
8490 }
8491 else
8492 {
8493 aParentAnimation->Remove (anAnimation);
8494 }
8495 }
bf7b2ceb 8496 // playback options
1beb58d7 8497 else if (anArg == "-play")
8498 {
8499 toPlay = Standard_True;
8500 if (++anArgIter < theArgNb)
8501 {
8502 if (*theArgVec[anArgIter] == '-')
8503 {
8504 --anArgIter;
8505 continue;
8506 }
8507 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
8508
8509 if (++anArgIter < theArgNb)
8510 {
8511 if (*theArgVec[anArgIter] == '-')
8512 {
8513 --anArgIter;
8514 continue;
8515 }
8516 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8517 }
8518 }
8519 }
8520 else if (anArg == "-resume")
8521 {
8522 toPlay = Standard_True;
8523 aPlayStartTime = anAnimation->ElapsedTime();
8524 if (++anArgIter < theArgNb)
8525 {
8526 if (*theArgVec[anArgIter] == '-')
8527 {
8528 --anArgIter;
8529 continue;
8530 }
8531
8532 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
8533 }
8534 }
8535 else if (anArg == "-playspeed"
8536 || anArg == "-speed")
8537 {
8538 if (++anArgIter >= theArgNb)
8539 {
8540 std::cout << "Syntax error at " << anArg << ".\n";
8541 return 1;
8542 }
8543 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
8544 }
8545 else if (anArg == "-lock"
8546 || anArg == "-lockloop"
8547 || anArg == "-playlockloop")
8548 {
8549 isLockLoop = Standard_True;
8550 }
8551 else if (anArg == "-freecamera"
8552 || anArg == "-playfreecamera"
8553 || anArg == "-freelook")
8554 {
8555 isFreeCamera = Standard_True;
8556 }
08f8a185 8557 // video recodring options
8558 else if (anArg == "-rec"
8559 || anArg == "-record")
8560 {
8561 if (++anArgIter >= theArgNb)
8562 {
8563 std::cout << "Syntax error at " << anArg << ".\n";
8564 return 1;
8565 }
8566
8567 aRecFile = theArgVec[anArgIter];
8568 if (aRecParams.FpsNum <= 0)
8569 {
8570 aRecParams.FpsNum = 24;
8571 }
8572
8573 if (anArgIter + 2 < theArgNb
8574 && *theArgVec[anArgIter + 1] != '-'
8575 && *theArgVec[anArgIter + 2] != '-')
8576 {
8577 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
8578 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
8579 if (aWidthArg .IsIntegerValue()
8580 && aHeightArg.IsIntegerValue())
8581 {
8582 aRecParams.Width = aWidthArg .IntegerValue();
8583 aRecParams.Height = aHeightArg.IntegerValue();
8584 anArgIter += 2;
8585 }
8586 }
8587 }
1beb58d7 8588 else if (anArg == "-fps")
8589 {
8590 if (++anArgIter >= theArgNb)
8591 {
8592 std::cout << "Syntax error at " << anArg << ".\n";
8593 return 1;
8594 }
bf7b2ceb 8595
8596 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
8597 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
8598 if (aSplitIndex == 0)
8599 {
08f8a185 8600 aRecParams.FpsNum = aFpsArg.IntegerValue();
bf7b2ceb 8601 }
8602 else
8603 {
8604 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
8605 aFpsArg.Split (aFpsArg.Length() - 1);
8606 const TCollection_AsciiString aNumStr = aFpsArg;
08f8a185 8607 aRecParams.FpsNum = aNumStr.IntegerValue();
8608 aRecParams.FpsDen = aDenStr.IntegerValue();
8609 if (aRecParams.FpsDen < 1)
bf7b2ceb 8610 {
8611 std::cout << "Syntax error at " << anArg << ".\n";
8612 return 1;
8613 }
8614 }
1beb58d7 8615 }
08f8a185 8616 else if (anArg == "-format")
8617 {
8618 if (++anArgIter >= theArgNb)
8619 {
8620 std::cout << "Syntax error at " << anArg << ".\n";
8621 return 1;
8622 }
8623 aRecParams.Format = theArgVec[anArgIter];
8624 }
8625 else if (anArg == "-pix_fmt"
8626 || anArg == "-pixfmt"
8627 || anArg == "-pixelformat")
8628 {
8629 if (++anArgIter >= theArgNb)
8630 {
8631 std::cout << "Syntax error at " << anArg << ".\n";
8632 return 1;
8633 }
8634 aRecParams.PixelFormat = theArgVec[anArgIter];
8635 }
8636 else if (anArg == "-codec"
8637 || anArg == "-vcodec"
8638 || anArg == "-videocodec")
8639 {
8640 if (++anArgIter >= theArgNb)
8641 {
8642 std::cout << "Syntax error at " << anArg << ".\n";
8643 return 1;
8644 }
8645 aRecParams.VideoCodec = theArgVec[anArgIter];
8646 }
8647 else if (anArg == "-crf"
8648 || anArg == "-preset"
8649 || anArg == "-qp")
8650 {
8651 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
8652 if (++anArgIter >= theArgNb)
8653 {
8654 std::cout << "Syntax error at " << anArg << ".\n";
8655 return 1;
8656 }
8657
8658 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
8659 }
bf7b2ceb 8660 // animation definition options
1beb58d7 8661 else if (anArg == "-start"
8662 || anArg == "-starttime"
8663 || anArg == "-startpts")
8664 {
8665 if (++anArgIter >= theArgNb)
8666 {
8667 std::cout << "Syntax error at " << anArg << ".\n";
8668 return 1;
8669 }
8670
8671 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
8672 aRootAnimation->UpdateTotalDuration();
8673 }
8674 else if (anArg == "-end"
8675 || anArg == "-endtime"
8676 || anArg == "-endpts")
8677 {
8678 if (++anArgIter >= theArgNb)
8679 {
8680 std::cout << "Syntax error at " << anArg << ".\n";
8681 return 1;
8682 }
8683
8684 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
8685 aRootAnimation->UpdateTotalDuration();
8686 }
8687 else if (anArg == "-dur"
8688 || anArg == "-duration")
8689 {
8690 if (++anArgIter >= theArgNb)
8691 {
8692 std::cout << "Syntax error at " << anArg << ".\n";
8693 return 1;
8694 }
8695
8696 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
8697 aRootAnimation->UpdateTotalDuration();
8698 }
8699 else if (anArg == "-command"
8700 || anArg == "-cmd"
8701 || anArg == "-invoke"
8702 || anArg == "-eval"
8703 || anArg == "-proc")
8704 {
8705 if (++anArgIter >= theArgNb)
8706 {
8707 std::cout << "Syntax error at " << anArg << ".\n";
8708 return 1;
8709 }
8710
8711 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
8712 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
8713 }
8714 else if (anArg == "-objecttrsf"
8715 || anArg == "-objectransformation"
8716 || anArg == "-objtransformation"
8717 || anArg == "-objtrsf"
8718 || anArg == "-object"
8719 || anArg == "-obj")
8720 {
8721 if (++anArgIter >= theArgNb)
8722 {
8723 std::cout << "Syntax error at " << anArg << ".\n";
8724 return 1;
8725 }
8726
8727 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
8728 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
8f521168 8729 Handle(AIS_InteractiveObject) anObject;
8730 if (!aMapOfAIS.Find2 (anObjName, anObject))
1beb58d7 8731 {
8732 std::cout << "Syntax error: wrong object name at " << anArg << "\n";
8733 return 1;
8734 }
8735
1beb58d7 8736 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
8737 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
8738 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
8739 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
8740 Standard_Boolean isTrsfSet = Standard_False;
8741 Standard_Integer aTrsfArgIter = anArgIter + 1;
8742 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
8743 {
8744 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
8745 aTrsfArg.LowerCase();
8746 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
8747 if (aTrsfArg.StartsWith ("-rotation")
8748 || aTrsfArg.StartsWith ("-rot"))
8749 {
8750 isTrsfSet = Standard_True;
8751 if (aTrsfArgIter + 4 >= theArgNb
8752 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
8753 {
8754 std::cout << "Syntax error at " << aTrsfArg << ".\n";
8755 return 1;
8756 }
8757 aTrsfArgIter += 4;
8758 }
8759 else if (aTrsfArg.StartsWith ("-location")
8760 || aTrsfArg.StartsWith ("-loc"))
8761 {
8762 isTrsfSet = Standard_True;
8763 if (aTrsfArgIter + 3 >= theArgNb
8764 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
8765 {
8766 std::cout << "Syntax error at " << aTrsfArg << ".\n";
8767 return 1;
8768 }
8769 aTrsfArgIter += 3;
8770 }
8771 else if (aTrsfArg.StartsWith ("-scale"))
8772 {
8773 isTrsfSet = Standard_True;
8774 if (++aTrsfArgIter >= theArgNb)
8775 {
8776 std::cout << "Syntax error at " << aTrsfArg << ".\n";
8777 return 1;
8778 }
8779
8780 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
8781 if (!aScaleStr.IsRealValue())
8782 {
8783 std::cout << "Syntax error at " << aTrsfArg << ".\n";
8784 return 1;
8785 }
8786 aScales[anIndex] = aScaleStr.RealValue();
8787 }
8788 else
8789 {
8790 anArgIter = aTrsfArgIter - 1;
8791 break;
8792 }
8793 }
8794 if (!isTrsfSet)
8795 {
8796 std::cout << "Syntax error at " << anArg << ".\n";
8797 return 1;
8798 }
8799 else if (aTrsfArgIter >= theArgNb)
8800 {
8801 anArgIter = theArgNb;
8802 }
8803
8804 aTrsfs[0].SetRotation (aRotQuats[0]);
8805 aTrsfs[1].SetRotation (aRotQuats[1]);
8806 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
8807 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
8808 aTrsfs[0].SetScaleFactor (aScales[0]);
8809 aTrsfs[1].SetScaleFactor (aScales[1]);
8810
8811 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
8812 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
8813 }
8814 else if (anArg == "-viewtrsf"
8815 || anArg == "-view")
8816 {
8817 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
8818 if (aCamAnimation.IsNull())
8819 {
8820 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
8821 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
8822 }
8823
8824 Handle(Graphic3d_Camera) aCams[2] =
8825 {
8826 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
8827 new Graphic3d_Camera (aCamAnimation->View()->Camera())
8828 };
8829
8830 Standard_Boolean isTrsfSet = Standard_False;
8831 Standard_Integer aViewArgIter = anArgIter + 1;
8832 for (; aViewArgIter < theArgNb; ++aViewArgIter)
8833 {
8834 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
8835 aViewArg.LowerCase();
8836 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
8837 if (aViewArg.StartsWith ("-scale"))
8838 {
8839 isTrsfSet = Standard_True;
8840 if (++aViewArgIter >= theArgNb)
8841 {
8842 std::cout << "Syntax error at " << anArg << ".\n";
8843 return 1;
8844 }
8845
8846 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
8847 if (!aScaleStr.IsRealValue())
8848 {
8849 std::cout << "Syntax error at " << aViewArg << ".\n";
8850 return 1;
8851 }
8852 Standard_Real aScale = aScaleStr.RealValue();
8853 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
8854 aCams[anIndex]->SetScale (aScale);
8855 }
8856 else if (aViewArg.StartsWith ("-eye")
8857 || aViewArg.StartsWith ("-center")
8858 || aViewArg.StartsWith ("-at")
8859 || aViewArg.StartsWith ("-up"))
8860 {
8861 isTrsfSet = Standard_True;
8862 gp_XYZ anXYZ;
8863 if (aViewArgIter + 3 >= theArgNb
8864 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
8865 {
8866 std::cout << "Syntax error at " << aViewArg << ".\n";
8867 return 1;
8868 }
8869 aViewArgIter += 3;
8870
8871 if (aViewArg.StartsWith ("-eye"))
8872 {
8873 aCams[anIndex]->SetEye (anXYZ);
8874 }
8875 else if (aViewArg.StartsWith ("-center")
8876 || aViewArg.StartsWith ("-at"))
8877 {
8878 aCams[anIndex]->SetCenter (anXYZ);
8879 }
8880 else if (aViewArg.StartsWith ("-up"))
8881 {
8882 aCams[anIndex]->SetUp (anXYZ);
8883 }
8884 }
8885 else
8886 {
8887 anArgIter = aViewArgIter - 1;
8888 break;
8889 }
8890 }
8891 if (!isTrsfSet)
8892 {
8893 std::cout << "Syntax error at " << anArg << ".\n";
8894 return 1;
8895 }
8896 else if (aViewArgIter >= theArgNb)
8897 {
8898 anArgIter = theArgNb;
8899 }
8900
8901 aCamAnimation->SetCameraStart(aCams[0]);
8902 aCamAnimation->SetCameraEnd (aCams[1]);
197ac94e 8903 }
8904 else
8905 {
1beb58d7 8906 std::cout << "Syntax error at " << anArg << ".\n";
8907 return 1;
197ac94e 8908 }
8909 }
1beb58d7 8910
08f8a185 8911 if (!toPlay && aRecFile.IsEmpty())
197ac94e 8912 {
1beb58d7 8913 return 0;
8914 }
8915
8916 // Start animation timeline and process frame updating.
8917 TheIsAnimating = Standard_True;
8918 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
8919 Handle(Graphic3d_Camera) aCameraBack = new Graphic3d_Camera (aView->Camera());
bf7b2ceb 8920 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
1beb58d7 8921 if (isFreeCamera)
8922 {
8923 aView->Camera()->Copy (aCameraBack);
8924 }
8925
8926 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
08f8a185 8927 if (aRecParams.FpsNum <= 0)
1beb58d7 8928 {
8929 while (!anAnimation->IsStopped())
197ac94e 8930 {
1beb58d7 8931 aCameraBack->Copy (aView->Camera());
8932 const Standard_Real aPts = anAnimation->UpdateTimer();
8933 if (isFreeCamera)
8934 {
8935 aView->Camera()->Copy (aCameraBack);
8936 }
8937
8938 if (aPts >= anUpperPts)
8939 {
8940 anAnimation->Pause();
8941 break;
8942 }
8943
8944 if (aView->IsInvalidated())
8945 {
8946 aView->Redraw();
8947 }
8948 else
8949 {
8950 aView->RedrawImmediate();
8951 }
8952
8953 if (!isLockLoop)
8954 {
8955 // handle user events
8956 theDI.Eval ("after 1 set waiter 1");
8957 theDI.Eval ("vwait waiter");
8958 }
8959 if (!TheIsAnimating)
8960 {
8961 anAnimation->Pause();
8962 theDI << aPts;
8963 break;
8964 }
8965 }
8966
8967 if (aView->IsInvalidated())
8968 {
8969 aView->Redraw();
197ac94e 8970 }
8971 else
8972 {
1beb58d7 8973 aView->RedrawImmediate();
197ac94e 8974 }
8975 }
1beb58d7 8976 else
197ac94e 8977 {
bf7b2ceb 8978 OSD_Timer aPerfTimer;
8979 aPerfTimer.Start();
1beb58d7 8980
08f8a185 8981 Handle(Image_VideoRecorder) aRecorder;
8982 ImageFlipper aFlipper;
8983 Handle(Draw_ProgressIndicator) aProgress;
8984 if (!aRecFile.IsEmpty())
8985 {
8986 if (aRecParams.Width <= 0
8987 || aRecParams.Height <= 0)
8988 {
8989 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
8990 }
8991
8992 aRecorder = new Image_VideoRecorder();
8993 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
8994 {
8995 std::cout << "Error: failed to open video file for recording\n";
8996 return 0;
8997 }
8998
8999 aProgress = new Draw_ProgressIndicator (theDI, 1);
9000 }
9001
1beb58d7 9002 // Manage frame-rated animation here
9003 Standard_Real aPts = aPlayStartTime;
bf7b2ceb 9004 int64_t aNbFrames = 0;
08f8a185 9005 Message_ProgressSentry aPSentry (aProgress, "Video recording, sec", 0, Max (1, Standard_Integer(aPlayDuration / aPlaySpeed)), 1);
9006 Standard_Integer aSecondsProgress = 0;
9007 for (; aPts <= anUpperPts && aPSentry.More();)
197ac94e 9008 {
08f8a185 9009 const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
bf7b2ceb 9010 aPts = aPlayStartTime + aRecPts;
9011 ++aNbFrames;
1beb58d7 9012 if (!anAnimation->Update (aPts))
9013 {
9014 break;
9015 }
9016
08f8a185 9017 if (!aRecorder.IsNull())
9018 {
9019 V3d_ImageDumpOptions aDumpParams;
9020 aDumpParams.Width = aRecParams.Width;
9021 aDumpParams.Height = aRecParams.Height;
9022 aDumpParams.BufferType = Graphic3d_BT_RGBA;
9023 aDumpParams.StereoOptions = V3d_SDO_MONO;
9024 aDumpParams.ToAdjustAspect = Standard_True;
9025 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
9026 {
9027 std::cout << "Error: view dump is failed!\n";
9028 return 0;
9029 }
9030 aFlipper.FlipY (aRecorder->ChangeFrame());
9031 if (!aRecorder->PushFrame())
9032 {
9033 return 0;
9034 }
9035 }
9036 else
9037 {
9038 aView->Redraw();
9039 }
9040
9041 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
9042 {
9043 aPSentry.Next();
9044 ++aSecondsProgress;
9045 }
197ac94e 9046 }
bf7b2ceb 9047
9048 aPerfTimer.Stop();
1beb58d7 9049 anAnimation->Stop();
bf7b2ceb 9050 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
9051 theDI << "Average FPS: " << aRecFps << "\n"
9052 << "Nb. Frames: " << Standard_Real(aNbFrames);
9053
9054 aView->Redraw();
197ac94e 9055 }
9056
1beb58d7 9057 aView->SetImmediateUpdate (wasImmediateUpdate);
9058 TheIsAnimating = Standard_False;
4754e164 9059 return 0;
9060}
9061
1beb58d7 9062
4754e164 9063//=======================================================================
9064//function : VChangeSelected
dc3fe572 9065//purpose : Adds the shape to selection or remove one from it
4754e164 9066//=======================================================================
9067static Standard_Integer VChangeSelected (Draw_Interpretor& di,
9068 Standard_Integer argc,
9069 const char ** argv)
9070{
9071 if(argc != 2)
9072 {
9073 di<<"Usage : " << argv[0] << " shape \n";
9074 return 1;
9075 }
9076 //get AIS_Shape:
4754e164 9077 TCollection_AsciiString aName(argv[1]);
9078 Handle(AIS_InteractiveObject) anAISObject;
8f521168 9079 if (!GetMapOfAIS().Find2 (aName, anAISObject)
9080 || anAISObject.IsNull())
4754e164 9081 {
9082 di<<"Use 'vdisplay' before";
9083 return 1;
9084 }
4754e164 9085
8f521168 9086 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
4754e164 9087 return 0;
9088}
9089
4754e164 9090//=======================================================================
9091//function : VNbSelected
dc3fe572 9092//purpose : Returns number of selected objects
4754e164 9093//=======================================================================
9094static Standard_Integer VNbSelected (Draw_Interpretor& di,
9095 Standard_Integer argc,
9096 const char ** argv)
9097{
9098 if(argc != 1)
9099 {
9100 di << "Usage : " << argv[0] << "\n";
9101 return 1;
9102 }
9103 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9104 if(aContext.IsNull())
9105 {
9106 di << "use 'vinit' command before " << argv[0] << "\n";
9107 return 1;
9108 }
9109 di << aContext->NbSelected() << "\n";
9110 return 0;
9111}
9112
4754e164 9113//=======================================================================
9114//function : VPurgeDisplay
dc3fe572 9115//purpose : Switches altialiasing on or off
4754e164 9116//=======================================================================
9117static Standard_Integer VPurgeDisplay (Draw_Interpretor& di,
9118 Standard_Integer argc,
9119 const char ** argv)
9120{
eb4320f2 9121 if (argc > 1)
4754e164 9122 {
eb4320f2 9123 di << "Usage : " << argv[0] << "\n";
4754e164 9124 return 1;
9125 }
4754e164 9126 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9127 if (aContext.IsNull())
9128 {
9129 di << "use 'vinit' command before " << argv[0] << "\n";
9130 return 1;
9131 }
404c8936 9132
eb4320f2 9133 di << aContext->PurgeDisplay() << "\n";
4754e164 9134 return 0;
9135}
9136
9137//=======================================================================
9138//function : VSetViewSize
9139//purpose :
9140//=======================================================================
9141static Standard_Integer VSetViewSize (Draw_Interpretor& di,
9142 Standard_Integer argc,
9143 const char ** argv)
9144{
9145 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9146 if(aContext.IsNull())
9147 {
9148 di << "use 'vinit' command before " << argv[0] << "\n";
9149 return 1;
9150 }
9151 if(argc != 2)
9152 {
9153 di<<"Usage : " << argv[0] << " Size\n";
9154 return 1;
9155 }
6b62b2da 9156 Standard_Real aSize = Draw::Atof (argv[1]);
4754e164 9157 if (aSize <= 0.)
9158 {
9159 di<<"Bad Size value : " << aSize << "\n";
9160 return 1;
9161 }
9162
9163 Handle(V3d_View) aView = ViewerTest::CurrentView();
9164 aView->SetSize(aSize);
9165 return 0;
9166}
9167
9168//=======================================================================
9169//function : VMoveView
9170//purpose :
9171//=======================================================================
9172static Standard_Integer VMoveView (Draw_Interpretor& di,
9173 Standard_Integer argc,
9174 const char ** argv)
9175{
9176 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9177 if(aContext.IsNull())
9178 {
9179 di << "use 'vinit' command before " << argv[0] << "\n";
9180 return 1;
9181 }
9182 if(argc < 4 || argc > 5)
9183 {
9184 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9185 return 1;
9186 }
6b62b2da 9187 Standard_Real Dx = Draw::Atof (argv[1]);
9188 Standard_Real Dy = Draw::Atof (argv[2]);
9189 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 9190 Standard_Boolean aStart = Standard_True;
9191 if (argc == 5)
9192 {
6b62b2da 9193 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9194 }
9195
9196 Handle(V3d_View) aView = ViewerTest::CurrentView();
9197 aView->Move(Dx,Dy,Dz,aStart);
9198 return 0;
9199}
9200
9201//=======================================================================
9202//function : VTranslateView
9203//purpose :
9204//=======================================================================
9205static Standard_Integer VTranslateView (Draw_Interpretor& di,
9206 Standard_Integer argc,
9207 const char ** argv)
9208{
9209 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9210 if(aContext.IsNull())
9211 {
9212 di << "use 'vinit' command before " << argv[0] << "\n";
9213 return 1;
9214 }
9215 if(argc < 4 || argc > 5)
9216 {
9217 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
9218 return 1;
9219 }
6b62b2da 9220 Standard_Real Dx = Draw::Atof (argv[1]);
9221 Standard_Real Dy = Draw::Atof (argv[2]);
9222 Standard_Real Dz = Draw::Atof (argv[3]);
4754e164 9223 Standard_Boolean aStart = Standard_True;
dc3fe572 9224 if (argc == 5)
4754e164 9225 {
6b62b2da 9226 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9227 }
9228
9229 Handle(V3d_View) aView = ViewerTest::CurrentView();
9230 aView->Translate(Dx,Dy,Dz,aStart);
9231 return 0;
9232}
9233
9234//=======================================================================
9235//function : VTurnView
9236//purpose :
9237//=======================================================================
9238static Standard_Integer VTurnView (Draw_Interpretor& di,
9239 Standard_Integer argc,
9240 const char ** argv)
9241{
9242 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
9243 if(aContext.IsNull()) {
9244 di << "use 'vinit' command before " << argv[0] << "\n";
9245 return 1;
9246 }
9247 if(argc < 4 || argc > 5){
9248 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
9249 return 1;
9250 }
6b62b2da 9251 Standard_Real Ax = Draw::Atof (argv[1]);
9252 Standard_Real Ay = Draw::Atof (argv[2]);
9253 Standard_Real Az = Draw::Atof (argv[3]);
4754e164 9254 Standard_Boolean aStart = Standard_True;
dc3fe572 9255 if (argc == 5)
4754e164 9256 {
6b62b2da 9257 aStart = (Draw::Atoi (argv[4]) > 0);
4754e164 9258 }
9259
9260 Handle(V3d_View) aView = ViewerTest::CurrentView();
9261 aView->Turn(Ax,Ay,Az,aStart);
9262 return 0;
9263}
9264
269294d6 9265//==============================================================================
9266//function : VTextureEnv
9267//purpose : ENables or disables environment mapping
9268//==============================================================================
9269class OCC_TextureEnv : public Graphic3d_TextureEnv
9270{
9271public:
9272 OCC_TextureEnv(const Standard_CString FileName);
9273 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
9274 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
9275 const Standard_Boolean theModulateFlag,
9276 const Graphic3d_TypeOfTextureFilter theFilter,
9277 const Standard_ShortReal theXScale,
9278 const Standard_ShortReal theYScale,
9279 const Standard_ShortReal theXShift,
9280 const Standard_ShortReal theYShift,
9281 const Standard_ShortReal theAngle);
68858c7d 9282 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
269294d6 9283};
a3f6f591 9284DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
ec357c5c 9285
269294d6 9286OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
9287 : Graphic3d_TextureEnv(theFileName)
9288{
9289}
9290
9291OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
9292 : Graphic3d_TextureEnv(theTexId)
9293{
9294}
9295
9296void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
9297 const Standard_Boolean theModulateFlag,
9298 const Graphic3d_TypeOfTextureFilter theFilter,
9299 const Standard_ShortReal theXScale,
9300 const Standard_ShortReal theYScale,
9301 const Standard_ShortReal theXShift,
9302 const Standard_ShortReal theYShift,
9303 const Standard_ShortReal theAngle)
9304{
9305 myParams->SetRepeat (theRepeatFlag);
9306 myParams->SetModulate (theModulateFlag);
9307 myParams->SetFilter (theFilter);
9308 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
9309 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
9310 myParams->SetRotation (theAngle);
9311}
9312
35e08fe8 9313static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
269294d6 9314{
9315 // get the active view
9316 Handle(V3d_View) aView = ViewerTest::CurrentView();
9317 if (aView.IsNull())
9318 {
9319 std::cerr << "No active view. Please call vinit.\n";
9320 return 1;
9321 }
9322
9323 // Checking the input arguments
9324 Standard_Boolean anEnableFlag = Standard_False;
9325 Standard_Boolean isOk = theArgNb >= 2;
9326 if (isOk)
9327 {
9328 TCollection_AsciiString anEnableOpt(theArgVec[1]);
9329 anEnableFlag = anEnableOpt.IsEqual("on");
9330 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
9331 }
9332 if (anEnableFlag)
9333 {
9334 isOk = (theArgNb == 3 || theArgNb == 11);
9335 if (isOk)
9336 {
9337 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9338 isOk = (!aTextureOpt.IsIntegerValue() ||
9339 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
9340
9341 if (isOk && theArgNb == 11)
9342 {
9343 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
9344 aModulateOpt(theArgVec[4]),
9345 aFilterOpt (theArgVec[5]),
9346 aSScaleOpt (theArgVec[6]),
9347 aTScaleOpt (theArgVec[7]),
9348 aSTransOpt (theArgVec[8]),
9349 aTTransOpt (theArgVec[9]),
9350 anAngleOpt (theArgVec[10]);
9351 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
9352 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
9353 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
9354 aSScaleOpt.IsRealValue() && aTScaleOpt.IsRealValue() &&
9355 aSTransOpt.IsRealValue() && aTTransOpt.IsRealValue() &&
9356 anAngleOpt.IsRealValue());
9357 }
9358 }
9359 }
9360
9361 if (!isOk)
9362 {
9363 std::cerr << "Usage :" << std::endl;
9364 std::cerr << theArgVec[0] << " off" << std::endl;
9365 std::cerr << 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]" << std::endl;
9366 return 1;
9367 }
9368
9369 if (anEnableFlag)
9370 {
9371 TCollection_AsciiString aTextureOpt(theArgVec[2]);
9372 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
9373 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
9374 new OCC_TextureEnv(theArgVec[2]);
9375
9376 if (theArgNb == 11)
9377 {
9378 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
9379 aTexEnv->SetTextureParameters(
9380 aRepeatOpt. IsEqual("repeat"),
9381 aModulateOpt.IsEqual("modulate"),
9382 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
9383 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
9384 Graphic3d_TOTF_TRILINEAR,
9385 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
9386 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
9387 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
9388 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
9389 (Standard_ShortReal)Draw::Atof(theArgVec[10])
9390 );
9391 }
9392 aView->SetTextureEnv(aTexEnv);
269294d6 9393 }
9394 else // Disabling environment mapping
9395 {
269294d6 9396 Handle(Graphic3d_TextureEnv) aTexture;
9397 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
9398 }
9399
9400 aView->Redraw();
9401 return 0;
9402}
9403
3e05329c 9404namespace
9405{
9406 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
9407
9408 //! Remove registered clipping plane from all views and objects.
9409 static void removePlane (MapOfPlanes& theRegPlanes,
9410 const TCollection_AsciiString& theName)
9411 {
9412 Handle(Graphic3d_ClipPlane) aClipPlane;
9413 if (!theRegPlanes.Find (theName, aClipPlane))
9414 {
9415 std::cout << "Warning: no such plane.\n";
9416 return;
9417 }
9418
9419 theRegPlanes.UnBind (theName);
9420 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
9421 anIObjIt.More(); anIObjIt.Next())
9422 {
8f521168 9423 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
3e05329c 9424 aPrs->RemoveClipPlane (aClipPlane);
9425 }
9426
9427 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
9428 aViewIt.More(); aViewIt.Next())
9429 {
9430 const Handle(V3d_View)& aView = aViewIt.Key2();
9431 aView->RemoveClipPlane(aClipPlane);
9432 }
9433
9434 ViewerTest::RedrawAllViews();
9435 }
9436}
9437
4269bd1b 9438//===============================================================================================
9439//function : VClipPlane
9440//purpose :
9441//===============================================================================================
9442static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
9443{
9444 // use short-cut for created clip planes map of created (or "registered by name") clip planes
4269bd1b 9445 static MapOfPlanes aRegPlanes;
9446
9447 if (theArgsNb < 2)
9448 {
3e05329c 9449 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
9450 {
9451 theDi << aPlaneIter.Key() << " ";
9452 }
9453 return 0;
4269bd1b 9454 }
9455
9456 TCollection_AsciiString aCommand (theArgVec[1]);
3e05329c 9457 aCommand.LowerCase();
9458 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
9459 if (anActiveView.IsNull())
9460 {
9461 std::cout << "Error: no active view.\n";
9462 return 1;
9463 }
4269bd1b 9464
9465 // print maximum number of planes for current viewer
3e05329c 9466 if (aCommand == "-maxplanes"
9467 || aCommand == "maxplanes")
4269bd1b 9468 {
3e05329c 9469 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
9470 << " plane slots provided by driver.\n";
4269bd1b 9471 return 0;
9472 }
9473
9474 // create / delete plane instance
3e05329c 9475 if (aCommand == "-create"
9476 || aCommand == "create"
9477 || aCommand == "-delete"
9478 || aCommand == "delete"
9479 || aCommand == "-clone"
9480 || aCommand == "clone")
4269bd1b 9481 {
9482 if (theArgsNb < 3)
9483 {
3e05329c 9484 std::cout << "Syntax error: plane name is required.\n";
4269bd1b 9485 return 1;
9486 }
9487
3e05329c 9488 Standard_Boolean toCreate = aCommand == "-create"
9489 || aCommand == "create";
9490 Standard_Boolean toClone = aCommand == "-clone"
9491 || aCommand == "clone";
9492 Standard_Boolean toDelete = aCommand == "-delete"
9493 || aCommand == "delete";
4269bd1b 9494 TCollection_AsciiString aPlane (theArgVec[2]);
9495
9496 if (toCreate)
9497 {
9498 if (aRegPlanes.IsBound (aPlane))
9499 {
3e05329c 9500 std::cout << "Warning: existing plane has been overridden.\n";
9501 toDelete = true;
9502 }
9503 else
9504 {
9505 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9506 return 0;
4269bd1b 9507 }
4269bd1b 9508 }
9509 else if (toClone) // toClone
9510 {
9511 if (!aRegPlanes.IsBound (aPlane))
9512 {
3e05329c 9513 std::cout << "Error: no such plane.\n";
4269bd1b 9514 return 1;
9515 }
3e05329c 9516 else if (theArgsNb < 4)
4269bd1b 9517 {
3e05329c 9518 std::cout << "Syntax error: enter name for new plane.\n";
4269bd1b 9519 return 1;
9520 }
9521
9522 TCollection_AsciiString aClone (theArgVec[3]);
9523 if (aRegPlanes.IsBound (aClone))
9524 {
3e05329c 9525 std::cout << "Error: plane name is in use.\n";
4269bd1b 9526 return 1;
9527 }
9528
9529 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
9530
9531 aRegPlanes.Bind (aClone, aClipPlane->Clone());
3e05329c 9532 return 0;
4269bd1b 9533 }
4269bd1b 9534
3e05329c 9535 if (toDelete)
9536 {
9537 if (aPlane == "ALL"
9538 || aPlane == "all"
9539 || aPlane == "*")
4269bd1b 9540 {
3e05329c 9541 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
9542 {
9543 aPlane = aPlaneIter.Key();
9544 removePlane (aRegPlanes, aPlane);
9545 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
9546 }
4269bd1b 9547 }
3e05329c 9548 else
4269bd1b 9549 {
3e05329c 9550 removePlane (aRegPlanes, aPlane);
4269bd1b 9551 }
4269bd1b 9552 }
9553
3e05329c 9554 if (toCreate)
9555 {
9556 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
9557 }
4269bd1b 9558 return 0;
9559 }
9560
9561 // set / unset plane command
3e05329c 9562 if (aCommand == "set"
9563 || aCommand == "unset")
4269bd1b 9564 {
3e05329c 9565 if (theArgsNb < 5)
4269bd1b 9566 {
3e05329c 9567 std::cout << "Syntax error: need more arguments.\n";
4269bd1b 9568 return 1;
9569 }
9570
3e05329c 9571 // redirect to new syntax
9572 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
9573 anArgVec.SetValue (1, theArgVec[0]);
9574 anArgVec.SetValue (2, theArgVec[2]);
9575 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
9576 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
4269bd1b 9577 {
3e05329c 9578 anArgVec.SetValue (anIt, theArgVec[anIt]);
4269bd1b 9579 }
9580
3e05329c 9581 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
4269bd1b 9582 }
9583
9584 // change plane command
3e05329c 9585 TCollection_AsciiString aPlaneName;
9586 Handle(Graphic3d_ClipPlane) aClipPlane;
9587 Standard_Integer anArgIter = 0;
9588 if (aCommand == "-change"
9589 || aCommand == "change")
4269bd1b 9590 {
3e05329c 9591 // old syntax support
9592 if (theArgsNb < 3)
4269bd1b 9593 {
3e05329c 9594 std::cout << "Syntax error: need more arguments.\n";
4269bd1b 9595 return 1;
9596 }
9597
3e05329c 9598 anArgIter = 3;
9599 aPlaneName = theArgVec[2];
9600 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
4269bd1b 9601 {
3e05329c 9602 std::cout << "Error: no such plane '" << aPlaneName << "'.\n";
4269bd1b 9603 return 1;
9604 }
3e05329c 9605 }
9606 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
9607 {
9608 anArgIter = 2;
9609 aPlaneName = theArgVec[1];
9610 }
9611 else
9612 {
9613 anArgIter = 2;
9614 aPlaneName = theArgVec[1];
9615 aClipPlane = new Graphic3d_ClipPlane();
9616 aRegPlanes.Bind (aPlaneName, aClipPlane);
9617 theDi << "Created new plane " << aPlaneName << ".\n";
9618 }
4269bd1b 9619
3e05329c 9620 if (theArgsNb - anArgIter < 1)
9621 {
9622 std::cout << "Syntax error: need more arguments.\n";
9623 return 1;
9624 }
4269bd1b 9625
3e05329c 9626 for (; anArgIter < theArgsNb; ++anArgIter)
9627 {
9628 const char** aChangeArgs = theArgVec + anArgIter;
9629 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
9630 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
9631 aChangeArg.LowerCase();
4269bd1b 9632
3e05329c 9633 Standard_Boolean toEnable = Standard_True;
9634 if (ViewerTest::ParseOnOff (aChangeArgs[0], toEnable))
4269bd1b 9635 {
3e05329c 9636 aClipPlane->SetOn (toEnable);
4269bd1b 9637 }
25c35042 9638 else if (aChangeArg.StartsWith ("-equation")
9639 || aChangeArg.StartsWith ("equation"))
4269bd1b 9640 {
3e05329c 9641 if (aNbChangeArgs < 5)
4269bd1b 9642 {
3e05329c 9643 std::cout << "Syntax error: need more arguments.\n";
4269bd1b 9644 return 1;
9645 }
9646
25c35042 9647 Standard_Integer aSubIndex = 1;
9648 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
9649 if (aPrefixLen < aChangeArg.Length())
9650 {
9651 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
9652 if (!aSubStr.IsIntegerValue()
9653 || aSubStr.IntegerValue() <= 0)
9654 {
9655 std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n";
9656 return 1;
9657 }
9658 aSubIndex = aSubStr.IntegerValue();
9659 }
9660
9661 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
9662 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
9663 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
9664 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
9665 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9666 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
9667 {
9668 if (aSubPln->ChainNextPlane().IsNull())
9669 {
9670 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9671 }
9672 aSubPln = aSubPln->ChainNextPlane();
9673 }
9674 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9675 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
3e05329c 9676 anArgIter += 4;
4269bd1b 9677 }
25c35042 9678 else if ((aChangeArg == "-boxinterior"
9679 || aChangeArg == "-boxint"
9680 || aChangeArg == "-box")
9681 && aNbChangeArgs >= 7)
9682 {
9683 Graphic3d_BndBox3d aBndBox;
9684 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
9685 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
9686 anArgIter += 6;
9687
9688 Standard_Integer aNbSubPlanes = 6;
9689 const Graphic3d_Vec3d aDirArray[6] =
9690 {
9691 Graphic3d_Vec3d (-1, 0, 0),
9692 Graphic3d_Vec3d ( 1, 0, 0),
9693 Graphic3d_Vec3d ( 0,-1, 0),
9694 Graphic3d_Vec3d ( 0, 1, 0),
9695 Graphic3d_Vec3d ( 0, 0,-1),
9696 Graphic3d_Vec3d ( 0, 0, 1),
9697 };
9698 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
9699 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
9700 {
9701 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
9702 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
9703 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
9704 if (aSubPlaneIter + 1 == aNbSubPlanes)
9705 {
9706 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
9707 }
9708 else
9709 {
9710 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
9711 }
9712 aSubPln = aSubPln->ChainNextPlane();
9713 }
9714 }
3e05329c 9715 else if (aChangeArg == "-capping"
9716 || aChangeArg == "capping")
4269bd1b 9717 {
3e05329c 9718 if (aNbChangeArgs < 2)
4269bd1b 9719 {
3e05329c 9720 std::cout << "Syntax error: need more arguments.\n";
4269bd1b 9721 return 1;
9722 }
9723
3e05329c 9724 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9725 {
3e05329c 9726 aClipPlane->SetCapping (toEnable);
9727 anArgIter += 1;
9728 }
9729 else
9730 {
9731 // just skip otherwise (old syntax)
9732 }
9733 }
9734 else if (aChangeArg == "-useobjectmaterial"
9735 || aChangeArg == "-useobjectmat"
9736 || aChangeArg == "-useobjmat"
9737 || aChangeArg == "-useobjmaterial")
9738 {
9739 if (aNbChangeArgs < 2)
9740 {
9741 std::cout << "Syntax error: need more arguments.\n";
4269bd1b 9742 return 1;
9743 }
9744
3e05329c 9745 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
4269bd1b 9746 {
3e05329c 9747 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
9748 anArgIter += 1;
4269bd1b 9749 }
3e05329c 9750 }
9751 else if (aChangeArg == "-useobjecttexture"
9752 || aChangeArg == "-useobjecttex"
9753 || aChangeArg == "-useobjtexture"
9754 || aChangeArg == "-useobjtex")
9755 {
9756 if (aNbChangeArgs < 2)
4269bd1b 9757 {
3e05329c 9758 std::cout << "Syntax error: need more arguments.\n";
9759 return 1;
9760 }
4269bd1b 9761
3e05329c 9762 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9763 {
9764 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
9765 anArgIter += 1;
9766 }
9767 }
9768 else if (aChangeArg == "-useobjectshader"
9769 || aChangeArg == "-useobjshader")
9770 {
9771 if (aNbChangeArgs < 2)
9772 {
9773 std::cout << "Syntax error: need more arguments.\n";
9774 return 1;
9775 }
4269bd1b 9776
3e05329c 9777 if (ViewerTest::ParseOnOff (aChangeArgs[1], toEnable))
9778 {
9779 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
9780 anArgIter += 1;
4269bd1b 9781 }
3e05329c 9782 }
9783 else if (aChangeArg == "-color"
9784 || aChangeArg == "color")
9785 {
9786 Quantity_Color aColor;
9787 Standard_Integer aNbParsed = ViewerTest::ParseColor (aNbChangeArgs - 1,
9788 aChangeArgs + 1,
9789 aColor);
9790 if (aNbParsed == 0)
4269bd1b 9791 {
3e05329c 9792 std::cout << "Syntax error: need more arguments.\n";
9793 return 1;
9794 }
4269bd1b 9795
3e05329c 9796 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9797 aMat.SetAmbientColor (aColor);
9798 aMat.SetDiffuseColor (aColor);
9799 aClipPlane->SetCappingMaterial (aMat);
9800 anArgIter += aNbParsed;
9801 }
1b661a81 9802 else if ((aChangeArg == "-transparency"
9803 || aChangeArg == "-transp")
9804 && aNbChangeArgs >= 2)
9805 {
9806 TCollection_AsciiString aValStr (aChangeArgs[1]);
9807 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
9808 if (aValStr.IsRealValue())
9809 {
9810 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
9811 aMat.SetTransparency ((float )aValStr.RealValue());
9812 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
9813 aClipPlane->SetCappingMaterial (aMat);
9814 }
9815 else
9816 {
9817 aValStr.LowerCase();
9818 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
9819 if (aValStr == "opaque")
9820 {
9821 aMode = Graphic3d_AlphaMode_Opaque;
9822 }
9823 else if (aValStr == "mask")
9824 {
9825 aMode = Graphic3d_AlphaMode_Mask;
9826 }
9827 else if (aValStr == "blend")
9828 {
9829 aMode = Graphic3d_AlphaMode_Blend;
9830 }
9831 else if (aValStr == "blendauto")
9832 {
9833 aMode = Graphic3d_AlphaMode_BlendAuto;
9834 }
9835 else
9836 {
9837 std::cout << "Syntax error at '" << aValStr << "'\n";
9838 return 1;
9839 }
9840 anAspect->SetAlphaMode (aMode);
9841 aClipPlane->SetCappingAspect (anAspect);
9842 }
9843 anArgIter += 1;
9844 }
3e05329c 9845 else if (aChangeArg == "-texname"
9846 || aChangeArg == "texname")
9847 {
9848 if (aNbChangeArgs < 2)
9849 {
9850 std::cout << "Syntax error: need more arguments.\n";
9851 return 1;
9852 }
4269bd1b 9853
3e05329c 9854 TCollection_AsciiString aTextureName (aChangeArgs[1]);
9855 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
9856 if (!aTexture->IsDone())
9857 {
9858 aClipPlane->SetCappingTexture (NULL);
4269bd1b 9859 }
3e05329c 9860 else
4269bd1b 9861 {
3e05329c 9862 aTexture->EnableModulate();
9863 aTexture->EnableRepeat();
9864 aClipPlane->SetCappingTexture (aTexture);
9865 }
9866 anArgIter += 1;
9867 }
9868 else if (aChangeArg == "-texscale"
9869 || aChangeArg == "texscale")
9870 {
9871 if (aClipPlane->CappingTexture().IsNull())
9872 {
9873 std::cout << "Error: no texture is set.\n";
9874 return 1;
9875 }
4269bd1b 9876
3e05329c 9877 if (aNbChangeArgs < 3)
9878 {
9879 std::cout << "Syntax error: need more arguments.\n";
9880 return 1;
9881 }
4269bd1b 9882
3e05329c 9883 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9884 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9885 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
9886 anArgIter += 2;
9887 }
9888 else if (aChangeArg == "-texorigin"
9889 || aChangeArg == "texorigin") // texture origin
9890 {
9891 if (aClipPlane->CappingTexture().IsNull())
9892 {
9893 std::cout << "Error: no texture is set.\n";
9894 return 1;
9895 }
4269bd1b 9896
3e05329c 9897 if (aNbChangeArgs < 3)
9898 {
9899 std::cout << "Syntax error: need more arguments.\n";
9900 return 1;
4269bd1b 9901 }
3e05329c 9902
9903 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9904 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
9905
9906 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
9907 anArgIter += 2;
9908 }
9909 else if (aChangeArg == "-texrotate"
9910 || aChangeArg == "texrotate") // texture rotation
9911 {
9912 if (aClipPlane->CappingTexture().IsNull())
4269bd1b 9913 {
3e05329c 9914 std::cout << "Error: no texture is set.\n";
9915 return 1;
9916 }
4269bd1b 9917
3e05329c 9918 if (aNbChangeArgs < 2)
9919 {
9920 std::cout << "Syntax error: need more arguments.\n";
9921 return 1;
9922 }
4269bd1b 9923
3e05329c 9924 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
9925 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
9926 anArgIter += 1;
9927 }
9928 else if (aChangeArg == "-hatch"
9929 || aChangeArg == "hatch")
9930 {
9931 if (aNbChangeArgs < 2)
9932 {
9933 std::cout << "Syntax error: need more arguments.\n";
9934 return 1;
9935 }
4269bd1b 9936
3e05329c 9937 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
9938 aHatchStr.LowerCase();
9939 if (aHatchStr == "on")
9940 {
9941 aClipPlane->SetCappingHatchOn();
9942 }
9943 else if (aHatchStr == "off")
9944 {
9945 aClipPlane->SetCappingHatchOff();
4269bd1b 9946 }
3e05329c 9947 else
4269bd1b 9948 {
3e05329c 9949 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
9950 }
9951 anArgIter += 1;
9952 }
9953 else if (aChangeArg == "-delete"
9954 || aChangeArg == "delete")
9955 {
9956 removePlane (aRegPlanes, aPlaneName);
9957 return 0;
9958 }
9959 else if (aChangeArg == "-set"
32ca7711 9960 || aChangeArg == "-unset"
9961 || aChangeArg == "-setoverrideglobal")
3e05329c 9962 {
9963 // set / unset plane command
32ca7711 9964 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
9965 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
3e05329c 9966 Standard_Integer anIt = 1;
9967 for (; anIt < aNbChangeArgs; ++anIt)
9968 {
9969 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
9970 if (anEntityName.IsEmpty()
9971 || anEntityName.Value (1) == '-')
4269bd1b 9972 {
3e05329c 9973 break;
4269bd1b 9974 }
32ca7711 9975 else if (!toOverrideGlobal
9976 && ViewerTest_myViews.IsBound1 (anEntityName))
4269bd1b 9977 {
3e05329c 9978 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
9979 if (toSet)
9980 {
9981 aView->AddClipPlane (aClipPlane);
9982 }
9983 else
9984 {
9985 aView->RemoveClipPlane (aClipPlane);
9986 }
9987 continue;
4269bd1b 9988 }
3e05329c 9989 else if (GetMapOfAIS().IsBound2 (anEntityName))
4269bd1b 9990 {
8f521168 9991 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
3e05329c 9992 if (toSet)
9993 {
9994 aIObj->AddClipPlane (aClipPlane);
9995 }
9996 else
9997 {
9998 aIObj->RemoveClipPlane (aClipPlane);
9999 }
32ca7711 10000 if (!aIObj->ClipPlanes().IsNull())
10001 {
10002 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
10003 }
4269bd1b 10004 }
3e05329c 10005 else
4269bd1b 10006 {
3e05329c 10007 std::cout << "Error: object/view '" << anEntityName << "' is not found!\n";
10008 return 1;
4269bd1b 10009 }
3e05329c 10010 }
10011
10012 if (anIt == 1)
10013 {
10014 // apply to active view
10015 if (toSet)
4269bd1b 10016 {
3e05329c 10017 anActiveView->AddClipPlane (aClipPlane);
4269bd1b 10018 }
10019 else
10020 {
3e05329c 10021 anActiveView->RemoveClipPlane (aClipPlane);
4269bd1b 10022 }
10023 }
3e05329c 10024 else
10025 {
10026 anArgIter = anArgIter + anIt - 1;
10027 }
10028 }
10029 else
10030 {
10031 std::cout << "Syntax error: unknown argument '" << aChangeArg << "'.\n";
10032 return 1;
4269bd1b 10033 }
4269bd1b 10034 }
10035
3e05329c 10036 ViewerTest::RedrawAllViews();
10037 return 0;
4269bd1b 10038}
10039
b5ac8292 10040//===============================================================================================
10041//function : VZRange
10042//purpose :
10043//===============================================================================================
10044static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
10045{
197ac94e 10046 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
10047
10048 if (aCurrentView.IsNull())
b5ac8292 10049 {
197ac94e 10050 std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
b5ac8292 10051 return 1;
10052 }
10053
197ac94e 10054 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
b5ac8292 10055
10056 if (theArgsNb < 2)
10057 {
10058 theDi << "ZNear: " << aCamera->ZNear() << "\n";
10059 theDi << "ZFar: " << aCamera->ZFar() << "\n";
10060 return 0;
10061 }
10062
10063 if (theArgsNb == 3)
10064 {
6b62b2da 10065 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
10066 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
197ac94e 10067
10068 if (aNewZNear >= aNewZFar)
10069 {
10070 std::cout << theArgVec[0] << ": invalid arguments: znear should be less than zfar.\n";
10071 return 1;
10072 }
10073
10074 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
10075 {
10076 std::cout << theArgVec[0] << ": invalid arguments: ";
10077 std::cout << "znear, zfar should be positive for perspective camera.\n";
10078 return 1;
10079 }
10080
10081 aCamera->SetZRange (aNewZNear, aNewZFar);
b5ac8292 10082 }
10083 else
10084 {
197ac94e 10085 std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
b5ac8292 10086 return 1;
10087 }
10088
197ac94e 10089 aCurrentView->Redraw();
10090
b5ac8292 10091 return 0;
10092}
10093
10094//===============================================================================================
10095//function : VAutoZFit
10096//purpose :
10097//===============================================================================================
10098static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
10099{
197ac94e 10100 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
10101
10102 if (aCurrentView.IsNull())
b5ac8292 10103 {
197ac94e 10104 std::cout << theArgVec[0] << ": Call vinit before this command, please.\n";
b5ac8292 10105 return 1;
10106 }
10107
c357e426 10108 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
197ac94e 10109
10110 if (theArgsNb > 3)
b5ac8292 10111 {
197ac94e 10112 std::cout << theArgVec[0] << ": wrong command arguments. Type help for more information.\n";
10113 return 1;
b5ac8292 10114 }
10115
197ac94e 10116 if (theArgsNb < 2)
b5ac8292 10117 {
586db386 10118 theDi << "Auto z-fit mode: \n"
c357e426 10119 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
197ac94e 10120 << "Scale: " << aScale << "\n";
10121 return 0;
b5ac8292 10122 }
197ac94e 10123
10124 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
10125
10126 if (theArgsNb >= 3)
b5ac8292 10127 {
197ac94e 10128 aScale = Draw::Atoi (theArgVec[2]);
b5ac8292 10129 }
10130
c357e426 10131 aCurrentView->SetAutoZFitMode (isOn, aScale);
10132 aCurrentView->AutoZFit();
197ac94e 10133 aCurrentView->Redraw();
10134
b5ac8292 10135 return 0;
10136}
10137
6b62b2da 10138//! Auxiliary function to print projection type
10139inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
10140{
10141 switch (theProjType)
10142 {
10143 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
10144 case Graphic3d_Camera::Projection_Perspective: return "perspective";
10145 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
10146 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
10147 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
10148 }
10149 return "UNKNOWN";
10150}
10151
b5ac8292 10152//===============================================================================================
6b62b2da 10153//function : VCamera
b5ac8292 10154//purpose :
10155//===============================================================================================
6b62b2da 10156static int VCamera (Draw_Interpretor& theDI,
10157 Standard_Integer theArgsNb,
10158 const char** theArgVec)
b5ac8292 10159{
6b62b2da 10160 Handle(V3d_View) aView = ViewerTest::CurrentView();
10161 if (aView.IsNull())
b5ac8292 10162 {
6b62b2da 10163 std::cout << "Error: no active view.\n";
b5ac8292 10164 return 1;
10165 }
10166
6b62b2da 10167 Handle(Graphic3d_Camera) aCamera = aView->Camera();
10168 if (theArgsNb < 2)
b5ac8292 10169 {
6b62b2da 10170 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
10171 theDI << "FOVy: " << aCamera->FOVy() << "\n";
10172 theDI << "Distance: " << aCamera->Distance() << "\n";
10173 theDI << "IOD: " << aCamera->IOD() << "\n";
10174 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
10175 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
10176 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
10177 return 0;
b5ac8292 10178 }
10179
30a1b24e 10180 TCollection_AsciiString aPrsName;
6b62b2da 10181 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
b5ac8292 10182 {
6b62b2da 10183 Standard_CString anArg = theArgVec[anArgIter];
10184 TCollection_AsciiString anArgCase (anArg);
10185 anArgCase.LowerCase();
10186 if (anArgCase == "-proj"
10187 || anArgCase == "-projection"
10188 || anArgCase == "-projtype"
10189 || anArgCase == "-projectiontype")
10190 {
10191 theDI << projTypeName (aCamera->ProjectionType()) << " ";
10192 }
10193 else if (anArgCase == "-ortho"
10194 || anArgCase == "-orthographic")
b5ac8292 10195 {
10196 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
6b62b2da 10197 }
10198 else if (anArgCase == "-persp"
10199 || anArgCase == "-perspective"
10200 || anArgCase == "-perspmono"
10201 || anArgCase == "-perspectivemono"
10202 || anArgCase == "-mono")
b5ac8292 10203 {
10204 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10205 }
6b62b2da 10206 else if (anArgCase == "-stereo"
10207 || anArgCase == "-stereoscopic"
10208 || anArgCase == "-perspstereo"
10209 || anArgCase == "-perspectivestereo")
10210 {
10211 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10212 }
10213 else if (anArgCase == "-left"
10214 || anArgCase == "-lefteye"
10215 || anArgCase == "-monoleft"
10216 || anArgCase == "-monolefteye"
10217 || anArgCase == "-perpsleft"
10218 || anArgCase == "-perpslefteye")
b5ac8292 10219 {
10220 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
10221 }
6b62b2da 10222 else if (anArgCase == "-right"
10223 || anArgCase == "-righteye"
10224 || anArgCase == "-monoright"
10225 || anArgCase == "-monorighteye"
10226 || anArgCase == "-perpsright")
b5ac8292 10227 {
10228 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
10229 }
6b62b2da 10230 else if (anArgCase == "-dist"
10231 || anArgCase == "-distance")
b5ac8292 10232 {
6b62b2da 10233 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10234 if (anArgValue != NULL
10235 && *anArgValue != '-')
10236 {
10237 ++anArgIter;
10238 aCamera->SetDistance (Draw::Atof (anArgValue));
10239 continue;
10240 }
10241 theDI << aCamera->Distance() << " ";
b5ac8292 10242 }
6b62b2da 10243 else if (anArgCase == "-iod")
b5ac8292 10244 {
6b62b2da 10245 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10246 if (anArgValue != NULL
10247 && *anArgValue != '-')
10248 {
10249 ++anArgIter;
10250 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
10251 continue;
10252 }
10253 theDI << aCamera->IOD() << " ";
b5ac8292 10254 }
6b62b2da 10255 else if (anArgCase == "-iodtype")
b5ac8292 10256 {
6b62b2da 10257 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10258 TCollection_AsciiString anValueCase (anArgValue);
10259 anValueCase.LowerCase();
10260 if (anValueCase == "abs"
10261 || anValueCase == "absolute")
10262 {
10263 ++anArgIter;
10264 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
10265 continue;
10266 }
10267 else if (anValueCase == "rel"
10268 || anValueCase == "relative")
10269 {
10270 ++anArgIter;
10271 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
10272 continue;
10273 }
10274 else if (*anArgValue != '-')
10275 {
10276 std::cout << "Error: unknown IOD type '" << anArgValue << "'\n";
10277 return 1;
10278 }
10279 switch (aCamera->GetIODType())
10280 {
10281 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
10282 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
10283 }
b5ac8292 10284 }
6b62b2da 10285 else if (anArgCase == "-zfocus")
b5ac8292 10286 {
6b62b2da 10287 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10288 if (anArgValue != NULL
10289 && *anArgValue != '-')
10290 {
10291 ++anArgIter;
10292 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
10293 continue;
10294 }
10295 theDI << aCamera->ZFocus() << " ";
b5ac8292 10296 }
6b62b2da 10297 else if (anArgCase == "-zfocustype")
b5ac8292 10298 {
6b62b2da 10299 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
10300 TCollection_AsciiString anValueCase (anArgValue);
10301 anValueCase.LowerCase();
10302 if (anValueCase == "abs"
10303 || anValueCase == "absolute")
10304 {
10305 ++anArgIter;
10306 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
10307 continue;
10308 }
10309 else if (anValueCase == "rel"
10310 || anValueCase == "relative")
10311 {
10312 ++anArgIter;
10313 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
10314 continue;
10315 }
10316 else if (*anArgValue != '-')
10317 {
10318 std::cout << "Error: unknown ZFocus type '" << anArgValue << "'\n";
10319 return 1;
10320 }
10321 switch (aCamera->ZFocusType())
10322 {
10323 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
10324 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
10325 }
10326 }
10327 else if (anArgCase == "-fov"
10328 || anArgCase == "-fovy")
b5ac8292 10329 {
6b62b2da 10330 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
10331 if (anArgValue != NULL
10332 && *anArgValue != '-')
10333 {
10334 ++anArgIter;
10335 aCamera->SetFOVy (Draw::Atof (anArgValue));
10336 continue;
10337 }
10338 theDI << aCamera->FOVy() << " ";
b5ac8292 10339 }
30a1b24e 10340 else if (aPrsName.IsEmpty()
10341 && !anArgCase.StartsWith ("-"))
10342 {
10343 aPrsName = anArg;
10344 }
b5ac8292 10345 else
10346 {
6b62b2da 10347 std::cout << "Error: unknown argument '" << anArg << "'\n";
b5ac8292 10348 return 1;
10349 }
10350 }
b5ac8292 10351
30a1b24e 10352 if (aPrsName.IsEmpty()
10353 || theArgsNb > 2)
10354 {
10355 aView->AutoZFit();
10356 aView->Redraw();
10357 }
10358
10359 if (!aPrsName.IsEmpty())
10360 {
10361 Handle(AIS_CameraFrustum) aCameraFrustum;
10362 if (GetMapOfAIS().IsBound2 (aPrsName))
10363 {
10364 // find existing object
10365 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
10366 if (aCameraFrustum.IsNull())
10367 {
10368 std::cout << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum!\n";
10369 return 1;
10370 }
10371 }
10372
10373 if (aCameraFrustum.IsNull())
10374 {
10375 aCameraFrustum = new AIS_CameraFrustum();
10376 }
10377 else
10378 {
10379 // not include displayed object of old camera frustum in the new one.
10380 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
10381 aView->ZFitAll();
10382 }
10383 aCameraFrustum->SetCameraFrustum (aView->Camera());
10384
10385 ViewerTest::Display (aPrsName, aCameraFrustum);
10386 }
b5ac8292 10387
10388 return 0;
10389}
10390
f978241f 10391//! Parse stereo output mode
10392inline Standard_Boolean parseStereoMode (Standard_CString theArg,
10393 Graphic3d_StereoMode& theMode)
10394{
10395 TCollection_AsciiString aFlag (theArg);
10396 aFlag.LowerCase();
10397 if (aFlag == "quadbuffer")
10398 {
10399 theMode = Graphic3d_StereoMode_QuadBuffer;
10400 }
10401 else if (aFlag == "anaglyph")
10402 {
10403 theMode = Graphic3d_StereoMode_Anaglyph;
10404 }
10405 else if (aFlag == "row"
10406 || aFlag == "rowinterlaced")
10407 {
10408 theMode = Graphic3d_StereoMode_RowInterlaced;
10409 }
10410 else if (aFlag == "col"
10411 || aFlag == "colinterlaced"
10412 || aFlag == "columninterlaced")
10413 {
10414 theMode = Graphic3d_StereoMode_ColumnInterlaced;
10415 }
10416 else if (aFlag == "chess"
10417 || aFlag == "chessboard")
10418 {
10419 theMode = Graphic3d_StereoMode_ChessBoard;
10420 }
10421 else if (aFlag == "sbs"
10422 || aFlag == "sidebyside")
10423 {
10424 theMode = Graphic3d_StereoMode_SideBySide;
10425 }
10426 else if (aFlag == "ou"
10427 || aFlag == "overunder")
10428 {
10429 theMode = Graphic3d_StereoMode_OverUnder;
10430 }
10431 else if (aFlag == "pageflip"
10432 || aFlag == "softpageflip")
10433 {
10434 theMode = Graphic3d_StereoMode_SoftPageFlip;
10435 }
10436 else
10437 {
10438 return Standard_False;
10439 }
10440 return Standard_True;
10441}
10442
10443//! Parse anaglyph filter
10444inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
10445 Graphic3d_RenderingParams::Anaglyph& theFilter)
10446{
10447 TCollection_AsciiString aFlag (theArg);
10448 aFlag.LowerCase();
10449 if (aFlag == "redcyansimple")
10450 {
10451 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10452 }
10453 else if (aFlag == "redcyan"
10454 || aFlag == "redcyanoptimized")
10455 {
10456 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
10457 }
10458 else if (aFlag == "yellowbluesimple")
10459 {
10460 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
10461 }
10462 else if (aFlag == "yellowblue"
10463 || aFlag == "yellowblueoptimized")
10464 {
10465 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
10466 }
10467 else if (aFlag == "greenmagenta"
10468 || aFlag == "greenmagentasimple")
10469 {
10470 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
10471 }
10472 else
10473 {
10474 return Standard_False;
10475 }
10476 return Standard_True;
10477}
10478
b5ac8292 10479//==============================================================================
10480//function : VStereo
10481//purpose :
10482//==============================================================================
10483
10484static int VStereo (Draw_Interpretor& theDI,
10485 Standard_Integer theArgNb,
10486 const char** theArgVec)
10487{
f978241f 10488 Handle(V3d_View) aView = ViewerTest::CurrentView();
b5ac8292 10489 if (theArgNb < 2)
10490 {
b5ac8292 10491 if (aView.IsNull())
10492 {
f978241f 10493 std::cout << "Error: no active viewer!\n";
b5ac8292 10494 return 0;
10495 }
10496
10497 Standard_Boolean isActive = ViewerTest_myDefaultCaps.contextStereo;
10498 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
bf02aa7d 10499 if (isActive)
10500 {
10501 TCollection_AsciiString aMode;
10502 switch (aView->RenderingParams().StereoMode)
10503 {
10504 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
10505 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
10506 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
10507 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
10508 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
10509 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
10510 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
10511 case Graphic3d_StereoMode_Anaglyph :
10512 aMode = "anaglyph";
10513 switch (aView->RenderingParams().AnaglyphFilter)
10514 {
10515 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
10516 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
10517 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
10518 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
10519 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
10520 default: break;
10521 }
10522 default: break;
10523 }
10524 theDI << "Mode " << aMode << "\n";
10525 }
b5ac8292 10526 return 0;
10527 }
10528
f978241f 10529 Handle(Graphic3d_Camera) aCamera;
10530 Graphic3d_RenderingParams* aParams = NULL;
10531 Graphic3d_StereoMode aMode = Graphic3d_StereoMode_QuadBuffer;
10532 if (!aView.IsNull())
10533 {
10534 aParams = &aView->ChangeRenderingParams();
10535 aMode = aParams->StereoMode;
10536 aCamera = aView->Camera();
10537 }
10538
10539 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10540 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10541 {
10542 Standard_CString anArg = theArgVec[anArgIter];
10543 TCollection_AsciiString aFlag (anArg);
10544 aFlag.LowerCase();
10545 if (anUpdateTool.parseRedrawMode (aFlag))
10546 {
10547 continue;
10548 }
10549 else if (aFlag == "0"
10550 || aFlag == "off")
10551 {
10552 if (++anArgIter < theArgNb)
10553 {
10554 std::cout << "Error: wrong number of arguments!\n";
10555 return 1;
10556 }
10557
10558 if (!aCamera.IsNull()
10559 && aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
10560 {
10561 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
10562 }
10563 ViewerTest_myDefaultCaps.contextStereo = Standard_False;
10564 return 0;
10565 }
10566 else if (aFlag == "1"
10567 || aFlag == "on")
10568 {
10569 if (++anArgIter < theArgNb)
10570 {
10571 std::cout << "Error: wrong number of arguments!\n";
10572 return 1;
10573 }
10574
10575 if (!aCamera.IsNull())
10576 {
10577 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10578 }
10579 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10580 return 0;
10581 }
10582 else if (aFlag == "-reverse"
10583 || aFlag == "-reversed"
10584 || aFlag == "-swap")
10585 {
10586 Standard_Boolean toEnable = Standard_True;
10587 if (++anArgIter < theArgNb
a5565a3c 10588 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
f978241f 10589 {
10590 --anArgIter;
10591 }
10592 aParams->ToReverseStereo = toEnable;
10593 }
10594 else if (aFlag == "-noreverse"
10595 || aFlag == "-noswap")
10596 {
10597 Standard_Boolean toDisable = Standard_True;
10598 if (++anArgIter < theArgNb
a5565a3c 10599 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toDisable))
f978241f 10600 {
10601 --anArgIter;
10602 }
10603 aParams->ToReverseStereo = !toDisable;
10604 }
10605 else if (aFlag == "-mode"
10606 || aFlag == "-stereomode")
10607 {
10608 if (++anArgIter >= theArgNb
10609 || !parseStereoMode (theArgVec[anArgIter], aMode))
10610 {
10611 std::cout << "Error: syntax error at '" << anArg << "'\n";
10612 return 1;
10613 }
10614
10615 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10616 {
10617 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10618 }
10619 }
10620 else if (aFlag == "-anaglyph"
10621 || aFlag == "-anaglyphfilter")
10622 {
10623 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
10624 if (++anArgIter >= theArgNb
10625 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
10626 {
10627 std::cout << "Error: syntax error at '" << anArg << "'\n";
10628 return 1;
10629 }
10630
10631 aMode = Graphic3d_StereoMode_Anaglyph;
10632 aParams->AnaglyphFilter = aFilter;
10633 }
10634 else if (parseStereoMode (anArg, aMode)) // short syntax
10635 {
10636 if (aMode == Graphic3d_StereoMode_QuadBuffer)
10637 {
10638 ViewerTest_myDefaultCaps.contextStereo = Standard_True;
10639 }
10640 }
10641 else
10642 {
10643 std::cout << "Error: syntax error at '" << anArg << "'\n";
10644 return 1;
10645 }
10646 }
10647
10648 if (!aView.IsNull())
10649 {
10650 aParams->StereoMode = aMode;
10651 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
10652 }
b5ac8292 10653 return 0;
10654}
10655
392ac980 10656//===============================================================================================
10657//function : VDefaults
10658//purpose :
10659//===============================================================================================
10660static int VDefaults (Draw_Interpretor& theDi,
10661 Standard_Integer theArgsNb,
10662 const char** theArgVec)
10663{
10664 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
10665 if (aCtx.IsNull())
10666 {
10667 std::cerr << "No active viewer!\n";
10668 return 1;
10669 }
10670
10671 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
10672 if (theArgsNb < 2)
10673 {
10674 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
10675 {
10676 theDi << "DeflType: relative\n"
10677 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
10678 }
10679 else
10680 {
10681 theDi << "DeflType: absolute\n"
10682 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
10683 }
10684 theDi << "AngularDeflection: " << (180.0 * aDefParams->HLRAngle() / M_PI) << "\n";
4c513386 10685 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
392ac980 10686 return 0;
10687 }
10688
10689 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
10690 {
10691 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4c513386 10692 anArg.UpperCase();
10693 if (anArg == "-ABSDEFL"
10694 || anArg == "-ABSOLUTEDEFLECTION"
10695 || anArg == "-DEFL"
10696 || anArg == "-DEFLECTION")
392ac980 10697 {
4c513386 10698 if (++anArgIter >= theArgsNb)
10699 {
10700 std::cout << "Error: wrong syntax at " << anArg << "\n";
10701 return 1;
10702 }
392ac980 10703 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
4c513386 10704 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
392ac980 10705 }
4c513386 10706 else if (anArg == "-RELDEFL"
10707 || anArg == "-RELATIVEDEFLECTION"
10708 || anArg == "-DEVCOEFF"
10709 || anArg == "-DEVIATIONCOEFF"
10710 || anArg == "-DEVIATIONCOEFFICIENT")
392ac980 10711 {
4c513386 10712 if (++anArgIter >= theArgsNb)
10713 {
10714 std::cout << "Error: wrong syntax at " << anArg << "\n";
10715 return 1;
10716 }
392ac980 10717 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
4c513386 10718 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
392ac980 10719 }
4c513386 10720 else if (anArg == "-ANGDEFL"
10721 || anArg == "-ANGULARDEFL"
10722 || anArg == "-ANGULARDEFLECTION")
392ac980 10723 {
4c513386 10724 if (++anArgIter >= theArgsNb)
10725 {
10726 std::cout << "Error: wrong syntax at " << anArg << "\n";
10727 return 1;
10728 }
392ac980 10729 // currently HLRDeviationAngle is used instead of DeviationAngle in most places
4c513386 10730 aDefParams->SetHLRAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
10731 }
385c43e7 10732 else if (anArg == "-AUTOTR"
10733 || anArg == "-AUTOTRIANG"
10734 || anArg == "-AUTOTRIANGULATION")
4c513386 10735 {
10736 if (++anArgIter >= theArgsNb)
10737 {
10738 std::cout << "Error: wrong syntax at " << anArg << "\n";
10739 return 1;
10740 }
10741 TCollection_AsciiString aValue (theArgVec[anArgIter]);
10742 aValue.LowerCase();
10743 if (aValue == "on"
10744 || aValue == "1")
10745 {
10746 aDefParams->SetAutoTriangulation (Standard_True);
10747 }
10748 else if (aValue == "off"
10749 || aValue == "0")
10750 {
10751 aDefParams->SetAutoTriangulation (Standard_False);
10752 }
392ac980 10753 }
10754 else
10755 {
10756 std::cerr << "Warning, unknown argument '" << anArg.ToCString() << "'\n";
10757 }
10758 }
10759
10760 return 0;
10761}
10762
12381341 10763//! Auxiliary method
10764inline void addLight (const Handle(V3d_Light)& theLightNew,
992ed6b3 10765 const Graphic3d_ZLayerId theLayer,
12381341 10766 const Standard_Boolean theIsGlobal)
10767{
10768 if (theLightNew.IsNull())
10769 {
10770 return;
10771 }
10772
992ed6b3 10773 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10774 if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 10775 {
992ed6b3 10776 aViewer->AddLight (theLightNew);
10777 if (theIsGlobal)
10778 {
10779 aViewer->SetLightOn (theLightNew);
10780 }
10781 else
10782 {
10783 ViewerTest::CurrentView()->SetLightOn (theLightNew);
10784 }
12381341 10785 }
10786 else
10787 {
992ed6b3 10788 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
10789 if (aSettings.Lights().IsNull())
10790 {
10791 aSettings.SetLights (new Graphic3d_LightSet());
10792 }
10793 aSettings.Lights()->Add (theLightNew);
10794 aViewer->SetZLayerSettings (theLayer, aSettings);
12381341 10795 }
10796}
10797
10798//! Auxiliary method
10799inline Standard_Integer getLightId (const TCollection_AsciiString& theArgNext)
10800{
10801 TCollection_AsciiString anArgNextCase (theArgNext);
10802 anArgNextCase.UpperCase();
10803 if (anArgNextCase.Length() > 5
10804 && anArgNextCase.SubString (1, 5).IsEqual ("LIGHT"))
10805 {
10806 return theArgNext.SubString (6, theArgNext.Length()).IntegerValue();
10807 }
10808 else
10809 {
10810 return theArgNext.IntegerValue();
10811 }
10812}
10813
10814//===============================================================================================
10815//function : VLight
10816//purpose :
10817//===============================================================================================
10818static int VLight (Draw_Interpretor& theDi,
10819 Standard_Integer theArgsNb,
10820 const char** theArgVec)
10821{
10822 Handle(V3d_View) aView = ViewerTest::CurrentView();
10823 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
10824 if (aView.IsNull()
10825 || aViewer.IsNull())
10826 {
10827 std::cerr << "No active viewer!\n";
10828 return 1;
10829 }
10830
ee2be2a8 10831 Standard_Real anXYZ[3] = {};
10832 Standard_Real anAtten[2] = {};
12381341 10833 if (theArgsNb < 2)
10834 {
10835 // print lights info
10836 Standard_Integer aLightId = 0;
6a24c6de 10837 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
12381341 10838 {
6a24c6de 10839 Handle(V3d_Light) aLight = aLightIter.Value();
12381341 10840 const Quantity_Color aColor = aLight->Color();
992ed6b3 10841 theDi << "Light #" << aLightId
10842 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
10843 << " [" << aLight->GetId() << "]" << "\n";
12381341 10844 switch (aLight->Type())
10845 {
10846 case V3d_AMBIENT:
10847 {
189f85a3 10848 theDi << " Type: Ambient\n";
10849 theDi << " Intensity: " << aLight->Intensity() << "\n";
12381341 10850 break;
10851 }
10852 case V3d_DIRECTIONAL:
10853 {
189f85a3 10854 theDi << " Type: Directional\n";
10855 theDi << " Intensity: " << aLight->Intensity() << "\n";
10856 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10857 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10858 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10859 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
12381341 10860 break;
10861 }
10862 case V3d_POSITIONAL:
10863 {
189f85a3 10864 theDi << " Type: Positional\n";
10865 theDi << " Intensity: " << aLight->Intensity() << "\n";
10866 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
10867 theDi << " Smoothness: " << aLight->Smoothness() << "\n";
992ed6b3 10868 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10869 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10870 aLight->Attenuation (anAtten[0], anAtten[1]);
10871 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
12381341 10872 break;
10873 }
10874 case V3d_SPOT:
10875 {
189f85a3 10876 theDi << " Type: Spot\n";
10877 theDi << " Intensity: " << aLight->Intensity() << "\n";
10878 theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
992ed6b3 10879 aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]);
10880 theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10881 aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
10882 theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
10883 aLight->Attenuation (anAtten[0], anAtten[1]);
10884 theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n";
10885 theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n";
10886 theDi << " Exponent: " << aLight->Concentration() << "\n";
12381341 10887 break;
10888 }
10889 default:
10890 {
189f85a3 10891 theDi << " Type: UNKNOWN\n";
12381341 10892 break;
10893 }
10894 }
992ed6b3 10895 theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
12381341 10896 }
10897 }
10898
10899 Handle(V3d_Light) aLightNew;
10900 Handle(V3d_Light) aLightOld;
992ed6b3 10901 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
12381341 10902 Standard_Boolean isGlobal = Standard_True;
10903 Standard_Boolean toCreate = Standard_False;
761d8807 10904 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
12381341 10905 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
10906 {
992ed6b3 10907 Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
12381341 10908
10909 TCollection_AsciiString aName, aValue;
10910 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
10911 TCollection_AsciiString anArgCase (anArg);
10912 anArgCase.UpperCase();
761d8807 10913 if (anUpdateTool.parseRedrawMode (anArg))
10914 {
10915 continue;
10916 }
10917
12381341 10918 if (anArgCase.IsEqual ("NEW")
10919 || anArgCase.IsEqual ("ADD")
992ed6b3 10920 || anArgCase.IsEqual ("CREATE")
10921 || anArgCase.IsEqual ("-NEW")
10922 || anArgCase.IsEqual ("-ADD")
10923 || anArgCase.IsEqual ("-CREATE"))
12381341 10924 {
10925 toCreate = Standard_True;
10926 }
992ed6b3 10927 else if (anArgCase.IsEqual ("-LAYER")
10928 || anArgCase.IsEqual ("-ZLAYER"))
10929 {
10930 if (++anArgIt >= theArgsNb)
10931 {
10932 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
10933 return 1;
10934 }
10935
10936 TCollection_AsciiString aValStr (theArgVec[anArgIt]);
10937 aValStr.LowerCase();
10938 if (aValStr == "default"
10939 || aValStr == "def")
10940 {
10941 aLayer = Graphic3d_ZLayerId_Default;
10942 }
10943 else if (aValStr == "top")
10944 {
10945 aLayer = Graphic3d_ZLayerId_Top;
10946 }
10947 else if (aValStr == "topmost")
10948 {
10949 aLayer = Graphic3d_ZLayerId_Topmost;
10950 }
10951 else if (aValStr == "toposd"
10952 || aValStr == "osd")
10953 {
10954 aLayer = Graphic3d_ZLayerId_TopOSD;
10955 }
10956 else if (aValStr == "botosd"
10957 || aValStr == "bottom")
10958 {
10959 aLayer = Graphic3d_ZLayerId_BotOSD;
10960 }
10961 else if (aValStr.IsIntegerValue())
10962 {
10963 aLayer = Draw::Atoi (theArgVec[anArgIt]);
10964 }
10965 else
10966 {
10967 std::cout << "Wrong syntax at argument '" << anArg << "'!\n";
10968 return 1;
10969 }
10970 }
12381341 10971 else if (anArgCase.IsEqual ("GLOB")
992ed6b3 10972 || anArgCase.IsEqual ("GLOBAL")
10973 || anArgCase.IsEqual ("-GLOB")
10974 || anArgCase.IsEqual ("-GLOBAL"))
12381341 10975 {
10976 isGlobal = Standard_True;
10977 }
10978 else if (anArgCase.IsEqual ("LOC")
992ed6b3 10979 || anArgCase.IsEqual ("LOCAL")
10980 || anArgCase.IsEqual ("-LOC")
10981 || anArgCase.IsEqual ("-LOCAL"))
12381341 10982 {
10983 isGlobal = Standard_False;
10984 }
4fe9ad57 10985 else if (anArgCase.IsEqual ("DEF")
992ed6b3 10986 || anArgCase.IsEqual ("DEFAULTS")
10987 || anArgCase.IsEqual ("-DEF")
10988 || anArgCase.IsEqual ("-DEFAULTS"))
4fe9ad57 10989 {
10990 toCreate = Standard_False;
10991 aViewer->SetDefaultLights();
10992 }
10993 else if (anArgCase.IsEqual ("CLR")
992ed6b3 10994 || anArgCase.IsEqual ("CLEAR")
10995 || anArgCase.IsEqual ("-CLR")
10996 || anArgCase.IsEqual ("-CLEAR"))
4fe9ad57 10997 {
10998 toCreate = Standard_False;
992ed6b3 10999
11000 TColStd_SequenceOfInteger aLayers;
11001 aViewer->GetAllZLayers (aLayers);
11002 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4fe9ad57 11003 {
992ed6b3 11004 if (aLayeriter.Value() == aLayer
11005 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
11006 {
11007 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
11008 aSettings.SetLights (Handle(Graphic3d_LightSet)());
11009 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
11010 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
11011 {
11012 break;
11013 }
11014 }
11015 }
11016
11017 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
11018 {
11019 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
11020 {
11021 Handle(V3d_Light) aLight = aLightIter.Value();
11022 aViewer->DelLight (aLight);
11023 aLightIter = aView->ActiveLightIterator();
11024 }
4fe9ad57 11025 }
11026 }
12381341 11027 else if (anArgCase.IsEqual ("AMB")
11028 || anArgCase.IsEqual ("AMBIENT")
11029 || anArgCase.IsEqual ("AMBLIGHT"))
11030 {
12381341 11031 if (!toCreate)
11032 {
11033 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11034 return 1;
11035 }
992ed6b3 11036
11037 addLight (aLightNew, aLayer, isGlobal);
12381341 11038 toCreate = Standard_False;
992ed6b3 11039 aLightNew = new V3d_AmbientLight();
12381341 11040 }
11041 else if (anArgCase.IsEqual ("DIRECTIONAL")
11042 || anArgCase.IsEqual ("DIRLIGHT"))
11043 {
12381341 11044 if (!toCreate)
11045 {
11046 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11047 return 1;
11048 }
992ed6b3 11049
11050 addLight (aLightNew, aLayer, isGlobal);
12381341 11051 toCreate = Standard_False;
992ed6b3 11052 aLightNew = new V3d_DirectionalLight();
12381341 11053 }
11054 else if (anArgCase.IsEqual ("SPOT")
11055 || anArgCase.IsEqual ("SPOTLIGHT"))
11056 {
12381341 11057 if (!toCreate)
11058 {
11059 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11060 return 1;
11061 }
992ed6b3 11062
11063 addLight (aLightNew, aLayer, isGlobal);
12381341 11064 toCreate = Standard_False;
992ed6b3 11065 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 11066 }
11067 else if (anArgCase.IsEqual ("POSLIGHT")
11068 || anArgCase.IsEqual ("POSITIONAL"))
11069 {
12381341 11070 if (!toCreate)
11071 {
11072 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11073 return 1;
11074 }
992ed6b3 11075
11076 addLight (aLightNew, aLayer, isGlobal);
12381341 11077 toCreate = Standard_False;
992ed6b3 11078 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
12381341 11079 }
992ed6b3 11080 else if (anArgCase.IsEqual ("CHANGE")
11081 || anArgCase.IsEqual ("-CHANGE"))
12381341 11082 {
12381341 11083 if (++anArgIt >= theArgsNb)
11084 {
11085 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11086 return 1;
11087 }
11088
992ed6b3 11089 addLight (aLightNew, aLayer, isGlobal);
11090 aLightNew.Nullify();
12381341 11091 const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
11092 Standard_Integer aLightIt = 0;
6a24c6de 11093 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 11094 {
11095 if (aLightIt == aLightId)
11096 {
6a24c6de 11097 aLightOld = aLightIter.Value();
12381341 11098 break;
11099 }
11100 }
11101
11102 if (aLightOld.IsNull())
11103 {
11104 std::cerr << "Light " << theArgVec[anArgIt] << " is undefined!\n";
11105 return 1;
11106 }
11107 }
11108 else if (anArgCase.IsEqual ("DEL")
992ed6b3 11109 || anArgCase.IsEqual ("DELETE")
11110 || anArgCase.IsEqual ("-DEL")
11111 || anArgCase.IsEqual ("-DELETE"))
12381341 11112 {
11113 Handle(V3d_Light) aLightDel;
11114 if (++anArgIt >= theArgsNb)
11115 {
11116 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11117 return 1;
11118 }
11119
11120 const TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
11121 const Standard_Integer aLightDelId = getLightId (theArgVec[anArgIt]);
11122 Standard_Integer aLightIt = 0;
6a24c6de 11123 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
12381341 11124 {
6a24c6de 11125 aLightDel = aLightIter.Value();
12381341 11126 if (aLightIt == aLightDelId)
11127 {
11128 break;
11129 }
11130 }
992ed6b3 11131 if (aLightDel.IsNull())
11132 {
11133 continue;
11134 }
11135
11136 TColStd_SequenceOfInteger aLayers;
11137 aViewer->GetAllZLayers (aLayers);
11138 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
11139 {
11140 if (aLayeriter.Value() == aLayer
11141 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
11142 {
11143 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
11144 if (!aSettings.Lights().IsNull())
11145 {
11146 aSettings.Lights()->Remove (aLightDel);
11147 if (aSettings.Lights()->IsEmpty())
11148 {
11149 aSettings.SetLights (Handle(Graphic3d_LightSet)());
11150 }
11151 }
11152 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
11153 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
11154 {
11155 break;
11156 }
11157 }
11158 }
11159
11160 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
12381341 11161 {
11162 aViewer->DelLight (aLightDel);
11163 }
11164 }
11165 else if (anArgCase.IsEqual ("COLOR")
992ed6b3 11166 || anArgCase.IsEqual ("COLOUR")
11167 || anArgCase.IsEqual ("-COLOR")
11168 || anArgCase.IsEqual ("-COLOUR"))
12381341 11169 {
992ed6b3 11170 if (++anArgIt >= theArgsNb
11171 || aLightCurr.IsNull())
12381341 11172 {
11173 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11174 return 1;
11175 }
11176
11177 TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
11178 anArgNext.UpperCase();
11179 const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
992ed6b3 11180 aLightCurr->SetColor (aColor);
12381341 11181 }
11182 else if (anArgCase.IsEqual ("POS")
992ed6b3 11183 || anArgCase.IsEqual ("POSITION")
11184 || anArgCase.IsEqual ("-POS")
11185 || anArgCase.IsEqual ("-POSITION"))
12381341 11186 {
992ed6b3 11187 if ((anArgIt + 3) >= theArgsNb
11188 || aLightCurr.IsNull()
11189 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11190 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11191 {
11192 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11193 return 1;
11194 }
11195
11196 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11197 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11198 anXYZ[2] = Atof (theArgVec[++anArgIt]);
992ed6b3 11199 aLightCurr->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
12381341 11200 }
11201 else if (anArgCase.IsEqual ("DIR")
992ed6b3 11202 || anArgCase.IsEqual ("DIRECTION")
11203 || anArgCase.IsEqual ("-DIR")
11204 || anArgCase.IsEqual ("-DIRECTION"))
12381341 11205 {
992ed6b3 11206 if ((anArgIt + 3) >= theArgsNb
11207 || aLightCurr.IsNull()
11208 || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
11209 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11210 {
11211 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11212 return 1;
11213 }
11214
11215 anXYZ[0] = Atof (theArgVec[++anArgIt]);
11216 anXYZ[1] = Atof (theArgVec[++anArgIt]);
11217 anXYZ[2] = Atof (theArgVec[++anArgIt]);
992ed6b3 11218 aLightCurr->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
12381341 11219 }
189f85a3 11220 else if (anArgCase.IsEqual ("SM")
992ed6b3 11221 || anArgCase.IsEqual ("SMOOTHNESS")
11222 || anArgCase.IsEqual ("-SM")
11223 || anArgCase.IsEqual ("-SMOOTHNESS"))
189f85a3 11224 {
992ed6b3 11225 if (++anArgIt >= theArgsNb
11226 || aLightCurr.IsNull())
189f85a3 11227 {
11228 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11229 return 1;
11230 }
11231
992ed6b3 11232 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11233 if (Abs (aSmoothness) <= ShortRealEpsilon())
189f85a3 11234 {
11235 aLightCurr->SetIntensity (1.f);
11236 }
992ed6b3 11237 else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
189f85a3 11238 {
11239 aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
11240 }
11241 else
11242 {
11243 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightCurr->Smoothness());
11244 aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
11245 }
11246
992ed6b3 11247 if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
189f85a3 11248 {
992ed6b3 11249 aLightCurr->SetSmoothRadius (aSmoothness);
189f85a3 11250 }
992ed6b3 11251 else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
189f85a3 11252 {
992ed6b3 11253 aLightCurr->SetSmoothAngle (aSmoothness);
189f85a3 11254 }
11255 }
11256 else if (anArgCase.IsEqual ("INT")
992ed6b3 11257 || anArgCase.IsEqual ("INTENSITY")
11258 || anArgCase.IsEqual ("-INT")
11259 || anArgCase.IsEqual ("-INTENSITY"))
189f85a3 11260 {
992ed6b3 11261 if (++anArgIt >= theArgsNb
11262 || aLightCurr.IsNull())
189f85a3 11263 {
11264 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11265 return 1;
11266 }
11267
992ed6b3 11268 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11269 aLightCurr->SetIntensity (aIntensity);
189f85a3 11270 }
4fe9ad57 11271 else if (anArgCase.IsEqual ("ANG")
992ed6b3 11272 || anArgCase.IsEqual ("ANGLE")
11273 || anArgCase.IsEqual ("-ANG")
11274 || anArgCase.IsEqual ("-ANGLE"))
4fe9ad57 11275 {
992ed6b3 11276 if (++anArgIt >= theArgsNb
11277 || aLightCurr.IsNull()
11278 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
4fe9ad57 11279 {
11280 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11281 return 1;
11282 }
11283
992ed6b3 11284 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
11285 aLightCurr->SetAngle (Standard_ShortReal (anAngle / 180.0 * M_PI));
4fe9ad57 11286 }
12381341 11287 else if (anArgCase.IsEqual ("CONSTATTEN")
992ed6b3 11288 || anArgCase.IsEqual ("CONSTATTENUATION")
11289 || anArgCase.IsEqual ("-CONSTATTEN")
11290 || anArgCase.IsEqual ("-CONSTATTENUATION"))
12381341 11291 {
992ed6b3 11292 if (++anArgIt >= theArgsNb
11293 || aLightCurr.IsNull()
11294 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11295 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11296 {
11297 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11298 return 1;
11299 }
11300
992ed6b3 11301 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11302 anAtten[0] = Atof (theArgVec[anArgIt]);
11303 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11304 }
11305 else if (anArgCase.IsEqual ("LINATTEN")
11306 || anArgCase.IsEqual ("LINEARATTEN")
992ed6b3 11307 || anArgCase.IsEqual ("LINEARATTENUATION")
11308 || anArgCase.IsEqual ("-LINATTEN")
11309 || anArgCase.IsEqual ("-LINEARATTEN")
11310 || anArgCase.IsEqual ("-LINEARATTENUATION"))
12381341 11311 {
992ed6b3 11312 if (++anArgIt >= theArgsNb
11313 || aLightCurr.IsNull()
11314 || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
11315 && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
12381341 11316 {
11317 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11318 return 1;
11319 }
11320
992ed6b3 11321 aLightCurr->Attenuation (anAtten[0], anAtten[1]);
11322 anAtten[1] = Atof (theArgVec[anArgIt]);
11323 aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
12381341 11324 }
11325 else if (anArgCase.IsEqual ("EXP")
11326 || anArgCase.IsEqual ("EXPONENT")
11327 || anArgCase.IsEqual ("SPOTEXP")
992ed6b3 11328 || anArgCase.IsEqual ("SPOTEXPONENT")
11329 || anArgCase.IsEqual ("-EXP")
11330 || anArgCase.IsEqual ("-EXPONENT")
11331 || anArgCase.IsEqual ("-SPOTEXP")
11332 || anArgCase.IsEqual ("-SPOTEXPONENT"))
12381341 11333 {
992ed6b3 11334 if (++anArgIt >= theArgsNb
11335 || aLightCurr.IsNull()
11336 || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
12381341 11337 {
11338 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11339 return 1;
11340 }
11341
992ed6b3 11342 aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
12381341 11343 }
11344 else if (anArgCase.IsEqual ("HEAD")
992ed6b3 11345 || anArgCase.IsEqual ("HEADLIGHT")
11346 || anArgCase.IsEqual ("-HEAD")
11347 || anArgCase.IsEqual ("-HEADLIGHT"))
12381341 11348 {
992ed6b3 11349 if (aLightCurr.IsNull()
11350 || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
12381341 11351 {
11352 std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
11353 return 1;
11354 }
11355
992ed6b3 11356 Standard_Boolean isHeadLight = Standard_True;
11357 if (anArgIt + 1 < theArgsNb
11358 && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
12381341 11359 {
992ed6b3 11360 ++anArgIt;
12381341 11361 }
992ed6b3 11362 aLightCurr->SetHeadlight (isHeadLight);
12381341 11363 }
11364 else
11365 {
11366 std::cerr << "Warning: unknown argument '" << anArg << "'\n";
11367 }
11368 }
11369
992ed6b3 11370 addLight (aLightNew, aLayer, isGlobal);
12381341 11371 return 0;
11372}
11373
15669413 11374//! Read Graphic3d_RenderingParams::PerfCounters flag.
11375static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
11376 Standard_Boolean& theToReset,
11377 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
11378 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
11379{
11380 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
11381 TCollection_AsciiString aVal = theValue;
11382 Standard_Boolean toReverse = Standard_False;
11383 if (aVal == "none")
11384 {
11385 theToReset = Standard_True;
11386 return Standard_True;
11387 }
11388 else if (aVal.StartsWith ("-"))
11389 {
11390 toReverse = Standard_True;
11391 aVal = aVal.SubString (2, aVal.Length());
11392 }
11393 else if (aVal.StartsWith ("no"))
11394 {
11395 toReverse = Standard_True;
11396 aVal = aVal.SubString (3, aVal.Length());
11397 }
11398 else if (aVal.StartsWith ("+"))
11399 {
11400 aVal = aVal.SubString (2, aVal.Length());
11401 }
11402 else
11403 {
11404 theToReset = Standard_True;
11405 }
11406
11407 if ( aVal == "fps"
11408 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11409 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
11410 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
11411 else if (aVal == "structs"
11412 || aVal == "structures"
11413 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
11414 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
11415 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11416 else if (aVal == "tris"
11417 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
11418 else if (aVal == "pnts"
11419 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
11420 else if (aVal == "mem"
11421 || aVal == "gpumem"
11422 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
5e30547b 11423 else if (aVal == "skipimmediate"
11424 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
11425 else if (aVal == "frametime"
11426 || aVal == "frametimers"
11427 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
15669413 11428 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
11429 else if (aVal == "extended"
11430 || aVal == "verbose"
11431 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
5e30547b 11432 else if (aVal == "full"
11433 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
15669413 11434 else
11435 {
11436 return Standard_False;
11437 }
11438
11439 if (toReverse)
11440 {
11441 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
11442 }
11443 else
11444 {
11445 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
11446 }
11447 return Standard_True;
11448}
11449
11450//! Read Graphic3d_RenderingParams::PerfCounters flags.
11451static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
11452 Graphic3d_RenderingParams::PerfCounters& theFlags)
11453{
11454 TCollection_AsciiString aValue = theValue;
11455 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
11456 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
11457 Standard_Boolean toReset = Standard_False;
11458 for (;;)
11459 {
11460 Standard_Integer aSplitPos = aValue.Search ("|");
11461 if (aSplitPos <= 0)
11462 {
11463 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
11464 {
11465 return Standard_False;
11466 }
11467 if (toReset)
11468 {
11469 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
11470 }
11471 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
11472 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
11473 return Standard_True;
11474 }
11475
11476 if (aSplitPos > 1)
11477 {
11478 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
11479 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
11480 {
11481 return Standard_False;
11482 }
11483 }
11484 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
11485 }
11486}
11487
e276548b 11488//=======================================================================
bc8c79bb 11489//function : VRenderParams
11490//purpose : Enables/disables rendering features
e276548b 11491//=======================================================================
11492
bc8c79bb 11493static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
11494 Standard_Integer theArgNb,
11495 const char** theArgVec)
e276548b 11496{
7ae4a307 11497 Handle(V3d_View) aView = ViewerTest::CurrentView();
11498 if (aView.IsNull())
e276548b 11499 {
bc8c79bb 11500 std::cerr << "Error: no active viewer!\n";
e276548b 11501 return 1;
11502 }
bc8c79bb 11503
11504 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
6b62b2da 11505 TCollection_AsciiString aCmdName (theArgVec[0]);
11506 aCmdName.LowerCase();
11507 if (aCmdName == "vraytrace")
11508 {
11509 if (theArgNb == 1)
11510 {
11511 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
11512 return 0;
11513 }
11514 else if (theArgNb == 2)
11515 {
11516 TCollection_AsciiString aValue (theArgVec[1]);
11517 aValue.LowerCase();
11518 if (aValue == "on"
11519 || aValue == "1")
11520 {
11521 aParams.Method = Graphic3d_RM_RAYTRACING;
11522 aView->Redraw();
11523 return 0;
11524 }
11525 else if (aValue == "off"
11526 || aValue == "0")
11527 {
11528 aParams.Method = Graphic3d_RM_RASTERIZATION;
11529 aView->Redraw();
11530 return 0;
11531 }
11532 else
11533 {
11534 std::cout << "Error: unknown argument '" << theArgVec[1] << "'\n";
11535 return 1;
11536 }
11537 }
11538 else
11539 {
11540 std::cout << "Error: wrong number of arguments\n";
11541 return 1;
11542 }
11543 }
bc8c79bb 11544
11545 if (theArgNb < 2)
e276548b 11546 {
bc8c79bb 11547 theDI << "renderMode: ";
11548 switch (aParams.Method)
11549 {
11550 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11551 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
11552 }
11553 theDI << "\n";
a1073ae2 11554 theDI << "transparency: ";
11555 switch (aParams.TransparencyMethod)
11556 {
11557 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
11558 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
11559 << TCollection_AsciiString (aParams.OitDepthFactor); break;
11560 }
11561 theDI << "\n";
b4327ba8 11562 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
56689b27 11563 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
b4327ba8 11564 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
11565 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
11566 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
11567 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
11568 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
11569 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
11570 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
11571 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
11572 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
11573 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
b09447ed 11574 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
4eaaf9d8 11575 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
66d1cdc6 11576 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
8625ef7e 11577 theDI << "shadingModel: ";
11578 switch (aView->ShadingModel())
11579 {
dc89236f 11580 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
11581 case Graphic3d_TOSM_UNLIT: theDI << "unlit"; break;
11582 case Graphic3d_TOSM_FACET: theDI << "flat"; break;
11583 case Graphic3d_TOSM_VERTEX: theDI << "gouraud"; break;
11584 case Graphic3d_TOSM_FRAGMENT: theDI << "phong"; break;
8625ef7e 11585 }
15669413 11586 {
11587 theDI << "perfCounters:";
11588 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
11589 {
11590 theDI << " fps";
11591 }
11592 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
11593 {
11594 theDI << " cpu";
11595 }
11596 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
11597 {
11598 theDI << " structs";
11599 }
11600 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
11601 {
11602 theDI << " groups";
11603 }
11604 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
11605 {
11606 theDI << " arrays";
11607 }
11608 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
11609 {
11610 theDI << " tris";
11611 }
11612 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
11613 {
11614 theDI << " pnts";
11615 }
11616 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
11617 {
11618 theDI << " gpumem";
11619 }
5e30547b 11620 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
11621 {
11622 theDI << " frameTime";
11623 }
11624 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
11625 {
11626 theDI << " skipimmediate";
11627 }
15669413 11628 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
11629 {
11630 theDI << " none";
11631 }
11632 theDI << "\n";
11633 }
f88457e6 11634 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
c40eb6b9 11635 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
0e3025bc 11636 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
11637 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
11638 "noUpdate") << "\n";
8625ef7e 11639 theDI << "\n";
bc8c79bb 11640 return 0;
e276548b 11641 }
11642
bc8c79bb 11643 Standard_Boolean toPrint = Standard_False;
8625ef7e 11644 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
e276548b 11645 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11646 {
bc8c79bb 11647 Standard_CString anArg (theArgVec[anArgIter]);
11648 TCollection_AsciiString aFlag (anArg);
11649 aFlag.LowerCase();
8625ef7e 11650 if (anUpdateTool.parseRedrawMode (aFlag))
11651 {
11652 continue;
11653 }
11654 else if (aFlag == "-echo"
11655 || aFlag == "-print")
e276548b 11656 {
bc8c79bb 11657 toPrint = Standard_True;
8625ef7e 11658 anUpdateTool.Invalidate();
e276548b 11659 }
bc8c79bb 11660 else if (aFlag == "-mode"
11661 || aFlag == "-rendermode"
11662 || aFlag == "-render_mode")
e276548b 11663 {
bc8c79bb 11664 if (toPrint)
11665 {
11666 switch (aParams.Method)
11667 {
11668 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11669 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11670 }
11671 continue;
11672 }
e276548b 11673 else
bc8c79bb 11674 {
11675 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
11676 return 1;
11677 }
11678 }
11679 else if (aFlag == "-ray"
11680 || aFlag == "-raytrace")
11681 {
11682 if (toPrint)
11683 {
11684 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11685 continue;
11686 }
11687
11688 aParams.Method = Graphic3d_RM_RAYTRACING;
e276548b 11689 }
bc8c79bb 11690 else if (aFlag == "-rast"
11691 || aFlag == "-raster"
11692 || aFlag == "-rasterization")
e276548b 11693 {
bc8c79bb 11694 if (toPrint)
11695 {
11696 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11697 continue;
11698 }
11699
11700 aParams.Method = Graphic3d_RM_RASTERIZATION;
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 {
11711 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
11712 return 1;
11713 }
11714
11715 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11716 if (aNbSamples < 0)
11717 {
11718 std::cerr << "Error: invalid number of MSAA samples " << aNbSamples << ".\n";
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 {
11737 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
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 {
11745 std::cerr << "Error: invalid value of line width feather " << aFeather << ". Should be > 0\n";
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 {
11766 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
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 {
11777 std::cerr << "Error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]\n";
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 {
11790 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
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
11803 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
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
11818 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
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 {
11834 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
11835 return 1;
11836 }
11837
11838 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11839 if (aScale < 0.01)
11840 {
11841 std::cerr << "Error: invalid rendering resolution scale " << aScale << ".\n";
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 {
11859 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
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 {
11868 std::cerr << "Error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]\n";
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
a5565a3c 11887 && !ViewerTest::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
a5565a3c 11904 && !ViewerTest::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
a5565a3c 11920 && !ViewerTest::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
a5565a3c 11936 && !ViewerTest::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
a5565a3c 11952 && !ViewerTest::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
a5565a3c 11973 && !ViewerTest::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 {
11988 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
11989 return 1;
11990 }
11991
11992 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11993 if (!aMaxRadStr.IsRealValue())
11994 {
11995 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
11996 return 1;
11997 }
11998
11999 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
12000 if (aMaxRadiance <= 0.0)
12001 {
12002 std::cerr << "Error: invalid radiance clamping value " << aMaxRadiance << ".\n";
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
12020 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
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
12036 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
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
12052 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
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 {
12067 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
12068 return 1;
12069 }
12070
12071 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
12072 if (aTileSize < 1)
12073 {
12074 std::cerr << "Error: invalid size of ISS tile " << aTileSize << ".\n";
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 {
12088 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
12089 return 1;
12090 }
12091
12092 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
66d1cdc6 12093 if (aNbTiles < -1)
4eaaf9d8 12094 {
12095 std::cerr << "Error: invalid number of ISS tiles " << aNbTiles << ".\n";
4eaaf9d8 12096 return 1;
12097 }
66d1cdc6 12098 else if (aNbTiles > 0
12099 && (aNbTiles < 64
12100 || aNbTiles > 1024))
4eaaf9d8 12101 {
66d1cdc6 12102 std::cerr << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].\n";
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
a5565a3c 12116 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
189f85a3 12117 {
12118 --anArgIter;
12119 }
12120 aParams.UseEnvironmentMapBackground = toEnable;
12121 }
b4327ba8 12122 else if (aFlag == "-twoside")
12123 {
12124 if (toPrint)
12125 {
12126 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
12127 continue;
12128 }
12129
12130 Standard_Boolean toEnable = Standard_True;
12131 if (++anArgIter < theArgNb
12132 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12133 {
12134 --anArgIter;
12135 }
12136 aParams.TwoSidedBsdfModels = toEnable;
12137 }
8625ef7e 12138 else if (aFlag == "-shademodel"
12139 || aFlag == "-shadingmodel"
12140 || aFlag == "-shading")
12141 {
12142 if (toPrint)
12143 {
12144 switch (aView->ShadingModel())
12145 {
dc89236f 12146 case Graphic3d_TOSM_DEFAULT: theDI << "default"; break;
12147 case Graphic3d_TOSM_UNLIT: theDI << "unlit "; break;
12148 case Graphic3d_TOSM_FACET: theDI << "flat "; break;
12149 case Graphic3d_TOSM_VERTEX: theDI << "gouraud "; break;
12150 case Graphic3d_TOSM_FRAGMENT: theDI << "phong "; break;
8625ef7e 12151 }
12152 continue;
12153 }
12154
12155 if (++anArgIter >= theArgNb)
12156 {
12157 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
12158 }
12159
dc89236f 12160 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TOSM_DEFAULT;
12161 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
12162 && aModel != Graphic3d_TOSM_DEFAULT)
8625ef7e 12163 {
dc89236f 12164 aView->SetShadingModel (aModel);
8625ef7e 12165 }
12166 else
12167 {
dc89236f 12168 std::cout << "Error: unknown shading model '" << theArgVec[anArgIter] << "'\n";
8625ef7e 12169 return 1;
12170 }
12171 }
4b1c8733 12172 else if (aFlag == "-resolution")
12173 {
12174 if (++anArgIter >= theArgNb)
12175 {
12176 std::cerr << "Error: wrong syntax at argument '" << anArg << "'\n";
12177 return 1;
12178 }
12179
12180 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
12181 if (aResolution.IsIntegerValue())
12182 {
12183 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
12184 }
12185 else
12186 {
12187 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12188 return 1;
12189 }
12190 }
d877e610 12191 else if (aFlag == "-rebuildglsl"
12192 || aFlag == "-rebuild")
12193 {
12194 if (toPrint)
12195 {
12196 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
12197 continue;
12198 }
12199
12200 Standard_Boolean toEnable = Standard_True;
12201 if (++anArgIter < theArgNb
12202 && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
12203 {
12204 --anArgIter;
12205 }
12206 aParams.RebuildRayTracingShaders = toEnable;
12207 }
b27ab03d 12208 else if (aFlag == "-focal")
12209 {
12210 if (++anArgIter >= theArgNb)
12211 {
12212 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12213 return 1;
12214 }
12215
12216 TCollection_AsciiString aParam (theArgVec[anArgIter]);
12217 if (aParam.IsRealValue())
12218 {
12219 float aFocalDist = static_cast<float> (aParam.RealValue());
12220 if (aFocalDist < 0)
12221 {
12222 std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
12223 return 1;
12224 }
12225 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
12226 }
12227 else
12228 {
12229 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12230 return 1;
12231 }
12232 }
12233 else if (aFlag == "-aperture")
12234 {
12235 if (++anArgIter >= theArgNb)
12236 {
12237 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12238 return 1;
12239 }
12240
12241 TCollection_AsciiString aParam(theArgVec[anArgIter]);
12242 if (aParam.IsRealValue())
12243 {
12244 float aApertureSize = static_cast<float> (aParam.RealValue());
12245 if (aApertureSize < 0)
12246 {
12247 std::cout << "Error: parameter can't be negative at argument '" << anArg << "'.\n";
12248 return 1;
12249 }
12250 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
12251 }
12252 else
12253 {
12254 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12255 return 1;
12256 }
12257 }
eb85ed36 12258 else if (aFlag == "-exposure")
12259 {
12260 if (++anArgIter >= theArgNb)
12261 {
12262 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12263 return 1;
12264 }
12265
12266 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
12267 if (anExposure.IsRealValue())
12268 {
12269 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
12270 }
12271 else
12272 {
12273 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12274 return 1;
12275 }
12276 }
12277 else if (aFlag == "-whitepoint")
12278 {
12279 if (++anArgIter >= theArgNb)
12280 {
12281 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12282 return 1;
12283 }
12284
12285 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
12286 if (aWhitePoint.IsRealValue())
12287 {
12288 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
12289 }
12290 else
12291 {
12292 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12293 return 1;
12294 }
12295 }
12296 else if (aFlag == "-tonemapping")
12297 {
12298 if (++anArgIter >= theArgNb)
12299 {
12300 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12301 return 1;
12302 }
12303
12304 TCollection_AsciiString aMode (theArgVec[anArgIter]);
12305 aMode.LowerCase();
12306
12307 if (aMode == "disabled")
12308 {
12309 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
12310 }
12311 else if (aMode == "filmic")
12312 {
12313 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
12314 }
12315 else
12316 {
12317 std::cout << "Error: wrong syntax at argument'" << anArg << "'.\n";
12318 return 1;
12319 }
12320 }
15669413 12321 else if (aFlag == "-performancestats"
12322 || aFlag == "-performancecounters"
12323 || aFlag == "-perfstats"
12324 || aFlag == "-perfcounters"
12325 || aFlag == "-stats")
12326 {
12327 if (++anArgIter >= theArgNb)
12328 {
12329 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12330 return 1;
12331 }
12332
12333 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
12334 aFlagsStr.LowerCase();
12335 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
12336 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
12337 {
12338 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12339 return 1;
12340 }
12341 aView->ChangeRenderingParams().CollectedStats = aFlags;
12342 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
12343 }
12344 else if (aFlag == "-perfupdateinterval"
12345 || aFlag == "-statsupdateinterval")
12346 {
12347 if (++anArgIter >= theArgNb)
12348 {
12349 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12350 return 1;
12351 }
12352 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12353 }
5e30547b 12354 else if (aFlag == "-perfchart"
12355 || aFlag == "-statschart")
12356 {
12357 if (++anArgIter >= theArgNb)
12358 {
12359 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12360 return 1;
12361 }
12362 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12363 }
12364 else if (aFlag == "-perfchartmax"
12365 || aFlag == "-statschartmax")
12366 {
12367 if (++anArgIter >= theArgNb)
12368 {
12369 std::cout << "Error: wrong syntax at argument '" << anArg << "'\n";
12370 return 1;
12371 }
12372 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12373 }
0e3025bc 12374 else if (aFlag == "-frustumculling"
12375 || aFlag == "-culling")
12376 {
12377 if (toPrint)
12378 {
12379 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12380 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12381 "noUpdate") << " ";
12382 continue;
12383 }
12384
12385 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12386 if (++anArgIter < theArgNb)
12387 {
12388 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12389 aStateStr.LowerCase();
12390 bool toEnable = true;
12391 if (ViewerTest::ParseOnOff (aStateStr.ToCString(), toEnable))
12392 {
12393 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12394 }
12395 else if (aStateStr == "noupdate"
12396 || aStateStr == "freeze")
12397 {
12398 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12399 }
12400 else
12401 {
12402 --anArgIter;
12403 }
12404 }
12405 aParams.FrustumCullingState = aState;
12406 }
e276548b 12407 else
12408 {
bc8c79bb 12409 std::cout << "Error: wrong syntax, unknown flag '" << anArg << "'\n";
12410 return 1;
e276548b 12411 }
12412 }
189f85a3 12413
12414 return 0;
12415}
12416
79b544e6 12417//=======================================================================
12418//function : searchInfo
12419//purpose :
12420//=======================================================================
12421inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12422 const TCollection_AsciiString& theKey)
12423{
12424 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12425 {
12426 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12427 {
12428 return anIter.Value();
12429 }
12430 }
12431 return TCollection_AsciiString();
12432}
12433
12434//=======================================================================
12435//function : VStatProfiler
12436//purpose :
12437//=======================================================================
12438static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12439 Standard_Integer theArgNb,
12440 const char** theArgVec)
12441{
12442 Handle(V3d_View) aView = ViewerTest::CurrentView();
12443 if (aView.IsNull())
12444 {
12445 std::cerr << "Error: no active viewer!\n";
12446 return 1;
12447 }
12448
12449 Standard_Boolean toRedraw = Standard_True;
12450 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12451 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12452 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12453 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12454 {
12455 Standard_CString anArg (theArgVec[anArgIter]);
12456 TCollection_AsciiString aFlag (anArg);
12457 aFlag.LowerCase();
12458 if (aFlag == "-noredraw")
12459 {
12460 toRedraw = Standard_False;
12461 }
12462 else
12463 {
12464 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12465 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12466 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12467 else if (aFlag == "alllayers"
12468 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12469 else if (aFlag == "allstructs"
12470 || aFlag == "structs") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
12471 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12472 else if (aFlag == "allarrays"
12473 || aFlag == "fillarrays"
12474 || aFlag == "linearrays"
12475 || aFlag == "pointarrays"
12476 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12477 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
12478 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12479 else if (aFlag == "geommem"
12480 || aFlag == "texturemem"
12481 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12482 else if (aFlag == "elapsedframe"
12483 || aFlag == "cpuframeaverage"
12484 || aFlag == "cpupickingaverage"
12485 || aFlag == "cpucullingaverage"
12486 || aFlag == "cpudynaverage"
12487 || aFlag == "cpuframemax"
12488 || aFlag == "cpupickingmax"
12489 || aFlag == "cpucullingmax"
12490 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12491 else
12492 {
12493 std::cerr << "Unknown argument '" << theArgVec[anArgIter] << "'!\n";
12494 continue;
12495 }
12496
12497 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12498 }
12499 }
12500
12501 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12502 {
12503 aView->ChangeRenderingParams().CollectedStats =
12504 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12505
12506 if (toRedraw)
12507 {
12508 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12509 aView->Redraw();
12510 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12511 }
12512
12513 TColStd_IndexedDataMapOfStringString aDict;
12514 aView->StatisticInformation (aDict);
12515
12516 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12517
12518 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12519 {
12520 Standard_CString anArg(theArgVec[anArgIter]);
12521 TCollection_AsciiString aFlag(anArg);
12522 aFlag.LowerCase();
12523 if (aFlag == "fps")
12524 {
12525 theDI << searchInfo (aDict, "FPS") << " ";
12526 }
12527 else if (aFlag == "cpu")
12528 {
12529 theDI << searchInfo (aDict, "CPU FPS") << " ";
12530 }
12531 else if (aFlag == "alllayers")
12532 {
12533 theDI << searchInfo (aDict, "Layers") << " ";
12534 }
12535 else if (aFlag == "layers")
12536 {
12537 theDI << searchInfo (aDict, "Rendered layers") << " ";
12538 }
12539 else if (aFlag == "allstructs")
12540 {
12541 theDI << searchInfo (aDict, "Structs") << " ";
12542 }
12543 else if (aFlag == "structs")
12544 {
12545 theDI << searchInfo (aDict, "Rendered structs") << " ";
12546 }
12547 else if (aFlag == "groups")
12548 {
12549 theDI << searchInfo (aDict, "Rendered groups") << " ";
12550 }
12551 else if (aFlag == "allarrays")
12552 {
12553 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12554 }
12555 else if (aFlag == "fillarrays")
12556 {
12557 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12558 }
12559 else if (aFlag == "linearrays")
12560 {
12561 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12562 }
12563 else if (aFlag == "pointarrays")
12564 {
12565 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12566 }
12567 else if (aFlag == "textarrays")
12568 {
12569 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12570 }
12571 else if (aFlag == "triangles")
12572 {
12573 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12574 }
12575 else if (aFlag == "points")
12576 {
12577 theDI << searchInfo (aDict, "Rendered points") << " ";
12578 }
12579 else if (aFlag == "geommem")
12580 {
12581 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12582 }
12583 else if (aFlag == "texturemem")
12584 {
12585 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12586 }
12587 else if (aFlag == "framemem")
12588 {
12589 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12590 }
12591 else if (aFlag == "elapsedframe")
12592 {
12593 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12594 }
12595 else if (aFlag == "cpuframe_average")
12596 {
12597 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12598 }
12599 else if (aFlag == "cpupicking_average")
12600 {
12601 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12602 }
12603 else if (aFlag == "cpuculling_average")
12604 {
12605 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12606 }
12607 else if (aFlag == "cpudyn_average")
12608 {
12609 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12610 }
12611 else if (aFlag == "cpuframe_max")
12612 {
12613 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12614 }
12615 else if (aFlag == "cpupicking_max")
12616 {
12617 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12618 }
12619 else if (aFlag == "cpuculling_max")
12620 {
12621 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12622 }
12623 else if (aFlag == "cpudyn_max")
12624 {
12625 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12626 }
12627 }
12628 }
12629 else
12630 {
12631 if (toRedraw)
12632 {
12633 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12634 aView->Redraw();
12635 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12636 }
12637 theDI << "Statistic info:\n" << aView->StatisticInformation();
12638 }
12639 return 0;
12640}
12641
189f85a3 12642//=======================================================================
12643//function : VProgressiveMode
12644//purpose :
12645//=======================================================================
12646#if defined(_WIN32)
12647static Standard_Integer VProgressiveMode (Draw_Interpretor& /*theDI*/,
12648 Standard_Integer /*theNbArgs*/,
12649 const char** /*theArgs*/)
12650{
12651 Handle(V3d_View) aView = ViewerTest::CurrentView();
12652 if (aView.IsNull())
12653 {
12654 std::cerr << "Error: no active viewer!\n";
12655 return 1;
12656 }
12657
12658 std::cout << "Press Enter or Escape key to exit progressive rendering mode" << std::endl;
12659
12660 for (;;)
12661 {
12662 aView->Redraw();
12663
12664 Standard_Boolean toExit = Standard_False;
12665
12666 MSG aMsg;
ad03c234 12667 while (PeekMessageW (&aMsg, NULL, 0, 0, PM_REMOVE))
189f85a3 12668 {
12669 if (aMsg.message == WM_KEYDOWN && (aMsg.wParam == 0x0d || aMsg.wParam == 0x1b))
12670 {
12671 toExit = Standard_True;
12672 }
12673
12674 TranslateMessage (&aMsg);
ad03c234 12675 DispatchMessageW (&aMsg);
189f85a3 12676 }
12677
12678 if (toExit)
12679 {
12680 break;
12681 }
12682 }
12683
e276548b 12684 return 0;
12685}
189f85a3 12686#endif
e276548b 12687
0717ddc1 12688//=======================================================================
12689//function : VXRotate
12690//purpose :
12691//=======================================================================
12692static Standard_Integer VXRotate (Draw_Interpretor& di,
12693 Standard_Integer argc,
12694 const char ** argv)
12695{
12696 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12697 if (aContext.IsNull())
12698 {
586db386 12699 di << argv[0] << "ERROR : use 'vinit' command before \n";
0717ddc1 12700 return 1;
12701 }
8693dfd0 12702
0717ddc1 12703 if (argc != 3)
12704 {
586db386 12705 di << "ERROR : Usage : " << argv[0] << " name angle\n";
0717ddc1 12706 return 1;
12707 }
12708
12709 TCollection_AsciiString aName (argv[1]);
12710 Standard_Real anAngle = Draw::Atof (argv[2]);
12711
12712 // find object
12713 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12714 Handle(AIS_InteractiveObject) anIObj;
8f521168 12715 if (!aMap.Find2 (aName, anIObj))
0717ddc1 12716 {
586db386 12717 di << "Use 'vdisplay' before\n";
0717ddc1 12718 return 1;
12719 }
0717ddc1 12720
8f521168 12721 gp_Trsf aTransform;
12722 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12723 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
0717ddc1 12724
8f521168 12725 aContext->SetLocation (anIObj, aTransform);
12726 aContext->UpdateCurrentViewer();
0717ddc1 12727 return 0;
12728}
12729
625e1958 12730//===============================================================================================
12731//class : ViewerTest_AISManipulator
12732//purpose : Proxy class maintaining automated registry map to enlist existing AIS_Manipulator instances
12733//===============================================================================================
12734DEFINE_STANDARD_HANDLE (ViewerTest_AISManipulator, AIS_Manipulator)
12735
12736class ViewerTest_AISManipulator : public AIS_Manipulator
12737{
12738public:
12739
12740 ViewerTest_AISManipulator() : AIS_Manipulator()
12741 {
12742 GetMapOfAISManipulators().Add (this);
12743 }
12744
12745 virtual ~ViewerTest_AISManipulator()
12746 {
12747 GetMapOfAISManipulators().Remove (this);
12748 }
12749
12750 DEFINE_STANDARD_RTTIEXT(ViewerTest_AISManipulator, AIS_Manipulator)
12751};
12752
12753IMPLEMENT_STANDARD_HANDLE (ViewerTest_AISManipulator, AIS_Manipulator)
12754IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_AISManipulator, AIS_Manipulator)
12755
12756//===============================================================================================
12757//function : VManipulator
12758//purpose :
12759//===============================================================================================
12760static int VManipulator (Draw_Interpretor& theDi,
12761 Standard_Integer theArgsNb,
12762 const char** theArgVec)
12763{
12764 Handle(V3d_View) aView = ViewerTest::CurrentView();
12765 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12766 ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False);
12767 if (aView.IsNull()
12768 || aViewer.IsNull())
12769 {
12770 std::cerr << "No active viewer!\n";
12771 return 1;
12772 }
12773
12774 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12775 Standard_Integer anArgIter = 1;
12776 for (; anArgIter < theArgsNb; ++anArgIter)
12777 {
12778 anUpdateTool.parseRedrawMode (theArgVec[anArgIter]);
12779 }
12780
12781 ViewerTest_CmdParser aCmd;
293211ae 12782 aCmd.SetDescription ("Manages manipulator for interactive objects:");
625e1958 12783 aCmd.AddOption ("attach", "... object - attach manipulator to an object");
12784 aCmd.AddOption ("adjustPosition", "... {0|1} - adjust position when attaching");
12785 aCmd.AddOption ("adjustSize", "... {0|1} - adjust size when attaching ");
12786 aCmd.AddOption ("enableModes", "... {0|1} - enable modes when attaching ");
12787 aCmd.AddOption ("detach", "... - detach manipulator");
12788
12789 aCmd.AddOption ("startTransform", "... mouse_x mouse_y - invoke start transformation");
12790 aCmd.AddOption ("transform", "... mouse_x mouse_y - invoke transformation");
12791 aCmd.AddOption ("stopTransform", "... [abort] - invoke stop transformation");
12792
12793 aCmd.AddOption ("move", "... x y z - move object");
12794 aCmd.AddOption ("rotate", "... x y z dx dy dz angle - rotate object");
12795 aCmd.AddOption ("scale", "... factor - scale object");
12796
12797 aCmd.AddOption ("autoActivate", "... {0|1} - set activation on detection");
12798 aCmd.AddOption ("followTranslation", "... {0|1} - set following translation transform");
12799 aCmd.AddOption ("followRotation", "... {0|1} - set following rotation transform");
f522ce50 12800 aCmd.AddOption ("followDragging", "... {0|1} - set following dragging transform");
625e1958 12801 aCmd.AddOption ("gap", "... value - set gap between sub-parts");
12802 aCmd.AddOption ("part", "... axis mode {0|1} - set visual part");
84b904bc 12803 aCmd.AddOption ("parts", "... all axes mode {0|1} - set visual part");
625e1958 12804 aCmd.AddOption ("pos", "... x y z [nx ny nz [xx xy xz]] - set position of manipulator");
12805 aCmd.AddOption ("size", "... size - set size of manipulator");
12806 aCmd.AddOption ("zoomable", "... {0|1} - set zoom persistence");
12807
12808 aCmd.Parse (theArgsNb, theArgVec);
12809
12810 if (aCmd.HasOption ("help"))
12811 {
12812 theDi.PrintHelp (theArgVec[0]);
12813 return 0;
12814 }
12815
12816 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12817
293211ae 12818 TCollection_AsciiString aName (aCmd.Arg (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY, 0).c_str());
625e1958 12819
12820 if (aName.IsEmpty())
12821 {
12822 std::cerr << theArgVec[0] << " error: please specify AIS manipulator's name as the first argument.\n";
12823 return 1;
12824 }
12825
12826 // ----------------------------------
12827 // detach existing manipulator object
12828 // ----------------------------------
12829
12830 if (aCmd.HasOption ("detach"))
12831 {
12832 if (!aMapAIS.IsBound2 (aName))
12833 {
12834 std::cerr << theArgVec[0] << " error: could not find \"" << aName << "\" AIS object.\n";
12835 return 1;
12836 }
12837
12838 Handle(AIS_Manipulator) aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12839 if (aManipulator.IsNull())
12840 {
12841 std::cerr << theArgVec[0] << " error: \"" << aName << "\" is not an AIS manipulator.\n";
12842 return 1;
12843 }
12844
12845 aManipulator->Detach();
12846 aMapAIS.UnBind2 (aName);
0577ae8c 12847 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_True);
625e1958 12848
12849 return 0;
12850 }
12851
12852 // -----------------------------------------------
12853 // find or create manipulator if it does not exist
12854 // -----------------------------------------------
12855
12856 Handle(AIS_Manipulator) aManipulator;
12857 if (!aMapAIS.IsBound2 (aName))
12858 {
12859 std::cout << theArgVec[0] << ": AIS object \"" << aName << "\" has been created.\n";
12860
12861 aManipulator = new ViewerTest_AISManipulator();
12862 aMapAIS.Bind (aManipulator, aName);
12863 }
12864 else
12865 {
12866 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12867 if (aManipulator.IsNull())
12868 {
12869 std::cerr << theArgVec[0] << " error: \"" << aName << "\" is not an AIS manipulator.\n";
12870 return 1;
12871 }
12872 }
12873
12874 // -----------------------------------------
12875 // change properties of manipulator instance
12876 // -----------------------------------------
12877
12878 if (aCmd.HasOption ("autoActivate", 1, Standard_True))
12879 {
12880 aManipulator->SetModeActivationOnDetection (aCmd.ArgBool ("autoActivate"));
12881 }
12882 if (aCmd.HasOption ("followTranslation", 1, Standard_True))
12883 {
12884 aManipulator->ChangeTransformBehavior().SetFollowTranslation (aCmd.ArgBool ("followTranslation"));
12885 }
12886 if (aCmd.HasOption ("followRotation", 1, Standard_True))
12887 {
12888 aManipulator->ChangeTransformBehavior().SetFollowRotation (aCmd.ArgBool ("followRotation"));
12889 }
f522ce50 12890 if (aCmd.HasOption("followDragging", 1, Standard_True))
12891 {
12892 aManipulator->ChangeTransformBehavior().SetFollowDragging(aCmd.ArgBool("followDragging"));
12893 }
625e1958 12894 if (aCmd.HasOption ("gap", 1, Standard_True))
12895 {
12896 aManipulator->SetGap (aCmd.ArgFloat ("gap"));
12897 }
12898 if (aCmd.HasOption ("part", 3, Standard_True))
12899 {
12900 Standard_Integer anAxis = aCmd.ArgInt ("part", 0);
12901 Standard_Integer aMode = aCmd.ArgInt ("part", 1);
12902 Standard_Boolean aOnOff = aCmd.ArgBool ("part", 2);
f522ce50 12903 if (aMode < 1 || aMode > 4)
625e1958 12904 {
f522ce50 12905 std::cerr << theArgVec[0] << " error: mode value should be in range [1, 4].\n";
625e1958 12906 return 1;
12907 }
12908
12909 aManipulator->SetPart (anAxis, static_cast<AIS_ManipulatorMode> (aMode), aOnOff);
12910 }
84b904bc 12911 if (aCmd.HasOption("parts", 2, Standard_True))
12912 {
12913 Standard_Integer aMode = aCmd.ArgInt("parts", 0);
12914 Standard_Boolean aOnOff = aCmd.ArgBool("parts", 1);
12915 if (aMode < 1 || aMode > 4)
12916 {
12917 std::cerr << theArgVec[0] << " error: mode value should be in range [1, 4].\n";
12918 return 1;
12919 }
12920
12921 aManipulator->SetPart(static_cast<AIS_ManipulatorMode>(aMode), aOnOff);
12922 }
625e1958 12923 if (aCmd.HasOption ("pos", 3, Standard_True))
12924 {
12925 gp_Pnt aLocation = aCmd.ArgPnt ("pos", 0);
12926 gp_Dir aVDir = aCmd.HasOption ("pos", 6) ? gp_Dir (aCmd.ArgVec ("pos", 3)) : aManipulator->Position().Direction();
12927 gp_Dir aXDir = aCmd.HasOption ("pos", 9) ? gp_Dir (aCmd.ArgVec ("pos", 6)) : aManipulator->Position().XDirection();
12928
12929 aManipulator->SetPosition (gp_Ax2 (aLocation, aVDir, aXDir));
12930 }
12931 if (aCmd.HasOption ("size", 1, Standard_True))
12932 {
12933 aManipulator->SetSize (aCmd.ArgFloat ("size"));
12934 }
12935 if (aCmd.HasOption ("zoomable", 1, Standard_True))
12936 {
12937 aManipulator->SetZoomPersistence (!aCmd.ArgBool ("zoomable"));
12938
12939 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12940 {
12941 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
12942 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
12943 }
12944 }
12945
12946 // ---------------------------------------------------
12947 // attach, detach or access manipulator from an object
12948 // ---------------------------------------------------
12949
12950 if (aCmd.HasOption ("attach"))
12951 {
12952 // Find an object and attach manipulator to it
12953 if (!aCmd.HasOption ("attach", 1, Standard_True))
12954 {
12955 return 1;
12956 }
12957
12958 TCollection_AsciiString anObjName (aCmd.Arg ("attach", 0).c_str());
8f521168 12959 Handle(AIS_InteractiveObject) anObject;
12960 if (!aMapAIS.Find2 (anObjName, anObject))
625e1958 12961 {
12962 std::cerr << theArgVec[0] << " error: AIS object \"" << anObjName << "\" does not exist.\n";
12963 return 1;
12964 }
12965
8f521168 12966 for (ViewerTest_MapOfAISManipulators::Iterator anIt (GetMapOfAISManipulators()); anIt.More(); anIt.Next())
625e1958 12967 {
12968 if (anIt.Value()->IsAttached()
12969 && anIt.Value()->Object() == anObject)
12970 {
12971 std::cerr << theArgVec[0] << " error: AIS object \"" << anObjName << "\" already has manipulator.\n";
12972 return 1;
12973 }
12974 }
12975
12976 AIS_Manipulator::OptionsForAttach anOptions;
12977 if (aCmd.HasOption ("adjustPosition", 1, Standard_True))
12978 {
12979 anOptions.SetAdjustPosition (aCmd.ArgBool ("adjustPosition"));
12980 }
12981 if (aCmd.HasOption ("adjustSize", 1, Standard_True))
12982 {
12983 anOptions.SetAdjustSize (aCmd.ArgBool ("adjustSize"));
12984 }
12985 if (aCmd.HasOption ("enableModes", 1, Standard_True))
12986 {
12987 anOptions.SetEnableModes (aCmd.ArgBool ("enableModes"));
12988 }
12989
12990 aManipulator->Attach (anObject, anOptions);
12991 }
12992
12993 // --------------------------------------
12994 // apply transformation using manipulator
12995 // --------------------------------------
12996
12997 if (aCmd.HasOption ("startTransform", 2, Standard_True))
12998 {
12999 aManipulator->StartTransform (aCmd.ArgInt ("startTransform", 0), aCmd.ArgInt ("startTransform", 1), ViewerTest::CurrentView());
13000 }
13001 if (aCmd.HasOption ("transform", 2, Standard_True))
13002 {
13003 aManipulator->Transform (aCmd.ArgInt ("transform", 0), aCmd.ArgInt ("transform", 1), ViewerTest::CurrentView());
13004 }
13005 if (aCmd.HasOption ("stopTransform"))
13006 {
13007 Standard_Boolean toApply = !aCmd.HasOption ("stopTransform", 1) || (aCmd.Arg ("stopTransform", 0) != "abort");
13008
13009 aManipulator->StopTransform (toApply);
13010 }
13011
13012 gp_Trsf aT;
13013 if (aCmd.HasOption ("move", 3, Standard_True))
13014 {
13015 aT.SetTranslationPart (aCmd.ArgVec ("move"));
13016 }
13017 if (aCmd.HasOption ("rotate", 7, Standard_True))
13018 {
13019 aT.SetRotation (gp_Ax1 (aCmd.ArgPnt ("rotate", 0), aCmd.ArgVec ("rotate", 3)), aCmd.ArgDouble ("rotate", 6));
13020 }
13021 if (aCmd.HasOption ("scale", 1))
13022 {
13023 aT.SetScale (gp_Pnt(), aCmd.ArgDouble("scale"));
13024 }
13025
13026 if (aT.Form() != gp_Identity)
13027 {
13028 aManipulator->Transform (aT);
13029 }
13030
0577ae8c 13031 ViewerTest::GetAISContext()->Redisplay (aManipulator, Standard_True);
625e1958 13032
13033 return 0;
13034}
13035
8e5fb5ea 13036//===============================================================================================
13037//function : VSelectionProperties
13038//purpose :
13039//===============================================================================================
13040static int VSelectionProperties (Draw_Interpretor& theDi,
13041 Standard_Integer theArgsNb,
13042 const char** theArgVec)
13043{
13044 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
13045 if (aCtx.IsNull())
13046 {
13047 std::cerr << "No active viewer!\n";
13048 return 1;
13049 }
13050
be3d8cbc 13051 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
13052 {
13053 // handle obsolete alias
13054 bool toEnable = true;
13055 if (theArgsNb < 2)
13056 {
13057 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
13058 return 0;
13059 }
13060 else if (theArgsNb != 2
13061 || !ViewerTest::ParseOnOff (theArgVec[1], toEnable))
13062 {
13063 std::cout << "Syntax error: wrong number of parameters.";
13064 return 1;
13065 }
13066 if (toEnable != aCtx->ToHilightSelected())
13067 {
13068 aCtx->ClearDetected();
13069 aCtx->SetToHilightSelected (toEnable);
13070 }
13071 return 0;
13072 }
13073
f838dac4 13074 Standard_Boolean toPrint = theArgsNb == 1;
13075 Standard_Boolean toRedraw = Standard_False;
13076 Standard_Integer anArgIter = 1;
13077 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
13078 if (anArgIter < theArgsNb)
13079 {
13080 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
13081 anArgFirst.LowerCase();
13082 ++anArgIter;
13083 if (anArgFirst == "dynhighlight"
13084 || anArgFirst == "dynhilight"
13085 || anArgFirst == "dynamichighlight"
13086 || anArgFirst == "dynamichilight")
13087 {
13088 aType = Prs3d_TypeOfHighlight_Dynamic;
13089 }
13090 else if (anArgFirst == "localdynhighlight"
13091 || anArgFirst == "localdynhilight"
13092 || anArgFirst == "localdynamichighlight"
13093 || anArgFirst == "localdynamichilight")
13094 {
13095 aType = Prs3d_TypeOfHighlight_LocalDynamic;
13096 }
13097 else if (anArgFirst == "selhighlight"
13098 || anArgFirst == "selhilight"
13099 || anArgFirst == "selectedhighlight"
13100 || anArgFirst == "selectedhilight")
13101 {
13102 aType = Prs3d_TypeOfHighlight_Selected;
13103 }
13104 else if (anArgFirst == "localselhighlight"
13105 || anArgFirst == "localselhilight"
13106 || anArgFirst == "localselectedhighlight"
13107 || anArgFirst == "localselectedhilight")
13108 {
13109 aType = Prs3d_TypeOfHighlight_LocalSelected;
13110 }
13111 else
13112 {
13113 --anArgIter;
13114 }
13115 }
13116 for (; anArgIter < theArgsNb; ++anArgIter)
13117 {
13118 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13119 anArg.LowerCase();
13120 if (anArg == "-help")
13121 {
13122 theDi.PrintHelp (theArgVec[0]);
13123 return 0;
13124 }
13125 else if (anArg == "-print")
13126 {
13127 toPrint = Standard_True;
13128 }
13129 else if (anArg == "-autoactivate")
13130 {
13131 Standard_Boolean toEnable = Standard_True;
13132 if (anArgIter + 1 < theArgsNb
13133 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13134 {
13135 ++anArgIter;
13136 }
13137 aCtx->SetAutoActivateSelection (toEnable);
13138 }
be3d8cbc 13139 else if (anArg == "-automatichighlight"
13140 || anArg == "-automatichilight"
13141 || anArg == "-autohighlight"
13142 || anArg == "-autohilight")
13143 {
13144 Standard_Boolean toEnable = Standard_True;
13145 if (anArgIter + 1 < theArgsNb
13146 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13147 {
13148 ++anArgIter;
13149 }
13150 aCtx->ClearSelected (false);
13151 aCtx->ClearDetected();
13152 aCtx->SetAutomaticHilight (toEnable);
13153 toRedraw = true;
13154 }
13155 else if (anArg == "-highlightselected"
13156 || anArg == "-hilightselected")
13157 {
13158 Standard_Boolean toEnable = Standard_True;
13159 if (anArgIter + 1 < theArgsNb
13160 && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
13161 {
13162 ++anArgIter;
13163 }
13164 aCtx->ClearDetected();
13165 aCtx->SetToHilightSelected (toEnable);
13166 toRedraw = true;
13167 }
14c4193d 13168 else if (anArg == "-pickstrategy"
13169 || anArg == "-pickingstrategy")
13170 {
13171 if (++anArgIter >= theArgsNb)
13172 {
13173 std::cout << "Syntax error: type of highlighting is undefined\n";
13174 return 1;
13175 }
13176
13177 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13178 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13179 aVal.LowerCase();
13180 if (aVal == "first"
13181 || aVal == "firstaccepted"
13182 || aVal == "firstacceptable")
13183 {
13184 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13185 }
13186 else if (aVal == "topmost"
13187 || aVal == "onlyTopmost")
13188 {
13189 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13190 }
13191 else
13192 {
13193 std::cout << "Syntax error: unknwon picking strategy '" << aVal << "'\n";
13194 return 1;
13195 }
13196
13197 aCtx->SetPickingStrategy (aStrategy);
13198 }
f838dac4 13199 else if (anArg == "-pixtol"
13200 && anArgIter + 1 < theArgsNb)
13201 {
13202 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13203 }
13204 else if ((anArg == "-mode"
13205 || anArg == "-dispmode")
13206 && anArgIter + 1 < theArgsNb)
13207 {
13208 if (aType == Prs3d_TypeOfHighlight_None)
13209 {
13210 std::cout << "Syntax error: type of highlighting is undefined\n";
13211 return 1;
13212 }
8e5fb5ea 13213
f838dac4 13214 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13215 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13216 aStyle->SetDisplayMode (aDispMode);
13217 toRedraw = Standard_True;
13218 }
13219 else if (anArg == "-layer"
13220 && anArgIter + 1 < theArgsNb)
13221 {
13222 if (aType == Prs3d_TypeOfHighlight_None)
13223 {
13224 std::cout << "Syntax error: type of highlighting is undefined\n";
13225 return 1;
13226 }
8e5fb5ea 13227
55c8f0f7
BB
13228 ++anArgIter;
13229 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13230 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
f838dac4 13231 {
55c8f0f7
BB
13232 std::cerr << "Error: wrong syntax at " << theArgVec[anArgIter] << ".\n";
13233 return 1;
f838dac4 13234 }
8e5fb5ea 13235
f838dac4 13236 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13237 aStyle->SetZLayer (aNewLayer);
13238 toRedraw = Standard_True;
13239 }
13240 else if (anArg == "-hicolor"
13241 || anArg == "-selcolor"
13242 || anArg == "-color")
13243 {
13244 if (anArg.StartsWith ("-hi"))
13245 {
13246 aType = Prs3d_TypeOfHighlight_Dynamic;
13247 }
13248 else if (anArg.StartsWith ("-sel"))
13249 {
13250 aType = Prs3d_TypeOfHighlight_Selected;
13251 }
13252 else if (aType == Prs3d_TypeOfHighlight_None)
13253 {
13254 std::cout << "Syntax error: type of highlighting is undefined\n";
13255 return 1;
13256 }
8e5fb5ea 13257
f838dac4 13258 Quantity_Color aColor;
13259 Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgsNb - anArgIter - 1,
13260 theArgVec + anArgIter + 1,
13261 aColor);
13262 if (aNbParsed == 0)
13263 {
13264 std::cout << "Syntax error: need more arguments.\n";
13265 return 1;
13266 }
13267 anArgIter += aNbParsed;
8e5fb5ea 13268
f838dac4 13269 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13270 aStyle->SetColor (aColor);
13271 toRedraw = Standard_True;
13272 }
13273 else if ((anArg == "-transp"
13274 || anArg == "-transparency"
13275 || anArg == "-hitransp"
13276 || anArg == "-seltransp"
13277 || anArg == "-hitransplocal"
13278 || anArg == "-seltransplocal")
13279 && anArgIter + 1 < theArgsNb)
13280 {
13281 if (anArg.StartsWith ("-hi"))
13282 {
13283 aType = Prs3d_TypeOfHighlight_Dynamic;
13284 }
13285 else if (anArg.StartsWith ("-sel"))
13286 {
13287 aType = Prs3d_TypeOfHighlight_Selected;
13288 }
13289 else if (aType == Prs3d_TypeOfHighlight_None)
13290 {
13291 std::cout << "Syntax error: type of highlighting is undefined\n";
13292 return 1;
13293 }
8e5fb5ea 13294
f838dac4 13295 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13296 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13297 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13298 toRedraw = Standard_True;
13299 }
13300 else if ((anArg == "-mat"
13301 || anArg == "-material")
13302 && anArgIter + 1 < theArgsNb)
13303 {
13304 if (aType == Prs3d_TypeOfHighlight_None)
13305 {
13306 std::cout << "Syntax error: type of highlighting is undefined\n";
13307 return 1;
13308 }
8e5fb5ea 13309
f838dac4 13310 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13311 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
13312 if (aMatName != Graphic3d_NOM_DEFAULT)
13313 {
13314 ++anArgIter;
13315 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13316 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13317 Graphic3d_MaterialAspect aMat (aMatName);
13318 aMat.SetColor (aStyle->Color());
13319 aMat.SetTransparency (aStyle->Transparency());
13320 anAspect->SetFrontMaterial (aMat);
13321 anAspect->SetInteriorColor (aStyle->Color());
13322 aStyle->SetBasicFillAreaAspect (anAspect);
13323 }
13324 else
13325 {
13326 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13327 }
13328 toRedraw = Standard_True;
13329 }
13330 else
13331 {
13332 std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
13333 }
8e5fb5ea 13334 }
13335
f838dac4 13336 if (toPrint)
8e5fb5ea 13337 {
f838dac4 13338 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13339 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
8e5fb5ea 13340 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
be3d8cbc 13341 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13342 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
8e5fb5ea 13343 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
f838dac4 13344 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13345 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13346 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13347 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13348 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13349 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13350 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13351 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
8e5fb5ea 13352 }
13353
13354 if (aCtx->NbSelected() != 0 && toRedraw)
13355 {
13356 aCtx->HilightSelected (Standard_True);
13357 }
13358
13359 return 0;
13360}
13361
decdee7d 13362//===============================================================================================
13363//function : VDumpSelectionImage
13364//purpose :
13365//===============================================================================================
13366static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13367 Standard_Integer theArgsNb,
13368 const char** theArgVec)
13369{
13370 if (theArgsNb < 2)
13371 {
13372 std::cout << "Syntax error: wrong number arguments for '" << theArgVec[0] << "'\n";
13373 return 1;
13374 }
13375
13376 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13377 if (aContext.IsNull())
13378 {
13379 std::cout << "Error: no active view.\n";
13380 return 1;
13381 }
13382
13383 TCollection_AsciiString aFile;
13384 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13385 Image_Format anImgFormat = Image_Format_BGR;
decdee7d 13386 Standard_Integer aPickedIndex = 1;
13387 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13388 {
13389 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13390 aParam.LowerCase();
13391 if (aParam == "-type")
13392 {
13393 if (++anArgIter >= theArgsNb)
13394 {
13395 std::cout << "Syntax error: wrong number parameters of flag '-depth'.\n";
13396 return 1;
13397 }
13398
13399 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13400 aValue.LowerCase();
13401 if (aValue == "depth"
13402 || aValue == "normdepth"
13403 || aValue == "normalizeddepth")
13404 {
13405 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
dc858f4c 13406 anImgFormat = Image_Format_GrayF;
decdee7d 13407 }
13408 if (aValue == "depthinverted"
13409 || aValue == "normdepthinverted"
13410 || aValue == "normalizeddepthinverted"
13411 || aValue == "inverted")
13412 {
13413 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
dc858f4c 13414 anImgFormat = Image_Format_GrayF;
decdee7d 13415 }
13416 else if (aValue == "unnormdepth"
13417 || aValue == "unnormalizeddepth")
13418 {
13419 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
dc858f4c 13420 anImgFormat = Image_Format_GrayF;
decdee7d 13421 }
13422 else if (aValue == "objectcolor"
13423 || aValue == "object"
13424 || aValue == "color")
13425 {
13426 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13427 }
13428 else if (aValue == "entitycolor"
13429 || aValue == "entity")
13430 {
13431 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13432 }
13433 else if (aValue == "ownercolor"
13434 || aValue == "owner")
13435 {
13436 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13437 }
13438 else if (aValue == "selectionmodecolor"
13439 || aValue == "selectionmode"
13440 || aValue == "selmodecolor"
13441 || aValue == "selmode")
13442 {
13443 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13444 }
13445 }
13446 else if (aParam == "-picked"
13447 || aParam == "-pickeddepth"
13448 || aParam == "-pickedindex")
13449 {
13450 if (++anArgIter >= theArgsNb)
13451 {
13452 std::cout << "Syntax error: wrong number parameters at '" << aParam << "'.\n";
13453 return 1;
13454 }
13455
13456 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13457 }
13458 else if (aFile.IsEmpty())
13459 {
13460 aFile = theArgVec[anArgIter];
13461 }
13462 else
13463 {
13464 std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'.\n";
13465 return 1;
13466 }
13467 }
13468 if (aFile.IsEmpty())
13469 {
13470 std::cout << "Syntax error: image file name is missing.\n";
13471 return 1;
13472 }
13473
13474 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13475 Standard_Integer aWidth = 0, aHeight = 0;
13476 aView->Window()->Size (aWidth, aHeight);
13477
13478 Image_AlienPixMap aPixMap;
13479 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13480 {
13481 std::cout << "Error: can't allocate image.\n";
13482 return 1;
13483 }
13484 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13485 {
13486 std::cout << "Error: can't generate selection image.\n";
13487 return 1;
13488 }
13489 if (!aPixMap.Save (aFile))
13490 {
13491 std::cout << "Error: can't save selection image.\n";
13492 return 0;
13493 }
13494 return 0;
13495}
13496
7fd59977 13497//=======================================================================
13498//function : ViewerCommands
13499//purpose :
13500//=======================================================================
13501
13502void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
13503{
13504
13505 const char *group = "ZeViewer";
18d715bd 13506 theCommands.Add("vinit",
fd3f6bd0 13507 "vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]"
2e93433e 13508 "\n\t\t: [-exitOnClose] [-closeOnEscape] [-cloneActive] [-2d_mode {on|off}=off]"
fd3f6bd0 13509 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
13510 "\n\t\t: [-display displayName]"
13511 #endif
13512 "\n\t\t: Creates new View window with specified name viewName."
13513 "\n\t\t: By default the new view is created in the viewer and in"
13514 "\n\t\t: graphic driver shared with active view."
13515 "\n\t\t: -name {driverName/viewerName/viewName | viewerName/viewName | viewName}"
13516 "\n\t\t: If driverName isn't specified the driver will be shared with active view."
13517 "\n\t\t: If viewerName isn't specified the viewer will be shared with active view."
13518#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
13519 "\n\t\t: -display HostName.DisplayNumber[:ScreenNumber]"
13520 "\n\t\t: Display name will be used within creation of graphic driver, when specified."
18d715bd 13521#endif
fd3f6bd0 13522 "\n\t\t: -left, -top pixel position of left top corner of the window."
13523 "\n\t\t: -width, -height width and heigth of window respectively."
9e04ccdc 13524 "\n\t\t: -cloneActive floag to copy camera and dimensions of active view."
fd3f6bd0 13525 "\n\t\t: -exitOnClose when specified, closing the view will exit application."
13526 "\n\t\t: -closeOnEscape when specified, view will be closed on pressing Escape."
2e93433e 13527 "\n\t\t: -2d_mode when on, view will not react on rotate scene events"
fd3f6bd0 13528 "\n\t\t: Additional commands for operations with views: vclose, vactivate, vviewlist.",
7fd59977 13529 __FILE__,VInit,group);
18d715bd 13530 theCommands.Add("vclose" ,
d0cc1cb7 13531 "[view_id [keep_context=0|1]]\n"
18d715bd 13532 "or vclose ALL - to remove all created views\n"
13533 " - removes view(viewer window) defined by its view_id.\n"
13534 " - keep_context: by default 0; if 1 and the last view is deleted"
13535 " the current context is not removed.",
13536 __FILE__,VClose,group);
13537 theCommands.Add("vactivate" ,
e084dbbc 13538 "vactivate view_id [-noUpdate]"
18d715bd 13539 " - activates view(viewer window) defined by its view_id",
13540 __FILE__,VActivate,group);
13541 theCommands.Add("vviewlist",
13542 "vviewlist [format={tree, long}]"
13543 " - prints current list of views per viewer and graphic_driver ID shared between viewers"
13544 " - format: format of result output, if tree the output is a tree view;"
13545 "otherwise it's a list of full view names. By default format = tree",
13546 __FILE__,VViewList,group);
7fd59977 13547 theCommands.Add("vhelp" ,
13548 "vhelp : display help on the viewer commands",
13549 __FILE__,VHelp,group);
13550 theCommands.Add("vtop" ,
27af3052 13551 "vtop or <T> : Top view. Orientation +X+Y" ,
7fd59977 13552 __FILE__,VTop,group);
44b8f2d6 13553 theCommands.Add("vbottom" ,
27af3052 13554 "vbottom : Bottom view. Orientation +X-Y" ,
44b8f2d6 13555 __FILE__,VBottom,group);
13556 theCommands.Add("vleft" ,
27af3052 13557 "vleft : Left view. Orientation -Y+Z" ,
44b8f2d6 13558 __FILE__,VLeft,group);
13559 theCommands.Add("vright" ,
27af3052 13560 "vright : Right view. Orientation +Y+Z" ,
44b8f2d6 13561 __FILE__,VRight,group);
7fd59977 13562 theCommands.Add("vaxo" ,
27af3052 13563 " vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
7fd59977 13564 __FILE__,VAxo,group);
44b8f2d6 13565 theCommands.Add("vfront" ,
27af3052 13566 "vfront : Front view. Orientation +X+Z" ,
44b8f2d6 13567 __FILE__,VFront,group);
13568 theCommands.Add("vback" ,
27af3052 13569 "vback : Back view. Orientation -X+Z" ,
44b8f2d6 13570 __FILE__,VBack,group);
7fd59977 13571 theCommands.Add("vpick" ,
13572 "vpick : vpick X Y Z [shape subshape] ( all variables as string )",
13573 VPick,group);
1beb58d7 13574 theCommands.Add("vfit",
13575 "vfit or <F> [-selected] [-noupdate]"
b586500b 13576 "\n\t\t: [-selected] fits the scene according to bounding box of currently selected objects",
7fd59977 13577 __FILE__,VFit,group);
6262a303 13578 theCommands.Add ("vfitarea",
13579 "vfitarea x1 y1 x2 y2"
13580 "\n\t\t: vfitarea x1 y1 z1 x2 y2 z2"
13581 "\n\t\t: Fit view to show area located between two points"
13582 "\n\t\t: given in world 2D or 3D corrdinates.",
13583 __FILE__, VFitArea, group);
197ac94e 13584 theCommands.Add ("vzfit", "vzfit [scale]\n"
13585 " Matches Z near, Z far view volume planes to the displayed objects.\n"
13586 " \"scale\" - specifies factor to scale computed z range.\n",
13587 __FILE__, VZFit, group);
7fd59977 13588 theCommands.Add("vrepaint",
8693dfd0 13589 "vrepaint [-immediate] [-continuous FPS]"
13590 "\n\t\t: force redraw of active View"
13591 "\n\t\t: -immediate flag performs redraw of immediate layers only;"
13592 "\n\t\t: -continuous activates/deactivates continuous redraw of active View,"
13593 "\n\t\t: 0 means no continuous rendering,"
13594 "\n\t\t: -1 means non-stop redraws,"
13595 "\n\t\t: >0 specifies target framerate,",
7fd59977 13596 __FILE__,VRepaint,group);
13597 theCommands.Add("vclear",
faea8b40 13598 "vclear : vclear"
13599 "\n\t\t: remove all the object from the viewer",
7fd59977 13600 __FILE__,VClear,group);
293211ae 13601 theCommands.Add (
13602 "vbackground",
13603 "Changes background or some background settings.\n"
13604 "\n"
13605 "Usage:\n"
13606 " vbackground -imageFile ImageFile [-imageMode FillType]\n"
13607 " vbackground -imageMode FillType\n"
13608 " vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
13609 " vbackground -gradientMode FillMethod\n"
13610 " vbackground -color Color\n"
13611 " vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
13612 " vbackground -default -color Color\n"
13613 " vbackground -help\n"
13614 "\n"
13615 "Options:\n"
13616 " -imageFile (-imgFile, -image, -img): sets filename of image used as background\n"
13617 " -imageMode (-imgMode, -imageMd, -imgMd): sets image fill type\n"
13618 " -gradient (-grad, -gr): sets background gradient starting and ending colors\n"
13619 " -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
13620 " -color (-col): sets background color\n"
13621 " -default (-def): sets background default gradient or color\n"
13622 " -help (-h): outputs short help message\n"
13623 "\n"
13624 "Arguments:\n"
13625 " Color: Red Green Blue - where Red, Green, Blue must be integers within the range [0, 255]\n"
13626 " or reals within the range [0.0, 1.0]\n"
13627 " ColorName - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
13628 " #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
13629 " FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
13630 "CORNER4\n"
13631 " FillType: one of CENTERED, TILED, STRETCH, NONE\n"
13632 " ImageFile: a name of the file with the image used as a background\n",
13633 __FILE__,
13634 vbackground,
13635 group);
13636 theCommands.Add ("vsetbg",
13637 "Loads image as background."
13638 "\n\t\t: vsetbg ImageFile [FillType]"
13639 "\n\t\t: vsetbg -imageFile ImageFile [-imageMode FillType]"
13640 "\n\t\t: Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.",
13641 __FILE__,
13642 vbackground,
13643 group);
13644 theCommands.Add ("vsetbgmode",
13645 "Changes background image fill type."
13646 "\n\t\t: vsetbgmode [-imageMode] FillType"
13647 "\n\t\t: Alias for 'vbackground -imageMode FillType'.",
13648 __FILE__,
13649 vbackground,
13650 group);
13651 theCommands.Add ("vsetgradientbg",
13652 "Mounts gradient background."
13653 "\n\t\t: vsetgradientbg Color1 Color2 [FillMethod]"
13654 "\n\t\t: vsetgradientbg -gradient Color1 Color2 [-gradientMode FillMethod]"
13655 "\n\t\t: Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.",
13656 __FILE__,
13657 vbackground,
13658 group);
13659 theCommands.Add ("vsetgrbgmode",
13660 "Changes gradient background fill method."
13661 "\n\t\t: vsetgrbgmode [-gradientMode] FillMethod"
13662 "\n\t\t: Alias for 'vbackground -gradientMode FillMethod'.",
13663 __FILE__,
13664 vbackground,
13665 group);
13666 theCommands.Add ("vsetcolorbg",
13667 "Sets background color."
13668 "\n\t\t: vsetcolorbg [-color] Color."
13669 "\n\t\t: Alias for 'vbackground -color Color'.",
13670 __FILE__,
13671 vbackground,
13672 group);
13673 theCommands.Add ("vsetdefaultbg",
13674 "Sets default viewer background fill color (flat/gradient)."
13675 "\n\t\t: vsetdefaultbg Color1 Color2 [FillMethod]"
13676 "\n\t\t: vsetdefaultbg -gradient Color1 Color2 [-gradientMode FillMethod]"
13677 "\n\t\t: Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'."
13678 "\n\t\t: vsetdefaultbg [-color] Color"
13679 "\n\t\t: Alias for 'vbackground -default -color Color'.",
13680 __FILE__,
13681 vbackground,
13682 group);
7fd59977 13683 theCommands.Add("vscale",
13684 "vscale : vscale X Y Z",
13685 __FILE__,VScale,group);
13686 theCommands.Add("vzbufftrihedron",
536d98e2 13687 "vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]"
13688 "\n\t\t: [-position center|left_lower|left_upper|right_lower|right_upper]"
13689 "\n\t\t: [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]"
13690 "\n\t\t: [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]"
13691 "\n\t\t: [-nbfacets value=12] [-colorLabels color=WHITE]"
13692 "\n\t\t: Displays a trihedron",
13693 __FILE__,VZBuffTrihedron,group);
7fd59977 13694 theCommands.Add("vrotate",
4af098ba 13695 "vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]"
13696 "\n : Option -mouseStart starts rotation according to the mouse position"
13697 "\n : Option -mouseMove continues rotation with angle computed"
13698 "\n : from last and new mouse position."
13699 "\n : vrotate AX AY AZ [X Y Z]",
7fd59977 13700 __FILE__,VRotate,group);
13701 theCommands.Add("vzoom",
13702 "vzoom : vzoom coef",
13703 __FILE__,VZoom,group);
13704 theCommands.Add("vpan",
13705 "vpan : vpan dx dy",
13706 __FILE__,VPan,group);
7fd59977 13707 theCommands.Add("vcolorscale",
4b3d6eb1 13708 "vcolorscale name [-noupdate|-update] [-demo]"
13709 "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]"
13710 "\n\t\t: [-font HeightFont=20]"
13711 "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]"
13712 "\n\t\t: [-smoothTransition {on|off}=off]"
13713 "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]"
13714 "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]"
13715 "\n\t\t: [-textpos {left|right|center|none}=right]"
13716 "\n\t\t: [-labelAtBorder {on|off}=on]"
13717 "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]"
13718 "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]"
13719 "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]"
13720 "\n\t\t: [-xy Left=0 Bottom=0]"
13721 "\n\t\t: -demo - displays a color scale with demonstratio values"
13722 "\n\t\t: -colors - set colors for all intervals"
13723 "\n\t\t: -color - set color for specific interval"
13724 "\n\t\t: -textpos - horizontal label position relative to color scale bar"
13725 "\n\t\t: -labelAtBorder - vertical label position relative to color interval;"
13726 "\n\t\t: at border means the value inbetween neighbor intervals,"
13727 "\n\t\t: at center means the center value within current interval"
13728 "\n\t\t: -labels - set labels for all intervals"
13729 "\n\t\t: -freeLabels - same as -labels but does not require"
13730 "\n\t\t: matching the number of intervals"
13731 "\n\t\t: -label - set label for specific interval"
13732 "\n\t\t: -title - set title"
13733 "\n\t\t: -reversed - setup smooth color transition between intervals"
13734 "\n\t\t: -smoothTransition - swap colorscale direction"
13735 "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values"
13736 __FILE__, VColorScale, group);
7fd59977 13737 theCommands.Add("vgraduatedtrihedron",
a79f67f8 13738 "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n"
13739 "\t[-namefont Name] [-valuesfont Name]\n"
13740 "\t[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]\n"
13741 "\t[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]"
13742 "\t[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]\n"
13743 "\t[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]\n"
13744 "\t[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]"
13745 "\t[-xcolor Color] [-ycolor Color] [-zcolor Color]\n"
13746 "\t[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]\n"
13747 "\t[-xticks Number] [-yticks Number] [-zticks Number]\n"
13748 "\t[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]\n"
536d98e2 13749 "\t[-drawgrid on/off] [-drawaxes on/off]\n"
a79f67f8 13750 " - Displays or erases graduated trihedron"
13751 " - xname, yname, zname - names of axes, default: X, Y, Z\n"
13752 " - namefont - font of axes names. Default: Arial\n"
13753 " - xnameoffset, ynameoffset, znameoffset - offset of name from values or tickmarks or axis. Default: 30\n"
13754 " - xnamecolor, ynamecolor, znamecolor - colors of axes names\n"
13755 " - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values from tickmarks or axis. Default: 10\n"
13756 " - valuesfont - font of axes values. Default: Arial\n"
13757 " - xcolor, ycolor, zcolor - color of axis and values\n"
13758 " - xticks, yticks, xzicks - number of tickmark on axes. Default: 5\n"
13759 " - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10\n",
7fd59977 13760 __FILE__,VGraduatedTrihedron,group);
3bffef55 13761 theCommands.Add("vtile" ,
13762 "vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]"
13763 "\n\t\t: Setup view to draw a tile (a part of virtual bigger viewport)."
13764 "\n\t\t: -totalSize the size of virtual bigger viewport"
13765 "\n\t\t: -tileSize tile size (the view size will be used if omitted)"
13766 "\n\t\t: -lowerLeft tile offset as lower left corner"
13767 "\n\t\t: -upperLeft tile offset as upper left corner",
13768 __FILE__, VTile, group);
59f45b7c 13769 theCommands.Add("vzlayer",
7c3ef2f7 13770 "vzlayer [layerId]"
13771 "\n\t\t: [-add|-delete|-get|-settings]"
4ecf34cc 13772 "\n\t\t: [-origin X Y Z] [-cullDist Distance] [-cullSize Size]"
7c3ef2f7 13773 "\n\t\t: [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]"
13774 "\n\t\t: [-enable|-disable {positiveOffset|negativeOffset|textureenv}]"
13775 "\n\t\t: ZLayer list management:"
13776 "\n\t\t: -add add new z layer to viewer and print its id"
13777 "\n\t\t: -delete delete z layer"
13778 "\n\t\t: -get print sequence of z layers"
13779 "\n\t\t: -settings print status of z layer settings"
13780 "\n\t\t: -disable disables given setting"
13781 "\n\t\t: -enable enables given setting",
59f45b7c 13782 __FILE__,VZLayer,group);
20637bd2 13783 theCommands.Add("vlayerline",
13784 "vlayerline : vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]",
13785 __FILE__,VLayerLine,group);
79931835 13786 theCommands.Add("vgrid",
13787 "vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]"
13788 "\n\t\t: [-step X Y] [-size DX DY]"
13789 "\n\t\t: [-step StepRadius NbDivisions] [-radius Radius]",
2bd4c032 13790 __FILE__, VGrid, group);
c40b7d58 13791 theCommands.Add ("vpriviledgedplane",
13792 "vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]"
13793 "\n\t\t: Ox, Oy, Oz - plane origin"
13794 "\n\t\t: Nx, Ny, Nz - plane normal direction"
13795 "\n\t\t: Xx, Xy, Xz - plane x-reference axis direction"
13796 "\n\t\t: Sets or prints viewer's priviledged plane geometry.",
13797 __FILE__, VPriviledgedPlane, group);
f25b82d6 13798 theCommands.Add ("vconvert",
13799 "vconvert v [Mode={window|view}]"
13800 "\n\t\t: vconvert x y [Mode={window|view|grid|ray}]"
13801 "\n\t\t: vconvert x y z [Mode={window|grid}]"
13802 "\n\t\t: window - convert to window coordinates, pixels"
13803 "\n\t\t: view - convert to view projection plane"
13804 "\n\t\t: grid - convert to model coordinates, given on grid"
13805 "\n\t\t: ray - convert projection ray to model coordiantes"
13806 "\n\t\t: - vconvert v window : convert view to window;"
13807 "\n\t\t: - vconvert v view : convert window to view;"
13808 "\n\t\t: - vconvert x y window : convert view to window;"
13809 "\n\t\t: - vconvert x y view : convert window to view;"
13810 "\n\t\t: - vconvert x y : convert window to model;"
13811 "\n\t\t: - vconvert x y grid : convert window to model using grid;"
13812 "\n\t\t: - vconvert x y ray : convert window projection line to model;"
13813 "\n\t\t: - vconvert x y z window : convert model to window;"
13814 "\n\t\t: - vconvert x y z grid : convert view to model using grid;"
13815 "\n\t\t: Converts the given coordinates to window/view/model space.",
13816 __FILE__, VConvert, group);
208e6839 13817 theCommands.Add ("vfps",
e084dbbc 13818 "vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view",
208e6839 13819 __FILE__, VFps, group);
58655684 13820 theCommands.Add ("vgldebug",
c87535af 13821 "vgldebug [-sync {0|1}] [-debug {0|1}] [-glslWarn {0|1}]"
84e84755 13822 "\n\t\t: [-glslCode {off|short|full}] [-extraMsg {0|1}] [{0|1}]"
c87535af 13823 "\n\t\t: Request debug GL context. Should be called BEFORE vinit."
13824 "\n\t\t: Debug context can be requested only on Windows"
13825 "\n\t\t: with GL_ARB_debug_output extension implemented by GL driver!"
13826 "\n\t\t: -sync - request synchronized debug GL context"
13827 "\n\t\t: -glslWarn - log GLSL compiler/linker warnings,"
13828 "\n\t\t: which are suppressed by default,"
84e84755 13829 "\n\t\t: -glslCode - log GLSL program source code,"
13830 "\n\t\t: which are suppressed by default,"
c87535af 13831 "\n\t\t: -extraMsg - log extra diagnostic messages from GL context,"
13832 "\n\t\t: which are suppressed by default",
58655684 13833 __FILE__, VGlDebug, group);
208e6839 13834 theCommands.Add ("vvbo",
58655684 13835 "vvbo [{0|1}] : turn VBO usage On/Off; affects only newly displayed objects",
208e6839 13836 __FILE__, VVbo, group);
b5ac8292 13837 theCommands.Add ("vstereo",
f978241f 13838 "vstereo [0|1] [-mode Mode] [-reverse {0|1}]"
13839 "\n\t\t: [-anaglyph Filter]"
13840 "\n\t\t: Control stereo output mode. Available modes for -mode:"
13841 "\n\t\t: quadBuffer - OpenGL QuadBuffer stereo,"
13842 "\n\t\t: requires driver support."
13843 "\n\t\t: Should be called BEFORE vinit!"
13844 "\n\t\t: anaglyph - Anaglyph glasses"
13845 "\n\t\t: rowInterlaced - row-interlaced display"
13846 "\n\t\t: columnInterlaced - column-interlaced display"
13847 "\n\t\t: chessBoard - chess-board output"
13848 "\n\t\t: sideBySide - horizontal pair"
13849 "\n\t\t: overUnder - vertical pair"
13850 "\n\t\t: Available Anaglyph filters for -anaglyph:"
13851 "\n\t\t: redCyan, redCyanSimple, yellowBlue, yellowBlueSimple,"
13852 "\n\t\t: greenMagentaSimple",
b5ac8292 13853 __FILE__, VStereo, group);
a577aaab 13854 theCommands.Add ("vcaps",
2a332745 13855 "vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
1dfe71a6 13856 "\n\t\t: [-compatibleProfile {0|1}]"
56689b27 13857 "\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}]"
f978241f 13858 "\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
8625ef7e 13859 "\n\t\t: [-softMode {0|1}] [-noupdate|-update]"
13860 "\n\t\t: Modify particular graphic driver options:"
13861 "\n\t\t: FFP - use fixed-function pipeline instead of"
13862 "\n\t\t: built-in GLSL programs"
4e1523ef 13863 "\n\t\t: (requires compatible profile)"
2a332745 13864 "\n\t\t: polygonMode - use Polygon Mode instead of built-in GLSL programs"
8625ef7e 13865 "\n\t\t: VBO - use Vertex Buffer Object (copy vertex"
13866 "\n\t\t: arrays to GPU memory)"
13867 "\n\t\t: sprite - use textured sprites instead of bitmaps"
f978241f 13868 "\n\t\t: vsync - switch VSync on or off"
56689b27 13869 "\n\t\t: winBuffer - allow using window buffer for rendering"
4e1523ef 13870 "\n\t\t: Context creation options:"
13871 "\n\t\t: softMode - software OpenGL implementation"
13872 "\n\t\t: compatibleProfile - backward-compatible profile"
f978241f 13873 "\n\t\t: quadbuffer - QuadBuffer"
8625ef7e 13874 "\n\t\t: Unlike vrenderparams, these parameters control alternative"
13875 "\n\t\t: rendering paths producing the same visual result when"
13876 "\n\t\t: possible."
13877 "\n\t\t: Command is intended for testing old hardware compatibility.",
a577aaab 13878 __FILE__, VCaps, group);
f0430952 13879 theCommands.Add ("vmemgpu",
13880 "vmemgpu [f]: print system-dependent GPU memory information if available;"
13881 " with f option returns free memory in bytes",
13882 __FILE__, VMemGpu, group);
85e096c3 13883 theCommands.Add ("vreadpixel",
55c8f0f7 13884 "vreadpixel xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [-name]"
85e096c3 13885 " : Read pixel value for active view",
13886 __FILE__, VReadPixel, group);
692613e5 13887 theCommands.Add("diffimage",
fd3f6bd0 13888 "diffimage imageFile1 imageFile2 [diffImageFile]"
13889 "\n\t\t: [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]"
13890 "\n\t\t: [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]"
13891 "\n\t\t: Compare two images by content and generate difference image."
13892 "\n\t\t: When -exitOnClose is specified, closing the view will exit application."
13893 "\n\t\t: When -closeOnEscape is specified, view will be closed on pressing Escape.",
692613e5 13894 __FILE__, VDiffImage, group);
4754e164 13895 theCommands.Add ("vselect",
2157d6ac 13896 "vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1] [shift_selection = 0|1]\n"
4754e164 13897 "- emulates different types of selection:\n"
13898 "- 1) single click selection\n"
13899 "- 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)\n"
13900 "- 3) selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn)\n"
faea8b40 13901 "- 4) -allowoverlap manages overlap and inclusion detection in rectangular selection.\n"
13902 " If the flag is set to 1, both sensitives that were included completely and overlapped partially by defined rectangle will be detected,\n"
13903 " otherwise algorithm will chose only fully included sensitives. Default behavior is to detect only full inclusion. "
2157d6ac 13904 " (partial inclusion - overlap - is not allowed by default)\n"
13905 "- 5) any of these selections with shift button pressed",
4754e164 13906 __FILE__, VSelect, group);
13907 theCommands.Add ("vmoveto",
8a590580 13908 "vmoveto [x y] [-reset]"
13909 "\n\t\t: Emulates cursor movement to pixel position (x,y)."
13910 "\n\t\t: -reset resets current highlighting",
4754e164 13911 __FILE__, VMoveTo, group);
1beb58d7 13912 theCommands.Add ("vviewparams",
13913 "vviewparams [-args] [-scale [s]]"
13914 "\n\t\t: [-eye [x y z]] [-at [x y z]] [-up [x y z]]"
13915 "\n\t\t: [-proj [x y z]] [-center x y] [-size sx]"
13916 "\n\t\t: Manage current view parameters or prints all"
13917 "\n\t\t: current values when called without argument."
13918 "\n\t\t: -scale [s] prints or sets viewport relative scale"
13919 "\n\t\t: -eye [x y z] prints or sets eye location"
13920 "\n\t\t: -at [x y z] prints or sets center of look"
13921 "\n\t\t: -up [x y z] prints or sets direction of up vector"
13922 "\n\t\t: -proj [x y z] prints or sets direction of look"
13923 "\n\t\t: -center x y sets location of center of the screen in pixels"
13924 "\n\t\t: -size [sx] prints viewport projection width and height sizes"
13925 "\n\t\t: or changes the size of its maximum dimension"
13926 "\n\t\t: -args prints vviewparams arguments for restoring current view",
197ac94e 13927 __FILE__, VViewParams, group);
1beb58d7 13928
2e93433e 13929 theCommands.Add("v2dmode",
13930 "v2dmode [-name viewName] [-mode {-on|-off}=-on]"
13931 "\n\t\t: name - name of existing view, if not defined, the active view is changed"
13932 "\n\t\t: mode - switches On/Off rotation mode"
13933 "\n\t\t: Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:"
13934 "\n\t\t: - rotation of the view by 3rd mouse button with Ctrl active"
13935 "\n\t\t: - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right"
13936 "\n\t\t: View camera position might be changed only by commands.",
13937 __FILE__, V2DMode, group);
13938
1beb58d7 13939 theCommands.Add("vanimation", "Alias for vanim",
13940 __FILE__, VAnimation, group);
13941
13942 theCommands.Add("vanim",
13943 "List existing animations:"
13944 "\n\t\t: vanim"
13945 "\n\t\t: Animation playback:"
13946 "\n\t\t: vanim name -play|-resume [playFrom [playDuration]]"
13947 "\n\t\t: [-speed Coeff] [-freeLook] [-lockLoop]"
13948 "\n\t\t: -speed playback speed (1.0 is normal speed)"
13949 "\n\t\t: -freeLook skip camera animations"
13950 "\n\t\t: -lockLoop disable any interactions"
13951 "\n\t\t:"
13952 "\n\t\t: Animation definition:"
13953 "\n\t\t: vanim Name/sub/name [-clear] [-delete]"
13954 "\n\t\t: [start TimeSec] [duration TimeSec]"
13955 "\n\t\t:"
13956 "\n\t\t: Animation name defined in path-style (anim/name or anim.name)"
13957 "\n\t\t: specifies nested animations."
13958 "\n\t\t: There is no syntax to explicitly add new animation,"
13959 "\n\t\t: and all non-existing animations within the name will be"
13960 "\n\t\t: implicitly created on first use (including parents)."
13961 "\n\t\t:"
13962 "\n\t\t: Each animation might define the SINGLE action (see below),"
13963 "\n\t\t: like camera transition, object transformation or custom callback."
13964 "\n\t\t: Child animations can be used for defining concurrent actions."
13965 "\n\t\t:"
13966 "\n\t\t: Camera animation:"
13967 "\n\t\t: vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]"
13968 "\n\t\t: [-at1 X Y Z] [-at2 X Y Z]"
13969 "\n\t\t: [-up1 X Y Z] [-up2 X Y Z]"
13970 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
13971 "\n\t\t: -eyeX camera Eye positions pair (start and end)"
13972 "\n\t\t: -atX camera Center positions pair"
13973 "\n\t\t: -upX camera Up directions pair"
13974 "\n\t\t: -scaleX camera Scale factors pair"
13975 "\n\t\t: Object animation:"
13976 "\n\t\t: vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]"
13977 "\n\t\t: [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]"
13978 "\n\t\t: [-scale1 Scale] [-scale2 Scale]"
13979 "\n\t\t: -locX object Location points pair (translation)"
13980 "\n\t\t: -rotX object Orientations pair (quaternions)"
13981 "\n\t\t: -scaleX object Scale factors pair (quaternions)"
13982 "\n\t\t: Custom callback:"
13983 "\n\t\t: vanim name -invoke \"Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN\""
13984 "\n\t\t: %Pts overall animation presentation timestamp"
13985 "\n\t\t: %LocalPts local animation timestamp"
13986 "\n\t\t: %Normalized local animation normalized value in range 0..1"
08f8a185 13987 "\n\t\t:"
13988 "\n\t\t: Video recording:"
13989 "\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
13990 "\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
13991 "\n\t\t: [-crf Value] [-preset Preset]"
13992 "\n\t\t: -fps video framerate"
13993 "\n\t\t: -format file format, container (matroska, etc.)"
13994 "\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
13995 "\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
13996 "\n\t\t: -crf constant rate factor (specific to codec)"
13997 "\n\t\t: -preset codec parameters preset (specific to codec)"
1beb58d7 13998 __FILE__, VAnimation, group);
13999
4754e164 14000 theCommands.Add("vchangeselected",
dc3fe572 14001 "vchangeselected shape"
4754e164 14002 "- adds to shape to selection or remove one from it",
14003 __FILE__, VChangeSelected, group);
4754e164 14004 theCommands.Add ("vnbselected",
faea8b40 14005 "vnbselected"
14006 "\n\t\t: Returns number of selected objects", __FILE__, VNbSelected, group);
6b62b2da 14007 theCommands.Add ("vcamera",
30a1b24e 14008 "vcamera [PrsName] [-ortho] [-projtype]"
6b62b2da 14009 "\n\t\t: [-persp]"
14010 "\n\t\t: [-fovy [Angle]] [-distance [Distance]]"
14011 "\n\t\t: [-stereo] [-leftEye] [-rightEye]"
14012 "\n\t\t: [-iod [Distance]] [-iodType [absolute|relative]]"
14013 "\n\t\t: [-zfocus [Value]] [-zfocusType [absolute|relative]]"
30a1b24e 14014 "\n\t\t: Manages camera parameters."
14015 "\n\t\t: Displays frustum when presntation name PrsName is specified."
6b62b2da 14016 "\n\t\t: Prints current value when option called without argument."
14017 "\n\t\t: Orthographic camera:"
14018 "\n\t\t: -ortho activate orthographic projection"
14019 "\n\t\t: Perspective camera:"
14020 "\n\t\t: -persp activate perspective projection (mono)"
14021 "\n\t\t: -fovy field of view in y axis, in degrees"
14022 "\n\t\t: -distance distance of eye from camera center"
14023 "\n\t\t: Stereoscopic camera:"
14024 "\n\t\t: -stereo perspective projection (stereo)"
14025 "\n\t\t: -leftEye perspective projection (left eye)"
14026 "\n\t\t: -rightEye perspective projection (right eye)"
14027 "\n\t\t: -iod intraocular distance value"
14028 "\n\t\t: -iodType distance type, absolute or relative"
14029 "\n\t\t: -zfocus stereographic focus value"
14030 "\n\t\t: -zfocusType focus type, absolute or relative",
14031 __FILE__, VCamera, group);
b5ac8292 14032 theCommands.Add ("vautozfit", "command to enable or disable automatic z-range adjusting\n"
197ac94e 14033 "- vautozfit [on={1|0}] [scale]\n"
14034 " Prints or changes parameters of automatic z-fit mode:\n"
14035 " \"on\" - turns automatic z-fit on or off\n"
14036 " \"scale\" - specifies factor to scale computed z range.\n",
14037 __FILE__, VAutoZFit, group);
b5ac8292 14038 theCommands.Add ("vzrange", "command to manually access znear and zfar values\n"
14039 " vzrange - without parameters shows current values\n"
14040 " vzrange [znear] [zfar] - applies provided values to view",
14041 __FILE__,VZRange, group);
4754e164 14042 theCommands.Add ("vpurgedisplay",
eb4320f2 14043 "vpurgedisplay"
4754e164 14044 "- removes structures which don't belong to objects displayed in neutral point",
14045 __FILE__, VPurgeDisplay, group);
14046 theCommands.Add("vsetviewsize",
14047 "vsetviewsize size",
14048 __FILE__,VSetViewSize,group);
14049 theCommands.Add("vmoveview",
14050 "vmoveview Dx Dy Dz [Start = 1|0]",
14051 __FILE__,VMoveView,group);
14052 theCommands.Add("vtranslateview",
14053 "vtranslateview Dx Dy Dz [Start = 1|0)]",
14054 __FILE__,VTranslateView,group);
14055 theCommands.Add("vturnview",
14056 "vturnview Ax Ay Az [Start = 1|0]",
14057 __FILE__,VTurnView,group);
269294d6 14058 theCommands.Add("vtextureenv",
14059 "Enables or disables environment mapping in the 3D view, loading the texture from the given standard "
14060 "or user-defined file and optionally applying texture mapping parameters\n"
14061 " Usage:\n"
14062 " vtextureenv off - disables environment mapping\n"
14063 " vtextureenv on {std_texture|texture_file_name} [rep mod flt ss st ts tt rot] - enables environment mapping\n"
14064 " std_texture = (0..7)\n"
14065 " rep = {clamp|repeat}\n"
14066 " mod = {decal|modulate}\n"
14067 " flt = {nearest|bilinear|trilinear}\n"
14068 " ss, st - scale factors for s and t texture coordinates\n"
14069 " ts, tt - translation for s and t texture coordinates\n"
14070 " rot - texture rotation angle in degrees",
14071 __FILE__, VTextureEnv, group);
1eeef710 14072 theCommands.Add("vhlr",
14073 "vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]"
14074 "\n\t\t: Hidden Line Removal algorithm."
14075 "\n\t\t: -showHidden if set ON, hidden lines are drawn as dotted ones"
14076 "\n\t\t: -algoType type of HLR algorithm.\n",
0a768f56 14077 __FILE__,VHLR,group);
1eeef710 14078 theCommands.Add("vhlrtype",
14079 "vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]"
14080 "\n\t\t: Changes the type of HLR algorithm using for shapes:"
14081 "\n\t\t: 'algo' - exact HLR algorithm is applied"
14082 "\n\t\t: 'polyAlgo' - polygonal HLR algorithm is applied"
14083 "\n\t\t: If shapes are not given - option is applied to all shapes in the view",
0a768f56 14084 __FILE__,VHLRType,group);
3e05329c 14085 theCommands.Add("vclipplane",
14086 "vclipplane planeName [{0|1}]"
25c35042 14087 "\n\t\t: [-equation1 A B C D]"
14088 "\n\t\t: [-equation2 A B C D]"
14089 "\n\t\t: [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]"
32ca7711 14090 "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]"
3e05329c 14091 "\n\t\t: [-maxPlanes]"
14092 "\n\t\t: [-capping {0|1}]"
1b661a81 14093 "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
3e05329c 14094 "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
14095 "\n\t\t: [-texRotate Angle]"
14096 "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
14097 "\n\t\t: [-useObjShader {0|1}]"
14098 "\n\t\t: Clipping planes management:"
14099 "\n\t\t: -maxPlanes print plane limit for view"
14100 "\n\t\t: -delete delete plane with given name"
14101 "\n\t\t: {off|on|0|1} turn clipping on/off"
14102 "\n\t\t: -set|-unset set/unset plane for Object or View list;"
14103 "\n\t\t: applied to active View when list is omitted"
14104 "\n\t\t: -equation A B C D change plane equation"
14105 "\n\t\t: -clone SourcePlane NewPlane clone the plane definition."
14106 "\n\t\t: Capping options:"
14107 "\n\t\t: -capping {off|on|0|1} turn capping on/off"
14108 "\n\t\t: -color R G B set capping color"
1b661a81 14109 "\n\t\t: -transparency Value set capping transparency 0..1"
3e05329c 14110 "\n\t\t: -texName Texture set capping texture"
14111 "\n\t\t: -texScale SX SY set capping tex scale"
14112 "\n\t\t: -texOrigin TX TY set capping tex origin"
14113 "\n\t\t: -texRotate Angle set capping tex rotation"
14114 "\n\t\t: -hatch {on|off|ID} set capping hatching mask"
14115 "\n\t\t: -useObjMaterial {off|on|0|1} use material of clipped object"
14116 "\n\t\t: -useObjTexture {off|on|0|1} use texture of clipped object"
14117 "\n\t\t: -useObjShader {off|on|0|1} use shader program of object",
14118 __FILE__, VClipPlane, group);
392ac980 14119 theCommands.Add("vdefaults",
4c513386 14120 "vdefaults [-absDefl value]"
14121 "\n\t\t: [-devCoeff value]"
14122 "\n\t\t: [-angDefl value]"
14123 "\n\t\t: [-autoTriang {off/on | 0/1}]"
14124 , __FILE__, VDefaults, group);
12381341 14125 theCommands.Add("vlight",
816d03ee 14126 "tool to manage light sources, without arguments shows list of lights."
14127 "\n Main commands: "
992ed6b3 14128 "\n '-clear' to clear lights"
14129 "\n '-{def}aults' to load deafault lights"
14130 "\n '-add' <type> to add any light source"
816d03ee 14131 "\n where <type> is one of {amb}ient|directional|{spot}light|positional"
14132 "\n 'change' <lightId> to edit light source with specified lightId"
14133 "\n\n In addition to 'add' and 'change' commands you can use light parameters:"
992ed6b3 14134 "\n -layer Id"
14135 "\n -{pos}ition X Y Z"
14136 "\n -{dir}ection X Y Z (for directional light or for spotlight)"
14137 "\n -color colorName"
14138 "\n -{head}light 0|1"
14139 "\n -{sm}oothness value"
14140 "\n -{int}ensity value"
14141 "\n -{constAtten}uation value"
14142 "\n -{linearAtten}uation value"
14143 "\n -angle angleDeg"
14144 "\n -{spotexp}onent value"
14145 "\n -local|-global"
14146 "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red"
14147 "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
12381341 14148 __FILE__, VLight, group);
6b62b2da 14149 theCommands.Add("vraytrace",
14150 "vraytrace [0|1]"
189f85a3 14151 "\n\t\t: Turns on/off ray-tracing renderer."
6b62b2da 14152 "\n\t\t: 'vraytrace 0' alias for 'vrenderparams -raster'."
14153 "\n\t\t: 'vraytrace 1' alias for 'vrenderparams -rayTrace'.",
14154 __FILE__, VRenderParams, group);
bc8c79bb 14155 theCommands.Add("vrenderparams",
14156 "\n Manages rendering parameters: "
a1073ae2 14157 "\n '-raster' Disables GPU ray-tracing"
14158 "\n '-msaa 0..4' Specifies number of samples for MSAA"
2a332745 14159 "\n '-lineFeather > 0' Sets line feather factor"
a1073ae2 14160 "\n '-oit off|0.0-1.0' Enables/disables OIT and sets depth weight factor"
f88457e6 14161 "\n '-depthPrePass on|off' Enables/disables depth pre-pass"
c40eb6b9 14162 "\n '-alphatocoverage on|off' Enables/disables alpha to coverage (needs MSAA)"
a1073ae2 14163 "\n '-rendScale value Rendering resolution scale factor"
14164 "\n '-rayTrace' Enables GPU ray-tracing"
14165 "\n '-rayDepth 0..10' Defines maximum ray-tracing depth"
14166 "\n '-shadows on|off' Enables/disables shadows rendering"
14167 "\n '-reflections on|off' Enables/disables specular reflections"
14168 "\n '-fsaa on|off' Enables/disables adaptive anti-aliasing"
14169 "\n '-gleam on|off' Enables/disables transparency shadow effects"
14170 "\n '-gi on|off' Enables/disables global illumination effects"
14171 "\n '-brng on|off' Enables/disables blocked RNG (fast coherent PT)"
14172 "\n '-env on|off' Enables/disables environment map background"
14173 "\n '-twoside on|off' Enables/disables two-sided BSDF models (PT mode)"
14174 "\n '-iss on|off' Enables/disables adaptive screen sampling (PT mode)"
14175 "\n '-issd on|off' Shows screen sampling distribution in ISS mode"
14176 "\n '-maxrad > 0.0' Value used for clamping radiance estimation (PT mode)"
66d1cdc6 14177 "\n '-tileSize 1..4096' Specifies size of screen tiles in ISS mode (32 by default)"
14178 "\n '-nbtiles 64..1024' Specifies number of screen tiles per Redraw in ISS mode (256 by default)"
a1073ae2 14179 "\n '-rebuildGlsl on|off' Rebuild Ray-Tracing GLSL programs (for debugging)"
14180 "\n '-shadingModel model' Controls shading model from enumeration"
14181 "\n color, flat, gouraud, phong"
14182 "\n '-resolution value' Sets a new pixels density (PPI), defines scaling factor for parameters like text size"
b27ab03d 14183 "\n '-aperture >= 0.0' Aperture size of perspective camera for depth-of-field effect (0 disables DOF)"
14184 "\n '-focal >= 0.0' Focal distance of perspective camera for depth-of-field effect"
eb85ed36 14185 "\n '-exposure value' Exposure value for tone mapping (0.0 value disables the effect)"
14186 "\n '-whitepoint value' White point value for filmic tone mapping"
14187 "\n '-tonemapping mode' Tone mapping mode (disabled, filmic)"
5e30547b 14188 "\n '-perfCounters none|fps|cpu|layers|structures|groups|arrays|triagles|points"
14189 "\n ' |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate'"
15669413 14190 "\n Show/hide performance counters (flags can be combined)"
14191 "\n '-perfUpdateInterval nbSeconds' Performance counters update interval"
5e30547b 14192 "\n '-perfChart nbFrames' Show frame timers chart limited by specified number of frames"
14193 "\n '-perfChartMax seconds' Maximum time in seconds with the chart"
0e3025bc 14194 "\n '-frustumCulling on|off|noupdate' Enable/disable objects frustum clipping or"
14195 "\n set state to check structures culled previously."
8625ef7e 14196 "\n Unlike vcaps, these parameters dramatically change visual properties."
14197 "\n Command is intended to control presentation quality depending on"
14198 "\n hardware capabilities and performance.",
bc8c79bb 14199 __FILE__, VRenderParams, group);
79b544e6 14200 theCommands.Add("vstatprofiler",
14201 "\n vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups"
14202 "\n |allArrays|fillArrays|lineArrays|pointArrays|textArrays"
14203 "\n |triagles|points|geomMem|textureMem|frameMem"
14204 "\n |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage"
14205 "\n |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]"
14206 "\n [-noredraw]"
14207 "\n\t\t: Prints rendering statistics."
14208 "\n\t\t: If there are some parameters - print corresponding statistic counters values,"
14209 "\n\t\t: else - print all performance counters set previously."
14210 "\n\t\t: '-noredraw' Flag to avoid additional redraw call and use already collected values.\n",
14211 __FILE__, VStatProfiler, group);
49e1a5c7 14212 theCommands.Add ("vplace",
14213 "vplace dx dy"
14214 "\n\t\t: Places the point (in pixels) at the center of the window",
14215 __FILE__, VPlace, group);
0717ddc1 14216 theCommands.Add("vxrotate",
14217 "vxrotate",
14218 __FILE__,VXRotate,group);
14219
625e1958 14220 theCommands.Add("vmanipulator",
14221 "\n vmanipulator Name [-attach AISObject | -detach | ...]"
14222 "\n tool to create and manage AIS manipulators."
14223 "\n Options: "
14224 "\n '-attach AISObject' attach manipulator to AISObject"
14225 "\n '-adjustPosition {0|1}' adjust position when attaching"
14226 "\n '-adjustSize {0|1}' adjust size when attaching"
14227 "\n '-enableModes {0|1}' enable modes when attaching"
14228 "\n '-detach' detach manipulator"
14229 "\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
14230 "\n '-transform mouse_x mouse_y' - invoke transformation"
14231 "\n '-stopTransform [abort]' - invoke stop of transformation"
14232 "\n '-move x y z' - move attached object"
14233 "\n '-rotate x y z dx dy dz angle' - rotate attached object"
14234 "\n '-scale factor' - scale attached object"
14235 "\n '-autoActivate {0|1}' - set activation on detection"
14236 "\n '-followTranslation {0|1}' - set following translation transform"
14237 "\n '-followRotation {0|1}' - set following rotation transform"
f522ce50 14238 "\n '-followDragging {0|1}' - set following dragging transform"
625e1958 14239 "\n '-gap value' - set gap between sub-parts"
14240 "\n '-part axis mode {0|1}' - set visual part"
84b904bc 14241 "\n '-parts axis mode {0|1}' - set visual part"
625e1958 14242 "\n '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator"
14243 "\n '-size value' - set size of manipulator"
14244 "\n '-zoomable {0|1}' - set zoom persistence",
14245 __FILE__, VManipulator, group);
14246
8e5fb5ea 14247 theCommands.Add("vselprops",
f838dac4 14248 "\n vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]"
8e5fb5ea 14249 "\n Customizes selection and dynamic highlight parameters for the whole interactive context:"
14250 "\n -autoActivate {0|1} : disables|enables default computation and activation of global selection mode"
be3d8cbc 14251 "\n -autoHighlight {0|1} : disables|enables automatic highlighting in 3D Viewer"
14252 "\n -highlightSelected {0|1}: disables|enables highlighting of detected object in selected state"
14c4193d 14253 "\n -pickStrategy {first|topmost} : defines picking strategy"
14254 "\n 'first' to pick first acceptable (default)"
14255 "\n 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)"
8e5fb5ea 14256 "\n -pixTol value : sets up pixel tolerance"
f838dac4 14257 "\n -dispMode dispMode : sets display mode for highlighting"
14258 "\n -layer ZLayer : sets ZLayer for highlighting"
14259 "\n -color {name|r g b} : sets highlight color"
14260 "\n -transp value : sets transparency coefficient for highlight"
14261 "\n -material material : sets highlight material"
8e5fb5ea 14262 "\n -print : prints current state of all mentioned parameters",
14263 __FILE__, VSelectionProperties, group);
be3d8cbc 14264 theCommands.Add ("vhighlightselected",
14265 "vhighlightselected [0|1]: alias for vselprops -highlightSelected.\n",
14266 __FILE__, VSelectionProperties, group);
8e5fb5ea 14267
decdee7d 14268 theCommands.Add ("vseldump",
14269 "vseldump file -type {depth|unnormDepth|object|owner|selMode|entity}=depth -pickedIndex Index=1"
14270 "\n\t\t: Generate an image based on detection results:"
14271 "\n\t\t: depth normalized depth values"
14272 "\n\t\t: unnormDepth unnormalized depth values"
14273 "\n\t\t: object color of detected object"
14274 "\n\t\t: owner color of detected owner"
14275 "\n\t\t: selMode color of selection mode"
14276 "\n\t\t: entity color of etected entity",
14277 __FILE__, VDumpSelectionImage, group);
14278
189f85a3 14279#if defined(_WIN32)
14280 theCommands.Add("vprogressive",
14281 "vprogressive",
14282 __FILE__, VProgressiveMode, group);
14283#endif
7fd59977 14284}
293211ae 14285