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_Texture2D.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 ViewerTest_VinitParams& theParams)
482 // Default position and dimension of the viewer window.
483 // Note that left top corner is set to be sufficiently small to have
484 // window fit in the small screens (actual for remote desktops, see #23003).
485 // The position corresponds to the window's client area, thus some
486 // gap is added for window frame to be visible.
487 Graphic3d_Vec2d aPxTopLeft (20, 40);
488 Graphic3d_Vec2d aPxSize (409, 409);
489 Standard_Boolean isDefViewSize = Standard_True;
490 Standard_Boolean toCreateViewer = Standard_False;
491 const Standard_Boolean isVirtual = Draw_VirtualWindows || theParams.IsVirtual;
492 if (!theParams.ViewToClone.IsNull())
494 Graphic3d_Vec2i aCloneSize;
495 theParams.ViewToClone->Window()->Size (aCloneSize.x(), aCloneSize.y());
496 aPxSize = Graphic3d_Vec2d (aCloneSize);
497 isDefViewSize = Standard_False;
498 #if !defined(__EMSCRIPTEN__)
499 (void )isDefViewSize;
503 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
504 if (aFactory.IsNull())
506 Draw::GetInterpretor().Eval ("pload OPENGL");
507 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
508 if (aFactory.IsNull())
510 Draw::GetInterpretor().Eval ("pload GLES");
511 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
512 if (aFactory.IsNull())
514 throw Standard_ProgramError("Error: no graphic driver factory found");
519 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
520 ViewerTest_Names aViewNames (theParams.ViewName);
521 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
523 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
526 // Get graphic driver (create it or get from another view)
527 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
530 // Get connection string
531 #if defined(HAVE_XLIB)
532 if (!theParams.DisplayName.IsEmpty())
534 SetDisplayConnection (new Aspect_DisplayConnection (theParams.DisplayName));
538 Aspect_XDisplay* aDispX = NULL;
539 // create dedicated display connection instead of reusing Tk connection
540 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
541 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
542 Tcl_Interp* aTclInterp = aCommands.Interp();
543 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
544 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
545 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
548 SetDisplayConnection (new Aspect_DisplayConnection ());
551 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
554 // don't waste the time waiting for VSync when window is not displayed on the screen
555 aGraphicDriver->SetVerticalSync (false);
558 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
559 toCreateViewer = Standard_True;
563 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
566 // Get screen resolution
567 Graphic3d_Vec2i aScreenSize;
570 GetClientRect(GetDesktopWindow(), &aWindowSize);
571 aScreenSize.SetValues (aWindowSize.right, aWindowSize.bottom);
572 #elif defined(HAVE_XLIB)
573 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
574 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
575 aScreenSize.x() = WidthOfScreen(aScreen);
576 aScreenSize.y() = HeightOfScreen(aScreen);
577 #elif defined(__APPLE__)
578 GetCocoaScreenResolution (aScreenSize.x(), aScreenSize.y());
583 if (!theParams.ParentView.IsNull())
585 aPxTopLeft.SetValues (0, 0);
587 if (theParams.Offset.x() != 0)
589 aPxTopLeft.x() = theParams.Offset.x();
591 if (theParams.Offset.y() != 0)
593 aPxTopLeft.y() = theParams.Offset.y();
595 if (theParams.Size.x() != 0)
597 isDefViewSize = Standard_False;
598 aPxSize.x() = theParams.Size.x();
599 if (aPxSize.x() <= 1.0
600 && aScreenSize.x() > 0
601 && theParams.ParentView.IsNull())
603 aPxSize.x() = aPxSize.x() * double(aScreenSize.x());
606 if (theParams.Size.y() != 0)
608 isDefViewSize = Standard_False;
609 aPxSize.y() = theParams.Size.y();
610 if (aPxSize.y() <= 1.0
611 && aScreenSize.y() > 0
612 && theParams.ParentView.IsNull())
614 aPxSize.y() = aPxSize.y() * double(aScreenSize.y());
618 //Dispose the window if input parameters are default
619 if (!ViewerTest_myViews.IsEmpty()
620 && theParams.ParentView.IsNull()
621 && theParams.Offset.x() == 0
622 && theParams.Offset.y() == 0)
624 Standard_Integer aTop = 0, aLeft = 0, aRight = 0, aBottom = 0;
625 TCollection_AsciiString anOverlappedViewId("");
626 while (IsWindowOverlapped ((int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
627 (int )aPxTopLeft.x() + (int )aPxSize.x(),
628 (int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId))
630 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
632 if (IsWindowOverlapped (aRight + 20, (int )aPxTopLeft.y(), aRight + 20 + (int )aPxSize.x(),
633 (int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId)
634 && aRight + 2 * aPxSize.x() + 40 > aScreenSize.x())
636 if (aBottom + aPxSize.y() + 40 > aScreenSize.y())
643 aPxTopLeft.y() = aBottom + 40;
647 aPxTopLeft.x() = aRight + 20;
653 TCollection_AsciiString aTitle("3D View - ");
654 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
656 // Change name of current active window
657 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
659 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
663 Handle(V3d_Viewer) a3DViewer;
664 // If it's the single view, we first look for empty context
665 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
667 NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
668 anIter(ViewerTest_myContexts);
670 ViewerTest::SetAISContext (anIter.Value());
671 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
673 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
675 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
676 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
678 else if (a3DViewer.IsNull())
680 toCreateViewer = Standard_True;
681 a3DViewer = new V3d_Viewer(aGraphicDriver);
682 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
683 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
684 ViewerTest_DefaultBackground.GradientColor2,
685 ViewerTest_DefaultBackground.FillMethod);
689 if (ViewerTest::GetAISContext().IsNull() ||
690 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
692 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
693 ViewerTest::SetAISContext (aContext);
694 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
698 ViewerTest::ResetEventManager();
702 if (!theParams.ParentView.IsNull())
704 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast (theParams.ParentView->Window());
709 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
710 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
711 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
712 (int )aPxSize.x(), (int )aPxSize.y(),
714 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
715 #elif defined(HAVE_XLIB)
716 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
718 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
719 (int )aPxSize.x(), (int )aPxSize.y());
720 #elif defined(__APPLE__)
721 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
722 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
723 (int )aPxSize.x(), (int )aPxSize.y());
724 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
725 #elif defined(__EMSCRIPTEN__)
726 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
727 // the code should be revised for handling multiple canvas elements (which is technically also possible)
728 TCollection_AsciiString aCanvasId = getModuleCanvasId();
729 if (!aCanvasId.IsEmpty())
731 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
734 VT_GetWindow() = new Wasm_Window (aCanvasId);
735 Graphic3d_Vec2i aRealSize;
736 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
737 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
739 // Wasm_Window wraps an existing HTML element without creating a new one.
740 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
741 // but resize canvas if vinit has been called with explicitly specified dimensions.
742 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxSize));
746 VT_GetWindow() = new Aspect_NeutralWindow();
747 VT_GetWindow()->SetSize ((int )aPxSize.x(), (int )aPxSize.y());
749 VT_GetWindow()->SetVirtual (isVirtual);
753 Handle(V3d_View) aView;
754 if (!theParams.ViewToClone.IsNull())
756 aView = new ViewerTest_V3dView (a3DViewer, theParams.ViewToClone);
760 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
763 aView->View()->SetSubviewComposer (theParams.IsComposer);
764 if (!theParams.ParentView.IsNull())
766 aView->SetWindow (theParams.ParentView, aPxSize, theParams.Corner, aPxTopLeft, theParams.SubviewMargins);
770 aView->SetWindow (VT_GetWindow());
772 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
774 ViewerTest::CurrentView(aView);
775 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
777 // Setup for X11 or NT
778 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
779 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
781 // Set parameters for V3d_View and V3d_Viewer
782 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
783 aV3dView->SetComputedMode(Standard_False);
785 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
788 a3DViewer->SetDefaultLights();
789 a3DViewer->SetLightOn();
792 #if defined(HAVE_XLIB)
795 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
796 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
800 VT_GetWindow()->Map();
802 // Set the handle of created view in the event manager
803 ViewerTest::ResetEventManager();
805 ViewerTest::CurrentView()->Redraw();
810 return aViewNames.GetViewName();
813 //==============================================================================
814 //function : RedrawAllViews
815 //purpose : Redraw all created views
816 //==============================================================================
817 void ViewerTest::RedrawAllViews()
819 NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
820 for (; aViewIt.More(); aViewIt.Next())
822 const Handle(V3d_View)& aView = aViewIt.Key2();
827 //==============================================================================
830 //==============================================================================
831 static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
835 theDi << "Registered: ";
836 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
837 aFactoryIter.More(); aFactoryIter.Next())
839 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
840 theDi << aFactory->Name() << " ";
844 theDi << "Default: ";
845 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
847 theDi << aFactory->Name();
856 TCollection_AsciiString aNewActive;
858 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
860 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
861 anArgCase.LowerCase();
862 if (anArgCase == "-list")
864 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
865 aFactoryIter.More(); aFactoryIter.Next())
867 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
868 theDi << aFactory->Name() << " ";
871 else if ((anArgCase == "-default"
872 || anArgCase == "-load")
873 && aNewActive.IsEmpty())
875 toLoad = (anArgCase == "-load");
876 if (anArgIter + 1 < theArgsNb)
878 aNewActive = theArgVec[++anArgIter];
882 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
887 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
889 theDi << aFactory->Name();
897 else if (aNewActive.IsEmpty())
899 aNewActive = theArgVec[anArgIter];
903 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
908 if (!aNewActive.IsEmpty())
910 const TCollection_AsciiString aNameCopy = aNewActive;
911 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
912 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
913 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
915 aNewActive = "tkopengl";
917 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
918 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
919 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
921 aNewActive = "tkopengles";
923 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
924 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
925 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
927 aNewActive = "tkd3dhost";
932 if (aNewActive == "tkopengl")
934 Draw::GetInterpretor().Eval ("pload OPENGL");
936 else if (aNewActive == "tkopengles")
938 Draw::GetInterpretor().Eval ("pload GLES");
940 else if (aNewActive == "tkd3dhost")
942 Draw::GetInterpretor().Eval ("pload D3DHOST");
946 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
951 bool isFound = false;
952 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
953 aFactoryIter.More(); aFactoryIter.Next())
955 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
956 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
958 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
966 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
974 //==============================================================================
976 //purpose : Create the window viewer and initialize all the global variable
977 // Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
978 //==============================================================================
979 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
981 ViewerTest_VinitParams aParams;
982 TCollection_AsciiString aName, aValue;
983 int is2dMode = -1, aDpiAware = -1;
984 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
986 const TCollection_AsciiString anArg = theArgVec[anArgIt];
987 TCollection_AsciiString anArgCase = anArg;
988 anArgCase.LowerCase();
989 if (anArgIt + 1 < theArgsNb
990 && anArgCase == "-name")
992 aParams.ViewName = theArgVec[++anArgIt];
994 else if (anArgIt + 1 < theArgsNb
995 && (anArgCase == "-left"
996 || anArgCase == "-l")
997 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.x()))
1001 else if (anArgIt + 1 < theArgsNb
1002 && (anArgCase == "-top"
1003 || anArgCase == "-t")
1004 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.y()))
1008 else if (anArgIt + 1 < theArgsNb
1009 && (anArgCase == "-width"
1010 || anArgCase == "-w")
1011 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.x()))
1015 else if (anArgIt + 1 < theArgsNb
1016 && (anArgCase == "-height"
1017 || anArgCase == "-h")
1018 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.y()))
1022 else if (anArgIt + 1 < theArgsNb
1023 && (anArgCase == "-pos"
1024 || anArgCase == "-position"
1025 || anArgCase == "-corner")
1026 && ViewerTest::ParseCorner (theArgVec[anArgIt + 1], aParams.Corner))
1030 else if (anArgIt + 2 < theArgsNb
1031 && anArgCase == "-margins"
1032 && Draw::ParseInteger (theArgVec[anArgIt + 1], aParams.SubviewMargins.x())
1033 && Draw::ParseInteger (theArgVec[anArgIt + 2], aParams.SubviewMargins.y()))
1037 else if (anArgCase == "-virtual"
1038 || anArgCase == "-offscreen")
1040 aParams.IsVirtual = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1042 else if (anArgCase == "-composer")
1044 aParams.IsComposer = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
1046 else if (anArgCase == "-exitonclose")
1048 ViewerTest_EventManager::ToExitOnCloseView() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1050 else if (anArgCase == "-closeonescape"
1051 || anArgCase == "-closeonesc")
1053 ViewerTest_EventManager::ToCloseViewOnEscape() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1055 else if (anArgCase == "-2d_mode"
1056 || anArgCase == "-2dmode"
1057 || anArgCase == "-2d")
1059 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1060 is2dMode = toEnable ? 1 : 0;
1062 else if (anArgIt + 1 < theArgsNb
1063 && (anArgCase == "-disp"
1064 || anArgCase == "-display"))
1066 aParams.DisplayName = theArgVec[++anArgIt];
1068 else if (anArgCase == "-dpiaware")
1070 aDpiAware = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt) ? 1 : 0;
1072 else if (!ViewerTest::CurrentView().IsNull()
1073 && aParams.ViewToClone.IsNull()
1074 && (anArgCase == "-copy"
1075 || anArgCase == "-clone"
1076 || anArgCase == "-cloneactive"
1077 || anArgCase == "-cloneactiveview"))
1079 aParams.ViewToClone = ViewerTest::CurrentView();
1081 else if (!ViewerTest::CurrentView().IsNull()
1082 && aParams.ParentView.IsNull()
1083 && anArgCase == "-subview")
1085 aParams.ParentView = ViewerTest::CurrentView();
1086 if (aParams.ParentView.IsNull())
1088 Message::SendFail() << "Syntax error: cannot create of subview without parent";
1091 if (aParams.ParentView->IsSubview())
1093 aParams.ParentView = aParams.ParentView->ParentView();
1096 else if (!ViewerTest::CurrentView().IsNull()
1097 && aParams.ParentView.IsNull()
1098 && anArgCase == "-parent"
1099 && anArgIt + 1 < theArgsNb)
1101 TCollection_AsciiString aParentStr (theArgVec[++anArgIt]);
1102 ViewerTest_Names aViewNames (aParentStr);
1103 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1105 Message::SendFail() << "Syntax error: parent view '" << aParentStr << "' not found";
1109 aParams.ParentView = ViewerTest_myViews.Find1(aViewNames.GetViewName());
1110 if (aParams.ParentView->IsSubview())
1112 aParams.ParentView = aParams.ParentView->ParentView();
1116 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
1119 if (aName == "name")
1121 aParams.ViewName = aValue;
1123 else if (aName == "l"
1126 aParams.Offset.x() = (float)aValue.RealValue();
1128 else if (aName == "t"
1131 aParams.Offset.y() = (float)aValue.RealValue();
1133 else if (aName == "disp"
1134 || aName == "display")
1136 aParams.DisplayName = aValue;
1138 else if (aName == "w"
1139 || aName == "width")
1141 aParams.Size.x() = (float )aValue.RealValue();
1143 else if (aName == "h"
1144 || aName == "height")
1146 aParams.Size.y() = (float)aValue.RealValue();
1150 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1154 else if (aParams.ViewName.IsEmpty())
1156 aParams.ViewName = anArg;
1160 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1166 if (aDpiAware != -1)
1168 typedef void* (WINAPI *SetThreadDpiAwarenessContext_t)(void*);
1169 if (HMODULE aUser32Module = GetModuleHandleW (L"User32"))
1171 SetThreadDpiAwarenessContext_t aSetDpiAware = (SetThreadDpiAwarenessContext_t )GetProcAddress (aUser32Module, "SetThreadDpiAwarenessContext");
1174 // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
1175 if (aSetDpiAware ((void* )-4) == NULL)
1177 // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE for older systems
1178 if (aSetDpiAware ((void* )-3) == NULL)
1180 Message::SendFail() << "Error: unable to enable DPI awareness";
1186 // DPI_AWARENESS_CONTEXT_UNAWARE
1187 if (aSetDpiAware ((void* )-1) == NULL)
1189 Message::SendFail() << "Error: unable to disable DPI awareness";
1196 #if !defined(HAVE_XLIB)
1197 if (!aParams.DisplayName.IsEmpty())
1199 aParams.DisplayName.Clear();
1200 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
1205 ViewerTest_Names aViewNames (aParams.ViewName);
1206 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1208 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
1209 theDi.Eval (aCommand.ToCString());
1212 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1217 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
1220 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1226 //! Parse HLR algo type.
1227 static Standard_Boolean parseHlrAlgoType (const char* theName,
1228 Prs3d_TypeOfHLR& theType)
1230 TCollection_AsciiString aName (theName);
1232 if (aName == "polyalgo")
1234 theType = Prs3d_TOH_PolyAlgo;
1236 else if (aName == "algo")
1238 theType = Prs3d_TOH_Algo;
1242 return Standard_False;
1244 return Standard_True;
1247 //==============================================================================
1249 //purpose : hidden lines removal algorithm
1250 //==============================================================================
1252 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1254 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1255 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1258 Message::SendFail ("Error: no active viewer");
1262 Standard_Boolean hasHlrOnArg = Standard_False;
1263 Standard_Boolean hasShowHiddenArg = Standard_False;
1264 Standard_Boolean isHLROn = Standard_False;
1265 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
1266 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1267 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1268 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1270 TCollection_AsciiString anArg (argv[anArgIter]);
1272 if (anUpdateTool.parseRedrawMode (anArg))
1276 else if (anArg == "-showhidden"
1277 && anArgIter + 1 < argc
1278 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1281 hasShowHiddenArg = Standard_True;
1284 else if ((anArg == "-type"
1286 || anArg == "-algotype")
1287 && anArgIter + 1 < argc
1288 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1293 else if (!hasHlrOnArg
1294 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1296 hasHlrOnArg = Standard_True;
1300 else if (!hasShowHiddenArg
1301 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1303 hasShowHiddenArg = Standard_True;
1308 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1314 di << "HLR: " << aView->ComputedMode() << "\n";
1315 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
1317 switch (aCtx->DefaultDrawer()->TypeOfHLR())
1319 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
1320 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
1321 case Prs3d_TOH_Algo: di << "Algo\n"; break;
1323 anUpdateTool.Invalidate();
1327 Standard_Boolean toRecompute = Standard_False;
1328 if (aTypeOfHLR != Prs3d_TOH_NotSet
1329 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
1331 toRecompute = Standard_True;
1332 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1334 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
1336 toRecompute = Standard_True;
1339 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
1343 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
1348 if (aView->ComputedMode() && isHLROn && toRecompute)
1350 AIS_ListOfInteractive aListOfShapes;
1351 aCtx->DisplayedObjects (aListOfShapes);
1352 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
1354 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
1356 aCtx->Redisplay (aShape, Standard_False);
1361 aView->SetComputedMode (isHLROn);
1365 //==============================================================================
1366 //function : VHLRType
1367 //purpose : change type of using HLR algorithm
1368 //==============================================================================
1370 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1372 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1373 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1376 Message::SendFail ("Error: no active viewer");
1380 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1381 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1382 AIS_ListOfInteractive aListOfShapes;
1383 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1385 TCollection_AsciiString anArg (argv[anArgIter]);
1387 if (anUpdateTool.parseRedrawMode (anArg))
1391 else if ((anArg == "-type"
1393 || anArg == "-algotype")
1394 && anArgIter + 1 < argc
1395 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1401 else if (aTypeOfHLR == Prs3d_TOH_NotSet
1402 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
1408 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1409 TCollection_AsciiString aName (argv[anArgIter]);
1410 if (!aMap.IsBound2 (aName))
1412 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1416 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
1417 if (aShape.IsNull())
1419 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1422 aListOfShapes.Append (aShape);
1426 if (aTypeOfHLR == Prs3d_TOH_NotSet)
1428 Message::SendFail ("Syntax error: wrong number of arguments");
1432 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
1435 aCtx->DisplayedObjects (aListOfShapes);
1436 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1439 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
1441 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1442 if (aShape.IsNull())
1447 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
1448 && aView->ComputedMode();
1450 || aShape->TypeOfHLR() != aTypeOfHLR)
1452 aShape->SetTypeOfHLR (aTypeOfHLR);
1456 aCtx->Redisplay (aShape, Standard_False);
1462 //==============================================================================
1463 //function : FindViewIdByWindowHandle
1464 //purpose : Find theView Id in the map of views by window handle
1465 //==============================================================================
1466 #if defined(_WIN32) || defined(HAVE_XLIB)
1467 static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
1469 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
1470 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1472 Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
1473 if (aWindowHandle == theWindowHandle)
1474 return anIter.Key1();
1476 return TCollection_AsciiString("");
1480 //! Make the view active
1481 void ActivateView (const TCollection_AsciiString& theViewName,
1482 Standard_Boolean theToUpdate = Standard_True)
1484 if (const Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName))
1486 ViewerTest::ActivateView (aView, theToUpdate);
1490 //==============================================================================
1491 //function : ActivateView
1493 //==============================================================================
1494 void ViewerTest::ActivateView (const Handle(V3d_View)& theView,
1495 Standard_Boolean theToUpdate)
1497 Handle(V3d_View) aView = theView;
1498 const TCollection_AsciiString* aViewName = ViewerTest_myViews.Seek2 (aView);
1499 if (aViewName == nullptr)
1504 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
1505 if (anAISContext.IsNull())
1510 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
1512 if (!aCurrentView->Window().IsNull())
1514 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
1518 ViewerTest::CurrentView (aView);
1519 ViewerTest::SetAISContext (anAISContext);
1520 if (aView->IsSubview())
1522 aView->ParentView()->Window()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
1523 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->View()->ParentView()->Window());
1527 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->Window());
1529 if (!VT_GetWindow().IsNull())
1531 VT_GetWindow()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
1533 SetDisplayConnection(aView->Viewer()->Driver()->GetDisplayConnection());
1540 //==============================================================================
1541 //function : RemoveView
1543 //==============================================================================
1544 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
1545 const Standard_Boolean theToRemoveContext)
1547 if (!ViewerTest_myViews.IsBound2 (theView))
1552 const TCollection_AsciiString aViewName = ViewerTest_myViews.Find2 (theView);
1553 RemoveView (aViewName, theToRemoveContext);
1556 //==============================================================================
1557 //function : RemoveView
1558 //purpose : Close and remove view from display, clear maps if necessary
1559 //==============================================================================
1560 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
1562 if (!ViewerTest_myViews.IsBound1(theViewName))
1564 Message::SendFail() << "Wrong view name";
1568 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1569 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1570 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
1571 aRedrawer.Stop (aView);
1572 if (!aView->Subviews().IsEmpty())
1574 NCollection_Sequence<Handle(V3d_View)> aSubviews = aView->Subviews();
1575 for (const Handle(V3d_View)& aSubviewIter : aSubviews)
1577 RemoveView (aSubviewIter, isContextRemoved);
1581 // Activate another view if it's active now
1582 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
1584 if (ViewerTest_myViews.Extent() > 1)
1586 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1587 anIter.More(); anIter.Next())
1589 if (anIter.Key1() != theViewName)
1591 ActivateView (anIter.Value(), true);
1598 VT_GetWindow().Nullify();
1599 ViewerTest::CurrentView (Handle(V3d_View)());
1600 if (isContextRemoved)
1602 Handle(AIS_InteractiveContext) anEmptyContext;
1603 ViewerTest::SetAISContext(anEmptyContext);
1609 ViewerTest_myViews.UnBind1(theViewName);
1610 if (!aView->Window().IsNull())
1612 aView->Window()->Unmap();
1616 #if defined(HAVE_XLIB)
1617 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
1620 // Keep context opened only if the closed view is last to avoid
1621 // unused empty contexts
1622 if (!aCurrentContext.IsNull())
1624 // Check if there are more defined views in the viewer
1625 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
1626 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
1628 // Remove driver if there is no viewers that use it
1629 Standard_Boolean isRemoveDriver = Standard_True;
1630 for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1631 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1633 if (aCurrentContext != anIter.Key2() &&
1634 aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
1636 isRemoveDriver = Standard_False;
1641 aCurrentContext->RemoveAll (Standard_False);
1644 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1645 #if defined(HAVE_XLIB)
1646 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
1650 ViewerTest_myContexts.UnBind2(aCurrentContext);
1653 Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
1654 if (ViewerTest_EventManager::ToExitOnCloseView())
1656 Draw_Interprete ("exit");
1660 //==============================================================================
1662 //purpose : Remove the view defined by its name
1663 //==============================================================================
1665 static int VClose (Draw_Interpretor& /*theDi*/,
1666 Standard_Integer theArgsNb,
1667 const char** theArgVec)
1669 NCollection_List<TCollection_AsciiString> aViewList;
1672 TCollection_AsciiString anArg (theArgVec[1]);
1674 if (anArg.IsEqual ("ALL")
1675 || anArg.IsEqual ("*"))
1677 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
1678 anIter.More(); anIter.Next())
1680 aViewList.Append (anIter.Key1());
1682 if (aViewList.IsEmpty())
1684 std::cout << "No view to close\n";
1690 ViewerTest_Names aViewName (theArgVec[1]);
1691 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
1693 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
1696 aViewList.Append (aViewName.GetViewName());
1701 // close active view
1702 if (ViewerTest::CurrentView().IsNull())
1704 Message::SendFail ("Error: no active view");
1707 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1710 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
1711 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1712 anIter.More(); anIter.Next())
1714 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
1720 //==============================================================================
1721 //function : VActivate
1722 //purpose : Activate the view defined by its ID
1723 //==============================================================================
1725 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1729 theDi.Eval("vviewlist");
1733 TCollection_AsciiString aNameString;
1734 Standard_Boolean toUpdate = Standard_True;
1735 Standard_Boolean toActivate = Standard_True;
1736 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
1738 TCollection_AsciiString anArg (theArgVec[anArgIter]);
1741 && anArg == "-noupdate")
1743 toUpdate = Standard_False;
1746 && aNameString.IsEmpty()
1749 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1750 VT_GetWindow().Nullify();
1751 ViewerTest::CurrentView (Handle(V3d_View)());
1752 ViewerTest::ResetEventManager();
1753 theDi << theArgVec[0] << ": all views are inactive\n";
1754 toActivate = Standard_False;
1757 && aNameString.IsEmpty())
1759 aNameString = theArgVec[anArgIter];
1763 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
1772 else if (aNameString.IsEmpty())
1774 Message::SendFail ("Syntax error: wrong number of arguments");
1778 // Check if this view exists in the viewer with the driver
1779 ViewerTest_Names aViewNames (aNameString);
1780 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1782 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
1786 // Check if it is active already
1787 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1789 theDi << theArgVec[0] << ": the view is active already\n";
1793 ActivateView (aViewNames.GetViewName(), toUpdate);
1797 //==============================================================================
1798 //function : VViewList
1799 //purpose : Print current list of views per viewer and graphic driver ID
1800 // shared between viewers
1801 //==============================================================================
1803 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1807 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1808 << "Usage: " << theArgVec[0] << " name";
1811 if (ViewerTest_myContexts.Size() < 1)
1814 Standard_Boolean isTreeView =
1815 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1819 theDi << theArgVec[0] <<":\n";
1822 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
1823 aDriverIter.More(); aDriverIter.Next())
1826 theDi << aDriverIter.Key1() << ":\n";
1828 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
1829 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1831 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1835 TCollection_AsciiString aContextName(aContextIter.Key1());
1836 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
1839 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
1840 aViewIter.More(); aViewIter.Next())
1842 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1844 TCollection_AsciiString aViewName(aViewIter.Key1());
1847 if (aViewIter.Value() == ViewerTest::CurrentView())
1848 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
1850 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1854 theDi << aViewName << " ";
1864 //==============================================================================
1865 //function : GetMousePosition
1867 //==============================================================================
1868 void ViewerTest::GetMousePosition (Standard_Integer& theX,
1869 Standard_Integer& theY)
1871 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
1873 theX = aViewCtrl->LastMousePosition().x();
1874 theY = aViewCtrl->LastMousePosition().y();
1878 //==============================================================================
1879 //function : VViewProj
1880 //purpose : Switch view projection
1881 //==============================================================================
1882 static int VViewProj (Draw_Interpretor& ,
1883 Standard_Integer theNbArgs,
1884 const char** theArgVec)
1886 static Standard_Boolean isYup = Standard_False;
1887 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
1890 Message::SendFail ("Error: no active viewer");
1894 TCollection_AsciiString aCmdName (theArgVec[0]);
1895 Standard_Boolean isGeneralCmd = Standard_False;
1896 if (aCmdName == "vfront")
1898 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1900 else if (aCmdName == "vback")
1902 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1904 else if (aCmdName == "vtop")
1906 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1908 else if (aCmdName == "vbottom")
1910 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1912 else if (aCmdName == "vleft")
1914 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1916 else if (aCmdName == "vright")
1918 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1920 else if (aCmdName == "vaxo")
1922 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
1926 isGeneralCmd = Standard_True;
1927 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1929 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1930 anArgCase.LowerCase();
1931 if (anArgCase == "-zup")
1933 isYup = Standard_False;
1935 else if (anArgCase == "-yup")
1937 isYup = Standard_True;
1939 else if (anArgCase == "-front"
1940 || anArgCase == "front"
1941 || anArgCase == "-f"
1942 || anArgCase == "f")
1944 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1946 else if (anArgCase == "-back"
1947 || anArgCase == "back"
1948 || anArgCase == "-b"
1949 || anArgCase == "b")
1951 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1953 else if (anArgCase == "-top"
1954 || anArgCase == "top"
1955 || anArgCase == "-t"
1956 || anArgCase == "t")
1958 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1960 else if (anArgCase == "-bottom"
1961 || anArgCase == "bottom"
1962 || anArgCase == "-bot"
1963 || anArgCase == "bot"
1964 || anArgCase == "-b"
1965 || anArgCase == "b")
1967 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1969 else if (anArgCase == "-left"
1970 || anArgCase == "left"
1971 || anArgCase == "-l"
1972 || anArgCase == "l")
1974 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1976 else if (anArgCase == "-right"
1977 || anArgCase == "right"
1978 || anArgCase == "-r"
1979 || anArgCase == "r")
1981 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1983 else if (anArgCase == "-axoleft"
1984 || anArgCase == "-leftaxo"
1985 || anArgCase == "axoleft"
1986 || anArgCase == "leftaxo")
1988 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
1990 else if (anArgCase == "-axo"
1991 || anArgCase == "axo"
1992 || anArgCase == "-a"
1994 || anArgCase == "-axoright"
1995 || anArgCase == "-rightaxo"
1996 || anArgCase == "axoright"
1997 || anArgCase == "rightaxo")
1999 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
2001 else if (anArgCase == "+x")
2003 aView->SetProj (V3d_Xpos, isYup);
2005 else if (anArgCase == "-x")
2007 aView->SetProj (V3d_Xneg, isYup);
2009 else if (anArgCase == "+y")
2011 aView->SetProj (V3d_Ypos, isYup);
2013 else if (anArgCase == "-y")
2015 aView->SetProj (V3d_Yneg, isYup);
2017 else if (anArgCase == "+z")
2019 aView->SetProj (V3d_Zpos, isYup);
2021 else if (anArgCase == "-z")
2023 aView->SetProj (V3d_Zneg, isYup);
2025 else if (anArgCase == "+x+y+z")
2027 aView->SetProj (V3d_XposYposZpos, isYup);
2029 else if (anArgCase == "+x+y-z")
2031 aView->SetProj (V3d_XposYposZneg, isYup);
2033 else if (anArgCase == "+x-y+z")
2035 aView->SetProj (V3d_XposYnegZpos, isYup);
2037 else if (anArgCase == "+x-y-z")
2039 aView->SetProj (V3d_XposYnegZneg, isYup);
2041 else if (anArgCase == "-x+y+z")
2043 aView->SetProj (V3d_XnegYposZpos, isYup);
2045 else if (anArgCase == "-x+y-z")
2047 aView->SetProj (V3d_XnegYposZneg, isYup);
2049 else if (anArgCase == "-x-y+z")
2051 aView->SetProj (V3d_XnegYnegZpos, isYup);
2053 else if (anArgCase == "-x-y-z")
2055 aView->SetProj (V3d_XnegYnegZneg, isYup);
2057 else if (anArgCase == "+x+y")
2059 aView->SetProj (V3d_XposYpos, isYup);
2061 else if (anArgCase == "+x-y")
2063 aView->SetProj (V3d_XposYneg, isYup);
2065 else if (anArgCase == "-x+y")
2067 aView->SetProj (V3d_XnegYpos, isYup);
2069 else if (anArgCase == "-x-y")
2071 aView->SetProj (V3d_XnegYneg, isYup);
2073 else if (anArgCase == "+x+z")
2075 aView->SetProj (V3d_XposZpos, isYup);
2077 else if (anArgCase == "+x-z")
2079 aView->SetProj (V3d_XposZneg, isYup);
2081 else if (anArgCase == "-x+z")
2083 aView->SetProj (V3d_XnegZpos, isYup);
2085 else if (anArgCase == "-x-z")
2087 aView->SetProj (V3d_XnegZneg, isYup);
2089 else if (anArgCase == "+y+z")
2091 aView->SetProj (V3d_YposZpos, isYup);
2093 else if (anArgCase == "+y-z")
2095 aView->SetProj (V3d_YposZneg, isYup);
2097 else if (anArgCase == "-y+z")
2099 aView->SetProj (V3d_YnegZpos, isYup);
2101 else if (anArgCase == "-y-z")
2103 aView->SetProj (V3d_YnegZneg, isYup);
2105 else if (anArgIter + 1 < theNbArgs
2106 && anArgCase == "-frame"
2107 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
2109 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
2110 aFrameDef.LowerCase();
2111 gp_Dir aRight, anUp;
2112 if (aFrameDef.Value (2) == aFrameDef.Value (4))
2114 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2118 if (aFrameDef.Value (2) == 'x')
2120 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
2122 else if (aFrameDef.Value (2) == 'y')
2124 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
2126 else if (aFrameDef.Value (2) == 'z')
2128 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
2132 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2136 if (aFrameDef.Value (4) == 'x')
2138 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
2140 else if (aFrameDef.Value (4) == 'y')
2142 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
2144 else if (aFrameDef.Value (4) == 'z')
2146 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
2150 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2154 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
2155 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
2156 const gp_Dir aDir = anUp.Crossed (aRight);
2157 aCamera->SetCenter (gp_Pnt (0, 0, 0));
2158 aCamera->SetDirection (aDir);
2159 aCamera->SetUp (anUp);
2160 aCamera->OrthogonalizeUp();
2162 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
2167 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2176 Message::SendFail ("Syntax error: wrong number of arguments");
2182 //==============================================================================
2184 //purpose : Dsiplay help on viewer Keyboead and mouse commands
2185 //Draw arg : No args
2186 //==============================================================================
2188 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
2190 di << "=========================\n";
2191 di << "F : FitAll\n";
2192 di << "T : TopView\n";
2193 di << "B : BottomView\n";
2194 di << "R : RightView\n";
2195 di << "L : LeftView\n";
2196 di << "Backspace : AxonometricView\n";
2198 di << "=========================\n";
2199 di << "W, S : Fly forward/backward\n";
2200 di << "A, D : Slide left/right\n";
2201 di << "Q, E : Bank left/right\n";
2202 di << "-, + : Change flying speed\n";
2203 di << "Arrows : look left/right/up/down\n";
2204 di << "Arrows+Shift : slide left/right/up/down\n";
2206 di << "=========================\n";
2207 di << "S + Ctrl : Shading\n";
2208 di << "W + Ctrl : Wireframe\n";
2209 di << "H : HiddenLineRemoval\n";
2210 di << "U : Unset display mode\n";
2211 di << "Delete : Remove selection from viewer\n";
2213 di << "=========================\n";
2214 di << "Selection mode \n";
2215 di << "0 : Shape\n";
2216 di << "1 : Vertex\n";
2220 di << "5 : Shell\n";
2221 di << "6 : Solid\n";
2222 di << "7 : Compound\n";
2224 di << "=========================\n";
2225 di << "< : Hilight next detected\n";
2226 di << "> : Hilight previous detected\n";
2233 static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
2238 if (ViewerTest_myViews.IsEmpty())
2240 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2247 // Delete view from map of views
2248 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
2253 if (LOWORD(wParam) == WA_CLICKACTIVE
2254 || LOWORD(wParam) == WA_ACTIVE
2255 || ViewerTest::CurrentView().IsNull())
2257 // Activate inactive window
2258 if (VT_GetWindow().IsNull()
2259 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
2261 ActivateView (FindViewIdByWindowHandle (theWinHandle));
2268 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2270 && !VT_GetWindow().IsNull())
2273 aMsg.hwnd = theWinHandle;
2274 aMsg.message = theMsg;
2275 aMsg.wParam = wParam;
2276 aMsg.lParam = lParam;
2277 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
2284 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2287 //==============================================================================
2288 //function : ViewerMainLoop
2289 //purpose : Get a Event on the view and dispatch it
2290 //==============================================================================
2292 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2294 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
2295 if (aViewCtrl.IsNull()
2301 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2303 std::cout << "Start picking\n";
2307 while (aViewCtrl->ToPickPoint())
2309 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2310 if (GetMessageW (&aMsg, NULL, 0, 0))
2312 TranslateMessage (&aMsg);
2313 DispatchMessageW (&aMsg);
2317 std::cout << "Picking done\n";
2321 #elif defined(HAVE_XLIB)
2323 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2325 static XEvent aReport;
2326 const Standard_Boolean toPick = theNbArgs > 0;
2329 if (ViewerTest::CurrentEventManager().IsNull())
2333 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2336 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
2337 XNextEvent (aDisplay, &aReport);
2339 // Handle event for the chosen display connection
2340 switch (aReport.type)
2344 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2347 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2348 return toPick ? 0 : 1;
2354 // Activate inactive view
2355 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
2356 if (aWindow != aReport.xfocus.window)
2358 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2364 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2366 && !VT_GetWindow().IsNull())
2368 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
2373 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
2376 //==============================================================================
2377 //function : VProcessEvents
2378 //purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
2379 //==============================================================================
2380 static void VProcessEvents (ClientData theDispX, int)
2382 Display* aDispX = (Display* )theDispX;
2383 Handle(Aspect_DisplayConnection) aDispConn;
2384 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
2385 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
2387 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
2388 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
2390 aDispConn = aDispConnTmp;
2394 if (aDispConn.IsNull())
2396 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
2400 // process new events in queue
2401 SetDisplayConnection (aDispConn);
2403 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
2405 const int anEventResult = ViewerMainLoop (0, NULL);
2406 if (anEventResult == 0)
2411 aNbRemain = XPending (aDispX);
2412 if (++anEventIter >= aNbEventsMax
2419 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
2420 // it is possible that new events will arrive to queue before the end of this callback
2421 // so that either this callback should go into an infinite loop (blocking processing of other events)
2422 // or to keep unprocessed events till the next queue update (which can arrive not soon).
2423 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
2427 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
2428 aDummyEvent.type = ClientMessage;
2429 aDummyEvent.xclient.format = 32;
2430 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
2434 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
2436 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
2439 #elif !defined(__APPLE__)
2440 // =======================================================================
2441 // function : ViewerMainLoop
2443 // =======================================================================
2444 int ViewerMainLoop (Standard_Integer , const char** )
2451 //==============================================================================
2454 //==============================================================================
2456 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
2458 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2461 Message::SendFail ("Error: no active viewer");
2465 Standard_Boolean toFit = Standard_True;
2466 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2467 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2469 TCollection_AsciiString anArg (theArgv[anArgIter]);
2471 if (anUpdateTool.parseRedrawMode (anArg))
2475 else if (anArg == "-selected")
2477 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
2478 toFit = Standard_False;
2482 Message::SendFail() << "Syntax error at '" << anArg << "'";
2488 aView->FitAll (0.01, Standard_False);
2493 //=======================================================================
2494 //function : VFitArea
2495 //purpose : Fit view to show area located between two points
2496 // : given in world 2D or 3D coordinates.
2497 //=======================================================================
2498 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
2500 Handle(V3d_View) aView = ViewerTest::CurrentView();
2503 Message::SendFail ("Error: No active viewer");
2508 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
2509 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
2513 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2514 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2515 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
2516 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
2518 else if (theArgNb == 7)
2520 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2521 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2522 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
2523 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
2524 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
2525 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
2529 Message::SendFail ("Syntax error: Invalid number of arguments");
2530 theDI.PrintHelp(theArgVec[0]);
2534 // Convert model coordinates to view space
2535 Handle(Graphic3d_Camera) aCamera = aView->Camera();
2536 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
2537 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
2539 // Determine fit area
2540 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
2541 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
2543 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
2545 if (aDiagonal < Precision::Confusion())
2547 Message::SendFail ("Error: view area is too small");
2551 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
2555 //==============================================================================
2557 //purpose : ZFitall, no DRAW arguments
2558 //Draw arg : No args
2559 //==============================================================================
2560 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2562 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2564 if (aCurrentView.IsNull())
2566 Message::SendFail ("Error: no active viewer");
2572 aCurrentView->ZFitAll();
2573 aCurrentView->Redraw();
2577 Standard_Real aScale = 1.0;
2581 aScale = Draw::Atoi (theArgVec[1]);
2584 aCurrentView->ZFitAll (aScale);
2585 aCurrentView->Redraw();
2590 //==============================================================================
2591 //function : VRepaint
2593 //==============================================================================
2594 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
2596 Handle(V3d_View) aView = ViewerTest::CurrentView();
2599 Message::SendFail ("Error: no active viewer");
2603 Standard_Boolean isImmediateUpdate = Standard_False;
2604 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2606 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2608 if (anArg == "-immediate"
2611 isImmediateUpdate = Standard_True;
2612 if (anArgIter + 1 < theArgNb
2613 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
2618 else if (anArg == "-continuous"
2621 || anArg == "-framerate")
2623 Standard_Real aFps = -1.0;
2624 if (anArgIter + 1 < theArgNb
2625 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
2627 aFps = Draw::Atof (theArgVec[++anArgIter]);
2630 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2631 ViewerTest::CurrentEventManager()->SetContinuousRedraw (false);
2634 aRedrawer.Start (aView, aFps);
2636 else if (aFps < 0.0)
2638 if (ViewerTest::GetViewerFromContext()->ActiveViews().Extent() == 1)
2641 ViewerTest::CurrentEventManager()->SetContinuousRedraw (true);
2642 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
2645 aRedrawer.Start (aView, aFps);
2654 Message::SendFail() << "Syntax error at '" << anArg << "'";
2659 if (isImmediateUpdate)
2661 aView->RedrawImmediate();
2670 //==============================================================================
2672 //purpose : Remove all the object from the viewer
2673 //Draw arg : No args
2674 //==============================================================================
2676 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2678 Handle(V3d_View) V = ViewerTest::CurrentView();
2680 ViewerTest::Clear();
2684 //==============================================================================
2687 //==============================================================================
2689 static int VPick (Draw_Interpretor& ,
2690 Standard_Integer theNbArgs,
2691 const char** theArgVec)
2693 if (ViewerTest::CurrentView().IsNull())
2700 Message::SendFail ("Syntax error: wrong number of arguments");
2704 while (ViewerMainLoop (theNbArgs, theArgVec))
2712 //! Parse image fill method.
2713 static bool parseImageMode (const TCollection_AsciiString& theName,
2714 Aspect_FillMethod& theMode)
2716 TCollection_AsciiString aName = theName;
2718 if (aName == "none")
2720 theMode = Aspect_FM_NONE;
2722 else if (aName == "centered")
2724 theMode = Aspect_FM_CENTERED;
2726 else if (aName == "tiled")
2728 theMode = Aspect_FM_TILED;
2730 else if (aName == "stretch")
2732 theMode = Aspect_FM_STRETCH;
2741 //! Parse gradient fill method.
2742 static bool parseGradientMode (const TCollection_AsciiString& theName,
2743 Aspect_GradientFillMethod& theMode)
2745 TCollection_AsciiString aName = theName;
2747 if (aName == "none")
2749 theMode = Aspect_GradientFillMethod_None;
2751 else if (aName == "hor"
2752 || aName == "horizontal")
2754 theMode = Aspect_GradientFillMethod_Horizontal;
2756 else if (aName == "ver"
2758 || aName == "vertical")
2760 theMode = Aspect_GradientFillMethod_Vertical;
2762 else if (aName == "diag"
2763 || aName == "diagonal"
2765 || aName == "diagonal1")
2767 theMode = Aspect_GradientFillMethod_Diagonal1;
2769 else if (aName == "diag2"
2770 || aName == "diagonal2")
2772 theMode = Aspect_GradientFillMethod_Diagonal2;
2774 else if (aName == "corner1")
2776 theMode = Aspect_GradientFillMethod_Corner1;
2778 else if (aName == "corner2")
2780 theMode = Aspect_GradientFillMethod_Corner2;
2782 else if (aName == "corner3")
2784 theMode = Aspect_GradientFillMethod_Corner3;
2786 else if (aName == "corner4")
2788 theMode = Aspect_GradientFillMethod_Corner4;
2790 else if (aName == "ellip"
2791 || aName == "elliptical")
2793 theMode = Aspect_GradientFillMethod_Elliptical;
2802 //==============================================================================
2803 //function : VBackground
2805 //==============================================================================
2806 static int VBackground (Draw_Interpretor& theDI,
2807 Standard_Integer theNbArgs,
2808 const char** theArgVec)
2812 theDI << "Syntax error: wrong number of arguments";
2816 const TCollection_AsciiString aCmdName (theArgVec[0]);
2817 bool isDefault = aCmdName == "vsetdefaultbg";
2818 Standard_Integer aNbColors = 0;
2819 Quantity_ColorRGBA aColors[2];
2821 Aspect_GradientFillMethod aGradientMode = Aspect_GradientFillMethod_None;
2822 bool hasGradientMode = false;
2824 TCollection_AsciiString anImagePath;
2825 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
2826 bool hasImageMode = false;
2828 bool isSkydomeBg = false;
2829 Aspect_SkydomeBackground aSkydomeAspect;
2831 NCollection_Sequence<TCollection_AsciiString> aCubeMapSeq;
2832 Graphic3d_CubeMapOrder aCubeOrder = Graphic3d_CubeMapOrder::Default();
2833 bool isCubeZInverted = false;
2838 Handle(V3d_View) aView = ViewerTest::CurrentView();
2839 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
2840 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2842 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2844 if (anUpdateTool.parseRedrawMode (anArg))
2848 else if (anArg == "-default"
2853 else if (anArgIter + 1 < theNbArgs
2854 && (anArg == "-imagefile"
2855 || anArg == "-imgfile"
2856 || anArg == "-image"
2857 || anArg == "-img"))
2859 anImagePath = theArgVec[++anArgIter];
2861 else if (anArg == "-skydome"
2866 else if (anArgIter + 3 < theNbArgs
2868 && anArg == "-sundir")
2870 float aX = (float) Draw::Atof (theArgVec[++anArgIter]);
2871 float aY = (float) Draw::Atof (theArgVec[++anArgIter]);
2872 float aZ = (float) Draw::Atof (theArgVec[++anArgIter]);
2873 aSkydomeAspect.SetSunDirection (gp_Dir(aX, aY, aZ));
2875 else if (anArgIter + 1 < theNbArgs
2877 && anArg == "-cloud")
2879 float aCloudy = (float) Draw::Atof (theArgVec[++anArgIter]);
2880 aSkydomeAspect.SetCloudiness (aCloudy);
2882 else if (anArgIter + 1 < theNbArgs
2884 && anArg == "-time")
2886 float aTime = (float) Draw::Atof (theArgVec[++anArgIter]);
2887 aSkydomeAspect.SetTimeParameter (aTime);
2889 else if (anArgIter + 1 < theNbArgs
2893 float aFoggy = (float) Draw::Atof (theArgVec[++anArgIter]);
2894 aSkydomeAspect.SetFogginess (aFoggy);
2896 else if (anArgIter + 1 < theNbArgs
2898 && anArg == "-size")
2900 Standard_Integer aSize = Draw::Atoi (theArgVec[++anArgIter]);
2901 aSkydomeAspect.SetSize (aSize);
2903 else if (anArgIter + 1 < theNbArgs
2904 && aCubeMapSeq.IsEmpty()
2905 && (anArg == "-cubemap"
2909 aCubeMapSeq.Append (theArgVec[++anArgIter]);
2910 for (Standard_Integer aCubeSideIter = 1; anArgIter + aCubeSideIter < theNbArgs; ++aCubeSideIter)
2912 TCollection_AsciiString aSideArg (theArgVec[anArgIter + aCubeSideIter]);
2913 if (!aSideArg.IsEmpty()
2914 && aSideArg.Value (1) == '-')
2919 aCubeMapSeq.Append (aSideArg);
2920 if (aCubeMapSeq.Size() == 6)
2927 if (aCubeMapSeq.Size() > 1
2928 && aCubeMapSeq.Size() < 6)
2930 aCubeMapSeq.Remove (2, aCubeMapSeq.Size());
2933 else if (anArgIter + 6 < theNbArgs
2934 && anArg == "-order")
2936 for (Standard_Integer aCubeSideIter = 0; aCubeSideIter < 6; ++aCubeSideIter)
2938 Standard_Integer aSideArg = 0;
2939 if (!Draw::ParseInteger (theArgVec[anArgIter + aCubeSideIter + 1], aSideArg)
2943 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2946 aCubeOrder.Set ((Graphic3d_CubeMapSide )aCubeSideIter, (unsigned char )aSideArg);
2948 if (!aCubeOrder.IsValid())
2950 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2955 else if (anArg == "-invertedz"
2956 || anArg == "-noinvertedz"
2958 || anArg == "-noinvz")
2960 isCubeZInverted = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2962 else if (anArg == "-pbrenv"
2963 || anArg == "-nopbrenv"
2965 || anArg == "-noibl")
2967 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2968 if (anArgIter + 1 < theNbArgs)
2970 TCollection_AsciiString anIblArg (theArgVec[anArgIter + 1]);
2971 anIblArg.LowerCase();
2972 if (anIblArg == "keep"
2973 || anIblArg == "-1")
2978 else if (anIblArg == "ibl"
2980 || anIblArg == "on")
2982 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2985 else if (anIblArg == "noibl"
2987 || anIblArg == "off")
2989 toUseIBL = !anArg.StartsWith ("-no") ? 0 : 1;
2994 else if (anArg == "-srgb"
2995 || anArg == "-nosrgb")
2997 isSRgb = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2999 else if (aNbColors < 2
3000 && (anArg == "-color"
3001 || anArg == "-col"))
3003 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3004 theArgVec + (anArgIter + 1),
3005 aColors[aNbColors].ChangeRGB());
3008 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3011 anArgIter += aNbParsed;
3014 else if (anArgIter + 1 < theNbArgs
3015 && (anArg == "-gradientmode"
3016 || anArg == "-gradmode"
3017 || anArg == "-gradmd"
3018 || anArg == "-grmode"
3019 || anArg == "-grmd")
3020 && parseGradientMode (theArgVec[anArgIter + 1], aGradientMode))
3023 hasGradientMode = true;
3025 else if (anArgIter + 1 < theNbArgs
3026 && (anArg == "-imagemode"
3027 || anArg == "-imgmode"
3028 || anArg == "-imagemd"
3029 || anArg == "-imgmd")
3030 && parseImageMode (theArgVec[anArgIter + 1], anImageMode))
3033 hasImageMode = true;
3035 else if (aNbColors == 0
3036 && anArgIter + 2 < theNbArgs
3037 && (anArg == "-gradient"
3041 Standard_Integer aNbParsed1 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3042 theArgVec + (anArgIter + 1),
3043 aColors[aNbColors].ChangeRGB());
3044 anArgIter += aNbParsed1;
3046 if (aNbParsed1 == 0)
3048 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3051 Standard_Integer aNbParsed2 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3052 theArgVec + (anArgIter + 1),
3053 aColors[aNbColors].ChangeRGB());
3054 anArgIter += aNbParsed2;
3056 if (aNbParsed2 == 0)
3058 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3062 else if (parseGradientMode (theArgVec[anArgIter], aGradientMode))
3064 hasGradientMode = true;
3066 else if (aNbColors < 2
3067 && (Quantity_ColorRGBA::ColorFromName(theArgVec[anArgIter], aColors[aNbColors])
3068 || Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColors[aNbColors])))
3072 else if (anImagePath.IsEmpty()
3075 && aCubeMapSeq.IsEmpty())
3077 anImagePath = theArgVec[anArgIter];
3081 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3089 theDI << "Error: no active viewer";
3094 && !hasGradientMode)
3096 theDI << "Syntax error at '-default'";
3104 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
3105 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
3106 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_None;
3107 ViewerTest_DefaultBackground.FlatColor = aColors[0].GetRGB();
3108 ViewerTest_DefaultBackground.SetDefaultGradient();
3109 ViewerTest_DefaultBackground.SetDefaultColor();
3113 aView->SetBgGradientStyle (hasGradientMode ? aGradientMode : Aspect_GradientFillMethod_None);
3114 aView->SetBackgroundColor (aColors[0].GetRGB());
3117 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
3121 else if (aNbColors == 2)
3125 ViewerTest_DefaultBackground.GradientColor1 = aColors[0].GetRGB();
3126 ViewerTest_DefaultBackground.GradientColor2 = aColors[1].GetRGB();
3127 if (hasGradientMode)
3129 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
3131 else if (ViewerTest_DefaultBackground.FillMethod == Aspect_GradientFillMethod_None)
3133 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_Vertical;
3135 ViewerTest_DefaultBackground.SetDefaultGradient();
3139 if (!hasGradientMode)
3141 aGradientMode = aView->GradientBackground().BgGradientFillMethod();
3142 if (aGradientMode == Aspect_GradientFillMethod_None)
3144 aGradientMode = Aspect_GradientFillMethod_Vertical;
3147 aView->SetBgGradientColors (aColors[0].GetRGB(), aColors[1].GetRGB(), aGradientMode);
3150 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
3154 else if (hasGradientMode)
3158 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
3159 ViewerTest_DefaultBackground.SetDefaultGradient();
3163 aView->SetBgGradientStyle (aGradientMode);
3167 if (!anImagePath.IsEmpty())
3169 Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2D (anImagePath);
3170 aTextureMap->DisableModulate();
3171 aTextureMap->SetColorMap (isSRgb);
3172 if (!aTextureMap->IsDone())
3174 theDI << "Syntax error at '" << anImagePath << "'";
3177 aView->SetBackgroundImage (aTextureMap, anImageMode);
3179 else if (hasImageMode)
3181 aView->SetBgImageStyle (anImageMode);
3186 aView->SetBackgroundSkydome (aSkydomeAspect, toUseIBL != -1);
3189 if (!aCubeMapSeq.IsEmpty())
3191 Handle(Graphic3d_CubeMap) aCubeMap;
3192 if (aCubeMapSeq.Size() == 1)
3194 aCubeMap = new Graphic3d_CubeMapPacked (aCubeMapSeq.First(), aCubeOrder.Validated());
3198 NCollection_Array1<TCollection_AsciiString> aCubeMapArr (0, 5);
3199 Standard_Integer aCubeSide = 0;
3200 for (NCollection_Sequence<TCollection_AsciiString>::Iterator aFileIter (aCubeMapSeq); aFileIter.More(); aFileIter.Next(), ++aCubeSide)
3202 aCubeMapArr[aCubeSide] = aFileIter.Value();
3204 aCubeMap = new Graphic3d_CubeMapSeparate (aCubeMapArr);
3207 aCubeMap->SetZInversion (isCubeZInverted);
3208 aCubeMap->SetColorMap (isSRgb);
3210 aCubeMap->GetParams()->SetFilter (Graphic3d_TOTF_BILINEAR);
3211 aCubeMap->GetParams()->SetRepeat (false);
3212 aCubeMap->GetParams()->SetTextureUnit (Graphic3d_TextureUnit_EnvMap);
3214 aView->SetBackgroundCubeMap (aCubeMap, toUseIBL != -1);
3219 aView->SetImageBasedLighting (toUseIBL == 1);
3225 //==============================================================================
3227 //purpose : View Scaling
3228 //==============================================================================
3230 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3232 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3233 if ( V3dView.IsNull() ) return 1;
3236 di << argv[0] << "Invalid number of arguments\n";
3239 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
3242 //==============================================================================
3243 //function : VZBuffTrihedron
3245 //==============================================================================
3247 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3248 Standard_Integer theArgNb,
3249 const char** theArgVec)
3251 Handle(V3d_View) aView = ViewerTest::CurrentView();
3254 Message::SendFail ("Error: no active viewer");
3258 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
3260 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3261 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
3262 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3263 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3264 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
3265 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3266 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3267 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3268 Standard_Real aScale = 0.1;
3269 Standard_Real aSizeRatio = 0.8;
3270 Standard_Real anArrowDiam = 0.05;
3271 Standard_Integer aNbFacets = 12;
3272 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3274 Standard_CString anArg = theArgVec[anArgIter];
3275 TCollection_AsciiString aFlag (anArg);
3277 if (anUpdateTool.parseRedrawMode (aFlag))
3281 else if (aFlag == "-on")
3285 else if (aFlag == "-off")
3287 aView->TriedronErase();
3290 else if (aFlag == "-pos"
3291 || aFlag == "-position"
3292 || aFlag == "-corner")
3294 if (++anArgIter >= theArgNb)
3296 Message::SendFail() << "Syntax error at '" << anArg << "'";
3300 if (!ViewerTest::ParseCorner (theArgVec[anArgIter], aPosition))
3302 Message::SendFail() << "Syntax error at '" << anArg << "' - unknown position '" << theArgVec[anArgIter] << "'";
3306 else if (aFlag == "-type")
3308 if (++anArgIter >= theArgNb)
3310 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3314 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3315 aTypeName.LowerCase();
3316 if (aTypeName == "wireframe"
3317 || aTypeName == "wire")
3319 aVisType = V3d_WIREFRAME;
3321 else if (aTypeName == "zbuffer"
3322 || aTypeName == "shaded")
3324 aVisType = V3d_ZBUFFER;
3328 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
3331 else if (aFlag == "-scale")
3333 if (++anArgIter >= theArgNb)
3335 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3339 aScale = Draw::Atof (theArgVec[anArgIter]);
3341 else if (aFlag == "-size"
3342 || aFlag == "-sizeratio")
3344 if (++anArgIter >= theArgNb)
3346 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3350 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3352 else if (aFlag == "-arrowdiam"
3353 || aFlag == "-arrowdiameter")
3355 if (++anArgIter >= theArgNb)
3357 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3361 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3363 else if (aFlag == "-nbfacets")
3365 if (++anArgIter >= theArgNb)
3367 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3371 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3373 else if (aFlag == "-colorlabel"
3374 || aFlag == "-colorlabels"
3375 || aFlag == "-colorlabelx"
3376 || aFlag == "-colorlabely"
3377 || aFlag == "-colorlabelz"
3378 || aFlag == "-colorarrowx"
3379 || aFlag == "-colorarrowy"
3380 || aFlag == "-colorarrowz")
3382 Quantity_Color aColor;
3383 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3384 theArgVec + anArgIter + 1,
3388 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3392 if (aFlag == "-colorarrowx")
3394 anArrowColorX = aColor;
3396 else if (aFlag == "-colorarrowy")
3398 anArrowColorY = aColor;
3400 else if (aFlag == "-colorarrowz")
3402 anArrowColorZ = aColor;
3404 else if (aFlag == "-colorlabelx")
3406 aLabelsColorX = aColor;
3408 else if (aFlag == "-colorlabely")
3410 aLabelsColorY = aColor;
3412 else if (aFlag == "-colorlabelz")
3414 aLabelsColorZ = aColor;
3418 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
3420 anArgIter += aNbParsed;
3424 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3429 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
3430 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
3431 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
3432 aTrihedron->SetSizeRatio (aSizeRatio);
3433 aTrihedron->SetNbFacets (aNbFacets);
3434 aTrihedron->SetArrowDiameter(anArrowDiam);
3435 aTrihedron->SetScale (aScale);
3436 aTrihedron->SetPosition (aPosition);
3437 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
3438 aTrihedron->Display (aView);
3444 //==============================================================================
3445 //function : VRotate
3446 //purpose : Camera Rotating
3447 //==============================================================================
3449 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
3451 Handle(V3d_View) aView = ViewerTest::CurrentView();
3454 Message::SendFail ("Error: no active viewer");
3458 Standard_Boolean hasFlags = Standard_False;
3459 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3461 Standard_CString anArg (theArgVec[anArgIter]);
3462 TCollection_AsciiString aFlag (anArg);
3464 if (aFlag == "-mousestart"
3465 || aFlag == "-mousefrom")
3467 hasFlags = Standard_True;
3468 if (anArgIter + 2 >= theArgNb)
3470 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3474 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3475 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3476 aView->StartRotation (anX, anY);
3478 else if (aFlag == "-mousemove")
3480 hasFlags = Standard_True;
3481 if (anArgIter + 2 >= theArgNb)
3483 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3487 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3488 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3489 aView->Rotation (anX, anY);
3491 else if (theArgNb != 4
3494 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3503 else if (theArgNb == 4)
3505 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3506 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3507 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3508 aView->Rotate (anAX, anAY, anAZ);
3511 else if (theArgNb == 7)
3513 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3514 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3515 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3517 Standard_Real anX = Draw::Atof (theArgVec[4]);
3518 Standard_Real anY = Draw::Atof (theArgVec[5]);
3519 Standard_Real anZ = Draw::Atof (theArgVec[6]);
3521 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
3525 Message::SendFail ("Error: Invalid number of arguments");
3529 //==============================================================================
3531 //purpose : View zoom in / out (relative to current zoom)
3532 //==============================================================================
3534 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3535 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3536 if ( V3dView.IsNull() ) {
3541 Standard_Real coef = Draw::Atof(argv[1]);
3542 if ( coef <= 0.0 ) {
3543 di << argv[1] << "Invalid value\n";
3546 V3dView->SetZoom( Draw::Atof(argv[1]) );
3549 di << argv[0] << " Invalid number of arguments\n";
3554 //==============================================================================
3556 //purpose : View panning (in pixels)
3557 //==============================================================================
3559 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3560 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3561 if ( V3dView.IsNull() ) return 1;
3564 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
3567 di << argv[0] << " Invalid number of arguments\n";
3572 //==============================================================================
3574 //purpose : Place the point (in pixels) at the center of the window
3575 //==============================================================================
3576 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
3578 Handle(V3d_View) aView = ViewerTest::CurrentView();
3581 Message::SendFail ("Error: no active viewer");
3587 Message::SendFail ("Syntax error: wrong number of arguments");
3591 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
3596 static int VColorScale (Draw_Interpretor& theDI,
3597 Standard_Integer theArgNb,
3598 const char** theArgVec)
3600 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3601 Handle(V3d_View) aView = ViewerTest::CurrentView();
3602 if (aContext.IsNull())
3604 Message::SendFail ("Error: no active viewer");
3609 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
3613 Handle(AIS_ColorScale) aColorScale;
3614 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
3616 // find existing object
3617 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
3618 if (aColorScale.IsNull())
3620 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
3627 if (aColorScale.IsNull())
3629 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
3633 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
3634 << "Min range: " << aColorScale->GetMin() << "\n"
3635 << "Max range: " << aColorScale->GetMax() << "\n"
3636 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
3637 << "Text height: " << aColorScale->GetTextHeight() << "\n"
3638 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
3639 << "Color scale title: " << aColorScale->GetTitle() << "\n"
3640 << "Label position: ";
3641 switch (aColorScale->GetLabelPosition())
3643 case Aspect_TOCSP_NONE:
3646 case Aspect_TOCSP_LEFT:
3649 case Aspect_TOCSP_RIGHT:
3652 case Aspect_TOCSP_CENTER:
3653 theDI << "Center\n";
3659 if (aColorScale.IsNull())
3661 aColorScale = new AIS_ColorScale();
3662 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
3663 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
3666 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
3667 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
3669 Standard_CString anArg = theArgVec[anArgIter];
3670 TCollection_AsciiString aFlag (anArg);
3672 if (anUpdateTool.parseRedrawMode (aFlag))
3676 else if (aFlag == "-range")
3678 if (anArgIter + 3 >= theArgNb)
3680 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
3684 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
3685 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
3686 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
3687 if (!aRangeMin.IsRealValue (Standard_True)
3688 || !aRangeMax.IsRealValue (Standard_True))
3690 Message::SendFail ("Syntax error: the range values should be real");
3693 else if (!aNbIntervals.IsIntegerValue())
3695 Message::SendFail ("Syntax error: the number of intervals should be integer");
3699 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
3700 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
3702 else if (aFlag == "-font")
3704 if (anArgIter + 1 >= theArgNb)
3706 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3709 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
3710 if (!aFontArg.IsIntegerValue())
3712 Message::SendFail ("Syntax error: HeightFont value should be integer");
3716 aColorScale->SetTextHeight (aFontArg.IntegerValue());
3719 else if (aFlag == "-textpos")
3721 if (anArgIter + 1 >= theArgNb)
3723 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3727 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
3728 aTextPosArg.LowerCase();
3729 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
3730 if (aTextPosArg == "none")
3732 aLabPosition = Aspect_TOCSP_NONE;
3734 else if (aTextPosArg == "left")
3736 aLabPosition = Aspect_TOCSP_LEFT;
3738 else if (aTextPosArg == "right")
3740 aLabPosition = Aspect_TOCSP_RIGHT;
3742 else if (aTextPosArg == "center")
3744 aLabPosition = Aspect_TOCSP_CENTER;
3748 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
3751 aColorScale->SetLabelPosition (aLabPosition);
3753 else if (aFlag == "-logarithmic"
3756 if (anArgIter + 1 >= theArgNb)
3758 Message::SendFail() << "Synta error at argument '" << anArg << "'";
3762 Standard_Boolean IsLog;
3763 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
3765 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3768 aColorScale->SetLogarithmic (IsLog);
3770 else if (aFlag == "-huerange"
3773 if (anArgIter + 2 >= theArgNb)
3775 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3779 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
3780 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
3781 aColorScale->SetHueRange (aHueMin, aHueMax);
3783 else if (aFlag == "-colorrange")
3785 Quantity_Color aColorMin, aColorMax;
3786 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3787 theArgVec + (anArgIter + 1),
3789 anArgIter += aNbParsed1;
3790 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3791 theArgVec + (anArgIter + 1),
3793 anArgIter += aNbParsed2;
3797 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3801 aColorScale->SetColorRange (aColorMin, aColorMax);
3803 else if (aFlag == "-reversed"
3804 || aFlag == "-inverted"
3805 || aFlag == "-topdown"
3806 || aFlag == "-bottomup")
3808 Standard_Boolean toEnable = Standard_True;
3809 if (anArgIter + 1 < theArgNb
3810 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
3814 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
3816 else if (aFlag == "-smooth"
3817 || aFlag == "-smoothtransition")
3819 Standard_Boolean toEnable = Standard_True;
3820 if (anArgIter + 1 < theArgNb
3821 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3825 aColorScale->SetSmoothTransition (toEnable);
3827 else if (aFlag == "-xy")
3829 if (anArgIter + 2 >= theArgNb)
3831 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3835 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
3836 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
3837 if (!anX.IsIntegerValue()
3838 || !anY.IsIntegerValue())
3840 Message::SendFail ("Syntax error: coordinates should be integer values");
3844 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
3846 else if (aFlag == "-width"
3848 || aFlag == "-breadth")
3850 if (anArgIter + 1 >= theArgNb)
3852 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3856 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
3857 if (!aBreadth.IsIntegerValue())
3859 Message::SendFail ("Syntax error: a width should be an integer value");
3862 aColorScale->SetBreadth (aBreadth.IntegerValue());
3864 else if (aFlag == "-height"
3867 if (anArgIter + 1 >= theArgNb)
3869 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3873 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
3874 if (!aHeight.IsIntegerValue())
3876 Message::SendFail ("Syntax error: a width should be an integer value");
3879 aColorScale->SetHeight (aHeight.IntegerValue());
3881 else if (aFlag == "-color")
3883 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3885 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
3888 else if (anArgIter + 2 >= theArgNb)
3890 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3894 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
3895 if (!anInd.IsIntegerValue())
3897 Message::SendFail ("Syntax error: Index value should be integer");
3900 const Standard_Integer anIndex = anInd.IntegerValue();
3901 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
3903 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
3907 Quantity_Color aColor;
3908 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3909 theArgVec + (anArgIter + 1),
3913 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3916 aColorScale->SetIntervalColor (aColor, anIndex);
3917 aColorScale->SetColorType (Aspect_TOCSD_USER);
3918 anArgIter += aNbParsed;
3920 else if (aFlag == "-label")
3922 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3924 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
3927 else if (anArgIter + 2 >= theArgNb)
3929 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3933 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
3934 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
3936 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
3940 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
3941 aColorScale->SetLabel (aText, anIndex);
3942 aColorScale->SetLabelType (Aspect_TOCSD_USER);
3945 else if (aFlag == "-labelat"
3946 || aFlag == "-labat"
3947 || aFlag == "-labelatborder"
3948 || aFlag == "-labatborder"
3949 || aFlag == "-labelatcenter"
3950 || aFlag == "-labatcenter")
3952 Standard_Boolean toEnable = Standard_True;
3953 if (aFlag == "-labelat"
3954 || aFlag == "-labat")
3956 Standard_Integer aLabAtBorder = -1;
3957 if (++anArgIter >= theArgNb)
3959 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
3960 anAtBorder.LowerCase();
3961 if (anAtBorder == "border")
3965 else if (anAtBorder == "center")
3970 if (aLabAtBorder == -1)
3972 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3975 toEnable = (aLabAtBorder == 1);
3977 else if (anArgIter + 1 < theArgNb
3978 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3982 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
3983 || aFlag == "-labatcenter"
3987 else if (aFlag == "-colors")
3989 Aspect_SequenceOfColor aSeq;
3992 Quantity_Color aColor;
3993 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3994 theArgVec + (anArgIter + 1),
4000 anArgIter += aNbParsed;
4001 aSeq.Append (aColor);
4003 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
4005 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4006 << aColorScale->GetNumberOfIntervals() << " intervals";
4010 aColorScale->SetColors (aSeq);
4011 aColorScale->SetColorType (Aspect_TOCSD_USER);
4013 else if (aFlag == "-uniform")
4015 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4016 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4017 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4018 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4019 aColorScale->SetColorType (Aspect_TOCSD_USER);
4021 else if (aFlag == "-labels"
4022 || aFlag == "-freelabels")
4024 if (anArgIter + 1 >= theArgNb)
4026 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4030 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4031 ? aColorScale->GetNumberOfIntervals() + 1
4032 : aColorScale->GetNumberOfIntervals();
4033 if (aFlag == "-freelabels")
4036 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4038 if (anArgIter + aNbLabels >= theArgNb)
4040 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
4044 TColStd_SequenceOfExtendedString aSeq;
4045 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
4047 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
4049 aColorScale->SetLabels (aSeq);
4050 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4052 else if (aFlag == "-title")
4054 if (anArgIter + 1 >= theArgNb)
4056 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4060 Standard_Boolean isTwoArgs = Standard_False;
4061 if (anArgIter + 2 < theArgNb)
4063 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4064 aSecondArg.LowerCase();
4065 Standard_DISABLE_DEPRECATION_WARNINGS
4066 if (aSecondArg == "none")
4068 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
4069 isTwoArgs = Standard_True;
4071 else if (aSecondArg == "left")
4073 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
4074 isTwoArgs = Standard_True;
4076 else if (aSecondArg == "right")
4078 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
4079 isTwoArgs = Standard_True;
4081 else if (aSecondArg == "center")
4083 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
4084 isTwoArgs = Standard_True;
4086 Standard_ENABLE_DEPRECATION_WARNINGS
4089 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4090 aColorScale->SetTitle (aTitle);
4097 else if (aFlag == "-demoversion"
4098 || aFlag == "-demo")
4100 aColorScale->SetPosition (0, 0);
4101 aColorScale->SetTextHeight (16);
4102 aColorScale->SetRange (0.0, 100.0);
4103 aColorScale->SetNumberOfIntervals (10);
4104 aColorScale->SetBreadth (0);
4105 aColorScale->SetHeight (0);
4106 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4107 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4108 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
4110 else if (aFlag == "-findcolor")
4112 if (anArgIter + 1 >= theArgNb)
4114 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4118 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4120 if (!anArg1.IsRealValue (Standard_True))
4122 Message::SendFail ("Syntax error: the value should be real");
4126 Quantity_Color aColor;
4127 aColorScale->FindColor (anArg1.RealValue(), aColor);
4128 theDI << Quantity_Color::StringName (aColor.Name());
4133 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
4138 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4139 aView->Window()->Size (aWinWidth, aWinHeight);
4140 if (aColorScale->GetBreadth() == 0)
4142 aColorScale->SetBreadth (aWinWidth);
4144 if (aColorScale->GetHeight() == 0)
4146 aColorScale->SetHeight (aWinHeight);
4148 aColorScale->SetToUpdate();
4149 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
4153 //==============================================================================
4154 //function : VGraduatedTrihedron
4155 //purpose : Displays or hides a graduated trihedron
4156 //==============================================================================
4157 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4158 Quantity_Color& theColor)
4160 Quantity_NameOfColor aColorName;
4161 TCollection_AsciiString aVal = theValue;
4163 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
4165 return Standard_False;
4167 theColor = Quantity_Color (aColorName);
4168 return Standard_True;
4171 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
4175 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4176 << theArgs[0] <<"' for more information";
4180 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4181 TCollection_AsciiString aParseKey;
4182 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4184 TCollection_AsciiString anArg (theArgs [anArgIt]);
4186 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
4189 aParseKey.Remove (1);
4190 aParseKey.LowerCase();
4191 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4195 if (aParseKey.IsEmpty())
4200 aMapOfArgs(aParseKey)->Append (anArg);
4204 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4205 aMapIt.More(); aMapIt.Next())
4207 const TCollection_AsciiString& aKey = aMapIt.Key();
4208 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4210 // Bool key, without arguments
4211 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4212 && anArgs->IsEmpty())
4218 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4219 && anArgs->Length() == 1)
4225 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4226 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
4227 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4228 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
4229 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4234 // One string argument
4235 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4236 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
4237 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4242 // One integer argument
4243 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4244 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4245 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4246 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4247 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4252 // One real argument
4253 if ( aKey.IsEqual ("arrowlength")
4254 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
4259 // Two string arguments
4260 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
4261 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4266 TCollection_AsciiString aLowerKey;
4269 aLowerKey.LowerCase();
4270 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4271 << "Type help for more information";
4275 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4276 if (anAISContext.IsNull())
4278 Message::SendFail ("Error: no active viewer");
4282 Standard_Boolean toDisplay = Standard_True;
4283 Quantity_Color aColor;
4284 Graphic3d_GraduatedTrihedron aTrihedronData;
4285 // Process parameters
4286 Handle(TColStd_HSequenceOfAsciiString) aValues;
4287 if (aMapOfArgs.Find ("off", aValues))
4289 toDisplay = Standard_False;
4293 if (aMapOfArgs.Find ("xname", aValues))
4295 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4297 if (aMapOfArgs.Find ("yname", aValues))
4299 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4301 if (aMapOfArgs.Find ("zname", aValues))
4303 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4305 if (aMapOfArgs.Find ("xdrawname", aValues))
4307 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4309 if (aMapOfArgs.Find ("ydrawname", aValues))
4311 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4313 if (aMapOfArgs.Find ("zdrawname", aValues))
4315 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4317 if (aMapOfArgs.Find ("xnameoffset", aValues))
4319 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4321 if (aMapOfArgs.Find ("ynameoffset", aValues))
4323 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4325 if (aMapOfArgs.Find ("znameoffset", aValues))
4327 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4331 if (aMapOfArgs.Find ("xnamecolor", aValues))
4333 if (!GetColor (aValues->Value(1), aColor))
4335 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
4338 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4340 if (aMapOfArgs.Find ("ynamecolor", aValues))
4342 if (!GetColor (aValues->Value(1), aColor))
4344 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
4347 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4349 if (aMapOfArgs.Find ("znamecolor", aValues))
4351 if (!GetColor (aValues->Value(1), aColor))
4353 Message::SendFail ("Syntax error: -znamecolor wrong color name");
4356 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4358 if (aMapOfArgs.Find ("xcolor", aValues))
4360 if (!GetColor (aValues->Value(1), aColor))
4362 Message::SendFail ("Syntax error: -xcolor wrong color name");
4365 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4367 if (aMapOfArgs.Find ("ycolor", aValues))
4369 if (!GetColor (aValues->Value(1), aColor))
4371 Message::SendFail ("Syntax error: -ycolor wrong color name");
4374 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4376 if (aMapOfArgs.Find ("zcolor", aValues))
4378 if (!GetColor (aValues->Value(1), aColor))
4380 Message::SendFail ("Syntax error: -zcolor wrong color name");
4383 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4387 if (aMapOfArgs.Find ("xticks", aValues))
4389 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4391 if (aMapOfArgs.Find ("yticks", aValues))
4393 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4395 if (aMapOfArgs.Find ("zticks", aValues))
4397 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4399 if (aMapOfArgs.Find ("xticklength", aValues))
4401 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4403 if (aMapOfArgs.Find ("yticklength", aValues))
4405 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4407 if (aMapOfArgs.Find ("zticklength", aValues))
4409 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4411 if (aMapOfArgs.Find ("xdrawticks", aValues))
4413 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4415 if (aMapOfArgs.Find ("ydrawticks", aValues))
4417 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4419 if (aMapOfArgs.Find ("zdrawticks", aValues))
4421 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4425 if (aMapOfArgs.Find ("xdrawvalues", aValues))
4427 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4429 if (aMapOfArgs.Find ("ydrawvalues", aValues))
4431 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4433 if (aMapOfArgs.Find ("zdrawvalues", aValues))
4435 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4437 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
4439 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4441 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
4443 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4445 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
4447 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4451 if (aMapOfArgs.Find ("arrowlength", aValues))
4453 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
4457 if (aMapOfArgs.Find ("namefont", aValues))
4459 aTrihedronData.SetNamesFont (aValues->Value(1));
4461 if (aMapOfArgs.Find ("valuesfont", aValues))
4463 aTrihedronData.SetValuesFont (aValues->Value(1));
4466 if (aMapOfArgs.Find ("drawgrid", aValues))
4468 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
4470 if (aMapOfArgs.Find ("drawaxes", aValues))
4472 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
4475 // The final step: display of erase trihedron
4478 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
4482 ViewerTest::CurrentView()->GraduatedTrihedronErase();
4485 ViewerTest::GetAISContext()->UpdateCurrentViewer();
4486 ViewerTest::CurrentView()->Redraw();
4491 //==============================================================================
4494 //==============================================================================
4495 static int VTile (Draw_Interpretor& theDI,
4496 Standard_Integer theArgNb,
4497 const char** theArgVec)
4499 Handle(V3d_View) aView = ViewerTest::CurrentView();
4502 Message::SendFail ("Error: no active viewer");
4506 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
4509 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
4510 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
4511 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
4515 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
4516 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4518 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4520 if (anArg == "-lowerleft"
4521 || anArg == "-upperleft")
4523 if (anArgIter + 3 < theArgNb)
4525 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4528 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
4529 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4530 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4532 else if (anArg == "-total"
4533 || anArg == "-totalsize"
4534 || anArg == "-viewsize")
4536 if (anArgIter + 3 < theArgNb)
4538 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4541 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4542 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4543 if (aTile.TotalSize.x() < 1
4544 || aTile.TotalSize.y() < 1)
4546 Message::SendFail ("Error: total size is incorrect");
4550 else if (anArg == "-tilesize")
4552 if (anArgIter + 3 < theArgNb)
4554 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4558 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4559 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4560 if (aTile.TileSize.x() < 1
4561 || aTile.TileSize.y() < 1)
4563 Message::SendFail ("Error: tile size is incorrect");
4567 else if (anArg == "-unset")
4569 aView->Camera()->SetTile (Graphic3d_CameraTile());
4575 if (aTile.TileSize.x() < 1
4576 || aTile.TileSize.y() < 1)
4578 Message::SendFail ("Error: tile size is undefined");
4581 else if (aTile.TotalSize.x() < 1
4582 || aTile.TotalSize.y() < 1)
4584 Message::SendFail ("Error: total size is undefined");
4588 aView->Camera()->SetTile (aTile);
4593 //! Format ZLayer ID.
4594 inline const char* formZLayerId (const Standard_Integer theLayerId)
4598 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
4599 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
4600 case Graphic3d_ZLayerId_Top: return "[TOP]";
4601 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
4602 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
4603 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
4608 //! Print the ZLayer information.
4609 inline void printZLayerInfo (Draw_Interpretor& theDI,
4610 const Graphic3d_ZLayerSettings& theLayer)
4612 if (!theLayer.Name().IsEmpty())
4614 theDI << " Name: " << theLayer.Name() << "\n";
4616 if (theLayer.IsImmediate())
4618 theDI << " Immediate: TRUE\n";
4620 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4621 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
4622 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
4623 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
4624 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
4625 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
4626 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
4628 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
4632 //==============================================================================
4633 //function : VZLayer
4634 //purpose : Test z layer operations for v3d viewer
4635 //==============================================================================
4636 static int VZLayer (Draw_Interpretor& theDI,
4637 Standard_Integer theArgNb,
4638 const char** theArgVec)
4640 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4641 if (aContextAIS.IsNull())
4643 Message::SendFail ("Error: no active viewer");
4647 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
4650 TColStd_SequenceOfInteger aLayers;
4651 aViewer->GetAllZLayers (aLayers);
4652 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4654 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
4655 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
4656 printZLayerInfo (theDI, aSettings);
4661 Standard_Integer anArgIter = 1;
4662 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4663 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
4664 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
4670 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
4671 if (aFirstArg.IsIntegerValue())
4674 aLayerId = aFirstArg.IntegerValue();
4678 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
4685 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
4686 for (; anArgIter < theArgNb; ++anArgIter)
4688 // perform operation
4689 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4691 if (anUpdateTool.parseRedrawMode (anArg))
4695 else if (anArg == "-add"
4698 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4699 if (!aViewer->AddZLayer (aLayerId))
4701 Message::SendFail ("Error: can not add a new z layer");
4707 else if (anArg == "-insertbefore"
4708 && anArgIter + 1 < theArgNb
4709 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4712 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4713 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4715 Message::SendFail ("Error: can not add a new z layer");
4721 else if (anArg == "-insertafter"
4722 && anArgIter + 1 < theArgNb
4723 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4726 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4727 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4729 Message::SendFail ("Error: can not add a new z layer");
4735 else if (anArg == "-del"
4736 || anArg == "-delete"
4739 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4741 if (++anArgIter >= theArgNb)
4743 Message::SendFail ("Syntax error: id of z layer to remove is missing");
4747 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4750 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
4751 || aLayerId == Graphic3d_ZLayerId_Default
4752 || aLayerId == Graphic3d_ZLayerId_Top
4753 || aLayerId == Graphic3d_ZLayerId_Topmost
4754 || aLayerId == Graphic3d_ZLayerId_TopOSD
4755 || aLayerId == Graphic3d_ZLayerId_BotOSD)
4757 Message::SendFail ("Syntax error: standard Z layer can not be removed");
4761 // move all object displayed in removing layer to default layer
4762 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4763 anObjIter.More(); anObjIter.Next())
4765 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
4767 || aPrs->ZLayer() != aLayerId)
4771 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
4774 if (!aViewer->RemoveZLayer (aLayerId))
4776 Message::SendFail ("Z layer can not be removed");
4780 theDI << aLayerId << " ";
4783 else if (anArg == "-get"
4786 TColStd_SequenceOfInteger aLayers;
4787 aViewer->GetAllZLayers (aLayers);
4788 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4790 theDI << aLayeriter.Value() << " ";
4795 else if (anArg == "-name")
4797 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4799 Message::SendFail ("Syntax error: id of Z layer is missing");
4803 if (++anArgIter >= theArgNb)
4805 Message::SendFail ("Syntax error: name is missing");
4809 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4810 aSettings.SetName (theArgVec[anArgIter]);
4811 aViewer->SetZLayerSettings (aLayerId, aSettings);
4813 else if (anArg == "-origin")
4815 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4817 Message::SendFail ("Syntax error: id of Z layer is missing");
4821 if (anArgIter + 2 >= theArgNb)
4823 Message::SendFail ("Syntax error: origin coordinates are missing");
4827 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4829 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
4830 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
4831 anOrigin.SetZ (0.0);
4832 if (anArgIter + 3 < theArgNb)
4834 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
4841 aSettings.SetOrigin (anOrigin);
4842 aViewer->SetZLayerSettings (aLayerId, aSettings);
4844 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4845 && anArgIter + 1 < theArgNb
4846 && (anArg == "-cullingdistance"
4847 || anArg == "-cullingdist"
4848 || anArg == "-culldistance"
4849 || anArg == "-culldist"
4850 || anArg == "-distcull"
4851 || anArg == "-distculling"
4852 || anArg == "-distanceculling"))
4854 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4855 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
4856 aSettings.SetCullingDistance (aDist);
4857 aViewer->SetZLayerSettings (aLayerId, aSettings);
4859 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4860 && anArgIter + 1 < theArgNb
4861 && (anArg == "-cullingsize"
4862 || anArg == "-cullsize"
4863 || anArg == "-sizecull"
4864 || anArg == "-sizeculling"))
4866 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4867 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
4868 aSettings.SetCullingSize (aSize);
4869 aViewer->SetZLayerSettings (aLayerId, aSettings);
4871 else if (anArg == "-settings"
4872 || anArg == "settings")
4874 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4876 if (++anArgIter >= theArgNb)
4878 Message::SendFail ("Syntax error: id of Z layer is missing");
4882 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4885 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4886 printZLayerInfo (theDI, aSettings);
4888 else if (anArg == "-enable"
4889 || anArg == "enable"
4890 || anArg == "-disable"
4891 || anArg == "disable")
4893 const Standard_Boolean toEnable = anArg == "-enable"
4894 || anArg == "enable";
4895 if (++anArgIter >= theArgNb)
4897 Message::SendFail ("Syntax error: option name is missing");
4901 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
4903 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4905 if (++anArgIter >= theArgNb)
4907 Message::SendFail ("Syntax error: id of Z layer is missing");
4911 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4914 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4915 if (aSubOp == "depthtest"
4916 || aSubOp == "test")
4918 aSettings.SetEnableDepthTest (toEnable);
4920 else if (aSubOp == "depthwrite"
4921 || aSubOp == "write")
4923 aSettings.SetEnableDepthWrite (toEnable);
4925 else if (aSubOp == "depthclear"
4926 || aSubOp == "clear")
4928 aSettings.SetClearDepth (toEnable);
4930 else if (aSubOp == "depthoffset"
4931 || aSubOp == "offset")
4933 Graphic3d_PolygonOffset aParams;
4934 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
4937 if (anArgIter + 2 >= theArgNb)
4939 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
4943 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4944 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4946 aSettings.SetPolygonOffset (aParams);
4948 else if (aSubOp == "positiveoffset"
4949 || aSubOp == "poffset")
4953 aSettings.SetDepthOffsetPositive();
4957 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
4960 else if (aSubOp == "negativeoffset"
4961 || aSubOp == "noffset")
4965 aSettings.SetDepthOffsetNegative();
4969 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
4972 else if (aSubOp == "textureenv")
4974 aSettings.SetEnvironmentTexture (toEnable);
4976 else if (aSubOp == "raytracing")
4978 aSettings.SetRaytracable (toEnable);
4981 aViewer->SetZLayerSettings (aLayerId, aSettings);
4985 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
4993 // The interactive presentation of 2d layer item
4994 // for "vlayerline" command it provides a presentation of
4995 // line with user-defined linewidth, linetype and transparency.
4996 class V3d_LineItem : public AIS_InteractiveObject
5000 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
5003 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5004 Standard_Real X2, Standard_Real Y2,
5005 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5006 Standard_Real theWidth = 0.5,
5007 Standard_Real theTransp = 1.0);
5011 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5012 const Handle(Prs3d_Presentation)& thePrs,
5013 const Standard_Integer theMode) Standard_OVERRIDE;
5015 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5016 const Standard_Integer ) Standard_OVERRIDE
5021 Standard_Real myX1, myY1, myX2, myY2;
5022 Aspect_TypeOfLine myType;
5023 Standard_Real myWidth;
5026 // default constructor for line item
5027 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5028 Standard_Real X2, Standard_Real Y2,
5029 Aspect_TypeOfLine theType,
5030 Standard_Real theWidth,
5031 Standard_Real theTransp) :
5032 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5033 myType(theType), myWidth(theWidth)
5035 SetTransparency (1-theTransp);
5039 void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
5040 const Handle(Prs3d_Presentation)& thePresentation,
5041 const Standard_Integer )
5043 thePresentation->Clear();
5044 Quantity_Color aColor (Quantity_NOC_RED);
5045 Standard_Integer aWidth, aHeight;
5046 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
5047 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
5048 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5049 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5050 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5051 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5052 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5053 aGroup->AddPrimitiveArray (aPrim);
5056 //=============================================================================
5057 //function : VLayerLine
5058 //purpose : Draws line in the v3d view layer with given attributes: linetype,
5059 // : linewidth, transparency coefficient
5060 //============================================================================
5061 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5063 // get the active view
5064 Handle(V3d_View) aView = ViewerTest::CurrentView();
5067 di << "Call vinit before!\n";
5072 di << "Use: " << argv[0];
5073 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5074 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5075 di << " 0 - solid \n";
5076 di << " 1 - dashed \n";
5077 di << " 2 - dot \n";
5078 di << " 3 - dashdot\n";
5079 di << " transparency : { 0.0 - 1.0 } \n";
5080 di << " 0.0 - transparent\n";
5081 di << " 1.0 - visible \n";
5085 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5086 // get the input params
5087 Standard_Real X1 = Draw::Atof(argv[1]);
5088 Standard_Real Y1 = Draw::Atof(argv[2]);
5089 Standard_Real X2 = Draw::Atof(argv[3]);
5090 Standard_Real Y2 = Draw::Atof(argv[4]);
5092 Standard_Real aWidth = 0.5;
5093 Standard_Real aTransparency = 1.0;
5097 aWidth = Draw::Atof(argv[5]);
5099 // select appropriate line type
5100 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5102 && !ViewerTest::ParseLineType (argv[6], aLineType))
5104 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
5111 aTransparency = Draw::Atof(argv[7]);
5112 if (aTransparency < 0 || aTransparency > 1.0)
5113 aTransparency = 1.0;
5116 static Handle (V3d_LineItem) aLine;
5117 if (!aLine.IsNull())
5119 aContext->Erase (aLine, Standard_False);
5121 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5125 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
5126 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5127 aLine->SetToUpdate();
5128 aContext->Display (aLine, Standard_True);
5134 //==============================================================================
5137 //==============================================================================
5139 static int VGrid (Draw_Interpretor& /*theDI*/,
5140 Standard_Integer theArgNb,
5141 const char** theArgVec)
5143 Handle(V3d_View) aView = ViewerTest::CurrentView();
5144 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5145 if (aView.IsNull() || aViewer.IsNull())
5147 Message::SendFail ("Error: no active viewer");
5151 Aspect_GridType aType = aViewer->GridType();
5152 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
5153 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5154 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5155 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
5156 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
5157 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5159 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5161 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5165 else if (anArgIter + 1 < theArgNb
5166 && anArg == "-type")
5168 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5169 anArgNext.LowerCase();
5170 if (anArgNext == "r"
5171 || anArgNext == "rect"
5172 || anArgNext == "rectangular")
5174 aType = Aspect_GT_Rectangular;
5176 else if (anArgNext == "c"
5177 || anArgNext == "circ"
5178 || anArgNext == "circular")
5180 aType = Aspect_GT_Circular;
5184 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5188 else if (anArgIter + 1 < theArgNb
5189 && anArg == "-mode")
5191 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5192 anArgNext.LowerCase();
5193 if (anArgNext == "l"
5194 || anArgNext == "line"
5195 || anArgNext == "lines")
5197 aMode = Aspect_GDM_Lines;
5199 else if (anArgNext == "p"
5200 || anArgNext == "point"
5201 || anArgNext == "points")
5203 aMode = Aspect_GDM_Points;
5207 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5211 else if (anArgIter + 2 < theArgNb
5212 && (anArg == "-origin"
5213 || anArg == "-orig"))
5216 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5217 Draw::Atof (theArgVec[anArgIter + 2]));
5220 else if (anArgIter + 2 < theArgNb
5221 && anArg == "-step")
5224 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5225 Draw::Atof (theArgVec[anArgIter + 2]));
5226 if (aNewStepXY.x() <= 0.0
5227 || aNewStepXY.y() <= 0.0)
5229 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5234 else if (anArgIter + 1 < theArgNb
5235 && (anArg == "-angle"
5236 || anArg == "-rotangle"
5237 || anArg == "-rotationangle"))
5240 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5242 else if (anArgIter + 1 < theArgNb
5243 && (anArg == "-zoffset"
5247 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5249 else if (anArgIter + 1 < theArgNb
5250 && anArg == "-radius")
5254 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5255 if (aNewStepXY.x() <= 0.0)
5257 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
5261 else if (anArgIter + 2 < theArgNb
5262 && anArg == "-size")
5265 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5266 Draw::Atof (theArgVec[anArgIter + 2]));
5267 if (aNewStepXY.x() <= 0.0
5268 || aNewStepXY.y() <= 0.0)
5270 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5275 else if (anArg == "r"
5277 || anArg == "rectangular")
5279 aType = Aspect_GT_Rectangular;
5281 else if (anArg == "c"
5283 || anArg == "circular")
5285 aType = Aspect_GT_Circular;
5287 else if (anArg == "l"
5289 || anArg == "lines")
5291 aMode = Aspect_GDM_Lines;
5293 else if (anArg == "p"
5295 || anArg == "points")
5297 aMode = Aspect_GDM_Points;
5299 else if (anArgIter + 1 >= theArgNb
5302 aViewer->DeactivateGrid();
5307 Message::SendFail() << "Syntax error at '" << anArg << "'";
5312 if (aType == Aspect_GT_Rectangular)
5314 Graphic3d_Vec2d anOrigXY, aStepXY;
5315 Standard_Real aRotAngle = 0.0;
5316 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5319 anOrigXY = aNewOriginXY;
5323 aStepXY = aNewStepXY;
5327 aRotAngle = aNewRotAngle;
5329 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5330 if (hasSize || hasZOffset)
5332 Graphic3d_Vec3d aSize;
5333 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5336 aSize.x() = aNewSizeXY.x();
5337 aSize.y() = aNewSizeXY.y();
5341 aSize.z() = aNewZOffset;
5343 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5346 else if (aType == Aspect_GT_Circular)
5348 Graphic3d_Vec2d anOrigXY;
5349 Standard_Real aRadiusStep;
5350 Standard_Integer aDivisionNumber;
5351 Standard_Real aRotAngle = 0.0;
5352 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5355 anOrigXY = aNewOriginXY;
5359 aRadiusStep = aNewStepXY[0];
5360 aDivisionNumber = (int )aNewStepXY[1];
5361 if (aDivisionNumber < 1)
5363 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
5369 aRotAngle = aNewRotAngle;
5372 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5373 if (hasSize || hasZOffset)
5375 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5376 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5379 aRadius = aNewSizeXY.x();
5380 if (aNewSizeXY.y() != 0.0)
5382 Message::SendFail ("Syntax error: circular size should be specified as radius");
5388 aZOffset = aNewZOffset;
5390 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
5393 aViewer->ActivateGrid (aType, aMode);
5397 //==============================================================================
5398 //function : VPriviledgedPlane
5400 //==============================================================================
5402 static int VPriviledgedPlane (Draw_Interpretor& theDI,
5403 Standard_Integer theArgNb,
5404 const char** theArgVec)
5406 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
5408 Message::SendFail ("Error: wrong number of arguments! See usage:");
5409 theDI.PrintHelp (theArgVec[0]);
5413 // get the active viewer
5414 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5415 if (aViewer.IsNull())
5417 Message::SendFail ("Error: no active viewer");
5423 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
5424 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
5425 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
5426 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
5427 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
5428 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
5429 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
5433 Standard_Integer anArgIdx = 1;
5434 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
5435 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
5436 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
5437 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
5438 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
5439 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
5441 gp_Ax3 aPriviledgedPlane;
5442 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
5443 gp_Dir aNorm (aNormX, aNormY, aNormZ);
5446 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
5447 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
5448 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
5449 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
5450 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
5454 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
5457 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
5462 //==============================================================================
5463 //function : VConvert
5465 //==============================================================================
5467 static int VConvert (Draw_Interpretor& theDI,
5468 Standard_Integer theArgNb,
5469 const char** theArgVec)
5471 // get the active view
5472 Handle(V3d_View) aView = ViewerTest::CurrentView();
5475 Message::SendFail ("Error: no active viewer");
5479 enum { Model, Ray, View, Window, Grid } aMode = Model;
5481 // access coordinate arguments
5482 TColStd_SequenceOfReal aCoord;
5483 Standard_Integer anArgIdx = 1;
5484 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
5486 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5487 if (!anArg.IsRealValue (Standard_True))
5491 aCoord.Append (anArg.RealValue());
5494 // non-numeric argument too early
5495 if (aCoord.IsEmpty())
5497 Message::SendFail ("Error: wrong number of arguments! See usage:");
5498 theDI.PrintHelp (theArgVec[0]);
5502 // collect all other arguments and options
5503 for (; anArgIdx < theArgNb; ++anArgIdx)
5505 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5507 if (anArg == "window") aMode = Window;
5508 else if (anArg == "view") aMode = View;
5509 else if (anArg == "grid") aMode = Grid;
5510 else if (anArg == "ray") aMode = Ray;
5513 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
5514 theDI.PrintHelp (theArgVec[0]);
5519 // complete input checks
5520 if ((aCoord.Length() == 1 && theArgNb > 3) ||
5521 (aCoord.Length() == 2 && theArgNb > 4) ||
5522 (aCoord.Length() == 3 && theArgNb > 5))
5524 Message::SendFail ("Error: wrong number of arguments! See usage:");
5525 theDI.PrintHelp (theArgVec[0]);
5529 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
5530 Standard_Integer aXYp[2] = {0, 0};
5532 // convert one-dimensional coordinate
5533 if (aCoord.Length() == 1)
5537 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
5538 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
5540 Message::SendFail ("Error: wrong arguments! See usage:");
5541 theDI.PrintHelp (theArgVec[0]);
5546 // convert 2D coordinates from projection or view reference space
5547 if (aCoord.Length() == 2)
5552 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5553 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5557 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
5558 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
5562 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
5563 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5567 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5568 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
5569 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5573 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
5574 (Standard_Integer) aCoord (2),
5575 aXYZ[0], aXYZ[1], aXYZ[2],
5576 aXYZ[3], aXYZ[4], aXYZ[5]);
5577 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5581 Message::SendFail ("Error: wrong arguments! See usage:");
5582 theDI.PrintHelp (theArgVec[0]);
5587 // convert 3D coordinates from view reference space
5588 else if (aCoord.Length() == 3)
5593 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
5594 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5598 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
5599 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5603 Message::SendFail ("Error: wrong arguments! See usage:");
5604 theDI.PrintHelp (theArgVec[0]);
5612 //==============================================================================
5615 //==============================================================================
5617 static int VFps (Draw_Interpretor& theDI,
5618 Standard_Integer theArgNb,
5619 const char** theArgVec)
5621 // get the active view
5622 Handle(V3d_View) aView = ViewerTest::CurrentView();
5625 Message::SendFail ("Error: no active viewer");
5629 Standard_Integer aFramesNb = -1;
5630 Standard_Real aDuration = -1.0;
5631 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5633 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5636 && anArgIter + 1 < theArgNb
5637 && (anArg == "-duration"
5639 || anArg == "-time"))
5641 aDuration = Draw::Atof (theArgVec[++anArgIter]);
5643 else if (aFramesNb < 0
5644 && anArg.IsIntegerValue())
5646 aFramesNb = anArg.IntegerValue();
5649 Message::SendFail() << "Syntax error at '" << anArg << "'";
5655 Message::SendFail() << "Syntax error at '" << anArg << "'";
5659 if (aFramesNb < 0 && aDuration < 0.0)
5664 // the time is meaningless for first call
5665 // due to async OpenGl rendering
5668 // redraw view in loop to estimate average values
5671 Standard_Integer aFrameIter = 1;
5672 for (;; ++aFrameIter)
5676 && aFrameIter >= aFramesNb)
5678 && aTimer.ElapsedTime() >= aDuration))
5685 const Standard_Real aTime = aTimer.ElapsedTime();
5686 aTimer.OSD_Chronometer::Show (aCpu);
5688 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
5689 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
5691 // return statistics
5692 theDI << "FPS: " << aFpsAver << "\n"
5693 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
5695 // compute additional statistics in ray-tracing mode
5696 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
5697 if (aParams.Method == Graphic3d_RM_RAYTRACING)
5699 Graphic3d_Vec2i aWinSize (0, 0);
5700 aView->Window()->Size (aWinSize.x(), aWinSize.y());
5702 // 1 shadow ray and 1 secondary ray pew each bounce
5703 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
5704 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
5711 //==============================================================================
5712 //function : VMemGpu
5714 //==============================================================================
5716 static int VMemGpu (Draw_Interpretor& theDI,
5717 Standard_Integer theArgNb,
5718 const char** theArgVec)
5721 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5722 if (aContextAIS.IsNull())
5724 Message::SendFail ("Error: no active viewer");
5728 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
5729 if (aDriver.IsNull())
5731 Message::SendFail ("Error: graphic driver not available");
5735 Standard_Size aFreeBytes = 0;
5736 TCollection_AsciiString anInfo;
5737 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
5739 Message::SendFail ("Error: information not available");
5743 if (theArgNb > 1 && *theArgVec[1] == 'f')
5745 theDI << Standard_Real (aFreeBytes);
5755 // ==============================================================================
5756 // function : VReadPixel
5758 // ==============================================================================
5759 static int VReadPixel (Draw_Interpretor& theDI,
5760 Standard_Integer theArgNb,
5761 const char** theArgVec)
5763 // get the active view
5764 Handle(V3d_View) aView = ViewerTest::CurrentView();
5767 Message::SendFail ("Error: no active viewer");
5770 else if (theArgNb < 3)
5772 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
5773 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
5777 Image_Format aFormat = Image_Format_RGBA;
5778 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
5780 Standard_Integer aWidth, aHeight;
5781 aView->Window()->Size (aWidth, aHeight);
5782 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
5783 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
5784 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
5786 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
5790 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
5791 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
5793 TCollection_AsciiString aParam (theArgVec[anIter]);
5795 if (aParam == "-rgb"
5797 || aParam == "-srgb"
5798 || aParam == "srgb")
5800 aFormat = Image_Format_RGB;
5801 aBufferType = Graphic3d_BT_RGB;
5802 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
5804 else if (aParam == "-hls"
5807 aFormat = Image_Format_RGB;
5808 aBufferType = Graphic3d_BT_RGB;
5809 toShowHls = Standard_True;
5811 else if (aParam == "-rgbf"
5812 || aParam == "rgbf")
5814 aFormat = Image_Format_RGBF;
5815 aBufferType = Graphic3d_BT_RGB;
5817 else if (aParam == "-rgba"
5819 || aParam == "-srgba"
5820 || aParam == "srgba")
5822 aFormat = Image_Format_RGBA;
5823 aBufferType = Graphic3d_BT_RGBA;
5824 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
5826 else if (aParam == "-rgbaf"
5827 || aParam == "rgbaf")
5829 aFormat = Image_Format_RGBAF;
5830 aBufferType = Graphic3d_BT_RGBA;
5832 else if (aParam == "-depth"
5833 || aParam == "depth")
5835 aFormat = Image_Format_GrayF;
5836 aBufferType = Graphic3d_BT_Depth;
5838 else if (aParam == "-name"
5839 || aParam == "name")
5841 toShowName = Standard_True;
5843 else if (aParam == "-hex"
5846 toShowHex = Standard_True;
5850 Message::SendFail() << "Syntax error at '" << aParam << "'";
5855 Image_PixMap anImage;
5856 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
5858 Message::SendFail ("Error: image allocation failed");
5861 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
5863 Message::SendFail ("Error: image dump failed");
5867 // redirect possible warning messages that could have been added by ToPixMap
5868 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
5869 // contaminate result of the command
5870 Standard_CString aWarnLog = theDI.Result();
5871 if (aWarnLog != NULL && aWarnLog[0] != '\0')
5873 std::cout << aWarnLog << std::endl;
5877 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
5880 if (aBufferType == Graphic3d_BT_RGBA)
5882 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
5886 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
5891 if (aBufferType == Graphic3d_BT_RGBA)
5893 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
5897 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
5902 switch (aBufferType)
5905 case Graphic3d_BT_RGB:
5909 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
5911 else if (toShow_sRGB)
5913 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
5914 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
5918 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
5922 case Graphic3d_BT_RGBA:
5924 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
5925 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
5928 case Graphic3d_BT_Depth:
5930 theDI << aColor.GetRGB().Red();
5939 //! Auxiliary presentation for an image plane.
5940 class ViewerTest_ImagePrs : public AIS_InteractiveObject
5943 //! Main constructor.
5944 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
5945 const Standard_Real theWidth,
5946 const Standard_Real theHeight,
5947 const TCollection_AsciiString& theLabel)
5948 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
5952 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
5954 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
5955 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
5956 Graphic3d_MaterialAspect aMat;
5957 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
5958 aMat.SetAmbientColor (Quantity_NOC_BLACK);
5959 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
5960 aMat.SetSpecularColor (Quantity_NOC_BLACK);
5961 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
5962 aFillAspect->SetFrontMaterial (aMat);
5963 aFillAspect->SetTextureMap (new Graphic3d_Texture2D (theImage));
5964 aFillAspect->SetTextureMapOn();
5967 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
5968 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
5969 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
5970 myDrawer->SetTextAspect (aTextAspect);
5973 const gp_Dir aNorm (0.0, 0.0, 1.0);
5974 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
5975 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
5976 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
5977 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
5978 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
5979 myTris->AddEdge (1);
5980 myTris->AddEdge (2);
5981 myTris->AddEdge (3);
5982 myTris->AddEdge (3);
5983 myTris->AddEdge (2);
5984 myTris->AddEdge (4);
5986 myRect = new Graphic3d_ArrayOfPolylines (4);
5987 myRect->AddVertex (myTris->Vertice (1));
5988 myRect->AddVertex (myTris->Vertice (3));
5989 myRect->AddVertex (myTris->Vertice (4));
5990 myRect->AddVertex (myTris->Vertice (2));
5994 //! Returns TRUE for accepted display modes.
5995 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
5997 //! Compute presentation.
5998 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
5999 const Handle(Prs3d_Presentation)& thePrs,
6000 const Standard_Integer theMode) Standard_OVERRIDE
6006 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6007 aGroup->AddPrimitiveArray (myTris);
6008 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6009 aGroup->AddPrimitiveArray (myRect);
6010 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6015 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6016 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6017 aGroup->AddPrimitiveArray (myRect);
6018 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6024 //! Compute selection.
6025 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6029 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6030 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6031 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6032 theSel->Add (aSensitive);
6037 Handle(Graphic3d_ArrayOfTriangles) myTris;
6038 Handle(Graphic3d_ArrayOfPolylines) myRect;
6039 TCollection_AsciiString myLabel;
6040 Standard_Real myWidth;
6041 Standard_Real myHeight;
6044 //==============================================================================
6045 //function : VDiffImage
6046 //purpose : The draw-command compares two images.
6047 //==============================================================================
6049 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6053 Message::SendFail ("Syntax error: not enough arguments");
6057 Standard_Integer anArgIter = 1;
6058 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
6059 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
6060 TCollection_AsciiString aDiffImagePath;
6061 Standard_Real aTolColor = -1.0;
6062 Standard_Integer toBlackWhite = -1;
6063 Standard_Integer isBorderFilterOn = -1;
6064 Standard_Boolean isOldSyntax = Standard_False;
6065 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
6066 for (; anArgIter < theArgNb; ++anArgIter)
6068 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6070 if (anArgIter + 1 < theArgNb
6071 && (anArg == "-toleranceofcolor"
6072 || anArg == "-tolerancecolor"
6073 || anArg == "-tolerance"
6074 || anArg == "-toler"))
6076 aTolColor = Atof (theArgVec[++anArgIter]);
6077 if (aTolColor < 0.0 || aTolColor > 1.0)
6079 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6083 else if (anArg == "-blackwhite")
6085 Standard_Boolean toEnable = Standard_True;
6086 if (anArgIter + 1 < theArgNb
6087 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6091 toBlackWhite = toEnable ? 1 : 0;
6093 else if (anArg == "-borderfilter")
6095 Standard_Boolean toEnable = Standard_True;
6096 if (anArgIter + 1 < theArgNb
6097 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6101 isBorderFilterOn = toEnable ? 1 : 0;
6103 else if (anArg == "-exitonclose")
6105 ViewerTest_EventManager::ToExitOnCloseView() = true;
6106 if (anArgIter + 1 < theArgNb
6107 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
6112 else if (anArg == "-closeonescape"
6113 || anArg == "-closeonesc")
6115 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
6116 if (anArgIter + 1 < theArgNb
6117 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
6122 else if (anArgIter + 3 < theArgNb
6123 && anArg == "-display")
6125 aViewName = theArgVec[++anArgIter];
6126 aPrsNameRef = theArgVec[++anArgIter];
6127 aPrsNameNew = theArgVec[++anArgIter];
6128 if (anArgIter + 1 < theArgNb
6129 && *theArgVec[anArgIter + 1] != '-')
6131 aPrsNameDiff = theArgVec[++anArgIter];
6134 else if (aTolColor < 0.0
6135 && anArg.IsRealValue (Standard_True))
6137 isOldSyntax = Standard_True;
6138 aTolColor = anArg.RealValue();
6139 if (aTolColor < 0.0 || aTolColor > 1.0)
6141 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6145 else if (isOldSyntax
6146 && toBlackWhite == -1
6147 && (anArg == "0" || anArg == "1"))
6149 toBlackWhite = anArg == "1" ? 1 : 0;
6151 else if (isOldSyntax
6152 && isBorderFilterOn == -1
6153 && (anArg == "0" || anArg == "1"))
6155 isBorderFilterOn = anArg == "1" ? 1 : 0;
6157 else if (aDiffImagePath.IsEmpty())
6159 aDiffImagePath = theArgVec[anArgIter];
6163 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6168 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6169 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6170 if (!anImgRef->Load (anImgPathRef))
6172 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
6175 if (!anImgNew->Load (anImgPathNew))
6177 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
6181 // compare the images
6182 Image_Diff aComparer;
6183 Standard_Integer aDiffColorsNb = -1;
6184 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
6186 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6187 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6188 aDiffColorsNb = aComparer.Compare();
6189 theDI << aDiffColorsNb << "\n";
6192 // save image of difference
6193 Handle(Image_AlienPixMap) aDiff;
6194 if (aDiffColorsNb > 0
6195 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6197 aDiff = new Image_AlienPixMap();
6198 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6200 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
6203 aComparer.SaveDiffImage (*aDiff);
6204 if (!aDiffImagePath.IsEmpty()
6205 && !aDiff->Save (aDiffImagePath))
6207 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
6212 if (aViewName.IsEmpty())
6217 ViewerTest_Names aViewNames (aViewName);
6218 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6220 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6221 theDI.Eval (aCommand.ToCString());
6224 ViewerTest_VinitParams aParams;
6225 aParams.ViewName = aViewName;
6226 aParams.Size.x() = float(anImgRef->SizeX() * 2);
6227 aParams.Size.y() = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6228 ? float(anImgRef->SizeY() * 2)
6229 : float(anImgRef->SizeY());
6230 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
6232 Standard_Real aRatio = anImgRef->Ratio();
6233 Standard_Real aSizeX = 1.0;
6234 Standard_Real aSizeY = aSizeX / aRatio;
6236 OSD_Path aPath (anImgPathRef);
6237 TCollection_AsciiString aLabelRef;
6238 if (!aPath.Name().IsEmpty())
6240 aLabelRef = aPath.Name() + aPath.Extension();
6242 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6244 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6246 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6247 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6248 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
6251 OSD_Path aPath (anImgPathNew);
6252 TCollection_AsciiString aLabelNew;
6253 if (!aPath.Name().IsEmpty())
6255 aLabelNew = aPath.Name() + aPath.Extension();
6257 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
6259 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6261 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6262 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6263 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6265 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6266 if (!aDiff.IsNull())
6268 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6270 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6271 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6273 if (!aPrsNameDiff.IsEmpty())
6275 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6277 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6278 ViewerTest::CurrentView()->FitAll();
6282 //=======================================================================
6283 //function : VSelect
6284 //purpose : Emulates different types of selection by mouse:
6285 // 1) single click selection
6286 // 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6287 // 3) selection with polygon having corners at
6288 // pixel positions (x1,y1),...,(xn,yn)
6289 // 4) any of these selections with shift button pressed
6290 //=======================================================================
6291 static Standard_Integer VSelect (Draw_Interpretor& ,
6292 Standard_Integer theNbArgs,
6293 const char** theArgVec)
6295 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6298 Message::SendFail ("Error: no active viewer");
6302 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
6303 bool toAllowOverlap = false;
6304 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
6305 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6307 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6309 if (anArg == "-allowoverlap")
6311 toAllowOverlap = true;
6312 if (anArgIter + 1 < theNbArgs
6313 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
6318 else if (anArg == "-replace")
6320 aSelScheme = AIS_SelectionScheme_Replace;
6322 else if (anArg == "-replaceextra")
6324 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6326 else if (anArg == "-xor"
6327 || anArg == "-shift")
6329 aSelScheme = AIS_SelectionScheme_XOR;
6331 else if (anArg == "-add")
6333 aSelScheme = AIS_SelectionScheme_Add;
6335 else if (anArg == "-remove")
6337 aSelScheme = AIS_SelectionScheme_Remove;
6339 else if (anArgIter + 1 < theNbArgs
6340 && anArg.IsIntegerValue()
6341 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
6343 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6344 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6346 else if (anArgIter + 1 == theNbArgs
6347 && anArg.IsIntegerValue())
6349 if (anArg.IntegerValue() == 1)
6351 aSelScheme = AIS_SelectionScheme_XOR;
6356 Message::SendFail() << "Syntax error at '" << anArg << "'";
6363 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
6366 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
6367 if (aPnts.IsEmpty())
6369 aCtx->SelectDetected (aSelScheme);
6370 aCtx->CurrentViewer()->Invalidate();
6372 else if (aPnts.Length() == 2)
6375 && aPnts.First().y() < aPnts.Last().y())
6377 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6379 else if (!toAllowOverlap
6380 && aPnts.First().y() > aPnts.Last().y())
6382 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6385 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6389 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6391 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
6395 //=======================================================================
6396 //function : VMoveTo
6397 //purpose : Emulates cursor movement to defined pixel position
6398 //=======================================================================
6399 static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
6400 Standard_Integer theNbArgs,
6401 const char** theArgVec)
6403 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6404 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6405 if (aContext.IsNull())
6407 Message::SendFail ("Error: no active viewer");
6411 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
6412 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6414 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6415 anArgStr.LowerCase();
6416 if (anArgStr == "-reset"
6417 || anArgStr == "-clear")
6419 if (anArgIter + 1 < theNbArgs)
6421 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
6425 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
6426 && aContext->CurrentViewer()->GridEcho();
6429 aContext->CurrentViewer()->HideGridEcho (aView);
6431 if (aContext->ClearDetected() || toEchoGrid)
6433 aContext->CurrentViewer()->RedrawImmediate();
6437 else if (aMousePos.x() == IntegerLast()
6438 && anArgStr.IsIntegerValue())
6440 aMousePos.x() = anArgStr.IntegerValue();
6442 else if (aMousePos.y() == IntegerLast()
6443 && anArgStr.IsIntegerValue())
6445 aMousePos.y() = anArgStr.IntegerValue();
6449 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6454 if (aMousePos.x() == IntegerLast()
6455 || aMousePos.y() == IntegerLast())
6457 Message::SendFail ("Syntax error: wrong number of arguments");
6461 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
6462 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
6463 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
6465 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
6466 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
6467 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
6469 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
6471 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
6475 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
6479 //=======================================================================
6480 //function : VSelectByAxis
6482 //=======================================================================
6483 static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
6484 Standard_Integer theNbArgs,
6485 const char** theArgVec)
6487 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6488 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6489 if (aContext.IsNull())
6491 Message::SendFail ("Error: no active viewer");
6495 TCollection_AsciiString aName;
6496 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
6497 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
6498 Standard_Boolean isOnlyTop = true;
6499 Standard_Boolean toShowNormal = false;
6500 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6502 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6503 anArgStr.LowerCase();
6504 if (anArgStr == "-display")
6506 if (anArgIter + 1 >= theNbArgs)
6508 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
6511 aName = theArgVec[++anArgIter];
6513 else if (anArgStr == "-onlytop")
6516 if (anArgIter + 1 < theNbArgs
6517 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
6522 else if (anArgStr == "-shownormal")
6524 toShowNormal = true;
6525 if (anArgIter + 1 < theNbArgs
6526 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
6531 else if (Precision::IsInfinite(anAxisLocation.X())
6532 && anArgStr.IsRealValue())
6534 anAxisLocation.SetX (anArgStr.RealValue());
6536 else if (Precision::IsInfinite(anAxisLocation.Y())
6537 && anArgStr.IsRealValue())
6539 anAxisLocation.SetY (anArgStr.RealValue());
6541 else if (Precision::IsInfinite(anAxisLocation.Z())
6542 && anArgStr.IsRealValue())
6544 anAxisLocation.SetZ (anArgStr.RealValue());
6546 else if (Precision::IsInfinite(anAxisDirection.X())
6547 && anArgStr.IsRealValue())
6549 anAxisDirection.SetX (anArgStr.RealValue());
6551 else if (Precision::IsInfinite(anAxisDirection.Y())
6552 && anArgStr.IsRealValue())
6554 anAxisDirection.SetY (anArgStr.RealValue());
6556 else if (Precision::IsInfinite(anAxisDirection.Z())
6557 && anArgStr.IsRealValue())
6559 anAxisDirection.SetZ (anArgStr.RealValue());
6563 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6568 if (Precision::IsInfinite (anAxisLocation.X()) ||
6569 Precision::IsInfinite (anAxisLocation.Y()) ||
6570 Precision::IsInfinite (anAxisLocation.Z()) ||
6571 Precision::IsInfinite (anAxisDirection.X()) ||
6572 Precision::IsInfinite (anAxisDirection.Y()) ||
6573 Precision::IsInfinite (anAxisDirection.Z()))
6575 Message::SendFail() << "Invalid axis location and direction";
6579 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
6581 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
6583 theDI << "There are no any intersections with this axis.";
6586 NCollection_Sequence<gp_Pnt> aPoints;
6587 NCollection_Sequence<Graphic3d_Vec3> aNormals;
6588 NCollection_Sequence<Standard_Real> aNormalLengths;
6589 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
6591 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
6592 aPoints.Append (aPickedData.Point);
6593 aNormals.Append (aPickedData.Normal);
6594 Standard_Real aNormalLength = 1.0;
6595 if (!aPickedData.Entity.IsNull())
6597 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
6599 aNormalLengths.Append (aNormalLength);
6601 if (!aName.IsEmpty())
6603 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
6604 aContext->SetAutoActivateSelection (false);
6607 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
6608 Handle(Geom_Axis2Placement) anAx2Axis =
6609 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
6610 Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
6611 anAISAxis->SetColor (anAxisColor);
6612 ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
6614 // Display axis start point
6615 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
6616 anAISStartPnt->SetMarker (Aspect_TOM_O);
6617 anAISStartPnt->SetColor (anAxisColor);
6618 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
6620 Standard_Integer anIndex = 0;
6621 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
6623 const gp_Pnt& aPoint = aPntIter.Value();
6625 // Display normals in intersection points
6628 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
6629 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
6630 if (aNormal.SquareModulus() > ShortRealEpsilon())
6632 gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
6633 Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
6634 anAISNormal->SetColor (Quantity_NOC_BLUE);
6635 anAISNormal->SetInfiniteState (false);
6636 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
6640 // Display intersection points
6641 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
6642 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
6643 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
6644 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
6645 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
6648 aContext->SetAutoActivateSelection (wasAuto);
6651 Standard_Integer anIndex = 0;
6652 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
6654 const gp_Pnt& aPnt = anIter.Value();
6655 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
6662 //! Global map storing all animations registered in ViewerTest.
6663 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
6665 //! The animation calling the Draw Harness command.
6666 class ViewerTest_AnimationProc : public AIS_Animation
6668 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
6671 //! Main constructor.
6672 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
6673 Draw_Interpretor* theDI,
6674 const TCollection_AsciiString& theCommand)
6675 : AIS_Animation (theAnimationName),
6677 myCommand (theCommand)
6684 //! Evaluate the command.
6685 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
6687 TCollection_AsciiString aCmd = myCommand;
6688 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
6689 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
6690 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
6691 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
6692 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
6693 myDrawInter->Eval (aCmd.ToCString());
6696 //! Find the keyword in the command and replace it with value.
6697 //! @return the position of the keyword to pass value
6698 void replace (TCollection_AsciiString& theCmd,
6699 const TCollection_AsciiString& theKey,
6700 const TCollection_AsciiString& theVal)
6702 TCollection_AsciiString aCmd (theCmd);
6704 const Standard_Integer aPos = aCmd.Search (theKey);
6710 TCollection_AsciiString aPart1, aPart2;
6711 Standard_Integer aPart1To = aPos - 1;
6713 && aPart1To <= theCmd.Length())
6715 aPart1 = theCmd.SubString (1, aPart1To);
6718 Standard_Integer aPart2From = aPos + theKey.Length();
6720 && aPart2From <= theCmd.Length())
6722 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
6725 theCmd = aPart1 + theVal + aPart2;
6730 Draw_Interpretor* myDrawInter;
6731 TCollection_AsciiString myCommand;
6735 //! Auxiliary animation holder.
6736 class ViewerTest_AnimationHolder : public AIS_AnimationCamera
6738 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
6740 ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
6741 const Handle(V3d_View)& theView,
6742 const Standard_Boolean theIsFreeView)
6743 : AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
6745 if (theAnim->Timer().IsNull())
6747 theAnim->SetTimer (new Media_Timer());
6749 myTimer = theAnim->Timer();
6753 myCamStart = new Graphic3d_Camera (theView->Camera());
6759 virtual void StartTimer (const Standard_Real theStartPts,
6760 const Standard_Real thePlaySpeed,
6761 const Standard_Boolean theToUpdate,
6762 const Standard_Boolean theToStopTimer) Standard_OVERRIDE
6764 base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
6771 //! Pause animation.
6772 virtual void Pause() Standard_OVERRIDE
6774 myState = AnimationState_Paused;
6775 // default implementation would stop all children,
6776 // but we want to keep wrapped animation paused
6777 myAnimations.First()->Pause();
6782 virtual void Stop() Standard_OVERRIDE
6788 //! Process one step of the animation according to the input time progress, including all children.
6789 virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
6791 Handle(V3d_View) aView = myView;
6793 && !myCamStart.IsNull())
6795 myCamStart->Copy (aView->Camera());
6797 base_type::updateWithChildren (thePosition);
6799 && !myCamStart.IsNull())
6801 aView->Camera()->Copy (myCamStart);
6805 void abortPlayback()
6807 if (!myView.IsNull())
6814 //! Replace the animation with the new one.
6815 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
6816 Handle(AIS_Animation)& theAnimation,
6817 const Handle(AIS_Animation)& theAnimationNew)
6819 theAnimationNew->CopyFrom (theAnimation);
6820 if (!theParentAnimation.IsNull())
6822 theParentAnimation->Replace (theAnimation, theAnimationNew);
6826 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
6827 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
6829 theAnimation = theAnimationNew;
6832 //! Parse the point.
6833 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
6835 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
6836 if (!anXYZ[0].IsRealValue (Standard_True)
6837 || !anXYZ[1].IsRealValue (Standard_True)
6838 || !anXYZ[2].IsRealValue (Standard_True))
6840 return Standard_False;
6843 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
6844 return Standard_True;
6847 //! Parse the quaternion.
6848 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
6850 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
6851 if (!anXYZW[0].IsRealValue (Standard_True)
6852 || !anXYZW[1].IsRealValue (Standard_True)
6853 || !anXYZW[2].IsRealValue (Standard_True)
6854 || !anXYZW[3].IsRealValue (Standard_True))
6856 return Standard_False;
6859 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
6860 return Standard_True;
6863 //! Auxiliary class for flipping image upside-down.
6868 //! Empty constructor.
6869 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
6871 //! Perform flipping.
6872 Standard_Boolean FlipY (Image_PixMap& theImage)
6874 if (theImage.IsEmpty()
6875 || theImage.SizeX() == 0
6876 || theImage.SizeY() == 0)
6878 return Standard_False;
6881 const Standard_Size aRowSize = theImage.SizeRowBytes();
6882 if (myTmp.Size() < aRowSize
6883 && !myTmp.Allocate (aRowSize))
6885 return Standard_False;
6888 // for odd height middle row should be left as is
6889 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
6890 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
6892 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
6893 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
6894 memcpy (myTmp.ChangeData(), aTop, aRowSize);
6895 memcpy (aTop, aBot, aRowSize);
6896 memcpy (aBot, myTmp.Data(), aRowSize);
6898 return Standard_True;
6902 NCollection_Buffer myTmp;
6907 //=================================================================================================
6908 //function : VViewParams
6909 //purpose : Gets or sets AIS View characteristics
6910 //=================================================================================================
6911 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6913 Handle(V3d_View) aView = ViewerTest::CurrentView();
6916 Message::SendFail ("Error: no active viewer");
6920 Standard_Boolean toSetProj = Standard_False;
6921 Standard_Boolean toSetUp = Standard_False;
6922 Standard_Boolean toSetAt = Standard_False;
6923 Standard_Boolean toSetEye = Standard_False;
6924 Standard_Boolean toSetScale = Standard_False;
6925 Standard_Boolean toSetSize = Standard_False;
6926 Standard_Boolean toSetCenter2d = Standard_False;
6927 Standard_Real aViewScale = aView->Scale();
6928 Standard_Real aViewAspect = aView->Camera()->Aspect();
6929 Standard_Real aViewSize = 1.0;
6930 Graphic3d_Vec2i aCenter2d;
6931 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
6932 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
6933 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
6934 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
6935 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
6936 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
6937 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
6940 // print all of the available view parameters
6945 "Proj: %12g %12g %12g\n"
6946 "Up: %12g %12g %12g\n"
6947 "At: %12g %12g %12g\n"
6948 "Eye: %12g %12g %12g\n"
6949 "OrientMat: %12g %12g %12g %12g\n"
6950 " %12g %12g %12g %12g\n"
6951 " %12g %12g %12g %12g\n"
6952 " %12g %12g %12g %12g\n"
6953 "ProjMat: %12g %12g %12g %12g\n"
6954 " %12g %12g %12g %12g\n"
6955 " %12g %12g %12g %12g\n"
6956 " %12g %12g %12g %12g\n",
6957 aViewScale, aViewAspect,
6958 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6959 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6960 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
6961 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
6962 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
6963 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
6964 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
6965 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
6966 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
6967 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
6968 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
6969 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
6974 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
6975 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6977 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6979 if (anUpdateTool.parseRedrawMode (anArg))
6983 else if (anArg == "-cmd"
6984 || anArg == "-command"
6985 || anArg == "-args")
6994 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6995 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6996 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
6999 else if (anArg == "-scale"
7000 || anArg == "-size")
7002 if (anArgIter + 1 < theArgsNb
7003 && *theArgVec[anArgIter + 1] != '-')
7005 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
7006 if (aValueArg.IsRealValue (Standard_True))
7009 if (anArg == "-scale")
7011 toSetScale = Standard_True;
7012 aViewScale = aValueArg.RealValue();
7014 else if (anArg == "-size")
7016 toSetSize = Standard_True;
7017 aViewSize = aValueArg.RealValue();
7022 if (anArg == "-scale")
7024 theDi << "Scale: " << aView->Scale() << "\n";
7026 else if (anArg == "-size")
7028 Graphic3d_Vec2d aSizeXY;
7029 aView->Size (aSizeXY.x(), aSizeXY.y());
7030 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7033 else if (anArg == "-eye"
7036 || anArg == "-proj")
7038 if (anArgIter + 3 < theArgsNb)
7041 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7044 if (anArg == "-eye")
7046 toSetEye = Standard_True;
7049 else if (anArg == "-at")
7051 toSetAt = Standard_True;
7054 else if (anArg == "-up")
7056 toSetUp = Standard_True;
7059 else if (anArg == "-proj")
7061 toSetProj = Standard_True;
7068 if (anArg == "-eye")
7070 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7072 else if (anArg == "-at")
7074 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7076 else if (anArg == "-up")
7078 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7080 else if (anArg == "-proj")
7082 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7085 else if (anArg == "-center")
7087 if (anArgIter + 2 < theArgsNb)
7089 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7090 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7091 if (anX.IsIntegerValue()
7092 && anY.IsIntegerValue())
7094 toSetCenter2d = Standard_True;
7095 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7101 Message::SendFail() << "Syntax error at '" << anArg << "'";
7106 // change view parameters in proper order
7109 aView->SetScale (aViewScale);
7113 aView->SetSize (aViewSize);
7117 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7121 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7125 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7129 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7133 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
7139 //==============================================================================
7140 //function : V2DMode
7142 //==============================================================================
7143 static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7145 bool is2dMode = true;
7146 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7147 if (aV3dView.IsNull())
7149 Message::SendFail ("Error: no active viewer");
7152 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7154 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7155 TCollection_AsciiString anArgCase = anArg;
7156 anArgCase.LowerCase();
7157 if (anArgIt + 1 < theArgsNb
7158 && anArgCase == "-name")
7160 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7161 TCollection_AsciiString aViewName = aViewNames.GetViewName();
7162 if (!ViewerTest_myViews.IsBound1 (aViewName))
7164 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
7167 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7169 else if (anArgCase == "-mode")
7171 if (anArgIt + 1 < theArgsNb
7172 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
7177 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
7183 Message::SendFail() << "Syntax error: unknown argument " << anArg;
7188 aV3dView->SetView2DMode (is2dMode);
7192 //==============================================================================
7193 //function : VAnimation
7195 //==============================================================================
7196 static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7197 Standard_Integer theArgNb,
7198 const char** theArgVec)
7200 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7203 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7204 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7206 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
7212 Message::SendFail ("Error: no active viewer");
7216 Standard_Integer anArgIter = 1;
7217 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7218 if (aNameArg.IsEmpty())
7220 Message::SendFail ("Syntax error: animation name is not defined");
7224 TCollection_AsciiString aNameArgLower = aNameArg;
7225 aNameArgLower.LowerCase();
7226 if (aNameArgLower == "-reset"
7227 || aNameArgLower == "-clear")
7229 ViewerTest_AnimationTimelineMap.Clear();
7232 else if (aNameArg.Value (1) == '-')
7234 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
7238 const char* aNameSplitter = "/";
7239 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7240 if (aSplitPos == -1)
7242 aNameSplitter = ".";
7243 aSplitPos = aNameArg.Search (aNameSplitter);
7246 // find existing or create a new animation by specified name within syntax "parent.child".
7247 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7248 for (; !aNameArg.IsEmpty();)
7250 TCollection_AsciiString aNameParent;
7251 if (aSplitPos != -1)
7253 if (aSplitPos == aNameArg.Length())
7255 Message::SendFail ("Syntax error: animation name is not defined");
7259 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7260 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7262 aSplitPos = aNameArg.Search (aNameSplitter);
7266 aNameParent = aNameArg;
7270 if (anAnimation.IsNull())
7272 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7274 anAnimation = new AIS_Animation (aNameParent);
7275 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7277 aRootAnimation = anAnimation;
7281 aParentAnimation = anAnimation;
7282 anAnimation = aParentAnimation->Find (aNameParent);
7283 if (anAnimation.IsNull())
7285 anAnimation = new AIS_Animation (aNameParent);
7286 aParentAnimation->Add (anAnimation);
7290 if (anAnimation.IsNull())
7292 Message::SendFail() << "Syntax error: wrong number of arguments";
7296 if (anArgIter >= theArgNb)
7298 // just print the list of children
7299 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
7301 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
7306 // animation parameters
7307 Standard_Boolean toPlay = Standard_False;
7308 Standard_Real aPlaySpeed = 1.0;
7309 Standard_Real aPlayStartTime = anAnimation->StartPts();
7310 Standard_Real aPlayDuration = anAnimation->Duration();
7311 Standard_Boolean isFreeCamera = Standard_False;
7312 Standard_Boolean toPauseOnClick = Standard_True;
7313 Standard_Boolean isLockLoop = Standard_False;
7315 // video recording parameters
7316 TCollection_AsciiString aRecFile;
7317 Image_VideoParams aRecParams;
7319 Handle(V3d_View) aView = ViewerTest::CurrentView();
7320 for (; anArgIter < theArgNb; ++anArgIter)
7322 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7325 if (anArg == "-reset"
7326 || anArg == "-clear")
7328 anAnimation->Clear();
7330 else if (anArg == "-remove"
7332 || anArg == "-delete")
7334 if (aParentAnimation.IsNull())
7336 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7340 aParentAnimation->Remove (anAnimation);
7344 else if (anArg == "-play")
7346 toPlay = Standard_True;
7347 if (++anArgIter < theArgNb)
7349 if (*theArgVec[anArgIter] == '-')
7354 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7356 if (++anArgIter < theArgNb)
7358 if (*theArgVec[anArgIter] == '-')
7363 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7367 else if (anArg == "-resume")
7369 toPlay = Standard_True;
7370 aPlayStartTime = anAnimation->ElapsedTime();
7371 if (++anArgIter < theArgNb)
7373 if (*theArgVec[anArgIter] == '-')
7379 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7382 else if (anArg == "-pause")
7384 anAnimation->Pause();
7386 else if (anArg == "-stop")
7388 anAnimation->Stop();
7390 else if (anArg == "-playspeed"
7391 || anArg == "-speed")
7393 if (++anArgIter >= theArgNb)
7395 Message::SendFail() << "Syntax error at " << anArg << "";
7398 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7400 else if (anArg == "-lock"
7401 || anArg == "-lockloop"
7402 || anArg == "-playlockloop")
7404 isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
7406 else if (anArg == "-freecamera"
7407 || anArg == "-nofreecamera"
7408 || anArg == "-playfreecamera"
7409 || anArg == "-noplayfreecamera"
7410 || anArg == "-freelook"
7411 || anArg == "-nofreelook")
7413 isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7415 else if (anArg == "-pauseonclick"
7416 || anArg == "-nopauseonclick"
7417 || anArg == "-nopause")
7419 toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7421 // video recodring options
7422 else if (anArg == "-rec"
7423 || anArg == "-record")
7425 if (++anArgIter >= theArgNb)
7427 Message::SendFail() << "Syntax error at " << anArg;
7431 aRecFile = theArgVec[anArgIter];
7432 if (aRecParams.FpsNum <= 0)
7434 aRecParams.FpsNum = 24;
7437 if (anArgIter + 2 < theArgNb
7438 && *theArgVec[anArgIter + 1] != '-'
7439 && *theArgVec[anArgIter + 2] != '-')
7441 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7442 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7443 if (aWidthArg .IsIntegerValue()
7444 && aHeightArg.IsIntegerValue())
7446 aRecParams.Width = aWidthArg .IntegerValue();
7447 aRecParams.Height = aHeightArg.IntegerValue();
7452 else if (anArg == "-fps")
7454 if (++anArgIter >= theArgNb)
7456 Message::SendFail() << "Syntax error at " << anArg;
7460 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7461 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7462 if (aSplitIndex == 0)
7464 aRecParams.FpsNum = aFpsArg.IntegerValue();
7468 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7469 aFpsArg.Split (aFpsArg.Length() - 1);
7470 const TCollection_AsciiString aNumStr = aFpsArg;
7471 aRecParams.FpsNum = aNumStr.IntegerValue();
7472 aRecParams.FpsDen = aDenStr.IntegerValue();
7473 if (aRecParams.FpsDen < 1)
7475 Message::SendFail() << "Syntax error at " << anArg;
7480 else if (anArg == "-format")
7482 if (++anArgIter >= theArgNb)
7484 Message::SendFail() << "Syntax error at " << anArg;
7487 aRecParams.Format = theArgVec[anArgIter];
7489 else if (anArg == "-pix_fmt"
7490 || anArg == "-pixfmt"
7491 || anArg == "-pixelformat")
7493 if (++anArgIter >= theArgNb)
7495 Message::SendFail() << "Syntax error at " << anArg;
7498 aRecParams.PixelFormat = theArgVec[anArgIter];
7500 else if (anArg == "-codec"
7501 || anArg == "-vcodec"
7502 || anArg == "-videocodec")
7504 if (++anArgIter >= theArgNb)
7506 Message::SendFail() << "Syntax error at " << anArg;
7509 aRecParams.VideoCodec = theArgVec[anArgIter];
7511 else if (anArg == "-crf"
7512 || anArg == "-preset"
7515 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
7516 if (++anArgIter >= theArgNb)
7518 Message::SendFail() << "Syntax error at " << anArg;
7522 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
7524 // animation definition options
7525 else if (anArg == "-start"
7526 || anArg == "-starttime"
7527 || anArg == "-startpts")
7529 if (++anArgIter >= theArgNb)
7531 Message::SendFail() << "Syntax error at " << anArg;
7535 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
7536 aRootAnimation->UpdateTotalDuration();
7538 else if (anArg == "-end"
7539 || anArg == "-endtime"
7540 || anArg == "-endpts")
7542 if (++anArgIter >= theArgNb)
7544 Message::SendFail() << "Syntax error at " << anArg;
7548 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
7549 aRootAnimation->UpdateTotalDuration();
7551 else if (anArg == "-dur"
7552 || anArg == "-duration")
7554 if (++anArgIter >= theArgNb)
7556 Message::SendFail() << "Syntax error at " << anArg;
7560 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
7561 aRootAnimation->UpdateTotalDuration();
7563 else if (anArg == "-command"
7565 || anArg == "-invoke"
7567 || anArg == "-proc")
7569 if (++anArgIter >= theArgNb)
7571 Message::SendFail() << "Syntax error at " << anArg;
7575 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
7576 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
7578 else if (anArg == "-objecttrsf"
7579 || anArg == "-objectransformation"
7580 || anArg == "-objtransformation"
7581 || anArg == "-objtrsf"
7582 || anArg == "-object"
7585 if (++anArgIter >= theArgNb)
7587 Message::SendFail() << "Syntax error at " << anArg;
7591 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
7592 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
7593 Handle(AIS_InteractiveObject) anObject;
7594 if (!aMapOfAIS.Find2 (anObjName, anObject))
7596 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
7600 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
7601 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
7602 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
7603 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
7604 Standard_Boolean isTrsfSet = Standard_False;
7605 Standard_Integer aTrsfArgIter = anArgIter + 1;
7606 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
7608 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
7609 aTrsfArg.LowerCase();
7610 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
7611 if (aTrsfArg.StartsWith ("-rotation")
7612 || aTrsfArg.StartsWith ("-rot"))
7614 isTrsfSet = Standard_True;
7615 if (aTrsfArgIter + 4 >= theArgNb
7616 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
7618 Message::SendFail() << "Syntax error at " << aTrsfArg;
7623 else if (aTrsfArg.StartsWith ("-location")
7624 || aTrsfArg.StartsWith ("-loc"))
7626 isTrsfSet = Standard_True;
7627 if (aTrsfArgIter + 3 >= theArgNb
7628 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
7630 Message::SendFail() << "Syntax error at " << aTrsfArg;
7635 else if (aTrsfArg.StartsWith ("-scale"))
7637 isTrsfSet = Standard_True;
7638 if (++aTrsfArgIter >= theArgNb)
7640 Message::SendFail() << "Syntax error at " << aTrsfArg;
7644 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
7645 if (!aScaleStr.IsRealValue (Standard_True))
7647 Message::SendFail() << "Syntax error at " << aTrsfArg;
7650 aScales[anIndex] = aScaleStr.RealValue();
7654 anArgIter = aTrsfArgIter - 1;
7660 Message::SendFail() << "Syntax error at " << anArg;
7663 else if (aTrsfArgIter >= theArgNb)
7665 anArgIter = theArgNb;
7668 aTrsfs[0].SetRotation (aRotQuats[0]);
7669 aTrsfs[1].SetRotation (aRotQuats[1]);
7670 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
7671 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
7672 aTrsfs[0].SetScaleFactor (aScales[0]);
7673 aTrsfs[1].SetScaleFactor (aScales[1]);
7675 Handle(AIS_AnimationObject) anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
7676 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
7678 else if (anArg == "-viewtrsf"
7679 || anArg == "-view")
7681 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
7682 if (aCamAnimation.IsNull())
7684 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
7685 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
7688 Handle(Graphic3d_Camera) aCams[2] =
7690 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
7691 new Graphic3d_Camera (aCamAnimation->View()->Camera())
7694 Standard_Boolean isTrsfSet = Standard_False;
7695 Standard_Integer aViewArgIter = anArgIter + 1;
7696 for (; aViewArgIter < theArgNb; ++aViewArgIter)
7698 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
7699 aViewArg.LowerCase();
7700 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
7701 if (aViewArg.StartsWith ("-scale"))
7703 isTrsfSet = Standard_True;
7704 if (++aViewArgIter >= theArgNb)
7706 Message::SendFail() << "Syntax error at " << anArg;
7710 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
7711 if (!aScaleStr.IsRealValue (Standard_True))
7713 Message::SendFail() << "Syntax error at " << aViewArg;
7716 Standard_Real aScale = aScaleStr.RealValue();
7717 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
7718 aCams[anIndex]->SetScale (aScale);
7720 else if (aViewArg.StartsWith ("-eye")
7721 || aViewArg.StartsWith ("-center")
7722 || aViewArg.StartsWith ("-at")
7723 || aViewArg.StartsWith ("-up"))
7725 isTrsfSet = Standard_True;
7727 if (aViewArgIter + 3 >= theArgNb
7728 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
7730 Message::SendFail() << "Syntax error at " << aViewArg;
7735 if (aViewArg.StartsWith ("-eye"))
7737 aCams[anIndex]->SetEye (anXYZ);
7739 else if (aViewArg.StartsWith ("-center")
7740 || aViewArg.StartsWith ("-at"))
7742 aCams[anIndex]->SetCenter (anXYZ);
7744 else if (aViewArg.StartsWith ("-up"))
7746 aCams[anIndex]->SetUp (anXYZ);
7751 anArgIter = aViewArgIter - 1;
7757 Message::SendFail() << "Syntax error at " << anArg;
7760 else if (aViewArgIter >= theArgNb)
7762 anArgIter = theArgNb;
7765 aCamAnimation->SetCameraStart(aCams[0]);
7766 aCamAnimation->SetCameraEnd (aCams[1]);
7770 Message::SendFail() << "Syntax error at " << anArg;
7775 ViewerTest::CurrentEventManager()->AbortViewAnimation();
7776 ViewerTest::CurrentEventManager()->SetObjectsAnimation (Handle(AIS_Animation)());
7777 if (!toPlay && aRecFile.IsEmpty())
7782 // Start animation timeline and process frame updating.
7783 if (aRecParams.FpsNum <= 0
7786 Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
7787 aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7788 ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
7789 ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
7790 ViewerTest::CurrentEventManager()->ProcessExpose();
7794 // Perform video recording
7795 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
7796 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
7797 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7799 OSD_Timer aPerfTimer;
7802 Handle(Image_VideoRecorder) aRecorder;
7803 ImageFlipper aFlipper;
7804 Handle(Draw_ProgressIndicator) aProgress;
7805 if (!aRecFile.IsEmpty())
7807 if (aRecParams.Width <= 0
7808 || aRecParams.Height <= 0)
7810 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
7813 aRecorder = new Image_VideoRecorder();
7814 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
7816 Message::SendFail ("Error: failed to open video file for recording");
7820 aProgress = new Draw_ProgressIndicator (theDI, 1);
7823 // Manage frame-rated animation here
7824 Standard_Real aPts = aPlayStartTime;
7825 int64_t aNbFrames = 0;
7826 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
7827 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
7828 Standard_Integer aSecondsProgress = 0;
7829 for (; aPts <= anUpperPts && aPS.More();)
7831 Standard_Real aRecPts = 0.0;
7832 if (aRecParams.FpsNum > 0)
7834 aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
7838 aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
7841 aPts = aPlayStartTime + aRecPts;
7843 if (!anAnimation->Update (aPts))
7848 if (!aRecorder.IsNull())
7850 V3d_ImageDumpOptions aDumpParams;
7851 aDumpParams.Width = aRecParams.Width;
7852 aDumpParams.Height = aRecParams.Height;
7853 aDumpParams.BufferType = Graphic3d_BT_RGBA;
7854 aDumpParams.StereoOptions = V3d_SDO_MONO;
7855 aDumpParams.ToAdjustAspect = Standard_True;
7856 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
7858 Message::SendFail ("Error: view dump is failed");
7861 aFlipper.FlipY (aRecorder->ChangeFrame());
7862 if (!aRecorder->PushFrame())
7872 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
7880 anAnimation->Stop();
7881 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
7882 theDI << "Average FPS: " << aRecFps << "\n"
7883 << "Nb. Frames: " << Standard_Real(aNbFrames);
7886 aView->SetImmediateUpdate (wasImmediateUpdate);
7891 //=======================================================================
7892 //function : VChangeSelected
7893 //purpose : Adds the shape to selection or remove one from it
7894 //=======================================================================
7895 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
7896 Standard_Integer argc,
7901 di<<"Usage : " << argv[0] << " shape \n";
7905 TCollection_AsciiString aName(argv[1]);
7906 Handle(AIS_InteractiveObject) anAISObject;
7907 if (!GetMapOfAIS().Find2 (aName, anAISObject)
7908 || anAISObject.IsNull())
7910 di<<"Use 'vdisplay' before";
7914 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
7918 //=======================================================================
7919 //function : VNbSelected
7920 //purpose : Returns number of selected objects
7921 //=======================================================================
7922 static Standard_Integer VNbSelected (Draw_Interpretor& di,
7923 Standard_Integer argc,
7928 di << "Usage : " << argv[0] << "\n";
7931 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7932 if(aContext.IsNull())
7934 di << "use 'vinit' command before " << argv[0] << "\n";
7937 di << aContext->NbSelected() << "\n";
7941 //=======================================================================
7942 //function : VSetViewSize
7944 //=======================================================================
7945 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
7946 Standard_Integer argc,
7949 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7950 if(aContext.IsNull())
7952 di << "use 'vinit' command before " << argv[0] << "\n";
7957 di<<"Usage : " << argv[0] << " Size\n";
7960 Standard_Real aSize = Draw::Atof (argv[1]);
7963 di<<"Bad Size value : " << aSize << "\n";
7967 Handle(V3d_View) aView = ViewerTest::CurrentView();
7968 aView->SetSize(aSize);
7972 //=======================================================================
7973 //function : VMoveView
7975 //=======================================================================
7976 static Standard_Integer VMoveView (Draw_Interpretor& di,
7977 Standard_Integer argc,
7980 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7981 if(aContext.IsNull())
7983 di << "use 'vinit' command before " << argv[0] << "\n";
7986 if(argc < 4 || argc > 5)
7988 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
7991 Standard_Real Dx = Draw::Atof (argv[1]);
7992 Standard_Real Dy = Draw::Atof (argv[2]);
7993 Standard_Real Dz = Draw::Atof (argv[3]);
7994 Standard_Boolean aStart = Standard_True;
7997 aStart = (Draw::Atoi (argv[4]) > 0);
8000 Handle(V3d_View) aView = ViewerTest::CurrentView();
8001 aView->Move(Dx,Dy,Dz,aStart);
8005 //=======================================================================
8006 //function : VTranslateView
8008 //=======================================================================
8009 static Standard_Integer VTranslateView (Draw_Interpretor& di,
8010 Standard_Integer argc,
8013 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8014 if(aContext.IsNull())
8016 di << "use 'vinit' command before " << argv[0] << "\n";
8019 if(argc < 4 || argc > 5)
8021 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8024 Standard_Real Dx = Draw::Atof (argv[1]);
8025 Standard_Real Dy = Draw::Atof (argv[2]);
8026 Standard_Real Dz = Draw::Atof (argv[3]);
8027 Standard_Boolean aStart = Standard_True;
8030 aStart = (Draw::Atoi (argv[4]) > 0);
8033 Handle(V3d_View) aView = ViewerTest::CurrentView();
8034 aView->Translate(Dx,Dy,Dz,aStart);
8038 //=======================================================================
8039 //function : VTurnView
8041 //=======================================================================
8042 static Standard_Integer VTurnView (Draw_Interpretor& di,
8043 Standard_Integer argc,
8046 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8047 if(aContext.IsNull()) {
8048 di << "use 'vinit' command before " << argv[0] << "\n";
8051 if(argc < 4 || argc > 5){
8052 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8055 Standard_Real Ax = Draw::Atof (argv[1]);
8056 Standard_Real Ay = Draw::Atof (argv[2]);
8057 Standard_Real Az = Draw::Atof (argv[3]);
8058 Standard_Boolean aStart = Standard_True;
8061 aStart = (Draw::Atoi (argv[4]) > 0);
8064 Handle(V3d_View) aView = ViewerTest::CurrentView();
8065 aView->Turn(Ax,Ay,Az,aStart);
8069 //==============================================================================
8070 //function : VTextureEnv
8071 //purpose : ENables or disables environment mapping
8072 //==============================================================================
8073 class OCC_TextureEnv : public Graphic3d_TextureEnv
8076 OCC_TextureEnv(const Standard_CString FileName);
8077 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8078 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8079 const Standard_Boolean theModulateFlag,
8080 const Graphic3d_TypeOfTextureFilter theFilter,
8081 const Standard_ShortReal theXScale,
8082 const Standard_ShortReal theYScale,
8083 const Standard_ShortReal theXShift,
8084 const Standard_ShortReal theYShift,
8085 const Standard_ShortReal theAngle);
8086 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
8088 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
8090 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8091 : Graphic3d_TextureEnv(theFileName)
8095 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8096 : Graphic3d_TextureEnv(theTexId)
8100 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8101 const Standard_Boolean theModulateFlag,
8102 const Graphic3d_TypeOfTextureFilter theFilter,
8103 const Standard_ShortReal theXScale,
8104 const Standard_ShortReal theYScale,
8105 const Standard_ShortReal theXShift,
8106 const Standard_ShortReal theYShift,
8107 const Standard_ShortReal theAngle)
8109 myParams->SetRepeat (theRepeatFlag);
8110 myParams->SetModulate (theModulateFlag);
8111 myParams->SetFilter (theFilter);
8112 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8113 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8114 myParams->SetRotation (theAngle);
8117 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
8119 // get the active view
8120 Handle(V3d_View) aView = ViewerTest::CurrentView();
8123 Message::SendFail ("Error: no active viewer");
8127 // Checking the input arguments
8128 Standard_Boolean anEnableFlag = Standard_False;
8129 Standard_Boolean isOk = theArgNb >= 2;
8132 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8133 anEnableFlag = anEnableOpt.IsEqual("on");
8134 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8138 isOk = (theArgNb == 3 || theArgNb == 11);
8141 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8142 isOk = (!aTextureOpt.IsIntegerValue() ||
8143 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8145 if (isOk && theArgNb == 11)
8147 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8148 aModulateOpt(theArgVec[4]),
8149 aFilterOpt (theArgVec[5]),
8150 aSScaleOpt (theArgVec[6]),
8151 aTScaleOpt (theArgVec[7]),
8152 aSTransOpt (theArgVec[8]),
8153 aTTransOpt (theArgVec[9]),
8154 anAngleOpt (theArgVec[10]);
8155 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8156 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8157 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
8158 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8159 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8160 anAngleOpt.IsRealValue (Standard_True));
8167 Message::SendFail() << "Usage:\n"
8168 << theArgVec[0] << " off\n"
8169 << 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]";
8175 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8176 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8177 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8178 new OCC_TextureEnv(theArgVec[2]);
8182 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8183 aTexEnv->SetTextureParameters(
8184 aRepeatOpt. IsEqual("repeat"),
8185 aModulateOpt.IsEqual("modulate"),
8186 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8187 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8188 Graphic3d_TOTF_TRILINEAR,
8189 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8190 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8191 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8192 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8193 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8196 aView->SetTextureEnv(aTexEnv);
8198 else // Disabling environment mapping
8200 Handle(Graphic3d_TextureEnv) aTexture;
8201 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8210 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8212 //! Remove registered clipping plane from all views and objects.
8213 static void removePlane (MapOfPlanes& theRegPlanes,
8214 const TCollection_AsciiString& theName)
8216 Handle(Graphic3d_ClipPlane) aClipPlane;
8217 if (!theRegPlanes.Find (theName, aClipPlane))
8219 Message::SendWarning ("Warning: no such plane");
8223 theRegPlanes.UnBind (theName);
8224 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8225 anIObjIt.More(); anIObjIt.Next())
8227 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
8228 aPrs->RemoveClipPlane (aClipPlane);
8231 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
8232 aViewIt.More(); aViewIt.Next())
8234 const Handle(V3d_View)& aView = aViewIt.Key2();
8235 aView->RemoveClipPlane(aClipPlane);
8238 ViewerTest::RedrawAllViews();
8242 //===============================================================================================
8243 //function : VClipPlane
8245 //===============================================================================================
8246 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8248 // use short-cut for created clip planes map of created (or "registered by name") clip planes
8249 static MapOfPlanes aRegPlanes;
8253 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8255 theDi << aPlaneIter.Key() << " ";
8260 TCollection_AsciiString aCommand (theArgVec[1]);
8261 aCommand.LowerCase();
8262 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8263 if (anActiveView.IsNull())
8265 Message::SendFail ("Error: no active viewer");
8269 // print maximum number of planes for current viewer
8270 if (aCommand == "-maxplanes"
8271 || aCommand == "maxplanes")
8273 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8274 << " plane slots provided by driver.\n";
8278 // create / delete plane instance
8279 if (aCommand == "-create"
8280 || aCommand == "create"
8281 || aCommand == "-delete"
8282 || aCommand == "delete"
8283 || aCommand == "-clone"
8284 || aCommand == "clone")
8288 Message::SendFail ("Syntax error: plane name is required");
8292 Standard_Boolean toCreate = aCommand == "-create"
8293 || aCommand == "create";
8294 Standard_Boolean toClone = aCommand == "-clone"
8295 || aCommand == "clone";
8296 Standard_Boolean toDelete = aCommand == "-delete"
8297 || aCommand == "delete";
8298 TCollection_AsciiString aPlane (theArgVec[2]);
8302 if (aRegPlanes.IsBound (aPlane))
8304 std::cout << "Warning: existing plane has been overridden.\n";
8309 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8313 else if (toClone) // toClone
8315 if (!aRegPlanes.IsBound (aPlane))
8317 Message::SendFail ("Error: no such plane");
8320 else if (theArgsNb < 4)
8322 Message::SendFail ("Syntax error: enter name for new plane");
8326 TCollection_AsciiString aClone (theArgVec[3]);
8327 if (aRegPlanes.IsBound (aClone))
8329 Message::SendFail ("Error: plane name is in use");
8333 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8335 aRegPlanes.Bind (aClone, aClipPlane->Clone());
8345 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8347 aPlane = aPlaneIter.Key();
8348 removePlane (aRegPlanes, aPlane);
8349 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8354 removePlane (aRegPlanes, aPlane);
8360 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8365 // set / unset plane command
8366 if (aCommand == "set"
8367 || aCommand == "unset")
8371 Message::SendFail ("Syntax error: need more arguments");
8375 // redirect to new syntax
8376 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8377 anArgVec.SetValue (1, theArgVec[0]);
8378 anArgVec.SetValue (2, theArgVec[2]);
8379 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8380 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
8382 anArgVec.SetValue (anIt, theArgVec[anIt]);
8385 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
8388 // change plane command
8389 TCollection_AsciiString aPlaneName;
8390 Handle(Graphic3d_ClipPlane) aClipPlane;
8391 Standard_Integer anArgIter = 0;
8392 if (aCommand == "-change"
8393 || aCommand == "change")
8395 // old syntax support
8398 Message::SendFail ("Syntax error: need more arguments");
8403 aPlaneName = theArgVec[2];
8404 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
8406 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
8410 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8413 aPlaneName = theArgVec[1];
8418 aPlaneName = theArgVec[1];
8419 aClipPlane = new Graphic3d_ClipPlane();
8420 aRegPlanes.Bind (aPlaneName, aClipPlane);
8421 theDi << "Created new plane " << aPlaneName << ".\n";
8424 if (theArgsNb - anArgIter < 1)
8426 Message::SendFail ("Syntax error: need more arguments");
8430 for (; anArgIter < theArgsNb; ++anArgIter)
8432 const char** aChangeArgs = theArgVec + anArgIter;
8433 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8434 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
8435 aChangeArg.LowerCase();
8437 Standard_Boolean toEnable = Standard_True;
8438 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
8440 aClipPlane->SetOn (toEnable);
8442 else if (aChangeArg.StartsWith ("-equation")
8443 || aChangeArg.StartsWith ("equation"))
8445 if (aNbChangeArgs < 5)
8447 Message::SendFail ("Syntax error: need more arguments");
8451 Standard_Integer aSubIndex = 1;
8452 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
8453 if (aPrefixLen < aChangeArg.Length())
8455 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
8456 if (!aSubStr.IsIntegerValue()
8457 || aSubStr.IntegerValue() <= 0)
8459 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8462 aSubIndex = aSubStr.IntegerValue();
8465 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
8466 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
8467 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
8468 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
8469 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8470 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
8472 if (aSubPln->ChainNextPlane().IsNull())
8474 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8476 aSubPln = aSubPln->ChainNextPlane();
8478 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8479 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
8482 else if ((aChangeArg == "-boxinterior"
8483 || aChangeArg == "-boxint"
8484 || aChangeArg == "-box")
8485 && aNbChangeArgs >= 7)
8487 Graphic3d_BndBox3d aBndBox;
8488 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
8489 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
8492 Standard_Integer aNbSubPlanes = 6;
8493 const Graphic3d_Vec3d aDirArray[6] =
8495 Graphic3d_Vec3d (-1, 0, 0),
8496 Graphic3d_Vec3d ( 1, 0, 0),
8497 Graphic3d_Vec3d ( 0,-1, 0),
8498 Graphic3d_Vec3d ( 0, 1, 0),
8499 Graphic3d_Vec3d ( 0, 0,-1),
8500 Graphic3d_Vec3d ( 0, 0, 1),
8502 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8503 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
8505 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
8506 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
8507 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
8508 if (aSubPlaneIter + 1 == aNbSubPlanes)
8510 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8514 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8516 aSubPln = aSubPln->ChainNextPlane();
8519 else if (aChangeArg == "-capping"
8520 || aChangeArg == "capping")
8522 if (aNbChangeArgs < 2)
8524 Message::SendFail ("Syntax error: need more arguments");
8528 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8530 aClipPlane->SetCapping (toEnable);
8535 // just skip otherwise (old syntax)
8538 else if (aChangeArg == "-useobjectmaterial"
8539 || aChangeArg == "-useobjectmat"
8540 || aChangeArg == "-useobjmat"
8541 || aChangeArg == "-useobjmaterial")
8543 if (aNbChangeArgs < 2)
8545 Message::SendFail ("Syntax error: need more arguments");
8549 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8551 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
8555 else if (aChangeArg == "-useobjecttexture"
8556 || aChangeArg == "-useobjecttex"
8557 || aChangeArg == "-useobjtexture"
8558 || aChangeArg == "-useobjtex")
8560 if (aNbChangeArgs < 2)
8562 Message::SendFail ("Syntax error: need more arguments");
8566 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8568 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
8572 else if (aChangeArg == "-useobjectshader"
8573 || aChangeArg == "-useobjshader")
8575 if (aNbChangeArgs < 2)
8577 Message::SendFail ("Syntax error: need more arguments");
8581 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8583 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
8587 else if (aChangeArg == "-color"
8588 || aChangeArg == "color")
8590 Quantity_Color aColor;
8591 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
8596 Message::SendFail ("Syntax error: need more arguments");
8599 aClipPlane->SetCappingColor (aColor);
8600 anArgIter += aNbParsed;
8602 else if (aNbChangeArgs >= 1
8603 && (aChangeArg == "-material"
8604 || aChangeArg == "material"))
8607 Graphic3d_NameOfMaterial aMatName;
8608 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
8610 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
8613 aClipPlane->SetCappingMaterial (aMatName);
8615 else if ((aChangeArg == "-transparency"
8616 || aChangeArg == "-transp")
8617 && aNbChangeArgs >= 2)
8619 TCollection_AsciiString aValStr (aChangeArgs[1]);
8620 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
8621 if (aValStr.IsRealValue (Standard_True))
8623 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
8624 aMat.SetTransparency ((float )aValStr.RealValue());
8625 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
8626 aClipPlane->SetCappingMaterial (aMat);
8630 aValStr.LowerCase();
8631 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
8632 if (aValStr == "opaque")
8634 aMode = Graphic3d_AlphaMode_Opaque;
8636 else if (aValStr == "mask")
8638 aMode = Graphic3d_AlphaMode_Mask;
8640 else if (aValStr == "blend")
8642 aMode = Graphic3d_AlphaMode_Blend;
8644 else if (aValStr == "maskblend"
8645 || aValStr == "blendmask")
8647 aMode = Graphic3d_AlphaMode_MaskBlend;
8649 else if (aValStr == "blendauto")
8651 aMode = Graphic3d_AlphaMode_BlendAuto;
8655 Message::SendFail() << "Syntax error at '" << aValStr << "'";
8658 anAspect->SetAlphaMode (aMode);
8659 aClipPlane->SetCappingAspect (anAspect);
8663 else if (aChangeArg == "-texname"
8664 || aChangeArg == "texname")
8666 if (aNbChangeArgs < 2)
8668 Message::SendFail ("Syntax error: need more arguments");
8672 TCollection_AsciiString aTextureName (aChangeArgs[1]);
8673 Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D (aTextureName);
8674 if (!aTexture->IsDone())
8676 aClipPlane->SetCappingTexture (NULL);
8680 aTexture->EnableModulate();
8681 aTexture->EnableRepeat();
8682 aClipPlane->SetCappingTexture (aTexture);
8686 else if (aChangeArg == "-texscale"
8687 || aChangeArg == "texscale")
8689 if (aClipPlane->CappingTexture().IsNull())
8691 Message::SendFail ("Error: no texture is set");
8695 if (aNbChangeArgs < 3)
8697 Message::SendFail ("Syntax error: need more arguments");
8701 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8702 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8703 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
8706 else if (aChangeArg == "-texorigin"
8707 || aChangeArg == "texorigin") // texture origin
8709 if (aClipPlane->CappingTexture().IsNull())
8711 Message::SendFail ("Error: no texture is set");
8715 if (aNbChangeArgs < 3)
8717 Message::SendFail ("Syntax error: need more arguments");
8721 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8722 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8724 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
8727 else if (aChangeArg == "-texrotate"
8728 || aChangeArg == "texrotate") // texture rotation
8730 if (aClipPlane->CappingTexture().IsNull())
8732 Message::SendFail ("Error: no texture is set");
8736 if (aNbChangeArgs < 2)
8738 Message::SendFail ("Syntax error: need more arguments");
8742 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8743 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
8746 else if (aChangeArg == "-hatch"
8747 || aChangeArg == "hatch")
8749 if (aNbChangeArgs < 2)
8751 Message::SendFail ("Syntax error: need more arguments");
8755 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
8756 aHatchStr.LowerCase();
8757 if (aHatchStr == "on")
8759 aClipPlane->SetCappingHatchOn();
8761 else if (aHatchStr == "off")
8763 aClipPlane->SetCappingHatchOff();
8767 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
8771 else if (aChangeArg == "-delete"
8772 || aChangeArg == "delete")
8774 removePlane (aRegPlanes, aPlaneName);
8777 else if (aChangeArg == "-set"
8778 || aChangeArg == "-unset"
8779 || aChangeArg == "-setoverrideglobal")
8781 // set / unset plane command
8782 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
8783 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
8784 Standard_Integer anIt = 1;
8785 for (; anIt < aNbChangeArgs; ++anIt)
8787 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
8788 if (anEntityName.IsEmpty()
8789 || anEntityName.Value (1) == '-')
8793 else if (!toOverrideGlobal
8794 && ViewerTest_myViews.IsBound1 (anEntityName))
8796 Handle(V3d_View) aView = ViewerTest_myViews.Find1 (anEntityName);
8799 aView->AddClipPlane (aClipPlane);
8803 aView->RemoveClipPlane (aClipPlane);
8807 else if (GetMapOfAIS().IsBound2 (anEntityName))
8809 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
8812 aIObj->AddClipPlane (aClipPlane);
8816 aIObj->RemoveClipPlane (aClipPlane);
8818 if (!aIObj->ClipPlanes().IsNull())
8820 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
8825 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
8832 // apply to active view
8835 anActiveView->AddClipPlane (aClipPlane);
8839 anActiveView->RemoveClipPlane (aClipPlane);
8844 anArgIter = anArgIter + anIt - 1;
8849 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8854 ViewerTest::RedrawAllViews();
8858 //===============================================================================================
8859 //function : VZRange
8861 //===============================================================================================
8862 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8864 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8866 if (aCurrentView.IsNull())
8868 Message::SendFail ("Error: no active viewer");
8872 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
8876 theDi << "ZNear: " << aCamera->ZNear() << "\n";
8877 theDi << "ZFar: " << aCamera->ZFar() << "\n";
8883 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
8884 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
8886 if (aNewZNear >= aNewZFar)
8888 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
8892 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
8894 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
8898 aCamera->SetZRange (aNewZNear, aNewZFar);
8902 Message::SendFail ("Syntax error: wrong command arguments");
8906 aCurrentView->Redraw();
8911 //===============================================================================================
8912 //function : VAutoZFit
8914 //===============================================================================================
8915 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8917 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8919 if (aCurrentView.IsNull())
8921 Message::SendFail ("Error: no active viewer");
8925 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
8929 Message::SendFail ("Syntax error: wrong command arguments");
8935 theDi << "Auto z-fit mode: \n"
8936 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
8937 << "Scale: " << aScale << "\n";
8941 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
8945 aScale = Draw::Atoi (theArgVec[2]);
8948 aCurrentView->SetAutoZFitMode (isOn, aScale);
8949 aCurrentView->Redraw();
8953 //! Auxiliary function to print projection type
8954 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
8956 switch (theProjType)
8958 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
8959 case Graphic3d_Camera::Projection_Perspective: return "perspective";
8960 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
8961 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
8962 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
8967 //===============================================================================================
8968 //function : VCamera
8970 //===============================================================================================
8971 static int VCamera (Draw_Interpretor& theDI,
8972 Standard_Integer theArgsNb,
8973 const char** theArgVec)
8975 Handle(V3d_View) aView = ViewerTest::CurrentView();
8978 Message::SendFail ("Error: no active viewer");
8982 Handle(Graphic3d_Camera) aCamera = aView->Camera();
8985 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
8986 theDI << "FOVy: " << aCamera->FOVy() << "\n";
8987 theDI << "FOVx: " << aCamera->FOVx() << "\n";
8988 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
8989 theDI << "Distance: " << aCamera->Distance() << "\n";
8990 theDI << "IOD: " << aCamera->IOD() << "\n";
8991 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
8992 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
8993 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
8994 theDI << "ZNear: " << aCamera->ZNear() << "\n";
8995 theDI << "ZFar: " << aCamera->ZFar() << "\n";
8999 TCollection_AsciiString aPrsName;
9000 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9002 Standard_CString anArg = theArgVec[anArgIter];
9003 TCollection_AsciiString anArgCase (anArg);
9004 anArgCase.LowerCase();
9005 if (anArgCase == "-proj"
9006 || anArgCase == "-projection"
9007 || anArgCase == "-projtype"
9008 || anArgCase == "-projectiontype")
9010 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9012 else if (anArgCase == "-ortho"
9013 || anArgCase == "-orthographic")
9015 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
9017 else if (anArgCase == "-persp"
9018 || anArgCase == "-perspective"
9019 || anArgCase == "-perspmono"
9020 || anArgCase == "-perspectivemono"
9021 || anArgCase == "-mono")
9023 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9025 else if (anArgCase == "-stereo"
9026 || anArgCase == "-stereoscopic"
9027 || anArgCase == "-perspstereo"
9028 || anArgCase == "-perspectivestereo")
9030 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9032 else if (anArgCase == "-left"
9033 || anArgCase == "-lefteye"
9034 || anArgCase == "-monoleft"
9035 || anArgCase == "-monolefteye"
9036 || anArgCase == "-perpsleft"
9037 || anArgCase == "-perpslefteye")
9039 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9041 else if (anArgCase == "-right"
9042 || anArgCase == "-righteye"
9043 || anArgCase == "-monoright"
9044 || anArgCase == "-monorighteye"
9045 || anArgCase == "-perpsright")
9047 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9049 else if (anArgCase == "-dist"
9050 || anArgCase == "-distance")
9052 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9053 if (anArgValue != NULL
9054 && *anArgValue != '-')
9057 aCamera->SetDistance (Draw::Atof (anArgValue));
9060 theDI << aCamera->Distance() << " ";
9062 else if (anArgCase == "-iod")
9064 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9065 if (anArgValue != NULL
9066 && *anArgValue != '-')
9069 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9072 theDI << aCamera->IOD() << " ";
9074 else if (anArgCase == "-iodtype")
9076 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9077 TCollection_AsciiString anValueCase (anArgValue);
9078 anValueCase.LowerCase();
9079 if (anValueCase == "abs"
9080 || anValueCase == "absolute")
9083 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9086 else if (anValueCase == "rel"
9087 || anValueCase == "relative")
9090 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9093 else if (*anArgValue != '-')
9095 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
9098 switch (aCamera->GetIODType())
9100 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9101 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9104 else if (anArgCase == "-zfocus")
9106 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9107 if (anArgValue != NULL
9108 && *anArgValue != '-')
9111 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9114 theDI << aCamera->ZFocus() << " ";
9116 else if (anArgCase == "-zfocustype")
9118 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9119 TCollection_AsciiString anValueCase (anArgValue);
9120 anValueCase.LowerCase();
9121 if (anValueCase == "abs"
9122 || anValueCase == "absolute")
9125 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9128 else if (anValueCase == "rel"
9129 || anValueCase == "relative")
9132 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9135 else if (*anArgValue != '-')
9137 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
9140 switch (aCamera->ZFocusType())
9142 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9143 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9146 else if (anArgCase == "-lockzup"
9147 || anArgCase == "-turntable")
9149 bool toLockUp = true;
9150 if (++anArgIter < theArgsNb
9151 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
9155 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9157 else if (anArgCase == "-rotationmode"
9158 || anArgCase == "-rotmode")
9160 AIS_RotationMode aRotMode = AIS_RotationMode_BndBoxActive;
9161 TCollection_AsciiString aRotStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9162 aRotStr.LowerCase();
9163 if (aRotStr == "bndboxactive"
9164 || aRotStr == "active")
9166 aRotMode = AIS_RotationMode_BndBoxActive;
9168 else if (aRotStr == "picklast"
9169 || aRotStr == "pick")
9171 aRotMode = AIS_RotationMode_PickLast;
9173 else if (aRotStr == "pickcenter")
9175 aRotMode = AIS_RotationMode_PickCenter;
9177 else if (aRotStr == "cameraat"
9178 || aRotStr == "cameracenter")
9180 aRotMode = AIS_RotationMode_CameraAt;
9182 else if (aRotStr == "bndboxscene"
9183 || aRotStr == "boxscene")
9185 aRotMode = AIS_RotationMode_BndBoxScene;
9189 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9193 ViewerTest::CurrentEventManager()->SetRotationMode (aRotMode);
9196 else if (anArgCase == "-navigationmode"
9197 || anArgCase == "-navmode")
9199 AIS_NavigationMode aNavMode = AIS_NavigationMode_Orbit;
9200 TCollection_AsciiString aNavStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9201 aNavStr.LowerCase();
9202 if (aNavStr == "orbit")
9204 aNavMode = AIS_NavigationMode_Orbit;
9206 else if (aNavStr == "flight"
9208 || aNavStr == "copter"
9209 || aNavStr == "helicopter")
9211 aNavMode = AIS_NavigationMode_FirstPersonFlight;
9213 else if (aNavStr == "walk"
9214 || aNavStr == "shooter")
9216 aNavMode = AIS_NavigationMode_FirstPersonWalk;
9220 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9224 Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
9225 aViewMgr->SetNavigationMode (aNavMode);
9226 if (aNavMode == AIS_NavigationMode_Orbit)
9228 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateOrbit);
9232 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateView);
9236 else if (anArgCase == "-fov"
9237 || anArgCase == "-fovy"
9238 || anArgCase == "-fovx"
9239 || anArgCase == "-fov2d")
9241 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9242 if (anArgValue != NULL
9243 && *anArgValue != '-')
9246 if (anArgCase == "-fov2d")
9248 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9250 else if (anArgCase == "-fovx")
9252 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9256 aCamera->SetFOVy (Draw::Atof (anArgValue));
9260 if (anArgCase == "-fov2d")
9262 theDI << aCamera->FOV2d() << " ";
9264 else if (anArgCase == "-fovx")
9266 theDI << aCamera->FOVx() << " ";
9270 theDI << aCamera->FOVy() << " ";
9273 else if (anArgIter + 1 < theArgsNb
9274 && anArgCase == "-xrpose")
9276 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9277 anXRArg.LowerCase();
9278 if (anXRArg == "base")
9280 aCamera = aView->View()->BaseXRCamera();
9282 else if (anXRArg == "head")
9284 aCamera = aView->View()->PosedXRCamera();
9288 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9291 if (aCamera.IsNull())
9293 Message::SendFail() << "Error: undefined XR pose";
9296 if (aView->AutoZFitMode())
9298 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9299 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9300 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9303 else if (aPrsName.IsEmpty()
9304 && !anArgCase.StartsWith ("-"))
9310 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
9315 if (aPrsName.IsEmpty()
9321 if (!aPrsName.IsEmpty())
9323 Handle(AIS_CameraFrustum) aCameraFrustum;
9324 if (GetMapOfAIS().IsBound2 (aPrsName))
9326 // find existing object
9327 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9328 if (aCameraFrustum.IsNull())
9330 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
9335 if (aCameraFrustum.IsNull())
9337 aCameraFrustum = new AIS_CameraFrustum();
9341 // not include displayed object of old camera frustum in the new one.
9342 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9345 aCameraFrustum->SetCameraFrustum (aCamera);
9347 ViewerTest::Display (aPrsName, aCameraFrustum);
9353 //! Parse stereo output mode
9354 inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9355 Graphic3d_StereoMode& theMode)
9357 TCollection_AsciiString aFlag (theArg);
9359 if (aFlag == "quadbuffer")
9361 theMode = Graphic3d_StereoMode_QuadBuffer;
9363 else if (aFlag == "anaglyph")
9365 theMode = Graphic3d_StereoMode_Anaglyph;
9367 else if (aFlag == "row"
9368 || aFlag == "rowinterlaced")
9370 theMode = Graphic3d_StereoMode_RowInterlaced;
9372 else if (aFlag == "col"
9373 || aFlag == "colinterlaced"
9374 || aFlag == "columninterlaced")
9376 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9378 else if (aFlag == "chess"
9379 || aFlag == "chessboard")
9381 theMode = Graphic3d_StereoMode_ChessBoard;
9383 else if (aFlag == "sbs"
9384 || aFlag == "sidebyside")
9386 theMode = Graphic3d_StereoMode_SideBySide;
9388 else if (aFlag == "ou"
9389 || aFlag == "overunder")
9391 theMode = Graphic3d_StereoMode_OverUnder;
9393 else if (aFlag == "pageflip"
9394 || aFlag == "softpageflip")
9396 theMode = Graphic3d_StereoMode_SoftPageFlip;
9398 else if (aFlag == "openvr"
9401 theMode = Graphic3d_StereoMode_OpenVR;
9405 return Standard_False;
9407 return Standard_True;
9410 //! Parse anaglyph filter
9411 inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9412 Graphic3d_RenderingParams::Anaglyph& theFilter)
9414 TCollection_AsciiString aFlag (theArg);
9416 if (aFlag == "redcyansimple")
9418 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9420 else if (aFlag == "redcyan"
9421 || aFlag == "redcyanoptimized")
9423 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9425 else if (aFlag == "yellowbluesimple")
9427 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9429 else if (aFlag == "yellowblue"
9430 || aFlag == "yellowblueoptimized")
9432 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9434 else if (aFlag == "greenmagenta"
9435 || aFlag == "greenmagentasimple")
9437 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9441 return Standard_False;
9443 return Standard_True;
9446 //==============================================================================
9447 //function : VStereo
9449 //==============================================================================
9451 static int VStereo (Draw_Interpretor& theDI,
9452 Standard_Integer theArgNb,
9453 const char** theArgVec)
9455 Handle(V3d_View) aView = ViewerTest::CurrentView();
9458 Message::SendFail ("Error: no active viewer");
9462 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9463 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9466 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
9467 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
9470 TCollection_AsciiString aMode;
9471 switch (aView->RenderingParams().StereoMode)
9473 case Graphic3d_StereoMode_QuadBuffer:
9475 aMode = "quadBuffer";
9478 case Graphic3d_StereoMode_RowInterlaced:
9480 aMode = "rowInterlaced";
9481 if (aView->RenderingParams().ToSmoothInterlacing)
9483 aMode.AssignCat (" (smoothed)");
9487 case Graphic3d_StereoMode_ColumnInterlaced:
9489 aMode = "columnInterlaced";
9490 if (aView->RenderingParams().ToSmoothInterlacing)
9492 aMode.AssignCat (" (smoothed)");
9496 case Graphic3d_StereoMode_ChessBoard:
9498 aMode = "chessBoard";
9499 if (aView->RenderingParams().ToSmoothInterlacing)
9501 aMode.AssignCat (" (smoothed)");
9505 case Graphic3d_StereoMode_SideBySide:
9507 aMode = "sideBySide";
9510 case Graphic3d_StereoMode_OverUnder:
9512 aMode = "overUnder";
9515 case Graphic3d_StereoMode_SoftPageFlip:
9517 aMode = "softPageFlip";
9520 case Graphic3d_StereoMode_OpenVR:
9525 case Graphic3d_StereoMode_Anaglyph:
9528 switch (aView->RenderingParams().AnaglyphFilter)
9530 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9531 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9532 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9533 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9534 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9535 case Graphic3d_RenderingParams::Anaglyph_UserDefined : aMode.AssignCat (" (userDefined)"); break;
9539 theDI << "Mode " << aMode << "\n";
9544 Graphic3d_StereoMode aMode = aParams->StereoMode;
9545 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9546 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9548 Standard_CString anArg = theArgVec[anArgIter];
9549 TCollection_AsciiString aFlag (anArg);
9551 if (anUpdateTool.parseRedrawMode (aFlag))
9555 else if (aFlag == "0"
9558 if (++anArgIter < theArgNb)
9560 Message::SendFail ("Error: wrong number of arguments");
9564 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
9566 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9570 else if (aFlag == "1"
9573 if (++anArgIter < theArgNb)
9575 Message::SendFail ("Error: wrong number of arguments");
9579 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9580 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
9585 else if (aFlag == "-reverse"
9586 || aFlag == "-noreverse"
9587 || aFlag == "-reversed"
9589 || aFlag == "-noswap")
9591 aParams->ToReverseStereo = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
9593 else if (aFlag == "-mode"
9594 || aFlag == "-stereomode")
9596 if (++anArgIter >= theArgNb
9597 || !parseStereoMode (theArgVec[anArgIter], aMode))
9599 Message::SendFail() << "Syntax error at '" << anArg << "'";
9603 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9605 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9608 else if (aFlag == "-anaglyph"
9609 || aFlag == "-anaglyphfilter")
9611 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9612 if (++anArgIter >= theArgNb
9613 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
9615 Message::SendFail() << "Syntax error at '" << anArg << "'";
9619 aMode = Graphic3d_StereoMode_Anaglyph;
9620 aParams->AnaglyphFilter = aFilter;
9622 else if (parseStereoMode (anArg, aMode)) // short syntax
9624 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9626 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9629 else if (anArgIter + 1 < theArgNb
9630 && aFlag == "-hmdfov2d")
9632 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
9633 if (aParams->HmdFov2d < 10.0f
9634 || aParams->HmdFov2d > 180.0f)
9636 Message::SendFail() << "Error: FOV is out of range";
9640 else if (aFlag == "-mirror"
9641 || aFlag == "-mirrorcomposer")
9643 aParams->ToMirrorComposer = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);;
9645 else if (aFlag == "-smooth"
9646 || aFlag == "-nosmooth"
9647 || aFlag == "-smoothinterlacing"
9648 || aFlag == "-nosmoothinterlacing")
9650 aParams->ToSmoothInterlacing = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
9652 else if (anArgIter + 1 < theArgNb
9653 && (aFlag == "-unitfactor"
9654 || aFlag == "-unitscale"))
9656 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
9660 Message::SendFail() << "Syntax error at '" << anArg << "'";
9665 aParams->StereoMode = aMode;
9666 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9667 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
9669 // initiate implicit continuous rendering
9670 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
9675 //===============================================================================================
9676 //function : VDefaults
9678 //===============================================================================================
9679 static int VDefaults (Draw_Interpretor& theDi,
9680 Standard_Integer theArgsNb,
9681 const char** theArgVec)
9683 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9686 Message::SendFail ("Error: no active viewer");
9690 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
9693 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
9695 theDi << "DeflType: relative\n"
9696 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
9700 theDi << "DeflType: absolute\n"
9701 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
9703 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
9704 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
9708 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9710 TCollection_AsciiString anArg (theArgVec[anArgIter]);
9712 if (anArg == "-ABSDEFL"
9713 || anArg == "-ABSOLUTEDEFLECTION"
9715 || anArg == "-DEFLECTION")
9717 if (++anArgIter >= theArgsNb)
9719 Message::SendFail() << "Syntax error at " << anArg;
9722 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
9723 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
9725 else if (anArg == "-RELDEFL"
9726 || anArg == "-RELATIVEDEFLECTION"
9727 || anArg == "-DEVCOEFF"
9728 || anArg == "-DEVIATIONCOEFF"
9729 || anArg == "-DEVIATIONCOEFFICIENT")
9731 if (++anArgIter >= theArgsNb)
9733 Message::SendFail() << "Syntax error at " << anArg;
9736 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
9737 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
9739 else if (anArg == "-ANGDEFL"
9740 || anArg == "-ANGULARDEFL"
9741 || anArg == "-ANGULARDEFLECTION")
9743 if (++anArgIter >= theArgsNb)
9745 Message::SendFail() << "Syntax error at " << anArg;
9748 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
9750 else if (anArg == "-AUTOTR"
9751 || anArg == "-AUTOTRIANG"
9752 || anArg == "-AUTOTRIANGULATION")
9755 bool toTurnOn = true;
9756 if (anArgIter >= theArgsNb
9757 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
9759 Message::SendFail() << "Syntax error at '" << anArg << "'";
9762 aDefParams->SetAutoTriangulation (toTurnOn);
9766 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
9774 //! Parse light source type from string.
9775 static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
9776 Graphic3d_TypeOfLightSource& theType)
9778 TCollection_AsciiString aType (theTypeName);
9781 || aType == "ambient"
9782 || aType == "amblight")
9784 theType = Graphic3d_TypeOfLightSource_Ambient;
9786 else if (aType == "directional"
9787 || aType == "dirlight")
9789 theType = Graphic3d_TypeOfLightSource_Directional;
9791 else if (aType == "spot"
9792 || aType == "spotlight")
9794 theType = Graphic3d_TypeOfLightSource_Spot;
9796 else if (aType == "poslight"
9797 || aType == "positional"
9801 theType = Graphic3d_TypeOfLightSource_Positional;
9810 //! Find existing light by name or index.
9811 static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
9813 Handle(V3d_Light) aLight;
9814 Standard_Integer aLightIndex = -1;
9815 Draw::ParseInteger (theName.ToCString(), aLightIndex);
9816 Standard_Integer aLightIt = 0;
9817 Handle(V3d_View) aView = ViewerTest::CurrentView();
9818 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
9820 if (aLightIndex != -1)
9822 if (aLightIt == aLightIndex)
9824 return aLightIter.Value();
9827 else if (aLightIter.Value()->GetId() == theName
9828 || aLightIter.Value()->Name() == theName)
9830 if (!aLight.IsNull())
9832 Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
9835 aLight = aLightIter.Value();
9841 //===============================================================================================
9844 //===============================================================================================
9845 static int VLight (Draw_Interpretor& theDi,
9846 Standard_Integer theArgsNb,
9847 const char** theArgVec)
9849 Handle(V3d_View) aView = ViewerTest::CurrentView();
9850 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
9851 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9853 || aViewer.IsNull())
9855 Message::SendFail ("Error: no active viewer");
9861 // print lights info
9862 Standard_Integer aLightId = 0;
9863 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
9865 Handle(V3d_Light) aLight = aLightIter.Value();
9866 const Quantity_Color aColor = aLight->Color();
9867 theDi << "Light #" << aLightId
9868 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
9869 << " [" << aLight->GetId() << "] "
9870 << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
9871 switch (aLight->Type())
9875 theDi << " Type: Ambient\n"
9876 << " Intensity: " << aLight->Intensity() << "\n";
9879 case V3d_DIRECTIONAL:
9881 theDi << " Type: Directional\n"
9882 << " Intensity: " << aLight->Intensity() << "\n"
9883 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9884 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9885 << " Smoothness: " << aLight->Smoothness() << "\n"
9886 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
9889 case V3d_POSITIONAL:
9891 theDi << " Type: Positional\n"
9892 << " Intensity: " << aLight->Intensity() << "\n"
9893 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9894 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9895 << " Smoothness: " << aLight->Smoothness() << "\n"
9896 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9897 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9898 << " Range: " << aLight->Range() << "\n";
9903 theDi << " Type: Spot\n"
9904 << " Intensity: " << aLight->Intensity() << "\n"
9905 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9906 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9907 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9908 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
9909 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9910 << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
9911 << " Exponent: " << aLight->Concentration() << "\n"
9912 << " Range: " << aLight->Range() << "\n";
9917 theDi << " Type: UNKNOWN\n";
9921 theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
9925 Handle(V3d_Light) aLightOld, aLightNew;
9926 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
9927 bool isGlobal = true;
9928 ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
9929 Handle(AIS_LightSource) aLightPrs;
9930 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
9932 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
9933 TCollection_AsciiString anArgCase (anArg);
9934 anArgCase.LowerCase();
9935 if (anUpdateTool.parseRedrawMode (anArg))
9939 else if (anArgCase == "-new"
9940 || anArgCase == "-add"
9941 || anArgCase == "-create"
9942 || anArgCase == "-type"
9943 || (anArgCase == "-reset"
9944 && !aLightNew.IsNull())
9945 || (anArgCase == "-defaults"
9946 && !aLightNew.IsNull())
9947 || anArgCase == "add"
9948 || anArgCase == "new"
9949 || anArgCase == "create")
9951 Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
9952 if (anArgCase == "-reset")
9954 aType = aLightNew->Type();
9956 else if (anArgIt + 1 >= theArgsNb
9957 || !parseLightSourceType (theArgVec[++anArgIt], aType))
9959 theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
9963 TCollection_AsciiString aName;
9964 if (!aLightNew.IsNull())
9966 aName = aLightNew->Name();
9970 case Graphic3d_TypeOfLightSource_Ambient:
9972 aLightNew = new V3d_AmbientLight();
9975 case Graphic3d_TypeOfLightSource_Directional:
9977 aLightNew = new V3d_DirectionalLight();
9980 case Graphic3d_TypeOfLightSource_Spot:
9982 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
9985 case Graphic3d_TypeOfLightSource_Positional:
9987 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
9992 if (anArgCase == "-type"
9993 && !aLightOld.IsNull())
9995 aLightNew->CopyFrom (aLightOld);
9997 aLightNew->SetName (aName);
9999 else if ((anArgCase == "-layer"
10000 || anArgCase == "-zlayer")
10001 && anArgIt + 1 < theArgsNb)
10003 if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
10004 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10006 Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
10010 else if (anArgCase == "-glob"
10011 || anArgCase == "-global"
10012 || anArgCase == "-loc"
10013 || anArgCase == "-local")
10015 isGlobal = anArgCase.StartsWith ("-glob");
10017 else if (anArgCase == "-def"
10018 || anArgCase == "-defaults"
10019 || anArgCase == "-reset")
10021 aViewer->SetDefaultLights();
10022 aLightOld.Nullify();
10023 aLightNew.Nullify();
10024 aLightPrs.Nullify();
10026 else if (anArgCase == "-clr"
10027 || anArgCase == "-clear"
10028 || anArgCase == "clear")
10030 TColStd_SequenceOfInteger aLayers;
10031 aViewer->GetAllZLayers (aLayers);
10032 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10034 if (aLayeriter.Value() == aLayer
10035 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10037 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10038 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10039 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10040 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10047 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10049 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
10050 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10052 Handle(V3d_Light) aLight = aLightIter.Value();
10053 Handle(AIS_InteractiveObject) aPrsObject;
10054 GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
10055 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10057 aCtx->Remove (aLightSourceDel, false);
10058 aMap.UnBind1 (aLightSourceDel);
10060 aViewer->DelLight (aLight);
10061 aLightIter = aView->ActiveLightIterator();
10065 aLightOld.Nullify();
10066 aLightNew.Nullify();
10067 aLightPrs.Nullify();
10069 else if (!aLightNew.IsNull()
10070 && (anArgCase == "-display"
10071 || anArgCase == "-disp"
10072 || anArgCase == "-presentation"
10073 || anArgCase == "-prs"))
10075 TCollection_AsciiString aLightName = aLightNew->Name();
10076 if (anArgIt + 1 < theArgsNb
10077 && theArgVec[anArgIt + 1][0] != '-')
10080 aLightName = theArgVec[++anArgIt];
10081 if (aLightNew->Name() != aLightName)
10083 if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
10085 theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
10088 aLightNew->SetName (aLightName);
10091 if (aLightName.IsEmpty())
10093 Message::SendFail() << "Error: nameless light source cannot be displayed";
10096 if (aLightPrs.IsNull())
10098 aLightPrs = new AIS_LightSource (aLightNew);
10100 theDi << aLightName << " ";
10102 else if (!aLightNew.IsNull()
10103 && (anArgCase == "-disable"
10104 || anArgCase == "-disabled"
10105 || anArgCase == "-enable"
10106 || anArgCase == "-enabled"))
10108 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10109 if (anArgCase == "-disable"
10110 || anArgCase == "-disabled")
10112 toEnable = !toEnable;
10114 aLightNew->SetEnabled (toEnable);
10116 else if (!aLightNew.IsNull()
10117 && (anArgCase == "-color"
10118 || anArgCase == "-colour"
10119 || anArgCase == "color"))
10121 Quantity_Color aColor;
10122 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10123 theArgVec + anArgIt + 1,
10125 anArgIt += aNbParsed;
10126 if (aNbParsed == 0)
10128 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10131 aLightNew->SetColor (aColor);
10133 else if (!aLightNew.IsNull()
10134 && (anArgCase == "-pos"
10135 || anArgCase == "-position"
10136 || anArgCase == "-prsposition"
10137 || anArgCase == "-prspos"
10138 || anArgCase == "pos"
10139 || anArgCase == "position")
10140 && (anArgIt + 3) < theArgsNb)
10143 if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
10145 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10150 if (anArgCase == "-prsposition"
10151 || anArgCase == "-prspos")
10153 aLightNew->SetDisplayPosition (aPosXYZ);
10157 if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
10158 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
10160 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10164 aLightNew->SetPosition (aPosXYZ);
10167 else if (!aLightNew.IsNull()
10168 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
10169 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10170 && (anArgCase == "-dir"
10171 || anArgCase == "-direction")
10172 && (anArgIt + 3) < theArgsNb)
10175 if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
10177 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10182 aLightNew->SetDirection (gp_Dir (aDirXYZ));
10184 else if (!aLightNew.IsNull()
10185 && (anArgCase == "-smoothangle"
10186 || anArgCase == "-smoothradius"
10187 || anArgCase == "-sm"
10188 || anArgCase == "-smoothness")
10189 && anArgIt + 1 < theArgsNb)
10191 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10192 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10194 aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
10196 if (Abs (aSmoothness) <= ShortRealEpsilon())
10198 aLightNew->SetIntensity (1.f);
10200 else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
10202 aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10206 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
10207 aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10210 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10212 aLightNew->SetSmoothRadius (aSmoothness);
10214 else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10216 aLightNew->SetSmoothAngle (aSmoothness);
10219 else if (!aLightNew.IsNull()
10220 && (anArgCase == "-int"
10221 || anArgCase == "-intensity")
10222 && anArgIt + 1 < theArgsNb)
10224 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10225 aLightNew->SetIntensity (aIntensity);
10227 else if (!aLightNew.IsNull()
10228 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10229 && (anArgCase == "-spotangle"
10230 || anArgCase == "-ang"
10231 || anArgCase == "-angle")
10232 && anArgIt + 1 < theArgsNb)
10234 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10235 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10236 aLightNew->SetAngle (anAngle);
10238 else if (!aLightNew.IsNull()
10239 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10240 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10241 && (anArgCase == "-constatten"
10242 || anArgCase == "-constattenuation")
10243 && anArgIt + 1 < theArgsNb)
10245 const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10246 aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
10248 else if (!aLightNew.IsNull()
10249 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10250 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10251 && (anArgCase == "-linatten"
10252 || anArgCase == "-linearatten"
10253 || anArgCase == "-linearattenuation")
10254 && anArgIt + 1 < theArgsNb)
10256 const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10257 aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
10259 else if (!aLightNew.IsNull()
10260 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10261 && (anArgCase == "-spotexp"
10262 || anArgCase == "-spotexponent"
10263 || anArgCase == "-exp"
10264 || anArgCase == "-exponent")
10265 && anArgIt + 1 < theArgsNb)
10267 aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
10269 else if (!aLightNew.IsNull()
10270 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10271 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
10272 && anArgCase == "-range"
10273 && anArgIt + 1 < theArgsNb)
10275 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
10276 aLightNew->SetRange (aRange);
10278 else if (!aLightNew.IsNull()
10279 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10280 && (anArgCase == "-head"
10281 || anArgCase == "-headlight"))
10283 Standard_Boolean isHeadLight = Standard_True;
10284 if (anArgIt + 1 < theArgsNb
10285 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
10289 aLightNew->SetHeadlight (isHeadLight);
10291 else if (!aLightNew.IsNull()
10292 && anArgCase == "-name"
10293 && anArgIt + 1 < theArgsNb)
10295 const TCollection_AsciiString aName = theArgVec[++anArgIt];
10296 if (aLightNew->Name() == aName)
10301 if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
10303 theDi << "Syntax error: light with name '" << aName << "' is already defined";
10306 aLightNew->SetName (aName);
10308 else if (!aLightPrs.IsNull()
10309 && (anArgCase == "-showzoomable"
10310 || anArgCase == "-prszoomable"
10311 || anArgCase == "-zoomable"))
10313 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10314 aLightPrs->SetZoomable (isZoomable);
10316 else if (!aLightPrs.IsNull()
10317 && (anArgCase == "-showdraggable"
10318 || anArgCase == "-prsdraggable"
10319 || anArgCase == "-draggable"))
10321 const bool isDraggable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10322 aLightPrs->SetDraggable (isDraggable);
10324 else if (!aLightPrs.IsNull()
10325 && (anArgCase == "-showname"
10326 || anArgCase == "-prsname"))
10328 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10329 aLightPrs->SetDisplayName (toDisplay);
10331 else if (!aLightPrs.IsNull()
10332 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10333 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10334 && (anArgCase == "-showrange"
10335 || anArgCase == "-prsrange"))
10337 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10338 aLightPrs->SetDisplayRange (toDisplay);
10340 else if (!aLightPrs.IsNull()
10341 && (anArgCase == "-showsize"
10342 || anArgCase == "-prssize")
10343 && anArgIt + 1 < theArgsNb)
10345 Standard_Real aSize = 0.0;
10346 if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
10348 || aLightPrs.IsNull())
10350 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10354 aLightPrs->SetSize (aSize);
10356 else if (!aLightPrs.IsNull()
10357 && (anArgCase == "-dirarcsize"
10358 || anArgCase == "-arcsize"
10359 || anArgCase == "-arc")
10360 && anArgIt + 1 < theArgsNb)
10362 Standard_Integer aSize = 0;
10363 if (!Draw::ParseInteger (theArgVec[anArgIt + 1], aSize)
10365 || aLightPrs->Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
10367 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10371 aLightPrs->SetArcSize (aSize);
10373 else if (!aLightNew.IsNull()
10374 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10375 && (anArgCase == "-castshadow"
10376 || anArgCase == "-castshadows"
10377 || anArgCase == "-shadows"))
10379 bool toCastShadows = true;
10380 if (anArgIt + 1 < theArgsNb
10381 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
10385 aLightNew->SetCastShadows (toCastShadows);
10387 else if (anArgCase == "-del"
10388 || anArgCase == "-delete"
10389 || anArgCase == "-remove"
10390 || anArgCase == "del"
10391 || anArgCase == "delete"
10392 || anArgCase == "remove")
10394 if (aLightOld.IsNull())
10396 if (!aLightNew.IsNull())
10398 aLightNew.Nullify();
10402 if (++anArgIt >= theArgsNb)
10404 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10408 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10409 aLightOld = findLightSource (anOldName);
10410 if (aLightOld.IsNull())
10412 Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
10417 aLightNew.Nullify();
10418 aLightPrs.Nullify();
10420 else if (anArgCase == "-change"
10421 || anArgCase == "change")
10423 // just skip old syntax
10425 else if (aLightNew.IsNull()
10426 && !anArgCase.StartsWith ("-"))
10428 if (!aLightNew.IsNull())
10433 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10434 aLightOld = findLightSource (anOldName);
10435 if (!aLightOld.IsNull())
10437 aLightNew = aLightOld;
10439 Handle(AIS_InteractiveObject) aPrsObject;
10440 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10441 aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
10445 Standard_Integer aLightIndex = -1;
10446 Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
10447 if (aLightIndex != -1)
10449 Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
10453 aLightNew = new V3d_AmbientLight();
10454 aLightNew->SetName (anOldName);
10459 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
10464 // delete old light source
10465 if (!aLightOld.IsNull()
10466 && aLightOld != aLightNew)
10468 TColStd_SequenceOfInteger aLayers;
10469 aViewer->GetAllZLayers (aLayers);
10470 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
10472 if (aLayerIter.Value() == aLayer
10473 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10475 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
10476 if (!aSettings.Lights().IsNull())
10478 aSettings.Lights()->Remove (aLightOld);
10479 if (aSettings.Lights()->IsEmpty())
10481 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10484 aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
10485 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10492 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10494 Handle(AIS_InteractiveObject) aPrsObject;
10495 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10496 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10498 aCtx->Remove (aLightSourceDel, false);
10499 GetMapOfAIS().UnBind1 (aLightSourceDel);
10501 aViewer->DelLight (aLightOld);
10503 aLightOld.Nullify();
10506 // add new light source
10507 if (!aLightNew.IsNull())
10509 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10511 aViewer->AddLight (aLightNew);
10514 aViewer->SetLightOn (aLightNew);
10518 aView->SetLightOn (aLightNew);
10523 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
10524 if (aSettings.Lights().IsNull())
10526 aSettings.SetLights (new Graphic3d_LightSet());
10528 aSettings.Lights()->Add (aLightNew);
10529 aViewer->SetZLayerSettings (aLayer, aSettings);
10532 if (!aLightPrs.IsNull())
10534 aLightPrs->SetLight (aLightNew);
10535 ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
10539 // manage presentations
10540 struct LightPrsSort
10542 bool operator() (const Handle(AIS_LightSource)& theLeft,
10543 const Handle(AIS_LightSource)& theRight)
10545 return theLeft->Light()->GetId() < theRight->Light()->GetId();
10549 AIS_ListOfInteractive aPrsList;
10550 aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
10551 if (!aPrsList.IsEmpty())
10553 // update light source presentations
10554 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
10555 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
10557 if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
10559 aLightPrsVec.push_back (aLightPrs2);
10563 // sort objects by id as AIS_InteractiveContext stores them in unordered map
10564 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
10566 Standard_Integer aTopStack = 0;
10567 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
10569 Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
10570 if (!aLightPrs2->TransformPersistence().IsNull()
10571 && aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
10573 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
10574 aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
10575 aTopStack += aPrsSize + aPrsSize / 2;
10577 aCtx->Redisplay (aLightPrs2, false);
10578 aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
10584 //===============================================================================================
10585 //function : VPBREnvironment
10587 //===============================================================================================
10588 static int VPBREnvironment (Draw_Interpretor&,
10589 Standard_Integer theArgsNb,
10590 const char** theArgVec)
10594 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
10598 Handle(V3d_View) aView = ViewerTest::CurrentView();
10599 if (aView.IsNull())
10601 Message::SendFail ("Error: no active viewer");
10605 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
10608 if (anArg == "-generate"
10609 || anArg == "-gen")
10611 aView->GeneratePBREnvironment (Standard_True);
10613 else if (anArg == "-clear")
10615 aView->ClearPBREnvironment (Standard_True);
10619 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
10626 //! Read Graphic3d_RenderingParams::PerfCounters flag.
10627 static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
10628 Standard_Boolean& theToReset,
10629 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
10630 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
10632 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
10633 TCollection_AsciiString aVal = theValue;
10634 Standard_Boolean toReverse = Standard_False;
10635 if (aVal == "none")
10637 theToReset = Standard_True;
10638 return Standard_True;
10640 else if (aVal.StartsWith ("-"))
10642 toReverse = Standard_True;
10643 aVal = aVal.SubString (2, aVal.Length());
10645 else if (aVal.StartsWith ("no"))
10647 toReverse = Standard_True;
10648 aVal = aVal.SubString (3, aVal.Length());
10650 else if (aVal.StartsWith ("+"))
10652 aVal = aVal.SubString (2, aVal.Length());
10656 theToReset = Standard_True;
10660 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
10661 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
10662 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
10663 else if (aVal == "structs"
10664 || aVal == "structures"
10665 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
10666 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
10667 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
10668 else if (aVal == "tris"
10669 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
10670 else if (aVal == "pnts"
10671 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
10672 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
10673 else if (aVal == "mem"
10674 || aVal == "gpumem"
10675 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
10676 else if (aVal == "skipimmediate"
10677 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
10678 else if (aVal == "frametime"
10679 || aVal == "frametimers"
10680 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
10681 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
10682 else if (aVal == "extended"
10683 || aVal == "verbose"
10684 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
10685 else if (aVal == "full"
10686 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
10689 return Standard_False;
10694 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
10698 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
10700 return Standard_True;
10703 //! Read Graphic3d_RenderingParams::PerfCounters flags.
10704 static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
10705 Graphic3d_RenderingParams::PerfCounters& theFlags)
10707 TCollection_AsciiString aValue = theValue;
10708 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
10709 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
10710 Standard_Boolean toReset = Standard_False;
10713 Standard_Integer aSplitPos = aValue.Search ("|");
10714 if (aSplitPos <= 0)
10716 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
10718 return Standard_False;
10722 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
10724 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
10725 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
10726 return Standard_True;
10731 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
10732 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
10734 return Standard_False;
10737 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
10741 //=======================================================================
10742 //function : VRenderParams
10743 //purpose : Enables/disables rendering features
10744 //=======================================================================
10746 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
10747 Standard_Integer theArgNb,
10748 const char** theArgVec)
10750 Handle(V3d_View) aView = ViewerTest::CurrentView();
10751 if (aView.IsNull())
10753 Message::SendFail ("Error: no active viewer");
10757 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
10758 TCollection_AsciiString aCmdName (theArgVec[0]);
10759 aCmdName.LowerCase();
10760 if (aCmdName == "vraytrace")
10764 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
10767 else if (theArgNb == 2)
10769 TCollection_AsciiString aValue (theArgVec[1]);
10770 aValue.LowerCase();
10774 aParams.Method = Graphic3d_RM_RAYTRACING;
10778 else if (aValue == "off"
10781 aParams.Method = Graphic3d_RM_RASTERIZATION;
10787 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
10793 Message::SendFail ("Syntax error: wrong number of arguments");
10800 theDI << "renderMode: ";
10801 switch (aParams.Method)
10803 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
10804 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
10807 theDI << "transparency: ";
10808 switch (aParams.TransparencyMethod)
10810 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
10811 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
10812 << TCollection_AsciiString (aParams.OitDepthFactor); break;
10813 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
10814 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
10817 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
10818 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
10819 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
10820 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
10821 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
10822 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
10823 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
10824 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
10825 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
10826 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
10827 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
10828 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
10829 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
10830 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
10831 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
10832 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
10833 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
10834 theDI << "shadingModel: ";
10835 switch (aView->ShadingModel())
10837 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
10838 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit"; break;
10839 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat"; break;
10840 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud"; break;
10841 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong"; break;
10842 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
10843 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
10847 theDI << "perfCounters:";
10848 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
10852 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
10856 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
10858 theDI << " structs";
10860 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
10862 theDI << " groups";
10864 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
10866 theDI << " arrays";
10868 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
10872 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
10876 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
10880 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
10882 theDI << " gpumem";
10884 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
10886 theDI << " frameTime";
10888 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
10890 theDI << " skipimmediate";
10892 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
10898 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
10899 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
10900 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
10901 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
10902 "noUpdate") << "\n";
10907 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
10908 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10909 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10911 Standard_CString anArg (theArgVec[anArgIter]);
10912 TCollection_AsciiString aFlag (anArg);
10914 if (anUpdateTool.parseRedrawMode (aFlag))
10918 else if (aFlag == "-echo"
10919 || aFlag == "-print")
10921 toPrint = Standard_True;
10922 anUpdateTool.Invalidate();
10924 else if (aFlag == "-reset")
10926 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
10928 else if (aFlag == "-sync"
10929 && (anArgIter + 1 < theArgNb))
10931 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
10932 aSyncFlag.LowerCase();
10933 if (aSyncFlag == "default"
10934 || aSyncFlag == "defaults"
10935 || aSyncFlag == "viewer")
10937 toSyncDefaults = true;
10939 else if (aSyncFlag == "allviews"
10940 || aSyncFlag == "views")
10942 toSyncAllViews = true;
10946 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
10950 else if (aFlag == "-mode"
10951 || aFlag == "-rendermode"
10952 || aFlag == "-render_mode")
10956 switch (aParams.Method)
10958 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
10959 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
10965 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10969 else if (aFlag == "-ray"
10970 || aFlag == "-raytrace")
10974 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
10978 bool isRayTrace = true;
10979 if (anArgIter + 1 < theArgNb
10980 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
10984 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
10986 else if (aFlag == "-rast"
10987 || aFlag == "-raster"
10988 || aFlag == "-rasterization")
10992 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
10996 bool isRaster = true;
10997 if (anArgIter + 1 < theArgNb
10998 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
11002 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
11004 else if (aFlag == "-msaa")
11008 theDI << aParams.NbMsaaSamples << " ";
11011 else if (++anArgIter >= theArgNb)
11013 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11017 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11018 if (aNbSamples < 0)
11020 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
11025 aParams.NbMsaaSamples = aNbSamples;
11028 else if (aFlag == "-linefeather"
11029 || aFlag == "-edgefeather"
11030 || aFlag == "-feather")
11034 theDI << " " << aParams.LineFeather << " ";
11037 else if (++anArgIter >= theArgNb)
11039 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11043 TCollection_AsciiString aParam = theArgVec[anArgIter];
11044 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11045 if (aFeather <= 0.0f)
11047 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
11050 aParams.LineFeather = aFeather;
11052 else if (aFlag == "-oit")
11056 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11058 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11060 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11062 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11066 theDI << "off" << " ";
11070 else if (++anArgIter >= theArgNb)
11072 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11076 TCollection_AsciiString aParam = theArgVec[anArgIter];
11077 aParam.LowerCase();
11078 if (aParam == "peeling"
11079 || aParam == "peel")
11081 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11082 if (anArgIter + 1 < theArgNb
11083 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11086 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11089 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11092 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11095 else if (aParam == "weighted"
11096 || aParam == "weight")
11098 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11099 if (anArgIter + 1 < theArgNb
11100 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11103 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11104 if (aWeight < 0.f || aWeight > 1.f)
11106 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11109 aParams.OitDepthFactor = aWeight;
11112 else if (aParam.IsRealValue())
11114 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11115 if (aWeight < 0.f || aWeight > 1.f)
11117 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11121 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11122 aParams.OitDepthFactor = aWeight;
11124 else if (aParam == "off")
11126 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11130 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11134 else if (aFlag == "-fonthinting"
11135 || aFlag == "-fonthint")
11139 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11141 theDI << "normal" << " ";
11143 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11145 theDI << "light" << " ";
11149 theDI << "off" << " ";
11153 else if (anArgIter + 1 >= theArgNb)
11155 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11159 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11160 aHintStyle.LowerCase();
11161 if (aHintStyle == "normal"
11162 || aHintStyle == "on"
11163 || aHintStyle == "1")
11165 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11166 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11168 else if (aHintStyle == "light")
11170 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11171 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11173 else if (aHintStyle == "no"
11174 || aHintStyle == "off"
11175 || aHintStyle == "0")
11177 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11178 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11182 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11186 else if (aFlag == "-fontautohinting"
11187 || aFlag == "-fontautohint")
11191 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11193 theDI << "force" << " ";
11195 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11197 theDI << "disallow" << " ";
11201 theDI << "auto" << " ";
11205 else if (anArgIter + 1 >= theArgNb)
11207 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11211 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11212 aHintStyle.LowerCase();
11213 if (aHintStyle == "force")
11215 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11216 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11218 else if (aHintStyle == "disallow"
11219 || aHintStyle == "no")
11221 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11222 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11224 else if (aHintStyle == "auto")
11226 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11227 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11231 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11235 else if (aFlag == "-depthprepass")
11239 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11242 aParams.ToEnableDepthPrepass = Standard_True;
11243 if (anArgIter + 1 < theArgNb
11244 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
11249 else if (aFlag == "-samplealphatocoverage"
11250 || aFlag == "-alphatocoverage")
11254 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11257 aParams.ToEnableAlphaToCoverage = Standard_True;
11258 if (anArgIter + 1 < theArgNb
11259 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
11264 else if (aFlag == "-rendscale"
11265 || aFlag == "-renderscale"
11266 || aFlag == "-renderresolutionscale")
11270 theDI << aParams.RenderResolutionScale << " ";
11273 else if (++anArgIter >= theArgNb)
11275 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11279 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11282 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
11287 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11290 else if (aFlag == "-raydepth"
11291 || aFlag == "-ray_depth")
11295 theDI << aParams.RaytracingDepth << " ";
11298 else if (++anArgIter >= theArgNb)
11300 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11304 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
11306 // We allow RaytracingDepth be more than 10 in case of GI enabled
11307 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
11309 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
11314 aParams.RaytracingDepth = aDepth;
11317 else if (aFlag == "-shad"
11318 || aFlag == "-shadows")
11322 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11326 Standard_Boolean toEnable = Standard_True;
11327 if (++anArgIter < theArgNb
11328 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11332 aParams.IsShadowEnabled = toEnable;
11334 else if (aFlag == "-shadowmapresolution"
11335 || aFlag == "-shadowmap")
11339 theDI << aParams.ShadowMapResolution << " ";
11342 else if (++anArgIter >= theArgNb)
11344 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11348 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11350 else if (aFlag == "-shadowmapbias")
11354 theDI << aParams.ShadowMapBias << " ";
11357 else if (++anArgIter >= theArgNb)
11359 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11363 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11365 else if (aFlag == "-refl"
11366 || aFlag == "-reflections")
11370 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11374 Standard_Boolean toEnable = Standard_True;
11375 if (++anArgIter < theArgNb
11376 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11380 aParams.IsReflectionEnabled = toEnable;
11382 else if (aFlag == "-fsaa")
11386 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11390 Standard_Boolean toEnable = Standard_True;
11391 if (++anArgIter < theArgNb
11392 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11396 aParams.IsAntialiasingEnabled = toEnable;
11398 else if (aFlag == "-gleam")
11402 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11406 Standard_Boolean toEnable = Standard_True;
11407 if (++anArgIter < theArgNb
11408 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11412 aParams.IsTransparentShadowEnabled = toEnable;
11414 else if (aFlag == "-gi")
11418 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11422 Standard_Boolean toEnable = Standard_True;
11423 if (++anArgIter < theArgNb
11424 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11428 aParams.IsGlobalIlluminationEnabled = toEnable;
11431 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11434 else if (aFlag == "-blockedrng"
11435 || aFlag == "-brng")
11439 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11443 Standard_Boolean toEnable = Standard_True;
11444 if (++anArgIter < theArgNb
11445 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11449 aParams.CoherentPathTracingMode = toEnable;
11451 else if (aFlag == "-maxrad")
11455 theDI << aParams.RadianceClampingValue << " ";
11458 else if (++anArgIter >= theArgNb)
11460 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11464 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11465 if (!aMaxRadStr.IsRealValue (Standard_True))
11467 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11471 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11472 if (aMaxRadiance <= 0.0)
11474 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
11479 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11482 else if (aFlag == "-iss")
11486 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11490 Standard_Boolean toEnable = Standard_True;
11491 if (++anArgIter < theArgNb
11492 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11496 aParams.AdaptiveScreenSampling = toEnable;
11498 else if (aFlag == "-issatomic")
11502 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
11506 Standard_Boolean toEnable = Standard_True;
11507 if (++anArgIter < theArgNb
11508 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11512 aParams.AdaptiveScreenSamplingAtomic = toEnable;
11514 else if (aFlag == "-issd")
11518 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
11522 Standard_Boolean toEnable = Standard_True;
11523 if (++anArgIter < theArgNb
11524 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11528 aParams.ShowSamplingTiles = toEnable;
11530 else if (aFlag == "-tilesize")
11534 theDI << aParams.RayTracingTileSize << " ";
11537 else if (++anArgIter >= theArgNb)
11539 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11543 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
11546 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
11549 aParams.RayTracingTileSize = aTileSize;
11551 else if (aFlag == "-nbtiles")
11555 theDI << aParams.NbRayTracingTiles << " ";
11558 else if (++anArgIter >= theArgNb)
11560 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11564 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
11567 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
11570 else if (aNbTiles > 0
11572 || aNbTiles > 1024))
11574 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
11576 aParams.NbRayTracingTiles = aNbTiles;
11578 else if (aFlag == "-env")
11582 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
11586 Standard_Boolean toEnable = Standard_True;
11587 if (++anArgIter < theArgNb
11588 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11592 aParams.UseEnvironmentMapBackground = toEnable;
11594 else if (aFlag == "-ignorenormalmap")
11598 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
11602 Standard_Boolean toEnable = Standard_True;
11603 if (++anArgIter < theArgNb
11604 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11608 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
11610 else if (aFlag == "-twoside")
11614 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
11618 Standard_Boolean toEnable = Standard_True;
11619 if (++anArgIter < theArgNb
11620 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11624 aParams.TwoSidedBsdfModels = toEnable;
11626 else if (aFlag == "-shademodel"
11627 || aFlag == "-shadingmodel"
11628 || aFlag == "-shading")
11632 switch (aView->ShadingModel())
11634 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
11635 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit "; break;
11636 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat "; break;
11637 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud "; break;
11638 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong "; break;
11639 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
11640 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
11645 if (++anArgIter >= theArgNb)
11647 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11650 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TypeOfShadingModel_DEFAULT;
11651 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
11652 && aModel != Graphic3d_TypeOfShadingModel_DEFAULT)
11654 aView->SetShadingModel (aModel);
11658 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
11662 else if (aFlag == "-pbrenvpow2size"
11663 || aFlag == "-pbrenvp2s"
11664 || aFlag == "-pep2s")
11666 if (++anArgIter >= theArgNb)
11668 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11672 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
11673 if (aPbrEnvPow2Size < 1)
11675 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
11678 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
11680 else if (aFlag == "-pbrenvspecmaplevelsnumber"
11681 || aFlag == "-pbrenvspecmapnblevels"
11682 || aFlag == "-pbrenvspecmaplevels"
11683 || aFlag == "-pbrenvsmln"
11684 || aFlag == "-pesmln")
11686 if (++anArgIter >= theArgNb)
11688 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11692 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
11693 if (aPbrEnvSpecMapNbLevels < 2)
11695 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
11698 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
11700 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
11701 || aFlag == "-pbrenvbakingdiffsamples"
11702 || aFlag == "-pbrenvbdsn")
11704 if (++anArgIter >= theArgNb)
11706 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11710 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11711 if (aPbrEnvBakingDiffNbSamples < 1)
11713 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
11716 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
11718 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
11719 || aFlag == "-pbrenvbakingspecsamples"
11720 || aFlag == "-pbrenvbssn")
11722 if (++anArgIter >= theArgNb)
11724 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11728 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
11729 if (aPbrEnvBakingSpecNbSamples < 1)
11731 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
11734 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
11736 else if (aFlag == "-pbrenvbakingprobability"
11737 || aFlag == "-pbrenvbp")
11739 if (++anArgIter >= theArgNb)
11741 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11744 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
11745 if (aPbrEnvBakingProbability < 0.f
11746 || aPbrEnvBakingProbability > 1.f)
11748 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
11751 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
11753 else if (aFlag == "-resolution")
11755 if (++anArgIter >= theArgNb)
11757 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11761 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
11762 if (aResolution.IsIntegerValue())
11764 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
11768 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
11772 else if (aFlag == "-rebuildglsl"
11773 || aFlag == "-rebuild")
11777 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
11781 Standard_Boolean toEnable = Standard_True;
11782 if (++anArgIter < theArgNb
11783 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11787 aParams.RebuildRayTracingShaders = toEnable;
11789 else if (aFlag == "-focal")
11791 if (++anArgIter >= theArgNb)
11793 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11797 TCollection_AsciiString aParam (theArgVec[anArgIter]);
11798 if (aParam.IsRealValue (Standard_True))
11800 float aFocalDist = static_cast<float> (aParam.RealValue());
11801 if (aFocalDist < 0)
11803 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11806 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
11810 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11814 else if (aFlag == "-aperture")
11816 if (++anArgIter >= theArgNb)
11818 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11822 TCollection_AsciiString aParam(theArgVec[anArgIter]);
11823 if (aParam.IsRealValue (Standard_True))
11825 float aApertureSize = static_cast<float> (aParam.RealValue());
11826 if (aApertureSize < 0)
11828 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11831 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
11835 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11839 else if (aFlag == "-exposure")
11841 if (++anArgIter >= theArgNb)
11843 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11847 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
11848 if (anExposure.IsRealValue (Standard_True))
11850 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
11854 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11858 else if (aFlag == "-whitepoint")
11860 if (++anArgIter >= theArgNb)
11862 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11866 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
11867 if (aWhitePoint.IsRealValue (Standard_True))
11869 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
11873 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11877 else if (aFlag == "-tonemapping")
11879 if (++anArgIter >= theArgNb)
11881 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11885 TCollection_AsciiString aMode (theArgVec[anArgIter]);
11888 if (aMode == "disabled")
11890 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
11892 else if (aMode == "filmic")
11894 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
11898 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11902 else if (aFlag == "-performancestats"
11903 || aFlag == "-performancecounters"
11904 || aFlag == "-perfstats"
11905 || aFlag == "-perfcounters"
11906 || aFlag == "-stats")
11908 if (++anArgIter >= theArgNb)
11910 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11914 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
11915 aFlagsStr.LowerCase();
11916 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
11917 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
11919 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11922 aView->ChangeRenderingParams().CollectedStats = aFlags;
11923 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
11925 else if (aFlag == "-perfupdateinterval"
11926 || aFlag == "-statsupdateinterval")
11928 if (++anArgIter >= theArgNb)
11930 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11933 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
11935 else if (aFlag == "-perfchart"
11936 || aFlag == "-statschart")
11938 if (++anArgIter >= theArgNb)
11940 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11943 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
11945 else if (aFlag == "-perfchartmax"
11946 || aFlag == "-statschartmax")
11948 if (++anArgIter >= theArgNb)
11950 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11953 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
11955 else if (aFlag == "-frustumculling"
11956 || aFlag == "-culling")
11960 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
11961 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
11962 "noUpdate") << " ";
11966 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
11967 if (++anArgIter < theArgNb)
11969 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
11970 aStateStr.LowerCase();
11971 bool toEnable = true;
11972 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
11974 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
11976 else if (aStateStr == "noupdate"
11977 || aStateStr == "freeze")
11979 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
11986 aParams.FrustumCullingState = aState;
11990 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
11995 // set current view parameters as defaults
11996 if (toSyncDefaults)
11998 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12000 if (toSyncAllViews)
12002 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12004 aViewIter.Value()->ChangeRenderingParams() = aParams;
12010 //=======================================================================
12011 //function : searchInfo
12013 //=======================================================================
12014 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12015 const TCollection_AsciiString& theKey)
12017 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12019 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12021 return anIter.Value();
12024 return TCollection_AsciiString();
12027 //=======================================================================
12028 //function : VStatProfiler
12030 //=======================================================================
12031 static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12032 Standard_Integer theArgNb,
12033 const char** theArgVec)
12035 Handle(V3d_View) aView = ViewerTest::CurrentView();
12036 if (aView.IsNull())
12038 Message::SendFail ("Error: no active viewer");
12042 Standard_Boolean toRedraw = Standard_True;
12043 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12044 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12045 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12046 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12048 Standard_CString anArg (theArgVec[anArgIter]);
12049 TCollection_AsciiString aFlag (anArg);
12051 if (aFlag == "-noredraw")
12053 toRedraw = Standard_False;
12057 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12058 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12059 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12060 else if (aFlag == "alllayers"
12061 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12062 else if (aFlag == "allstructs"
12063 || aFlag == "allstructures"
12064 || aFlag == "structs"
12065 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
12066 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12067 else if (aFlag == "allarrays"
12068 || aFlag == "fillarrays"
12069 || aFlag == "linearrays"
12070 || aFlag == "pointarrays"
12071 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12072 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
12073 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
12074 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12075 else if (aFlag == "geommem"
12076 || aFlag == "texturemem"
12077 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12078 else if (aFlag == "elapsedframe"
12079 || aFlag == "cpuframeaverage"
12080 || aFlag == "cpupickingaverage"
12081 || aFlag == "cpucullingaverage"
12082 || aFlag == "cpudynaverage"
12083 || aFlag == "cpuframemax"
12084 || aFlag == "cpupickingmax"
12085 || aFlag == "cpucullingmax"
12086 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12089 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
12093 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12097 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12099 aView->ChangeRenderingParams().CollectedStats =
12100 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12104 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12106 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12109 TColStd_IndexedDataMapOfStringString aDict;
12110 aView->StatisticInformation (aDict);
12112 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12114 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12116 Standard_CString anArg(theArgVec[anArgIter]);
12117 TCollection_AsciiString aFlag(anArg);
12119 if (aFlag == "fps")
12121 theDI << searchInfo (aDict, "FPS") << " ";
12123 else if (aFlag == "cpu")
12125 theDI << searchInfo (aDict, "CPU FPS") << " ";
12127 else if (aFlag == "alllayers")
12129 theDI << searchInfo (aDict, "Layers") << " ";
12131 else if (aFlag == "layers")
12133 theDI << searchInfo (aDict, "Rendered layers") << " ";
12135 else if (aFlag == "allstructs"
12136 || aFlag == "allstructures")
12138 theDI << searchInfo (aDict, "Structs") << " ";
12140 else if (aFlag == "structs"
12141 || aFlag == "structures")
12143 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12144 if (aRend.IsEmpty()) // all structures rendered
12146 aRend = searchInfo (aDict, "Structs");
12148 theDI << aRend << " ";
12150 else if (aFlag == "groups")
12152 theDI << searchInfo (aDict, "Rendered groups") << " ";
12154 else if (aFlag == "allarrays")
12156 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12158 else if (aFlag == "fillarrays")
12160 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12162 else if (aFlag == "linearrays")
12164 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12166 else if (aFlag == "pointarrays")
12168 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12170 else if (aFlag == "textarrays")
12172 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12174 else if (aFlag == "triangles")
12176 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12178 else if (aFlag == "points")
12180 theDI << searchInfo (aDict, "Rendered points") << " ";
12182 else if (aFlag == "geommem")
12184 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12186 else if (aFlag == "texturemem")
12188 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12190 else if (aFlag == "framemem")
12192 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12194 else if (aFlag == "elapsedframe")
12196 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12198 else if (aFlag == "cpuframe_average")
12200 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12202 else if (aFlag == "cpupicking_average")
12204 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12206 else if (aFlag == "cpuculling_average")
12208 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12210 else if (aFlag == "cpudyn_average")
12212 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12214 else if (aFlag == "cpuframe_max")
12216 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12218 else if (aFlag == "cpupicking_max")
12220 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12222 else if (aFlag == "cpuculling_max")
12224 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12226 else if (aFlag == "cpudyn_max")
12228 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12236 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12238 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12240 theDI << "Statistic info:\n" << aView->StatisticInformation();
12245 //=======================================================================
12246 //function : VXRotate
12248 //=======================================================================
12249 static Standard_Integer VXRotate (Draw_Interpretor& di,
12250 Standard_Integer argc,
12251 const char ** argv)
12253 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12254 if (aContext.IsNull())
12256 di << argv[0] << "ERROR : use 'vinit' command before \n";
12262 di << "ERROR : Usage : " << argv[0] << " name angle\n";
12266 TCollection_AsciiString aName (argv[1]);
12267 Standard_Real anAngle = Draw::Atof (argv[2]);
12270 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12271 Handle(AIS_InteractiveObject) anIObj;
12272 if (!aMap.Find2 (aName, anIObj))
12274 di << "Use 'vdisplay' before\n";
12278 gp_Trsf aTransform;
12279 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12280 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
12282 aContext->SetLocation (anIObj, aTransform);
12283 aContext->UpdateCurrentViewer();
12289 //! Structure for setting AIS_Manipulator::SetPart() property.
12290 struct ManipAxisModeOnOff
12292 Standard_Integer Axis;
12293 AIS_ManipulatorMode Mode;
12294 Standard_Boolean ToEnable;
12296 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12299 enum ManipAjustPosition
12301 ManipAjustPosition_Off,
12302 ManipAjustPosition_Center,
12303 ManipAjustPosition_Location,
12304 ManipAjustPosition_ShapeLocation,
12308 //===============================================================================================
12309 //function : VManipulator
12311 //===============================================================================================
12312 static int VManipulator (Draw_Interpretor& theDi,
12313 Standard_Integer theArgsNb,
12314 const char** theArgVec)
12316 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
12317 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12318 if (aCurrentView.IsNull()
12319 || aViewer.IsNull())
12321 Message::SendFail ("Error: no active viewer");
12325 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12326 Standard_Integer anArgIter = 1;
12327 Handle(AIS_Manipulator) aManipulator;
12328 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12329 TCollection_AsciiString aName;
12331 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12332 Standard_Real aGap = -1.0, aSize = -1.0;
12333 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12334 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12336 bool toDetach = false;
12337 AIS_Manipulator::OptionsForAttach anAttachOptions;
12338 Handle(AIS_InteractiveObject) anAttachObject;
12339 Handle(V3d_View) aViewAffinity;
12340 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12342 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12343 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12344 Standard_Integer toStopMouseTransform = -1;
12345 // explicit transformation
12348 Standard_Real aTmpReal = 0.0;
12349 gp_XYZ aRotPnt, aRotAxis;
12350 for (; anArgIter < theArgsNb; ++anArgIter)
12352 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12354 if (anUpdateTool.parseRedrawMode (anArg))
12358 else if (anArg == "-help")
12360 theDi.PrintHelp (theArgVec[0]);
12364 else if (anArg == "-autoactivate"
12365 || anArg == "-noautoactivate")
12367 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12369 else if (anArg == "-followtranslation"
12370 || anArg == "-nofollowtranslation")
12372 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12374 else if (anArg == "-followrotation"
12375 || anArg == "-nofollowrotation")
12377 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12379 else if (anArg == "-followdragging"
12380 || anArg == "-nofollowdragging")
12382 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12384 else if (anArg == "-gap"
12385 && anArgIter + 1 < theArgsNb
12386 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12391 else if (anArg == "-size"
12392 && anArgIter + 1 < theArgsNb
12393 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12398 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12399 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12401 ManipAxisModeOnOff aPart;
12402 Standard_Integer aMode = 0;
12403 if (anArg == "-part")
12405 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12406 || aPart.Axis < 0 || aPart.Axis > 3)
12408 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12412 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12413 || aMode < 1 || aMode > 4)
12415 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12418 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12420 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12423 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12424 aParts.Append (aPart);
12426 else if (anArg == "-pos"
12427 && anArgIter + 3 < theArgsNb
12428 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12431 if (anArgIter + 3 < theArgsNb
12432 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12433 && aVDir.Modulus() > Precision::Confusion())
12437 if (anArgIter + 3 < theArgsNb
12438 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12439 && anXDir.Modulus() > Precision::Confusion())
12444 else if (anArg == "-zoomable"
12445 || anArg == "-notzoomable")
12447 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12450 else if (anArg == "-adjustposition"
12451 || anArg == "-noadjustposition")
12453 anAttachPos = ManipAjustPosition_Center;
12454 if (anArgIter + 1 < theArgsNb)
12456 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12457 aPosName.LowerCase();
12458 if (aPosName == "0")
12460 anAttachPos = ManipAjustPosition_Off;
12462 else if (aPosName == "1"
12463 || aPosName == "center")
12465 anAttachPos = ManipAjustPosition_Center;
12467 else if (aPosName == "transformation"
12468 || aPosName == "trsf"
12469 || aPosName == "location"
12470 || aPosName == "loc")
12472 anAttachPos = ManipAjustPosition_Location;
12474 else if (aPosName == "shapelocation"
12475 || aPosName == "shapeloc")
12477 anAttachPos = ManipAjustPosition_ShapeLocation;
12484 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12486 else if (anArg == "-adjustsize"
12487 || anArg == "-noadjustsize")
12489 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12491 else if (anArg == "-enablemodes"
12492 || anArg == "-enablemodes")
12494 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12497 else if (anArg == "-starttransform"
12498 && anArgIter + 2 < theArgsNb
12499 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12500 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
12504 else if (anArg == "-transform"
12505 && anArgIter + 2 < theArgsNb
12506 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
12507 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
12511 else if (anArg == "-stoptransform")
12513 toStopMouseTransform = 1;
12514 if (anArgIter + 1 < theArgsNb
12515 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
12518 toStopMouseTransform = 0;
12522 else if (anArg == "-move"
12523 && anArgIter + 3 < theArgsNb
12524 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
12527 aTrsf.SetTranslationPart (aTmpXYZ);
12529 else if (anArg == "-scale"
12530 && anArgIter + 1 < theArgsNb
12531 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
12534 aTrsf.SetScale (gp_Pnt(), aTmpReal);
12536 else if (anArg == "-rotate"
12537 && anArgIter + 7 < theArgsNb
12538 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
12539 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
12540 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
12543 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
12546 else if (anArg == "-detach")
12550 else if (anArg == "-attach"
12551 && anArgIter + 1 < theArgsNb)
12553 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
12554 if (!aMapAIS.Find2 (anObjName, anAttachObject))
12556 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
12560 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
12562 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
12563 if (!aManip.IsNull()
12564 && aManip->IsAttached()
12565 && aManip->Object() == anAttachObject)
12567 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
12572 else if (anArg == "-view"
12573 && anArgIter + 1 < theArgsNb
12574 && aViewAffinity.IsNull())
12576 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
12577 if (aViewString == "active")
12579 aViewAffinity = ViewerTest::CurrentView();
12581 else // Check view name
12583 ViewerTest_Names aViewNames (aViewString);
12584 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
12586 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
12589 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
12590 if (aViewAffinity.IsNull())
12592 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
12597 else if (aName.IsEmpty())
12599 aName = theArgVec[anArgIter];
12600 if (!aMapAIS.IsBound2 (aName))
12602 aManipulator = new AIS_Manipulator();
12603 aManipulator->SetModeActivationOnDetection (true);
12604 aMapAIS.Bind (aManipulator, aName);
12608 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12609 if (aManipulator.IsNull())
12611 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
12618 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
12622 if (aName.IsEmpty())
12624 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
12628 && aManipulator.IsNull())
12630 aManipulator = new AIS_Manipulator();
12631 aManipulator->SetModeActivationOnDetection (true);
12632 aMapAIS.Bind (aManipulator, aName);
12635 // -----------------------------------------
12636 // change properties of manipulator instance
12637 // -----------------------------------------
12639 if (toAutoActivate != -1)
12641 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
12643 if (toFollowTranslation != -1)
12645 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
12647 if (toFollowRotation != -1)
12649 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
12651 if (toFollowDragging != -1)
12653 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
12657 aManipulator->SetGap ((float )aGap);
12660 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
12662 const ManipAxisModeOnOff& aPart = aPartIter.Value();
12663 if (aPart.Axis == -1)
12665 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
12669 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
12675 aManipulator->SetSize ((float )aSize);
12677 if (isZoomable != -1)
12679 aManipulator->SetZoomPersistence (isZoomable == 0);
12681 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12683 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
12684 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
12688 // ----------------------------------
12689 // detach existing manipulator object
12690 // ----------------------------------
12694 aManipulator->Detach();
12695 aMapAIS.UnBind2 (aName);
12696 ViewerTest::GetAISContext()->Remove (aManipulator, false);
12699 // ---------------------------------------------------
12700 // attach, detach or access manipulator from an object
12701 // ---------------------------------------------------
12703 if (!anAttachObject.IsNull())
12705 aManipulator->Attach (anAttachObject, anAttachOptions);
12707 if (!aViewAffinity.IsNull())
12709 for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
12710 anIter.More(); anIter.Next())
12712 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
12714 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
12717 if (anAttachPos != ManipAjustPosition_Off
12718 && aManipulator->IsAttached()
12719 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
12721 gp_Ax2 aPosition = gp::XOY();
12722 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
12723 switch (anAttachPos)
12725 case ManipAjustPosition_Off:
12729 case ManipAjustPosition_Location:
12731 aPosition = gp::XOY().Transformed (aBaseTrsf);
12734 case ManipAjustPosition_ShapeLocation:
12736 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
12738 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
12742 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
12747 case ManipAjustPosition_Center:
12750 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
12753 anObjIter.Value()->BoundingBox (anObjBox);
12754 aBox.Add (anObjBox);
12756 aBox = aBox.FinitePart();
12757 if (!aBox.IsVoid())
12759 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
12760 aPosition.SetLocation (aCenter);
12765 aManipulator->SetPosition (aPosition);
12767 if (!Precision::IsInfinite (aLocation.X()))
12769 if (aVDir.Modulus() <= Precision::Confusion())
12771 aVDir = aManipulator->Position().Direction().XYZ();
12773 if (anXDir.Modulus() <= Precision::Confusion())
12775 anXDir = aManipulator->Position().XDirection().XYZ();
12777 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
12780 // --------------------------------------
12781 // apply transformation using manipulator
12782 // --------------------------------------
12784 if (aMousePosFrom.x() != IntegerLast())
12786 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
12788 if (aMousePosTo.x() != IntegerLast())
12790 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
12792 if (toStopMouseTransform != -1)
12794 aManipulator->StopTransform (toStopMouseTransform == 1);
12797 if (aTrsf.Form() != gp_Identity)
12799 aManipulator->Transform (aTrsf);
12802 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12804 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
12809 //===============================================================================================
12810 //function : VSelectionProperties
12812 //===============================================================================================
12813 static int VSelectionProperties (Draw_Interpretor& theDi,
12814 Standard_Integer theArgsNb,
12815 const char** theArgVec)
12817 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
12820 Message::SendFail ("Error: no active viewer");
12824 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
12826 // handle obsolete alias
12827 bool toEnable = true;
12830 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
12833 else if (theArgsNb != 2
12834 || !Draw::ParseOnOff (theArgVec[1], toEnable))
12836 Message::SendFail ("Syntax error: wrong number of parameters");
12839 if (toEnable != aCtx->ToHilightSelected())
12841 aCtx->ClearDetected();
12842 aCtx->SetToHilightSelected (toEnable);
12847 Standard_Boolean toPrint = theArgsNb == 1;
12848 Standard_Boolean toRedraw = Standard_False;
12849 Standard_Integer anArgIter = 1;
12850 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
12851 if (anArgIter < theArgsNb)
12853 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
12854 anArgFirst.LowerCase();
12856 if (anArgFirst == "dynhighlight"
12857 || anArgFirst == "dynhilight"
12858 || anArgFirst == "dynamichighlight"
12859 || anArgFirst == "dynamichilight")
12861 aType = Prs3d_TypeOfHighlight_Dynamic;
12863 else if (anArgFirst == "localdynhighlight"
12864 || anArgFirst == "localdynhilight"
12865 || anArgFirst == "localdynamichighlight"
12866 || anArgFirst == "localdynamichilight")
12868 aType = Prs3d_TypeOfHighlight_LocalDynamic;
12870 else if (anArgFirst == "selhighlight"
12871 || anArgFirst == "selhilight"
12872 || anArgFirst == "selectedhighlight"
12873 || anArgFirst == "selectedhilight")
12875 aType = Prs3d_TypeOfHighlight_Selected;
12877 else if (anArgFirst == "localselhighlight"
12878 || anArgFirst == "localselhilight"
12879 || anArgFirst == "localselectedhighlight"
12880 || anArgFirst == "localselectedhilight")
12882 aType = Prs3d_TypeOfHighlight_LocalSelected;
12889 for (; anArgIter < theArgsNb; ++anArgIter)
12891 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12893 if (anArg == "-help")
12895 theDi.PrintHelp (theArgVec[0]);
12898 else if (anArg == "-print")
12900 toPrint = Standard_True;
12902 else if (anArg == "-autoactivate")
12904 Standard_Boolean toEnable = Standard_True;
12905 if (anArgIter + 1 < theArgsNb
12906 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12910 aCtx->SetAutoActivateSelection (toEnable);
12912 else if (anArg == "-automatichighlight"
12913 || anArg == "-automatichilight"
12914 || anArg == "-autohighlight"
12915 || anArg == "-autohilight")
12917 Standard_Boolean toEnable = Standard_True;
12918 if (anArgIter + 1 < theArgsNb
12919 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12923 aCtx->ClearSelected (false);
12924 aCtx->ClearDetected();
12925 aCtx->SetAutomaticHilight (toEnable);
12928 else if (anArg == "-highlightselected"
12929 || anArg == "-hilightselected")
12931 Standard_Boolean toEnable = Standard_True;
12932 if (anArgIter + 1 < theArgsNb
12933 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12937 aCtx->ClearDetected();
12938 aCtx->SetToHilightSelected (toEnable);
12941 else if (anArg == "-pickstrategy"
12942 || anArg == "-pickingstrategy")
12944 if (++anArgIter >= theArgsNb)
12946 Message::SendFail ("Syntax error: type of highlighting is undefined");
12950 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
12951 TCollection_AsciiString aVal (theArgVec[anArgIter]);
12953 if (aVal == "first"
12954 || aVal == "firstaccepted"
12955 || aVal == "firstacceptable")
12957 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
12959 else if (aVal == "topmost"
12960 || aVal == "onlyTopmost")
12962 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
12966 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
12970 aCtx->SetPickingStrategy (aStrategy);
12972 else if (anArg == "-pixtol"
12973 && anArgIter + 1 < theArgsNb)
12975 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
12977 else if (anArg == "-preferclosest")
12979 bool toPreferClosest = true;
12980 if (anArgIter + 1 < theArgsNb
12981 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
12985 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
12987 else if ((anArg == "-depthtol"
12988 || anArg == "-depthtolerance")
12989 && anArgIter + 1 < theArgsNb)
12991 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
12992 aTolType.LowerCase();
12993 if (aTolType == "uniform")
12995 if (anArgIter + 1 >= theArgsNb)
12997 Message::SendFail() << "Syntax error: wrong number of arguments";
13000 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13001 Draw::Atof (theArgVec[++anArgIter]));
13003 else if (aTolType == "uniformpx")
13005 if (anArgIter + 1 >= theArgsNb)
13007 Message::SendFail() << "Syntax error: wrong number of arguments";
13010 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13011 Draw::Atof (theArgVec[++anArgIter]));
13013 else if (aTolType == "sensfactor")
13015 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13019 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13023 else if ((anArg == "-mode"
13024 || anArg == "-dispmode")
13025 && anArgIter + 1 < theArgsNb)
13027 if (aType == Prs3d_TypeOfHighlight_None)
13029 Message::SendFail ("Syntax error: type of highlighting is undefined");
13033 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13034 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13035 aStyle->SetDisplayMode (aDispMode);
13036 toRedraw = Standard_True;
13038 else if (anArg == "-layer"
13039 && anArgIter + 1 < theArgsNb)
13041 if (aType == Prs3d_TypeOfHighlight_None)
13043 Message::SendFail ("Syntax error: type of highlighting is undefined");
13048 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13049 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
13051 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
13055 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13056 aStyle->SetZLayer (aNewLayer);
13057 toRedraw = Standard_True;
13059 else if (anArg == "-hicolor"
13060 || anArg == "-selcolor"
13061 || anArg == "-color")
13063 if (anArg.StartsWith ("-hi"))
13065 aType = Prs3d_TypeOfHighlight_Dynamic;
13067 else if (anArg.StartsWith ("-sel"))
13069 aType = Prs3d_TypeOfHighlight_Selected;
13071 else if (aType == Prs3d_TypeOfHighlight_None)
13073 Message::SendFail ("Syntax error: type of highlighting is undefined");
13077 Quantity_Color aColor;
13078 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13079 theArgVec + anArgIter + 1,
13081 if (aNbParsed == 0)
13083 Message::SendFail ("Syntax error: need more arguments");
13086 anArgIter += aNbParsed;
13088 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13089 aStyle->SetColor (aColor);
13090 toRedraw = Standard_True;
13092 else if ((anArg == "-transp"
13093 || anArg == "-transparency"
13094 || anArg == "-hitransp"
13095 || anArg == "-seltransp"
13096 || anArg == "-hitransplocal"
13097 || anArg == "-seltransplocal")
13098 && anArgIter + 1 < theArgsNb)
13100 if (anArg.StartsWith ("-hi"))
13102 aType = Prs3d_TypeOfHighlight_Dynamic;
13104 else if (anArg.StartsWith ("-sel"))
13106 aType = Prs3d_TypeOfHighlight_Selected;
13108 else if (aType == Prs3d_TypeOfHighlight_None)
13110 Message::SendFail ("Syntax error: type of highlighting is undefined");
13114 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13115 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13116 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13117 toRedraw = Standard_True;
13119 else if ((anArg == "-mat"
13120 || anArg == "-material")
13121 && anArgIter + 1 < theArgsNb)
13123 if (aType == Prs3d_TypeOfHighlight_None)
13125 Message::SendFail ("Syntax error: type of highlighting is undefined");
13129 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13130 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
13131 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
13134 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13135 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13136 Graphic3d_MaterialAspect aMat (aMatName);
13137 aMat.SetColor (aStyle->Color());
13138 aMat.SetTransparency (aStyle->Transparency());
13139 anAspect->SetFrontMaterial (aMat);
13140 anAspect->SetInteriorColor (aStyle->Color());
13141 aStyle->SetBasicFillAreaAspect (anAspect);
13145 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13147 toRedraw = Standard_True;
13151 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
13158 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13159 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
13160 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
13161 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13162 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
13163 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
13164 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13165 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13166 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13167 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13168 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13169 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13170 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13171 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
13174 if (aCtx->NbSelected() != 0 && toRedraw)
13176 aCtx->HilightSelected (Standard_True);
13182 //===============================================================================================
13183 //function : VDumpSelectionImage
13185 //===============================================================================================
13186 static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13187 Standard_Integer theArgsNb,
13188 const char** theArgVec)
13190 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13191 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13192 if (aContext.IsNull())
13194 Message::SendFail ("Error: no active viewer");
13198 TCollection_AsciiString aFile;
13199 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13200 Handle(Graphic3d_Camera) aCustomCam;
13201 Image_Format anImgFormat = Image_Format_BGR;
13202 Standard_Integer aPickedIndex = 1;
13203 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13205 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13206 aParam.LowerCase();
13207 if (aParam == "-type")
13209 if (++anArgIter >= theArgsNb)
13211 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
13215 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13216 aValue.LowerCase();
13217 if (aValue == "depth"
13218 || aValue == "normdepth"
13219 || aValue == "normalizeddepth")
13221 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13222 anImgFormat = Image_Format_GrayF;
13224 else if (aValue == "depthinverted"
13225 || aValue == "normdepthinverted"
13226 || aValue == "normalizeddepthinverted"
13227 || aValue == "inverted")
13229 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
13230 anImgFormat = Image_Format_GrayF;
13232 else if (aValue == "unnormdepth"
13233 || aValue == "unnormalizeddepth")
13235 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
13236 anImgFormat = Image_Format_GrayF;
13238 else if (aValue == "objectcolor"
13239 || aValue == "object"
13240 || aValue == "color")
13242 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13244 else if (aValue == "entitycolor"
13245 || aValue == "entity")
13247 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13249 else if (aValue == "entitytypecolor"
13250 || aValue == "entitytype")
13252 aType = StdSelect_TypeOfSelectionImage_ColoredEntityType;
13254 else if (aValue == "ownercolor"
13255 || aValue == "owner")
13257 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13259 else if (aValue == "selectionmodecolor"
13260 || aValue == "selectionmode"
13261 || aValue == "selmodecolor"
13262 || aValue == "selmode")
13264 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13266 else if (aValue == "surfnormal"
13267 || aValue == "surfacenormal"
13268 || aValue == "normal")
13270 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13274 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13278 else if (aParam == "-picked"
13279 || aParam == "-pickeddepth"
13280 || aParam == "-pickedindex")
13282 if (++anArgIter >= theArgsNb)
13284 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
13288 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13290 else if (anArgIter + 1 < theArgsNb
13291 && aParam == "-xrpose")
13293 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13294 anXRArg.LowerCase();
13295 if (anXRArg == "base")
13297 aCustomCam = aView->View()->BaseXRCamera();
13299 else if (anXRArg == "head")
13301 aCustomCam = aView->View()->PosedXRCamera();
13305 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13308 if (aCustomCam.IsNull())
13310 Message::SendFail() << "Error: undefined XR pose";
13314 else if (aFile.IsEmpty())
13316 aFile = theArgVec[anArgIter];
13320 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13324 if (aFile.IsEmpty())
13326 Message::SendFail ("Syntax error: image file name is missing");
13330 Standard_Integer aWidth = 0, aHeight = 0;
13331 aView->Window()->Size (aWidth, aHeight);
13333 Image_AlienPixMap aPixMap;
13334 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13336 Message::SendFail ("Error: can't allocate image");
13340 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13341 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13342 if (!aCustomCam.IsNull())
13344 aView->SetCamera (aCustomCam);
13346 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13348 Message::SendFail ("Error: can't generate selection image");
13351 if (!aCustomCam.IsNull())
13353 aView->SetCamera (aCamBack);
13355 aView->SetImmediateUpdate (wasImmUpdate);
13357 if (!aPixMap.Save (aFile))
13359 Message::SendFail ("Error: can't save selection image");
13365 //===============================================================================================
13366 //function : VViewCube
13368 //===============================================================================================
13369 static int VViewCube (Draw_Interpretor& ,
13370 Standard_Integer theNbArgs,
13371 const char** theArgVec)
13373 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13374 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13375 if (aContext.IsNull() || aView.IsNull())
13377 Message::SendFail ("Error: no active viewer");
13380 else if (theNbArgs < 2)
13382 Message::SendFail ("Syntax error: wrong number arguments");
13386 Handle(AIS_ViewCube) aViewCube;
13387 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13388 Quantity_Color aColorRgb;
13389 TCollection_AsciiString aName;
13390 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13392 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13394 if (anUpdateTool.parseRedrawMode (anArg))
13398 else if (aViewCube.IsNull())
13400 aName = theArgVec[anArgIter];
13401 if (aName.StartsWith ("-"))
13403 Message::SendFail ("Syntax error: object name should be specified");
13406 Handle(AIS_InteractiveObject) aPrs;
13407 GetMapOfAIS().Find2 (aName, aPrs);
13408 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13409 if (aViewCube.IsNull())
13411 aViewCube = new AIS_ViewCube();
13412 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13413 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13414 aViewCube->SetFixedAnimationLoop (false);
13417 else if (anArg == "-reset")
13419 aViewCube->ResetStyles();
13421 else if (anArg == "-color"
13422 || anArg == "-boxcolor"
13423 || anArg == "-boxsidecolor"
13424 || anArg == "-sidecolor"
13425 || anArg == "-boxedgecolor"
13426 || anArg == "-edgecolor"
13427 || anArg == "-boxcornercolor"
13428 || anArg == "-cornercolor"
13429 || anArg == "-innercolor"
13430 || anArg == "-textcolor"
13431 || anArg == "-xaxistextcolor"
13432 || anArg == "-yaxistextcolor"
13433 || anArg == "-zaxistextcolor")
13435 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13436 theArgVec + anArgIter + 1,
13438 if (aNbParsed == 0)
13440 Message::SendFail() << "Syntax error at '" << anArg << "'";
13443 anArgIter += aNbParsed;
13444 if (anArg == "-boxcolor")
13446 aViewCube->SetBoxColor (aColorRgb);
13448 else if (anArg == "-boxsidecolor"
13449 || anArg == "-sidecolor")
13451 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13452 aViewCube->SynchronizeAspects();
13454 else if (anArg == "-boxedgecolor"
13455 || anArg == "-edgecolor")
13457 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13458 aViewCube->SynchronizeAspects();
13460 else if (anArg == "-boxcornercolor"
13461 || anArg == "-cornercolor")
13463 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13464 aViewCube->SynchronizeAspects();
13466 else if (anArg == "-innercolor")
13468 aViewCube->SetInnerColor (aColorRgb);
13470 else if (anArg == "-textcolor")
13472 aViewCube->SetTextColor (aColorRgb);
13474 else if (anArg == "-xaxistextcolor"
13475 || anArg == "-yaxistextcolor"
13476 || anArg == "-zaxistextcolor")
13478 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13479 ? Prs3d_DatumParts_XAxis
13480 : (anArg.Value (2) == 'y'
13481 ? Prs3d_DatumParts_YAxis
13482 : Prs3d_DatumParts_ZAxis);
13483 aViewCube->Attributes()->SetOwnDatumAspects();
13484 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13488 aViewCube->SetColor (aColorRgb);
13491 else if (anArgIter + 1 < theNbArgs
13492 && (anArg == "-transparency"
13493 || anArg == "-boxtransparency"))
13495 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13496 if (aValue < 0.0 || aValue > 1.0)
13498 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
13502 if (anArg == "-boxtransparency")
13504 aViewCube->SetBoxTransparency (aValue);
13508 aViewCube->SetTransparency (aValue);
13511 else if (anArg == "-axes"
13512 || anArg == "-edges"
13513 || anArg == "-vertices"
13514 || anArg == "-vertexes"
13515 || anArg == "-fixedanimation")
13517 bool toShow = true;
13518 if (anArgIter + 1 < theNbArgs
13519 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
13523 if (anArg == "-fixedanimation")
13525 aViewCube->SetFixedAnimationLoop (toShow);
13527 else if (anArg == "-axes")
13529 aViewCube->SetDrawAxes (toShow);
13531 else if (anArg == "-edges")
13533 aViewCube->SetDrawEdges (toShow);
13537 aViewCube->SetDrawVertices (toShow);
13540 else if (anArg == "-yup"
13541 || anArg == "-zup")
13544 if (anArgIter + 1 < theNbArgs
13545 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
13549 if (anArg == "-yup")
13551 aViewCube->SetYup (isOn);
13555 aViewCube->SetYup (!isOn);
13558 else if (anArgIter + 1 < theNbArgs
13559 && anArg == "-font")
13561 aViewCube->SetFont (theArgVec[++anArgIter]);
13563 else if (anArgIter + 1 < theNbArgs
13564 && anArg == "-fontheight")
13566 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13568 else if (anArgIter + 1 < theNbArgs
13569 && (anArg == "-size"
13570 || anArg == "-boxsize"))
13572 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13573 anArg != "-boxsize");
13575 else if (anArgIter + 1 < theNbArgs
13576 && (anArg == "-boxfacet"
13577 || anArg == "-boxfacetextension"
13578 || anArg == "-facetextension"
13579 || anArg == "-extension"))
13581 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13583 else if (anArgIter + 1 < theNbArgs
13584 && (anArg == "-boxedgegap"
13585 || anArg == "-edgegap"))
13587 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13589 else if (anArgIter + 1 < theNbArgs
13590 && (anArg == "-boxedgeminsize"
13591 || anArg == "-edgeminsize"))
13593 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
13595 else if (anArgIter + 1 < theNbArgs
13596 && (anArg == "-boxcornerminsize"
13597 || anArg == "-cornerminsize"))
13599 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
13601 else if (anArgIter + 1 < theNbArgs
13602 && anArg == "-axespadding")
13604 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
13606 else if (anArgIter + 1 < theNbArgs
13607 && anArg == "-roundradius")
13609 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
13611 else if (anArgIter + 1 < theNbArgs
13612 && anArg == "-duration")
13614 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
13616 else if (anArgIter + 1 < theNbArgs
13617 && anArg == "-axesradius")
13619 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
13621 else if (anArgIter + 1 < theNbArgs
13622 && anArg == "-axesconeradius")
13624 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
13626 else if (anArgIter + 1 < theNbArgs
13627 && anArg == "-axessphereradius")
13629 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
13633 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13637 if (aViewCube.IsNull())
13639 Message::SendFail ("Syntax error: wrong number of arguments");
13643 ViewerTest::Display (aName, aViewCube, false);
13647 //! Parse color type argument.
13648 static bool parseColorType (const char* theString,
13649 Quantity_TypeOfColor& theType)
13651 TCollection_AsciiString aType (theString);
13653 if (aType == "rgb") { theType = Quantity_TOC_RGB; }
13654 else if (aType == "srgb") { theType = Quantity_TOC_sRGB; }
13655 else if (aType == "hex") { theType = Quantity_TOC_sRGB; }
13656 else if (aType == "name") { theType = Quantity_TOC_sRGB; }
13657 else if (aType == "hls") { theType = Quantity_TOC_HLS; }
13658 else if (aType == "lab") { theType = Quantity_TOC_CIELab; }
13659 else if (aType == "lch") { theType = Quantity_TOC_CIELch; }
13660 else { return false; }
13664 //===============================================================================================
13665 //function : VColorConvert
13667 //===============================================================================================
13668 static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13670 Quantity_TypeOfColor aTypeFrom = Quantity_TOC_RGB, aTypeTo = Quantity_TOC_RGB;
13671 double anInput[4] = {};
13672 Quantity_ColorRGBA aColor (0.0f, 0.0f, 0.0f, 1.0f);
13673 bool toPrintHex = false, toPrintName = false, hasAlpha = false;
13674 for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13676 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
13677 anArgCase.LowerCase();
13678 if ((anArgCase == "-from"
13679 || anArgCase == "from")
13680 && anArgIter + 1 < theNbArgs
13681 && parseColorType (theArgVec[anArgIter + 1], aTypeFrom))
13685 else if ((anArgCase == "-to"
13686 || anArgCase == "to")
13687 && anArgIter + 1 < theNbArgs
13688 && parseColorType (theArgVec[anArgIter + 1], aTypeTo))
13690 TCollection_AsciiString aToStr (theArgVec[++anArgIter]);
13691 aToStr.LowerCase();
13692 toPrintHex = (aToStr == "hex");
13693 toPrintName = (aToStr == "name");
13695 else if (Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColor))
13697 hasAlpha = anArgCase.Length() >= 8;
13699 else if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aColor.ChangeRGB()))
13703 else if (anArgIter + 2 < theNbArgs
13704 && Draw::ParseReal (theArgVec[anArgIter + 0], anInput[0])
13705 && Draw::ParseReal (theArgVec[anArgIter + 1], anInput[1])
13706 && Draw::ParseReal (theArgVec[anArgIter + 2], anInput[2]))
13708 if (anArgIter + 3 < theNbArgs
13709 && Draw::ParseReal (theArgVec[anArgIter + 3], anInput[3]))
13712 aColor.SetAlpha ((float )anInput[3]);
13716 aColor.ChangeRGB().SetValues (anInput[0], anInput[1], anInput[2], aTypeFrom);
13720 theDI << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13727 if (hasAlpha || aColor.Alpha() < 1.0f)
13729 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
13733 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
13736 else if (toPrintName)
13738 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
13742 double anOutput[3] = {};
13743 aColor.GetRGB().Values (anOutput[0], anOutput[1], anOutput[2], aTypeTo);
13745 // print values with 6 decimal digits
13746 char aBuffer[1024];
13747 if (hasAlpha || aColor.Alpha() < 1.0f)
13749 Sprintf (aBuffer, "%.6f %.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2], aColor.Alpha());
13753 Sprintf (aBuffer, "%.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2]);
13760 //===============================================================================================
13761 //function : VColorDiff
13763 //===============================================================================================
13764 static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13766 if (theNbArgs != 7)
13768 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13772 double aR1 = Draw::Atof (theArgVec[1]);
13773 double aG1 = Draw::Atof (theArgVec[2]);
13774 double aB1 = Draw::Atof (theArgVec[3]);
13775 double aR2 = Draw::Atof (theArgVec[4]);
13776 double aG2 = Draw::Atof (theArgVec[5]);
13777 double aB2 = Draw::Atof (theArgVec[6]);
13779 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
13780 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
13782 theDI << aColor1.DeltaE2000 (aColor2);
13787 //===============================================================================================
13788 //function : VSelBvhBuild
13790 //===============================================================================================
13791 static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
13793 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
13796 Message::SendFail ("Error: no active viewer");
13802 Message::SendFail ("Error: command syntax is incorrect, see help");
13806 Standard_Integer toEnable = -1;
13807 Standard_Integer aThreadsNb = -1;
13808 Standard_Boolean toWait = Standard_False;
13810 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13812 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13815 if (anArg == "-nbthreads"
13816 && anArgIter + 1 < theNbArgs)
13818 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
13819 if (aThreadsNb < 1)
13821 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
13824 else if (anArg == "-wait")
13826 toWait = Standard_True;
13828 else if (toEnable == -1)
13830 Standard_Boolean toEnableValue = Standard_True;
13831 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
13833 toEnable = toEnableValue ? 1 : 0;
13837 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13843 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13848 if (aThreadsNb == -1)
13852 if (toEnable != -1)
13854 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
13858 aCtx->MainSelector()->WaitForBVHBuild();
13864 //=======================================================================
13865 //function : ViewerTest_ExitProc
13867 //=======================================================================
13868 static void ViewerTest_ExitProc (ClientData )
13870 NCollection_List<TCollection_AsciiString> aViewList;
13871 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
13872 anIter.More(); anIter.Next())
13874 aViewList.Append (anIter.Key1());
13877 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
13878 anIter.More(); anIter.Next())
13880 ViewerTest::RemoveView (anIter.Value(), true);
13884 //=======================================================================
13885 //function : ViewerCommands
13887 //=======================================================================
13889 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
13891 static bool TheIsInitialized = false;
13892 if (TheIsInitialized)
13897 TheIsInitialized = true;
13898 // define destruction callback to destroy views in a well-defined order
13899 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
13901 const char* aGroup = "AIS Viewer";
13902 const char* aFileName = __FILE__;
13903 auto addCmd = [&](const char* theName, Draw_Interpretor::CommandFunction theFunc, const char* theHelp)
13905 theCommands.Add (theName, theHelp, aFileName, theFunc, aGroup);
13908 addCmd ("vdriver", VDriver, /* [vdriver] */ R"(
13909 vdriver [-list] [-default DriverName] [-load DriverName]
13910 Manages active graphic driver factory.
13911 Prints current active driver when called without arguments.
13912 Makes specified driver active when ActiveName argument is specified.
13913 -list print registered factories
13914 -default define which factory should be used by default (to be used by next vinit call)
13915 -load try loading factory plugin and set it as default one
13916 )" /* [vdriver] */);
13918 addCmd ("vinit", VInit, /* [vinit] */ R"(
13919 vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]
13920 [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {0|1}]=0 [-2d_mode {0|1}]=0
13921 [-display displayName] [-dpiAware {0|1}]=0
13922 [-subview] [-parent OtherView] [-composer {0|1}]=0 [-margins DX DY]=0
13923 Creates new View window with specified name viewName.
13924 By default the new view is created in the viewer and in graphic driver shared with active view.
13925 -name {driverName/viewerName/viewName | viewerName/viewName | viewName}
13926 if driverName isn't specified the driver will be shared with active view;
13927 if viewerName isn't specified the viewer will be shared with active view.
13928 -display HostName.DisplayNumber[:ScreenNumber]
13930 Display name will be used within creation of graphic driver, when specified.
13931 -left, -top pixel position of left top corner of the window.
13932 -width, -height width and height of window respectively.
13933 -cloneActive flag to copy camera and dimensions of active view.
13934 -exitOnClose when specified, closing the view will exit application.
13935 -closeOnEscape when specified, view will be closed on pressing Escape.
13936 -virtual create an offscreen window within interactive session
13937 -subview create a subview within another view
13938 -2d_mode when on, view will not react on rotate scene events
13939 -dpiAware override dpi aware hint (Windows platform)
13940 Additional commands for operations with views: vclose, vactivate, vviewlist.
13943 addCmd ("vclose", VClose, /* [vclose] */ R"(
13944 vclose [view_id [keep_context=0|1]]
13945 or vclose ALL - to remove all created views
13946 - removes view(viewer window) defined by its view_id.
13947 - keep_context: by default 0; if 1 and the last view is deleted the current context is not removed.
13948 )" /* [vclose] */);
13950 addCmd ("vactivate", VActivate, /* [vactivate] */ R"(
13951 vactivate view_id [-noUpdate]
13952 Activates view(viewer window) defined by its view_id.
13953 )" /* [vactivate] */);
13955 addCmd ("vviewlist", VViewList, /* [vviewlist] */ R"(
13956 vviewlist [format={tree, long}]=tree
13957 Prints current list of views per viewer and graphic_driver ID shared between viewers
13958 - format: format of result output, if tree the output is a tree view;
13959 otherwise it's a list of full view names.
13960 )" /* [vviewlist] */);
13962 addCmd ("vhelp", VHelp, /* [vhelp] */ R"(
13963 vhelp : display help on the viewer commands and list of hotkeys.
13966 addCmd ("vviewproj", VViewProj, /* [vviewproj] */ R"(
13967 vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]
13968 [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]
13969 Setup view direction
13970 -Yup use Y-up convention instead of Zup (which is default).
13971 +-X+-Y+-Z define direction as combination of DX, DY and DZ;
13972 for example '+Z' will show front of the model,
13973 '-X-Y+Z' will define left axonometric view.
13974 -frame define camera Up and Right directions (regardless Up convention);
13975 for example '+X+Z' will show front of the model with Z-up.
13976 )" /* [vviewproj] */);
13978 addCmd ("vtop", VViewProj, /* [vtop] */ R"(
13979 vtop or <T> : Display top view (+X+Y) in the 3D viewer window.
13982 addCmd ("vbottom", VViewProj, /* [vbottom] */ R"(
13983 vbottom : Display bottom view (+X-Y) in the 3D viewer window.
13984 )" /* [vbottom] */);
13986 addCmd ("vleft", VViewProj, /* [vleft] */ R"(
13987 vleft : Display left view (-Y+Z) in the 3D viewer window.
13990 addCmd ("vright", VViewProj, /* [vright] */ R"(
13991 vright : Display right view (+Y+Z) in the 3D viewer window.
13992 )" /* [vright] */);
13994 addCmd ("vaxo", VViewProj, /* [vaxo] */ R"(
13995 vaxo or <A> : Display axonometric view (+X-Y+Z) in the 3D viewer window.
13998 addCmd ("vfront", VViewProj, /* [vfront] */ R"(
13999 vfront : Display front view (+X+Z) in the 3D viewer window.
14000 )" /* [vfront] */);
14002 addCmd ("vback", VViewProj, /* [vfront] */ R"(
14003 vback : Display back view (-X+Z) in the 3D viewer window.
14006 addCmd ("vpick", VPick, /* [vpick] */ R"(
14007 vpick X Y Z [shape subshape]
14010 addCmd ("vfit", VFit, /* [vfit] */ R"(
14011 vfit or <F> [-selected] [-noupdate]
14012 Fit all / selected. Objects in the view are visualized to occupy the maximum surface.
14015 addCmd ("vfitarea", VFitArea, /* [vfitarea] */ R"(
14016 vfitarea [x1 y1 x2 y2] [x1 y1 z1 x2 y2 z2]
14017 Fit view to show area located between two points
14018 given in world 2D or 3D coordinates.
14019 )" /* [vfitarea] */);
14021 addCmd ("vzfit", VZFit, /* [vzfit] */ R"(
14023 Automatic depth panning.
14024 Matches Z near, Z far view volume planes to the displayed objects.
14025 - "scale" specifies factor to scale computed z range.
14028 addCmd ("vrepaint", VRepaint, /* [vrepaint] */ R"(
14029 vrepaint [-immediate] [-continuous FPS]
14030 Force redraw of active View.
14031 -immediate flag performs redraw of immediate layers only;
14032 -continuous activates/deactivates continuous redraw of active View,
14033 0 means no continuous rendering,
14034 -1 means non-stop redraws,
14035 >0 specifies target framerate.
14036 )" /* [vrepaint] */);
14038 addCmd ("vclear", VClear, /* [vclear] */ R"(
14039 vclear : Remove all the object from the viewer
14040 )" /* [vclear] */);
14042 addCmd ("vbackground", VBackground, /* [vbackground] */ R"(
14043 vbackground [-color Color [-default]]
14044 [-gradient Color1 Color2 [-default]
14045 [-gradientMode {NONE|HORIZONTAL|VERTICAL|DIAG1|DIAG2|CORNER1|CORNER2|CORNER3|ELLIPTICAL}]=VERT]
14046 [-imageFile ImageFile [-imageMode {CENTERED|TILED|STRETCH|NONE}]=CENTERED [-srgb {0|1}]=1]
14047 [-cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]=0]
14048 [-skydome [-sunDir X Y Z=0 1 0] [-cloud Cloudy=0.2] [-time Time=0.0]
14049 [-fog Haze=0.0] [-size SizePx=512]]
14050 [-pbrEnv {ibl|noibl|keep}]
14051 Changes background or some background settings.
14052 -color sets background color
14053 -gradient sets background gradient starting and ending colors
14054 -gradientMode sets gradient fill method
14055 -default sets background default gradient or color
14056 -imageFile sets filename of image used as background
14057 -imageMode sets image fill type
14058 -cubemap sets environment cubemap as background
14059 -invertedz sets inversion of Z axis for background cubemap rendering; FALSE when unspecified
14060 -pbrEnv sets on/off Image Based Lighting (IBL) from background cubemap for PBR
14061 -srgb prefer sRGB texture format when applicable; TRUE when unspecified"
14062 -order defines order of tiles in one image cubemap
14063 TileIndexi defubes an index in range [0, 5] for i tile of one image packed cubemap
14064 (has no effect in case of multi-image cubemaps).
14065 Skydome background parameters (generated cubemap):
14066 -skydome sets procedurally generated skydome as background
14067 -sunDir sets direction to the sun, direction with negative y component represents moon direction (-x, -y, -z)
14068 -cloud sets cloud intensity (0.0 - clear sky, 1.0 - very high cloudy)
14069 -time might be tweaked to slightly change appearance of clouds
14070 -fog sets mist intensity (0.0 - no mist at all, 1.0 - high mist)
14071 -size sets size in pixels of cubemap side
14072 )" /* [vbackground] */);
14074 addCmd ("vsetbg", VBackground, /* [vsetbg] */ R"(
14075 Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.
14076 )" /* [vsetbg] */);
14078 addCmd ("vsetbgmode", VBackground, /* [vsetbgmode] */ R"(
14079 Alias for 'vbackground -imageMode FillType'.
14080 )" /* [vsetbgmode] */);
14082 addCmd ("vsetgradientbg", VBackground, /* [vsetgradientbg] */ R"(
14083 Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.
14084 )" /* [vsetgradientbg] */);
14086 addCmd ("vsetgrbgmode", VBackground, /* [vsetgrbgmode] */ R"(
14087 Alias for 'vbackground -gradientMode FillMethod'.
14088 )" /* [vsetgrbgmode] */);
14090 addCmd ("vsetcolorbg", VBackground, /* [vsetcolorbg] */ R"(
14091 Alias for 'vbackground -color Color'.
14092 )" /* [vsetcolorbg] */);
14094 addCmd ("vsetdefaultbg", VBackground, /* [vsetdefaultbg] */ R"(
14095 Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'
14096 and for 'vbackground -default -color Color'.
14097 )" /* [vsetdefaultbg] */);
14099 addCmd ("vscale", VScale, /* [vscale] */ R"(
14101 )" /* [vscale] */);
14103 addCmd ("vzbufftrihedron", VZBuffTrihedron, /* [vzbufftrihedron] */ R"(
14104 vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]
14105 [-position center|left_lower|left_upper|right_lower|right_upper]
14106 [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]
14107 [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]
14108 [-nbfacets value=12] [-colorLabels color=WHITE]
14109 [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]
14110 Displays a trihedron.
14111 )" /* [vzbufftrihedron] */);
14113 addCmd ("vrotate", VRotate, /* [vrotate] */ R"(
14114 vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]
14115 -mouseStart start rotation according to the mouse position;
14116 -mouseMove continue rotation with angle computed
14117 from last and new mouse position.
14118 )" /* [vrotate] */);
14120 addCmd ("vzoom", VZoom, /* [vzoom] */ R"(
14124 addCmd ("vpan", VPan, /* [vpan] */ R"(
14128 addCmd ("vcolorscale", VColorScale, /* [vcolorscale] */ R"(
14129 vcolorscale name [-noupdate|-update] [-demo]
14130 [-range RangeMin=0 RangeMax=1 NbIntervals=10]
14131 [-font HeightFont=20]
14132 [-logarithmic {on|off}=off] [-reversed {on|off}=off]
14133 [-smoothTransition {on|off}=off]
14134 [-hueRange MinAngle=230 MaxAngle=0]
14135 [-colorRange MinColor=BLUE1 MaxColor=RED]
14136 [-textPos {left|right|center|none}=right]
14137 [-labelAtBorder {on|off}=on]
14138 [-colors Color1 Color2 ...] [-color Index Color]
14139 [-labels Label1 Label2 ...] [-label Index Label]
14140 [-freeLabels NbOfLabels Label1 Label2 ...]
14141 [-xy Left=0 Bottom=0]
14142 [-uniform lightness hue_from hue_to]
14143 -demo display a color scale with demonstration values
14144 -colors set colors for all intervals
14145 -color set color for specific interval
14146 -uniform generate colors with the same lightness
14147 -textpos horizontal label position relative to color scale bar
14148 -labelAtBorder vertical label position relative to color interval;
14149 at border means the value inbetween neighbor intervals,
14150 at center means the center value within current interval
14151 -labels set labels for all intervals
14152 -freeLabels same as -labels but does not require
14153 matching the number of intervals
14154 -label set label for specific interval
14156 -reversed setup smooth color transition between intervals
14157 -smoothTransition swap colorscale direction
14158 -hueRange set hue angles corresponding to minimum and maximum values
14159 )" /* [vcolorscale] */);
14161 addCmd ("vgraduatedtrihedron", VGraduatedTrihedron, /* [vgraduatedtrihedron] */ R"(
14162 vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]
14163 [-namefont Name] [-valuesfont Name]
14164 [-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]
14165 [-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]
14166 [-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]
14167 [-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]
14168 [-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]
14169 [-xcolor Color] [-ycolor Color] [-zcolor Color]
14170 [-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]
14171 [-xticks Number] [-yticks Number] [-zticks Number]
14172 [-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]
14173 [-drawgrid on/off] [-drawaxes on/off]
14174 Display or erase graduated trihedron
14175 - xname, yname, zname - names of axes, default: X, Y, Z
14176 - namefont - font of axes names. Default: Arial
14177 - xnameoffset, ynameoffset, znameoffset - offset of name
14178 from values or tickmarks or axis. Default: 30
14179 - xnamecolor, ynamecolor, znamecolor - colors of axes names
14180 - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values
14181 from tickmarks or axis. Default: 10
14182 - valuesfont - font of axes values. Default: Arial
14183 - xcolor, ycolor, zcolor - color of axis and values
14184 - xticks, yticks, xzicks - number of tickmark on axes. Default: 5
14185 - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10
14186 )" /* [vgraduatedtrihedron] */);
14188 addCmd ("vtile", VTile, /* [vtile] */ R"(
14189 vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]
14190 Setup view to draw a tile (a part of virtual bigger viewport).
14191 -totalSize the size of virtual bigger viewport
14192 -tileSize tile size (the view size will be used if omitted)
14193 -lowerLeft tile offset as lower left corner
14194 -upperLeft tile offset as upper left corner
14197 addCmd ("vzlayer", VZLayer, /* [vzlayer] */ R"(
14199 [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]
14200 [-origin X Y Z] [-cullDist Distance] [-cullSize Size]
14201 [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]
14202 [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]
14203 ZLayer list management
14204 -add add new z layer to viewer and print its id
14205 -insertBefore add new z layer and insert it before existing one
14206 -insertAfter add new z layer and insert it after existing one
14207 -delete delete z layer
14208 -get print sequence of z layers
14209 -settings print status of z layer settings
14210 -disable disables given setting
14211 -enable enables given setting
14212 )" /* [vzlayer] */);
14214 addCmd ("vlayerline", VLayerLine, /* [vlayerline] */ R"(
14215 vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]
14216 )" /* [vlayerline] */);
14218 addCmd ("vgrid", VGrid, /* [vgrid] */ R"(
14219 vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]
14220 [-step X Y] [-size DX DY]
14221 [-step StepRadius NbDivisions] [-radius Radius]
14224 addCmd ("vpriviledgedplane", VPriviledgedPlane, /* [vpriviledgedplane] */ R"(
14225 vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]
14226 Sets or prints viewer's priviledged plane geometry:
14227 Ox, Oy, Oz - plane origin;
14228 Nx, Ny, Nz - plane normal direction;
14229 Xx, Xy, Xz - plane x-reference axis direction.
14230 )" /* [vpriviledgedplane] */);
14232 addCmd ("vconvert", VConvert, /* [vconvert] */ R"(
14233 vconvert v [Mode={window|view}]
14234 vconvert x y [Mode={window|view|grid|ray}]
14235 vconvert x y z [Mode={window|grid}]
14236 Convert the given coordinates to window/view/model space:
14237 - window - convert to window coordinates, pixels;
14238 - view - convert to view projection plane;
14239 - grid - convert to model coordinates, given on grid;
14240 - ray - convert projection ray to model coordinates.
14241 )" /* [vconvert] */);
14243 addCmd ("vfps", VFps, /* [vfps] */ R"(
14244 vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view.
14247 addCmd ("vstereo", VStereo, /* [vstereo] */ R"(
14248 vstereo [0|1] [-mode Mode] [-reverse {0|1}]
14249 [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]
14250 [-anaglyph Filter] [-smoothInterlacing]
14251 Control stereo output mode. Available modes for -mode:
14252 quadBuffer OpenGL QuadBuffer stereo;
14253 requires driver support;
14254 should be called BEFORE vinit!
14255 anaglyph Anaglyph glasses, filters for -anaglyph:
14256 redCyan, redCyanSimple, yellowBlue, yellowBlueSimple, greenMagentaSimple.
14257 rowInterlaced row-interlaced display
14258 smooth smooth interlaced output for better text readability
14259 columnInterlaced column-interlaced display
14260 chessBoard chess-board output
14261 sideBySide horizontal pair
14262 overUnder vertical pair
14263 openVR OpenVR (HMD), extra options:
14264 -mirrorComposer flag to mirror VR frame in the window (debug);
14265 -unitFactor specifies meters scale factor for mapping VR input.
14266 )" /* [vstereo] */);
14268 addCmd ("vmemgpu", VMemGpu, /* [vmemgpu] */ R"(
14269 vmemgpu [f]: print system-dependent GPU memory information if available;
14270 with f option returns free memory in bytes.
14271 )" /* [vmemgpu] */);
14273 addCmd ("vreadpixel", VReadPixel, /* [vreadpixel] */ R"(
14274 vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]
14275 Read pixel value for active view.
14276 )" /* [vreadpixel] */);
14278 addCmd ("diffimage", VDiffImage, /* [diffimage] */ R"(
14279 diffimage imageFile1 imageFile2 [diffImageFile]
14280 [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]
14281 [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]
14282 Compare two images by content and generate difference image.
14283 When -exitOnClose is specified, closing the view will exit application.
14284 When -closeOnEscape is specified, view will be closed on pressing Escape.
14285 )" /* [diffimage] */);
14287 addCmd ("vselect", VSelect, /* [vselect] */ R"(
14288 vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1]
14289 [-replace|-replaceextra|-xor|-add|-remove]
14290 Emulate different types of selection:
14291 1) Single click selection.
14292 2) Selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2).
14293 3) Selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn).
14294 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.
14295 If the flag is set to 1, both sensitives that were included completely
14296 and overlapped partially by defined rectangle or polygon will be detected,
14297 otherwise algorithm will chose only fully included sensitives.
14298 Default behavior is to detect only full inclusion
14299 (partial inclusion - overlap - is not allowed by default).
14300 5) Selection scheme replace, replaceextra, xor, add or remove (replace by default).
14301 )" /* [vselect] */);
14303 addCmd ("vmoveto", VMoveTo, /* [vmoveto] */ R"(
14304 vmoveto [x y] [-reset]
14305 Emulate cursor movement to pixel position (x,y).
14306 -reset resets current highlighting.
14307 )" /* [vmoveto] */);
14309 addCmd ("vselaxis", VSelectByAxis, /* [vselaxis] */ R"(
14310 vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14311 Provides intersection by given axis and print result intersection points.
14312 -onlyTop switches On/Off mode to find only top point or all;
14313 -display Name displays intersecting axis and result intersection points for debug goals;
14314 -showNormal adds displaying of normal in intersection point or not.
14315 )" /* [vselaxis] */);
14317 addCmd ("vviewparams", VViewParams, /* [vviewparams] */ R"(
14318 vviewparams [-args] [-scale [s]]
14319 [-eye [x y z]] [-at [x y z]] [-up [x y z]]
14320 [-proj [x y z]] [-center x y] [-size sx]
14321 Manage current view parameters (camera orientation) or prints all
14322 current values when called without argument.
14323 -scale [s] prints or sets viewport relative scale
14324 -eye [x y z] prints or sets eye location
14325 -at [x y z] prints or sets center of look
14326 -up [x y z] prints or sets direction of up vector
14327 -proj [x y z] prints or sets direction of look
14328 -center x y sets location of center of the screen in pixels
14329 -size [sx] prints viewport projection width and height sizes
14330 or changes the size of its maximum dimension
14331 -args prints vviewparams arguments for restoring current view
14332 )" /* [vviewparams] */);
14334 addCmd ("v2dmode", V2DMode, /* [v2dmode] */ R"(
14335 v2dmode [-name viewName] [-mode {-on|-off}=-on]
14336 name - name of existing view, if not defined, the active view is changed;
14337 mode - switches On/Off rotation mode.
14338 Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:
14339 - rotation of the view by 3rd mouse button with Ctrl active
14340 - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right
14341 View camera position might be changed only by commands.
14342 )" /* [v2dmode] */);
14344 addCmd ("vanimation", VAnimation, /* [vanimation] */ R"(
14346 )" /* [vanimation] */);
14348 addCmd ("vanim", VAnimation, /* [vanim] */ R"(
14349 List existing animations:
14352 Animation playback:
14353 vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]]
14354 [-speed Coeff] [-freeLook] [-noPauseOnClick] [-lockLoop]
14356 -speed playback speed (1.0 is normal speed)
14357 -freeLook skip camera animations
14358 -noPauseOnClick do not pause animation on mouse click
14359 -lockLoop disable any interactions
14361 Animation definition:
14362 vanim Name/sub/name [-clear] [-delete]
14363 [-start TimeSec] [-duration TimeSec] [-end TimeSec]
14365 Animation name defined in path-style (anim/name or anim.name)
14366 specifies nested animations.
14367 There is no syntax to explicitly add new animation,
14368 and all non-existing animations within the name will be
14369 implicitly created on first use (including parents).
14371 Each animation might define the SINGLE action (see below),
14372 like camera transition, object transformation or custom callback.
14373 Child animations can be used for defining concurrent actions.
14376 vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]
14377 [-at1 X Y Z] [-at2 X Y Z]
14378 [-up1 X Y Z] [-up2 X Y Z]
14379 [-scale1 Scale] [-scale2 Scale]
14380 -eyeX camera Eye positions pair (start and end)
14381 -atX camera Center positions pair
14382 -upX camera Up directions pair
14383 -scaleX camera Scale factors pair
14386 vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]
14387 [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]
14388 [-scale1 Scale] [-scale2 Scale]
14389 -locX object Location points pair (translation)
14390 -rotX object Orientations pair (quaternions)
14391 -scaleX object Scale factors pair (quaternions)
14394 vanim name -invoke "Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN"
14396 %Pts overall animation presentation timestamp
14397 %LocalPts local animation timestamp
14398 %Normalized local animation normalized value in range 0..1
14401 vanim name -record FileName [Width Height] [-fps FrameRate=24]
14402 [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]
14403 [-crf Value] [-preset Preset]
14404 -fps video framerate
14405 -format file format, container (matroska, etc.)
14406 -vcodec video codec identifier (ffv1, mjpeg, etc.)
14407 -pix_fmt image pixel format (yuv420p, rgb24, etc.)
14408 -crf constant rate factor (specific to codec)
14409 -preset codec parameters preset (specific to codec)
14412 addCmd ("vchangeselected", VChangeSelected, /* [vchangeselected] */ R"(
14413 vchangeselected shape : Add shape to selection or remove one from it.
14414 )" /* [vchangeselected] */);
14416 addCmd ("vnbselected", VNbSelected, /* [vnbselected] */ R"(
14417 vnbselected : Returns number of selected objects in the interactive context.
14418 )" /* [vnbselected] */);
14420 addCmd ("vcamera", VCamera, /* [vcamera] */ R"(
14421 vcamera [PrsName] [-ortho] [-projtype]
14423 [-fovy [Angle]] [-distance [Distance]]
14424 [-stereo] [-leftEye] [-rightEye]
14425 [-iod [Distance]] [-iodType [absolute|relative]]
14426 [-zfocus [Value]] [-zfocusType [absolute|relative]]
14427 [-fov2d [Angle]] [-lockZup {0|1}]
14428 [-rotationMode {active|pick|pickCenter|cameraAt|scene}]
14429 [-navigationMode {orbit|walk|flight}]
14430 [-xrPose base|head=base]
14431 Manages camera parameters.
14432 Displays frustum when presentation name PrsName is specified.
14433 Prints current value when option called without argument.
14435 Orthographic camera:
14436 -ortho activate orthographic projection.
14438 Perspective camera:
14439 -persp activate perspective projection (mono);
14440 -fovy field of view in y axis, in degrees;
14441 -fov2d field of view limit for 2d on-screen elements;
14442 -distance distance of eye from camera center;
14443 -lockZup lock Z up (turntable mode);
14444 -rotationMode rotation mode (gravity point);
14445 -navigationMode navigation mode.
14447 Stereoscopic camera:
14448 -stereo perspective projection (stereo);
14449 -leftEye perspective projection (left eye);
14450 -rightEye perspective projection (right eye);
14451 -iod intraocular distance value;
14452 -iodType distance type, absolute or relative;
14453 -zfocus stereographic focus value;
14454 -zfocusType focus type, absolute or relative.
14455 )" /* [vcamera] */);
14457 addCmd ("vautozfit", VAutoZFit, /* [vautozfit] */ R"(
14458 vautozfit [on={1|0}] [scale]
14459 Prints or changes parameters of automatic z-fit mode:
14460 "on" - turns automatic z-fit on or off;
14461 "scale" - specifies factor to scale computed z range.
14462 )" /* [vautozfit] */);
14464 addCmd ("vzrange", VZRange, /* [vzrange] */ R"(
14465 vzrange [znear] [zfar]
14466 Applies provided znear/zfar to view or prints current values.
14467 )" /* [vzrange] */);
14469 addCmd ("vsetviewsize", VSetViewSize, /* [vsetviewsize] */ R"(
14471 )" /* [vsetviewsize] */);
14473 addCmd ("vmoveview", VMoveView, /* [vmoveview] */ R"(
14474 vmoveview Dx Dy Dz [Start = 1|0]
14475 )" /* [vmoveview] */);
14477 addCmd ("vtranslateview", VTranslateView, /* [vtranslateview] */ R"(
14478 vtranslateview Dx Dy Dz [Start = 1|0)]
14479 )" /* [vtranslateview] */);
14481 addCmd ("vturnview", VTurnView, /* [vturnview] */ R"(
14482 vturnview Ax Ay Az [Start = 1|0]
14483 )" /* [vturnview] */);
14485 addCmd ("vtextureenv", VTextureEnv, /* [vtextureenv] */ R"(
14486 vtextureenv {on|off} {image_file}
14487 [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} ss st ts tt rot]
14488 Enables or disables environment mapping in the 3D view, loading the texture from the given standard
14489 or user-defined file and optionally applying texture mapping parameters.
14490 ss, st - scale factors for s and t texture coordinates;
14491 ts, tt - translation for s and t texture coordinates;
14492 rot - texture rotation angle in degrees.
14493 )" /* [vtextureenv] */);
14495 addCmd ("vhlr", VHLR, /* [vhlr] */ R"(
14496 vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]
14497 Hidden Line Removal algorithm.
14498 -showHidden if set ON, hidden lines are drawn as dotted ones;
14499 -algoType type of HLR algorithm:
14500 'algo' - exact HLR algorithm is applied;
14501 'polyAlgo' - polygonal HLR algorithm is applied.
14504 addCmd ("vhlrtype", VHLRType, /* [vhlrtype] */ R"(
14505 vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]
14506 Changes the type of HLR algorithm using for shapes:
14507 'algo' - exact HLR algorithm is applied;
14508 'polyAlgo' - polygonal HLR algorithm is applied.
14509 If shapes are not given - option is applied to all shapes in the view.
14510 )" /* [vhlrtype] */);
14512 addCmd ("vclipplane", VClipPlane, /* [vclipplane] */ R"(
14513 vclipplane planeName [{0|1}]
14514 [-equation1 A B C D]
14515 [-equation2 A B C D]
14516 [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]
14517 [-set|-unset|-setOverrideGlobal [objects|views]]
14520 [-color R G B] [-transparency Value] [-hatch {on|off|ID}]
14521 [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]
14523 [-useObjMaterial {0|1}] [-useObjTexture {0|1}]
14524 [-useObjShader {0|1}]
14526 Clipping planes management:
14527 -maxPlanes print plane limit for view;
14528 -delete delete plane with given name;
14529 {off|on|0|1} turn clipping on/off;
14530 -set|-unset set/unset plane for Object or View list;
14531 applied to active View when list is omitted;
14532 -equation A B C D change plane equation;
14533 -clone SourcePlane NewPlane clone the plane definition.
14536 -capping {off|on|0|1} turn capping on/off;
14537 -color R G B set capping color;
14538 -transparency Value set capping transparency 0..1;
14539 -texName Texture set capping texture;
14540 -texScale SX SY set capping tex scale;
14541 -texOrigin TX TY set capping tex origin;
14542 -texRotate Angle set capping tex rotation;
14543 -hatch {on|off|ID} set capping hatching mask;
14544 -useObjMaterial {off|on|0|1} use material of clipped object;
14545 -useObjTexture {off|on|0|1} use texture of clipped object;
14546 -useObjShader {off|on|0|1} use shader program of object.
14547 )" /* [vclipplane] */);
14549 addCmd ("vdefaults", VDefaults, /* [vdefaults] */ R"(
14550 vdefaults [-absDefl value] [-devCoeff value] [-angDefl value]
14551 [-autoTriang {off/on | 0/1}]
14552 )" /* [vdefaults] */);
14554 addCmd ("vlight", VLight, /* [vlight] */ R"(
14555 vlight [lightName] [-noupdate]
14556 [-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]
14557 [-type {ambient|directional|spotlight|positional}] [-name value]
14558 [-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]
14559 [-headlight 0|1] [-castShadows 0|1]
14560 [-range value] [-constAttenuation value] [-linearAttenuation value]
14561 [-spotExponent value] [-spotAngle angleDeg]
14562 [-smoothAngle value] [-smoothRadius value]
14563 [-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]
14566 Command manages light sources. Without arguments shows list of lights.
14567 Arguments affecting the list of defined/active lights:
14568 -clear remove all light sources;
14569 -defaults defines two standard light sources;
14570 -reset resets light source parameters to default values;
14571 -type sets type of light source;
14572 -name sets new name to light source;
14573 -global assigns light source to all views (default state);
14574 -local assigns light source to active view;
14575 -zlayer assigns light source to specified Z-Layer.
14577 Ambient light parameters:
14578 -color sets (normalized) light color;
14579 -intensity sets intensity of light source, 1.0 by default;
14580 affects also environment cubemap intensity.
14582 Point light parameters:
14583 -color sets (normalized) light color;
14584 -intensity sets PBR intensity;
14585 -range sets clamping distance;
14586 -constAtten (obsolete) sets constant attenuation factor;
14587 -linearAtten (obsolete) sets linear attenuation factor;
14588 -smoothRadius sets PBR smoothing radius.
14590 Directional light parameters:
14591 -color sets (normalized) light color;
14592 -intensity sets PBR intensity;
14593 -direction sets direction;
14594 -headlight sets headlight flag;
14595 -castShadows enables/disables shadow casting;
14596 -smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range.
14598 Spot light parameters:
14599 -color sets (normalized) light color;
14600 -intensity sets PBR intensity;
14601 -range sets clamping distance;
14602 -position sets position;
14603 -direction sets direction;
14604 -spotAngle sets spotlight angle;
14605 -spotExp sets spotlight exponenta;
14606 -headlight sets headlight flag;
14607 -constAtten (obsolete) sets constant attenuation factor;
14608 -linearAtten (obsolete) sets linear attenuation factor.
14610 Light presentation parameters:
14611 -display adds light source presentation;
14612 -showName shows/hides the name of light source; 1 by default;
14613 -showRange shows/hides the range of spot/positional light source; 1 by default;
14614 -prsZoomable makes light presentation zoomable/non-zoomable;
14615 -prsDraggable makes light presentation draggable/non-draggable;
14616 -prsSize sets light presentation size;
14617 -arcSize sets arc presentation size(in pixels)
14618 for rotation directional light source; 25 by default.
14621 vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED
14622 vlight redlight -delete
14623 )" /* [vlight] */);
14625 addCmd ("vpbrenv", VPBREnvironment, /* [vpbrenv] */ R"(
14626 vpbrenv -clear|-generate
14627 Clears or generates PBR environment map of active view.
14628 -clear clears PBR environment (fills by white color);
14629 -generate generates PBR environment from current background cubemap.
14630 )" /* [vpbrenv] */);
14632 addCmd ("vraytrace", VRenderParams, /* [vraytrace] */ R"(
14633 vraytrace [0|1] : Turns on/off ray-tracing renderer.
14634 'vraytrace 0' alias for 'vrenderparams -raster'.
14635 'vraytrace 1' alias for 'vrenderparams -rayTrace'.
14636 )" /* [vraytrace] */);
14638 addCmd ("vrenderparams", VRenderParams, /* [vrenderparams] */ R"(
14639 Manages rendering parameters, affecting visual appearance, quality and performance.
14640 Should be applied taking into account GPU hardware capabilities and performance.
14643 vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]
14644 [-msaa 0..8=0] [-rendScale scale=1]
14645 [-resolution value=72] [-fontHinting {off|normal|light}=off]
14646 [-fontAutoHinting {auto|force|disallow}=auto]
14647 [-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]
14648 [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]
14649 [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]
14650 [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]
14651 [-sync {default|views}] [-reset]
14652 -raster Disables GPU ray-tracing.
14653 -shadingModel Controls shading model.
14654 -msaa Specifies number of samples for MSAA.
14655 -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA).
14656 -resolution Sets new pixels density (PPI) used as text scaling factor.
14657 -fontHinting Enables/disables font hinting for better readability on low-resolution screens.
14658 -fontAutoHinting Manages font autohinting.
14659 -lineFeather Sets line feather factor while displaying mesh edges.
14660 -alphaToCoverage Enables/disables alpha to coverage (needs MSAA).
14661 -oit Enables/disables order-independent transparency (OIT) rendering;
14662 off unordered transparency (but opaque objects implicitly draw first);
14663 weighted weight OIT is managed by depth weight factor 0.0..1.0;
14664 peeling depth peeling OIT is managed by number of peeling layers.
14665 -shadows Enables/disables shadows rendering.
14666 -shadowMapResolution Shadow texture map resolution.
14667 -shadowMapBias Shadow map bias.
14668 -depthPrePass Enables/disables depth pre-pass.
14669 -frustumCulling Enables/disables objects frustum clipping or
14670 sets state to check structures culled previously.
14671 -sync Sets active View parameters as Viewer defaults / to other Views.
14672 -reset Resets active View parameters to Viewer defaults.
14674 Diagnostic output (on-screen overlay):
14675 vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points
14676 |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]
14677 [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]
14678 -perfCounters Show/hide performance counters (flags can be combined).
14679 -perfUpdateInterval Performance counters update interval.
14680 -perfChart Show frame timers chart limited by specified number of frames.
14681 -perfChartMax Maximum time in seconds with the chart.
14683 Ray-Tracing options:
14684 vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]
14685 [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]
14686 [-gi {on|off}=off] [-brng {on|off}=off]
14687 [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]
14688 [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]
14689 [-maxRad {value>0}=30.0]
14690 [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]
14691 [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]
14692 -rayTrace Enables GPU ray-tracing.
14693 -rayDepth Defines maximum ray-tracing depth.
14694 -reflections Enables/disables specular reflections.
14695 -fsaa Enables/disables adaptive anti-aliasing.
14696 -gleam Enables/disables transparency shadow effects.
14697 -gi Enables/disables global illumination effects (Path-Tracing).
14698 -env Enables/disables environment map background.
14699 -ignoreNormalMap Enables/disables normal map ignoring during path tracing.
14700 -twoSide Enables/disables two-sided BSDF models (PT mode).
14701 -iss Enables/disables adaptive screen sampling (PT mode).
14702 -maxRad Value used for clamping radiance estimation (PT mode).
14703 -tileSize Specifies size of screen tiles in ISS mode (32 by default).
14704 -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default).
14705 -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF).
14706 -focal Focal distance of perspective camera for depth-of-field effect.
14707 -exposure Exposure value for tone mapping (0.0 value disables the effect).
14708 -whitePoint White point value for filmic tone mapping.
14709 -toneMapping Tone mapping mode (disabled, filmic).
14711 PBR environment baking parameters (advanced/debug):
14712 vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]
14713 [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]
14714 -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size).
14715 -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map.
14716 -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during
14717 diffuse IBL map's sherical harmonics calculation.
14718 -pbrEnvBSSN Controls maximum number of samples per mipmap level
14719 in Monte-Carlo integration during specular IBL maps generation.
14720 -pbrEnvBP Controls strength of samples number reducing
14721 during specular IBL maps generation (1 disables reducing).
14724 vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]
14725 -issd Shows screen sampling distribution in ISS mode.
14726 -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging).
14727 -brng Enables/disables blocked RNG (fast coherent PT).
14728 )" /* [vrenderparams] */);
14730 addCmd ("vstatprofiler", VStatProfiler, /* [vstatprofiler] */ R"(
14731 vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups
14732 |allArrays|fillArrays|lineArrays|pointArrays|textArrays
14733 |triangles|points|geomMem|textureMem|frameMem
14734 |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage
14735 |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]
14737 Prints rendering statistics for specified counters or for all when unspecified.
14738 Set '-noredraw' flag to avoid additional redraw call and use already collected values.
14739 )" /* [vstatprofiler] */);
14741 addCmd ("vplace", VPlace, /* [vplace] */ R"(
14742 vplace dx dy : Places the point (in pixels) at the center of the window
14743 )" /* [vplace] */);
14745 addCmd ("vxrotate", VXRotate, /* [vxrotate] */ R"(
14747 )" /* [vxrotate] */);
14749 addCmd ("vmanipulator", VManipulator, /* [vmanipulator] */ R"(
14750 vmanipulator Name [-attach AISObject | -detach | ...]
14751 Tool to create and manage AIS manipulators.
14753 '-attach AISObject' attach manipulator to AISObject
14754 '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching
14755 '-adjustSize {0|1}' adjust size when attaching
14756 '-enableModes {0|1}' enable modes when attaching
14757 '-view {active | [name of view]}' display manipulator only in defined view,
14758 by default it is displayed in all views of the current viewer
14759 '-detach' detach manipulator
14760 '-startTransform mouse_x mouse_y' - invoke start of transformation
14761 '-transform mouse_x mouse_y' - invoke transformation
14762 '-stopTransform [abort]' - invoke stop of transformation
14763 '-move x y z' - move attached object
14764 '-rotate x y z dx dy dz angle' - rotate attached object
14765 '-scale factor' - scale attached object
14766 '-autoActivate {0|1}' - set activation on detection
14767 '-followTranslation {0|1}' - set following translation transform
14768 '-followRotation {0|1}' - set following rotation transform
14769 '-followDragging {0|1}' - set following dragging transform
14770 '-gap value' - set gap between sub-parts
14771 '-part axis mode {0|1}' - set visual part
14772 '-parts axis mode {0|1}' - set visual part
14773 '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator
14774 '-size value' - set size of manipulator
14775 '-zoomable {0|1}' - set zoom persistence
14776 )" /* [vmanipulator] */);
14778 addCmd ("vselprops", VSelectionProperties, /* [vselprops] */ R"(
14779 vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]
14780 Customizes selection and dynamic highlight parameters for the whole interactive context:
14781 -autoActivate {0|1} disables|enables default computation
14782 and activation of global selection mode
14783 -autoHighlight {0|1} disables|enables automatic highlighting in 3D Viewer
14784 -highlightSelected {0|1} disables|enables highlighting of detected object in selected state
14785 -pickStrategy {first|topmost} : defines picking strategy
14786 'first' to pick first acceptable (default)
14787 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)
14788 -pixTol value sets up pixel tolerance
14789 -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth
14790 -depthTol {sensfactor} use sensitive factor for sorting results by depth
14791 -preferClosest {0|1} sets if depth should take precedence over priority while sorting results
14792 -dispMode dispMode sets display mode for highlighting
14793 -layer ZLayer sets ZLayer for highlighting
14794 -color {name|r g b} sets highlight color
14795 -transp value sets transparency coefficient for highlight
14796 -material material sets highlight material
14797 -print prints current state of all mentioned parameters
14798 )" /* [vselprops] */);
14800 addCmd ("vhighlightselected", VSelectionProperties, /* [vhighlightselected] */ R"(
14801 vhighlightselected [0|1] : alias for vselprops -highlightSelected.
14802 )" /* [vhighlightselected] */);
14804 addCmd ("vseldump", VDumpSelectionImage, /* [vseldump] */ R"(
14805 vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|entityType|surfNormal}=depth
14806 -pickedIndex Index=1
14807 [-xrPose base|head=base]
14808 Generate an image based on detection results:
14809 depth normalized depth values
14810 unnormDepth unnormalized depth values
14811 object color of detected object
14812 owner color of detected owner
14813 selMode color of selection mode
14814 entity color of detected entity
14815 entityType color of detected entity type
14816 surfNormal normal direction values
14817 )" /* [vseldump] */);
14819 addCmd ("vviewcube", VViewCube, /* [vviewcube] */ R"(
14821 Displays interactive view manipulation object. Options:
14822 -reset reset geometric and visual attributes
14823 -size Size adapted size of View Cube
14824 -boxSize Size box size
14825 -axes {0|1} show/hide axes (trihedron)
14826 -edges {0|1} show/hide edges of View Cube
14827 -vertices {0|1} show/hide vertices of View Cube
14828 -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation
14829 -color Color color of View Cube
14830 -boxColor Color box color
14831 -boxSideColor Color box sides color
14832 -boxEdgeColor Color box edges color
14833 -boxCornerColor Color box corner color
14834 -textColor Color color of side text of view cube
14835 -innerColor Color inner box color
14836 -transparency Value transparency of object within [0, 1] range
14837 -boxTransparency Value transparency of box within [0, 1] range
14838 -xAxisTextColor Color color of X axis label
14839 -yAxisTextColor Color color of Y axis label
14840 -zAxisTextColor Color color of Z axis label
14841 -font Name font name
14842 -fontHeight Value font height
14843 -boxFacetExtension Value box facet extension
14844 -boxEdgeGap Value gap between box edges and box sides
14845 -boxEdgeMinSize Value minimal box edge size
14846 -boxCornerMinSize Value minimal box corner size
14847 -axesPadding Value padding between box and arrows
14848 -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range
14849 -axesRadius Value radius of axes of the trihedron
14850 -axesConeRadius Value radius of the cone (arrow) of the trihedron
14851 -axesSphereRadius Value radius of the sphere (central point) of trihedron
14852 -fixedAnimation {0|1} uninterruptible animation loop
14853 -duration Seconds animation duration in seconds
14854 )" /* [vviewcube] */);
14856 addCmd ("vcolorconvert", VColorConvert, /* [vcolorconvert] */ R"(
14857 vcolorconvert [-from {sRGB|HLS|Lab|Lch|RGB}]=RGB [-to {sRGB|HLS|Lab|Lch|RGB|hex|name}]=RGB C1 C2 C2
14858 To convert color from specified color space to linear RGB:
14859 vcolorconvert -from {sRGB|HLS|Lab|Lch|RGB} C1 C2 C2
14860 To convert linear RGB color to specified color space:
14861 vcolorconvert -to {sRGB|HLS|Lab|Lch|RGB|hex|name} R G B
14862 )" /* [vcolorconvert] */);
14864 addCmd ("vcolordiff", VColorDiff, /* [vcolordiff] */ R"(
14865 vcolordiff R1 G1 B1 R2 G2 B2 : returns CIEDE2000 color difference between two RGB colors.
14866 )" /* [vcolordiff] */);
14868 addCmd ("vselbvhbuild", VSelBvhBuild, /* [vselbvhbuild] */ R"(
14869 vselbvhbuild [{0|1}] [-nbThreads value] [-wait]
14870 Turns on/off prebuilding of BVH within background thread(s).
14871 -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1);
14872 -wait waits for building all of BVH.
14873 )" /* [vselbvhbuild] */);