1 // Created on: 1998-09-01
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
21 #include <ViewerTest.hxx>
23 #include <AIS_AnimationCamera.hxx>
24 #include <AIS_AnimationObject.hxx>
25 #include <AIS_Axis.hxx>
26 #include <AIS_CameraFrustum.hxx>
27 #include <AIS_ColorScale.hxx>
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_LightSource.hxx>
30 #include <AIS_ListOfInteractive.hxx>
31 #include <AIS_ListIteratorOfListOfInteractive.hxx>
32 #include <AIS_Manipulator.hxx>
33 #include <AIS_ViewCube.hxx>
34 #include <AIS_Shape.hxx>
35 #include <AIS_Point.hxx>
36 #include <Aspect_DisplayConnection.hxx>
37 #include <Aspect_Grid.hxx>
38 #include <Aspect_TypeOfLine.hxx>
40 #include <Draw_Appli.hxx>
41 #include <Draw_Interpretor.hxx>
42 #include <Draw_ProgressIndicator.hxx>
46 #include <Geom_Axis2Placement.hxx>
47 #include <Geom_CartesianPoint.hxx>
48 #include <Graphic3d_ArrayOfPolylines.hxx>
49 #include <Graphic3d_AspectFillArea3d.hxx>
50 #include <Graphic3d_AspectMarker3d.hxx>
51 #include <Graphic3d_ClipPlane.hxx>
52 #include <Graphic3d_CubeMapPacked.hxx>
53 #include <Graphic3d_CubeMapSeparate.hxx>
54 #include <Graphic3d_GraduatedTrihedron.hxx>
55 #include <Graphic3d_GraphicDriver.hxx>
56 #include <Graphic3d_GraphicDriverFactory.hxx>
57 #include <Graphic3d_NameOfTextureEnv.hxx>
58 #include <Graphic3d_Texture2Dmanual.hxx>
59 #include <Graphic3d_TextureEnv.hxx>
60 #include <Graphic3d_TextureParams.hxx>
61 #include <Graphic3d_TypeOfTextureFilter.hxx>
62 #include <Image_AlienPixMap.hxx>
63 #include <Image_Diff.hxx>
64 #include <Image_VideoRecorder.hxx>
65 #include <Message.hxx>
66 #include <Message_ProgressScope.hxx>
67 #include <Message_ProgressRange.hxx>
68 #include <NCollection_DataMap.hxx>
69 #include <NCollection_List.hxx>
70 #include <NCollection_LocalArray.hxx>
71 #include <NCollection_Vector.hxx>
73 #include <OSD_Parallel.hxx>
74 #include <OSD_Timer.hxx>
75 #include <Prs3d_ShadingAspect.hxx>
76 #include <Prs3d_DatumAspect.hxx>
77 #include <Prs3d_Drawer.hxx>
78 #include <Prs3d_LineAspect.hxx>
79 #include <Prs3d_Text.hxx>
80 #include <Select3D_SensitivePrimitiveArray.hxx>
81 #include <TColStd_HSequenceOfAsciiString.hxx>
82 #include <TColStd_SequenceOfInteger.hxx>
83 #include <TColStd_HSequenceOfReal.hxx>
84 #include <TColgp_Array1OfPnt2d.hxx>
85 #include <TColStd_MapOfAsciiString.hxx>
86 #include <ViewerTest_AutoUpdater.hxx>
87 #include <ViewerTest_ContinuousRedrawer.hxx>
88 #include <ViewerTest_EventManager.hxx>
89 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
90 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
91 #include <ViewerTest_CmdParser.hxx>
92 #include <ViewerTest_V3dView.hxx>
93 #include <V3d_AmbientLight.hxx>
94 #include <V3d_DirectionalLight.hxx>
95 #include <V3d_PositionalLight.hxx>
96 #include <V3d_SpotLight.hxx>
97 #include <V3d_Trihedron.hxx>
98 #include <V3d_Viewer.hxx>
99 #include <UnitsAPI.hxx>
106 #include <WNT_WClass.hxx>
107 #include <WNT_Window.hxx>
108 #include <WNT_HIDSpaceMouse.hxx>
109 #elif defined(HAVE_XLIB)
110 #include <Xw_Window.hxx>
111 #include <X11/Xlib.h>
112 #include <X11/Xutil.h>
113 #elif defined(__APPLE__)
114 #include <Cocoa_Window.hxx>
115 #elif defined(__EMSCRIPTEN__)
116 #include <Wasm_Window.hxx>
117 #include <emscripten/emscripten.h>
119 #include <Aspect_NeutralWindow.hxx>
122 //==============================================================================
123 // VIEWER GLOBAL VARIABLES
124 //==============================================================================
126 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
127 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
129 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
130 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
133 typedef WNT_Window ViewerTest_Window;
134 #elif defined(HAVE_XLIB)
135 typedef Xw_Window ViewerTest_Window;
136 static void VProcessEvents(ClientData,int);
137 #elif defined(__APPLE__)
138 typedef Cocoa_Window ViewerTest_Window;
139 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
140 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
141 #elif defined(__EMSCRIPTEN__)
142 typedef Wasm_Window ViewerTest_Window;
144 typedef Aspect_NeutralWindow ViewerTest_Window;
147 #if defined(__EMSCRIPTEN__)
148 //! Return DOM id of default WebGL canvas from Module.canvas.
149 EM_JS(char*, occJSModuleCanvasId, (), {
150 const aCanvasId = Module.canvas.id;
151 const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
152 const aStrPtr = Module._malloc (aNbBytes);
153 stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
157 //! Return DOM id of default WebGL canvas from Module.canvas.
158 static TCollection_AsciiString getModuleCanvasId()
160 char* aRawId = occJSModuleCanvasId();
161 TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
167 static Handle(ViewerTest_Window)& VT_GetWindow()
169 static Handle(ViewerTest_Window) aWindow;
173 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
175 static Handle(Aspect_DisplayConnection) aDisplayConnection;
176 return aDisplayConnection;
179 static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
181 GetDisplayConnection() = theDisplayConnection;
184 NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
185 static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
186 static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
190 Quantity_Color FlatColor;
191 Quantity_Color GradientColor1;
192 Quantity_Color GradientColor2;
193 Aspect_GradientFillMethod FillMethod;
195 //! Sets the gradient filling for a background in a default viewer.
196 void SetDefaultGradient()
198 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator aCtxIter (ViewerTest_myContexts);
199 aCtxIter.More(); aCtxIter.Next())
201 const Handle (V3d_Viewer)& aViewer = aCtxIter.Value()->CurrentViewer();
202 aViewer->SetDefaultBgGradientColors (GradientColor1, GradientColor2, FillMethod);
206 //! Sets the color used for filling a background in a default viewer.
207 void SetDefaultColor()
209 for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator aCtxIter (ViewerTest_myContexts);
210 aCtxIter.More(); aCtxIter.Next())
212 const Handle (V3d_Viewer)& aViewer = aCtxIter.Value()->CurrentViewer();
213 aViewer->SetDefaultBackgroundColor (FlatColor);
217 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GradientFillMethod_None };
219 //==============================================================================
220 // EVENT GLOBAL VARIABLES
221 //==============================================================================
224 static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
227 //==============================================================================
230 //==============================================================================
232 const Handle(WNT_WClass)& ViewerTest::WClass()
234 static Handle(WNT_WClass) theWClass;
236 if (theWClass.IsNull())
238 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
239 CS_VREDRAW | CS_HREDRAW, 0, 0,
240 ::LoadCursor (NULL, IDC_ARROW));
246 //==============================================================================
247 //function : CreateName
248 //purpose : Create numerical name for new object in theMap
249 //==============================================================================
250 template <typename ObjectType>
251 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
252 const TCollection_AsciiString& theDefaultString)
254 if (theObjectMap.IsEmpty())
255 return theDefaultString + TCollection_AsciiString(1);
257 Standard_Integer aNextKey = 1;
258 Standard_Boolean isFound = Standard_False;
261 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
262 // Look for objects with default names
263 if (theObjectMap.IsBound1(aStringKey))
268 isFound = Standard_True;
271 return theDefaultString + TCollection_AsciiString(aNextKey);
274 //==============================================================================
275 //structure : ViewerTest_Names
276 //purpose : Allow to operate with full view name: driverName/viewerName/viewName
277 //==============================================================================
278 struct ViewerTest_Names
281 TCollection_AsciiString myDriverName;
282 TCollection_AsciiString myViewerName;
283 TCollection_AsciiString myViewName;
287 const TCollection_AsciiString& GetDriverName () const
291 void SetDriverName (const TCollection_AsciiString& theDriverName)
293 myDriverName = theDriverName;
295 const TCollection_AsciiString& GetViewerName () const
299 void SetViewerName (const TCollection_AsciiString& theViewerName)
301 myViewerName = theViewerName;
303 const TCollection_AsciiString& GetViewName () const
307 void SetViewName (const TCollection_AsciiString& theViewName)
309 myViewName = theViewName;
312 //===========================================================================
313 //function : Constructor for ViewerTest_Names
314 //purpose : Get view, viewer, driver names from custom string
315 //===========================================================================
317 ViewerTest_Names (const TCollection_AsciiString& theInputString)
319 TCollection_AsciiString aName(theInputString);
320 if (theInputString.IsEmpty())
322 // Get current configuration
323 if (ViewerTest_myDrivers.IsEmpty())
324 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
325 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
327 myDriverName = ViewerTest_myDrivers.Find2
328 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
330 if(ViewerTest_myContexts.IsEmpty())
332 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
333 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
337 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
340 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
344 // There is at least view name
345 Standard_Integer aParserNumber = 0;
346 for (Standard_Integer i = 0; i < 3; ++i)
348 Standard_Integer aParserPos = aName.SearchFromEnd("/");
352 aName.Split(aParserPos-1);
357 if (aParserNumber == 0)
360 if (!ViewerTest::GetAISContext().IsNull())
362 myDriverName = ViewerTest_myDrivers.Find2
363 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
364 myViewerName = ViewerTest_myContexts.Find2
365 (ViewerTest::GetAISContext());
369 // There is no opened contexts here, need to create names for viewer and driver
370 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
371 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
373 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
374 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
376 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
378 else if (aParserNumber == 1)
380 // Here is viewerName/viewName
381 if (!ViewerTest::GetAISContext().IsNull())
382 myDriverName = ViewerTest_myDrivers.Find2
383 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
386 // There is no opened contexts here, need to create name for driver
387 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
388 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
390 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
392 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
396 //Here is driverName/viewerName/viewName
397 myDriverName = TCollection_AsciiString(aName);
399 TCollection_AsciiString aViewerName(theInputString);
400 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
401 myViewerName = TCollection_AsciiString(aViewerName);
403 myViewName = TCollection_AsciiString(theInputString);
409 //==============================================================================
410 //function : FindContextByView
411 //purpose : Find AIS_InteractiveContext by View
412 //==============================================================================
414 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
416 Handle(AIS_InteractiveContext) anAISContext;
418 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
419 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
421 if (anIter.Value()->CurrentViewer() == theView->Viewer())
422 return anIter.Key2();
427 //==============================================================================
428 //function : IsWindowOverlapped
429 //purpose : Check if theWindow overlapp another view
430 //==============================================================================
432 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
433 const Standard_Integer thePxTop,
434 const Standard_Integer thePxRight,
435 const Standard_Integer thePxBottom,
436 TCollection_AsciiString& theViewId)
438 for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
439 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
441 Standard_Integer aTop = 0,
445 anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
446 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
447 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
448 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
449 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
451 theViewId = anIter.Key1();
452 return Standard_True;
455 return Standard_False;
458 // Workaround: to create and delete non-orthographic views outside ViewerTest
459 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
461 ViewerTest_myViews.UnBind1 (theName);
464 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
465 const Handle(V3d_View)& theView)
467 ViewerTest_myViews.Bind (theName, theView);
470 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
472 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
475 //==============================================================================
476 //function : ViewerInit
477 //purpose : Create the window viewer and initialize all the global variable
478 //==============================================================================
480 TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft,
481 const Standard_Integer thePxTop,
482 const Standard_Integer thePxWidth,
483 const Standard_Integer thePxHeight,
484 const TCollection_AsciiString& theViewName,
485 const TCollection_AsciiString& theDisplayName,
486 const Handle(V3d_View)& theViewToClone,
487 const Standard_Boolean theIsVirtual)
489 // Default position and dimension of the viewer window.
490 // Note that left top corner is set to be sufficiently small to have
491 // window fit in the small screens (actual for remote desktops, see #23003).
492 // The position corresponds to the window's client area, thus some
493 // gap is added for window frame to be visible.
494 Standard_Integer aPxLeft = 20, aPxTop = 40;
495 Standard_Integer aPxWidth = 409, aPxHeight = 409;
496 Standard_Boolean isDefViewSize = Standard_True;
497 Standard_Boolean toCreateViewer = Standard_False;
498 const Standard_Boolean isVirtual = Draw_VirtualWindows || theIsVirtual;
499 if (!theViewToClone.IsNull())
501 theViewToClone->Window()->Size (aPxWidth, aPxHeight);
502 isDefViewSize = Standard_False;
503 #if !defined(__EMSCRIPTEN__)
504 (void )isDefViewSize;
508 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
509 if (aFactory.IsNull())
511 Draw::GetInterpretor().Eval ("pload OPENGL");
512 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
513 if (aFactory.IsNull())
515 Draw::GetInterpretor().Eval ("pload GLES");
516 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
517 if (aFactory.IsNull())
519 throw Standard_ProgramError("Error: no graphic driver factory found");
524 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
525 ViewerTest_Names aViewNames(theViewName);
526 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
528 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
541 isDefViewSize = Standard_False;
542 aPxWidth = thePxWidth;
544 if (thePxHeight != 0)
546 isDefViewSize = Standard_False;
547 aPxHeight = thePxHeight;
550 // Get graphic driver (create it or get from another view)
551 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
554 // Get connection string
555 #if defined(HAVE_XLIB)
556 if (!theDisplayName.IsEmpty())
558 SetDisplayConnection (new Aspect_DisplayConnection (theDisplayName));
562 Aspect_XDisplay* aDispX = NULL;
563 // create dedicated display connection instead of reusing Tk connection
564 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
565 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
566 Tcl_Interp* aTclInterp = aCommands.Interp();
567 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
568 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
569 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
572 (void)theDisplayName; // avoid warning on unused argument
573 SetDisplayConnection (new Aspect_DisplayConnection ());
576 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
579 // don't waste the time waiting for VSync when window is not displayed on the screen
580 aGraphicDriver->SetVerticalSync (false);
583 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
584 toCreateViewer = Standard_True;
588 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
591 //Dispose the window if input parameters are default
592 if (!ViewerTest_myViews.IsEmpty() && thePxLeft == 0 && thePxTop == 0)
594 Standard_Integer aTop = 0,
601 // Get screen resolution
604 GetClientRect(GetDesktopWindow(), &aWindowSize);
605 aScreenHeight = aWindowSize.bottom;
606 aScreenWidth = aWindowSize.right;
607 #elif defined(HAVE_XLIB)
608 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
609 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
610 aScreenWidth = WidthOfScreen(aScreen);
611 aScreenHeight = HeightOfScreen(aScreen);
612 #elif defined(__APPLE__)
613 GetCocoaScreenResolution (aScreenWidth, aScreenHeight);
618 TCollection_AsciiString anOverlappedViewId("");
620 while (IsWindowOverlapped (aPxLeft, aPxTop, aPxLeft + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId))
622 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
624 if (IsWindowOverlapped (aRight + 20, aPxTop, aRight + 20 + aPxWidth, aPxTop + aPxHeight, anOverlappedViewId)
625 && aRight + 2*aPxWidth + 40 > aScreenWidth)
627 if (aBottom + aPxHeight + 40 > aScreenHeight)
634 aPxTop = aBottom + 40;
637 aPxLeft = aRight + 20;
642 TCollection_AsciiString aTitle("3D View - ");
643 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
645 // Change name of current active window
646 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
648 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
652 Handle(V3d_Viewer) a3DViewer;
653 // If it's the single view, we first look for empty context
654 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
656 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
657 anIter(ViewerTest_myContexts);
659 ViewerTest::SetAISContext (anIter.Value());
660 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
662 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
664 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
665 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
667 else if (a3DViewer.IsNull())
669 toCreateViewer = Standard_True;
670 a3DViewer = new V3d_Viewer(aGraphicDriver);
671 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
672 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
673 ViewerTest_DefaultBackground.GradientColor2,
674 ViewerTest_DefaultBackground.FillMethod);
678 if (ViewerTest::GetAISContext().IsNull() ||
679 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
681 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
682 ViewerTest::SetAISContext (aContext);
683 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
687 ViewerTest::ResetEventManager();
692 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
693 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
697 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
698 #elif defined(HAVE_XLIB)
699 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
702 aPxWidth, aPxHeight);
703 #elif defined(__APPLE__)
704 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
706 aPxWidth, aPxHeight);
707 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
708 #elif defined(__EMSCRIPTEN__)
709 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
710 // the code should be revised for handling multiple canvas elements (which is technically also possible)
711 TCollection_AsciiString aCanvasId = getModuleCanvasId();
712 if (!aCanvasId.IsEmpty())
714 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
717 VT_GetWindow() = new Wasm_Window (aCanvasId);
718 Graphic3d_Vec2i aRealSize;
719 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
720 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
722 // Wasm_Window wraps an existing HTML element without creating a new one.
723 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
724 // but resize canvas if vinit has been called with explicitly specified dimensions.
725 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxWidth, aPxHeight));
729 VT_GetWindow() = new Aspect_NeutralWindow();
730 VT_GetWindow()->SetSize (aPxWidth, aPxHeight);
732 VT_GetWindow()->SetVirtual (isVirtual);
735 Handle(V3d_View) aView;
736 if (!theViewToClone.IsNull())
738 aView = new ViewerTest_V3dView (a3DViewer, theViewToClone);
742 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
745 aView->SetWindow (VT_GetWindow());
746 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
748 ViewerTest::CurrentView(aView);
749 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
751 // Setup for X11 or NT
752 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
753 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
755 // Set parameters for V3d_View and V3d_Viewer
756 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
757 aV3dView->SetComputedMode(Standard_False);
759 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
762 a3DViewer->SetDefaultLights();
763 a3DViewer->SetLightOn();
766 #if defined(HAVE_XLIB)
769 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
770 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
774 VT_GetWindow()->Map();
776 // Set the handle of created view in the event manager
777 ViewerTest::ResetEventManager();
779 ViewerTest::CurrentView()->Redraw();
784 return aViewNames.GetViewName();
787 //==============================================================================
788 //function : RedrawAllViews
789 //purpose : Redraw all created views
790 //==============================================================================
791 void ViewerTest::RedrawAllViews()
793 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
794 for (; aViewIt.More(); aViewIt.Next())
796 const Handle(V3d_View)& aView = aViewIt.Key2();
801 //==============================================================================
804 //==============================================================================
805 static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
809 theDi << "Registered: ";
810 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
811 aFactoryIter.More(); aFactoryIter.Next())
813 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
814 theDi << aFactory->Name() << " ";
818 theDi << "Default: ";
819 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
821 theDi << aFactory->Name();
830 TCollection_AsciiString aNewActive;
832 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
834 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
835 anArgCase.LowerCase();
836 if (anArgCase == "-list")
838 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
839 aFactoryIter.More(); aFactoryIter.Next())
841 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
842 theDi << aFactory->Name() << " ";
845 else if ((anArgCase == "-default"
846 || anArgCase == "-load")
847 && aNewActive.IsEmpty())
849 toLoad = (anArgCase == "-load");
850 if (anArgIter + 1 < theArgsNb)
852 aNewActive = theArgVec[++anArgIter];
856 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
861 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
863 theDi << aFactory->Name();
871 else if (aNewActive.IsEmpty())
873 aNewActive = theArgVec[anArgIter];
877 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
882 if (!aNewActive.IsEmpty())
884 const TCollection_AsciiString aNameCopy = aNewActive;
885 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
886 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
887 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
889 aNewActive = "tkopengl";
891 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
892 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
893 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
895 aNewActive = "tkopengles";
897 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
898 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
899 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
901 aNewActive = "tkd3dhost";
906 if (aNewActive == "tkopengl")
908 Draw::GetInterpretor().Eval ("pload OPENGL");
910 else if (aNewActive == "tkopengles")
912 Draw::GetInterpretor().Eval ("pload GLES");
914 else if (aNewActive == "tkd3dhost")
916 Draw::GetInterpretor().Eval ("pload D3DHOST");
920 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
925 bool isFound = false;
926 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
927 aFactoryIter.More(); aFactoryIter.Next())
929 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
930 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
932 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
940 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
948 //==============================================================================
950 //purpose : Create the window viewer and initialize all the global variable
951 // Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
952 //==============================================================================
953 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
955 TCollection_AsciiString aViewName, aDisplayName;
956 Standard_Integer aPxLeft = 0, aPxTop = 0, aPxWidth = 0, aPxHeight = 0;
957 Standard_Boolean isVirtual = false;
958 Handle(V3d_View) aCopyFrom;
959 TCollection_AsciiString aName, aValue;
961 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
963 const TCollection_AsciiString anArg = theArgVec[anArgIt];
964 TCollection_AsciiString anArgCase = anArg;
965 anArgCase.LowerCase();
966 if (anArgIt + 1 < theArgsNb
967 && anArgCase == "-name")
969 aViewName = theArgVec[++anArgIt];
971 else if (anArgIt + 1 < theArgsNb
972 && (anArgCase == "-left"
973 || anArgCase == "-l"))
975 aPxLeft = Draw::Atoi (theArgVec[++anArgIt]);
977 else if (anArgIt + 1 < theArgsNb
978 && (anArgCase == "-top"
979 || anArgCase == "-t"))
981 aPxTop = Draw::Atoi (theArgVec[++anArgIt]);
983 else if (anArgIt + 1 < theArgsNb
984 && (anArgCase == "-width"
985 || anArgCase == "-w"))
987 aPxWidth = Draw::Atoi (theArgVec[++anArgIt]);
989 else if (anArgIt + 1 < theArgsNb
990 && (anArgCase == "-height"
991 || anArgCase == "-h"))
993 aPxHeight = Draw::Atoi (theArgVec[++anArgIt]);
995 else if (anArgCase == "-virtual"
996 || anArgCase == "-offscreen")
999 if (anArgIt + 1 < theArgsNb
1000 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isVirtual))
1005 else if (anArgCase == "-exitonclose")
1007 ViewerTest_EventManager::ToExitOnCloseView() = true;
1008 if (anArgIt + 1 < theArgsNb
1009 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToExitOnCloseView()))
1014 else if (anArgCase == "-closeonescape"
1015 || anArgCase == "-closeonesc")
1017 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
1018 if (anArgIt + 1 < theArgsNb
1019 && Draw::ParseOnOff (theArgVec[anArgIt + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
1024 else if (anArgCase == "-2d_mode"
1025 || anArgCase == "-2dmode"
1026 || anArgCase == "-2d")
1028 bool toEnable = true;
1029 if (anArgIt + 1 < theArgsNb
1030 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toEnable))
1034 is2dMode = toEnable ? 1 : 0;
1036 else if (anArgIt + 1 < theArgsNb
1037 && (anArgCase == "-disp"
1038 || anArgCase == "-display"))
1040 aDisplayName = theArgVec[++anArgIt];
1042 else if (!ViewerTest::CurrentView().IsNull()
1043 && aCopyFrom.IsNull()
1044 && (anArgCase == "-copy"
1045 || anArgCase == "-clone"
1046 || anArgCase == "-cloneactive"
1047 || anArgCase == "-cloneactiveview"))
1049 aCopyFrom = ViewerTest::CurrentView();
1052 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
1055 if (aName == "name")
1059 else if (aName == "l"
1062 aPxLeft = aValue.IntegerValue();
1064 else if (aName == "t"
1067 aPxTop = aValue.IntegerValue();
1069 else if (aName == "disp"
1070 || aName == "display")
1072 aDisplayName = aValue;
1074 else if (aName == "w"
1075 || aName == "width")
1077 aPxWidth = aValue.IntegerValue();
1079 else if (aName == "h"
1080 || aName == "height")
1082 aPxHeight = aValue.IntegerValue();
1086 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1090 else if (aViewName.IsEmpty())
1096 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1101 #if !defined(HAVE_XLIB)
1102 if (!aDisplayName.IsEmpty())
1104 aDisplayName.Clear();
1105 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
1109 ViewerTest_Names aViewNames (aViewName);
1110 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1112 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
1113 theDi.Eval (aCommand.ToCString());
1116 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1121 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aPxWidth, aPxHeight,
1122 aViewName, aDisplayName, aCopyFrom, isVirtual);
1125 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1131 //! Parse HLR algo type.
1132 static Standard_Boolean parseHlrAlgoType (const char* theName,
1133 Prs3d_TypeOfHLR& theType)
1135 TCollection_AsciiString aName (theName);
1137 if (aName == "polyalgo")
1139 theType = Prs3d_TOH_PolyAlgo;
1141 else if (aName == "algo")
1143 theType = Prs3d_TOH_Algo;
1147 return Standard_False;
1149 return Standard_True;
1152 //==============================================================================
1154 //purpose : hidden lines removal algorithm
1155 //==============================================================================
1157 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1159 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1160 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1163 Message::SendFail ("Error: no active viewer");
1167 Standard_Boolean hasHlrOnArg = Standard_False;
1168 Standard_Boolean hasShowHiddenArg = Standard_False;
1169 Standard_Boolean isHLROn = Standard_False;
1170 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
1171 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1172 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1173 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1175 TCollection_AsciiString anArg (argv[anArgIter]);
1177 if (anUpdateTool.parseRedrawMode (anArg))
1181 else if (anArg == "-showhidden"
1182 && anArgIter + 1 < argc
1183 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1186 hasShowHiddenArg = Standard_True;
1189 else if ((anArg == "-type"
1191 || anArg == "-algotype")
1192 && anArgIter + 1 < argc
1193 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1198 else if (!hasHlrOnArg
1199 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1201 hasHlrOnArg = Standard_True;
1205 else if (!hasShowHiddenArg
1206 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1208 hasShowHiddenArg = Standard_True;
1213 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1219 di << "HLR: " << aView->ComputedMode() << "\n";
1220 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
1222 switch (aCtx->DefaultDrawer()->TypeOfHLR())
1224 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
1225 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
1226 case Prs3d_TOH_Algo: di << "Algo\n"; break;
1228 anUpdateTool.Invalidate();
1232 Standard_Boolean toRecompute = Standard_False;
1233 if (aTypeOfHLR != Prs3d_TOH_NotSet
1234 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
1236 toRecompute = Standard_True;
1237 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1239 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
1241 toRecompute = Standard_True;
1244 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
1248 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
1253 if (aView->ComputedMode() && isHLROn && toRecompute)
1255 AIS_ListOfInteractive aListOfShapes;
1256 aCtx->DisplayedObjects (aListOfShapes);
1257 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
1259 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
1261 aCtx->Redisplay (aShape, Standard_False);
1266 aView->SetComputedMode (isHLROn);
1270 //==============================================================================
1271 //function : VHLRType
1272 //purpose : change type of using HLR algorithm
1273 //==============================================================================
1275 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1277 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1278 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1281 Message::SendFail ("Error: no active viewer");
1285 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1286 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1287 AIS_ListOfInteractive aListOfShapes;
1288 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1290 TCollection_AsciiString anArg (argv[anArgIter]);
1292 if (anUpdateTool.parseRedrawMode (anArg))
1296 else if ((anArg == "-type"
1298 || anArg == "-algotype")
1299 && anArgIter + 1 < argc
1300 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1306 else if (aTypeOfHLR == Prs3d_TOH_NotSet
1307 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
1313 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1314 TCollection_AsciiString aName (argv[anArgIter]);
1315 if (!aMap.IsBound2 (aName))
1317 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1321 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
1322 if (aShape.IsNull())
1324 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1327 aListOfShapes.Append (aShape);
1331 if (aTypeOfHLR == Prs3d_TOH_NotSet)
1333 Message::SendFail ("Syntax error: wrong number of arguments");
1337 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
1340 aCtx->DisplayedObjects (aListOfShapes);
1341 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1344 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
1346 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1347 if (aShape.IsNull())
1352 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
1353 && aView->ComputedMode();
1355 || aShape->TypeOfHLR() != aTypeOfHLR)
1357 aShape->SetTypeOfHLR (aTypeOfHLR);
1361 aCtx->Redisplay (aShape, Standard_False);
1367 //==============================================================================
1368 //function : FindViewIdByWindowHandle
1369 //purpose : Find theView Id in the map of views by window handle
1370 //==============================================================================
1371 #if defined(_WIN32) || defined(HAVE_XLIB)
1372 static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
1374 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
1375 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1377 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
1378 if (aWindowHandle == theWindowHandle)
1379 return anIter.Key1();
1381 return TCollection_AsciiString("");
1385 //! Make the view active
1386 void ActivateView (const TCollection_AsciiString& theViewName,
1387 Standard_Boolean theToUpdate = Standard_True)
1389 const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1395 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
1396 if (!anAISContext.IsNull())
1398 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
1400 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
1403 ViewerTest::CurrentView (aView);
1404 ViewerTest::SetAISContext (anAISContext);
1405 aView->Window()->SetTitle (TCollection_AsciiString("3D View - ") + theViewName + "(*)");
1406 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(ViewerTest::CurrentView()->Window());
1407 SetDisplayConnection(ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
1410 ViewerTest::CurrentView()->Redraw();
1415 //==============================================================================
1416 //function : RemoveView
1418 //==============================================================================
1419 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
1420 const Standard_Boolean theToRemoveContext)
1422 if (!ViewerTest_myViews.IsBound2 (theView))
1427 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
1428 RemoveView (aViewName, theToRemoveContext);
1431 //==============================================================================
1432 //function : RemoveView
1433 //purpose : Close and remove view from display, clear maps if necessary
1434 //==============================================================================
1435 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
1437 if (!ViewerTest_myViews.IsBound1(theViewName))
1439 Message::SendFail() << "Wrong view name";
1443 // Activate another view if it's active now
1444 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
1446 if (ViewerTest_myViews.Extent() > 1)
1448 TCollection_AsciiString aNewViewName;
1449 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1450 anIter.More(); anIter.Next())
1452 if (anIter.Key1() != theViewName)
1454 aNewViewName = anIter.Key1();
1458 ActivateView (aNewViewName);
1462 VT_GetWindow().Nullify();
1463 ViewerTest::CurrentView (Handle(V3d_View)());
1464 if (isContextRemoved)
1466 Handle(AIS_InteractiveContext) anEmptyContext;
1467 ViewerTest::SetAISContext(anEmptyContext);
1473 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1474 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1475 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
1476 aRedrawer.Stop (aView);
1478 // Remove view resources
1479 ViewerTest_myViews.UnBind1(theViewName);
1480 aView->Window()->Unmap();
1483 #if defined(HAVE_XLIB)
1484 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
1487 // Keep context opened only if the closed view is last to avoid
1488 // unused empty contexts
1489 if (!aCurrentContext.IsNull())
1491 // Check if there are more defined views in the viewer
1492 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
1493 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
1495 // Remove driver if there is no viewers that use it
1496 Standard_Boolean isRemoveDriver = Standard_True;
1497 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1498 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1500 if (aCurrentContext != anIter.Key2() &&
1501 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
1503 isRemoveDriver = Standard_False;
1508 aCurrentContext->RemoveAll (Standard_False);
1511 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1512 #if defined(HAVE_XLIB)
1513 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
1517 ViewerTest_myContexts.UnBind2(aCurrentContext);
1520 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
1521 if (ViewerTest_EventManager::ToExitOnCloseView())
1523 Draw_Interprete ("exit");
1527 //==============================================================================
1529 //purpose : Remove the view defined by its name
1530 //==============================================================================
1532 static int VClose (Draw_Interpretor& /*theDi*/,
1533 Standard_Integer theArgsNb,
1534 const char** theArgVec)
1536 NCollection_List<TCollection_AsciiString> aViewList;
1539 TCollection_AsciiString anArg (theArgVec[1]);
1541 if (anArg.IsEqual ("ALL")
1542 || anArg.IsEqual ("*"))
1544 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1545 anIter.More(); anIter.Next())
1547 aViewList.Append (anIter.Key1());
1549 if (aViewList.IsEmpty())
1551 std::cout << "No view to close\n";
1557 ViewerTest_Names aViewName (theArgVec[1]);
1558 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
1560 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
1563 aViewList.Append (aViewName.GetViewName());
1568 // close active view
1569 if (ViewerTest::CurrentView().IsNull())
1571 Message::SendFail ("Error: no active view");
1574 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1577 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
1578 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1579 anIter.More(); anIter.Next())
1581 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
1587 //==============================================================================
1588 //function : VActivate
1589 //purpose : Activate the view defined by its ID
1590 //==============================================================================
1592 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1596 theDi.Eval("vviewlist");
1600 TCollection_AsciiString aNameString;
1601 Standard_Boolean toUpdate = Standard_True;
1602 Standard_Boolean toActivate = Standard_True;
1603 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
1605 TCollection_AsciiString anArg (theArgVec[anArgIter]);
1608 && anArg == "-noupdate")
1610 toUpdate = Standard_False;
1613 && aNameString.IsEmpty()
1616 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1617 VT_GetWindow().Nullify();
1618 ViewerTest::CurrentView (Handle(V3d_View)());
1619 ViewerTest::ResetEventManager();
1620 theDi << theArgVec[0] << ": all views are inactive\n";
1621 toActivate = Standard_False;
1624 && aNameString.IsEmpty())
1626 aNameString = theArgVec[anArgIter];
1630 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
1639 else if (aNameString.IsEmpty())
1641 Message::SendFail ("Syntax error: wrong number of arguments");
1645 // Check if this view exists in the viewer with the driver
1646 ViewerTest_Names aViewNames (aNameString);
1647 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1649 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
1653 // Check if it is active already
1654 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1656 theDi << theArgVec[0] << ": the view is active already\n";
1660 ActivateView (aViewNames.GetViewName(), toUpdate);
1664 //==============================================================================
1665 //function : VViewList
1666 //purpose : Print current list of views per viewer and graphic driver ID
1667 // shared between viewers
1668 //==============================================================================
1670 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1674 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1675 << "Usage: " << theArgVec[0] << " name";
1678 if (ViewerTest_myContexts.Size() < 1)
1681 Standard_Boolean isTreeView =
1682 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1686 theDi << theArgVec[0] <<":\n";
1689 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
1690 aDriverIter.More(); aDriverIter.Next())
1693 theDi << aDriverIter.Key1() << ":\n";
1695 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1696 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1698 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1702 TCollection_AsciiString aContextName(aContextIter.Key1());
1703 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
1706 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
1707 aViewIter.More(); aViewIter.Next())
1709 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1711 TCollection_AsciiString aViewName(aViewIter.Key1());
1714 if (aViewIter.Value() == ViewerTest::CurrentView())
1715 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
1717 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1721 theDi << aViewName << " ";
1731 //==============================================================================
1732 //function : GetMousePosition
1734 //==============================================================================
1735 void ViewerTest::GetMousePosition (Standard_Integer& theX,
1736 Standard_Integer& theY)
1738 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
1740 theX = aViewCtrl->LastMousePosition().x();
1741 theY = aViewCtrl->LastMousePosition().y();
1745 //==============================================================================
1746 //function : VViewProj
1747 //purpose : Switch view projection
1748 //==============================================================================
1749 static int VViewProj (Draw_Interpretor& ,
1750 Standard_Integer theNbArgs,
1751 const char** theArgVec)
1753 static Standard_Boolean isYup = Standard_False;
1754 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
1757 Message::SendFail ("Error: no active viewer");
1761 TCollection_AsciiString aCmdName (theArgVec[0]);
1762 Standard_Boolean isGeneralCmd = Standard_False;
1763 if (aCmdName == "vfront")
1765 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1767 else if (aCmdName == "vback")
1769 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1771 else if (aCmdName == "vtop")
1773 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1775 else if (aCmdName == "vbottom")
1777 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1779 else if (aCmdName == "vleft")
1781 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1783 else if (aCmdName == "vright")
1785 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1787 else if (aCmdName == "vaxo")
1789 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
1793 isGeneralCmd = Standard_True;
1794 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1796 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1797 anArgCase.LowerCase();
1798 if (anArgCase == "-zup")
1800 isYup = Standard_False;
1802 else if (anArgCase == "-yup")
1804 isYup = Standard_True;
1806 else if (anArgCase == "-front"
1807 || anArgCase == "front"
1808 || anArgCase == "-f"
1809 || anArgCase == "f")
1811 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1813 else if (anArgCase == "-back"
1814 || anArgCase == "back"
1815 || anArgCase == "-b"
1816 || anArgCase == "b")
1818 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1820 else if (anArgCase == "-top"
1821 || anArgCase == "top"
1822 || anArgCase == "-t"
1823 || anArgCase == "t")
1825 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1827 else if (anArgCase == "-bottom"
1828 || anArgCase == "bottom"
1829 || anArgCase == "-bot"
1830 || anArgCase == "bot"
1831 || anArgCase == "-b"
1832 || anArgCase == "b")
1834 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1836 else if (anArgCase == "-left"
1837 || anArgCase == "left"
1838 || anArgCase == "-l"
1839 || anArgCase == "l")
1841 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1843 else if (anArgCase == "-right"
1844 || anArgCase == "right"
1845 || anArgCase == "-r"
1846 || anArgCase == "r")
1848 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1850 else if (anArgCase == "-axoleft"
1851 || anArgCase == "-leftaxo"
1852 || anArgCase == "axoleft"
1853 || anArgCase == "leftaxo")
1855 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
1857 else if (anArgCase == "-axo"
1858 || anArgCase == "axo"
1859 || anArgCase == "-a"
1861 || anArgCase == "-axoright"
1862 || anArgCase == "-rightaxo"
1863 || anArgCase == "axoright"
1864 || anArgCase == "rightaxo")
1866 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
1868 else if (anArgCase == "+x")
1870 aView->SetProj (V3d_Xpos, isYup);
1872 else if (anArgCase == "-x")
1874 aView->SetProj (V3d_Xneg, isYup);
1876 else if (anArgCase == "+y")
1878 aView->SetProj (V3d_Ypos, isYup);
1880 else if (anArgCase == "-y")
1882 aView->SetProj (V3d_Yneg, isYup);
1884 else if (anArgCase == "+z")
1886 aView->SetProj (V3d_Zpos, isYup);
1888 else if (anArgCase == "-z")
1890 aView->SetProj (V3d_Zneg, isYup);
1892 else if (anArgCase == "+x+y+z")
1894 aView->SetProj (V3d_XposYposZpos, isYup);
1896 else if (anArgCase == "+x+y-z")
1898 aView->SetProj (V3d_XposYposZneg, isYup);
1900 else if (anArgCase == "+x-y+z")
1902 aView->SetProj (V3d_XposYnegZpos, isYup);
1904 else if (anArgCase == "+x-y-z")
1906 aView->SetProj (V3d_XposYnegZneg, isYup);
1908 else if (anArgCase == "-x+y+z")
1910 aView->SetProj (V3d_XnegYposZpos, isYup);
1912 else if (anArgCase == "-x+y-z")
1914 aView->SetProj (V3d_XnegYposZneg, isYup);
1916 else if (anArgCase == "-x-y+z")
1918 aView->SetProj (V3d_XnegYnegZpos, isYup);
1920 else if (anArgCase == "-x-y-z")
1922 aView->SetProj (V3d_XnegYnegZneg, isYup);
1924 else if (anArgCase == "+x+y")
1926 aView->SetProj (V3d_XposYpos, isYup);
1928 else if (anArgCase == "+x-y")
1930 aView->SetProj (V3d_XposYneg, isYup);
1932 else if (anArgCase == "-x+y")
1934 aView->SetProj (V3d_XnegYpos, isYup);
1936 else if (anArgCase == "-x-y")
1938 aView->SetProj (V3d_XnegYneg, isYup);
1940 else if (anArgCase == "+x+z")
1942 aView->SetProj (V3d_XposZpos, isYup);
1944 else if (anArgCase == "+x-z")
1946 aView->SetProj (V3d_XposZneg, isYup);
1948 else if (anArgCase == "-x+z")
1950 aView->SetProj (V3d_XnegZpos, isYup);
1952 else if (anArgCase == "-x-z")
1954 aView->SetProj (V3d_XnegZneg, isYup);
1956 else if (anArgCase == "+y+z")
1958 aView->SetProj (V3d_YposZpos, isYup);
1960 else if (anArgCase == "+y-z")
1962 aView->SetProj (V3d_YposZneg, isYup);
1964 else if (anArgCase == "-y+z")
1966 aView->SetProj (V3d_YnegZpos, isYup);
1968 else if (anArgCase == "-y-z")
1970 aView->SetProj (V3d_YnegZneg, isYup);
1972 else if (anArgIter + 1 < theNbArgs
1973 && anArgCase == "-frame"
1974 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
1976 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
1977 aFrameDef.LowerCase();
1978 gp_Dir aRight, anUp;
1979 if (aFrameDef.Value (2) == aFrameDef.Value (4))
1981 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
1985 if (aFrameDef.Value (2) == 'x')
1987 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
1989 else if (aFrameDef.Value (2) == 'y')
1991 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
1993 else if (aFrameDef.Value (2) == 'z')
1995 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
1999 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2003 if (aFrameDef.Value (4) == 'x')
2005 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
2007 else if (aFrameDef.Value (4) == 'y')
2009 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
2011 else if (aFrameDef.Value (4) == 'z')
2013 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
2017 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2021 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
2022 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
2023 const gp_Dir aDir = anUp.Crossed (aRight);
2024 aCamera->SetCenter (gp_Pnt (0, 0, 0));
2025 aCamera->SetDirection (aDir);
2026 aCamera->SetUp (anUp);
2027 aCamera->OrthogonalizeUp();
2029 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
2034 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2043 Message::SendFail ("Syntax error: wrong number of arguments");
2049 //==============================================================================
2051 //purpose : Dsiplay help on viewer Keyboead and mouse commands
2052 //Draw arg : No args
2053 //==============================================================================
2055 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
2057 di << "=========================\n";
2058 di << "F : FitAll\n";
2059 di << "T : TopView\n";
2060 di << "B : BottomView\n";
2061 di << "R : RightView\n";
2062 di << "L : LeftView\n";
2063 di << "Backspace : AxonometricView\n";
2065 di << "=========================\n";
2066 di << "W, S : Fly forward/backward\n";
2067 di << "A, D : Slide left/right\n";
2068 di << "Q, E : Bank left/right\n";
2069 di << "-, + : Change flying speed\n";
2070 di << "Arrows : look left/right/up/down\n";
2071 di << "Arrows+Shift : slide left/right/up/down\n";
2073 di << "=========================\n";
2074 di << "S + Ctrl : Shading\n";
2075 di << "W + Ctrl : Wireframe\n";
2076 di << "H : HiddenLineRemoval\n";
2077 di << "U : Unset display mode\n";
2078 di << "Delete : Remove selection from viewer\n";
2080 di << "=========================\n";
2081 di << "Selection mode \n";
2082 di << "0 : Shape\n";
2083 di << "1 : Vertex\n";
2087 di << "5 : Shell\n";
2088 di << "6 : Solid\n";
2089 di << "7 : Compound\n";
2091 di << "=========================\n";
2092 di << "< : Hilight next detected\n";
2093 di << "> : Hilight previous detected\n";
2100 static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
2105 if (ViewerTest_myViews.IsEmpty())
2107 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2114 // Delete view from map of views
2115 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
2120 if (LOWORD(wParam) == WA_CLICKACTIVE
2121 || LOWORD(wParam) == WA_ACTIVE
2122 || ViewerTest::CurrentView().IsNull())
2124 // Activate inactive window
2125 if (VT_GetWindow().IsNull()
2126 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
2128 ActivateView (FindViewIdByWindowHandle (theWinHandle));
2135 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2137 && !VT_GetWindow().IsNull())
2140 aMsg.hwnd = theWinHandle;
2141 aMsg.message = theMsg;
2142 aMsg.wParam = wParam;
2143 aMsg.lParam = lParam;
2144 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
2151 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2154 //==============================================================================
2155 //function : ViewerMainLoop
2156 //purpose : Get a Event on the view and dispatch it
2157 //==============================================================================
2159 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2161 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
2162 if (aViewCtrl.IsNull()
2168 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2170 std::cout << "Start picking\n";
2174 while (aViewCtrl->ToPickPoint())
2176 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2177 if (GetMessageW (&aMsg, NULL, 0, 0))
2179 TranslateMessage (&aMsg);
2180 DispatchMessageW (&aMsg);
2184 std::cout << "Picking done\n";
2188 #elif defined(HAVE_XLIB)
2190 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2192 static XEvent aReport;
2193 const Standard_Boolean toPick = theNbArgs > 0;
2196 if (ViewerTest::CurrentEventManager().IsNull())
2200 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2203 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
2204 XNextEvent (aDisplay, &aReport);
2206 // Handle event for the chosen display connection
2207 switch (aReport.type)
2211 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2214 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2215 return toPick ? 0 : 1;
2221 // Activate inactive view
2222 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
2223 if (aWindow != aReport.xfocus.window)
2225 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2231 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2233 && !VT_GetWindow().IsNull())
2235 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
2240 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
2243 //==============================================================================
2244 //function : VProcessEvents
2245 //purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
2246 //==============================================================================
2247 static void VProcessEvents (ClientData theDispX, int)
2249 Display* aDispX = (Display* )theDispX;
2250 Handle(Aspect_DisplayConnection) aDispConn;
2251 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2252 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
2254 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
2255 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
2257 aDispConn = aDispConnTmp;
2261 if (aDispConn.IsNull())
2263 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
2267 // process new events in queue
2268 SetDisplayConnection (aDispConn);
2270 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
2272 const int anEventResult = ViewerMainLoop (0, NULL);
2273 if (anEventResult == 0)
2278 aNbRemain = XPending (aDispX);
2279 if (++anEventIter >= aNbEventsMax
2286 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
2287 // it is possible that new events will arrive to queue before the end of this callback
2288 // so that either this callback should go into an infinite loop (blocking processing of other events)
2289 // or to keep unprocessed events till the next queue update (which can arrive not soon).
2290 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
2294 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
2295 aDummyEvent.type = ClientMessage;
2296 aDummyEvent.xclient.format = 32;
2297 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
2301 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
2303 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
2306 #elif !defined(__APPLE__)
2307 // =======================================================================
2308 // function : ViewerMainLoop
2310 // =======================================================================
2311 int ViewerMainLoop (Standard_Integer , const char** )
2318 //==============================================================================
2321 //==============================================================================
2323 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
2325 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2328 Message::SendFail ("Error: no active viewer");
2332 Standard_Boolean toFit = Standard_True;
2333 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2334 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2336 TCollection_AsciiString anArg (theArgv[anArgIter]);
2338 if (anUpdateTool.parseRedrawMode (anArg))
2342 else if (anArg == "-selected")
2344 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
2345 toFit = Standard_False;
2349 Message::SendFail() << "Syntax error at '" << anArg << "'";
2355 aView->FitAll (0.01, Standard_False);
2360 //=======================================================================
2361 //function : VFitArea
2362 //purpose : Fit view to show area located between two points
2363 // : given in world 2D or 3D coordinates.
2364 //=======================================================================
2365 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
2367 Handle(V3d_View) aView = ViewerTest::CurrentView();
2370 Message::SendFail ("Error: No active viewer");
2375 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
2376 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
2380 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2381 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2382 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
2383 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
2385 else if (theArgNb == 7)
2387 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2388 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2389 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
2390 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
2391 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
2392 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
2396 Message::SendFail ("Syntax error: Invalid number of arguments");
2397 theDI.PrintHelp(theArgVec[0]);
2401 // Convert model coordinates to view space
2402 Handle(Graphic3d_Camera) aCamera = aView->Camera();
2403 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
2404 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
2406 // Determine fit area
2407 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
2408 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
2410 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
2412 if (aDiagonal < Precision::Confusion())
2414 Message::SendFail ("Error: view area is too small");
2418 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
2422 //==============================================================================
2424 //purpose : ZFitall, no DRAW arguments
2425 //Draw arg : No args
2426 //==============================================================================
2427 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2429 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2431 if (aCurrentView.IsNull())
2433 Message::SendFail ("Error: no active viewer");
2439 aCurrentView->ZFitAll();
2440 aCurrentView->Redraw();
2444 Standard_Real aScale = 1.0;
2448 aScale = Draw::Atoi (theArgVec[1]);
2451 aCurrentView->ZFitAll (aScale);
2452 aCurrentView->Redraw();
2457 //==============================================================================
2458 //function : VRepaint
2460 //==============================================================================
2461 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
2463 Handle(V3d_View) aView = ViewerTest::CurrentView();
2466 Message::SendFail ("Error: no active viewer");
2470 Standard_Boolean isImmediateUpdate = Standard_False;
2471 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2473 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2475 if (anArg == "-immediate"
2478 isImmediateUpdate = Standard_True;
2479 if (anArgIter + 1 < theArgNb
2480 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
2485 else if (anArg == "-continuous"
2488 || anArg == "-framerate")
2490 Standard_Real aFps = -1.0;
2491 if (anArgIter + 1 < theArgNb
2492 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
2494 aFps = Draw::Atof (theArgVec[++anArgIter]);
2497 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2498 ViewerTest::CurrentEventManager()->SetContinuousRedraw (false);
2501 aRedrawer.Start (aView, aFps);
2503 else if (aFps < 0.0)
2505 if (ViewerTest::GetViewerFromContext()->ActiveViews().Extent() == 1)
2508 ViewerTest::CurrentEventManager()->SetContinuousRedraw (true);
2509 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
2512 aRedrawer.Start (aView, aFps);
2521 Message::SendFail() << "Syntax error at '" << anArg << "'";
2526 if (isImmediateUpdate)
2528 aView->RedrawImmediate();
2537 //==============================================================================
2539 //purpose : Remove all the object from the viewer
2540 //Draw arg : No args
2541 //==============================================================================
2543 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2545 Handle(V3d_View) V = ViewerTest::CurrentView();
2547 ViewerTest::Clear();
2551 //==============================================================================
2554 //==============================================================================
2556 static int VPick (Draw_Interpretor& ,
2557 Standard_Integer theNbArgs,
2558 const char** theArgVec)
2560 if (ViewerTest::CurrentView().IsNull())
2567 Message::SendFail ("Syntax error: wrong number of arguments");
2571 while (ViewerMainLoop (theNbArgs, theArgVec))
2579 //! Parse image fill method.
2580 static bool parseImageMode (const TCollection_AsciiString& theName,
2581 Aspect_FillMethod& theMode)
2583 TCollection_AsciiString aName = theName;
2585 if (aName == "none")
2587 theMode = Aspect_FM_NONE;
2589 else if (aName == "centered")
2591 theMode = Aspect_FM_CENTERED;
2593 else if (aName == "tiled")
2595 theMode = Aspect_FM_TILED;
2597 else if (aName == "stretch")
2599 theMode = Aspect_FM_STRETCH;
2608 //! Parse gradient fill method.
2609 static bool parseGradientMode (const TCollection_AsciiString& theName,
2610 Aspect_GradientFillMethod& theMode)
2612 TCollection_AsciiString aName = theName;
2614 if (aName == "none")
2616 theMode = Aspect_GradientFillMethod_None;
2618 else if (aName == "hor"
2619 || aName == "horizontal")
2621 theMode = Aspect_GradientFillMethod_Horizontal;
2623 else if (aName == "ver"
2625 || aName == "vertical")
2627 theMode = Aspect_GradientFillMethod_Vertical;
2629 else if (aName == "diag"
2630 || aName == "diagonal"
2632 || aName == "diagonal1")
2634 theMode = Aspect_GradientFillMethod_Diagonal1;
2636 else if (aName == "diag2"
2637 || aName == "diagonal2")
2639 theMode = Aspect_GradientFillMethod_Diagonal2;
2641 else if (aName == "corner1")
2643 theMode = Aspect_GradientFillMethod_Corner1;
2645 else if (aName == "corner2")
2647 theMode = Aspect_GradientFillMethod_Corner2;
2649 else if (aName == "corner3")
2651 theMode = Aspect_GradientFillMethod_Corner3;
2653 else if (aName == "corner4")
2655 theMode = Aspect_GradientFillMethod_Corner4;
2657 else if (aName == "ellip"
2658 || aName == "elliptical")
2660 theMode = Aspect_GradientFillMethod_Elliptical;
2669 //==============================================================================
2670 //function : VBackground
2672 //==============================================================================
2673 static int VBackground (Draw_Interpretor& theDI,
2674 Standard_Integer theNbArgs,
2675 const char** theArgVec)
2679 theDI << "Syntax error: wrong number of arguments";
2683 const TCollection_AsciiString aCmdName (theArgVec[0]);
2684 bool isDefault = aCmdName == "vsetdefaultbg";
2685 Standard_Integer aNbColors = 0;
2686 Quantity_ColorRGBA aColors[2];
2688 Aspect_GradientFillMethod aGradientMode = Aspect_GradientFillMethod_None;
2689 bool hasGradientMode = false;
2691 TCollection_AsciiString anImagePath;
2692 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
2693 bool hasImageMode = false;
2695 NCollection_Sequence<TCollection_AsciiString> aCubeMapSeq;
2696 Graphic3d_CubeMapOrder aCubeOrder = Graphic3d_CubeMapOrder::Default();
2697 bool isCubeZInverted = false;
2702 Handle(V3d_View) aView = ViewerTest::CurrentView();
2703 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
2704 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2706 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2708 if (anUpdateTool.parseRedrawMode (anArg))
2712 else if (anArg == "-default"
2717 else if (anArgIter + 1 < theNbArgs
2718 && (anArg == "-imagefile"
2719 || anArg == "-imgfile"
2720 || anArg == "-image"
2721 || anArg == "-img"))
2723 anImagePath = theArgVec[++anArgIter];
2725 else if (anArgIter + 1 < theNbArgs
2726 && aCubeMapSeq.IsEmpty()
2727 && (anArg == "-cubemap"
2731 aCubeMapSeq.Append (theArgVec[++anArgIter]);
2732 for (Standard_Integer aCubeSideIter = 1; anArgIter + aCubeSideIter < theNbArgs; ++aCubeSideIter)
2734 TCollection_AsciiString aSideArg (theArgVec[anArgIter + aCubeSideIter]);
2735 if (!aSideArg.IsEmpty()
2736 && aSideArg.Value (1) == '-')
2741 aCubeMapSeq.Append (aSideArg);
2742 if (aCubeMapSeq.Size() == 6)
2749 if (aCubeMapSeq.Size() > 1
2750 && aCubeMapSeq.Size() < 6)
2752 aCubeMapSeq.Remove (2, aCubeMapSeq.Size());
2755 else if (anArgIter + 6 < theNbArgs
2756 && anArg == "-order")
2758 for (Standard_Integer aCubeSideIter = 0; aCubeSideIter < 6; ++aCubeSideIter)
2760 Standard_Integer aSideArg = 0;
2761 if (!Draw::ParseInteger (theArgVec[anArgIter + aCubeSideIter + 1], aSideArg)
2765 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2768 aCubeOrder.Set ((Graphic3d_CubeMapSide )aCubeSideIter, (unsigned char )aSideArg);
2770 if (!aCubeOrder.IsValid())
2772 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2777 else if (anArg == "-invertedz"
2778 || anArg == "-noinvertedz"
2780 || anArg == "-noinvz")
2782 isCubeZInverted = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2784 else if (anArg == "-pbrenv"
2785 || anArg == "-nopbrenv"
2787 || anArg == "-noibl")
2789 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2790 if (anArgIter + 1 < theNbArgs)
2792 TCollection_AsciiString anIblArg (theArgVec[anArgIter + 1]);
2793 anIblArg.LowerCase();
2794 if (anIblArg == "keep"
2795 || anIblArg == "-1")
2800 else if (anIblArg == "ibl"
2802 || anIblArg == "on")
2804 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2807 else if (anIblArg == "noibl"
2809 || anIblArg == "off")
2811 toUseIBL = !anArg.StartsWith ("-no") ? 0 : 1;
2816 else if (anArg == "-srgb"
2817 || anArg == "-nosrgb")
2819 isSRgb = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2821 else if (aNbColors < 2
2822 && (anArg == "-color"
2823 || anArg == "-col"))
2825 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - (anArgIter + 1),
2826 theArgVec + (anArgIter + 1),
2827 aColors[aNbColors].ChangeRGB());
2830 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2833 anArgIter += aNbParsed;
2836 else if (anArgIter + 1 < theNbArgs
2837 && (anArg == "-gradientmode"
2838 || anArg == "-gradmode"
2839 || anArg == "-gradmd"
2840 || anArg == "-grmode"
2841 || anArg == "-grmd")
2842 && parseGradientMode (theArgVec[anArgIter + 1], aGradientMode))
2845 hasGradientMode = true;
2847 else if (anArgIter + 1 < theNbArgs
2848 && (anArg == "-imagemode"
2849 || anArg == "-imgmode"
2850 || anArg == "-imagemd"
2851 || anArg == "-imgmd")
2852 && parseImageMode (theArgVec[anArgIter + 1], anImageMode))
2855 hasImageMode = true;
2857 else if (aNbColors == 0
2858 && anArgIter + 2 < theNbArgs
2859 && (anArg == "-gradient"
2863 Standard_Integer aNbParsed1 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
2864 theArgVec + (anArgIter + 1),
2865 aColors[aNbColors].ChangeRGB());
2866 anArgIter += aNbParsed1;
2868 if (aNbParsed1 == 0)
2870 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2873 Standard_Integer aNbParsed2 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
2874 theArgVec + (anArgIter + 1),
2875 aColors[aNbColors].ChangeRGB());
2876 anArgIter += aNbParsed2;
2878 if (aNbParsed2 == 0)
2880 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2884 else if (parseGradientMode (theArgVec[anArgIter], aGradientMode))
2886 hasGradientMode = true;
2888 else if (aNbColors < 2
2889 && (Quantity_ColorRGBA::ColorFromName(theArgVec[anArgIter], aColors[aNbColors])
2890 || Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColors[aNbColors])))
2894 else if (anImagePath.IsEmpty()
2897 && aCubeMapSeq.IsEmpty())
2899 anImagePath = theArgVec[anArgIter];
2903 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2911 theDI << "Error: no active viewer";
2916 && !hasGradientMode)
2918 theDI << "Syntax error at '-default'";
2926 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
2927 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
2928 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_None;
2929 ViewerTest_DefaultBackground.FlatColor = aColors[0].GetRGB();
2930 ViewerTest_DefaultBackground.SetDefaultGradient();
2931 ViewerTest_DefaultBackground.SetDefaultColor();
2935 aView->SetBgGradientStyle (hasGradientMode ? aGradientMode : Aspect_GradientFillMethod_None);
2936 aView->SetBackgroundColor (aColors[0].GetRGB());
2939 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
2943 else if (aNbColors == 2)
2947 ViewerTest_DefaultBackground.GradientColor1 = aColors[0].GetRGB();
2948 ViewerTest_DefaultBackground.GradientColor2 = aColors[1].GetRGB();
2949 if (hasGradientMode)
2951 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
2953 else if (ViewerTest_DefaultBackground.FillMethod == Aspect_GradientFillMethod_None)
2955 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_Vertical;
2957 ViewerTest_DefaultBackground.SetDefaultGradient();
2961 if (!hasGradientMode)
2963 aGradientMode = aView->GradientBackground().BgGradientFillMethod();
2964 if (aGradientMode == Aspect_GradientFillMethod_None)
2966 aGradientMode = Aspect_GradientFillMethod_Vertical;
2969 aView->SetBgGradientColors (aColors[0].GetRGB(), aColors[1].GetRGB(), aGradientMode);
2972 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
2976 else if (hasGradientMode)
2980 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
2981 ViewerTest_DefaultBackground.SetDefaultGradient();
2985 aView->SetBgGradientStyle (aGradientMode);
2989 if (!anImagePath.IsEmpty())
2991 Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2Dmanual (anImagePath);
2992 aTextureMap->DisableModulate();
2993 aTextureMap->SetColorMap (isSRgb);
2994 if (!aTextureMap->IsDone())
2996 theDI << "Syntax error at '" << anImagePath << "'";
2999 aView->SetBackgroundImage (aTextureMap, anImageMode);
3001 else if (hasImageMode)
3003 aView->SetBgImageStyle (anImageMode);
3006 if (!aCubeMapSeq.IsEmpty())
3008 Handle(Graphic3d_CubeMap) aCubeMap;
3009 if (aCubeMapSeq.Size() == 1)
3011 aCubeMap = new Graphic3d_CubeMapPacked (aCubeMapSeq.First(), aCubeOrder.Validated());
3015 NCollection_Array1<TCollection_AsciiString> aCubeMapArr (0, 5);
3016 Standard_Integer aCubeSide = 0;
3017 for (NCollection_Sequence<TCollection_AsciiString>::Iterator aFileIter (aCubeMapSeq); aFileIter.More(); aFileIter.Next(), ++aCubeSide)
3019 aCubeMapArr[aCubeSide] = aFileIter.Value();
3021 aCubeMap = new Graphic3d_CubeMapSeparate (aCubeMapArr);
3024 aCubeMap->SetZInversion (isCubeZInverted);
3025 aCubeMap->SetColorMap (isSRgb);
3027 aCubeMap->GetParams()->SetFilter (Graphic3d_TOTF_BILINEAR);
3028 aCubeMap->GetParams()->SetRepeat (false);
3029 aCubeMap->GetParams()->SetTextureUnit (Graphic3d_TextureUnit_EnvMap);
3031 aView->SetBackgroundCubeMap (aCubeMap, toUseIBL != -1);
3036 aView->SetImageBasedLighting (toUseIBL == 1);
3042 //==============================================================================
3044 //purpose : View Scaling
3045 //==============================================================================
3047 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3049 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3050 if ( V3dView.IsNull() ) return 1;
3053 di << argv[0] << "Invalid number of arguments\n";
3056 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
3059 //==============================================================================
3060 //function : VZBuffTrihedron
3062 //==============================================================================
3064 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3065 Standard_Integer theArgNb,
3066 const char** theArgVec)
3068 Handle(V3d_View) aView = ViewerTest::CurrentView();
3071 Message::SendFail ("Error: no active viewer");
3075 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
3077 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3078 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
3079 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3080 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3081 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
3082 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3083 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3084 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3085 Standard_Real aScale = 0.1;
3086 Standard_Real aSizeRatio = 0.8;
3087 Standard_Real anArrowDiam = 0.05;
3088 Standard_Integer aNbFacets = 12;
3089 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3091 Standard_CString anArg = theArgVec[anArgIter];
3092 TCollection_AsciiString aFlag (anArg);
3094 if (anUpdateTool.parseRedrawMode (aFlag))
3098 else if (aFlag == "-on")
3102 else if (aFlag == "-off")
3104 aView->TriedronErase();
3107 else if (aFlag == "-pos"
3108 || aFlag == "-position"
3109 || aFlag == "-corner")
3111 if (++anArgIter >= theArgNb)
3113 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3117 TCollection_AsciiString aPosName (theArgVec[anArgIter]);
3118 aPosName.LowerCase();
3119 if (aPosName == "center")
3121 aPosition = Aspect_TOTP_CENTER;
3123 else if (aPosName == "left_lower"
3124 || aPosName == "lower_left"
3125 || aPosName == "leftlower"
3126 || aPosName == "lowerleft")
3128 aPosition = Aspect_TOTP_LEFT_LOWER;
3130 else if (aPosName == "left_upper"
3131 || aPosName == "upper_left"
3132 || aPosName == "leftupper"
3133 || aPosName == "upperleft")
3135 aPosition = Aspect_TOTP_LEFT_UPPER;
3137 else if (aPosName == "right_lower"
3138 || aPosName == "lower_right"
3139 || aPosName == "rightlower"
3140 || aPosName == "lowerright")
3142 aPosition = Aspect_TOTP_RIGHT_LOWER;
3144 else if (aPosName == "right_upper"
3145 || aPosName == "upper_right"
3146 || aPosName == "rightupper"
3147 || aPosName == "upperright")
3149 aPosition = Aspect_TOTP_RIGHT_UPPER;
3153 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown position '" << aPosName << "'";
3157 else if (aFlag == "-type")
3159 if (++anArgIter >= theArgNb)
3161 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3165 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3166 aTypeName.LowerCase();
3167 if (aTypeName == "wireframe"
3168 || aTypeName == "wire")
3170 aVisType = V3d_WIREFRAME;
3172 else if (aTypeName == "zbuffer"
3173 || aTypeName == "shaded")
3175 aVisType = V3d_ZBUFFER;
3179 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
3182 else if (aFlag == "-scale")
3184 if (++anArgIter >= theArgNb)
3186 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3190 aScale = Draw::Atof (theArgVec[anArgIter]);
3192 else if (aFlag == "-size"
3193 || aFlag == "-sizeratio")
3195 if (++anArgIter >= theArgNb)
3197 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3201 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3203 else if (aFlag == "-arrowdiam"
3204 || aFlag == "-arrowdiameter")
3206 if (++anArgIter >= theArgNb)
3208 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3212 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3214 else if (aFlag == "-nbfacets")
3216 if (++anArgIter >= theArgNb)
3218 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3222 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3224 else if (aFlag == "-colorlabel"
3225 || aFlag == "-colorlabels"
3226 || aFlag == "-colorlabelx"
3227 || aFlag == "-colorlabely"
3228 || aFlag == "-colorlabelz"
3229 || aFlag == "-colorarrowx"
3230 || aFlag == "-colorarrowy"
3231 || aFlag == "-colorarrowz")
3233 Quantity_Color aColor;
3234 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3235 theArgVec + anArgIter + 1,
3239 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3243 if (aFlag == "-colorarrowx")
3245 anArrowColorX = aColor;
3247 else if (aFlag == "-colorarrowy")
3249 anArrowColorY = aColor;
3251 else if (aFlag == "-colorarrowz")
3253 anArrowColorZ = aColor;
3255 else if (aFlag == "-colorlabelx")
3257 aLabelsColorX = aColor;
3259 else if (aFlag == "-colorlabely")
3261 aLabelsColorY = aColor;
3263 else if (aFlag == "-colorlabelz")
3265 aLabelsColorZ = aColor;
3269 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
3271 anArgIter += aNbParsed;
3275 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3280 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
3281 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
3282 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
3283 aTrihedron->SetSizeRatio (aSizeRatio);
3284 aTrihedron->SetNbFacets (aNbFacets);
3285 aTrihedron->SetArrowDiameter(anArrowDiam);
3286 aTrihedron->SetScale (aScale);
3287 aTrihedron->SetPosition (aPosition);
3288 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
3289 aTrihedron->Display (aView);
3295 //==============================================================================
3296 //function : VRotate
3297 //purpose : Camera Rotating
3298 //==============================================================================
3300 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
3302 Handle(V3d_View) aView = ViewerTest::CurrentView();
3305 Message::SendFail ("Error: no active viewer");
3309 Standard_Boolean hasFlags = Standard_False;
3310 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3312 Standard_CString anArg (theArgVec[anArgIter]);
3313 TCollection_AsciiString aFlag (anArg);
3315 if (aFlag == "-mousestart"
3316 || aFlag == "-mousefrom")
3318 hasFlags = Standard_True;
3319 if (anArgIter + 2 >= theArgNb)
3321 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3325 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3326 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3327 aView->StartRotation (anX, anY);
3329 else if (aFlag == "-mousemove")
3331 hasFlags = Standard_True;
3332 if (anArgIter + 2 >= theArgNb)
3334 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3338 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3339 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3340 aView->Rotation (anX, anY);
3342 else if (theArgNb != 4
3345 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3354 else if (theArgNb == 4)
3356 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3357 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3358 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3359 aView->Rotate (anAX, anAY, anAZ);
3362 else if (theArgNb == 7)
3364 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3365 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3366 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3368 Standard_Real anX = Draw::Atof (theArgVec[4]);
3369 Standard_Real anY = Draw::Atof (theArgVec[5]);
3370 Standard_Real anZ = Draw::Atof (theArgVec[6]);
3372 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
3376 Message::SendFail ("Error: Invalid number of arguments");
3380 //==============================================================================
3382 //purpose : View zoom in / out (relative to current zoom)
3383 //==============================================================================
3385 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3386 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3387 if ( V3dView.IsNull() ) {
3392 Standard_Real coef = Draw::Atof(argv[1]);
3393 if ( coef <= 0.0 ) {
3394 di << argv[1] << "Invalid value\n";
3397 V3dView->SetZoom( Draw::Atof(argv[1]) );
3400 di << argv[0] << " Invalid number of arguments\n";
3405 //==============================================================================
3407 //purpose : View panning (in pixels)
3408 //==============================================================================
3410 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3411 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3412 if ( V3dView.IsNull() ) return 1;
3415 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
3418 di << argv[0] << " Invalid number of arguments\n";
3423 //==============================================================================
3425 //purpose : Place the point (in pixels) at the center of the window
3426 //==============================================================================
3427 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
3429 Handle(V3d_View) aView = ViewerTest::CurrentView();
3432 Message::SendFail ("Error: no active viewer");
3438 Message::SendFail ("Syntax error: wrong number of arguments");
3442 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
3447 static int VColorScale (Draw_Interpretor& theDI,
3448 Standard_Integer theArgNb,
3449 const char** theArgVec)
3451 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3452 Handle(V3d_View) aView = ViewerTest::CurrentView();
3453 if (aContext.IsNull())
3455 Message::SendFail ("Error: no active viewer");
3460 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
3464 Handle(AIS_ColorScale) aColorScale;
3465 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
3467 // find existing object
3468 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
3469 if (aColorScale.IsNull())
3471 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
3478 if (aColorScale.IsNull())
3480 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
3484 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
3485 << "Min range: " << aColorScale->GetMin() << "\n"
3486 << "Max range: " << aColorScale->GetMax() << "\n"
3487 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
3488 << "Text height: " << aColorScale->GetTextHeight() << "\n"
3489 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
3490 << "Color scale title: " << aColorScale->GetTitle() << "\n"
3491 << "Label position: ";
3492 switch (aColorScale->GetLabelPosition())
3494 case Aspect_TOCSP_NONE:
3497 case Aspect_TOCSP_LEFT:
3500 case Aspect_TOCSP_RIGHT:
3503 case Aspect_TOCSP_CENTER:
3504 theDI << "Center\n";
3510 if (aColorScale.IsNull())
3512 aColorScale = new AIS_ColorScale();
3513 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
3514 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
3517 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
3518 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
3520 Standard_CString anArg = theArgVec[anArgIter];
3521 TCollection_AsciiString aFlag (anArg);
3523 if (anUpdateTool.parseRedrawMode (aFlag))
3527 else if (aFlag == "-range")
3529 if (anArgIter + 3 >= theArgNb)
3531 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
3535 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
3536 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
3537 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
3538 if (!aRangeMin.IsRealValue (Standard_True)
3539 || !aRangeMax.IsRealValue (Standard_True))
3541 Message::SendFail ("Syntax error: the range values should be real");
3544 else if (!aNbIntervals.IsIntegerValue())
3546 Message::SendFail ("Syntax error: the number of intervals should be integer");
3550 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
3551 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
3553 else if (aFlag == "-font")
3555 if (anArgIter + 1 >= theArgNb)
3557 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3560 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
3561 if (!aFontArg.IsIntegerValue())
3563 Message::SendFail ("Syntax error: HeightFont value should be integer");
3567 aColorScale->SetTextHeight (aFontArg.IntegerValue());
3570 else if (aFlag == "-textpos")
3572 if (anArgIter + 1 >= theArgNb)
3574 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3578 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
3579 aTextPosArg.LowerCase();
3580 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
3581 if (aTextPosArg == "none")
3583 aLabPosition = Aspect_TOCSP_NONE;
3585 else if (aTextPosArg == "left")
3587 aLabPosition = Aspect_TOCSP_LEFT;
3589 else if (aTextPosArg == "right")
3591 aLabPosition = Aspect_TOCSP_RIGHT;
3593 else if (aTextPosArg == "center")
3595 aLabPosition = Aspect_TOCSP_CENTER;
3599 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
3602 aColorScale->SetLabelPosition (aLabPosition);
3604 else if (aFlag == "-logarithmic"
3607 if (anArgIter + 1 >= theArgNb)
3609 Message::SendFail() << "Synta error at argument '" << anArg << "'";
3613 Standard_Boolean IsLog;
3614 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
3616 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3619 aColorScale->SetLogarithmic (IsLog);
3621 else if (aFlag == "-huerange"
3624 if (anArgIter + 2 >= theArgNb)
3626 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3630 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
3631 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
3632 aColorScale->SetHueRange (aHueMin, aHueMax);
3634 else if (aFlag == "-colorrange")
3636 Quantity_Color aColorMin, aColorMax;
3637 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3638 theArgVec + (anArgIter + 1),
3640 anArgIter += aNbParsed1;
3641 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3642 theArgVec + (anArgIter + 1),
3644 anArgIter += aNbParsed2;
3648 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3652 aColorScale->SetColorRange (aColorMin, aColorMax);
3654 else if (aFlag == "-reversed"
3655 || aFlag == "-inverted"
3656 || aFlag == "-topdown"
3657 || aFlag == "-bottomup")
3659 Standard_Boolean toEnable = Standard_True;
3660 if (anArgIter + 1 < theArgNb
3661 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
3665 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
3667 else if (aFlag == "-smooth"
3668 || aFlag == "-smoothtransition")
3670 Standard_Boolean toEnable = Standard_True;
3671 if (anArgIter + 1 < theArgNb
3672 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3676 aColorScale->SetSmoothTransition (toEnable);
3678 else if (aFlag == "-xy")
3680 if (anArgIter + 2 >= theArgNb)
3682 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3686 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
3687 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
3688 if (!anX.IsIntegerValue()
3689 || !anY.IsIntegerValue())
3691 Message::SendFail ("Syntax error: coordinates should be integer values");
3695 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
3697 else if (aFlag == "-width"
3699 || aFlag == "-breadth")
3701 if (anArgIter + 1 >= theArgNb)
3703 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3707 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
3708 if (!aBreadth.IsIntegerValue())
3710 Message::SendFail ("Syntax error: a width should be an integer value");
3713 aColorScale->SetBreadth (aBreadth.IntegerValue());
3715 else if (aFlag == "-height"
3718 if (anArgIter + 1 >= theArgNb)
3720 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3724 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
3725 if (!aHeight.IsIntegerValue())
3727 Message::SendFail ("Syntax error: a width should be an integer value");
3730 aColorScale->SetHeight (aHeight.IntegerValue());
3732 else if (aFlag == "-color")
3734 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3736 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
3739 else if (anArgIter + 2 >= theArgNb)
3741 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3745 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
3746 if (!anInd.IsIntegerValue())
3748 Message::SendFail ("Syntax error: Index value should be integer");
3751 const Standard_Integer anIndex = anInd.IntegerValue();
3752 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
3754 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
3758 Quantity_Color aColor;
3759 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3760 theArgVec + (anArgIter + 1),
3764 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3767 aColorScale->SetIntervalColor (aColor, anIndex);
3768 aColorScale->SetColorType (Aspect_TOCSD_USER);
3769 anArgIter += aNbParsed;
3771 else if (aFlag == "-label")
3773 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3775 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
3778 else if (anArgIter + 2 >= theArgNb)
3780 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3784 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
3785 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
3787 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
3791 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
3792 aColorScale->SetLabel (aText, anIndex);
3793 aColorScale->SetLabelType (Aspect_TOCSD_USER);
3796 else if (aFlag == "-labelat"
3797 || aFlag == "-labat"
3798 || aFlag == "-labelatborder"
3799 || aFlag == "-labatborder"
3800 || aFlag == "-labelatcenter"
3801 || aFlag == "-labatcenter")
3803 Standard_Boolean toEnable = Standard_True;
3804 if (aFlag == "-labelat"
3805 || aFlag == "-labat")
3807 Standard_Integer aLabAtBorder = -1;
3808 if (++anArgIter >= theArgNb)
3810 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
3811 anAtBorder.LowerCase();
3812 if (anAtBorder == "border")
3816 else if (anAtBorder == "center")
3821 if (aLabAtBorder == -1)
3823 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3826 toEnable = (aLabAtBorder == 1);
3828 else if (anArgIter + 1 < theArgNb
3829 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3833 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
3834 || aFlag == "-labatcenter"
3838 else if (aFlag == "-colors")
3840 Aspect_SequenceOfColor aSeq;
3843 Quantity_Color aColor;
3844 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3845 theArgVec + (anArgIter + 1),
3851 anArgIter += aNbParsed;
3852 aSeq.Append (aColor);
3854 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
3856 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
3857 << aColorScale->GetNumberOfIntervals() << " intervals";
3861 aColorScale->SetColors (aSeq);
3862 aColorScale->SetColorType (Aspect_TOCSD_USER);
3864 else if (aFlag == "-uniform")
3866 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
3867 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
3868 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
3869 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
3870 aColorScale->SetColorType (Aspect_TOCSD_USER);
3872 else if (aFlag == "-labels"
3873 || aFlag == "-freelabels")
3875 if (anArgIter + 1 >= theArgNb)
3877 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3881 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
3882 ? aColorScale->GetNumberOfIntervals() + 1
3883 : aColorScale->GetNumberOfIntervals();
3884 if (aFlag == "-freelabels")
3887 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
3889 if (anArgIter + aNbLabels >= theArgNb)
3891 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
3895 TColStd_SequenceOfExtendedString aSeq;
3896 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
3898 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
3900 aColorScale->SetLabels (aSeq);
3901 aColorScale->SetLabelType (Aspect_TOCSD_USER);
3903 else if (aFlag == "-title")
3905 if (anArgIter + 1 >= theArgNb)
3907 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3911 Standard_Boolean isTwoArgs = Standard_False;
3912 if (anArgIter + 2 < theArgNb)
3914 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
3915 aSecondArg.LowerCase();
3916 Standard_DISABLE_DEPRECATION_WARNINGS
3917 if (aSecondArg == "none")
3919 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
3920 isTwoArgs = Standard_True;
3922 else if (aSecondArg == "left")
3924 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
3925 isTwoArgs = Standard_True;
3927 else if (aSecondArg == "right")
3929 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
3930 isTwoArgs = Standard_True;
3932 else if (aSecondArg == "center")
3934 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
3935 isTwoArgs = Standard_True;
3937 Standard_ENABLE_DEPRECATION_WARNINGS
3940 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
3941 aColorScale->SetTitle (aTitle);
3948 else if (aFlag == "-demoversion"
3949 || aFlag == "-demo")
3951 aColorScale->SetPosition (0, 0);
3952 aColorScale->SetTextHeight (16);
3953 aColorScale->SetRange (0.0, 100.0);
3954 aColorScale->SetNumberOfIntervals (10);
3955 aColorScale->SetBreadth (0);
3956 aColorScale->SetHeight (0);
3957 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
3958 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
3959 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
3961 else if (aFlag == "-findcolor")
3963 if (anArgIter + 1 >= theArgNb)
3965 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3969 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
3971 if (!anArg1.IsRealValue (Standard_True))
3973 Message::SendFail ("Syntax error: the value should be real");
3977 Quantity_Color aColor;
3978 aColorScale->FindColor (anArg1.RealValue(), aColor);
3979 theDI << Quantity_Color::StringName (aColor.Name());
3984 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
3989 Standard_Integer aWinWidth = 0, aWinHeight = 0;
3990 aView->Window()->Size (aWinWidth, aWinHeight);
3991 if (aColorScale->GetBreadth() == 0)
3993 aColorScale->SetBreadth (aWinWidth);
3995 if (aColorScale->GetHeight() == 0)
3997 aColorScale->SetHeight (aWinHeight);
3999 aColorScale->SetToUpdate();
4000 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
4004 //==============================================================================
4005 //function : VGraduatedTrihedron
4006 //purpose : Displays or hides a graduated trihedron
4007 //==============================================================================
4008 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4009 Quantity_Color& theColor)
4011 Quantity_NameOfColor aColorName;
4012 TCollection_AsciiString aVal = theValue;
4014 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
4016 return Standard_False;
4018 theColor = Quantity_Color (aColorName);
4019 return Standard_True;
4022 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
4026 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4027 << theArgs[0] <<"' for more information";
4031 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4032 TCollection_AsciiString aParseKey;
4033 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4035 TCollection_AsciiString anArg (theArgs [anArgIt]);
4037 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
4040 aParseKey.Remove (1);
4041 aParseKey.LowerCase();
4042 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4046 if (aParseKey.IsEmpty())
4051 aMapOfArgs(aParseKey)->Append (anArg);
4055 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4056 aMapIt.More(); aMapIt.Next())
4058 const TCollection_AsciiString& aKey = aMapIt.Key();
4059 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4061 // Bool key, without arguments
4062 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4063 && anArgs->IsEmpty())
4069 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4070 && anArgs->Length() == 1)
4076 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4077 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
4078 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4079 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
4080 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4085 // One string argument
4086 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4087 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
4088 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4093 // One integer argument
4094 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4095 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4096 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4097 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4098 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4103 // One real argument
4104 if ( aKey.IsEqual ("arrowlength")
4105 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
4110 // Two string arguments
4111 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
4112 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4117 TCollection_AsciiString aLowerKey;
4120 aLowerKey.LowerCase();
4121 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4122 << "Type help for more information";
4126 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4127 if (anAISContext.IsNull())
4129 Message::SendFail ("Error: no active viewer");
4133 Standard_Boolean toDisplay = Standard_True;
4134 Quantity_Color aColor;
4135 Graphic3d_GraduatedTrihedron aTrihedronData;
4136 // Process parameters
4137 Handle(TColStd_HSequenceOfAsciiString) aValues;
4138 if (aMapOfArgs.Find ("off", aValues))
4140 toDisplay = Standard_False;
4144 if (aMapOfArgs.Find ("xname", aValues))
4146 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4148 if (aMapOfArgs.Find ("yname", aValues))
4150 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4152 if (aMapOfArgs.Find ("zname", aValues))
4154 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4156 if (aMapOfArgs.Find ("xdrawname", aValues))
4158 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4160 if (aMapOfArgs.Find ("ydrawname", aValues))
4162 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4164 if (aMapOfArgs.Find ("zdrawname", aValues))
4166 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4168 if (aMapOfArgs.Find ("xnameoffset", aValues))
4170 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4172 if (aMapOfArgs.Find ("ynameoffset", aValues))
4174 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4176 if (aMapOfArgs.Find ("znameoffset", aValues))
4178 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4182 if (aMapOfArgs.Find ("xnamecolor", aValues))
4184 if (!GetColor (aValues->Value(1), aColor))
4186 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
4189 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4191 if (aMapOfArgs.Find ("ynamecolor", aValues))
4193 if (!GetColor (aValues->Value(1), aColor))
4195 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
4198 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4200 if (aMapOfArgs.Find ("znamecolor", aValues))
4202 if (!GetColor (aValues->Value(1), aColor))
4204 Message::SendFail ("Syntax error: -znamecolor wrong color name");
4207 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4209 if (aMapOfArgs.Find ("xcolor", aValues))
4211 if (!GetColor (aValues->Value(1), aColor))
4213 Message::SendFail ("Syntax error: -xcolor wrong color name");
4216 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4218 if (aMapOfArgs.Find ("ycolor", aValues))
4220 if (!GetColor (aValues->Value(1), aColor))
4222 Message::SendFail ("Syntax error: -ycolor wrong color name");
4225 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4227 if (aMapOfArgs.Find ("zcolor", aValues))
4229 if (!GetColor (aValues->Value(1), aColor))
4231 Message::SendFail ("Syntax error: -zcolor wrong color name");
4234 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4238 if (aMapOfArgs.Find ("xticks", aValues))
4240 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4242 if (aMapOfArgs.Find ("yticks", aValues))
4244 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4246 if (aMapOfArgs.Find ("zticks", aValues))
4248 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4250 if (aMapOfArgs.Find ("xticklength", aValues))
4252 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4254 if (aMapOfArgs.Find ("yticklength", aValues))
4256 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4258 if (aMapOfArgs.Find ("zticklength", aValues))
4260 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4262 if (aMapOfArgs.Find ("xdrawticks", aValues))
4264 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4266 if (aMapOfArgs.Find ("ydrawticks", aValues))
4268 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4270 if (aMapOfArgs.Find ("zdrawticks", aValues))
4272 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4276 if (aMapOfArgs.Find ("xdrawvalues", aValues))
4278 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4280 if (aMapOfArgs.Find ("ydrawvalues", aValues))
4282 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4284 if (aMapOfArgs.Find ("zdrawvalues", aValues))
4286 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4288 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
4290 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4292 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
4294 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4296 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
4298 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4302 if (aMapOfArgs.Find ("arrowlength", aValues))
4304 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
4308 if (aMapOfArgs.Find ("namefont", aValues))
4310 aTrihedronData.SetNamesFont (aValues->Value(1));
4312 if (aMapOfArgs.Find ("valuesfont", aValues))
4314 aTrihedronData.SetValuesFont (aValues->Value(1));
4317 if (aMapOfArgs.Find ("drawgrid", aValues))
4319 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
4321 if (aMapOfArgs.Find ("drawaxes", aValues))
4323 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
4326 // The final step: display of erase trihedron
4329 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
4333 ViewerTest::CurrentView()->GraduatedTrihedronErase();
4336 ViewerTest::GetAISContext()->UpdateCurrentViewer();
4337 ViewerTest::CurrentView()->Redraw();
4342 //==============================================================================
4345 //==============================================================================
4346 static int VTile (Draw_Interpretor& theDI,
4347 Standard_Integer theArgNb,
4348 const char** theArgVec)
4350 Handle(V3d_View) aView = ViewerTest::CurrentView();
4353 Message::SendFail ("Error: no active viewer");
4357 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
4360 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
4361 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
4362 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
4366 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
4367 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4369 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4371 if (anArg == "-lowerleft"
4372 || anArg == "-upperleft")
4374 if (anArgIter + 3 < theArgNb)
4376 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4379 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
4380 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4381 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4383 else if (anArg == "-total"
4384 || anArg == "-totalsize"
4385 || anArg == "-viewsize")
4387 if (anArgIter + 3 < theArgNb)
4389 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4392 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4393 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4394 if (aTile.TotalSize.x() < 1
4395 || aTile.TotalSize.y() < 1)
4397 Message::SendFail ("Error: total size is incorrect");
4401 else if (anArg == "-tilesize")
4403 if (anArgIter + 3 < theArgNb)
4405 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4409 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4410 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4411 if (aTile.TileSize.x() < 1
4412 || aTile.TileSize.y() < 1)
4414 Message::SendFail ("Error: tile size is incorrect");
4418 else if (anArg == "-unset")
4420 aView->Camera()->SetTile (Graphic3d_CameraTile());
4426 if (aTile.TileSize.x() < 1
4427 || aTile.TileSize.y() < 1)
4429 Message::SendFail ("Error: tile size is undefined");
4432 else if (aTile.TotalSize.x() < 1
4433 || aTile.TotalSize.y() < 1)
4435 Message::SendFail ("Error: total size is undefined");
4439 aView->Camera()->SetTile (aTile);
4444 //! Format ZLayer ID.
4445 inline const char* formZLayerId (const Standard_Integer theLayerId)
4449 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
4450 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
4451 case Graphic3d_ZLayerId_Top: return "[TOP]";
4452 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
4453 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
4454 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
4459 //! Print the ZLayer information.
4460 inline void printZLayerInfo (Draw_Interpretor& theDI,
4461 const Graphic3d_ZLayerSettings& theLayer)
4463 if (!theLayer.Name().IsEmpty())
4465 theDI << " Name: " << theLayer.Name() << "\n";
4467 if (theLayer.IsImmediate())
4469 theDI << " Immediate: TRUE\n";
4471 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4472 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
4473 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
4474 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
4475 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
4476 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
4477 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
4479 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
4483 //==============================================================================
4484 //function : VZLayer
4485 //purpose : Test z layer operations for v3d viewer
4486 //==============================================================================
4487 static int VZLayer (Draw_Interpretor& theDI,
4488 Standard_Integer theArgNb,
4489 const char** theArgVec)
4491 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4492 if (aContextAIS.IsNull())
4494 Message::SendFail ("Error: no active viewer");
4498 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
4501 TColStd_SequenceOfInteger aLayers;
4502 aViewer->GetAllZLayers (aLayers);
4503 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4505 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
4506 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
4507 printZLayerInfo (theDI, aSettings);
4512 Standard_Integer anArgIter = 1;
4513 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4514 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
4515 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
4521 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
4522 if (aFirstArg.IsIntegerValue())
4525 aLayerId = aFirstArg.IntegerValue();
4529 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
4536 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
4537 for (; anArgIter < theArgNb; ++anArgIter)
4539 // perform operation
4540 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4542 if (anUpdateTool.parseRedrawMode (anArg))
4546 else if (anArg == "-add"
4549 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4550 if (!aViewer->AddZLayer (aLayerId))
4552 Message::SendFail ("Error: can not add a new z layer");
4558 else if (anArg == "-insertbefore"
4559 && anArgIter + 1 < theArgNb
4560 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4563 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4564 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4566 Message::SendFail ("Error: can not add a new z layer");
4572 else if (anArg == "-insertafter"
4573 && anArgIter + 1 < theArgNb
4574 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4577 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4578 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4580 Message::SendFail ("Error: can not add a new z layer");
4586 else if (anArg == "-del"
4587 || anArg == "-delete"
4590 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4592 if (++anArgIter >= theArgNb)
4594 Message::SendFail ("Syntax error: id of z layer to remove is missing");
4598 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4601 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
4602 || aLayerId == Graphic3d_ZLayerId_Default
4603 || aLayerId == Graphic3d_ZLayerId_Top
4604 || aLayerId == Graphic3d_ZLayerId_Topmost
4605 || aLayerId == Graphic3d_ZLayerId_TopOSD
4606 || aLayerId == Graphic3d_ZLayerId_BotOSD)
4608 Message::SendFail ("Syntax error: standard Z layer can not be removed");
4612 // move all object displayed in removing layer to default layer
4613 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4614 anObjIter.More(); anObjIter.Next())
4616 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
4618 || aPrs->ZLayer() != aLayerId)
4622 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
4625 if (!aViewer->RemoveZLayer (aLayerId))
4627 Message::SendFail ("Z layer can not be removed");
4631 theDI << aLayerId << " ";
4634 else if (anArg == "-get"
4637 TColStd_SequenceOfInteger aLayers;
4638 aViewer->GetAllZLayers (aLayers);
4639 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4641 theDI << aLayeriter.Value() << " ";
4646 else if (anArg == "-name")
4648 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4650 Message::SendFail ("Syntax error: id of Z layer is missing");
4654 if (++anArgIter >= theArgNb)
4656 Message::SendFail ("Syntax error: name is missing");
4660 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4661 aSettings.SetName (theArgVec[anArgIter]);
4662 aViewer->SetZLayerSettings (aLayerId, aSettings);
4664 else if (anArg == "-origin")
4666 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4668 Message::SendFail ("Syntax error: id of Z layer is missing");
4672 if (anArgIter + 2 >= theArgNb)
4674 Message::SendFail ("Syntax error: origin coordinates are missing");
4678 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4680 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
4681 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
4682 anOrigin.SetZ (0.0);
4683 if (anArgIter + 3 < theArgNb)
4685 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
4692 aSettings.SetOrigin (anOrigin);
4693 aViewer->SetZLayerSettings (aLayerId, aSettings);
4695 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4696 && anArgIter + 1 < theArgNb
4697 && (anArg == "-cullingdistance"
4698 || anArg == "-cullingdist"
4699 || anArg == "-culldistance"
4700 || anArg == "-culldist"
4701 || anArg == "-distcull"
4702 || anArg == "-distculling"
4703 || anArg == "-distanceculling"))
4705 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4706 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
4707 aSettings.SetCullingDistance (aDist);
4708 aViewer->SetZLayerSettings (aLayerId, aSettings);
4710 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4711 && anArgIter + 1 < theArgNb
4712 && (anArg == "-cullingsize"
4713 || anArg == "-cullsize"
4714 || anArg == "-sizecull"
4715 || anArg == "-sizeculling"))
4717 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4718 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
4719 aSettings.SetCullingSize (aSize);
4720 aViewer->SetZLayerSettings (aLayerId, aSettings);
4722 else if (anArg == "-settings"
4723 || anArg == "settings")
4725 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4727 if (++anArgIter >= theArgNb)
4729 Message::SendFail ("Syntax error: id of Z layer is missing");
4733 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4736 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4737 printZLayerInfo (theDI, aSettings);
4739 else if (anArg == "-enable"
4740 || anArg == "enable"
4741 || anArg == "-disable"
4742 || anArg == "disable")
4744 const Standard_Boolean toEnable = anArg == "-enable"
4745 || anArg == "enable";
4746 if (++anArgIter >= theArgNb)
4748 Message::SendFail ("Syntax error: option name is missing");
4752 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
4754 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4756 if (++anArgIter >= theArgNb)
4758 Message::SendFail ("Syntax error: id of Z layer is missing");
4762 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4765 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4766 if (aSubOp == "depthtest"
4767 || aSubOp == "test")
4769 aSettings.SetEnableDepthTest (toEnable);
4771 else if (aSubOp == "depthwrite"
4772 || aSubOp == "write")
4774 aSettings.SetEnableDepthWrite (toEnable);
4776 else if (aSubOp == "depthclear"
4777 || aSubOp == "clear")
4779 aSettings.SetClearDepth (toEnable);
4781 else if (aSubOp == "depthoffset"
4782 || aSubOp == "offset")
4784 Graphic3d_PolygonOffset aParams;
4785 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
4788 if (anArgIter + 2 >= theArgNb)
4790 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
4794 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4795 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4797 aSettings.SetPolygonOffset (aParams);
4799 else if (aSubOp == "positiveoffset"
4800 || aSubOp == "poffset")
4804 aSettings.SetDepthOffsetPositive();
4808 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
4811 else if (aSubOp == "negativeoffset"
4812 || aSubOp == "noffset")
4816 aSettings.SetDepthOffsetNegative();
4820 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
4823 else if (aSubOp == "textureenv")
4825 aSettings.SetEnvironmentTexture (toEnable);
4827 else if (aSubOp == "raytracing")
4829 aSettings.SetRaytracable (toEnable);
4832 aViewer->SetZLayerSettings (aLayerId, aSettings);
4836 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
4844 // The interactive presentation of 2d layer item
4845 // for "vlayerline" command it provides a presentation of
4846 // line with user-defined linewidth, linetype and transparency.
4847 class V3d_LineItem : public AIS_InteractiveObject
4851 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
4854 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4855 Standard_Real X2, Standard_Real Y2,
4856 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
4857 Standard_Real theWidth = 0.5,
4858 Standard_Real theTransp = 1.0);
4862 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
4863 const Handle(Prs3d_Presentation)& thePrs,
4864 const Standard_Integer theMode) Standard_OVERRIDE;
4866 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
4867 const Standard_Integer ) Standard_OVERRIDE
4872 Standard_Real myX1, myY1, myX2, myY2;
4873 Aspect_TypeOfLine myType;
4874 Standard_Real myWidth;
4877 // default constructor for line item
4878 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
4879 Standard_Real X2, Standard_Real Y2,
4880 Aspect_TypeOfLine theType,
4881 Standard_Real theWidth,
4882 Standard_Real theTransp) :
4883 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
4884 myType(theType), myWidth(theWidth)
4886 SetTransparency (1-theTransp);
4890 void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
4891 const Handle(Prs3d_Presentation)& thePresentation,
4892 const Standard_Integer )
4894 thePresentation->Clear();
4895 Quantity_Color aColor (Quantity_NOC_RED);
4896 Standard_Integer aWidth, aHeight;
4897 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
4898 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
4899 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
4900 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
4901 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
4902 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
4903 aGroup->SetPrimitivesAspect (anAspect->Aspect());
4904 aGroup->AddPrimitiveArray (aPrim);
4907 //=============================================================================
4908 //function : VLayerLine
4909 //purpose : Draws line in the v3d view layer with given attributes: linetype,
4910 // : linewidth, transparency coefficient
4911 //============================================================================
4912 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
4914 // get the active view
4915 Handle(V3d_View) aView = ViewerTest::CurrentView();
4918 di << "Call vinit before!\n";
4923 di << "Use: " << argv[0];
4924 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
4925 di << " linetype : { 0 | 1 | 2 | 3 } \n";
4926 di << " 0 - solid \n";
4927 di << " 1 - dashed \n";
4928 di << " 2 - dot \n";
4929 di << " 3 - dashdot\n";
4930 di << " transparency : { 0.0 - 1.0 } \n";
4931 di << " 0.0 - transparent\n";
4932 di << " 1.0 - visible \n";
4936 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4937 // get the input params
4938 Standard_Real X1 = Draw::Atof(argv[1]);
4939 Standard_Real Y1 = Draw::Atof(argv[2]);
4940 Standard_Real X2 = Draw::Atof(argv[3]);
4941 Standard_Real Y2 = Draw::Atof(argv[4]);
4943 Standard_Real aWidth = 0.5;
4944 Standard_Real aTransparency = 1.0;
4948 aWidth = Draw::Atof(argv[5]);
4950 // select appropriate line type
4951 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
4953 && !ViewerTest::ParseLineType (argv[6], aLineType))
4955 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
4962 aTransparency = Draw::Atof(argv[7]);
4963 if (aTransparency < 0 || aTransparency > 1.0)
4964 aTransparency = 1.0;
4967 static Handle (V3d_LineItem) aLine;
4968 if (!aLine.IsNull())
4970 aContext->Erase (aLine, Standard_False);
4972 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
4976 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
4977 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
4978 aLine->SetToUpdate();
4979 aContext->Display (aLine, Standard_True);
4985 //==============================================================================
4988 //==============================================================================
4990 static int VGrid (Draw_Interpretor& /*theDI*/,
4991 Standard_Integer theArgNb,
4992 const char** theArgVec)
4994 Handle(V3d_View) aView = ViewerTest::CurrentView();
4995 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
4996 if (aView.IsNull() || aViewer.IsNull())
4998 Message::SendFail ("Error: no active viewer");
5002 Aspect_GridType aType = aViewer->GridType();
5003 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
5004 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5005 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5006 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
5007 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
5008 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5010 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5012 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5016 else if (anArgIter + 1 < theArgNb
5017 && anArg == "-type")
5019 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5020 anArgNext.LowerCase();
5021 if (anArgNext == "r"
5022 || anArgNext == "rect"
5023 || anArgNext == "rectangular")
5025 aType = Aspect_GT_Rectangular;
5027 else if (anArgNext == "c"
5028 || anArgNext == "circ"
5029 || anArgNext == "circular")
5031 aType = Aspect_GT_Circular;
5035 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5039 else if (anArgIter + 1 < theArgNb
5040 && anArg == "-mode")
5042 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5043 anArgNext.LowerCase();
5044 if (anArgNext == "l"
5045 || anArgNext == "line"
5046 || anArgNext == "lines")
5048 aMode = Aspect_GDM_Lines;
5050 else if (anArgNext == "p"
5051 || anArgNext == "point"
5052 || anArgNext == "points")
5054 aMode = Aspect_GDM_Points;
5058 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5062 else if (anArgIter + 2 < theArgNb
5063 && (anArg == "-origin"
5064 || anArg == "-orig"))
5067 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5068 Draw::Atof (theArgVec[anArgIter + 2]));
5071 else if (anArgIter + 2 < theArgNb
5072 && anArg == "-step")
5075 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5076 Draw::Atof (theArgVec[anArgIter + 2]));
5077 if (aNewStepXY.x() <= 0.0
5078 || aNewStepXY.y() <= 0.0)
5080 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5085 else if (anArgIter + 1 < theArgNb
5086 && (anArg == "-angle"
5087 || anArg == "-rotangle"
5088 || anArg == "-rotationangle"))
5091 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5093 else if (anArgIter + 1 < theArgNb
5094 && (anArg == "-zoffset"
5098 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5100 else if (anArgIter + 1 < theArgNb
5101 && anArg == "-radius")
5105 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5106 if (aNewStepXY.x() <= 0.0)
5108 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
5112 else if (anArgIter + 2 < theArgNb
5113 && anArg == "-size")
5116 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5117 Draw::Atof (theArgVec[anArgIter + 2]));
5118 if (aNewStepXY.x() <= 0.0
5119 || aNewStepXY.y() <= 0.0)
5121 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5126 else if (anArg == "r"
5128 || anArg == "rectangular")
5130 aType = Aspect_GT_Rectangular;
5132 else if (anArg == "c"
5134 || anArg == "circular")
5136 aType = Aspect_GT_Circular;
5138 else if (anArg == "l"
5140 || anArg == "lines")
5142 aMode = Aspect_GDM_Lines;
5144 else if (anArg == "p"
5146 || anArg == "points")
5148 aMode = Aspect_GDM_Points;
5150 else if (anArgIter + 1 >= theArgNb
5153 aViewer->DeactivateGrid();
5158 Message::SendFail() << "Syntax error at '" << anArg << "'";
5163 if (aType == Aspect_GT_Rectangular)
5165 Graphic3d_Vec2d anOrigXY, aStepXY;
5166 Standard_Real aRotAngle = 0.0;
5167 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5170 anOrigXY = aNewOriginXY;
5174 aStepXY = aNewStepXY;
5178 aRotAngle = aNewRotAngle;
5180 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5181 if (hasSize || hasZOffset)
5183 Graphic3d_Vec3d aSize;
5184 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5187 aSize.x() = aNewSizeXY.x();
5188 aSize.y() = aNewSizeXY.y();
5192 aSize.z() = aNewZOffset;
5194 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5197 else if (aType == Aspect_GT_Circular)
5199 Graphic3d_Vec2d anOrigXY;
5200 Standard_Real aRadiusStep;
5201 Standard_Integer aDivisionNumber;
5202 Standard_Real aRotAngle = 0.0;
5203 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5206 anOrigXY = aNewOriginXY;
5210 aRadiusStep = aNewStepXY[0];
5211 aDivisionNumber = (int )aNewStepXY[1];
5212 if (aDivisionNumber < 1)
5214 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
5220 aRotAngle = aNewRotAngle;
5223 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5224 if (hasSize || hasZOffset)
5226 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5227 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5230 aRadius = aNewSizeXY.x();
5231 if (aNewSizeXY.y() != 0.0)
5233 Message::SendFail ("Syntax error: circular size should be specified as radius");
5239 aZOffset = aNewZOffset;
5241 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
5244 aViewer->ActivateGrid (aType, aMode);
5248 //==============================================================================
5249 //function : VPriviledgedPlane
5251 //==============================================================================
5253 static int VPriviledgedPlane (Draw_Interpretor& theDI,
5254 Standard_Integer theArgNb,
5255 const char** theArgVec)
5257 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
5259 Message::SendFail ("Error: wrong number of arguments! See usage:");
5260 theDI.PrintHelp (theArgVec[0]);
5264 // get the active viewer
5265 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5266 if (aViewer.IsNull())
5268 Message::SendFail ("Error: no active viewer");
5274 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
5275 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
5276 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
5277 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
5278 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
5279 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
5280 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
5284 Standard_Integer anArgIdx = 1;
5285 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
5286 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
5287 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
5288 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
5289 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
5290 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
5292 gp_Ax3 aPriviledgedPlane;
5293 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
5294 gp_Dir aNorm (aNormX, aNormY, aNormZ);
5297 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
5298 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
5299 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
5300 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
5301 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
5305 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
5308 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
5313 //==============================================================================
5314 //function : VConvert
5316 //==============================================================================
5318 static int VConvert (Draw_Interpretor& theDI,
5319 Standard_Integer theArgNb,
5320 const char** theArgVec)
5322 // get the active view
5323 Handle(V3d_View) aView = ViewerTest::CurrentView();
5326 Message::SendFail ("Error: no active viewer");
5330 enum { Model, Ray, View, Window, Grid } aMode = Model;
5332 // access coordinate arguments
5333 TColStd_SequenceOfReal aCoord;
5334 Standard_Integer anArgIdx = 1;
5335 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
5337 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5338 if (!anArg.IsRealValue (Standard_True))
5342 aCoord.Append (anArg.RealValue());
5345 // non-numeric argument too early
5346 if (aCoord.IsEmpty())
5348 Message::SendFail ("Error: wrong number of arguments! See usage:");
5349 theDI.PrintHelp (theArgVec[0]);
5353 // collect all other arguments and options
5354 for (; anArgIdx < theArgNb; ++anArgIdx)
5356 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5358 if (anArg == "window") aMode = Window;
5359 else if (anArg == "view") aMode = View;
5360 else if (anArg == "grid") aMode = Grid;
5361 else if (anArg == "ray") aMode = Ray;
5364 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
5365 theDI.PrintHelp (theArgVec[0]);
5370 // complete input checks
5371 if ((aCoord.Length() == 1 && theArgNb > 3) ||
5372 (aCoord.Length() == 2 && theArgNb > 4) ||
5373 (aCoord.Length() == 3 && theArgNb > 5))
5375 Message::SendFail ("Error: wrong number of arguments! See usage:");
5376 theDI.PrintHelp (theArgVec[0]);
5380 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
5381 Standard_Integer aXYp[2] = {0, 0};
5383 // convert one-dimensional coordinate
5384 if (aCoord.Length() == 1)
5388 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
5389 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
5391 Message::SendFail ("Error: wrong arguments! See usage:");
5392 theDI.PrintHelp (theArgVec[0]);
5397 // convert 2D coordinates from projection or view reference space
5398 if (aCoord.Length() == 2)
5403 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5404 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5408 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
5409 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
5413 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
5414 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5418 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5419 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
5420 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5424 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
5425 (Standard_Integer) aCoord (2),
5426 aXYZ[0], aXYZ[1], aXYZ[2],
5427 aXYZ[3], aXYZ[4], aXYZ[5]);
5428 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5432 Message::SendFail ("Error: wrong arguments! See usage:");
5433 theDI.PrintHelp (theArgVec[0]);
5438 // convert 3D coordinates from view reference space
5439 else if (aCoord.Length() == 3)
5444 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
5445 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5449 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
5450 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5454 Message::SendFail ("Error: wrong arguments! See usage:");
5455 theDI.PrintHelp (theArgVec[0]);
5463 //==============================================================================
5466 //==============================================================================
5468 static int VFps (Draw_Interpretor& theDI,
5469 Standard_Integer theArgNb,
5470 const char** theArgVec)
5472 // get the active view
5473 Handle(V3d_View) aView = ViewerTest::CurrentView();
5476 Message::SendFail ("Error: no active viewer");
5480 Standard_Integer aFramesNb = -1;
5481 Standard_Real aDuration = -1.0;
5482 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5484 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5487 && anArgIter + 1 < theArgNb
5488 && (anArg == "-duration"
5490 || anArg == "-time"))
5492 aDuration = Draw::Atof (theArgVec[++anArgIter]);
5494 else if (aFramesNb < 0
5495 && anArg.IsIntegerValue())
5497 aFramesNb = anArg.IntegerValue();
5500 Message::SendFail() << "Syntax error at '" << anArg << "'";
5506 Message::SendFail() << "Syntax error at '" << anArg << "'";
5510 if (aFramesNb < 0 && aDuration < 0.0)
5515 // the time is meaningless for first call
5516 // due to async OpenGl rendering
5519 // redraw view in loop to estimate average values
5522 Standard_Integer aFrameIter = 1;
5523 for (;; ++aFrameIter)
5527 && aFrameIter >= aFramesNb)
5529 && aTimer.ElapsedTime() >= aDuration))
5536 const Standard_Real aTime = aTimer.ElapsedTime();
5537 aTimer.OSD_Chronometer::Show (aCpu);
5539 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
5540 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
5542 // return statistics
5543 theDI << "FPS: " << aFpsAver << "\n"
5544 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
5546 // compute additional statistics in ray-tracing mode
5547 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
5548 if (aParams.Method == Graphic3d_RM_RAYTRACING)
5550 Graphic3d_Vec2i aWinSize (0, 0);
5551 aView->Window()->Size (aWinSize.x(), aWinSize.y());
5553 // 1 shadow ray and 1 secondary ray pew each bounce
5554 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
5555 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
5562 //==============================================================================
5563 //function : VMemGpu
5565 //==============================================================================
5567 static int VMemGpu (Draw_Interpretor& theDI,
5568 Standard_Integer theArgNb,
5569 const char** theArgVec)
5572 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5573 if (aContextAIS.IsNull())
5575 Message::SendFail ("Error: no active viewer");
5579 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
5580 if (aDriver.IsNull())
5582 Message::SendFail ("Error: graphic driver not available");
5586 Standard_Size aFreeBytes = 0;
5587 TCollection_AsciiString anInfo;
5588 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
5590 Message::SendFail ("Error: information not available");
5594 if (theArgNb > 1 && *theArgVec[1] == 'f')
5596 theDI << Standard_Real (aFreeBytes);
5606 // ==============================================================================
5607 // function : VReadPixel
5609 // ==============================================================================
5610 static int VReadPixel (Draw_Interpretor& theDI,
5611 Standard_Integer theArgNb,
5612 const char** theArgVec)
5614 // get the active view
5615 Handle(V3d_View) aView = ViewerTest::CurrentView();
5618 Message::SendFail ("Error: no active viewer");
5621 else if (theArgNb < 3)
5623 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
5624 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
5628 Image_Format aFormat = Image_Format_RGBA;
5629 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
5631 Standard_Integer aWidth, aHeight;
5632 aView->Window()->Size (aWidth, aHeight);
5633 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
5634 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
5635 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
5637 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
5641 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
5642 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
5644 TCollection_AsciiString aParam (theArgVec[anIter]);
5646 if (aParam == "-rgb"
5648 || aParam == "-srgb"
5649 || aParam == "srgb")
5651 aFormat = Image_Format_RGB;
5652 aBufferType = Graphic3d_BT_RGB;
5653 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
5655 else if (aParam == "-hls"
5658 aFormat = Image_Format_RGB;
5659 aBufferType = Graphic3d_BT_RGB;
5660 toShowHls = Standard_True;
5662 else if (aParam == "-rgbf"
5663 || aParam == "rgbf")
5665 aFormat = Image_Format_RGBF;
5666 aBufferType = Graphic3d_BT_RGB;
5668 else if (aParam == "-rgba"
5670 || aParam == "-srgba"
5671 || aParam == "srgba")
5673 aFormat = Image_Format_RGBA;
5674 aBufferType = Graphic3d_BT_RGBA;
5675 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
5677 else if (aParam == "-rgbaf"
5678 || aParam == "rgbaf")
5680 aFormat = Image_Format_RGBAF;
5681 aBufferType = Graphic3d_BT_RGBA;
5683 else if (aParam == "-depth"
5684 || aParam == "depth")
5686 aFormat = Image_Format_GrayF;
5687 aBufferType = Graphic3d_BT_Depth;
5689 else if (aParam == "-name"
5690 || aParam == "name")
5692 toShowName = Standard_True;
5694 else if (aParam == "-hex"
5697 toShowHex = Standard_True;
5701 Message::SendFail() << "Syntax error at '" << aParam << "'";
5706 Image_PixMap anImage;
5707 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
5709 Message::SendFail ("Error: image allocation failed");
5712 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
5714 Message::SendFail ("Error: image dump failed");
5718 // redirect possible warning messages that could have been added by ToPixMap
5719 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
5720 // contaminate result of the command
5721 Standard_CString aWarnLog = theDI.Result();
5722 if (aWarnLog != NULL && aWarnLog[0] != '\0')
5724 std::cout << aWarnLog << std::endl;
5728 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
5731 if (aBufferType == Graphic3d_BT_RGBA)
5733 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
5737 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
5742 if (aBufferType == Graphic3d_BT_RGBA)
5744 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
5748 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
5753 switch (aBufferType)
5756 case Graphic3d_BT_RGB:
5760 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
5762 else if (toShow_sRGB)
5764 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
5765 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
5769 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
5773 case Graphic3d_BT_RGBA:
5775 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
5776 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
5779 case Graphic3d_BT_Depth:
5781 theDI << aColor.GetRGB().Red();
5790 //! Auxiliary presentation for an image plane.
5791 class ViewerTest_ImagePrs : public AIS_InteractiveObject
5794 //! Main constructor.
5795 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
5796 const Standard_Real theWidth,
5797 const Standard_Real theHeight,
5798 const TCollection_AsciiString& theLabel)
5799 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
5803 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
5805 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
5806 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
5807 Graphic3d_MaterialAspect aMat;
5808 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
5809 aMat.SetAmbientColor (Quantity_NOC_BLACK);
5810 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
5811 aMat.SetSpecularColor (Quantity_NOC_BLACK);
5812 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
5813 aFillAspect->SetFrontMaterial (aMat);
5814 aFillAspect->SetTextureMap (new Graphic3d_Texture2Dmanual (theImage));
5815 aFillAspect->SetTextureMapOn();
5818 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
5819 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
5820 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
5821 myDrawer->SetTextAspect (aTextAspect);
5824 const gp_Dir aNorm (0.0, 0.0, 1.0);
5825 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
5826 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
5827 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
5828 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
5829 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
5830 myTris->AddEdge (1);
5831 myTris->AddEdge (2);
5832 myTris->AddEdge (3);
5833 myTris->AddEdge (3);
5834 myTris->AddEdge (2);
5835 myTris->AddEdge (4);
5837 myRect = new Graphic3d_ArrayOfPolylines (4);
5838 myRect->AddVertex (myTris->Vertice (1));
5839 myRect->AddVertex (myTris->Vertice (3));
5840 myRect->AddVertex (myTris->Vertice (4));
5841 myRect->AddVertex (myTris->Vertice (2));
5845 //! Returns TRUE for accepted display modes.
5846 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
5848 //! Compute presentation.
5849 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
5850 const Handle(Prs3d_Presentation)& thePrs,
5851 const Standard_Integer theMode) Standard_OVERRIDE
5857 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
5858 aGroup->AddPrimitiveArray (myTris);
5859 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
5860 aGroup->AddPrimitiveArray (myRect);
5861 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
5866 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
5867 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
5868 aGroup->AddPrimitiveArray (myRect);
5869 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
5875 //! Compute selection.
5876 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
5880 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
5881 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
5882 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
5883 theSel->Add (aSensitive);
5888 Handle(Graphic3d_ArrayOfTriangles) myTris;
5889 Handle(Graphic3d_ArrayOfPolylines) myRect;
5890 TCollection_AsciiString myLabel;
5891 Standard_Real myWidth;
5892 Standard_Real myHeight;
5895 //==============================================================================
5896 //function : VDiffImage
5897 //purpose : The draw-command compares two images.
5898 //==============================================================================
5900 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
5904 Message::SendFail ("Syntax error: not enough arguments");
5908 Standard_Integer anArgIter = 1;
5909 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
5910 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
5911 TCollection_AsciiString aDiffImagePath;
5912 Standard_Real aTolColor = -1.0;
5913 Standard_Integer toBlackWhite = -1;
5914 Standard_Integer isBorderFilterOn = -1;
5915 Standard_Boolean isOldSyntax = Standard_False;
5916 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
5917 for (; anArgIter < theArgNb; ++anArgIter)
5919 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5921 if (anArgIter + 1 < theArgNb
5922 && (anArg == "-toleranceofcolor"
5923 || anArg == "-tolerancecolor"
5924 || anArg == "-tolerance"
5925 || anArg == "-toler"))
5927 aTolColor = Atof (theArgVec[++anArgIter]);
5928 if (aTolColor < 0.0 || aTolColor > 1.0)
5930 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
5934 else if (anArg == "-blackwhite")
5936 Standard_Boolean toEnable = Standard_True;
5937 if (anArgIter + 1 < theArgNb
5938 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
5942 toBlackWhite = toEnable ? 1 : 0;
5944 else if (anArg == "-borderfilter")
5946 Standard_Boolean toEnable = Standard_True;
5947 if (anArgIter + 1 < theArgNb
5948 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
5952 isBorderFilterOn = toEnable ? 1 : 0;
5954 else if (anArg == "-exitonclose")
5956 ViewerTest_EventManager::ToExitOnCloseView() = true;
5957 if (anArgIter + 1 < theArgNb
5958 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
5963 else if (anArg == "-closeonescape"
5964 || anArg == "-closeonesc")
5966 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
5967 if (anArgIter + 1 < theArgNb
5968 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
5973 else if (anArgIter + 3 < theArgNb
5974 && anArg == "-display")
5976 aViewName = theArgVec[++anArgIter];
5977 aPrsNameRef = theArgVec[++anArgIter];
5978 aPrsNameNew = theArgVec[++anArgIter];
5979 if (anArgIter + 1 < theArgNb
5980 && *theArgVec[anArgIter + 1] != '-')
5982 aPrsNameDiff = theArgVec[++anArgIter];
5985 else if (aTolColor < 0.0
5986 && anArg.IsRealValue (Standard_True))
5988 isOldSyntax = Standard_True;
5989 aTolColor = anArg.RealValue();
5990 if (aTolColor < 0.0 || aTolColor > 1.0)
5992 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
5996 else if (isOldSyntax
5997 && toBlackWhite == -1
5998 && (anArg == "0" || anArg == "1"))
6000 toBlackWhite = anArg == "1" ? 1 : 0;
6002 else if (isOldSyntax
6003 && isBorderFilterOn == -1
6004 && (anArg == "0" || anArg == "1"))
6006 isBorderFilterOn = anArg == "1" ? 1 : 0;
6008 else if (aDiffImagePath.IsEmpty())
6010 aDiffImagePath = theArgVec[anArgIter];
6014 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6019 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6020 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6021 if (!anImgRef->Load (anImgPathRef))
6023 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
6026 if (!anImgNew->Load (anImgPathNew))
6028 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
6032 // compare the images
6033 Image_Diff aComparer;
6034 Standard_Integer aDiffColorsNb = -1;
6035 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
6037 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6038 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6039 aDiffColorsNb = aComparer.Compare();
6040 theDI << aDiffColorsNb << "\n";
6043 // save image of difference
6044 Handle(Image_AlienPixMap) aDiff;
6045 if (aDiffColorsNb > 0
6046 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6048 aDiff = new Image_AlienPixMap();
6049 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6051 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
6054 aComparer.SaveDiffImage (*aDiff);
6055 if (!aDiffImagePath.IsEmpty()
6056 && !aDiff->Save (aDiffImagePath))
6058 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
6063 if (aViewName.IsEmpty())
6068 ViewerTest_Names aViewNames (aViewName);
6069 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6071 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6072 theDI.Eval (aCommand.ToCString());
6075 Standard_Integer aPxLeft = 0;
6076 Standard_Integer aPxTop = 0;
6077 Standard_Integer aWinSizeX = int(anImgRef->SizeX() * 2);
6078 Standard_Integer aWinSizeY = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6079 ? int(anImgRef->SizeY() * 2)
6080 : int(anImgRef->SizeY());
6081 TCollection_AsciiString aDisplayName;
6082 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aPxLeft, aPxTop, aWinSizeX, aWinSizeY,
6083 aViewName, aDisplayName);
6085 Standard_Real aRatio = anImgRef->Ratio();
6086 Standard_Real aSizeX = 1.0;
6087 Standard_Real aSizeY = aSizeX / aRatio;
6089 OSD_Path aPath (anImgPathRef);
6090 TCollection_AsciiString aLabelRef;
6091 if (!aPath.Name().IsEmpty())
6093 aLabelRef = aPath.Name() + aPath.Extension();
6095 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6097 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6099 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6100 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6101 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
6104 OSD_Path aPath (anImgPathNew);
6105 TCollection_AsciiString aLabelNew;
6106 if (!aPath.Name().IsEmpty())
6108 aLabelNew = aPath.Name() + aPath.Extension();
6110 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
6112 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6114 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6115 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6116 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6118 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6119 if (!aDiff.IsNull())
6121 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6123 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6124 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6126 if (!aPrsNameDiff.IsEmpty())
6128 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6130 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6131 ViewerTest::CurrentView()->FitAll();
6135 //=======================================================================
6136 //function : VSelect
6137 //purpose : Emulates different types of selection by mouse:
6138 // 1) single click selection
6139 // 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6140 // 3) selection with polygon having corners at
6141 // pixel positions (x1,y1),...,(xn,yn)
6142 // 4) any of these selections with shift button pressed
6143 //=======================================================================
6144 static Standard_Integer VSelect (Draw_Interpretor& ,
6145 Standard_Integer theNbArgs,
6146 const char** theArgVec)
6148 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6151 Message::SendFail ("Error: no active viewer");
6155 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
6156 bool toAllowOverlap = false;
6157 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
6158 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6160 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6162 if (anArg == "-allowoverlap")
6164 toAllowOverlap = true;
6165 if (anArgIter + 1 < theNbArgs
6166 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
6171 else if (anArg == "-replace")
6173 aSelScheme = AIS_SelectionScheme_Replace;
6175 else if (anArg == "-replaceextra")
6177 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6179 else if (anArg == "-xor"
6180 || anArg == "-shift")
6182 aSelScheme = AIS_SelectionScheme_XOR;
6184 else if (anArg == "-add")
6186 aSelScheme = AIS_SelectionScheme_Add;
6188 else if (anArg == "-remove")
6190 aSelScheme = AIS_SelectionScheme_Remove;
6192 else if (anArgIter + 1 < theNbArgs
6193 && anArg.IsIntegerValue()
6194 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
6196 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6197 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6199 else if (anArgIter + 1 == theNbArgs
6200 && anArg.IsIntegerValue())
6202 if (anArg.IntegerValue() == 1)
6204 aSelScheme = AIS_SelectionScheme_XOR;
6209 Message::SendFail() << "Syntax error at '" << anArg << "'";
6216 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
6219 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
6220 if (aPnts.IsEmpty())
6222 aCtx->SelectDetected (aSelScheme);
6223 aCtx->CurrentViewer()->Invalidate();
6225 else if (aPnts.Length() == 2)
6228 && aPnts.First().y() < aPnts.Last().y())
6230 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6232 else if (!toAllowOverlap
6233 && aPnts.First().y() > aPnts.Last().y())
6235 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6238 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6242 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6244 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
6248 //=======================================================================
6249 //function : VMoveTo
6250 //purpose : Emulates cursor movement to defined pixel position
6251 //=======================================================================
6252 static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
6253 Standard_Integer theNbArgs,
6254 const char** theArgVec)
6256 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6257 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6258 if (aContext.IsNull())
6260 Message::SendFail ("Error: no active viewer");
6264 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
6265 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6267 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6268 anArgStr.LowerCase();
6269 if (anArgStr == "-reset"
6270 || anArgStr == "-clear")
6272 if (anArgIter + 1 < theNbArgs)
6274 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
6278 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
6279 && aContext->CurrentViewer()->GridEcho();
6282 aContext->CurrentViewer()->HideGridEcho (aView);
6284 if (aContext->ClearDetected() || toEchoGrid)
6286 aContext->CurrentViewer()->RedrawImmediate();
6290 else if (aMousePos.x() == IntegerLast()
6291 && anArgStr.IsIntegerValue())
6293 aMousePos.x() = anArgStr.IntegerValue();
6295 else if (aMousePos.y() == IntegerLast()
6296 && anArgStr.IsIntegerValue())
6298 aMousePos.y() = anArgStr.IntegerValue();
6302 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6307 if (aMousePos.x() == IntegerLast()
6308 || aMousePos.y() == IntegerLast())
6310 Message::SendFail ("Syntax error: wrong number of arguments");
6314 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
6315 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
6316 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
6318 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
6319 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
6320 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
6322 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
6324 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
6328 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
6332 //=======================================================================
6333 //function : VSelectByAxis
6335 //=======================================================================
6336 static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
6337 Standard_Integer theNbArgs,
6338 const char** theArgVec)
6340 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6341 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6342 if (aContext.IsNull())
6344 Message::SendFail ("Error: no active viewer");
6348 TCollection_AsciiString aName;
6349 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
6350 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
6351 Standard_Boolean isOnlyTop = true;
6352 Standard_Boolean toShowNormal = false;
6353 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6355 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6356 anArgStr.LowerCase();
6357 if (anArgStr == "-display")
6359 if (anArgIter + 1 >= theNbArgs)
6361 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
6364 aName = theArgVec[++anArgIter];
6366 else if (anArgStr == "-onlytop")
6369 if (anArgIter + 1 < theNbArgs
6370 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
6375 else if (anArgStr == "-shownormal")
6377 toShowNormal = true;
6378 if (anArgIter + 1 < theNbArgs
6379 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
6384 else if (Precision::IsInfinite(anAxisLocation.X())
6385 && anArgStr.IsRealValue())
6387 anAxisLocation.SetX (anArgStr.RealValue());
6389 else if (Precision::IsInfinite(anAxisLocation.Y())
6390 && anArgStr.IsRealValue())
6392 anAxisLocation.SetY (anArgStr.RealValue());
6394 else if (Precision::IsInfinite(anAxisLocation.Z())
6395 && anArgStr.IsRealValue())
6397 anAxisLocation.SetZ (anArgStr.RealValue());
6399 else if (Precision::IsInfinite(anAxisDirection.X())
6400 && anArgStr.IsRealValue())
6402 anAxisDirection.SetX (anArgStr.RealValue());
6404 else if (Precision::IsInfinite(anAxisDirection.Y())
6405 && anArgStr.IsRealValue())
6407 anAxisDirection.SetY (anArgStr.RealValue());
6409 else if (Precision::IsInfinite(anAxisDirection.Z())
6410 && anArgStr.IsRealValue())
6412 anAxisDirection.SetZ (anArgStr.RealValue());
6416 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6421 if (Precision::IsInfinite (anAxisLocation.X()) ||
6422 Precision::IsInfinite (anAxisLocation.Y()) ||
6423 Precision::IsInfinite (anAxisLocation.Z()) ||
6424 Precision::IsInfinite (anAxisDirection.X()) ||
6425 Precision::IsInfinite (anAxisDirection.Y()) ||
6426 Precision::IsInfinite (anAxisDirection.Z()))
6428 Message::SendFail() << "Invalid axis location and direction";
6432 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
6434 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
6436 theDI << "There are no any intersections with this axis.";
6439 NCollection_Sequence<gp_Pnt> aPoints;
6440 NCollection_Sequence<Graphic3d_Vec3> aNormals;
6441 NCollection_Sequence<Standard_Real> aNormalLengths;
6442 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
6444 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
6445 aPoints.Append (aPickedData.Point);
6446 aNormals.Append (aPickedData.Normal);
6447 Standard_Real aNormalLength = 1.0;
6448 if (!aPickedData.Entity.IsNull())
6450 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
6452 aNormalLengths.Append (aNormalLength);
6454 if (!aName.IsEmpty())
6456 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
6457 aContext->SetAutoActivateSelection (false);
6460 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
6461 Handle(Geom_Axis2Placement) anAx2Axis =
6462 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
6463 Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
6464 anAISAxis->SetColor (anAxisColor);
6465 ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
6467 // Display axis start point
6468 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
6469 anAISStartPnt->SetMarker (Aspect_TOM_O);
6470 anAISStartPnt->SetColor (anAxisColor);
6471 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
6473 Standard_Integer anIndex = 0;
6474 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
6476 const gp_Pnt& aPoint = aPntIter.Value();
6478 // Display normals in intersection points
6481 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
6482 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
6483 if (aNormal.SquareModulus() > ShortRealEpsilon())
6485 gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
6486 Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
6487 anAISNormal->SetColor (Quantity_NOC_BLUE);
6488 anAISNormal->SetInfiniteState (false);
6489 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
6493 // Display intersection points
6494 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
6495 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
6496 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
6497 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
6498 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
6501 aContext->SetAutoActivateSelection (wasAuto);
6504 Standard_Integer anIndex = 0;
6505 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
6507 const gp_Pnt& aPnt = anIter.Value();
6508 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
6515 //! Global map storing all animations registered in ViewerTest.
6516 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
6518 //! The animation calling the Draw Harness command.
6519 class ViewerTest_AnimationProc : public AIS_Animation
6521 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
6524 //! Main constructor.
6525 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
6526 Draw_Interpretor* theDI,
6527 const TCollection_AsciiString& theCommand)
6528 : AIS_Animation (theAnimationName),
6530 myCommand (theCommand)
6537 //! Evaluate the command.
6538 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
6540 TCollection_AsciiString aCmd = myCommand;
6541 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
6542 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
6543 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
6544 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
6545 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
6546 myDrawInter->Eval (aCmd.ToCString());
6549 //! Find the keyword in the command and replace it with value.
6550 //! @return the position of the keyword to pass value
6551 void replace (TCollection_AsciiString& theCmd,
6552 const TCollection_AsciiString& theKey,
6553 const TCollection_AsciiString& theVal)
6555 TCollection_AsciiString aCmd (theCmd);
6557 const Standard_Integer aPos = aCmd.Search (theKey);
6563 TCollection_AsciiString aPart1, aPart2;
6564 Standard_Integer aPart1To = aPos - 1;
6566 && aPart1To <= theCmd.Length())
6568 aPart1 = theCmd.SubString (1, aPart1To);
6571 Standard_Integer aPart2From = aPos + theKey.Length();
6573 && aPart2From <= theCmd.Length())
6575 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
6578 theCmd = aPart1 + theVal + aPart2;
6583 Draw_Interpretor* myDrawInter;
6584 TCollection_AsciiString myCommand;
6588 //! Auxiliary animation holder.
6589 class ViewerTest_AnimationHolder : public AIS_AnimationCamera
6591 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
6593 ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
6594 const Handle(V3d_View)& theView,
6595 const Standard_Boolean theIsFreeView)
6596 : AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
6598 if (theAnim->Timer().IsNull())
6600 theAnim->SetTimer (new Media_Timer());
6602 myTimer = theAnim->Timer();
6606 myCamStart = new Graphic3d_Camera (theView->Camera());
6612 virtual void StartTimer (const Standard_Real theStartPts,
6613 const Standard_Real thePlaySpeed,
6614 const Standard_Boolean theToUpdate,
6615 const Standard_Boolean theToStopTimer) Standard_OVERRIDE
6617 base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
6624 //! Pause animation.
6625 virtual void Pause() Standard_OVERRIDE
6627 myState = AnimationState_Paused;
6628 // default implementation would stop all children,
6629 // but we want to keep wrapped animation paused
6630 myAnimations.First()->Pause();
6635 virtual void Stop() Standard_OVERRIDE
6641 //! Process one step of the animation according to the input time progress, including all children.
6642 virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
6644 Handle(V3d_View) aView = myView;
6646 && !myCamStart.IsNull())
6648 myCamStart->Copy (aView->Camera());
6650 base_type::updateWithChildren (thePosition);
6652 && !myCamStart.IsNull())
6654 aView->Camera()->Copy (myCamStart);
6658 void abortPlayback()
6660 if (!myView.IsNull())
6667 //! Replace the animation with the new one.
6668 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
6669 Handle(AIS_Animation)& theAnimation,
6670 const Handle(AIS_Animation)& theAnimationNew)
6672 theAnimationNew->CopyFrom (theAnimation);
6673 if (!theParentAnimation.IsNull())
6675 theParentAnimation->Replace (theAnimation, theAnimationNew);
6679 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
6680 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
6682 theAnimation = theAnimationNew;
6685 //! Parse the point.
6686 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
6688 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
6689 if (!anXYZ[0].IsRealValue (Standard_True)
6690 || !anXYZ[1].IsRealValue (Standard_True)
6691 || !anXYZ[2].IsRealValue (Standard_True))
6693 return Standard_False;
6696 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
6697 return Standard_True;
6700 //! Parse the quaternion.
6701 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
6703 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
6704 if (!anXYZW[0].IsRealValue (Standard_True)
6705 || !anXYZW[1].IsRealValue (Standard_True)
6706 || !anXYZW[2].IsRealValue (Standard_True)
6707 || !anXYZW[3].IsRealValue (Standard_True))
6709 return Standard_False;
6712 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
6713 return Standard_True;
6716 //! Auxiliary class for flipping image upside-down.
6721 //! Empty constructor.
6722 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
6724 //! Perform flipping.
6725 Standard_Boolean FlipY (Image_PixMap& theImage)
6727 if (theImage.IsEmpty()
6728 || theImage.SizeX() == 0
6729 || theImage.SizeY() == 0)
6731 return Standard_False;
6734 const Standard_Size aRowSize = theImage.SizeRowBytes();
6735 if (myTmp.Size() < aRowSize
6736 && !myTmp.Allocate (aRowSize))
6738 return Standard_False;
6741 // for odd height middle row should be left as is
6742 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
6743 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
6745 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
6746 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
6747 memcpy (myTmp.ChangeData(), aTop, aRowSize);
6748 memcpy (aTop, aBot, aRowSize);
6749 memcpy (aBot, myTmp.Data(), aRowSize);
6751 return Standard_True;
6755 NCollection_Buffer myTmp;
6760 //=================================================================================================
6761 //function : VViewParams
6762 //purpose : Gets or sets AIS View characteristics
6763 //=================================================================================================
6764 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6766 Handle(V3d_View) aView = ViewerTest::CurrentView();
6769 Message::SendFail ("Error: no active viewer");
6773 Standard_Boolean toSetProj = Standard_False;
6774 Standard_Boolean toSetUp = Standard_False;
6775 Standard_Boolean toSetAt = Standard_False;
6776 Standard_Boolean toSetEye = Standard_False;
6777 Standard_Boolean toSetScale = Standard_False;
6778 Standard_Boolean toSetSize = Standard_False;
6779 Standard_Boolean toSetCenter2d = Standard_False;
6780 Standard_Real aViewScale = aView->Scale();
6781 Standard_Real aViewAspect = aView->Camera()->Aspect();
6782 Standard_Real aViewSize = 1.0;
6783 Graphic3d_Vec2i aCenter2d;
6784 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
6785 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
6786 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
6787 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
6788 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
6789 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
6790 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
6793 // print all of the available view parameters
6798 "Proj: %12g %12g %12g\n"
6799 "Up: %12g %12g %12g\n"
6800 "At: %12g %12g %12g\n"
6801 "Eye: %12g %12g %12g\n"
6802 "OrientMat: %12g %12g %12g %12g\n"
6803 " %12g %12g %12g %12g\n"
6804 " %12g %12g %12g %12g\n"
6805 " %12g %12g %12g %12g\n"
6806 "ProjMat: %12g %12g %12g %12g\n"
6807 " %12g %12g %12g %12g\n"
6808 " %12g %12g %12g %12g\n"
6809 " %12g %12g %12g %12g\n",
6810 aViewScale, aViewAspect,
6811 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6812 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6813 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
6814 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
6815 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
6816 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
6817 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
6818 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
6819 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
6820 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
6821 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
6822 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
6827 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
6828 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6830 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6832 if (anUpdateTool.parseRedrawMode (anArg))
6836 else if (anArg == "-cmd"
6837 || anArg == "-command"
6838 || anArg == "-args")
6847 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6848 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6849 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
6852 else if (anArg == "-scale"
6853 || anArg == "-size")
6855 if (anArgIter + 1 < theArgsNb
6856 && *theArgVec[anArgIter + 1] != '-')
6858 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
6859 if (aValueArg.IsRealValue (Standard_True))
6862 if (anArg == "-scale")
6864 toSetScale = Standard_True;
6865 aViewScale = aValueArg.RealValue();
6867 else if (anArg == "-size")
6869 toSetSize = Standard_True;
6870 aViewSize = aValueArg.RealValue();
6875 if (anArg == "-scale")
6877 theDi << "Scale: " << aView->Scale() << "\n";
6879 else if (anArg == "-size")
6881 Graphic3d_Vec2d aSizeXY;
6882 aView->Size (aSizeXY.x(), aSizeXY.y());
6883 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
6886 else if (anArg == "-eye"
6889 || anArg == "-proj")
6891 if (anArgIter + 3 < theArgsNb)
6894 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
6897 if (anArg == "-eye")
6899 toSetEye = Standard_True;
6902 else if (anArg == "-at")
6904 toSetAt = Standard_True;
6907 else if (anArg == "-up")
6909 toSetUp = Standard_True;
6912 else if (anArg == "-proj")
6914 toSetProj = Standard_True;
6921 if (anArg == "-eye")
6923 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
6925 else if (anArg == "-at")
6927 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
6929 else if (anArg == "-up")
6931 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
6933 else if (anArg == "-proj")
6935 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
6938 else if (anArg == "-center")
6940 if (anArgIter + 2 < theArgsNb)
6942 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
6943 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
6944 if (anX.IsIntegerValue()
6945 && anY.IsIntegerValue())
6947 toSetCenter2d = Standard_True;
6948 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
6954 Message::SendFail() << "Syntax error at '" << anArg << "'";
6959 // change view parameters in proper order
6962 aView->SetScale (aViewScale);
6966 aView->SetSize (aViewSize);
6970 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
6974 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
6978 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
6982 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
6986 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
6992 //==============================================================================
6993 //function : V2DMode
6995 //==============================================================================
6996 static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
6998 bool is2dMode = true;
6999 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7000 if (aV3dView.IsNull())
7002 Message::SendFail ("Error: no active viewer");
7005 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7007 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7008 TCollection_AsciiString anArgCase = anArg;
7009 anArgCase.LowerCase();
7010 if (anArgIt + 1 < theArgsNb
7011 && anArgCase == "-name")
7013 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7014 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7015 if (!ViewerTest_myViews.IsBound1 (aViewName))
7017 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
7020 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7022 else if (anArgCase == "-mode")
7024 if (anArgIt + 1 < theArgsNb
7025 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
7030 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
7036 Message::SendFail() << "Syntax error: unknown argument " << anArg;
7041 aV3dView->SetView2DMode (is2dMode);
7045 //==============================================================================
7046 //function : VAnimation
7048 //==============================================================================
7049 static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7050 Standard_Integer theArgNb,
7051 const char** theArgVec)
7053 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7056 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7057 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7059 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
7065 Message::SendFail ("Error: no active viewer");
7069 Standard_Integer anArgIter = 1;
7070 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7071 if (aNameArg.IsEmpty())
7073 Message::SendFail ("Syntax error: animation name is not defined");
7077 TCollection_AsciiString aNameArgLower = aNameArg;
7078 aNameArgLower.LowerCase();
7079 if (aNameArgLower == "-reset"
7080 || aNameArgLower == "-clear")
7082 ViewerTest_AnimationTimelineMap.Clear();
7085 else if (aNameArg.Value (1) == '-')
7087 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
7091 const char* aNameSplitter = "/";
7092 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7093 if (aSplitPos == -1)
7095 aNameSplitter = ".";
7096 aSplitPos = aNameArg.Search (aNameSplitter);
7099 // find existing or create a new animation by specified name within syntax "parent.child".
7100 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7101 for (; !aNameArg.IsEmpty();)
7103 TCollection_AsciiString aNameParent;
7104 if (aSplitPos != -1)
7106 if (aSplitPos == aNameArg.Length())
7108 Message::SendFail ("Syntax error: animation name is not defined");
7112 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7113 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7115 aSplitPos = aNameArg.Search (aNameSplitter);
7119 aNameParent = aNameArg;
7123 if (anAnimation.IsNull())
7125 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7127 anAnimation = new AIS_Animation (aNameParent);
7128 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7130 aRootAnimation = anAnimation;
7134 aParentAnimation = anAnimation;
7135 anAnimation = aParentAnimation->Find (aNameParent);
7136 if (anAnimation.IsNull())
7138 anAnimation = new AIS_Animation (aNameParent);
7139 aParentAnimation->Add (anAnimation);
7143 if (anAnimation.IsNull())
7145 Message::SendFail() << "Syntax error: wrong number of arguments";
7149 if (anArgIter >= theArgNb)
7151 // just print the list of children
7152 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
7154 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
7159 // animation parameters
7160 Standard_Boolean toPlay = Standard_False;
7161 Standard_Real aPlaySpeed = 1.0;
7162 Standard_Real aPlayStartTime = anAnimation->StartPts();
7163 Standard_Real aPlayDuration = anAnimation->Duration();
7164 Standard_Boolean isFreeCamera = Standard_False;
7165 Standard_Boolean toPauseOnClick = Standard_True;
7166 Standard_Boolean isLockLoop = Standard_False;
7168 // video recording parameters
7169 TCollection_AsciiString aRecFile;
7170 Image_VideoParams aRecParams;
7172 Handle(V3d_View) aView = ViewerTest::CurrentView();
7173 for (; anArgIter < theArgNb; ++anArgIter)
7175 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7178 if (anArg == "-reset"
7179 || anArg == "-clear")
7181 anAnimation->Clear();
7183 else if (anArg == "-remove"
7185 || anArg == "-delete")
7187 if (aParentAnimation.IsNull())
7189 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7193 aParentAnimation->Remove (anAnimation);
7197 else if (anArg == "-play")
7199 toPlay = Standard_True;
7200 if (++anArgIter < theArgNb)
7202 if (*theArgVec[anArgIter] == '-')
7207 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7209 if (++anArgIter < theArgNb)
7211 if (*theArgVec[anArgIter] == '-')
7216 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7220 else if (anArg == "-resume")
7222 toPlay = Standard_True;
7223 aPlayStartTime = anAnimation->ElapsedTime();
7224 if (++anArgIter < theArgNb)
7226 if (*theArgVec[anArgIter] == '-')
7232 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7235 else if (anArg == "-pause")
7237 anAnimation->Pause();
7239 else if (anArg == "-stop")
7241 anAnimation->Stop();
7243 else if (anArg == "-playspeed"
7244 || anArg == "-speed")
7246 if (++anArgIter >= theArgNb)
7248 Message::SendFail() << "Syntax error at " << anArg << "";
7251 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7253 else if (anArg == "-lock"
7254 || anArg == "-lockloop"
7255 || anArg == "-playlockloop")
7257 isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
7259 else if (anArg == "-freecamera"
7260 || anArg == "-nofreecamera"
7261 || anArg == "-playfreecamera"
7262 || anArg == "-noplayfreecamera"
7263 || anArg == "-freelook"
7264 || anArg == "-nofreelook")
7266 isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7268 else if (anArg == "-pauseonclick"
7269 || anArg == "-nopauseonclick"
7270 || anArg == "-nopause")
7272 toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7274 // video recodring options
7275 else if (anArg == "-rec"
7276 || anArg == "-record")
7278 if (++anArgIter >= theArgNb)
7280 Message::SendFail() << "Syntax error at " << anArg;
7284 aRecFile = theArgVec[anArgIter];
7285 if (aRecParams.FpsNum <= 0)
7287 aRecParams.FpsNum = 24;
7290 if (anArgIter + 2 < theArgNb
7291 && *theArgVec[anArgIter + 1] != '-'
7292 && *theArgVec[anArgIter + 2] != '-')
7294 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7295 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7296 if (aWidthArg .IsIntegerValue()
7297 && aHeightArg.IsIntegerValue())
7299 aRecParams.Width = aWidthArg .IntegerValue();
7300 aRecParams.Height = aHeightArg.IntegerValue();
7305 else if (anArg == "-fps")
7307 if (++anArgIter >= theArgNb)
7309 Message::SendFail() << "Syntax error at " << anArg;
7313 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7314 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7315 if (aSplitIndex == 0)
7317 aRecParams.FpsNum = aFpsArg.IntegerValue();
7321 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7322 aFpsArg.Split (aFpsArg.Length() - 1);
7323 const TCollection_AsciiString aNumStr = aFpsArg;
7324 aRecParams.FpsNum = aNumStr.IntegerValue();
7325 aRecParams.FpsDen = aDenStr.IntegerValue();
7326 if (aRecParams.FpsDen < 1)
7328 Message::SendFail() << "Syntax error at " << anArg;
7333 else if (anArg == "-format")
7335 if (++anArgIter >= theArgNb)
7337 Message::SendFail() << "Syntax error at " << anArg;
7340 aRecParams.Format = theArgVec[anArgIter];
7342 else if (anArg == "-pix_fmt"
7343 || anArg == "-pixfmt"
7344 || anArg == "-pixelformat")
7346 if (++anArgIter >= theArgNb)
7348 Message::SendFail() << "Syntax error at " << anArg;
7351 aRecParams.PixelFormat = theArgVec[anArgIter];
7353 else if (anArg == "-codec"
7354 || anArg == "-vcodec"
7355 || anArg == "-videocodec")
7357 if (++anArgIter >= theArgNb)
7359 Message::SendFail() << "Syntax error at " << anArg;
7362 aRecParams.VideoCodec = theArgVec[anArgIter];
7364 else if (anArg == "-crf"
7365 || anArg == "-preset"
7368 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
7369 if (++anArgIter >= theArgNb)
7371 Message::SendFail() << "Syntax error at " << anArg;
7375 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
7377 // animation definition options
7378 else if (anArg == "-start"
7379 || anArg == "-starttime"
7380 || anArg == "-startpts")
7382 if (++anArgIter >= theArgNb)
7384 Message::SendFail() << "Syntax error at " << anArg;
7388 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
7389 aRootAnimation->UpdateTotalDuration();
7391 else if (anArg == "-end"
7392 || anArg == "-endtime"
7393 || anArg == "-endpts")
7395 if (++anArgIter >= theArgNb)
7397 Message::SendFail() << "Syntax error at " << anArg;
7401 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
7402 aRootAnimation->UpdateTotalDuration();
7404 else if (anArg == "-dur"
7405 || anArg == "-duration")
7407 if (++anArgIter >= theArgNb)
7409 Message::SendFail() << "Syntax error at " << anArg;
7413 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
7414 aRootAnimation->UpdateTotalDuration();
7416 else if (anArg == "-command"
7418 || anArg == "-invoke"
7420 || anArg == "-proc")
7422 if (++anArgIter >= theArgNb)
7424 Message::SendFail() << "Syntax error at " << anArg;
7428 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
7429 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
7431 else if (anArg == "-objecttrsf"
7432 || anArg == "-objectransformation"
7433 || anArg == "-objtransformation"
7434 || anArg == "-objtrsf"
7435 || anArg == "-object"
7438 if (++anArgIter >= theArgNb)
7440 Message::SendFail() << "Syntax error at " << anArg;
7444 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
7445 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
7446 Handle(AIS_InteractiveObject) anObject;
7447 if (!aMapOfAIS.Find2 (anObjName, anObject))
7449 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
7453 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
7454 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
7455 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
7456 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
7457 Standard_Boolean isTrsfSet = Standard_False;
7458 Standard_Integer aTrsfArgIter = anArgIter + 1;
7459 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
7461 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
7462 aTrsfArg.LowerCase();
7463 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
7464 if (aTrsfArg.StartsWith ("-rotation")
7465 || aTrsfArg.StartsWith ("-rot"))
7467 isTrsfSet = Standard_True;
7468 if (aTrsfArgIter + 4 >= theArgNb
7469 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
7471 Message::SendFail() << "Syntax error at " << aTrsfArg;
7476 else if (aTrsfArg.StartsWith ("-location")
7477 || aTrsfArg.StartsWith ("-loc"))
7479 isTrsfSet = Standard_True;
7480 if (aTrsfArgIter + 3 >= theArgNb
7481 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
7483 Message::SendFail() << "Syntax error at " << aTrsfArg;
7488 else if (aTrsfArg.StartsWith ("-scale"))
7490 isTrsfSet = Standard_True;
7491 if (++aTrsfArgIter >= theArgNb)
7493 Message::SendFail() << "Syntax error at " << aTrsfArg;
7497 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
7498 if (!aScaleStr.IsRealValue (Standard_True))
7500 Message::SendFail() << "Syntax error at " << aTrsfArg;
7503 aScales[anIndex] = aScaleStr.RealValue();
7507 anArgIter = aTrsfArgIter - 1;
7513 Message::SendFail() << "Syntax error at " << anArg;
7516 else if (aTrsfArgIter >= theArgNb)
7518 anArgIter = theArgNb;
7521 aTrsfs[0].SetRotation (aRotQuats[0]);
7522 aTrsfs[1].SetRotation (aRotQuats[1]);
7523 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
7524 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
7525 aTrsfs[0].SetScaleFactor (aScales[0]);
7526 aTrsfs[1].SetScaleFactor (aScales[1]);
7528 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
7529 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
7531 else if (anArg == "-viewtrsf"
7532 || anArg == "-view")
7534 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
7535 if (aCamAnimation.IsNull())
7537 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
7538 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
7541 Handle(Graphic3d_Camera) aCams[2] =
7543 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
7544 new Graphic3d_Camera (aCamAnimation->View()->Camera())
7547 Standard_Boolean isTrsfSet = Standard_False;
7548 Standard_Integer aViewArgIter = anArgIter + 1;
7549 for (; aViewArgIter < theArgNb; ++aViewArgIter)
7551 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
7552 aViewArg.LowerCase();
7553 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
7554 if (aViewArg.StartsWith ("-scale"))
7556 isTrsfSet = Standard_True;
7557 if (++aViewArgIter >= theArgNb)
7559 Message::SendFail() << "Syntax error at " << anArg;
7563 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
7564 if (!aScaleStr.IsRealValue (Standard_True))
7566 Message::SendFail() << "Syntax error at " << aViewArg;
7569 Standard_Real aScale = aScaleStr.RealValue();
7570 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
7571 aCams[anIndex]->SetScale (aScale);
7573 else if (aViewArg.StartsWith ("-eye")
7574 || aViewArg.StartsWith ("-center")
7575 || aViewArg.StartsWith ("-at")
7576 || aViewArg.StartsWith ("-up"))
7578 isTrsfSet = Standard_True;
7580 if (aViewArgIter + 3 >= theArgNb
7581 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
7583 Message::SendFail() << "Syntax error at " << aViewArg;
7588 if (aViewArg.StartsWith ("-eye"))
7590 aCams[anIndex]->SetEye (anXYZ);
7592 else if (aViewArg.StartsWith ("-center")
7593 || aViewArg.StartsWith ("-at"))
7595 aCams[anIndex]->SetCenter (anXYZ);
7597 else if (aViewArg.StartsWith ("-up"))
7599 aCams[anIndex]->SetUp (anXYZ);
7604 anArgIter = aViewArgIter - 1;
7610 Message::SendFail() << "Syntax error at " << anArg;
7613 else if (aViewArgIter >= theArgNb)
7615 anArgIter = theArgNb;
7618 aCamAnimation->SetCameraStart(aCams[0]);
7619 aCamAnimation->SetCameraEnd (aCams[1]);
7623 Message::SendFail() << "Syntax error at " << anArg;
7628 ViewerTest::CurrentEventManager()->AbortViewAnimation();
7629 ViewerTest::CurrentEventManager()->SetObjectsAnimation (Handle(AIS_Animation)());
7630 if (!toPlay && aRecFile.IsEmpty())
7635 // Start animation timeline and process frame updating.
7636 if (aRecParams.FpsNum <= 0
7639 Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
7640 aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7641 ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
7642 ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
7643 ViewerTest::CurrentEventManager()->ProcessExpose();
7647 // Perform video recording
7648 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
7649 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
7650 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7652 OSD_Timer aPerfTimer;
7655 Handle(Image_VideoRecorder) aRecorder;
7656 ImageFlipper aFlipper;
7657 Handle(Draw_ProgressIndicator) aProgress;
7658 if (!aRecFile.IsEmpty())
7660 if (aRecParams.Width <= 0
7661 || aRecParams.Height <= 0)
7663 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
7666 aRecorder = new Image_VideoRecorder();
7667 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
7669 Message::SendFail ("Error: failed to open video file for recording");
7673 aProgress = new Draw_ProgressIndicator (theDI, 1);
7676 // Manage frame-rated animation here
7677 Standard_Real aPts = aPlayStartTime;
7678 int64_t aNbFrames = 0;
7679 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
7680 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
7681 Standard_Integer aSecondsProgress = 0;
7682 for (; aPts <= anUpperPts && aPS.More();)
7684 Standard_Real aRecPts = 0.0;
7685 if (aRecParams.FpsNum > 0)
7687 aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
7691 aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
7694 aPts = aPlayStartTime + aRecPts;
7696 if (!anAnimation->Update (aPts))
7701 if (!aRecorder.IsNull())
7703 V3d_ImageDumpOptions aDumpParams;
7704 aDumpParams.Width = aRecParams.Width;
7705 aDumpParams.Height = aRecParams.Height;
7706 aDumpParams.BufferType = Graphic3d_BT_RGBA;
7707 aDumpParams.StereoOptions = V3d_SDO_MONO;
7708 aDumpParams.ToAdjustAspect = Standard_True;
7709 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
7711 Message::SendFail ("Error: view dump is failed");
7714 aFlipper.FlipY (aRecorder->ChangeFrame());
7715 if (!aRecorder->PushFrame())
7725 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
7733 anAnimation->Stop();
7734 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
7735 theDI << "Average FPS: " << aRecFps << "\n"
7736 << "Nb. Frames: " << Standard_Real(aNbFrames);
7739 aView->SetImmediateUpdate (wasImmediateUpdate);
7744 //=======================================================================
7745 //function : VChangeSelected
7746 //purpose : Adds the shape to selection or remove one from it
7747 //=======================================================================
7748 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
7749 Standard_Integer argc,
7754 di<<"Usage : " << argv[0] << " shape \n";
7758 TCollection_AsciiString aName(argv[1]);
7759 Handle(AIS_InteractiveObject) anAISObject;
7760 if (!GetMapOfAIS().Find2 (aName, anAISObject)
7761 || anAISObject.IsNull())
7763 di<<"Use 'vdisplay' before";
7767 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
7771 //=======================================================================
7772 //function : VNbSelected
7773 //purpose : Returns number of selected objects
7774 //=======================================================================
7775 static Standard_Integer VNbSelected (Draw_Interpretor& di,
7776 Standard_Integer argc,
7781 di << "Usage : " << argv[0] << "\n";
7784 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7785 if(aContext.IsNull())
7787 di << "use 'vinit' command before " << argv[0] << "\n";
7790 di << aContext->NbSelected() << "\n";
7794 //=======================================================================
7795 //function : VSetViewSize
7797 //=======================================================================
7798 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
7799 Standard_Integer argc,
7802 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7803 if(aContext.IsNull())
7805 di << "use 'vinit' command before " << argv[0] << "\n";
7810 di<<"Usage : " << argv[0] << " Size\n";
7813 Standard_Real aSize = Draw::Atof (argv[1]);
7816 di<<"Bad Size value : " << aSize << "\n";
7820 Handle(V3d_View) aView = ViewerTest::CurrentView();
7821 aView->SetSize(aSize);
7825 //=======================================================================
7826 //function : VMoveView
7828 //=======================================================================
7829 static Standard_Integer VMoveView (Draw_Interpretor& di,
7830 Standard_Integer argc,
7833 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7834 if(aContext.IsNull())
7836 di << "use 'vinit' command before " << argv[0] << "\n";
7839 if(argc < 4 || argc > 5)
7841 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
7844 Standard_Real Dx = Draw::Atof (argv[1]);
7845 Standard_Real Dy = Draw::Atof (argv[2]);
7846 Standard_Real Dz = Draw::Atof (argv[3]);
7847 Standard_Boolean aStart = Standard_True;
7850 aStart = (Draw::Atoi (argv[4]) > 0);
7853 Handle(V3d_View) aView = ViewerTest::CurrentView();
7854 aView->Move(Dx,Dy,Dz,aStart);
7858 //=======================================================================
7859 //function : VTranslateView
7861 //=======================================================================
7862 static Standard_Integer VTranslateView (Draw_Interpretor& di,
7863 Standard_Integer argc,
7866 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7867 if(aContext.IsNull())
7869 di << "use 'vinit' command before " << argv[0] << "\n";
7872 if(argc < 4 || argc > 5)
7874 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
7877 Standard_Real Dx = Draw::Atof (argv[1]);
7878 Standard_Real Dy = Draw::Atof (argv[2]);
7879 Standard_Real Dz = Draw::Atof (argv[3]);
7880 Standard_Boolean aStart = Standard_True;
7883 aStart = (Draw::Atoi (argv[4]) > 0);
7886 Handle(V3d_View) aView = ViewerTest::CurrentView();
7887 aView->Translate(Dx,Dy,Dz,aStart);
7891 //=======================================================================
7892 //function : VTurnView
7894 //=======================================================================
7895 static Standard_Integer VTurnView (Draw_Interpretor& di,
7896 Standard_Integer argc,
7899 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7900 if(aContext.IsNull()) {
7901 di << "use 'vinit' command before " << argv[0] << "\n";
7904 if(argc < 4 || argc > 5){
7905 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
7908 Standard_Real Ax = Draw::Atof (argv[1]);
7909 Standard_Real Ay = Draw::Atof (argv[2]);
7910 Standard_Real Az = Draw::Atof (argv[3]);
7911 Standard_Boolean aStart = Standard_True;
7914 aStart = (Draw::Atoi (argv[4]) > 0);
7917 Handle(V3d_View) aView = ViewerTest::CurrentView();
7918 aView->Turn(Ax,Ay,Az,aStart);
7922 //==============================================================================
7923 //function : VTextureEnv
7924 //purpose : ENables or disables environment mapping
7925 //==============================================================================
7926 class OCC_TextureEnv : public Graphic3d_TextureEnv
7929 OCC_TextureEnv(const Standard_CString FileName);
7930 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
7931 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
7932 const Standard_Boolean theModulateFlag,
7933 const Graphic3d_TypeOfTextureFilter theFilter,
7934 const Standard_ShortReal theXScale,
7935 const Standard_ShortReal theYScale,
7936 const Standard_ShortReal theXShift,
7937 const Standard_ShortReal theYShift,
7938 const Standard_ShortReal theAngle);
7939 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
7941 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
7943 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
7944 : Graphic3d_TextureEnv(theFileName)
7948 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
7949 : Graphic3d_TextureEnv(theTexId)
7953 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
7954 const Standard_Boolean theModulateFlag,
7955 const Graphic3d_TypeOfTextureFilter theFilter,
7956 const Standard_ShortReal theXScale,
7957 const Standard_ShortReal theYScale,
7958 const Standard_ShortReal theXShift,
7959 const Standard_ShortReal theYShift,
7960 const Standard_ShortReal theAngle)
7962 myParams->SetRepeat (theRepeatFlag);
7963 myParams->SetModulate (theModulateFlag);
7964 myParams->SetFilter (theFilter);
7965 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
7966 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
7967 myParams->SetRotation (theAngle);
7970 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
7972 // get the active view
7973 Handle(V3d_View) aView = ViewerTest::CurrentView();
7976 Message::SendFail ("Error: no active viewer");
7980 // Checking the input arguments
7981 Standard_Boolean anEnableFlag = Standard_False;
7982 Standard_Boolean isOk = theArgNb >= 2;
7985 TCollection_AsciiString anEnableOpt(theArgVec[1]);
7986 anEnableFlag = anEnableOpt.IsEqual("on");
7987 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
7991 isOk = (theArgNb == 3 || theArgNb == 11);
7994 TCollection_AsciiString aTextureOpt(theArgVec[2]);
7995 isOk = (!aTextureOpt.IsIntegerValue() ||
7996 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
7998 if (isOk && theArgNb == 11)
8000 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8001 aModulateOpt(theArgVec[4]),
8002 aFilterOpt (theArgVec[5]),
8003 aSScaleOpt (theArgVec[6]),
8004 aTScaleOpt (theArgVec[7]),
8005 aSTransOpt (theArgVec[8]),
8006 aTTransOpt (theArgVec[9]),
8007 anAngleOpt (theArgVec[10]);
8008 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8009 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8010 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
8011 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8012 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8013 anAngleOpt.IsRealValue (Standard_True));
8020 Message::SendFail() << "Usage:\n"
8021 << theArgVec[0] << " off\n"
8022 << 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]";
8028 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8029 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8030 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8031 new OCC_TextureEnv(theArgVec[2]);
8035 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8036 aTexEnv->SetTextureParameters(
8037 aRepeatOpt. IsEqual("repeat"),
8038 aModulateOpt.IsEqual("modulate"),
8039 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8040 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8041 Graphic3d_TOTF_TRILINEAR,
8042 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8043 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8044 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8045 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8046 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8049 aView->SetTextureEnv(aTexEnv);
8051 else // Disabling environment mapping
8053 Handle(Graphic3d_TextureEnv) aTexture;
8054 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8063 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8065 //! Remove registered clipping plane from all views and objects.
8066 static void removePlane (MapOfPlanes& theRegPlanes,
8067 const TCollection_AsciiString& theName)
8069 Handle(Graphic3d_ClipPlane) aClipPlane;
8070 if (!theRegPlanes.Find (theName, aClipPlane))
8072 Message::SendWarning ("Warning: no such plane");
8076 theRegPlanes.UnBind (theName);
8077 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8078 anIObjIt.More(); anIObjIt.Next())
8080 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
8081 aPrs->RemoveClipPlane (aClipPlane);
8084 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8085 aViewIt.More(); aViewIt.Next())
8087 const Handle(V3d_View)& aView = aViewIt.Key2();
8088 aView->RemoveClipPlane(aClipPlane);
8091 ViewerTest::RedrawAllViews();
8095 //===============================================================================================
8096 //function : VClipPlane
8098 //===============================================================================================
8099 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8101 // use short-cut for created clip planes map of created (or "registered by name") clip planes
8102 static MapOfPlanes aRegPlanes;
8106 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8108 theDi << aPlaneIter.Key() << " ";
8113 TCollection_AsciiString aCommand (theArgVec[1]);
8114 aCommand.LowerCase();
8115 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8116 if (anActiveView.IsNull())
8118 Message::SendFail ("Error: no active viewer");
8122 // print maximum number of planes for current viewer
8123 if (aCommand == "-maxplanes"
8124 || aCommand == "maxplanes")
8126 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8127 << " plane slots provided by driver.\n";
8131 // create / delete plane instance
8132 if (aCommand == "-create"
8133 || aCommand == "create"
8134 || aCommand == "-delete"
8135 || aCommand == "delete"
8136 || aCommand == "-clone"
8137 || aCommand == "clone")
8141 Message::SendFail ("Syntax error: plane name is required");
8145 Standard_Boolean toCreate = aCommand == "-create"
8146 || aCommand == "create";
8147 Standard_Boolean toClone = aCommand == "-clone"
8148 || aCommand == "clone";
8149 Standard_Boolean toDelete = aCommand == "-delete"
8150 || aCommand == "delete";
8151 TCollection_AsciiString aPlane (theArgVec[2]);
8155 if (aRegPlanes.IsBound (aPlane))
8157 std::cout << "Warning: existing plane has been overridden.\n";
8162 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8166 else if (toClone) // toClone
8168 if (!aRegPlanes.IsBound (aPlane))
8170 Message::SendFail ("Error: no such plane");
8173 else if (theArgsNb < 4)
8175 Message::SendFail ("Syntax error: enter name for new plane");
8179 TCollection_AsciiString aClone (theArgVec[3]);
8180 if (aRegPlanes.IsBound (aClone))
8182 Message::SendFail ("Error: plane name is in use");
8186 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8188 aRegPlanes.Bind (aClone, aClipPlane->Clone());
8198 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8200 aPlane = aPlaneIter.Key();
8201 removePlane (aRegPlanes, aPlane);
8202 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8207 removePlane (aRegPlanes, aPlane);
8213 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8218 // set / unset plane command
8219 if (aCommand == "set"
8220 || aCommand == "unset")
8224 Message::SendFail ("Syntax error: need more arguments");
8228 // redirect to new syntax
8229 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8230 anArgVec.SetValue (1, theArgVec[0]);
8231 anArgVec.SetValue (2, theArgVec[2]);
8232 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8233 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
8235 anArgVec.SetValue (anIt, theArgVec[anIt]);
8238 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
8241 // change plane command
8242 TCollection_AsciiString aPlaneName;
8243 Handle(Graphic3d_ClipPlane) aClipPlane;
8244 Standard_Integer anArgIter = 0;
8245 if (aCommand == "-change"
8246 || aCommand == "change")
8248 // old syntax support
8251 Message::SendFail ("Syntax error: need more arguments");
8256 aPlaneName = theArgVec[2];
8257 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
8259 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
8263 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8266 aPlaneName = theArgVec[1];
8271 aPlaneName = theArgVec[1];
8272 aClipPlane = new Graphic3d_ClipPlane();
8273 aRegPlanes.Bind (aPlaneName, aClipPlane);
8274 theDi << "Created new plane " << aPlaneName << ".\n";
8277 if (theArgsNb - anArgIter < 1)
8279 Message::SendFail ("Syntax error: need more arguments");
8283 for (; anArgIter < theArgsNb; ++anArgIter)
8285 const char** aChangeArgs = theArgVec + anArgIter;
8286 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8287 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
8288 aChangeArg.LowerCase();
8290 Standard_Boolean toEnable = Standard_True;
8291 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
8293 aClipPlane->SetOn (toEnable);
8295 else if (aChangeArg.StartsWith ("-equation")
8296 || aChangeArg.StartsWith ("equation"))
8298 if (aNbChangeArgs < 5)
8300 Message::SendFail ("Syntax error: need more arguments");
8304 Standard_Integer aSubIndex = 1;
8305 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
8306 if (aPrefixLen < aChangeArg.Length())
8308 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
8309 if (!aSubStr.IsIntegerValue()
8310 || aSubStr.IntegerValue() <= 0)
8312 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8315 aSubIndex = aSubStr.IntegerValue();
8318 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
8319 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
8320 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
8321 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
8322 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8323 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
8325 if (aSubPln->ChainNextPlane().IsNull())
8327 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8329 aSubPln = aSubPln->ChainNextPlane();
8331 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8332 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
8335 else if ((aChangeArg == "-boxinterior"
8336 || aChangeArg == "-boxint"
8337 || aChangeArg == "-box")
8338 && aNbChangeArgs >= 7)
8340 Graphic3d_BndBox3d aBndBox;
8341 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
8342 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
8345 Standard_Integer aNbSubPlanes = 6;
8346 const Graphic3d_Vec3d aDirArray[6] =
8348 Graphic3d_Vec3d (-1, 0, 0),
8349 Graphic3d_Vec3d ( 1, 0, 0),
8350 Graphic3d_Vec3d ( 0,-1, 0),
8351 Graphic3d_Vec3d ( 0, 1, 0),
8352 Graphic3d_Vec3d ( 0, 0,-1),
8353 Graphic3d_Vec3d ( 0, 0, 1),
8355 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8356 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
8358 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
8359 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
8360 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
8361 if (aSubPlaneIter + 1 == aNbSubPlanes)
8363 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8367 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8369 aSubPln = aSubPln->ChainNextPlane();
8372 else if (aChangeArg == "-capping"
8373 || aChangeArg == "capping")
8375 if (aNbChangeArgs < 2)
8377 Message::SendFail ("Syntax error: need more arguments");
8381 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8383 aClipPlane->SetCapping (toEnable);
8388 // just skip otherwise (old syntax)
8391 else if (aChangeArg == "-useobjectmaterial"
8392 || aChangeArg == "-useobjectmat"
8393 || aChangeArg == "-useobjmat"
8394 || aChangeArg == "-useobjmaterial")
8396 if (aNbChangeArgs < 2)
8398 Message::SendFail ("Syntax error: need more arguments");
8402 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8404 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
8408 else if (aChangeArg == "-useobjecttexture"
8409 || aChangeArg == "-useobjecttex"
8410 || aChangeArg == "-useobjtexture"
8411 || aChangeArg == "-useobjtex")
8413 if (aNbChangeArgs < 2)
8415 Message::SendFail ("Syntax error: need more arguments");
8419 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8421 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
8425 else if (aChangeArg == "-useobjectshader"
8426 || aChangeArg == "-useobjshader")
8428 if (aNbChangeArgs < 2)
8430 Message::SendFail ("Syntax error: need more arguments");
8434 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8436 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
8440 else if (aChangeArg == "-color"
8441 || aChangeArg == "color")
8443 Quantity_Color aColor;
8444 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
8449 Message::SendFail ("Syntax error: need more arguments");
8452 aClipPlane->SetCappingColor (aColor);
8453 anArgIter += aNbParsed;
8455 else if (aNbChangeArgs >= 1
8456 && (aChangeArg == "-material"
8457 || aChangeArg == "material"))
8460 Graphic3d_NameOfMaterial aMatName;
8461 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
8463 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
8466 aClipPlane->SetCappingMaterial (aMatName);
8468 else if ((aChangeArg == "-transparency"
8469 || aChangeArg == "-transp")
8470 && aNbChangeArgs >= 2)
8472 TCollection_AsciiString aValStr (aChangeArgs[1]);
8473 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
8474 if (aValStr.IsRealValue (Standard_True))
8476 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
8477 aMat.SetTransparency ((float )aValStr.RealValue());
8478 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
8479 aClipPlane->SetCappingMaterial (aMat);
8483 aValStr.LowerCase();
8484 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
8485 if (aValStr == "opaque")
8487 aMode = Graphic3d_AlphaMode_Opaque;
8489 else if (aValStr == "mask")
8491 aMode = Graphic3d_AlphaMode_Mask;
8493 else if (aValStr == "blend")
8495 aMode = Graphic3d_AlphaMode_Blend;
8497 else if (aValStr == "maskblend"
8498 || aValStr == "blendmask")
8500 aMode = Graphic3d_AlphaMode_MaskBlend;
8502 else if (aValStr == "blendauto")
8504 aMode = Graphic3d_AlphaMode_BlendAuto;
8508 Message::SendFail() << "Syntax error at '" << aValStr << "'";
8511 anAspect->SetAlphaMode (aMode);
8512 aClipPlane->SetCappingAspect (anAspect);
8516 else if (aChangeArg == "-texname"
8517 || aChangeArg == "texname")
8519 if (aNbChangeArgs < 2)
8521 Message::SendFail ("Syntax error: need more arguments");
8525 TCollection_AsciiString aTextureName (aChangeArgs[1]);
8526 Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName);
8527 if (!aTexture->IsDone())
8529 aClipPlane->SetCappingTexture (NULL);
8533 aTexture->EnableModulate();
8534 aTexture->EnableRepeat();
8535 aClipPlane->SetCappingTexture (aTexture);
8539 else if (aChangeArg == "-texscale"
8540 || aChangeArg == "texscale")
8542 if (aClipPlane->CappingTexture().IsNull())
8544 Message::SendFail ("Error: no texture is set");
8548 if (aNbChangeArgs < 3)
8550 Message::SendFail ("Syntax error: need more arguments");
8554 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8555 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8556 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
8559 else if (aChangeArg == "-texorigin"
8560 || aChangeArg == "texorigin") // texture origin
8562 if (aClipPlane->CappingTexture().IsNull())
8564 Message::SendFail ("Error: no texture is set");
8568 if (aNbChangeArgs < 3)
8570 Message::SendFail ("Syntax error: need more arguments");
8574 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8575 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8577 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
8580 else if (aChangeArg == "-texrotate"
8581 || aChangeArg == "texrotate") // texture rotation
8583 if (aClipPlane->CappingTexture().IsNull())
8585 Message::SendFail ("Error: no texture is set");
8589 if (aNbChangeArgs < 2)
8591 Message::SendFail ("Syntax error: need more arguments");
8595 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8596 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
8599 else if (aChangeArg == "-hatch"
8600 || aChangeArg == "hatch")
8602 if (aNbChangeArgs < 2)
8604 Message::SendFail ("Syntax error: need more arguments");
8608 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
8609 aHatchStr.LowerCase();
8610 if (aHatchStr == "on")
8612 aClipPlane->SetCappingHatchOn();
8614 else if (aHatchStr == "off")
8616 aClipPlane->SetCappingHatchOff();
8620 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
8624 else if (aChangeArg == "-delete"
8625 || aChangeArg == "delete")
8627 removePlane (aRegPlanes, aPlaneName);
8630 else if (aChangeArg == "-set"
8631 || aChangeArg == "-unset"
8632 || aChangeArg == "-setoverrideglobal")
8634 // set / unset plane command
8635 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
8636 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
8637 Standard_Integer anIt = 1;
8638 for (; anIt < aNbChangeArgs; ++anIt)
8640 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
8641 if (anEntityName.IsEmpty()
8642 || anEntityName.Value (1) == '-')
8646 else if (!toOverrideGlobal
8647 && ViewerTest_myViews.IsBound1 (anEntityName))
8649 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
8652 aView->AddClipPlane (aClipPlane);
8656 aView->RemoveClipPlane (aClipPlane);
8660 else if (GetMapOfAIS().IsBound2 (anEntityName))
8662 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
8665 aIObj->AddClipPlane (aClipPlane);
8669 aIObj->RemoveClipPlane (aClipPlane);
8671 if (!aIObj->ClipPlanes().IsNull())
8673 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
8678 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
8685 // apply to active view
8688 anActiveView->AddClipPlane (aClipPlane);
8692 anActiveView->RemoveClipPlane (aClipPlane);
8697 anArgIter = anArgIter + anIt - 1;
8702 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8707 ViewerTest::RedrawAllViews();
8711 //===============================================================================================
8712 //function : VZRange
8714 //===============================================================================================
8715 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8717 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8719 if (aCurrentView.IsNull())
8721 Message::SendFail ("Error: no active viewer");
8725 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
8729 theDi << "ZNear: " << aCamera->ZNear() << "\n";
8730 theDi << "ZFar: " << aCamera->ZFar() << "\n";
8736 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
8737 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
8739 if (aNewZNear >= aNewZFar)
8741 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
8745 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
8747 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
8751 aCamera->SetZRange (aNewZNear, aNewZFar);
8755 Message::SendFail ("Syntax error: wrong command arguments");
8759 aCurrentView->Redraw();
8764 //===============================================================================================
8765 //function : VAutoZFit
8767 //===============================================================================================
8768 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8770 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8772 if (aCurrentView.IsNull())
8774 Message::SendFail ("Error: no active viewer");
8778 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
8782 Message::SendFail ("Syntax error: wrong command arguments");
8788 theDi << "Auto z-fit mode: \n"
8789 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
8790 << "Scale: " << aScale << "\n";
8794 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
8798 aScale = Draw::Atoi (theArgVec[2]);
8801 aCurrentView->SetAutoZFitMode (isOn, aScale);
8802 aCurrentView->Redraw();
8806 //! Auxiliary function to print projection type
8807 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
8809 switch (theProjType)
8811 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
8812 case Graphic3d_Camera::Projection_Perspective: return "perspective";
8813 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
8814 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
8815 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
8820 //===============================================================================================
8821 //function : VCamera
8823 //===============================================================================================
8824 static int VCamera (Draw_Interpretor& theDI,
8825 Standard_Integer theArgsNb,
8826 const char** theArgVec)
8828 Handle(V3d_View) aView = ViewerTest::CurrentView();
8831 Message::SendFail ("Error: no active viewer");
8835 Handle(Graphic3d_Camera) aCamera = aView->Camera();
8838 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
8839 theDI << "FOVy: " << aCamera->FOVy() << "\n";
8840 theDI << "FOVx: " << aCamera->FOVx() << "\n";
8841 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
8842 theDI << "Distance: " << aCamera->Distance() << "\n";
8843 theDI << "IOD: " << aCamera->IOD() << "\n";
8844 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
8845 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
8846 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
8847 theDI << "ZNear: " << aCamera->ZNear() << "\n";
8848 theDI << "ZFar: " << aCamera->ZFar() << "\n";
8852 TCollection_AsciiString aPrsName;
8853 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
8855 Standard_CString anArg = theArgVec[anArgIter];
8856 TCollection_AsciiString anArgCase (anArg);
8857 anArgCase.LowerCase();
8858 if (anArgCase == "-proj"
8859 || anArgCase == "-projection"
8860 || anArgCase == "-projtype"
8861 || anArgCase == "-projectiontype")
8863 theDI << projTypeName (aCamera->ProjectionType()) << " ";
8865 else if (anArgCase == "-ortho"
8866 || anArgCase == "-orthographic")
8868 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
8870 else if (anArgCase == "-persp"
8871 || anArgCase == "-perspective"
8872 || anArgCase == "-perspmono"
8873 || anArgCase == "-perspectivemono"
8874 || anArgCase == "-mono")
8876 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
8878 else if (anArgCase == "-stereo"
8879 || anArgCase == "-stereoscopic"
8880 || anArgCase == "-perspstereo"
8881 || anArgCase == "-perspectivestereo")
8883 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
8885 else if (anArgCase == "-left"
8886 || anArgCase == "-lefteye"
8887 || anArgCase == "-monoleft"
8888 || anArgCase == "-monolefteye"
8889 || anArgCase == "-perpsleft"
8890 || anArgCase == "-perpslefteye")
8892 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
8894 else if (anArgCase == "-right"
8895 || anArgCase == "-righteye"
8896 || anArgCase == "-monoright"
8897 || anArgCase == "-monorighteye"
8898 || anArgCase == "-perpsright")
8900 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
8902 else if (anArgCase == "-dist"
8903 || anArgCase == "-distance")
8905 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
8906 if (anArgValue != NULL
8907 && *anArgValue != '-')
8910 aCamera->SetDistance (Draw::Atof (anArgValue));
8913 theDI << aCamera->Distance() << " ";
8915 else if (anArgCase == "-iod")
8917 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
8918 if (anArgValue != NULL
8919 && *anArgValue != '-')
8922 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
8925 theDI << aCamera->IOD() << " ";
8927 else if (anArgCase == "-iodtype")
8929 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
8930 TCollection_AsciiString anValueCase (anArgValue);
8931 anValueCase.LowerCase();
8932 if (anValueCase == "abs"
8933 || anValueCase == "absolute")
8936 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
8939 else if (anValueCase == "rel"
8940 || anValueCase == "relative")
8943 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
8946 else if (*anArgValue != '-')
8948 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
8951 switch (aCamera->GetIODType())
8953 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
8954 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
8957 else if (anArgCase == "-zfocus")
8959 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
8960 if (anArgValue != NULL
8961 && *anArgValue != '-')
8964 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
8967 theDI << aCamera->ZFocus() << " ";
8969 else if (anArgCase == "-zfocustype")
8971 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
8972 TCollection_AsciiString anValueCase (anArgValue);
8973 anValueCase.LowerCase();
8974 if (anValueCase == "abs"
8975 || anValueCase == "absolute")
8978 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
8981 else if (anValueCase == "rel"
8982 || anValueCase == "relative")
8985 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
8988 else if (*anArgValue != '-')
8990 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
8993 switch (aCamera->ZFocusType())
8995 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
8996 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
8999 else if (anArgCase == "-lockzup"
9000 || anArgCase == "-turntable")
9002 bool toLockUp = true;
9003 if (++anArgIter < theArgsNb
9004 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
9008 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9010 else if (anArgCase == "-rotationmode"
9011 || anArgCase == "-rotmode")
9013 AIS_RotationMode aRotMode = AIS_RotationMode_BndBoxActive;
9014 TCollection_AsciiString aRotStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9015 aRotStr.LowerCase();
9016 if (aRotStr == "bndboxactive"
9017 || aRotStr == "active")
9019 aRotMode = AIS_RotationMode_BndBoxActive;
9021 else if (aRotStr == "picklast"
9022 || aRotStr == "pick")
9024 aRotMode = AIS_RotationMode_PickLast;
9026 else if (aRotStr == "pickcenter")
9028 aRotMode = AIS_RotationMode_PickCenter;
9030 else if (aRotStr == "cameraat"
9031 || aRotStr == "cameracenter")
9033 aRotMode = AIS_RotationMode_CameraAt;
9035 else if (aRotStr == "bndboxscene"
9036 || aRotStr == "boxscene")
9038 aRotMode = AIS_RotationMode_BndBoxScene;
9042 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9046 ViewerTest::CurrentEventManager()->SetRotationMode (aRotMode);
9049 else if (anArgCase == "-navigationmode"
9050 || anArgCase == "-navmode")
9052 AIS_NavigationMode aNavMode = AIS_NavigationMode_Orbit;
9053 TCollection_AsciiString aNavStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9054 aNavStr.LowerCase();
9055 if (aNavStr == "orbit")
9057 aNavMode = AIS_NavigationMode_Orbit;
9059 else if (aNavStr == "flight"
9061 || aNavStr == "copter"
9062 || aNavStr == "helicopter")
9064 aNavMode = AIS_NavigationMode_FirstPersonFlight;
9066 else if (aNavStr == "walk"
9067 || aNavStr == "shooter")
9069 aNavMode = AIS_NavigationMode_FirstPersonWalk;
9073 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9077 Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
9078 aViewMgr->SetNavigationMode (aNavMode);
9079 if (aNavMode == AIS_NavigationMode_Orbit)
9081 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateOrbit);
9085 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateView);
9089 else if (anArgCase == "-fov"
9090 || anArgCase == "-fovy"
9091 || anArgCase == "-fovx"
9092 || anArgCase == "-fov2d")
9094 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9095 if (anArgValue != NULL
9096 && *anArgValue != '-')
9099 if (anArgCase == "-fov2d")
9101 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9103 else if (anArgCase == "-fovx")
9105 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9109 aCamera->SetFOVy (Draw::Atof (anArgValue));
9113 if (anArgCase == "-fov2d")
9115 theDI << aCamera->FOV2d() << " ";
9117 else if (anArgCase == "-fovx")
9119 theDI << aCamera->FOVx() << " ";
9123 theDI << aCamera->FOVy() << " ";
9126 else if (anArgIter + 1 < theArgsNb
9127 && anArgCase == "-xrpose")
9129 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9130 anXRArg.LowerCase();
9131 if (anXRArg == "base")
9133 aCamera = aView->View()->BaseXRCamera();
9135 else if (anXRArg == "head")
9137 aCamera = aView->View()->PosedXRCamera();
9141 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9144 if (aCamera.IsNull())
9146 Message::SendFail() << "Error: undefined XR pose";
9149 if (aView->AutoZFitMode())
9151 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9152 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9153 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9156 else if (aPrsName.IsEmpty()
9157 && !anArgCase.StartsWith ("-"))
9163 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
9168 if (aPrsName.IsEmpty()
9174 if (!aPrsName.IsEmpty())
9176 Handle(AIS_CameraFrustum) aCameraFrustum;
9177 if (GetMapOfAIS().IsBound2 (aPrsName))
9179 // find existing object
9180 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9181 if (aCameraFrustum.IsNull())
9183 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
9188 if (aCameraFrustum.IsNull())
9190 aCameraFrustum = new AIS_CameraFrustum();
9194 // not include displayed object of old camera frustum in the new one.
9195 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9198 aCameraFrustum->SetCameraFrustum (aCamera);
9200 ViewerTest::Display (aPrsName, aCameraFrustum);
9206 //! Parse stereo output mode
9207 inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9208 Graphic3d_StereoMode& theMode)
9210 TCollection_AsciiString aFlag (theArg);
9212 if (aFlag == "quadbuffer")
9214 theMode = Graphic3d_StereoMode_QuadBuffer;
9216 else if (aFlag == "anaglyph")
9218 theMode = Graphic3d_StereoMode_Anaglyph;
9220 else if (aFlag == "row"
9221 || aFlag == "rowinterlaced")
9223 theMode = Graphic3d_StereoMode_RowInterlaced;
9225 else if (aFlag == "col"
9226 || aFlag == "colinterlaced"
9227 || aFlag == "columninterlaced")
9229 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9231 else if (aFlag == "chess"
9232 || aFlag == "chessboard")
9234 theMode = Graphic3d_StereoMode_ChessBoard;
9236 else if (aFlag == "sbs"
9237 || aFlag == "sidebyside")
9239 theMode = Graphic3d_StereoMode_SideBySide;
9241 else if (aFlag == "ou"
9242 || aFlag == "overunder")
9244 theMode = Graphic3d_StereoMode_OverUnder;
9246 else if (aFlag == "pageflip"
9247 || aFlag == "softpageflip")
9249 theMode = Graphic3d_StereoMode_SoftPageFlip;
9251 else if (aFlag == "openvr"
9254 theMode = Graphic3d_StereoMode_OpenVR;
9258 return Standard_False;
9260 return Standard_True;
9263 //! Parse anaglyph filter
9264 inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9265 Graphic3d_RenderingParams::Anaglyph& theFilter)
9267 TCollection_AsciiString aFlag (theArg);
9269 if (aFlag == "redcyansimple")
9271 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9273 else if (aFlag == "redcyan"
9274 || aFlag == "redcyanoptimized")
9276 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9278 else if (aFlag == "yellowbluesimple")
9280 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9282 else if (aFlag == "yellowblue"
9283 || aFlag == "yellowblueoptimized")
9285 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9287 else if (aFlag == "greenmagenta"
9288 || aFlag == "greenmagentasimple")
9290 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9294 return Standard_False;
9296 return Standard_True;
9299 //==============================================================================
9300 //function : VStereo
9302 //==============================================================================
9304 static int VStereo (Draw_Interpretor& theDI,
9305 Standard_Integer theArgNb,
9306 const char** theArgVec)
9308 Handle(V3d_View) aView = ViewerTest::CurrentView();
9311 Message::SendFail ("Error: no active viewer");
9315 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9316 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9319 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
9320 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
9323 TCollection_AsciiString aMode;
9324 switch (aView->RenderingParams().StereoMode)
9326 case Graphic3d_StereoMode_QuadBuffer : aMode = "quadBuffer"; break;
9327 case Graphic3d_StereoMode_RowInterlaced : aMode = "rowInterlaced"; break;
9328 case Graphic3d_StereoMode_ColumnInterlaced : aMode = "columnInterlaced"; break;
9329 case Graphic3d_StereoMode_ChessBoard : aMode = "chessBoard"; break;
9330 case Graphic3d_StereoMode_SideBySide : aMode = "sideBySide"; break;
9331 case Graphic3d_StereoMode_OverUnder : aMode = "overUnder"; break;
9332 case Graphic3d_StereoMode_SoftPageFlip : aMode = "softpageflip"; break;
9333 case Graphic3d_StereoMode_OpenVR : aMode = "openVR"; break;
9334 case Graphic3d_StereoMode_Anaglyph :
9336 switch (aView->RenderingParams().AnaglyphFilter)
9338 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9339 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9340 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9341 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9342 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9347 theDI << "Mode " << aMode << "\n";
9352 Graphic3d_StereoMode aMode = aParams->StereoMode;
9353 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9354 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9356 Standard_CString anArg = theArgVec[anArgIter];
9357 TCollection_AsciiString aFlag (anArg);
9359 if (anUpdateTool.parseRedrawMode (aFlag))
9363 else if (aFlag == "0"
9366 if (++anArgIter < theArgNb)
9368 Message::SendFail ("Error: wrong number of arguments");
9372 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
9374 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9378 else if (aFlag == "1"
9381 if (++anArgIter < theArgNb)
9383 Message::SendFail ("Error: wrong number of arguments");
9387 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9388 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
9393 else if (aFlag == "-reverse"
9394 || aFlag == "-reversed"
9395 || aFlag == "-swap")
9397 Standard_Boolean toEnable = Standard_True;
9398 if (++anArgIter < theArgNb
9399 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
9403 aParams->ToReverseStereo = toEnable;
9405 else if (aFlag == "-noreverse"
9406 || aFlag == "-noswap")
9408 Standard_Boolean toDisable = Standard_True;
9409 if (++anArgIter < theArgNb
9410 && !Draw::ParseOnOff (theArgVec[anArgIter], toDisable))
9414 aParams->ToReverseStereo = !toDisable;
9416 else if (aFlag == "-mode"
9417 || aFlag == "-stereomode")
9419 if (++anArgIter >= theArgNb
9420 || !parseStereoMode (theArgVec[anArgIter], aMode))
9422 Message::SendFail() << "Syntax error at '" << anArg << "'";
9426 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9428 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9431 else if (aFlag == "-anaglyph"
9432 || aFlag == "-anaglyphfilter")
9434 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9435 if (++anArgIter >= theArgNb
9436 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
9438 Message::SendFail() << "Syntax error at '" << anArg << "'";
9442 aMode = Graphic3d_StereoMode_Anaglyph;
9443 aParams->AnaglyphFilter = aFilter;
9445 else if (parseStereoMode (anArg, aMode)) // short syntax
9447 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9449 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9452 else if (anArgIter + 1 < theArgNb
9453 && aFlag == "-hmdfov2d")
9455 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
9456 if (aParams->HmdFov2d < 10.0f
9457 || aParams->HmdFov2d > 180.0f)
9459 Message::SendFail() << "Error: FOV is out of range";
9463 else if (aFlag == "-mirror"
9464 || aFlag == "-mirrorcomposer")
9466 Standard_Boolean toEnable = Standard_True;
9467 if (++anArgIter < theArgNb
9468 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
9472 aParams->ToMirrorComposer = toEnable;
9474 else if (anArgIter + 1 < theArgNb
9475 && (aFlag == "-unitfactor"
9476 || aFlag == "-unitscale"))
9478 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
9482 Message::SendFail() << "Syntax error at '" << anArg << "'";
9487 aParams->StereoMode = aMode;
9488 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9489 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
9491 // initiate implicit continuous rendering
9492 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
9497 //===============================================================================================
9498 //function : VDefaults
9500 //===============================================================================================
9501 static int VDefaults (Draw_Interpretor& theDi,
9502 Standard_Integer theArgsNb,
9503 const char** theArgVec)
9505 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9508 Message::SendFail ("Error: no active viewer");
9512 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
9515 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
9517 theDi << "DeflType: relative\n"
9518 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
9522 theDi << "DeflType: absolute\n"
9523 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
9525 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
9526 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
9530 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9532 TCollection_AsciiString anArg (theArgVec[anArgIter]);
9534 if (anArg == "-ABSDEFL"
9535 || anArg == "-ABSOLUTEDEFLECTION"
9537 || anArg == "-DEFLECTION")
9539 if (++anArgIter >= theArgsNb)
9541 Message::SendFail() << "Syntax error at " << anArg;
9544 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
9545 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
9547 else if (anArg == "-RELDEFL"
9548 || anArg == "-RELATIVEDEFLECTION"
9549 || anArg == "-DEVCOEFF"
9550 || anArg == "-DEVIATIONCOEFF"
9551 || anArg == "-DEVIATIONCOEFFICIENT")
9553 if (++anArgIter >= theArgsNb)
9555 Message::SendFail() << "Syntax error at " << anArg;
9558 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
9559 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
9561 else if (anArg == "-ANGDEFL"
9562 || anArg == "-ANGULARDEFL"
9563 || anArg == "-ANGULARDEFLECTION")
9565 if (++anArgIter >= theArgsNb)
9567 Message::SendFail() << "Syntax error at " << anArg;
9570 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
9572 else if (anArg == "-AUTOTR"
9573 || anArg == "-AUTOTRIANG"
9574 || anArg == "-AUTOTRIANGULATION")
9577 bool toTurnOn = true;
9578 if (anArgIter >= theArgsNb
9579 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
9581 Message::SendFail() << "Syntax error at '" << anArg << "'";
9584 aDefParams->SetAutoTriangulation (toTurnOn);
9588 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
9596 //! Parse light source type from string.
9597 static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
9598 Graphic3d_TypeOfLightSource& theType)
9600 TCollection_AsciiString aType (theTypeName);
9603 || aType == "ambient"
9604 || aType == "amblight")
9606 theType = Graphic3d_TypeOfLightSource_Ambient;
9608 else if (aType == "directional"
9609 || aType == "dirlight")
9611 theType = Graphic3d_TypeOfLightSource_Directional;
9613 else if (aType == "spot"
9614 || aType == "spotlight")
9616 theType = Graphic3d_TypeOfLightSource_Spot;
9618 else if (aType == "poslight"
9619 || aType == "positional"
9623 theType = Graphic3d_TypeOfLightSource_Positional;
9632 //! Find existing light by name or index.
9633 static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
9635 Handle(V3d_Light) aLight;
9636 Standard_Integer aLightIndex = -1;
9637 Draw::ParseInteger (theName.ToCString(), aLightIndex);
9638 Standard_Integer aLightIt = 0;
9639 Handle(V3d_View) aView = ViewerTest::CurrentView();
9640 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
9642 if (aLightIndex != -1)
9644 if (aLightIt == aLightIndex)
9646 return aLightIter.Value();
9649 else if (aLightIter.Value()->GetId() == theName
9650 || aLightIter.Value()->Name() == theName)
9652 if (!aLight.IsNull())
9654 Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
9657 aLight = aLightIter.Value();
9663 //===============================================================================================
9666 //===============================================================================================
9667 static int VLight (Draw_Interpretor& theDi,
9668 Standard_Integer theArgsNb,
9669 const char** theArgVec)
9671 Handle(V3d_View) aView = ViewerTest::CurrentView();
9672 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
9673 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9675 || aViewer.IsNull())
9677 Message::SendFail ("Error: no active viewer");
9683 // print lights info
9684 Standard_Integer aLightId = 0;
9685 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
9687 Handle(V3d_Light) aLight = aLightIter.Value();
9688 const Quantity_Color aColor = aLight->Color();
9689 theDi << "Light #" << aLightId
9690 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
9691 << " [" << aLight->GetId() << "] "
9692 << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
9693 switch (aLight->Type())
9697 theDi << " Type: Ambient\n"
9698 << " Intensity: " << aLight->Intensity() << "\n";
9701 case V3d_DIRECTIONAL:
9703 theDi << " Type: Directional\n"
9704 << " Intensity: " << aLight->Intensity() << "\n"
9705 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9706 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9707 << " Smoothness: " << aLight->Smoothness() << "\n"
9708 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
9711 case V3d_POSITIONAL:
9713 theDi << " Type: Positional\n"
9714 << " Intensity: " << aLight->Intensity() << "\n"
9715 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9716 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9717 << " Smoothness: " << aLight->Smoothness() << "\n"
9718 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9719 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9720 << " Range: " << aLight->Range() << "\n";
9725 theDi << " Type: Spot\n"
9726 << " Intensity: " << aLight->Intensity() << "\n"
9727 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9728 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9729 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9730 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
9731 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9732 << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
9733 << " Exponent: " << aLight->Concentration() << "\n"
9734 << " Range: " << aLight->Range() << "\n";
9739 theDi << " Type: UNKNOWN\n";
9743 theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
9747 Handle(V3d_Light) aLightOld, aLightNew;
9748 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
9749 bool isGlobal = true;
9750 ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
9751 Handle(AIS_LightSource) aLightPrs;
9752 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
9754 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
9755 TCollection_AsciiString anArgCase (anArg);
9756 anArgCase.LowerCase();
9757 if (anUpdateTool.parseRedrawMode (anArg))
9761 else if (anArgCase == "-new"
9762 || anArgCase == "-add"
9763 || anArgCase == "-create"
9764 || anArgCase == "-type"
9765 || (anArgCase == "-reset"
9766 && !aLightNew.IsNull())
9767 || (anArgCase == "-defaults"
9768 && !aLightNew.IsNull())
9769 || anArgCase == "add"
9770 || anArgCase == "new"
9771 || anArgCase == "create")
9773 Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
9774 if (anArgCase == "-reset")
9776 aType = aLightNew->Type();
9778 else if (anArgIt + 1 >= theArgsNb
9779 || !parseLightSourceType (theArgVec[++anArgIt], aType))
9781 theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
9785 TCollection_AsciiString aName;
9786 if (!aLightNew.IsNull())
9788 aName = aLightNew->Name();
9792 case Graphic3d_TypeOfLightSource_Ambient:
9794 aLightNew = new V3d_AmbientLight();
9797 case Graphic3d_TypeOfLightSource_Directional:
9799 aLightNew = new V3d_DirectionalLight();
9802 case Graphic3d_TypeOfLightSource_Spot:
9804 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
9807 case Graphic3d_TypeOfLightSource_Positional:
9809 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
9814 if (anArgCase == "-type"
9815 && !aLightOld.IsNull())
9817 aLightNew->CopyFrom (aLightOld);
9819 aLightNew->SetName (aName);
9821 else if ((anArgCase == "-layer"
9822 || anArgCase == "-zlayer")
9823 && anArgIt + 1 < theArgsNb)
9825 if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
9826 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
9828 Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
9832 else if (anArgCase == "-glob"
9833 || anArgCase == "-global"
9834 || anArgCase == "-loc"
9835 || anArgCase == "-local")
9837 isGlobal = anArgCase.StartsWith ("-glob");
9839 else if (anArgCase == "-def"
9840 || anArgCase == "-defaults"
9841 || anArgCase == "-reset")
9843 aViewer->SetDefaultLights();
9844 aLightOld.Nullify();
9845 aLightNew.Nullify();
9846 aLightPrs.Nullify();
9848 else if (anArgCase == "-clr"
9849 || anArgCase == "-clear"
9850 || anArgCase == "clear")
9852 TColStd_SequenceOfInteger aLayers;
9853 aViewer->GetAllZLayers (aLayers);
9854 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
9856 if (aLayeriter.Value() == aLayer
9857 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
9859 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
9860 aSettings.SetLights (Handle(Graphic3d_LightSet)());
9861 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
9862 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
9869 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
9871 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
9872 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
9874 Handle(V3d_Light) aLight = aLightIter.Value();
9875 Handle(AIS_InteractiveObject) aPrsObject;
9876 GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
9877 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
9879 aCtx->Remove (aLightSourceDel, false);
9880 aMap.UnBind1 (aLightSourceDel);
9882 aViewer->DelLight (aLight);
9883 aLightIter = aView->ActiveLightIterator();
9887 aLightOld.Nullify();
9888 aLightNew.Nullify();
9889 aLightPrs.Nullify();
9891 else if (!aLightNew.IsNull()
9892 && (anArgCase == "-display"
9893 || anArgCase == "-disp"
9894 || anArgCase == "-presentation"
9895 || anArgCase == "-prs"))
9897 TCollection_AsciiString aLightName = aLightNew->Name();
9898 if (anArgIt + 1 < theArgsNb
9899 && theArgVec[anArgIt + 1][0] != '-')
9902 aLightName = theArgVec[++anArgIt];
9903 if (aLightNew->Name() != aLightName)
9905 if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
9907 theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
9910 aLightNew->SetName (aLightName);
9913 if (aLightName.IsEmpty())
9915 Message::SendFail() << "Error: nameless light source cannot be displayed";
9918 if (aLightPrs.IsNull())
9920 aLightPrs = new AIS_LightSource (aLightNew);
9922 theDi << aLightName << " ";
9924 else if (!aLightNew.IsNull()
9925 && (anArgCase == "-disable"
9926 || anArgCase == "-disabled"
9927 || anArgCase == "-enable"
9928 || anArgCase == "-enabled"))
9930 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
9931 if (anArgCase == "-disable"
9932 || anArgCase == "-disabled")
9934 toEnable = !toEnable;
9936 aLightNew->SetEnabled (toEnable);
9938 else if (!aLightNew.IsNull()
9939 && (anArgCase == "-color"
9940 || anArgCase == "-colour"
9941 || anArgCase == "color"))
9943 Quantity_Color aColor;
9944 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
9945 theArgVec + anArgIt + 1,
9947 anArgIt += aNbParsed;
9950 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
9953 aLightNew->SetColor (aColor);
9955 else if (!aLightNew.IsNull()
9956 && (anArgCase == "-pos"
9957 || anArgCase == "-position"
9958 || anArgCase == "-prsposition"
9959 || anArgCase == "-prspos"
9960 || anArgCase == "pos"
9961 || anArgCase == "position")
9962 && (anArgIt + 3) < theArgsNb)
9965 if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
9967 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
9972 if (anArgCase == "-prsposition"
9973 || anArgCase == "-prspos")
9975 aLightNew->SetDisplayPosition (aPosXYZ);
9979 if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
9980 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
9982 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
9986 aLightNew->SetPosition (aPosXYZ);
9989 else if (!aLightNew.IsNull()
9990 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
9991 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
9992 && (anArgCase == "-dir"
9993 || anArgCase == "-direction")
9994 && (anArgIt + 3) < theArgsNb)
9997 if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
9999 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10004 aLightNew->SetDirection (gp_Dir (aDirXYZ));
10006 else if (!aLightNew.IsNull()
10007 && (anArgCase == "-smoothangle"
10008 || anArgCase == "-smoothradius"
10009 || anArgCase == "-sm"
10010 || anArgCase == "-smoothness")
10011 && anArgIt + 1 < theArgsNb)
10013 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10014 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10016 aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
10018 if (Abs (aSmoothness) <= ShortRealEpsilon())
10020 aLightNew->SetIntensity (1.f);
10022 else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
10024 aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10028 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
10029 aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10032 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10034 aLightNew->SetSmoothRadius (aSmoothness);
10036 else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10038 aLightNew->SetSmoothAngle (aSmoothness);
10041 else if (!aLightNew.IsNull()
10042 && (anArgCase == "-int"
10043 || anArgCase == "-intensity")
10044 && anArgIt + 1 < theArgsNb)
10046 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10047 aLightNew->SetIntensity (aIntensity);
10049 else if (!aLightNew.IsNull()
10050 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10051 && (anArgCase == "-spotangle"
10052 || anArgCase == "-ang"
10053 || anArgCase == "-angle")
10054 && anArgIt + 1 < theArgsNb)
10056 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10057 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10058 aLightNew->SetAngle (anAngle);
10060 else if (!aLightNew.IsNull()
10061 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10062 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10063 && (anArgCase == "-constatten"
10064 || anArgCase == "-constattenuation")
10065 && anArgIt + 1 < theArgsNb)
10067 const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10068 aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
10070 else if (!aLightNew.IsNull()
10071 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10072 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10073 && (anArgCase == "-linatten"
10074 || anArgCase == "-linearatten"
10075 || anArgCase == "-linearattenuation")
10076 && anArgIt + 1 < theArgsNb)
10078 const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10079 aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
10081 else if (!aLightNew.IsNull()
10082 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10083 && (anArgCase == "-spotexp"
10084 || anArgCase == "-spotexponent"
10085 || anArgCase == "-exp"
10086 || anArgCase == "-exponent")
10087 && anArgIt + 1 < theArgsNb)
10089 aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
10091 else if (!aLightNew.IsNull()
10092 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10093 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
10094 && anArgCase == "-range"
10095 && anArgIt + 1 < theArgsNb)
10097 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
10098 aLightNew->SetRange (aRange);
10100 else if (!aLightNew.IsNull()
10101 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10102 && (anArgCase == "-head"
10103 || anArgCase == "-headlight"))
10105 Standard_Boolean isHeadLight = Standard_True;
10106 if (anArgIt + 1 < theArgsNb
10107 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
10111 aLightNew->SetHeadlight (isHeadLight);
10113 else if (!aLightNew.IsNull()
10114 && anArgCase == "-name"
10115 && anArgIt + 1 < theArgsNb)
10117 const TCollection_AsciiString aName = theArgVec[++anArgIt];
10118 if (aLightNew->Name() == aName)
10123 if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
10125 theDi << "Syntax error: light with name '" << aName << "' is already defined";
10128 aLightNew->SetName (aName);
10130 else if (!aLightPrs.IsNull()
10131 && (anArgCase == "-showzoomable"
10132 || anArgCase == "-prszoomable"
10133 || anArgCase == "-zoomable"))
10135 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10136 aLightPrs->SetZoomable (isZoomable);
10138 else if (!aLightPrs.IsNull()
10139 && (anArgCase == "-showdraggable"
10140 || anArgCase == "-prsdraggable"
10141 || anArgCase == "-draggable"))
10143 const bool isDraggable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10144 aLightPrs->SetDraggable (isDraggable);
10146 else if (!aLightPrs.IsNull()
10147 && (anArgCase == "-showname"
10148 || anArgCase == "-prsname"))
10150 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10151 aLightPrs->SetDisplayName (toDisplay);
10153 else if (!aLightPrs.IsNull()
10154 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10155 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10156 && (anArgCase == "-showrange"
10157 || anArgCase == "-prsrange"))
10159 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10160 aLightPrs->SetDisplayRange (toDisplay);
10162 else if (!aLightPrs.IsNull()
10163 && (anArgCase == "-showsize"
10164 || anArgCase == "-prssize")
10165 && anArgIt + 1 < theArgsNb)
10167 Standard_Real aSize = 0.0;
10168 if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
10170 || aLightPrs.IsNull())
10172 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10176 aLightPrs->SetSize (aSize);
10178 else if (!aLightPrs.IsNull()
10179 && (anArgCase == "-dirarcsize"
10180 || anArgCase == "-arcsize"
10181 || anArgCase == "-arc")
10182 && anArgIt + 1 < theArgsNb)
10184 Standard_Integer aSize = 0;
10185 if (!Draw::ParseInteger (theArgVec[anArgIt + 1], aSize)
10187 || aLightPrs->Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
10189 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10193 aLightPrs->SetArcSize (aSize);
10195 else if (!aLightNew.IsNull()
10196 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10197 && (anArgCase == "-castshadow"
10198 || anArgCase == "-castshadows"
10199 || anArgCase == "-shadows"))
10201 bool toCastShadows = true;
10202 if (anArgIt + 1 < theArgsNb
10203 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
10207 aLightNew->SetCastShadows (toCastShadows);
10209 else if (anArgCase == "-del"
10210 || anArgCase == "-delete"
10211 || anArgCase == "-remove"
10212 || anArgCase == "del"
10213 || anArgCase == "delete"
10214 || anArgCase == "remove")
10216 if (aLightOld.IsNull())
10218 if (!aLightNew.IsNull())
10220 aLightNew.Nullify();
10224 if (++anArgIt >= theArgsNb)
10226 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10230 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10231 aLightOld = findLightSource (anOldName);
10232 if (aLightOld.IsNull())
10234 Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
10239 aLightNew.Nullify();
10240 aLightPrs.Nullify();
10242 else if (anArgCase == "-change"
10243 || anArgCase == "change")
10245 // just skip old syntax
10247 else if (aLightNew.IsNull()
10248 && !anArgCase.StartsWith ("-"))
10250 if (!aLightNew.IsNull())
10255 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10256 aLightOld = findLightSource (anOldName);
10257 if (!aLightOld.IsNull())
10259 aLightNew = aLightOld;
10261 Handle(AIS_InteractiveObject) aPrsObject;
10262 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10263 aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
10267 Standard_Integer aLightIndex = -1;
10268 Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
10269 if (aLightIndex != -1)
10271 Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
10275 aLightNew = new V3d_AmbientLight();
10276 aLightNew->SetName (anOldName);
10281 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
10286 // delete old light source
10287 if (!aLightOld.IsNull()
10288 && aLightOld != aLightNew)
10290 TColStd_SequenceOfInteger aLayers;
10291 aViewer->GetAllZLayers (aLayers);
10292 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
10294 if (aLayerIter.Value() == aLayer
10295 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10297 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
10298 if (!aSettings.Lights().IsNull())
10300 aSettings.Lights()->Remove (aLightOld);
10301 if (aSettings.Lights()->IsEmpty())
10303 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10306 aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
10307 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10314 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10316 Handle(AIS_InteractiveObject) aPrsObject;
10317 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10318 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10320 aCtx->Remove (aLightSourceDel, false);
10321 GetMapOfAIS().UnBind1 (aLightSourceDel);
10323 aViewer->DelLight (aLightOld);
10325 aLightOld.Nullify();
10328 // add new light source
10329 if (!aLightNew.IsNull())
10331 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10333 aViewer->AddLight (aLightNew);
10336 aViewer->SetLightOn (aLightNew);
10340 aView->SetLightOn (aLightNew);
10345 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
10346 if (aSettings.Lights().IsNull())
10348 aSettings.SetLights (new Graphic3d_LightSet());
10350 aSettings.Lights()->Add (aLightNew);
10351 aViewer->SetZLayerSettings (aLayer, aSettings);
10354 if (!aLightPrs.IsNull())
10356 aLightPrs->SetLight (aLightNew);
10357 ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
10361 // manage presentations
10362 struct LightPrsSort
10364 bool operator() (const Handle(AIS_LightSource)& theLeft,
10365 const Handle(AIS_LightSource)& theRight)
10367 return theLeft->Light()->GetId() < theRight->Light()->GetId();
10371 AIS_ListOfInteractive aPrsList;
10372 aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
10373 if (!aPrsList.IsEmpty())
10375 // update light source presentations
10376 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
10377 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
10379 if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
10381 aLightPrsVec.push_back (aLightPrs2);
10385 // sort objects by id as AIS_InteractiveContext stores them in unordered map
10386 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
10388 Standard_Integer aTopStack = 0;
10389 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
10391 Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
10392 if (!aLightPrs2->TransformPersistence().IsNull()
10393 && aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
10395 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
10396 aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
10397 aTopStack += aPrsSize + aPrsSize / 2;
10399 aCtx->Redisplay (aLightPrs2, false);
10400 aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
10406 //===============================================================================================
10407 //function : VPBREnvironment
10409 //===============================================================================================
10410 static int VPBREnvironment (Draw_Interpretor&,
10411 Standard_Integer theArgsNb,
10412 const char** theArgVec)
10416 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
10420 Handle(V3d_View) aView = ViewerTest::CurrentView();
10421 if (aView.IsNull())
10423 Message::SendFail ("Error: no active viewer");
10427 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
10430 if (anArg == "-generate"
10431 || anArg == "-gen")
10433 aView->GeneratePBREnvironment (Standard_True);
10435 else if (anArg == "-clear")
10437 aView->ClearPBREnvironment (Standard_True);
10441 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
10448 //! Read Graphic3d_RenderingParams::PerfCounters flag.
10449 static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
10450 Standard_Boolean& theToReset,
10451 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
10452 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
10454 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
10455 TCollection_AsciiString aVal = theValue;
10456 Standard_Boolean toReverse = Standard_False;
10457 if (aVal == "none")
10459 theToReset = Standard_True;
10460 return Standard_True;
10462 else if (aVal.StartsWith ("-"))
10464 toReverse = Standard_True;
10465 aVal = aVal.SubString (2, aVal.Length());
10467 else if (aVal.StartsWith ("no"))
10469 toReverse = Standard_True;
10470 aVal = aVal.SubString (3, aVal.Length());
10472 else if (aVal.StartsWith ("+"))
10474 aVal = aVal.SubString (2, aVal.Length());
10478 theToReset = Standard_True;
10482 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
10483 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
10484 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
10485 else if (aVal == "structs"
10486 || aVal == "structures"
10487 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
10488 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
10489 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
10490 else if (aVal == "tris"
10491 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
10492 else if (aVal == "pnts"
10493 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
10494 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
10495 else if (aVal == "mem"
10496 || aVal == "gpumem"
10497 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
10498 else if (aVal == "skipimmediate"
10499 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
10500 else if (aVal == "frametime"
10501 || aVal == "frametimers"
10502 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
10503 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
10504 else if (aVal == "extended"
10505 || aVal == "verbose"
10506 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
10507 else if (aVal == "full"
10508 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
10511 return Standard_False;
10516 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
10520 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
10522 return Standard_True;
10525 //! Read Graphic3d_RenderingParams::PerfCounters flags.
10526 static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
10527 Graphic3d_RenderingParams::PerfCounters& theFlags)
10529 TCollection_AsciiString aValue = theValue;
10530 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
10531 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
10532 Standard_Boolean toReset = Standard_False;
10535 Standard_Integer aSplitPos = aValue.Search ("|");
10536 if (aSplitPos <= 0)
10538 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
10540 return Standard_False;
10544 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
10546 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
10547 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
10548 return Standard_True;
10553 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
10554 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
10556 return Standard_False;
10559 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
10563 //=======================================================================
10564 //function : VRenderParams
10565 //purpose : Enables/disables rendering features
10566 //=======================================================================
10568 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
10569 Standard_Integer theArgNb,
10570 const char** theArgVec)
10572 Handle(V3d_View) aView = ViewerTest::CurrentView();
10573 if (aView.IsNull())
10575 Message::SendFail ("Error: no active viewer");
10579 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
10580 TCollection_AsciiString aCmdName (theArgVec[0]);
10581 aCmdName.LowerCase();
10582 if (aCmdName == "vraytrace")
10586 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
10589 else if (theArgNb == 2)
10591 TCollection_AsciiString aValue (theArgVec[1]);
10592 aValue.LowerCase();
10596 aParams.Method = Graphic3d_RM_RAYTRACING;
10600 else if (aValue == "off"
10603 aParams.Method = Graphic3d_RM_RASTERIZATION;
10609 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
10615 Message::SendFail ("Syntax error: wrong number of arguments");
10622 theDI << "renderMode: ";
10623 switch (aParams.Method)
10625 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
10626 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
10629 theDI << "transparency: ";
10630 switch (aParams.TransparencyMethod)
10632 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
10633 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
10634 << TCollection_AsciiString (aParams.OitDepthFactor); break;
10635 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
10636 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
10639 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
10640 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
10641 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
10642 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
10643 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
10644 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
10645 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
10646 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
10647 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
10648 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
10649 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
10650 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
10651 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
10652 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
10653 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
10654 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
10655 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
10656 theDI << "shadingModel: ";
10657 switch (aView->ShadingModel())
10659 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
10660 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit"; break;
10661 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat"; break;
10662 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud"; break;
10663 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong"; break;
10664 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
10665 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
10669 theDI << "perfCounters:";
10670 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
10674 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
10678 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
10680 theDI << " structs";
10682 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
10684 theDI << " groups";
10686 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
10688 theDI << " arrays";
10690 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
10694 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
10698 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
10702 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
10704 theDI << " gpumem";
10706 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
10708 theDI << " frameTime";
10710 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
10712 theDI << " skipimmediate";
10714 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
10720 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
10721 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
10722 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
10723 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
10724 "noUpdate") << "\n";
10729 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
10730 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10731 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10733 Standard_CString anArg (theArgVec[anArgIter]);
10734 TCollection_AsciiString aFlag (anArg);
10736 if (anUpdateTool.parseRedrawMode (aFlag))
10740 else if (aFlag == "-echo"
10741 || aFlag == "-print")
10743 toPrint = Standard_True;
10744 anUpdateTool.Invalidate();
10746 else if (aFlag == "-reset")
10748 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
10750 else if (aFlag == "-sync"
10751 && (anArgIter + 1 < theArgNb))
10753 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
10754 aSyncFlag.LowerCase();
10755 if (aSyncFlag == "default"
10756 || aSyncFlag == "defaults"
10757 || aSyncFlag == "viewer")
10759 toSyncDefaults = true;
10761 else if (aSyncFlag == "allviews"
10762 || aSyncFlag == "views")
10764 toSyncAllViews = true;
10768 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
10772 else if (aFlag == "-mode"
10773 || aFlag == "-rendermode"
10774 || aFlag == "-render_mode")
10778 switch (aParams.Method)
10780 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
10781 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
10787 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10791 else if (aFlag == "-ray"
10792 || aFlag == "-raytrace")
10796 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
10800 bool isRayTrace = true;
10801 if (anArgIter + 1 < theArgNb
10802 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
10806 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
10808 else if (aFlag == "-rast"
10809 || aFlag == "-raster"
10810 || aFlag == "-rasterization")
10814 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
10818 bool isRaster = true;
10819 if (anArgIter + 1 < theArgNb
10820 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
10824 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
10826 else if (aFlag == "-msaa")
10830 theDI << aParams.NbMsaaSamples << " ";
10833 else if (++anArgIter >= theArgNb)
10835 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10839 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
10840 if (aNbSamples < 0)
10842 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
10847 aParams.NbMsaaSamples = aNbSamples;
10850 else if (aFlag == "-linefeather"
10851 || aFlag == "-edgefeather"
10852 || aFlag == "-feather")
10856 theDI << " " << aParams.LineFeather << " ";
10859 else if (++anArgIter >= theArgNb)
10861 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10865 TCollection_AsciiString aParam = theArgVec[anArgIter];
10866 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
10867 if (aFeather <= 0.0f)
10869 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
10872 aParams.LineFeather = aFeather;
10874 else if (aFlag == "-oit")
10878 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
10880 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
10882 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
10884 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
10888 theDI << "off" << " ";
10892 else if (++anArgIter >= theArgNb)
10894 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10898 TCollection_AsciiString aParam = theArgVec[anArgIter];
10899 aParam.LowerCase();
10900 if (aParam == "peeling"
10901 || aParam == "peel")
10903 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
10904 if (anArgIter + 1 < theArgNb
10905 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
10908 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
10911 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
10914 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
10917 else if (aParam == "weighted"
10918 || aParam == "weight")
10920 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
10921 if (anArgIter + 1 < theArgNb
10922 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
10925 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
10926 if (aWeight < 0.f || aWeight > 1.f)
10928 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
10931 aParams.OitDepthFactor = aWeight;
10934 else if (aParam.IsRealValue())
10936 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
10937 if (aWeight < 0.f || aWeight > 1.f)
10939 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
10943 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
10944 aParams.OitDepthFactor = aWeight;
10946 else if (aParam == "off")
10948 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
10952 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10956 else if (aFlag == "-fonthinting"
10957 || aFlag == "-fonthint")
10961 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
10963 theDI << "normal" << " ";
10965 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
10967 theDI << "light" << " ";
10971 theDI << "off" << " ";
10975 else if (anArgIter + 1 >= theArgNb)
10977 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
10981 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
10982 aHintStyle.LowerCase();
10983 if (aHintStyle == "normal"
10984 || aHintStyle == "on"
10985 || aHintStyle == "1")
10987 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
10988 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
10990 else if (aHintStyle == "light")
10992 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
10993 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
10995 else if (aHintStyle == "no"
10996 || aHintStyle == "off"
10997 || aHintStyle == "0")
10999 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11000 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11004 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11008 else if (aFlag == "-fontautohinting"
11009 || aFlag == "-fontautohint")
11013 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11015 theDI << "force" << " ";
11017 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11019 theDI << "disallow" << " ";
11023 theDI << "auto" << " ";
11027 else if (anArgIter + 1 >= theArgNb)
11029 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11033 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11034 aHintStyle.LowerCase();
11035 if (aHintStyle == "force")
11037 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11038 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11040 else if (aHintStyle == "disallow"
11041 || aHintStyle == "no")
11043 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11044 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11046 else if (aHintStyle == "auto")
11048 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11049 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11053 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11057 else if (aFlag == "-depthprepass")
11061 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11064 aParams.ToEnableDepthPrepass = Standard_True;
11065 if (anArgIter + 1 < theArgNb
11066 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
11071 else if (aFlag == "-samplealphatocoverage"
11072 || aFlag == "-alphatocoverage")
11076 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11079 aParams.ToEnableAlphaToCoverage = Standard_True;
11080 if (anArgIter + 1 < theArgNb
11081 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
11086 else if (aFlag == "-rendscale"
11087 || aFlag == "-renderscale"
11088 || aFlag == "-renderresolutionscale")
11092 theDI << aParams.RenderResolutionScale << " ";
11095 else if (++anArgIter >= theArgNb)
11097 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11101 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11104 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
11109 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11112 else if (aFlag == "-raydepth"
11113 || aFlag == "-ray_depth")
11117 theDI << aParams.RaytracingDepth << " ";
11120 else if (++anArgIter >= theArgNb)
11122 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11126 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
11128 // We allow RaytracingDepth be more than 10 in case of GI enabled
11129 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
11131 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
11136 aParams.RaytracingDepth = aDepth;
11139 else if (aFlag == "-shad"
11140 || aFlag == "-shadows")
11144 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11148 Standard_Boolean toEnable = Standard_True;
11149 if (++anArgIter < theArgNb
11150 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11154 aParams.IsShadowEnabled = toEnable;
11156 else if (aFlag == "-shadowmapresolution"
11157 || aFlag == "-shadowmap")
11161 theDI << aParams.ShadowMapResolution << " ";
11164 else if (++anArgIter >= theArgNb)
11166 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11170 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11172 else if (aFlag == "-shadowmapbias")
11176 theDI << aParams.ShadowMapBias << " ";
11179 else if (++anArgIter >= theArgNb)
11181 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11185 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11187 else if (aFlag == "-refl"
11188 || aFlag == "-reflections")
11192 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11196 Standard_Boolean toEnable = Standard_True;
11197 if (++anArgIter < theArgNb
11198 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11202 aParams.IsReflectionEnabled = toEnable;
11204 else if (aFlag == "-fsaa")
11208 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11212 Standard_Boolean toEnable = Standard_True;
11213 if (++anArgIter < theArgNb
11214 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11218 aParams.IsAntialiasingEnabled = toEnable;
11220 else if (aFlag == "-gleam")
11224 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11228 Standard_Boolean toEnable = Standard_True;
11229 if (++anArgIter < theArgNb
11230 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11234 aParams.IsTransparentShadowEnabled = toEnable;
11236 else if (aFlag == "-gi")
11240 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11244 Standard_Boolean toEnable = Standard_True;
11245 if (++anArgIter < theArgNb
11246 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11250 aParams.IsGlobalIlluminationEnabled = toEnable;
11253 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11256 else if (aFlag == "-blockedrng"
11257 || aFlag == "-brng")
11261 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11265 Standard_Boolean toEnable = Standard_True;
11266 if (++anArgIter < theArgNb
11267 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11271 aParams.CoherentPathTracingMode = toEnable;
11273 else if (aFlag == "-maxrad")
11277 theDI << aParams.RadianceClampingValue << " ";
11280 else if (++anArgIter >= theArgNb)
11282 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11286 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11287 if (!aMaxRadStr.IsRealValue (Standard_True))
11289 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11293 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11294 if (aMaxRadiance <= 0.0)
11296 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
11301 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11304 else if (aFlag == "-iss")
11308 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11312 Standard_Boolean toEnable = Standard_True;
11313 if (++anArgIter < theArgNb
11314 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11318 aParams.AdaptiveScreenSampling = toEnable;
11320 else if (aFlag == "-issatomic")
11324 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
11328 Standard_Boolean toEnable = Standard_True;
11329 if (++anArgIter < theArgNb
11330 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11334 aParams.AdaptiveScreenSamplingAtomic = toEnable;
11336 else if (aFlag == "-issd")
11340 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
11344 Standard_Boolean toEnable = Standard_True;
11345 if (++anArgIter < theArgNb
11346 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11350 aParams.ShowSamplingTiles = toEnable;
11352 else if (aFlag == "-tilesize")
11356 theDI << aParams.RayTracingTileSize << " ";
11359 else if (++anArgIter >= theArgNb)
11361 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11365 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
11368 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
11371 aParams.RayTracingTileSize = aTileSize;
11373 else if (aFlag == "-nbtiles")
11377 theDI << aParams.NbRayTracingTiles << " ";
11380 else if (++anArgIter >= theArgNb)
11382 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11386 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
11389 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
11392 else if (aNbTiles > 0
11394 || aNbTiles > 1024))
11396 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
11398 aParams.NbRayTracingTiles = aNbTiles;
11400 else if (aFlag == "-env")
11404 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
11408 Standard_Boolean toEnable = Standard_True;
11409 if (++anArgIter < theArgNb
11410 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11414 aParams.UseEnvironmentMapBackground = toEnable;
11416 else if (aFlag == "-ignorenormalmap")
11420 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
11424 Standard_Boolean toEnable = Standard_True;
11425 if (++anArgIter < theArgNb
11426 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11430 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
11432 else if (aFlag == "-twoside")
11436 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
11440 Standard_Boolean toEnable = Standard_True;
11441 if (++anArgIter < theArgNb
11442 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11446 aParams.TwoSidedBsdfModels = toEnable;
11448 else if (aFlag == "-shademodel"
11449 || aFlag == "-shadingmodel"
11450 || aFlag == "-shading")
11454 switch (aView->ShadingModel())
11456 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
11457 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit "; break;
11458 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat "; break;
11459 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud "; break;
11460 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong "; break;
11461 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
11462 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
11467 if (++anArgIter >= theArgNb)
11469 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11472 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TypeOfShadingModel_DEFAULT;
11473 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
11474 && aModel != Graphic3d_TypeOfShadingModel_DEFAULT)
11476 aView->SetShadingModel (aModel);
11480 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
11484 else if (aFlag == "-pbrenvpow2size"
11485 || aFlag == "-pbrenvp2s"
11486 || aFlag == "-pep2s")
11488 if (++anArgIter >= theArgNb)
11490 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11494 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
11495 if (aPbrEnvPow2Size < 1)
11497 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
11500 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
11502 else if (aFlag == "-pbrenvspecmaplevelsnumber"
11503 || aFlag == "-pbrenvspecmapnblevels"
11504 || aFlag == "-pbrenvspecmaplevels"
11505 || aFlag == "-pbrenvsmln"
11506 || aFlag == "-pesmln")
11508 if (++anArgIter >= theArgNb)
11510 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11514 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
11515 if (aPbrEnvSpecMapNbLevels < 2)
11517 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
11520 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
11522 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
11523 || aFlag == "-pbrenvbakingdiffsamples"
11524 || aFlag == "-pbrenvbdsn")
11526 if (++anArgIter >= theArgNb)
11528 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11532 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11533 if (aPbrEnvBakingDiffNbSamples < 1)
11535 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
11538 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
11540 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
11541 || aFlag == "-pbrenvbakingspecsamples"
11542 || aFlag == "-pbrenvbssn")
11544 if (++anArgIter >= theArgNb)
11546 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11550 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
11551 if (aPbrEnvBakingSpecNbSamples < 1)
11553 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
11556 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
11558 else if (aFlag == "-pbrenvbakingprobability"
11559 || aFlag == "-pbrenvbp")
11561 if (++anArgIter >= theArgNb)
11563 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11566 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
11567 if (aPbrEnvBakingProbability < 0.f
11568 || aPbrEnvBakingProbability > 1.f)
11570 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
11573 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
11575 else if (aFlag == "-resolution")
11577 if (++anArgIter >= theArgNb)
11579 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11583 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
11584 if (aResolution.IsIntegerValue())
11586 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
11590 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
11594 else if (aFlag == "-rebuildglsl"
11595 || aFlag == "-rebuild")
11599 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
11603 Standard_Boolean toEnable = Standard_True;
11604 if (++anArgIter < theArgNb
11605 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11609 aParams.RebuildRayTracingShaders = toEnable;
11611 else if (aFlag == "-focal")
11613 if (++anArgIter >= theArgNb)
11615 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11619 TCollection_AsciiString aParam (theArgVec[anArgIter]);
11620 if (aParam.IsRealValue (Standard_True))
11622 float aFocalDist = static_cast<float> (aParam.RealValue());
11623 if (aFocalDist < 0)
11625 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11628 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
11632 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11636 else if (aFlag == "-aperture")
11638 if (++anArgIter >= theArgNb)
11640 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11644 TCollection_AsciiString aParam(theArgVec[anArgIter]);
11645 if (aParam.IsRealValue (Standard_True))
11647 float aApertureSize = static_cast<float> (aParam.RealValue());
11648 if (aApertureSize < 0)
11650 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11653 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
11657 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11661 else if (aFlag == "-exposure")
11663 if (++anArgIter >= theArgNb)
11665 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11669 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
11670 if (anExposure.IsRealValue (Standard_True))
11672 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
11676 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11680 else if (aFlag == "-whitepoint")
11682 if (++anArgIter >= theArgNb)
11684 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11688 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
11689 if (aWhitePoint.IsRealValue (Standard_True))
11691 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
11695 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11699 else if (aFlag == "-tonemapping")
11701 if (++anArgIter >= theArgNb)
11703 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11707 TCollection_AsciiString aMode (theArgVec[anArgIter]);
11710 if (aMode == "disabled")
11712 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
11714 else if (aMode == "filmic")
11716 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
11720 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11724 else if (aFlag == "-performancestats"
11725 || aFlag == "-performancecounters"
11726 || aFlag == "-perfstats"
11727 || aFlag == "-perfcounters"
11728 || aFlag == "-stats")
11730 if (++anArgIter >= theArgNb)
11732 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11736 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
11737 aFlagsStr.LowerCase();
11738 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
11739 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
11741 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11744 aView->ChangeRenderingParams().CollectedStats = aFlags;
11745 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
11747 else if (aFlag == "-perfupdateinterval"
11748 || aFlag == "-statsupdateinterval")
11750 if (++anArgIter >= theArgNb)
11752 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11755 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
11757 else if (aFlag == "-perfchart"
11758 || aFlag == "-statschart")
11760 if (++anArgIter >= theArgNb)
11762 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11765 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
11767 else if (aFlag == "-perfchartmax"
11768 || aFlag == "-statschartmax")
11770 if (++anArgIter >= theArgNb)
11772 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11775 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
11777 else if (aFlag == "-frustumculling"
11778 || aFlag == "-culling")
11782 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
11783 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
11784 "noUpdate") << " ";
11788 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
11789 if (++anArgIter < theArgNb)
11791 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
11792 aStateStr.LowerCase();
11793 bool toEnable = true;
11794 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
11796 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
11798 else if (aStateStr == "noupdate"
11799 || aStateStr == "freeze")
11801 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
11808 aParams.FrustumCullingState = aState;
11812 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
11817 // set current view parameters as defaults
11818 if (toSyncDefaults)
11820 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
11822 if (toSyncAllViews)
11824 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
11826 aViewIter.Value()->ChangeRenderingParams() = aParams;
11832 //=======================================================================
11833 //function : searchInfo
11835 //=======================================================================
11836 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
11837 const TCollection_AsciiString& theKey)
11839 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
11841 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
11843 return anIter.Value();
11846 return TCollection_AsciiString();
11849 //=======================================================================
11850 //function : VStatProfiler
11852 //=======================================================================
11853 static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
11854 Standard_Integer theArgNb,
11855 const char** theArgVec)
11857 Handle(V3d_View) aView = ViewerTest::CurrentView();
11858 if (aView.IsNull())
11860 Message::SendFail ("Error: no active viewer");
11864 Standard_Boolean toRedraw = Standard_True;
11865 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
11866 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
11867 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
11868 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11870 Standard_CString anArg (theArgVec[anArgIter]);
11871 TCollection_AsciiString aFlag (anArg);
11873 if (aFlag == "-noredraw")
11875 toRedraw = Standard_False;
11879 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
11880 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
11881 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
11882 else if (aFlag == "alllayers"
11883 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
11884 else if (aFlag == "allstructs"
11885 || aFlag == "allstructures"
11886 || aFlag == "structs"
11887 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
11888 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
11889 else if (aFlag == "allarrays"
11890 || aFlag == "fillarrays"
11891 || aFlag == "linearrays"
11892 || aFlag == "pointarrays"
11893 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
11894 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
11895 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
11896 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
11897 else if (aFlag == "geommem"
11898 || aFlag == "texturemem"
11899 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
11900 else if (aFlag == "elapsedframe"
11901 || aFlag == "cpuframeaverage"
11902 || aFlag == "cpupickingaverage"
11903 || aFlag == "cpucullingaverage"
11904 || aFlag == "cpudynaverage"
11905 || aFlag == "cpuframemax"
11906 || aFlag == "cpupickingmax"
11907 || aFlag == "cpucullingmax"
11908 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
11911 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
11915 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
11919 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
11921 aView->ChangeRenderingParams().CollectedStats =
11922 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
11926 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
11928 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
11931 TColStd_IndexedDataMapOfStringString aDict;
11932 aView->StatisticInformation (aDict);
11934 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
11936 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
11938 Standard_CString anArg(theArgVec[anArgIter]);
11939 TCollection_AsciiString aFlag(anArg);
11941 if (aFlag == "fps")
11943 theDI << searchInfo (aDict, "FPS") << " ";
11945 else if (aFlag == "cpu")
11947 theDI << searchInfo (aDict, "CPU FPS") << " ";
11949 else if (aFlag == "alllayers")
11951 theDI << searchInfo (aDict, "Layers") << " ";
11953 else if (aFlag == "layers")
11955 theDI << searchInfo (aDict, "Rendered layers") << " ";
11957 else if (aFlag == "allstructs"
11958 || aFlag == "allstructures")
11960 theDI << searchInfo (aDict, "Structs") << " ";
11962 else if (aFlag == "structs"
11963 || aFlag == "structures")
11965 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
11966 if (aRend.IsEmpty()) // all structures rendered
11968 aRend = searchInfo (aDict, "Structs");
11970 theDI << aRend << " ";
11972 else if (aFlag == "groups")
11974 theDI << searchInfo (aDict, "Rendered groups") << " ";
11976 else if (aFlag == "allarrays")
11978 theDI << searchInfo (aDict, "Rendered arrays") << " ";
11980 else if (aFlag == "fillarrays")
11982 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
11984 else if (aFlag == "linearrays")
11986 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
11988 else if (aFlag == "pointarrays")
11990 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
11992 else if (aFlag == "textarrays")
11994 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
11996 else if (aFlag == "triangles")
11998 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12000 else if (aFlag == "points")
12002 theDI << searchInfo (aDict, "Rendered points") << " ";
12004 else if (aFlag == "geommem")
12006 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12008 else if (aFlag == "texturemem")
12010 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12012 else if (aFlag == "framemem")
12014 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12016 else if (aFlag == "elapsedframe")
12018 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12020 else if (aFlag == "cpuframe_average")
12022 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12024 else if (aFlag == "cpupicking_average")
12026 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12028 else if (aFlag == "cpuculling_average")
12030 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12032 else if (aFlag == "cpudyn_average")
12034 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12036 else if (aFlag == "cpuframe_max")
12038 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12040 else if (aFlag == "cpupicking_max")
12042 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12044 else if (aFlag == "cpuculling_max")
12046 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12048 else if (aFlag == "cpudyn_max")
12050 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12058 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12060 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12062 theDI << "Statistic info:\n" << aView->StatisticInformation();
12067 //=======================================================================
12068 //function : VXRotate
12070 //=======================================================================
12071 static Standard_Integer VXRotate (Draw_Interpretor& di,
12072 Standard_Integer argc,
12073 const char ** argv)
12075 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12076 if (aContext.IsNull())
12078 di << argv[0] << "ERROR : use 'vinit' command before \n";
12084 di << "ERROR : Usage : " << argv[0] << " name angle\n";
12088 TCollection_AsciiString aName (argv[1]);
12089 Standard_Real anAngle = Draw::Atof (argv[2]);
12092 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12093 Handle(AIS_InteractiveObject) anIObj;
12094 if (!aMap.Find2 (aName, anIObj))
12096 di << "Use 'vdisplay' before\n";
12100 gp_Trsf aTransform;
12101 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12102 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
12104 aContext->SetLocation (anIObj, aTransform);
12105 aContext->UpdateCurrentViewer();
12111 //! Structure for setting AIS_Manipulator::SetPart() property.
12112 struct ManipAxisModeOnOff
12114 Standard_Integer Axis;
12115 AIS_ManipulatorMode Mode;
12116 Standard_Boolean ToEnable;
12118 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12121 enum ManipAjustPosition
12123 ManipAjustPosition_Off,
12124 ManipAjustPosition_Center,
12125 ManipAjustPosition_Location,
12126 ManipAjustPosition_ShapeLocation,
12130 //===============================================================================================
12131 //function : VManipulator
12133 //===============================================================================================
12134 static int VManipulator (Draw_Interpretor& theDi,
12135 Standard_Integer theArgsNb,
12136 const char** theArgVec)
12138 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
12139 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12140 if (aCurrentView.IsNull()
12141 || aViewer.IsNull())
12143 Message::SendFail ("Error: no active viewer");
12147 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12148 Standard_Integer anArgIter = 1;
12149 Handle(AIS_Manipulator) aManipulator;
12150 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12151 TCollection_AsciiString aName;
12153 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12154 Standard_Real aGap = -1.0, aSize = -1.0;
12155 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12156 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12158 bool toDetach = false;
12159 AIS_Manipulator::OptionsForAttach anAttachOptions;
12160 Handle(AIS_InteractiveObject) anAttachObject;
12161 Handle(V3d_View) aViewAffinity;
12162 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12164 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12165 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12166 Standard_Integer toStopMouseTransform = -1;
12167 // explicit transformation
12170 Standard_Real aTmpReal = 0.0;
12171 gp_XYZ aRotPnt, aRotAxis;
12172 for (; anArgIter < theArgsNb; ++anArgIter)
12174 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12176 if (anUpdateTool.parseRedrawMode (anArg))
12180 else if (anArg == "-help")
12182 theDi.PrintHelp (theArgVec[0]);
12186 else if (anArg == "-autoactivate"
12187 || anArg == "-noautoactivate")
12189 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12191 else if (anArg == "-followtranslation"
12192 || anArg == "-nofollowtranslation")
12194 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12196 else if (anArg == "-followrotation"
12197 || anArg == "-nofollowrotation")
12199 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12201 else if (anArg == "-followdragging"
12202 || anArg == "-nofollowdragging")
12204 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12206 else if (anArg == "-gap"
12207 && anArgIter + 1 < theArgsNb
12208 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12213 else if (anArg == "-size"
12214 && anArgIter + 1 < theArgsNb
12215 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12220 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12221 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12223 ManipAxisModeOnOff aPart;
12224 Standard_Integer aMode = 0;
12225 if (anArg == "-part")
12227 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12228 || aPart.Axis < 0 || aPart.Axis > 3)
12230 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12234 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12235 || aMode < 1 || aMode > 4)
12237 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12240 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12242 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12245 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12246 aParts.Append (aPart);
12248 else if (anArg == "-pos"
12249 && anArgIter + 3 < theArgsNb
12250 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12253 if (anArgIter + 3 < theArgsNb
12254 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12255 && aVDir.Modulus() > Precision::Confusion())
12259 if (anArgIter + 3 < theArgsNb
12260 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12261 && anXDir.Modulus() > Precision::Confusion())
12266 else if (anArg == "-zoomable"
12267 || anArg == "-notzoomable")
12269 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12272 else if (anArg == "-adjustposition"
12273 || anArg == "-noadjustposition")
12275 anAttachPos = ManipAjustPosition_Center;
12276 if (anArgIter + 1 < theArgsNb)
12278 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12279 aPosName.LowerCase();
12280 if (aPosName == "0")
12282 anAttachPos = ManipAjustPosition_Off;
12284 else if (aPosName == "1"
12285 || aPosName == "center")
12287 anAttachPos = ManipAjustPosition_Center;
12289 else if (aPosName == "transformation"
12290 || aPosName == "trsf"
12291 || aPosName == "location"
12292 || aPosName == "loc")
12294 anAttachPos = ManipAjustPosition_Location;
12296 else if (aPosName == "shapelocation"
12297 || aPosName == "shapeloc")
12299 anAttachPos = ManipAjustPosition_ShapeLocation;
12306 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12308 else if (anArg == "-adjustsize"
12309 || anArg == "-noadjustsize")
12311 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12313 else if (anArg == "-enablemodes"
12314 || anArg == "-enablemodes")
12316 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12319 else if (anArg == "-starttransform"
12320 && anArgIter + 2 < theArgsNb
12321 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12322 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
12326 else if (anArg == "-transform"
12327 && anArgIter + 2 < theArgsNb
12328 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
12329 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
12333 else if (anArg == "-stoptransform")
12335 toStopMouseTransform = 1;
12336 if (anArgIter + 1 < theArgsNb
12337 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
12340 toStopMouseTransform = 0;
12344 else if (anArg == "-move"
12345 && anArgIter + 3 < theArgsNb
12346 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
12349 aTrsf.SetTranslationPart (aTmpXYZ);
12351 else if (anArg == "-scale"
12352 && anArgIter + 1 < theArgsNb
12353 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
12356 aTrsf.SetScale (gp_Pnt(), aTmpReal);
12358 else if (anArg == "-rotate"
12359 && anArgIter + 7 < theArgsNb
12360 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
12361 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
12362 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
12365 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
12368 else if (anArg == "-detach")
12372 else if (anArg == "-attach"
12373 && anArgIter + 1 < theArgsNb)
12375 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
12376 if (!aMapAIS.Find2 (anObjName, anAttachObject))
12378 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
12382 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
12384 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
12385 if (!aManip.IsNull()
12386 && aManip->IsAttached()
12387 && aManip->Object() == anAttachObject)
12389 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
12394 else if (anArg == "-view"
12395 && anArgIter + 1 < theArgsNb
12396 && aViewAffinity.IsNull())
12398 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
12399 if (aViewString == "active")
12401 aViewAffinity = ViewerTest::CurrentView();
12403 else // Check view name
12405 ViewerTest_Names aViewNames (aViewString);
12406 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
12408 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
12411 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
12412 if (aViewAffinity.IsNull())
12414 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
12419 else if (aName.IsEmpty())
12421 aName = theArgVec[anArgIter];
12422 if (!aMapAIS.IsBound2 (aName))
12424 aManipulator = new AIS_Manipulator();
12425 aManipulator->SetModeActivationOnDetection (true);
12426 aMapAIS.Bind (aManipulator, aName);
12430 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12431 if (aManipulator.IsNull())
12433 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
12440 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
12444 if (aName.IsEmpty())
12446 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
12450 && aManipulator.IsNull())
12452 aManipulator = new AIS_Manipulator();
12453 aManipulator->SetModeActivationOnDetection (true);
12454 aMapAIS.Bind (aManipulator, aName);
12457 // -----------------------------------------
12458 // change properties of manipulator instance
12459 // -----------------------------------------
12461 if (toAutoActivate != -1)
12463 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
12465 if (toFollowTranslation != -1)
12467 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
12469 if (toFollowRotation != -1)
12471 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
12473 if (toFollowDragging != -1)
12475 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
12479 aManipulator->SetGap ((float )aGap);
12482 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
12484 const ManipAxisModeOnOff& aPart = aPartIter.Value();
12485 if (aPart.Axis == -1)
12487 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
12491 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
12497 aManipulator->SetSize ((float )aSize);
12499 if (isZoomable != -1)
12501 aManipulator->SetZoomPersistence (isZoomable == 0);
12503 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12505 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
12506 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
12510 // ----------------------------------
12511 // detach existing manipulator object
12512 // ----------------------------------
12516 aManipulator->Detach();
12517 aMapAIS.UnBind2 (aName);
12518 ViewerTest::GetAISContext()->Remove (aManipulator, false);
12521 // ---------------------------------------------------
12522 // attach, detach or access manipulator from an object
12523 // ---------------------------------------------------
12525 if (!anAttachObject.IsNull())
12527 aManipulator->Attach (anAttachObject, anAttachOptions);
12529 if (!aViewAffinity.IsNull())
12531 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
12532 anIter.More(); anIter.Next())
12534 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
12536 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
12539 if (anAttachPos != ManipAjustPosition_Off
12540 && aManipulator->IsAttached()
12541 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
12543 gp_Ax2 aPosition = gp::XOY();
12544 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
12545 switch (anAttachPos)
12547 case ManipAjustPosition_Off:
12551 case ManipAjustPosition_Location:
12553 aPosition = gp::XOY().Transformed (aBaseTrsf);
12556 case ManipAjustPosition_ShapeLocation:
12558 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
12560 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
12564 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
12569 case ManipAjustPosition_Center:
12572 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
12575 anObjIter.Value()->BoundingBox (anObjBox);
12576 aBox.Add (anObjBox);
12578 aBox = aBox.FinitePart();
12579 if (!aBox.IsVoid())
12581 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
12582 aPosition.SetLocation (aCenter);
12587 aManipulator->SetPosition (aPosition);
12589 if (!Precision::IsInfinite (aLocation.X()))
12591 if (aVDir.Modulus() <= Precision::Confusion())
12593 aVDir = aManipulator->Position().Direction().XYZ();
12595 if (anXDir.Modulus() <= Precision::Confusion())
12597 anXDir = aManipulator->Position().XDirection().XYZ();
12599 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
12602 // --------------------------------------
12603 // apply transformation using manipulator
12604 // --------------------------------------
12606 if (aMousePosFrom.x() != IntegerLast())
12608 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
12610 if (aMousePosTo.x() != IntegerLast())
12612 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
12614 if (toStopMouseTransform != -1)
12616 aManipulator->StopTransform (toStopMouseTransform == 1);
12619 if (aTrsf.Form() != gp_Identity)
12621 aManipulator->Transform (aTrsf);
12624 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12626 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
12631 //===============================================================================================
12632 //function : VSelectionProperties
12634 //===============================================================================================
12635 static int VSelectionProperties (Draw_Interpretor& theDi,
12636 Standard_Integer theArgsNb,
12637 const char** theArgVec)
12639 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
12642 Message::SendFail ("Error: no active viewer");
12646 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
12648 // handle obsolete alias
12649 bool toEnable = true;
12652 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
12655 else if (theArgsNb != 2
12656 || !Draw::ParseOnOff (theArgVec[1], toEnable))
12658 Message::SendFail ("Syntax error: wrong number of parameters");
12661 if (toEnable != aCtx->ToHilightSelected())
12663 aCtx->ClearDetected();
12664 aCtx->SetToHilightSelected (toEnable);
12669 Standard_Boolean toPrint = theArgsNb == 1;
12670 Standard_Boolean toRedraw = Standard_False;
12671 Standard_Integer anArgIter = 1;
12672 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
12673 if (anArgIter < theArgsNb)
12675 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
12676 anArgFirst.LowerCase();
12678 if (anArgFirst == "dynhighlight"
12679 || anArgFirst == "dynhilight"
12680 || anArgFirst == "dynamichighlight"
12681 || anArgFirst == "dynamichilight")
12683 aType = Prs3d_TypeOfHighlight_Dynamic;
12685 else if (anArgFirst == "localdynhighlight"
12686 || anArgFirst == "localdynhilight"
12687 || anArgFirst == "localdynamichighlight"
12688 || anArgFirst == "localdynamichilight")
12690 aType = Prs3d_TypeOfHighlight_LocalDynamic;
12692 else if (anArgFirst == "selhighlight"
12693 || anArgFirst == "selhilight"
12694 || anArgFirst == "selectedhighlight"
12695 || anArgFirst == "selectedhilight")
12697 aType = Prs3d_TypeOfHighlight_Selected;
12699 else if (anArgFirst == "localselhighlight"
12700 || anArgFirst == "localselhilight"
12701 || anArgFirst == "localselectedhighlight"
12702 || anArgFirst == "localselectedhilight")
12704 aType = Prs3d_TypeOfHighlight_LocalSelected;
12711 for (; anArgIter < theArgsNb; ++anArgIter)
12713 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12715 if (anArg == "-help")
12717 theDi.PrintHelp (theArgVec[0]);
12720 else if (anArg == "-print")
12722 toPrint = Standard_True;
12724 else if (anArg == "-autoactivate")
12726 Standard_Boolean toEnable = Standard_True;
12727 if (anArgIter + 1 < theArgsNb
12728 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12732 aCtx->SetAutoActivateSelection (toEnable);
12734 else if (anArg == "-automatichighlight"
12735 || anArg == "-automatichilight"
12736 || anArg == "-autohighlight"
12737 || anArg == "-autohilight")
12739 Standard_Boolean toEnable = Standard_True;
12740 if (anArgIter + 1 < theArgsNb
12741 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12745 aCtx->ClearSelected (false);
12746 aCtx->ClearDetected();
12747 aCtx->SetAutomaticHilight (toEnable);
12750 else if (anArg == "-highlightselected"
12751 || anArg == "-hilightselected")
12753 Standard_Boolean toEnable = Standard_True;
12754 if (anArgIter + 1 < theArgsNb
12755 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12759 aCtx->ClearDetected();
12760 aCtx->SetToHilightSelected (toEnable);
12763 else if (anArg == "-pickstrategy"
12764 || anArg == "-pickingstrategy")
12766 if (++anArgIter >= theArgsNb)
12768 Message::SendFail ("Syntax error: type of highlighting is undefined");
12772 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
12773 TCollection_AsciiString aVal (theArgVec[anArgIter]);
12775 if (aVal == "first"
12776 || aVal == "firstaccepted"
12777 || aVal == "firstacceptable")
12779 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
12781 else if (aVal == "topmost"
12782 || aVal == "onlyTopmost")
12784 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
12788 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
12792 aCtx->SetPickingStrategy (aStrategy);
12794 else if (anArg == "-pixtol"
12795 && anArgIter + 1 < theArgsNb)
12797 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
12799 else if (anArg == "-preferclosest")
12801 bool toPreferClosest = true;
12802 if (anArgIter + 1 < theArgsNb
12803 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
12807 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
12809 else if ((anArg == "-depthtol"
12810 || anArg == "-depthtolerance")
12811 && anArgIter + 1 < theArgsNb)
12813 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
12814 aTolType.LowerCase();
12815 if (aTolType == "uniform")
12817 if (anArgIter + 1 >= theArgsNb)
12819 Message::SendFail() << "Syntax error: wrong number of arguments";
12822 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
12823 Draw::Atof (theArgVec[++anArgIter]));
12825 else if (aTolType == "uniformpx")
12827 if (anArgIter + 1 >= theArgsNb)
12829 Message::SendFail() << "Syntax error: wrong number of arguments";
12832 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
12833 Draw::Atof (theArgVec[++anArgIter]));
12835 else if (aTolType == "sensfactor")
12837 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
12841 Message::SendFail() << "Syntax error at '" << aTolType << "'";
12845 else if ((anArg == "-mode"
12846 || anArg == "-dispmode")
12847 && anArgIter + 1 < theArgsNb)
12849 if (aType == Prs3d_TypeOfHighlight_None)
12851 Message::SendFail ("Syntax error: type of highlighting is undefined");
12855 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
12856 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
12857 aStyle->SetDisplayMode (aDispMode);
12858 toRedraw = Standard_True;
12860 else if (anArg == "-layer"
12861 && anArgIter + 1 < theArgsNb)
12863 if (aType == Prs3d_TypeOfHighlight_None)
12865 Message::SendFail ("Syntax error: type of highlighting is undefined");
12870 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
12871 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
12873 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
12877 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
12878 aStyle->SetZLayer (aNewLayer);
12879 toRedraw = Standard_True;
12881 else if (anArg == "-hicolor"
12882 || anArg == "-selcolor"
12883 || anArg == "-color")
12885 if (anArg.StartsWith ("-hi"))
12887 aType = Prs3d_TypeOfHighlight_Dynamic;
12889 else if (anArg.StartsWith ("-sel"))
12891 aType = Prs3d_TypeOfHighlight_Selected;
12893 else if (aType == Prs3d_TypeOfHighlight_None)
12895 Message::SendFail ("Syntax error: type of highlighting is undefined");
12899 Quantity_Color aColor;
12900 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
12901 theArgVec + anArgIter + 1,
12903 if (aNbParsed == 0)
12905 Message::SendFail ("Syntax error: need more arguments");
12908 anArgIter += aNbParsed;
12910 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
12911 aStyle->SetColor (aColor);
12912 toRedraw = Standard_True;
12914 else if ((anArg == "-transp"
12915 || anArg == "-transparency"
12916 || anArg == "-hitransp"
12917 || anArg == "-seltransp"
12918 || anArg == "-hitransplocal"
12919 || anArg == "-seltransplocal")
12920 && anArgIter + 1 < theArgsNb)
12922 if (anArg.StartsWith ("-hi"))
12924 aType = Prs3d_TypeOfHighlight_Dynamic;
12926 else if (anArg.StartsWith ("-sel"))
12928 aType = Prs3d_TypeOfHighlight_Selected;
12930 else if (aType == Prs3d_TypeOfHighlight_None)
12932 Message::SendFail ("Syntax error: type of highlighting is undefined");
12936 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
12937 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
12938 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
12939 toRedraw = Standard_True;
12941 else if ((anArg == "-mat"
12942 || anArg == "-material")
12943 && anArgIter + 1 < theArgsNb)
12945 if (aType == Prs3d_TypeOfHighlight_None)
12947 Message::SendFail ("Syntax error: type of highlighting is undefined");
12951 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
12952 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
12953 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
12956 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
12957 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
12958 Graphic3d_MaterialAspect aMat (aMatName);
12959 aMat.SetColor (aStyle->Color());
12960 aMat.SetTransparency (aStyle->Transparency());
12961 anAspect->SetFrontMaterial (aMat);
12962 anAspect->SetInteriorColor (aStyle->Color());
12963 aStyle->SetBasicFillAreaAspect (anAspect);
12967 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
12969 toRedraw = Standard_True;
12973 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
12980 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
12981 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
12982 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
12983 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
12984 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
12985 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
12986 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
12987 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
12988 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
12989 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
12990 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
12991 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
12992 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
12993 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
12996 if (aCtx->NbSelected() != 0 && toRedraw)
12998 aCtx->HilightSelected (Standard_True);
13004 //===============================================================================================
13005 //function : VDumpSelectionImage
13007 //===============================================================================================
13008 static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13009 Standard_Integer theArgsNb,
13010 const char** theArgVec)
13012 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13013 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13014 if (aContext.IsNull())
13016 Message::SendFail ("Error: no active viewer");
13020 TCollection_AsciiString aFile;
13021 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13022 Handle(Graphic3d_Camera) aCustomCam;
13023 Image_Format anImgFormat = Image_Format_BGR;
13024 Standard_Integer aPickedIndex = 1;
13025 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13027 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13028 aParam.LowerCase();
13029 if (aParam == "-type")
13031 if (++anArgIter >= theArgsNb)
13033 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
13037 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13038 aValue.LowerCase();
13039 if (aValue == "depth"
13040 || aValue == "normdepth"
13041 || aValue == "normalizeddepth")
13043 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13044 anImgFormat = Image_Format_GrayF;
13046 else if (aValue == "depthinverted"
13047 || aValue == "normdepthinverted"
13048 || aValue == "normalizeddepthinverted"
13049 || aValue == "inverted")
13051 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
13052 anImgFormat = Image_Format_GrayF;
13054 else if (aValue == "unnormdepth"
13055 || aValue == "unnormalizeddepth")
13057 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
13058 anImgFormat = Image_Format_GrayF;
13060 else if (aValue == "objectcolor"
13061 || aValue == "object"
13062 || aValue == "color")
13064 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13066 else if (aValue == "entitycolor"
13067 || aValue == "entity")
13069 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13071 else if (aValue == "entitytypecolor"
13072 || aValue == "entitytype")
13074 aType = StdSelect_TypeOfSelectionImage_ColoredEntityType;
13076 else if (aValue == "ownercolor"
13077 || aValue == "owner")
13079 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13081 else if (aValue == "selectionmodecolor"
13082 || aValue == "selectionmode"
13083 || aValue == "selmodecolor"
13084 || aValue == "selmode")
13086 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13088 else if (aValue == "surfnormal"
13089 || aValue == "surfacenormal"
13090 || aValue == "normal")
13092 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13096 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13100 else if (aParam == "-picked"
13101 || aParam == "-pickeddepth"
13102 || aParam == "-pickedindex")
13104 if (++anArgIter >= theArgsNb)
13106 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
13110 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13112 else if (anArgIter + 1 < theArgsNb
13113 && aParam == "-xrpose")
13115 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13116 anXRArg.LowerCase();
13117 if (anXRArg == "base")
13119 aCustomCam = aView->View()->BaseXRCamera();
13121 else if (anXRArg == "head")
13123 aCustomCam = aView->View()->PosedXRCamera();
13127 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13130 if (aCustomCam.IsNull())
13132 Message::SendFail() << "Error: undefined XR pose";
13136 else if (aFile.IsEmpty())
13138 aFile = theArgVec[anArgIter];
13142 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13146 if (aFile.IsEmpty())
13148 Message::SendFail ("Syntax error: image file name is missing");
13152 Standard_Integer aWidth = 0, aHeight = 0;
13153 aView->Window()->Size (aWidth, aHeight);
13155 Image_AlienPixMap aPixMap;
13156 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13158 Message::SendFail ("Error: can't allocate image");
13162 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13163 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13164 if (!aCustomCam.IsNull())
13166 aView->SetCamera (aCustomCam);
13168 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13170 Message::SendFail ("Error: can't generate selection image");
13173 if (!aCustomCam.IsNull())
13175 aView->SetCamera (aCamBack);
13177 aView->SetImmediateUpdate (wasImmUpdate);
13179 if (!aPixMap.Save (aFile))
13181 Message::SendFail ("Error: can't save selection image");
13187 //===============================================================================================
13188 //function : VViewCube
13190 //===============================================================================================
13191 static int VViewCube (Draw_Interpretor& ,
13192 Standard_Integer theNbArgs,
13193 const char** theArgVec)
13195 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13196 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13197 if (aContext.IsNull() || aView.IsNull())
13199 Message::SendFail ("Error: no active viewer");
13202 else if (theNbArgs < 2)
13204 Message::SendFail ("Syntax error: wrong number arguments");
13208 Handle(AIS_ViewCube) aViewCube;
13209 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13210 Quantity_Color aColorRgb;
13211 TCollection_AsciiString aName;
13212 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13214 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13216 if (anUpdateTool.parseRedrawMode (anArg))
13220 else if (aViewCube.IsNull())
13222 aName = theArgVec[anArgIter];
13223 if (aName.StartsWith ("-"))
13225 Message::SendFail ("Syntax error: object name should be specified");
13228 Handle(AIS_InteractiveObject) aPrs;
13229 GetMapOfAIS().Find2 (aName, aPrs);
13230 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13231 if (aViewCube.IsNull())
13233 aViewCube = new AIS_ViewCube();
13234 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13235 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13236 aViewCube->SetFixedAnimationLoop (false);
13239 else if (anArg == "-reset")
13241 aViewCube->ResetStyles();
13243 else if (anArg == "-color"
13244 || anArg == "-boxcolor"
13245 || anArg == "-boxsidecolor"
13246 || anArg == "-sidecolor"
13247 || anArg == "-boxedgecolor"
13248 || anArg == "-edgecolor"
13249 || anArg == "-boxcornercolor"
13250 || anArg == "-cornercolor"
13251 || anArg == "-innercolor"
13252 || anArg == "-textcolor"
13253 || anArg == "-xaxistextcolor"
13254 || anArg == "-yaxistextcolor"
13255 || anArg == "-zaxistextcolor")
13257 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13258 theArgVec + anArgIter + 1,
13260 if (aNbParsed == 0)
13262 Message::SendFail() << "Syntax error at '" << anArg << "'";
13265 anArgIter += aNbParsed;
13266 if (anArg == "-boxcolor")
13268 aViewCube->SetBoxColor (aColorRgb);
13270 else if (anArg == "-boxsidecolor"
13271 || anArg == "-sidecolor")
13273 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13274 aViewCube->SynchronizeAspects();
13276 else if (anArg == "-boxedgecolor"
13277 || anArg == "-edgecolor")
13279 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13280 aViewCube->SynchronizeAspects();
13282 else if (anArg == "-boxcornercolor"
13283 || anArg == "-cornercolor")
13285 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13286 aViewCube->SynchronizeAspects();
13288 else if (anArg == "-innercolor")
13290 aViewCube->SetInnerColor (aColorRgb);
13292 else if (anArg == "-textcolor")
13294 aViewCube->SetTextColor (aColorRgb);
13296 else if (anArg == "-xaxistextcolor"
13297 || anArg == "-yaxistextcolor"
13298 || anArg == "-zaxistextcolor")
13300 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13301 ? Prs3d_DatumParts_XAxis
13302 : (anArg.Value (2) == 'y'
13303 ? Prs3d_DatumParts_YAxis
13304 : Prs3d_DatumParts_ZAxis);
13305 aViewCube->Attributes()->SetOwnDatumAspects();
13306 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13310 aViewCube->SetColor (aColorRgb);
13313 else if (anArgIter + 1 < theNbArgs
13314 && (anArg == "-transparency"
13315 || anArg == "-boxtransparency"))
13317 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13318 if (aValue < 0.0 || aValue > 1.0)
13320 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
13324 if (anArg == "-boxtransparency")
13326 aViewCube->SetBoxTransparency (aValue);
13330 aViewCube->SetTransparency (aValue);
13333 else if (anArg == "-axes"
13334 || anArg == "-edges"
13335 || anArg == "-vertices"
13336 || anArg == "-vertexes"
13337 || anArg == "-fixedanimation")
13339 bool toShow = true;
13340 if (anArgIter + 1 < theNbArgs
13341 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
13345 if (anArg == "-fixedanimation")
13347 aViewCube->SetFixedAnimationLoop (toShow);
13349 else if (anArg == "-axes")
13351 aViewCube->SetDrawAxes (toShow);
13353 else if (anArg == "-edges")
13355 aViewCube->SetDrawEdges (toShow);
13359 aViewCube->SetDrawVertices (toShow);
13362 else if (anArg == "-yup"
13363 || anArg == "-zup")
13366 if (anArgIter + 1 < theNbArgs
13367 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
13371 if (anArg == "-yup")
13373 aViewCube->SetYup (isOn);
13377 aViewCube->SetYup (!isOn);
13380 else if (anArgIter + 1 < theNbArgs
13381 && anArg == "-font")
13383 aViewCube->SetFont (theArgVec[++anArgIter]);
13385 else if (anArgIter + 1 < theNbArgs
13386 && anArg == "-fontheight")
13388 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13390 else if (anArgIter + 1 < theNbArgs
13391 && (anArg == "-size"
13392 || anArg == "-boxsize"))
13394 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13395 anArg != "-boxsize");
13397 else if (anArgIter + 1 < theNbArgs
13398 && (anArg == "-boxfacet"
13399 || anArg == "-boxfacetextension"
13400 || anArg == "-facetextension"
13401 || anArg == "-extension"))
13403 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13405 else if (anArgIter + 1 < theNbArgs
13406 && (anArg == "-boxedgegap"
13407 || anArg == "-edgegap"))
13409 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13411 else if (anArgIter + 1 < theNbArgs
13412 && (anArg == "-boxedgeminsize"
13413 || anArg == "-edgeminsize"))
13415 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
13417 else if (anArgIter + 1 < theNbArgs
13418 && (anArg == "-boxcornerminsize"
13419 || anArg == "-cornerminsize"))
13421 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
13423 else if (anArgIter + 1 < theNbArgs
13424 && anArg == "-axespadding")
13426 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
13428 else if (anArgIter + 1 < theNbArgs
13429 && anArg == "-roundradius")
13431 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
13433 else if (anArgIter + 1 < theNbArgs
13434 && anArg == "-duration")
13436 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
13438 else if (anArgIter + 1 < theNbArgs
13439 && anArg == "-axesradius")
13441 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
13443 else if (anArgIter + 1 < theNbArgs
13444 && anArg == "-axesconeradius")
13446 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
13448 else if (anArgIter + 1 < theNbArgs
13449 && anArg == "-axessphereradius")
13451 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
13455 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13459 if (aViewCube.IsNull())
13461 Message::SendFail ("Syntax error: wrong number of arguments");
13465 ViewerTest::Display (aName, aViewCube, false);
13469 //===============================================================================================
13470 //function : VColorConvert
13472 //===============================================================================================
13473 static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13475 if (theNbArgs != 6)
13477 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13481 Standard_Boolean convertFrom = (! strcasecmp (theArgVec[1], "from"));
13482 if (! convertFrom && strcasecmp (theArgVec[1], "to"))
13484 std::cerr << "Error: first argument must be either \"to\" or \"from\"" << std::endl;
13488 const char* aTypeStr = theArgVec[2];
13489 Quantity_TypeOfColor aType = Quantity_TOC_RGB;
13490 if (! strcasecmp (aTypeStr, "srgb"))
13492 aType = Quantity_TOC_sRGB;
13494 else if (! strcasecmp (aTypeStr, "hls"))
13496 aType = Quantity_TOC_HLS;
13498 else if (! strcasecmp (aTypeStr, "lab"))
13500 aType = Quantity_TOC_CIELab;
13502 else if (! strcasecmp (aTypeStr, "lch"))
13504 aType = Quantity_TOC_CIELch;
13508 std::cerr << "Error: unknown colorspace type: " << aTypeStr << std::endl;
13512 double aC1 = Draw::Atof (theArgVec[3]);
13513 double aC2 = Draw::Atof (theArgVec[4]);
13514 double aC3 = Draw::Atof (theArgVec[5]);
13516 Quantity_Color aColor (aC1, aC2, aC3, convertFrom ? aType : Quantity_TOC_RGB);
13517 aColor.Values (aC1, aC2, aC3, convertFrom ? Quantity_TOC_RGB : aType);
13519 // print values with 6 decimal digits
13521 Sprintf (buffer, "%.6f %.6f %.6f", aC1, aC2, aC3);
13527 //===============================================================================================
13528 //function : VColorDiff
13530 //===============================================================================================
13531 static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13533 if (theNbArgs != 7)
13535 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13539 double aR1 = Draw::Atof (theArgVec[1]);
13540 double aG1 = Draw::Atof (theArgVec[2]);
13541 double aB1 = Draw::Atof (theArgVec[3]);
13542 double aR2 = Draw::Atof (theArgVec[4]);
13543 double aG2 = Draw::Atof (theArgVec[5]);
13544 double aB2 = Draw::Atof (theArgVec[6]);
13546 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
13547 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
13549 theDI << aColor1.DeltaE2000 (aColor2);
13554 //===============================================================================================
13555 //function : VSelBvhBuild
13557 //===============================================================================================
13558 static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
13560 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
13563 Message::SendFail ("Error: no active viewer");
13569 Message::SendFail ("Error: command syntax is incorrect, see help");
13573 Standard_Integer toEnable = -1;
13574 Standard_Integer aThreadsNb = -1;
13575 Standard_Boolean toWait = Standard_False;
13577 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13579 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13582 if (anArg == "-nbthreads"
13583 && anArgIter + 1 < theNbArgs)
13585 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
13586 if (aThreadsNb < 1)
13588 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
13591 else if (anArg == "-wait")
13593 toWait = Standard_True;
13595 else if (toEnable == -1)
13597 Standard_Boolean toEnableValue = Standard_True;
13598 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
13600 toEnable = toEnableValue ? 1 : 0;
13604 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13610 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13615 if (aThreadsNb == -1)
13619 if (toEnable != -1)
13621 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
13625 aCtx->MainSelector()->WaitForBVHBuild();
13631 //=======================================================================
13632 //function : ViewerTest_ExitProc
13634 //=======================================================================
13635 static void ViewerTest_ExitProc (ClientData )
13637 NCollection_List<TCollection_AsciiString> aViewList;
13638 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
13639 anIter.More(); anIter.Next())
13641 aViewList.Append (anIter.Key1());
13644 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
13645 anIter.More(); anIter.Next())
13647 ViewerTest::RemoveView (anIter.Value(), true);
13651 //=======================================================================
13652 //function : ViewerCommands
13654 //=======================================================================
13656 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
13658 static bool TheIsInitialized = false;
13659 if (TheIsInitialized)
13664 TheIsInitialized = true;
13665 // define destruction callback to destroy views in a well-defined order
13666 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
13668 const char* aGroup = "AIS Viewer";
13669 const char* aFileName = __FILE__;
13670 auto addCmd = [&](const char* theName, Draw_Interpretor::CommandFunction theFunc, const char* theHelp)
13672 theCommands.Add (theName, theHelp, aFileName, theFunc, aGroup);
13675 addCmd ("vdriver", VDriver, /* [vdriver] */ R"(
13676 vdriver [-list] [-default DriverName] [-load DriverName]
13677 Manages active graphic driver factory.
13678 Prints current active driver when called without arguments.
13679 Makes specified driver active when ActiveName argument is specified.
13680 -list print registered factories
13681 -default define which factory should be used by default (to be used by next vinit call)
13682 -load try loading factory plugin and set it as default one
13683 )" /* [vdriver] */);
13685 addCmd ("vinit", VInit, /* [vinit] */ R"(
13686 vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]
13687 [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {on|off}=off] [-2d_mode {on|off}=off]
13688 [-display displayName]
13689 Creates new View window with specified name viewName.
13690 By default the new view is created in the viewer and in graphic driver shared with active view.
13691 -name {driverName/viewerName/viewName | viewerName/viewName | viewName}
13692 if driverName isn't specified the driver will be shared with active view;
13693 if viewerName isn't specified the viewer will be shared with active view.
13694 -display HostName.DisplayNumber[:ScreenNumber]
13696 Display name will be used within creation of graphic driver, when specified.
13697 -left, -top pixel position of left top corner of the window.
13698 -width, -height width and height of window respectively.
13699 -cloneActive flag to copy camera and dimensions of active view.
13700 -exitOnClose when specified, closing the view will exit application.
13701 -closeOnEscape when specified, view will be closed on pressing Escape.
13702 -virtual create an offscreen window within interactive session
13703 -2d_mode when on, view will not react on rotate scene events
13704 Additional commands for operations with views: vclose, vactivate, vviewlist.
13707 addCmd ("vclose", VClose, /* [vclose] */ R"(
13708 vclose [view_id [keep_context=0|1]]
13709 or vclose ALL - to remove all created views
13710 - removes view(viewer window) defined by its view_id.
13711 - keep_context: by default 0; if 1 and the last view is deleted the current context is not removed.
13712 )" /* [vclose] */);
13714 addCmd ("vactivate", VActivate, /* [vactivate] */ R"(
13715 vactivate view_id [-noUpdate]
13716 Activates view(viewer window) defined by its view_id.
13717 )" /* [vactivate] */);
13719 addCmd ("vviewlist", VViewList, /* [vviewlist] */ R"(
13720 vviewlist [format={tree, long}]=tree
13721 Prints current list of views per viewer and graphic_driver ID shared between viewers
13722 - format: format of result output, if tree the output is a tree view;
13723 otherwise it's a list of full view names.
13724 )" /* [vviewlist] */);
13726 addCmd ("vhelp", VHelp, /* [vhelp] */ R"(
13727 vhelp : display help on the viewer commands and list of hotkeys.
13730 addCmd ("vviewproj", VViewProj, /* [vviewproj] */ R"(
13731 vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]
13732 [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]
13733 Setup view direction
13734 -Yup use Y-up convention instead of Zup (which is default).
13735 +-X+-Y+-Z define direction as combination of DX, DY and DZ;
13736 for example '+Z' will show front of the model,
13737 '-X-Y+Z' will define left axonometric view.
13738 -frame define camera Up and Right directions (regardless Up convention);
13739 for example '+X+Z' will show front of the model with Z-up.
13740 )" /* [vviewproj] */);
13742 addCmd ("vtop", VViewProj, /* [vtop] */ R"(
13743 vtop or <T> : Display top view (+X+Y) in the 3D viewer window.
13746 addCmd ("vbottom", VViewProj, /* [vbottom] */ R"(
13747 vbottom : Display bottom view (+X-Y) in the 3D viewer window.
13748 )" /* [vbottom] */);
13750 addCmd ("vleft", VViewProj, /* [vleft] */ R"(
13751 vleft : Display left view (-Y+Z) in the 3D viewer window.
13754 addCmd ("vright", VViewProj, /* [vright] */ R"(
13755 vright : Display right view (+Y+Z) in the 3D viewer window.
13756 )" /* [vright] */);
13758 addCmd ("vaxo", VViewProj, /* [vaxo] */ R"(
13759 vaxo or <A> : Display axonometric view (+X-Y+Z) in the 3D viewer window.
13762 addCmd ("vfront", VViewProj, /* [vfront] */ R"(
13763 vfront : Display front view (+X+Z) in the 3D viewer window.
13764 )" /* [vfront] */);
13766 addCmd ("vback", VViewProj, /* [vfront] */ R"(
13767 vback : Display back view (-X+Z) in the 3D viewer window.
13770 addCmd ("vpick", VPick, /* [vpick] */ R"(
13771 vpick X Y Z [shape subshape]
13774 addCmd ("vfit", VFit, /* [vfit] */ R"(
13775 vfit or <F> [-selected] [-noupdate]
13776 Fit all / selected. Objects in the view are visualized to occupy the maximum surface.
13779 addCmd ("vfitarea", VFitArea, /* [vfitarea] */ R"(
13780 vfitarea [x1 y1 x2 y2] [x1 y1 z1 x2 y2 z2]
13781 Fit view to show area located between two points
13782 given in world 2D or 3D coordinates.
13783 )" /* [vfitarea] */);
13785 addCmd ("vzfit", VZFit, /* [vzfit] */ R"(
13787 Automatic depth panning.
13788 Matches Z near, Z far view volume planes to the displayed objects.
13789 - "scale" specifies factor to scale computed z range.
13792 addCmd ("vrepaint", VRepaint, /* [vrepaint] */ R"(
13793 vrepaint [-immediate] [-continuous FPS]
13794 Force redraw of active View.
13795 -immediate flag performs redraw of immediate layers only;
13796 -continuous activates/deactivates continuous redraw of active View,
13797 0 means no continuous rendering,
13798 -1 means non-stop redraws,
13799 >0 specifies target framerate.
13800 )" /* [vrepaint] */);
13802 addCmd ("vclear", VClear, /* [vclear] */ R"(
13803 vclear : Remove all the object from the viewer
13804 )" /* [vclear] */);
13806 addCmd ("vbackground", VBackground, /* [vbackground] */ R"(
13807 vbackground [-color Color [-default]]
13808 [-gradient Color1 Color2 [-default]
13809 [-gradientMode {NONE|HORIZONTAL|VERTICAL|DIAG1|DIAG2|CORNER1|CORNER2|CORNER3|ELLIPTICAL}]=VERT]
13810 [-imageFile ImageFile [-imageMode {CENTERED|TILED|STRETCH|NONE}]=CENTERED [-srgb {0|1}]=1]
13811 [-cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]=0]
13812 [-pbrEnv {ibl|noibl|keep}]
13813 Changes background or some background settings.
13814 -color sets background color
13815 -gradient sets background gradient starting and ending colors
13816 -gradientMode sets gradient fill method
13817 -default sets background default gradient or color
13818 -imageFile sets filename of image used as background
13819 -imageMode sets image fill type
13820 -cubemap sets environment cubemap as background
13821 -invertedz sets inversion of Z axis for background cubemap rendering; FALSE when unspecified
13822 -pbrEnv sets on/off Image Based Lighting (IBL) from background cubemap for PBR
13823 -srgb prefer sRGB texture format when applicable; TRUE when unspecified"
13824 -order defines order of tiles in one image cubemap
13825 TileIndexi defubes an index in range [0, 5] for i tile of one image packed cubemap
13826 (has no effect in case of multi-image cubemaps).
13827 )" /* [vbackground] */);
13829 addCmd ("vsetbg", VBackground, /* [vsetbg] */ R"(
13830 Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.
13831 )" /* [vsetbg] */);
13833 addCmd ("vsetbgmode", VBackground, /* [vsetbgmode] */ R"(
13834 Alias for 'vbackground -imageMode FillType'.
13835 )" /* [vsetbgmode] */);
13837 addCmd ("vsetgradientbg", VBackground, /* [vsetgradientbg] */ R"(
13838 Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.
13839 )" /* [vsetgradientbg] */);
13841 addCmd ("vsetgrbgmode", VBackground, /* [vsetgrbgmode] */ R"(
13842 Alias for 'vbackground -gradientMode FillMethod'.
13843 )" /* [vsetgrbgmode] */);
13845 addCmd ("vsetcolorbg", VBackground, /* [vsetcolorbg] */ R"(
13846 Alias for 'vbackground -color Color'.
13847 )" /* [vsetcolorbg] */);
13849 addCmd ("vsetdefaultbg", VBackground, /* [vsetdefaultbg] */ R"(
13850 Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'
13851 and for 'vbackground -default -color Color'.
13852 )" /* [vsetdefaultbg] */);
13854 addCmd ("vscale", VScale, /* [vscale] */ R"(
13856 )" /* [vscale] */);
13858 addCmd ("vzbufftrihedron", VZBuffTrihedron, /* [vzbufftrihedron] */ R"(
13859 vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]
13860 [-position center|left_lower|left_upper|right_lower|right_upper]
13861 [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]
13862 [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]
13863 [-nbfacets value=12] [-colorLabels color=WHITE]
13864 [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]
13865 Displays a trihedron.
13866 )" /* [vzbufftrihedron] */);
13868 addCmd ("vrotate", VRotate, /* [vrotate] */ R"(
13869 vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]
13870 -mouseStart start rotation according to the mouse position;
13871 -mouseMove continue rotation with angle computed
13872 from last and new mouse position.
13873 )" /* [vrotate] */);
13875 addCmd ("vzoom", VZoom, /* [vzoom] */ R"(
13879 addCmd ("vpan", VPan, /* [vpan] */ R"(
13883 addCmd ("vcolorscale", VColorScale, /* [vcolorscale] */ R"(
13884 vcolorscale name [-noupdate|-update] [-demo]
13885 [-range RangeMin=0 RangeMax=1 NbIntervals=10]
13886 [-font HeightFont=20]
13887 [-logarithmic {on|off}=off] [-reversed {on|off}=off]
13888 [-smoothTransition {on|off}=off]
13889 [-hueRange MinAngle=230 MaxAngle=0]
13890 [-colorRange MinColor=BLUE1 MaxColor=RED]
13891 [-textPos {left|right|center|none}=right]
13892 [-labelAtBorder {on|off}=on]
13893 [-colors Color1 Color2 ...] [-color Index Color]
13894 [-labels Label1 Label2 ...] [-label Index Label]
13895 [-freeLabels NbOfLabels Label1 Label2 ...]
13896 [-xy Left=0 Bottom=0]
13897 [-uniform lightness hue_from hue_to]
13898 -demo display a color scale with demonstration values
13899 -colors set colors for all intervals
13900 -color set color for specific interval
13901 -uniform generate colors with the same lightness
13902 -textpos horizontal label position relative to color scale bar
13903 -labelAtBorder vertical label position relative to color interval;
13904 at border means the value inbetween neighbor intervals,
13905 at center means the center value within current interval
13906 -labels set labels for all intervals
13907 -freeLabels same as -labels but does not require
13908 matching the number of intervals
13909 -label set label for specific interval
13911 -reversed setup smooth color transition between intervals
13912 -smoothTransition swap colorscale direction
13913 -hueRange set hue angles corresponding to minimum and maximum values
13914 )" /* [vcolorscale] */);
13916 addCmd ("vgraduatedtrihedron", VGraduatedTrihedron, /* [vgraduatedtrihedron] */ R"(
13917 vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]
13918 [-namefont Name] [-valuesfont Name]
13919 [-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]
13920 [-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]
13921 [-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]
13922 [-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]
13923 [-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]
13924 [-xcolor Color] [-ycolor Color] [-zcolor Color]
13925 [-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]
13926 [-xticks Number] [-yticks Number] [-zticks Number]
13927 [-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]
13928 [-drawgrid on/off] [-drawaxes on/off]
13929 Display or erase graduated trihedron
13930 - xname, yname, zname - names of axes, default: X, Y, Z
13931 - namefont - font of axes names. Default: Arial
13932 - xnameoffset, ynameoffset, znameoffset - offset of name
13933 from values or tickmarks or axis. Default: 30
13934 - xnamecolor, ynamecolor, znamecolor - colors of axes names
13935 - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values
13936 from tickmarks or axis. Default: 10
13937 - valuesfont - font of axes values. Default: Arial
13938 - xcolor, ycolor, zcolor - color of axis and values
13939 - xticks, yticks, xzicks - number of tickmark on axes. Default: 5
13940 - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10
13941 )" /* [vgraduatedtrihedron] */);
13943 addCmd ("vtile", VTile, /* [vtile] */ R"(
13944 vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]
13945 Setup view to draw a tile (a part of virtual bigger viewport).
13946 -totalSize the size of virtual bigger viewport
13947 -tileSize tile size (the view size will be used if omitted)
13948 -lowerLeft tile offset as lower left corner
13949 -upperLeft tile offset as upper left corner
13952 addCmd ("vzlayer", VZLayer, /* [vzlayer] */ R"(
13954 [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]
13955 [-origin X Y Z] [-cullDist Distance] [-cullSize Size]
13956 [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]
13957 [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]
13958 ZLayer list management
13959 -add add new z layer to viewer and print its id
13960 -insertBefore add new z layer and insert it before existing one
13961 -insertAfter add new z layer and insert it after existing one
13962 -delete delete z layer
13963 -get print sequence of z layers
13964 -settings print status of z layer settings
13965 -disable disables given setting
13966 -enable enables given setting
13967 )" /* [vzlayer] */);
13969 addCmd ("vlayerline", VLayerLine, /* [vlayerline] */ R"(
13970 vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]
13971 )" /* [vlayerline] */);
13973 addCmd ("vgrid", VGrid, /* [vgrid] */ R"(
13974 vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]
13975 [-step X Y] [-size DX DY]
13976 [-step StepRadius NbDivisions] [-radius Radius]
13979 addCmd ("vpriviledgedplane", VPriviledgedPlane, /* [vpriviledgedplane] */ R"(
13980 vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]
13981 Sets or prints viewer's priviledged plane geometry:
13982 Ox, Oy, Oz - plane origin;
13983 Nx, Ny, Nz - plane normal direction;
13984 Xx, Xy, Xz - plane x-reference axis direction.
13985 )" /* [vpriviledgedplane] */);
13987 addCmd ("vconvert", VConvert, /* [vconvert] */ R"(
13988 vconvert v [Mode={window|view}]
13989 vconvert x y [Mode={window|view|grid|ray}]
13990 vconvert x y z [Mode={window|grid}]
13991 Convert the given coordinates to window/view/model space:
13992 - window - convert to window coordinates, pixels;
13993 - view - convert to view projection plane;
13994 - grid - convert to model coordinates, given on grid;
13995 - ray - convert projection ray to model coordinates.
13996 )" /* [vconvert] */);
13998 addCmd ("vfps", VFps, /* [vfps] */ R"(
13999 vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view.
14002 addCmd ("vstereo", VStereo, /* [vstereo] */ R"(
14003 vstereo [0|1] [-mode Mode] [-reverse {0|1}]
14004 [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]
14006 Control stereo output mode. Available modes for -mode:
14007 quadBuffer OpenGL QuadBuffer stereo;
14008 requires driver support;
14009 should be called BEFORE vinit!
14010 anaglyph Anaglyph glasses, filters for -anaglyph:
14011 redCyan, redCyanSimple, yellowBlue, yellowBlueSimple, greenMagentaSimple.
14012 rowInterlaced row-interlaced display
14013 columnInterlaced column-interlaced display
14014 chessBoard chess-board output
14015 sideBySide horizontal pair
14016 overUnder vertical pair
14017 openVR OpenVR (HMD), extra options:
14018 -mirrorComposer flag to mirror VR frame in the window (debug);
14019 -unitFactor specifies meters scale factor for mapping VR input.
14020 )" /* [vstereo] */);
14022 addCmd ("vmemgpu", VMemGpu, /* [vmemgpu] */ R"(
14023 vmemgpu [f]: print system-dependent GPU memory information if available;
14024 with f option returns free memory in bytes.
14025 )" /* [vmemgpu] */);
14027 addCmd ("vreadpixel", VReadPixel, /* [vreadpixel] */ R"(
14028 vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]
14029 Read pixel value for active view.
14030 )" /* [vreadpixel] */);
14032 addCmd ("diffimage", VDiffImage, /* [diffimage] */ R"(
14033 diffimage imageFile1 imageFile2 [diffImageFile]
14034 [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]
14035 [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]
14036 Compare two images by content and generate difference image.
14037 When -exitOnClose is specified, closing the view will exit application.
14038 When -closeOnEscape is specified, view will be closed on pressing Escape.
14039 )" /* [diffimage] */);
14041 addCmd ("vselect", VSelect, /* [vselect] */ R"(
14042 vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1]
14043 [-replace|-replaceextra|-xor|-add|-remove]
14044 Emulate different types of selection:
14045 1) Single click selection.
14046 2) Selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2).
14047 3) Selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn).
14048 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.
14049 If the flag is set to 1, both sensitives that were included completely
14050 and overlapped partially by defined rectangle or polygon will be detected,
14051 otherwise algorithm will chose only fully included sensitives.
14052 Default behavior is to detect only full inclusion
14053 (partial inclusion - overlap - is not allowed by default).
14054 5) Selection scheme replace, replaceextra, xor, add or remove (replace by default).
14055 )" /* [vselect] */);
14057 addCmd ("vmoveto", VMoveTo, /* [vmoveto] */ R"(
14058 vmoveto [x y] [-reset]
14059 Emulate cursor movement to pixel position (x,y).
14060 -reset resets current highlighting.
14061 )" /* [vmoveto] */);
14063 addCmd ("vselaxis", VSelectByAxis, /* [vselaxis] */ R"(
14064 vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14065 Provides intersection by given axis and print result intersection points.
14066 -onlyTop switches On/Off mode to find only top point or all;
14067 -display Name displays intersecting axis and result intersection points for debug goals;
14068 -showNormal adds displaying of normal in intersection point or not.
14069 )" /* [vselaxis] */);
14071 addCmd ("vviewparams", VViewParams, /* [vviewparams] */ R"(
14072 vviewparams [-args] [-scale [s]]
14073 [-eye [x y z]] [-at [x y z]] [-up [x y z]]
14074 [-proj [x y z]] [-center x y] [-size sx]
14075 Manage current view parameters (camera orientation) or prints all
14076 current values when called without argument.
14077 -scale [s] prints or sets viewport relative scale
14078 -eye [x y z] prints or sets eye location
14079 -at [x y z] prints or sets center of look
14080 -up [x y z] prints or sets direction of up vector
14081 -proj [x y z] prints or sets direction of look
14082 -center x y sets location of center of the screen in pixels
14083 -size [sx] prints viewport projection width and height sizes
14084 or changes the size of its maximum dimension
14085 -args prints vviewparams arguments for restoring current view
14086 )" /* [vviewparams] */);
14088 addCmd ("v2dmode", V2DMode, /* [v2dmode] */ R"(
14089 v2dmode [-name viewName] [-mode {-on|-off}=-on]
14090 name - name of existing view, if not defined, the active view is changed;
14091 mode - switches On/Off rotation mode.
14092 Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:
14093 - rotation of the view by 3rd mouse button with Ctrl active
14094 - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right
14095 View camera position might be changed only by commands.
14096 )" /* [v2dmode] */);
14098 addCmd ("vanimation", VAnimation, /* [vanimation] */ R"(
14100 )" /* [vanimation] */);
14102 addCmd ("vanim", VAnimation, /* [vanim] */ R"(
14103 List existing animations:
14106 Animation playback:
14107 vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]]
14108 [-speed Coeff] [-freeLook] [-noPauseOnClick] [-lockLoop]
14110 -speed playback speed (1.0 is normal speed)
14111 -freeLook skip camera animations
14112 -noPauseOnClick do not pause animation on mouse click
14113 -lockLoop disable any interactions
14115 Animation definition:
14116 vanim Name/sub/name [-clear] [-delete]
14117 [start TimeSec] [duration TimeSec]
14119 Animation name defined in path-style (anim/name or anim.name)
14120 specifies nested animations.
14121 There is no syntax to explicitly add new animation,
14122 and all non-existing animations within the name will be
14123 implicitly created on first use (including parents).
14125 Each animation might define the SINGLE action (see below),
14126 like camera transition, object transformation or custom callback.
14127 Child animations can be used for defining concurrent actions.
14130 vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]
14131 [-at1 X Y Z] [-at2 X Y Z]
14132 [-up1 X Y Z] [-up2 X Y Z]
14133 [-scale1 Scale] [-scale2 Scale]
14134 -eyeX camera Eye positions pair (start and end)
14135 -atX camera Center positions pair
14136 -upX camera Up directions pair
14137 -scaleX camera Scale factors pair
14140 vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]
14141 [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]
14142 [-scale1 Scale] [-scale2 Scale]
14143 -locX object Location points pair (translation)
14144 -rotX object Orientations pair (quaternions)
14145 -scaleX object Scale factors pair (quaternions)
14148 vanim name -invoke "Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN"
14150 %Pts overall animation presentation timestamp
14151 %LocalPts local animation timestamp
14152 %Normalized local animation normalized value in range 0..1
14155 vanim name -record FileName [Width Height] [-fps FrameRate=24]
14156 [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]
14157 [-crf Value] [-preset Preset]
14158 -fps video framerate
14159 -format file format, container (matroska, etc.)
14160 -vcodec video codec identifier (ffv1, mjpeg, etc.)
14161 -pix_fmt image pixel format (yuv420p, rgb24, etc.)
14162 -crf constant rate factor (specific to codec)
14163 -preset codec parameters preset (specific to codec)
14166 addCmd ("vchangeselected", VChangeSelected, /* [vchangeselected] */ R"(
14167 vchangeselected shape : Add shape to selection or remove one from it.
14168 )" /* [vchangeselected] */);
14170 addCmd ("vnbselected", VNbSelected, /* [vnbselected] */ R"(
14171 vnbselected : Returns number of selected objects in the interactive context.
14172 )" /* [vnbselected] */);
14174 addCmd ("vcamera", VCamera, /* [vcamera] */ R"(
14175 vcamera [PrsName] [-ortho] [-projtype]
14177 [-fovy [Angle]] [-distance [Distance]]
14178 [-stereo] [-leftEye] [-rightEye]
14179 [-iod [Distance]] [-iodType [absolute|relative]]
14180 [-zfocus [Value]] [-zfocusType [absolute|relative]]
14181 [-fov2d [Angle]] [-lockZup {0|1}]
14182 [-rotationMode {active|pick|pickCenter|cameraAt|scene}]
14183 [-navigationMode {orbit|walk|flight}]
14184 [-xrPose base|head=base]
14185 Manages camera parameters.
14186 Displays frustum when presentation name PrsName is specified.
14187 Prints current value when option called without argument.
14189 Orthographic camera:
14190 -ortho activate orthographic projection.
14192 Perspective camera:
14193 -persp activate perspective projection (mono);
14194 -fovy field of view in y axis, in degrees;
14195 -fov2d field of view limit for 2d on-screen elements;
14196 -distance distance of eye from camera center;
14197 -lockZup lock Z up (turntable mode);
14198 -rotationMode rotation mode (gravity point);
14199 -navigationMode navigation mode.
14201 Stereoscopic camera:
14202 -stereo perspective projection (stereo);
14203 -leftEye perspective projection (left eye);
14204 -rightEye perspective projection (right eye);
14205 -iod intraocular distance value;
14206 -iodType distance type, absolute or relative;
14207 -zfocus stereographic focus value;
14208 -zfocusType focus type, absolute or relative.
14209 )" /* [vcamera] */);
14211 addCmd ("vautozfit", VAutoZFit, /* [vautozfit] */ R"(
14212 vautozfit [on={1|0}] [scale]
14213 Prints or changes parameters of automatic z-fit mode:
14214 "on" - turns automatic z-fit on or off;
14215 "scale" - specifies factor to scale computed z range.
14216 )" /* [vautozfit] */);
14218 addCmd ("vzrange", VZRange, /* [vzrange] */ R"(
14219 vzrange [znear] [zfar]
14220 Applies provided znear/zfar to view or prints current values.
14221 )" /* [vzrange] */);
14223 addCmd ("vsetviewsize", VSetViewSize, /* [vsetviewsize] */ R"(
14225 )" /* [vsetviewsize] */);
14227 addCmd ("vmoveview", VMoveView, /* [vmoveview] */ R"(
14228 vmoveview Dx Dy Dz [Start = 1|0]
14229 )" /* [vmoveview] */);
14231 addCmd ("vtranslateview", VTranslateView, /* [vtranslateview] */ R"(
14232 vtranslateview Dx Dy Dz [Start = 1|0)]
14233 )" /* [vtranslateview] */);
14235 addCmd ("vturnview", VTurnView, /* [vturnview] */ R"(
14236 vturnview Ax Ay Az [Start = 1|0]
14237 )" /* [vturnview] */);
14239 addCmd ("vtextureenv", VTextureEnv, /* [vtextureenv] */ R"(
14240 vtextureenv {on|off} {image_file}
14241 [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} ss st ts tt rot]
14242 Enables or disables environment mapping in the 3D view, loading the texture from the given standard
14243 or user-defined file and optionally applying texture mapping parameters.
14244 ss, st - scale factors for s and t texture coordinates;
14245 ts, tt - translation for s and t texture coordinates;
14246 rot - texture rotation angle in degrees.
14247 )" /* [vtextureenv] */);
14249 addCmd ("vhlr", VHLR, /* [vhlr] */ R"(
14250 vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]
14251 Hidden Line Removal algorithm.
14252 -showHidden if set ON, hidden lines are drawn as dotted ones;
14253 -algoType type of HLR algorithm:
14254 'algo' - exact HLR algorithm is applied;
14255 'polyAlgo' - polygonal HLR algorithm is applied.
14258 addCmd ("vhlrtype", VHLRType, /* [vhlrtype] */ R"(
14259 vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]
14260 Changes the type of HLR algorithm using for shapes:
14261 'algo' - exact HLR algorithm is applied;
14262 'polyAlgo' - polygonal HLR algorithm is applied.
14263 If shapes are not given - option is applied to all shapes in the view.
14264 )" /* [vhlrtype] */);
14266 addCmd ("vclipplane", VClipPlane, /* [vclipplane] */ R"(
14267 vclipplane planeName [{0|1}]
14268 [-equation1 A B C D]
14269 [-equation2 A B C D]
14270 [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]
14271 [-set|-unset|-setOverrideGlobal [objects|views]]
14274 [-color R G B] [-transparency Value] [-hatch {on|off|ID}]
14275 [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]
14277 [-useObjMaterial {0|1}] [-useObjTexture {0|1}]
14278 [-useObjShader {0|1}]
14280 Clipping planes management:
14281 -maxPlanes print plane limit for view;
14282 -delete delete plane with given name;
14283 {off|on|0|1} turn clipping on/off;
14284 -set|-unset set/unset plane for Object or View list;
14285 applied to active View when list is omitted;
14286 -equation A B C D change plane equation;
14287 -clone SourcePlane NewPlane clone the plane definition.
14290 -capping {off|on|0|1} turn capping on/off;
14291 -color R G B set capping color;
14292 -transparency Value set capping transparency 0..1;
14293 -texName Texture set capping texture;
14294 -texScale SX SY set capping tex scale;
14295 -texOrigin TX TY set capping tex origin;
14296 -texRotate Angle set capping tex rotation;
14297 -hatch {on|off|ID} set capping hatching mask;
14298 -useObjMaterial {off|on|0|1} use material of clipped object;
14299 -useObjTexture {off|on|0|1} use texture of clipped object;
14300 -useObjShader {off|on|0|1} use shader program of object.
14301 )" /* [vclipplane] */);
14303 addCmd ("vdefaults", VDefaults, /* [vdefaults] */ R"(
14304 vdefaults [-absDefl value] [-devCoeff value] [-angDefl value]
14305 [-autoTriang {off/on | 0/1}]
14306 )" /* [vdefaults] */);
14308 addCmd ("vlight", VLight, /* [vlight] */ R"(
14309 vlight [lightName] [-noupdate]
14310 [-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]
14311 [-type {ambient|directional|spotlight|positional}] [-name value]
14312 [-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]
14313 [-headlight 0|1] [-castShadows 0|1]
14314 [-range value] [-constAttenuation value] [-linearAttenuation value]
14315 [-spotExponent value] [-spotAngle angleDeg]
14316 [-smoothAngle value] [-smoothRadius value]
14317 [-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]
14320 Command manages light sources. Without arguments shows list of lights.
14321 Arguments affecting the list of defined/active lights:
14322 -clear remove all light sources;
14323 -defaults defines two standard light sources;
14324 -reset resets light source parameters to default values;
14325 -type sets type of light source;
14326 -name sets new name to light source;
14327 -global assigns light source to all views (default state);
14328 -local assigns light source to active view;
14329 -zlayer assigns light source to specified Z-Layer.
14331 Ambient light parameters:
14332 -color sets (normalized) light color;
14333 -intensity sets intensity of light source, 1.0 by default;
14334 affects also environment cubemap intensity.
14336 Point light parameters:
14337 -color sets (normalized) light color;
14338 -intensity sets PBR intensity;
14339 -range sets clamping distance;
14340 -constAtten (obsolete) sets constant attenuation factor;
14341 -linearAtten (obsolete) sets linear attenuation factor;
14342 -smoothRadius sets PBR smoothing radius.
14344 Directional light parameters:
14345 -color sets (normalized) light color;
14346 -intensity sets PBR intensity;
14347 -direction sets direction;
14348 -headlight sets headlight flag;
14349 -castShadows enables/disables shadow casting;
14350 -smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range.
14352 Spot light parameters:
14353 -color sets (normalized) light color;
14354 -intensity sets PBR intensity;
14355 -range sets clamping distance;
14356 -position sets position;
14357 -direction sets direction;
14358 -spotAngle sets spotlight angle;
14359 -spotExp sets spotlight exponenta;
14360 -headlight sets headlight flag;
14361 -constAtten (obsolete) sets constant attenuation factor;
14362 -linearAtten (obsolete) sets linear attenuation factor.
14364 Light presentation parameters:
14365 -display adds light source presentation;
14366 -showName shows/hides the name of light source; 1 by default;
14367 -showRange shows/hides the range of spot/positional light source; 1 by default;
14368 -prsZoomable makes light presentation zoomable/non-zoomable;
14369 -prsDraggable makes light presentation draggable/non-draggable;
14370 -prsSize sets light presentation size;
14371 -arcSize sets arc presentation size(in pixels)
14372 for rotation directional light source; 25 by default.
14375 vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED
14376 vlight redlight -delete
14377 )" /* [vlight] */);
14379 addCmd ("vpbrenv", VPBREnvironment, /* [vpbrenv] */ R"(
14380 vpbrenv -clear|-generate
14381 Clears or generates PBR environment map of active view.
14382 -clear clears PBR environment (fills by white color);
14383 -generate generates PBR environment from current background cubemap.
14384 )" /* [vpbrenv] */);
14386 addCmd ("vraytrace", VRenderParams, /* [vraytrace] */ R"(
14387 vraytrace [0|1] : Turns on/off ray-tracing renderer.
14388 'vraytrace 0' alias for 'vrenderparams -raster'.
14389 'vraytrace 1' alias for 'vrenderparams -rayTrace'.
14390 )" /* [vraytrace] */);
14392 addCmd ("vrenderparams", VRenderParams, /* [vrenderparams] */ R"(
14393 Manages rendering parameters, affecting visual appearance, quality and performance.
14394 Should be applied taking into account GPU hardware capabilities and performance.
14397 vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]
14398 [-msaa 0..8=0] [-rendScale scale=1]
14399 [-resolution value=72] [-fontHinting {off|normal|light}=off]
14400 [-fontAutoHinting {auto|force|disallow}=auto]
14401 [-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]
14402 [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]
14403 [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]
14404 [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]
14405 [-sync {default|views}] [-reset]
14406 -raster Disables GPU ray-tracing.
14407 -shadingModel Controls shading model.
14408 -msaa Specifies number of samples for MSAA.
14409 -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA).
14410 -resolution Sets new pixels density (PPI) used as text scaling factor.
14411 -fontHinting Enables/disables font hinting for better readability on low-resolution screens.
14412 -fontAutoHinting Manages font autohinting.
14413 -lineFeather Sets line feather factor while displaying mesh edges.
14414 -alphaToCoverage Enables/disables alpha to coverage (needs MSAA).
14415 -oit Enables/disables order-independent transparency (OIT) rendering;
14416 off unordered transparency (but opaque objects implicitly draw first);
14417 weighted weight OIT is managed by depth weight factor 0.0..1.0;
14418 peeling depth peeling OIT is managed by number of peeling layers.
14419 -shadows Enables/disables shadows rendering.
14420 -shadowMapResolution Shadow texture map resolution.
14421 -shadowMapBias Shadow map bias.
14422 -depthPrePass Enables/disables depth pre-pass.
14423 -frustumCulling Enables/disables objects frustum clipping or
14424 sets state to check structures culled previously.
14425 -sync Sets active View parameters as Viewer defaults / to other Views.
14426 -reset Resets active View parameters to Viewer defaults.
14428 Diagnostic output (on-screen overlay):
14429 vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points
14430 |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]
14431 [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]
14432 -perfCounters Show/hide performance counters (flags can be combined).
14433 -perfUpdateInterval Performance counters update interval.
14434 -perfChart Show frame timers chart limited by specified number of frames.
14435 -perfChartMax Maximum time in seconds with the chart.
14437 Ray-Tracing options:
14438 vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]
14439 [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]
14440 [-gi {on|off}=off] [-brng {on|off}=off]
14441 [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]
14442 [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]
14443 [-maxRad {value>0}=30.0]
14444 [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]
14445 [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]
14446 -rayTrace Enables GPU ray-tracing.
14447 -rayDepth Defines maximum ray-tracing depth.
14448 -reflections Enables/disables specular reflections.
14449 -fsaa Enables/disables adaptive anti-aliasing.
14450 -gleam Enables/disables transparency shadow effects.
14451 -gi Enables/disables global illumination effects (Path-Tracing).
14452 -env Enables/disables environment map background.
14453 -ignoreNormalMap Enables/disables normal map ignoring during path tracing.
14454 -twoSide Enables/disables two-sided BSDF models (PT mode).
14455 -iss Enables/disables adaptive screen sampling (PT mode).
14456 -maxRad Value used for clamping radiance estimation (PT mode).
14457 -tileSize Specifies size of screen tiles in ISS mode (32 by default).
14458 -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default).
14459 -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF).
14460 -focal Focal distance of perspective camera for depth-of-field effect.
14461 -exposure Exposure value for tone mapping (0.0 value disables the effect).
14462 -whitePoint White point value for filmic tone mapping.
14463 -toneMapping Tone mapping mode (disabled, filmic).
14465 PBR environment baking parameters (advanced/debug):
14466 vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]
14467 [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]
14468 -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size).
14469 -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map.
14470 -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during
14471 diffuse IBL map's sherical harmonics calculation.
14472 -pbrEnvBSSN Controls maximum number of samples per mipmap level
14473 in Monte-Carlo integration during specular IBL maps generation.
14474 -pbrEnvBP Controls strength of samples number reducing
14475 during specular IBL maps generation (1 disables reducing).
14478 vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]
14479 -issd Shows screen sampling distribution in ISS mode.
14480 -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging).
14481 -brng Enables/disables blocked RNG (fast coherent PT).
14482 )" /* [vrenderparams] */);
14484 addCmd ("vstatprofiler", VStatProfiler, /* [vstatprofiler] */ R"(
14485 vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups
14486 |allArrays|fillArrays|lineArrays|pointArrays|textArrays
14487 |triangles|points|geomMem|textureMem|frameMem
14488 |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage
14489 |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]
14491 Prints rendering statistics for specified counters or for all when unspecified.
14492 Set '-noredraw' flag to avoid additional redraw call and use already collected values.
14493 )" /* [vstatprofiler] */);
14495 addCmd ("vplace", VPlace, /* [vplace] */ R"(
14496 vplace dx dy : Places the point (in pixels) at the center of the window
14497 )" /* [vplace] */);
14499 addCmd ("vxrotate", VXRotate, /* [vxrotate] */ R"(
14501 )" /* [vxrotate] */);
14503 addCmd ("vmanipulator", VManipulator, /* [vmanipulator] */ R"(
14504 vmanipulator Name [-attach AISObject | -detach | ...]
14505 Tool to create and manage AIS manipulators.
14507 '-attach AISObject' attach manipulator to AISObject
14508 '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching
14509 '-adjustSize {0|1}' adjust size when attaching
14510 '-enableModes {0|1}' enable modes when attaching
14511 '-view {active | [name of view]}' display manipulator only in defined view,
14512 by default it is displayed in all views of the current viewer
14513 '-detach' detach manipulator
14514 '-startTransform mouse_x mouse_y' - invoke start of transformation
14515 '-transform mouse_x mouse_y' - invoke transformation
14516 '-stopTransform [abort]' - invoke stop of transformation
14517 '-move x y z' - move attached object
14518 '-rotate x y z dx dy dz angle' - rotate attached object
14519 '-scale factor' - scale attached object
14520 '-autoActivate {0|1}' - set activation on detection
14521 '-followTranslation {0|1}' - set following translation transform
14522 '-followRotation {0|1}' - set following rotation transform
14523 '-followDragging {0|1}' - set following dragging transform
14524 '-gap value' - set gap between sub-parts
14525 '-part axis mode {0|1}' - set visual part
14526 '-parts axis mode {0|1}' - set visual part
14527 '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator
14528 '-size value' - set size of manipulator
14529 '-zoomable {0|1}' - set zoom persistence
14530 )" /* [vmanipulator] */);
14532 addCmd ("vselprops", VSelectionProperties, /* [vselprops] */ R"(
14533 vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]
14534 Customizes selection and dynamic highlight parameters for the whole interactive context:
14535 -autoActivate {0|1} disables|enables default computation
14536 and activation of global selection mode
14537 -autoHighlight {0|1} disables|enables automatic highlighting in 3D Viewer
14538 -highlightSelected {0|1} disables|enables highlighting of detected object in selected state
14539 -pickStrategy {first|topmost} : defines picking strategy
14540 'first' to pick first acceptable (default)
14541 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)
14542 -pixTol value sets up pixel tolerance
14543 -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth
14544 -depthTol {sensfactor} use sensitive factor for sorting results by depth
14545 -preferClosest {0|1} sets if depth should take precedence over priority while sorting results
14546 -dispMode dispMode sets display mode for highlighting
14547 -layer ZLayer sets ZLayer for highlighting
14548 -color {name|r g b} sets highlight color
14549 -transp value sets transparency coefficient for highlight
14550 -material material sets highlight material
14551 -print prints current state of all mentioned parameters
14552 )" /* [vselprops] */);
14554 addCmd ("vhighlightselected", VSelectionProperties, /* [vhighlightselected] */ R"(
14555 vhighlightselected [0|1] : alias for vselprops -highlightSelected.
14556 )" /* [vhighlightselected] */);
14558 addCmd ("vseldump", VDumpSelectionImage, /* [vseldump] */ R"(
14559 vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|entityType|surfNormal}=depth
14560 -pickedIndex Index=1
14561 [-xrPose base|head=base]
14562 Generate an image based on detection results:
14563 depth normalized depth values
14564 unnormDepth unnormalized depth values
14565 object color of detected object
14566 owner color of detected owner
14567 selMode color of selection mode
14568 entity color of detected entity
14569 entityType color of detected entity type
14570 surfNormal normal direction values
14571 )" /* [vseldump] */);
14573 addCmd ("vviewcube", VViewCube, /* [vviewcube] */ R"(
14575 Displays interactive view manipulation object. Options:
14576 -reset reset geometric and visual attributes
14577 -size Size adapted size of View Cube
14578 -boxSize Size box size
14579 -axes {0|1} show/hide axes (trihedron)
14580 -edges {0|1} show/hide edges of View Cube
14581 -vertices {0|1} show/hide vertices of View Cube
14582 -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation
14583 -color Color color of View Cube
14584 -boxColor Color box color
14585 -boxSideColor Color box sides color
14586 -boxEdgeColor Color box edges color
14587 -boxCornerColor Color box corner color
14588 -textColor Color color of side text of view cube
14589 -innerColor Color inner box color
14590 -transparency Value transparency of object within [0, 1] range
14591 -boxTransparency Value transparency of box within [0, 1] range
14592 -xAxisTextColor Color color of X axis label
14593 -yAxisTextColor Color color of Y axis label
14594 -zAxisTextColor Color color of Z axis label
14595 -font Name font name
14596 -fontHeight Value font height
14597 -boxFacetExtension Value box facet extension
14598 -boxEdgeGap Value gap between box edges and box sides
14599 -boxEdgeMinSize Value minimal box edge size
14600 -boxCornerMinSize Value minimal box corner size
14601 -axesPadding Value padding between box and arrows
14602 -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range
14603 -axesRadius Value radius of axes of the trihedron
14604 -axesConeRadius Value radius of the cone (arrow) of the trihedron
14605 -axesSphereRadius Value radius of the sphere (central point) of trihedron
14606 -fixedAnimation {0|1} uninterruptible animation loop
14607 -duration Seconds animation duration in seconds
14608 )" /* [vviewcube] */);
14610 addCmd ("vcolorconvert", VColorConvert, /* [vcolorconvert] */ R"(
14611 vcolorconvert {from|to} type C1 C2 C2
14612 vcolorconvert from type C1 C2 C2 : Converts color from specified color space to linear RGB
14613 vcolorconvert to type R G B : Converts linear RGB color to specified color space
14614 Type can be sRGB, HLS, Lab, or Lch.
14615 )" /* [vcolorconvert] */);
14617 addCmd ("vcolordiff", VColorDiff, /* [vcolordiff] */ R"(
14618 vcolordiff R1 G1 B1 R2 G2 B2 : returns CIEDE2000 color difference between two RGB colors.
14619 )" /* [vcolordiff] */);
14621 addCmd ("vselbvhbuild", VSelBvhBuild, /* [vselbvhbuild] */ R"(
14622 vselbvhbuild [{0|1}] [-nbThreads value] [-wait]
14623 Turns on/off prebuilding of BVH within background thread(s).
14624 -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1);
14625 -wait waits for building all of BVH.
14626 )" /* [vselbvhbuild] */);