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_AnimationAxisRotation.hxx>
24 #include <AIS_AnimationCamera.hxx>
25 #include <AIS_AnimationObject.hxx>
26 #include <AIS_Axis.hxx>
27 #include <AIS_CameraFrustum.hxx>
28 #include <AIS_ColorScale.hxx>
29 #include <AIS_InteractiveContext.hxx>
30 #include <AIS_LightSource.hxx>
31 #include <AIS_ListOfInteractive.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>
39 #include <Draw_Appli.hxx>
40 #include <Draw_Interpretor.hxx>
41 #include <Draw_ProgressIndicator.hxx>
45 #include <Geom_Axis2Placement.hxx>
46 #include <Geom_CartesianPoint.hxx>
47 #include <Graphic3d_ArrayOfPolylines.hxx>
48 #include <Graphic3d_AspectFillArea3d.hxx>
49 #include <Graphic3d_ClipPlane.hxx>
50 #include <Graphic3d_CubeMapPacked.hxx>
51 #include <Graphic3d_CubeMapSeparate.hxx>
52 #include <Graphic3d_GraduatedTrihedron.hxx>
53 #include <Graphic3d_GraphicDriver.hxx>
54 #include <Graphic3d_GraphicDriverFactory.hxx>
55 #include <Graphic3d_NameOfTextureEnv.hxx>
56 #include <Graphic3d_Texture2D.hxx>
57 #include <Graphic3d_TextureEnv.hxx>
58 #include <Graphic3d_TextureParams.hxx>
59 #include <Graphic3d_TypeOfTextureFilter.hxx>
60 #include <Image_AlienPixMap.hxx>
61 #include <Image_Diff.hxx>
62 #include <Image_VideoRecorder.hxx>
63 #include <Message.hxx>
64 #include <Message_ProgressScope.hxx>
65 #include <NCollection_DataMap.hxx>
66 #include <NCollection_List.hxx>
67 #include <NCollection_LocalArray.hxx>
68 #include <OSD_Parallel.hxx>
69 #include <OSD_Timer.hxx>
70 #include <Prs3d_ShadingAspect.hxx>
71 #include <Prs3d_DatumAspect.hxx>
72 #include <Prs3d_Drawer.hxx>
73 #include <Prs3d_LineAspect.hxx>
74 #include <Prs3d_Text.hxx>
75 #include <Select3D_SensitivePrimitiveArray.hxx>
76 #include <TColStd_HSequenceOfAsciiString.hxx>
77 #include <TColStd_SequenceOfInteger.hxx>
78 #include <TColStd_HSequenceOfReal.hxx>
79 #include <ViewerTest_AutoUpdater.hxx>
80 #include <ViewerTest_ContinuousRedrawer.hxx>
81 #include <ViewerTest_EventManager.hxx>
82 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
83 #include <ViewerTest_CmdParser.hxx>
84 #include <ViewerTest_V3dView.hxx>
85 #include <V3d_AmbientLight.hxx>
86 #include <V3d_DirectionalLight.hxx>
87 #include <V3d_PositionalLight.hxx>
88 #include <V3d_SpotLight.hxx>
89 #include <V3d_Trihedron.hxx>
90 #include <V3d_Viewer.hxx>
91 #include <UnitsAPI.hxx>
96 #include <WNT_WClass.hxx>
97 #include <WNT_Window.hxx>
98 #elif defined(HAVE_XLIB)
99 #include <Xw_Window.hxx>
100 #include <X11/Xlib.h>
101 #include <X11/Xutil.h>
102 #elif defined(__APPLE__)
103 #include <Cocoa_Window.hxx>
104 #elif defined(__EMSCRIPTEN__)
105 #include <Wasm_Window.hxx>
106 #include <emscripten/emscripten.h>
108 #include <Aspect_NeutralWindow.hxx>
111 //==============================================================================
112 // VIEWER GLOBAL VARIABLES
113 //==============================================================================
115 Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
116 Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
118 Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
119 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
122 typedef WNT_Window ViewerTest_Window;
123 #elif defined(HAVE_XLIB)
124 typedef Xw_Window ViewerTest_Window;
125 static void VProcessEvents(ClientData,int);
126 #elif defined(__APPLE__)
127 typedef Cocoa_Window ViewerTest_Window;
128 extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
129 extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
130 #elif defined(__EMSCRIPTEN__)
131 typedef Wasm_Window ViewerTest_Window;
133 typedef Aspect_NeutralWindow ViewerTest_Window;
136 #if defined(__EMSCRIPTEN__)
137 //! Return DOM id of default WebGL canvas from Module.canvas.
138 EM_JS(char*, occJSModuleCanvasId, (), {
139 const aCanvasId = Module.canvas.id;
140 const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
141 const aStrPtr = Module._malloc (aNbBytes);
142 stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
146 //! Return DOM id of default WebGL canvas from Module.canvas.
147 static TCollection_AsciiString getModuleCanvasId()
149 char* aRawId = occJSModuleCanvasId();
150 TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
158 static Handle(ViewerTest_Window)& VT_GetWindow()
160 static Handle(ViewerTest_Window) aWindow;
164 static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
166 static Handle(Aspect_DisplayConnection) aDisplayConnection;
167 return aDisplayConnection;
170 using ViewerTest_ViewerCommandsViewMap = NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>;
171 using ViewerTest_ViewerCommandsInteractiveContextMap = NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>;
172 using ViewerTest_ViewerCommandsGraphicDriverMap = NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>;
174 static void SetDisplayConnection(const Handle(Aspect_DisplayConnection)& theDisplayConnection)
176 GetDisplayConnection() = theDisplayConnection;
179 static ViewerTest_ViewerCommandsInteractiveContextMap ViewerTest_myContexts;
180 static ViewerTest_ViewerCommandsGraphicDriverMap ViewerTest_myDrivers;
183 ViewerTest_ViewerCommandsViewMap ViewerTest_myViews;
187 Quantity_Color FlatColor;
188 Quantity_Color GradientColor1;
189 Quantity_Color GradientColor2;
190 Aspect_GradientFillMethod FillMethod;
192 //! Sets the gradient filling for a background in a default viewer.
193 void SetDefaultGradient()
195 for (ViewerTest_ViewerCommandsInteractiveContextMap::Iterator aCtxIter (ViewerTest_myContexts);
196 aCtxIter.More(); aCtxIter.Next())
198 const Handle (V3d_Viewer)& aViewer = aCtxIter.Key2()->CurrentViewer();
199 aViewer->SetDefaultBgGradientColors (GradientColor1, GradientColor2, FillMethod);
203 //! Sets the color used for filling a background in a default viewer.
204 void SetDefaultColor()
206 for (ViewerTest_ViewerCommandsInteractiveContextMap::Iterator aCtxIter (ViewerTest_myContexts);
207 aCtxIter.More(); aCtxIter.Next())
209 const Handle (V3d_Viewer)& aViewer = aCtxIter.Key2()->CurrentViewer();
210 aViewer->SetDefaultBackgroundColor (FlatColor);
214 } ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GradientFillMethod_None };
216 //==============================================================================
217 // EVENT GLOBAL VARIABLES
218 //==============================================================================
221 static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
224 //==============================================================================
227 //==============================================================================
229 const Handle(WNT_WClass)& ViewerTest::WClass()
231 static Handle(WNT_WClass) theWClass;
233 if (theWClass.IsNull())
235 theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
236 CS_VREDRAW | CS_HREDRAW, 0, 0,
237 ::LoadCursor (NULL, IDC_ARROW));
243 //==============================================================================
244 //function : CreateName
245 //purpose : Create numerical name for new object in theMap
246 //==============================================================================
247 template <typename ObjectType>
248 TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
249 const TCollection_AsciiString& theDefaultString)
251 if (theObjectMap.IsEmpty())
252 return theDefaultString + TCollection_AsciiString(1);
254 Standard_Integer aNextKey = 1;
255 Standard_Boolean isFound = Standard_False;
258 TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
259 // Look for objects with default names
260 if (theObjectMap.IsBound1(aStringKey))
265 isFound = Standard_True;
268 return theDefaultString + TCollection_AsciiString(aNextKey);
271 //==============================================================================
272 //structure : ViewerTest_Names
273 //purpose : Allow to operate with full view name: driverName/viewerName/viewName
274 //==============================================================================
275 struct ViewerTest_Names
278 TCollection_AsciiString myDriverName;
279 TCollection_AsciiString myViewerName;
280 TCollection_AsciiString myViewName;
284 const TCollection_AsciiString& GetDriverName () const
288 void SetDriverName (const TCollection_AsciiString& theDriverName)
290 myDriverName = theDriverName;
292 const TCollection_AsciiString& GetViewerName () const
296 void SetViewerName (const TCollection_AsciiString& theViewerName)
298 myViewerName = theViewerName;
300 const TCollection_AsciiString& GetViewName () const
304 void SetViewName (const TCollection_AsciiString& theViewName)
306 myViewName = theViewName;
309 //===========================================================================
310 //function : Constructor for ViewerTest_Names
311 //purpose : Get view, viewer, driver names from custom string
312 //===========================================================================
314 ViewerTest_Names (const TCollection_AsciiString& theInputString)
316 TCollection_AsciiString aName(theInputString);
317 if (theInputString.IsEmpty())
319 // Get current configuration
320 if (ViewerTest_myDrivers.IsEmpty())
321 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
322 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
324 myDriverName = ViewerTest_myDrivers.Find2
325 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
327 if(ViewerTest_myContexts.IsEmpty())
329 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
330 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
334 myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
337 myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
341 // There is at least view name
342 Standard_Integer aParserNumber = 0;
343 for (Standard_Integer i = 0; i < 3; ++i)
345 Standard_Integer aParserPos = aName.SearchFromEnd("/");
349 aName.Split(aParserPos-1);
354 if (aParserNumber == 0)
357 if (!ViewerTest::GetAISContext().IsNull())
359 myDriverName = ViewerTest_myDrivers.Find2
360 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
361 myViewerName = ViewerTest_myContexts.Find2
362 (ViewerTest::GetAISContext());
366 // There is no opened contexts here, need to create names for viewer and driver
367 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
368 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
370 myViewerName = CreateName <Handle(AIS_InteractiveContext)>
371 (ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
373 myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
375 else if (aParserNumber == 1)
377 // Here is viewerName/viewName
378 if (!ViewerTest::GetAISContext().IsNull())
379 myDriverName = ViewerTest_myDrivers.Find2
380 (ViewerTest::GetAISContext()->CurrentViewer()->Driver());
383 // There is no opened contexts here, need to create name for driver
384 myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
385 (ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
387 myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
389 myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
393 //Here is driverName/viewerName/viewName
394 myDriverName = TCollection_AsciiString(aName);
396 TCollection_AsciiString aViewerName(theInputString);
397 aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
398 myViewerName = TCollection_AsciiString(aViewerName);
400 myViewName = TCollection_AsciiString(theInputString);
406 //==============================================================================
407 //function : FindContextByView
408 //purpose : Find AIS_InteractiveContext by View
409 //==============================================================================
411 Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
413 Handle(AIS_InteractiveContext) anAISContext;
415 for (ViewerTest_ViewerCommandsInteractiveContextMap::Iterator
416 anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
418 if (anIter.Key2()->CurrentViewer() == theView->Viewer())
419 return anIter.Key2();
424 //==============================================================================
425 //function : IsWindowOverlapped
426 //purpose : Check if theWindow overlapp another view
427 //==============================================================================
429 Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
430 const Standard_Integer thePxTop,
431 const Standard_Integer thePxRight,
432 const Standard_Integer thePxBottom,
433 TCollection_AsciiString& theViewId)
435 for(ViewerTest_ViewerCommandsViewMap::Iterator
436 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
438 Standard_Integer aTop = 0,
442 anIter.Key2()->Window()->Position(aLeft, aTop, aRight, aBottom);
443 if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
444 (thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
445 (thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
446 (thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
448 theViewId = anIter.Key1();
449 return Standard_True;
452 return Standard_False;
455 // Workaround: to create and delete non-orthographic views outside ViewerTest
456 void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
458 ViewerTest_myViews.UnBind1 (theName);
461 void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
462 const Handle(V3d_View)& theView)
464 ViewerTest_myViews.Bind (theName, theView);
467 TCollection_AsciiString ViewerTest::GetCurrentViewName ()
469 return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
472 //==============================================================================
473 //function : ViewerInit
474 //purpose : Create the window viewer and initialize all the global variable
475 //==============================================================================
477 TCollection_AsciiString ViewerTest::ViewerInit (const ViewerTest_VinitParams& theParams)
479 // Default position and dimension of the viewer window.
480 // Note that left top corner is set to be sufficiently small to have
481 // window fit in the small screens (actual for remote desktops, see #23003).
482 // The position corresponds to the window's client area, thus some
483 // gap is added for window frame to be visible.
484 Graphic3d_Vec2d aPxTopLeft (20, 40);
485 Graphic3d_Vec2d aPxSize (409, 409);
486 Standard_Boolean isDefViewSize = Standard_True;
487 Standard_Boolean toCreateViewer = Standard_False;
488 const Standard_Boolean isVirtual = Draw_VirtualWindows || theParams.IsVirtual;
489 if (!theParams.ViewToClone.IsNull())
491 Graphic3d_Vec2i aCloneSize;
492 theParams.ViewToClone->Window()->Size (aCloneSize.x(), aCloneSize.y());
493 aPxSize = Graphic3d_Vec2d (aCloneSize);
494 isDefViewSize = Standard_False;
495 #if !defined(__EMSCRIPTEN__)
496 (void )isDefViewSize;
500 Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
501 if (aFactory.IsNull())
503 Draw::GetInterpretor().Eval ("pload OPENGL");
504 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
505 if (aFactory.IsNull())
507 Draw::GetInterpretor().Eval ("pload GLES");
508 aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
509 if (aFactory.IsNull())
511 throw Standard_ProgramError("Error: no graphic driver factory found");
516 Handle(Graphic3d_GraphicDriver) aGraphicDriver;
517 ViewerTest_Names aViewNames (theParams.ViewName);
518 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
520 aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
523 // Get graphic driver (create it or get from another view)
524 const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
527 // Get connection string
528 #if defined(HAVE_XLIB)
529 if (!theParams.DisplayName.IsEmpty())
531 SetDisplayConnection (new Aspect_DisplayConnection (theParams.DisplayName));
535 Aspect_XDisplay* aDispX = NULL;
536 // create dedicated display connection instead of reusing Tk connection
537 // so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
538 /*Draw_Interpretor& aCommands = Draw::GetInterpretor();
539 Tcl_Interp* aTclInterp = aCommands.Interp();
540 Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
541 aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
542 SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
545 SetDisplayConnection (new Aspect_DisplayConnection ());
548 aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
551 // don't waste the time waiting for VSync when window is not displayed on the screen
552 aGraphicDriver->SetVerticalSync (false);
555 ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
556 toCreateViewer = Standard_True;
560 aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
563 // Get screen resolution
564 Graphic3d_Vec2i aScreenSize;
567 GetClientRect(GetDesktopWindow(), &aWindowSize);
568 aScreenSize.SetValues (aWindowSize.right, aWindowSize.bottom);
569 #elif defined(HAVE_XLIB)
570 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
571 Screen* aScreen = DefaultScreenOfDisplay(aDispX);
572 aScreenSize.x() = WidthOfScreen(aScreen);
573 aScreenSize.y() = HeightOfScreen(aScreen);
574 #elif defined(__APPLE__)
575 GetCocoaScreenResolution (aScreenSize.x(), aScreenSize.y());
580 if (!theParams.ParentView.IsNull())
582 aPxTopLeft.SetValues (0, 0);
584 if (theParams.Offset.x() != 0)
586 aPxTopLeft.x() = theParams.Offset.x();
588 if (theParams.Offset.y() != 0)
590 aPxTopLeft.y() = theParams.Offset.y();
592 if (theParams.Size.x() != 0)
594 isDefViewSize = Standard_False;
595 aPxSize.x() = theParams.Size.x();
596 if (aPxSize.x() <= 1.0
597 && aScreenSize.x() > 0
598 && theParams.ParentView.IsNull())
600 aPxSize.x() = aPxSize.x() * double(aScreenSize.x());
603 if (theParams.Size.y() != 0)
605 isDefViewSize = Standard_False;
606 aPxSize.y() = theParams.Size.y();
607 if (aPxSize.y() <= 1.0
608 && aScreenSize.y() > 0
609 && theParams.ParentView.IsNull())
611 aPxSize.y() = aPxSize.y() * double(aScreenSize.y());
615 //Dispose the window if input parameters are default
616 if (!ViewerTest_myViews.IsEmpty()
617 && theParams.ParentView.IsNull()
618 && theParams.Offset.x() == 0
619 && theParams.Offset.y() == 0)
621 Standard_Integer aTop = 0, aLeft = 0, aRight = 0, aBottom = 0;
622 TCollection_AsciiString anOverlappedViewId("");
623 while (IsWindowOverlapped ((int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
624 (int )aPxTopLeft.x() + (int )aPxSize.x(),
625 (int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId))
627 ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
629 if (IsWindowOverlapped (aRight + 20, (int )aPxTopLeft.y(), aRight + 20 + (int )aPxSize.x(),
630 (int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId)
631 && aRight + 2 * aPxSize.x() + 40 > aScreenSize.x())
633 if (aBottom + aPxSize.y() + 40 > aScreenSize.y())
640 aPxTopLeft.y() = aBottom + 40;
644 aPxTopLeft.x() = aRight + 20;
650 TCollection_AsciiString aTitle("3D View - ");
651 aTitle = aTitle + aViewNames.GetViewName() + "(*)";
653 // Change name of current active window
654 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
656 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
660 Handle(V3d_Viewer) a3DViewer;
661 // If it's the single view, we first look for empty context
662 if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
664 ViewerTest_ViewerCommandsInteractiveContextMap::Iterator
665 anIter(ViewerTest_myContexts);
667 ViewerTest::SetAISContext (anIter.Key2());
668 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
670 else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
672 ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
673 a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
675 else if (a3DViewer.IsNull())
677 toCreateViewer = Standard_True;
678 a3DViewer = new V3d_Viewer(aGraphicDriver);
679 a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
680 a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
681 ViewerTest_DefaultBackground.GradientColor2,
682 ViewerTest_DefaultBackground.FillMethod);
686 if (ViewerTest::GetAISContext().IsNull() ||
687 !(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
689 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
690 ViewerTest::SetAISContext (aContext);
691 ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
695 ViewerTest::ResetEventManager();
699 if (!theParams.ParentView.IsNull())
701 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast (theParams.ParentView->Window());
706 VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
707 isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
708 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
709 (int )aPxSize.x(), (int )aPxSize.y(),
711 VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
712 #elif defined(HAVE_XLIB)
713 VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
715 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
716 (int )aPxSize.x(), (int )aPxSize.y());
717 #elif defined(__APPLE__)
718 VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
719 (int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
720 (int )aPxSize.x(), (int )aPxSize.y());
721 ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
722 #elif defined(__EMSCRIPTEN__)
723 // current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
724 // the code should be revised for handling multiple canvas elements (which is technically also possible)
725 TCollection_AsciiString aCanvasId = getModuleCanvasId();
726 if (!aCanvasId.IsEmpty())
728 aCanvasId = TCollection_AsciiString("#") + aCanvasId;
731 VT_GetWindow() = new Wasm_Window (aCanvasId);
732 Graphic3d_Vec2i aRealSize;
733 VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
734 if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
736 // Wasm_Window wraps an existing HTML element without creating a new one.
737 // Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
738 // but resize canvas if vinit has been called with explicitly specified dimensions.
739 VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxSize));
743 VT_GetWindow() = new Aspect_NeutralWindow();
744 VT_GetWindow()->SetSize ((int )aPxSize.x(), (int )aPxSize.y());
746 VT_GetWindow()->SetVirtual (isVirtual);
750 Handle(V3d_View) aView;
751 if (!theParams.ViewToClone.IsNull())
753 aView = new ViewerTest_V3dView (a3DViewer, theParams.ViewToClone);
757 aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
760 aView->View()->SetSubviewComposer (theParams.IsComposer);
761 if (!theParams.ParentView.IsNull())
763 aView->SetWindow (theParams.ParentView, aPxSize, theParams.Corner, aPxTopLeft, theParams.SubviewMargins);
767 aView->SetWindow (VT_GetWindow());
769 ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
771 ViewerTest::CurrentView(aView);
772 ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
774 // Setup for X11 or NT
775 SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
776 ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
778 // Set parameters for V3d_View and V3d_Viewer
779 const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
780 aV3dView->SetComputedMode(Standard_False);
782 a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
785 a3DViewer->SetDefaultLights();
786 a3DViewer->SetLightOn();
789 #if defined(HAVE_XLIB)
792 ::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
793 Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
797 VT_GetWindow()->Map();
799 // Set the handle of created view in the event manager
800 ViewerTest::ResetEventManager();
802 ViewerTest::CurrentView()->Redraw();
807 return aViewNames.GetViewName();
810 //==============================================================================
811 //function : RedrawAllViews
812 //purpose : Redraw all created views
813 //==============================================================================
814 void ViewerTest::RedrawAllViews()
816 ViewerTest_ViewerCommandsViewMap::Iterator aViewIt(ViewerTest_myViews);
817 for (; aViewIt.More(); aViewIt.Next())
819 const Handle(V3d_View)& aView = aViewIt.Key2();
824 //==============================================================================
827 //==============================================================================
828 static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
832 theDi << "Registered: ";
833 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
834 aFactoryIter.More(); aFactoryIter.Next())
836 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
837 theDi << aFactory->Name() << " ";
841 theDi << "Default: ";
842 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
844 theDi << aFactory->Name();
853 TCollection_AsciiString aNewActive;
855 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
857 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
858 anArgCase.LowerCase();
859 if (anArgCase == "-list")
861 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
862 aFactoryIter.More(); aFactoryIter.Next())
864 const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
865 theDi << aFactory->Name() << " ";
868 else if ((anArgCase == "-default"
869 || anArgCase == "-load")
870 && aNewActive.IsEmpty())
872 toLoad = (anArgCase == "-load");
873 if (anArgIter + 1 < theArgsNb)
875 aNewActive = theArgVec[++anArgIter];
879 theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
884 if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
886 theDi << aFactory->Name();
894 else if (aNewActive.IsEmpty())
896 aNewActive = theArgVec[anArgIter];
900 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
905 if (!aNewActive.IsEmpty())
907 const TCollection_AsciiString aNameCopy = aNewActive;
908 if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
909 || TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
910 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
912 aNewActive = "tkopengl";
914 else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
915 || TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
916 || TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
918 aNewActive = "tkopengles";
920 else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
921 || TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
922 || TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
924 aNewActive = "tkd3dhost";
929 if (aNewActive == "tkopengl")
931 Draw::GetInterpretor().Eval ("pload OPENGL");
933 else if (aNewActive == "tkopengles")
935 Draw::GetInterpretor().Eval ("pload GLES");
937 else if (aNewActive == "tkd3dhost")
939 Draw::GetInterpretor().Eval ("pload D3DHOST");
943 theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
948 bool isFound = false;
949 for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
950 aFactoryIter.More(); aFactoryIter.Next())
952 Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
953 if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
955 Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
963 theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
971 //==============================================================================
973 //purpose : Create the window viewer and initialize all the global variable
974 // Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
975 //==============================================================================
976 static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
978 ViewerTest_VinitParams aParams;
979 TCollection_AsciiString aName, aValue;
980 int is2dMode = -1, aDpiAware = -1;
981 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
983 const TCollection_AsciiString anArg = theArgVec[anArgIt];
984 TCollection_AsciiString anArgCase = anArg;
985 anArgCase.LowerCase();
986 if (anArgIt + 1 < theArgsNb
987 && anArgCase == "-name")
989 aParams.ViewName = theArgVec[++anArgIt];
991 else if (anArgIt + 1 < theArgsNb
992 && (anArgCase == "-left"
993 || anArgCase == "-l")
994 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.x()))
998 else if (anArgIt + 1 < theArgsNb
999 && (anArgCase == "-top"
1000 || anArgCase == "-t")
1001 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.y()))
1005 else if (anArgIt + 1 < theArgsNb
1006 && (anArgCase == "-width"
1007 || anArgCase == "-w")
1008 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.x()))
1012 else if (anArgIt + 1 < theArgsNb
1013 && (anArgCase == "-height"
1014 || anArgCase == "-h")
1015 && Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.y()))
1019 else if (anArgIt + 1 < theArgsNb
1020 && (anArgCase == "-pos"
1021 || anArgCase == "-position"
1022 || anArgCase == "-corner")
1023 && ViewerTest::ParseCorner (theArgVec[anArgIt + 1], aParams.Corner))
1027 else if (anArgIt + 2 < theArgsNb
1028 && anArgCase == "-margins"
1029 && Draw::ParseInteger (theArgVec[anArgIt + 1], aParams.SubviewMargins.x())
1030 && Draw::ParseInteger (theArgVec[anArgIt + 2], aParams.SubviewMargins.y()))
1034 else if (anArgCase == "-virtual"
1035 || anArgCase == "-offscreen")
1037 aParams.IsVirtual = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1039 else if (anArgCase == "-composer")
1041 aParams.IsComposer = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
1043 else if (anArgCase == "-exitonclose")
1045 ViewerTest_EventManager::ToExitOnCloseView() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1047 else if (anArgCase == "-closeonescape"
1048 || anArgCase == "-closeonesc")
1050 ViewerTest_EventManager::ToCloseViewOnEscape() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1052 else if (anArgCase == "-2d_mode"
1053 || anArgCase == "-2dmode"
1054 || anArgCase == "-2d")
1056 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
1057 is2dMode = toEnable ? 1 : 0;
1059 else if (anArgIt + 1 < theArgsNb
1060 && (anArgCase == "-disp"
1061 || anArgCase == "-display"))
1063 aParams.DisplayName = theArgVec[++anArgIt];
1065 else if (anArgCase == "-dpiaware")
1067 aDpiAware = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt) ? 1 : 0;
1069 else if (!ViewerTest::CurrentView().IsNull()
1070 && aParams.ViewToClone.IsNull()
1071 && (anArgCase == "-copy"
1072 || anArgCase == "-clone"
1073 || anArgCase == "-cloneactive"
1074 || anArgCase == "-cloneactiveview"))
1076 aParams.ViewToClone = ViewerTest::CurrentView();
1078 else if (!ViewerTest::CurrentView().IsNull()
1079 && aParams.ParentView.IsNull()
1080 && anArgCase == "-subview")
1082 aParams.ParentView = ViewerTest::CurrentView();
1083 if (aParams.ParentView.IsNull())
1085 Message::SendFail() << "Syntax error: cannot create of subview without parent";
1088 if (aParams.ParentView->IsSubview())
1090 aParams.ParentView = aParams.ParentView->ParentView();
1093 else if (!ViewerTest::CurrentView().IsNull()
1094 && aParams.ParentView.IsNull()
1095 && anArgCase == "-parent"
1096 && anArgIt + 1 < theArgsNb)
1098 TCollection_AsciiString aParentStr (theArgVec[++anArgIt]);
1099 ViewerTest_Names aViewNames (aParentStr);
1100 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1102 Message::SendFail() << "Syntax error: parent view '" << aParentStr << "' not found";
1106 aParams.ParentView = ViewerTest_myViews.Find1(aViewNames.GetViewName());
1107 if (aParams.ParentView->IsSubview())
1109 aParams.ParentView = aParams.ParentView->ParentView();
1113 else if (ViewerTest::SplitParameter (anArg, aName, aValue))
1116 if (aName == "name")
1118 aParams.ViewName = aValue;
1120 else if (aName == "l"
1123 aParams.Offset.x() = (float)aValue.RealValue();
1125 else if (aName == "t"
1128 aParams.Offset.y() = (float)aValue.RealValue();
1130 else if (aName == "disp"
1131 || aName == "display")
1133 aParams.DisplayName = aValue;
1135 else if (aName == "w"
1136 || aName == "width")
1138 aParams.Size.x() = (float )aValue.RealValue();
1140 else if (aName == "h"
1141 || aName == "height")
1143 aParams.Size.y() = (float)aValue.RealValue();
1147 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1151 else if (aParams.ViewName.IsEmpty())
1153 aParams.ViewName = anArg;
1157 Message::SendFail() << "Syntax error: unknown argument " << anArg;
1163 if (aDpiAware != -1)
1165 typedef void* (WINAPI *SetThreadDpiAwarenessContext_t)(void*);
1166 if (HMODULE aUser32Module = GetModuleHandleW (L"User32"))
1168 SetThreadDpiAwarenessContext_t aSetDpiAware = (SetThreadDpiAwarenessContext_t )GetProcAddress (aUser32Module, "SetThreadDpiAwarenessContext");
1171 // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
1172 if (aSetDpiAware ((void* )-4) == NULL)
1174 // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE for older systems
1175 if (aSetDpiAware ((void* )-3) == NULL)
1177 Message::SendFail() << "Error: unable to enable DPI awareness";
1183 // DPI_AWARENESS_CONTEXT_UNAWARE
1184 if (aSetDpiAware ((void* )-1) == NULL)
1186 Message::SendFail() << "Error: unable to disable DPI awareness";
1193 #if !defined(HAVE_XLIB)
1194 if (!aParams.DisplayName.IsEmpty())
1196 aParams.DisplayName.Clear();
1197 Message::SendWarning() << "Warning: display parameter will be ignored.\n";
1202 ViewerTest_Names aViewNames (aParams.ViewName);
1203 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
1205 TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
1206 theDi.Eval (aCommand.ToCString());
1209 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1214 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
1217 ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
1223 //! Parse HLR algo type.
1224 static Standard_Boolean parseHlrAlgoType (const char* theName,
1225 Prs3d_TypeOfHLR& theType)
1227 TCollection_AsciiString aName (theName);
1229 if (aName == "polyalgo")
1231 theType = Prs3d_TOH_PolyAlgo;
1233 else if (aName == "algo")
1235 theType = Prs3d_TOH_Algo;
1239 return Standard_False;
1241 return Standard_True;
1244 //==============================================================================
1246 //purpose : hidden lines removal algorithm
1247 //==============================================================================
1249 static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1251 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1252 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1255 Message::SendFail ("Error: no active viewer");
1259 Standard_Boolean hasHlrOnArg = Standard_False;
1260 Standard_Boolean hasShowHiddenArg = Standard_False;
1261 Standard_Boolean isHLROn = Standard_False;
1262 Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
1263 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1264 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1265 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1267 TCollection_AsciiString anArg (argv[anArgIter]);
1269 if (anUpdateTool.parseRedrawMode (anArg))
1273 else if (anArg == "-showhidden"
1274 && anArgIter + 1 < argc
1275 && Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
1278 hasShowHiddenArg = Standard_True;
1281 else if ((anArg == "-type"
1283 || anArg == "-algotype")
1284 && anArgIter + 1 < argc
1285 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1290 else if (!hasHlrOnArg
1291 && Draw::ParseOnOff (argv[anArgIter], isHLROn))
1293 hasHlrOnArg = Standard_True;
1297 else if (!hasShowHiddenArg
1298 && Draw::ParseOnOff(argv[anArgIter], toShowHidden))
1300 hasShowHiddenArg = Standard_True;
1305 Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
1311 di << "HLR: " << aView->ComputedMode() << "\n";
1312 di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
1314 switch (aCtx->DefaultDrawer()->TypeOfHLR())
1316 case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
1317 case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
1318 case Prs3d_TOH_Algo: di << "Algo\n"; break;
1320 anUpdateTool.Invalidate();
1324 Standard_Boolean toRecompute = Standard_False;
1325 if (aTypeOfHLR != Prs3d_TOH_NotSet
1326 && aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
1328 toRecompute = Standard_True;
1329 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1331 if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
1333 toRecompute = Standard_True;
1336 aCtx->DefaultDrawer()->EnableDrawHiddenLine();
1340 aCtx->DefaultDrawer()->DisableDrawHiddenLine();
1345 if (aView->ComputedMode() && isHLROn && toRecompute)
1347 AIS_ListOfInteractive aListOfShapes;
1348 aCtx->DisplayedObjects (aListOfShapes);
1349 for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
1351 if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
1353 aCtx->Redisplay (aShape, Standard_False);
1358 aView->SetComputedMode (isHLROn);
1362 //==============================================================================
1363 //function : VHLRType
1364 //purpose : change type of using HLR algorithm
1365 //==============================================================================
1367 static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
1369 const Handle(V3d_View) aView = ViewerTest::CurrentView();
1370 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
1373 Message::SendFail ("Error: no active viewer");
1377 Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
1378 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
1379 AIS_ListOfInteractive aListOfShapes;
1380 for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
1382 TCollection_AsciiString anArg (argv[anArgIter]);
1384 if (anUpdateTool.parseRedrawMode (anArg))
1388 else if ((anArg == "-type"
1390 || anArg == "-algotype")
1391 && anArgIter + 1 < argc
1392 && parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
1398 else if (aTypeOfHLR == Prs3d_TOH_NotSet
1399 && parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
1405 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
1406 TCollection_AsciiString aName (argv[anArgIter]);
1407 if (!aMap.IsBound2 (aName))
1409 Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
1413 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
1414 if (aShape.IsNull())
1416 Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
1419 aListOfShapes.Append (aShape);
1423 if (aTypeOfHLR == Prs3d_TOH_NotSet)
1425 Message::SendFail ("Syntax error: wrong number of arguments");
1429 const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
1432 aCtx->DisplayedObjects (aListOfShapes);
1433 aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
1436 for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
1438 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
1439 if (aShape.IsNull())
1444 const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
1445 && aView->ComputedMode();
1447 || aShape->TypeOfHLR() != aTypeOfHLR)
1449 aShape->SetTypeOfHLR (aTypeOfHLR);
1453 aCtx->Redisplay (aShape, Standard_False);
1459 //==============================================================================
1460 //function : FindViewIdByWindowHandle
1461 //purpose : Find theView Id in the map of views by window handle
1462 //==============================================================================
1463 #if defined(_WIN32) || defined(HAVE_XLIB)
1464 static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
1466 for (ViewerTest_ViewerCommandsViewMap::Iterator
1467 anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
1469 Aspect_Drawable aWindowHandle = anIter.Key2()->Window()->NativeHandle();
1470 if (aWindowHandle == theWindowHandle)
1471 return anIter.Key1();
1473 return TCollection_AsciiString("");
1477 //! Make the view active
1478 void ActivateView (const TCollection_AsciiString& theViewName,
1479 Standard_Boolean theToUpdate = Standard_True)
1481 if (const Handle(V3d_View)& aView = ViewerTest_myViews.Find1(theViewName))
1483 ViewerTest::ActivateView (aView, theToUpdate);
1487 //==============================================================================
1488 //function : ActivateView
1490 //==============================================================================
1491 void ViewerTest::ActivateView (const Handle(V3d_View)& theView,
1492 Standard_Boolean theToUpdate)
1494 const Handle(V3d_View)& aView = theView;
1495 const TCollection_AsciiString* aViewName = ViewerTest_myViews.Seek2 (aView);
1496 if (aViewName == nullptr)
1501 Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
1502 if (anAISContext.IsNull())
1507 if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
1509 if (!aCurrentView->Window().IsNull())
1511 aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
1515 ViewerTest::CurrentView (aView);
1516 ViewerTest::SetAISContext (anAISContext);
1517 if (aView->IsSubview())
1519 aView->ParentView()->Window()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
1520 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->View()->ParentView()->Window());
1524 VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->Window());
1526 if (!VT_GetWindow().IsNull())
1528 VT_GetWindow()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
1530 SetDisplayConnection(aView->Viewer()->Driver()->GetDisplayConnection());
1537 //==============================================================================
1538 //function : RemoveView
1540 //==============================================================================
1541 void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
1542 const Standard_Boolean theToRemoveContext)
1544 if (!ViewerTest_myViews.IsBound2 (theView))
1549 const TCollection_AsciiString& aViewName = ViewerTest_myViews.Find2 (theView);
1550 RemoveView (aViewName, theToRemoveContext);
1553 //==============================================================================
1554 //function : RemoveView
1555 //purpose : Close and remove view from display, clear maps if necessary
1556 //==============================================================================
1557 void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
1559 if (!ViewerTest_myViews.IsBound1(theViewName))
1561 Message::SendFail() << "Wrong view name";
1565 Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
1566 Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
1567 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
1568 aRedrawer.Stop (aView);
1569 if (!aView->Subviews().IsEmpty())
1571 NCollection_Sequence<Handle(V3d_View)> aSubviews = aView->Subviews();
1572 for (const Handle(V3d_View)& aSubviewIter : aSubviews)
1574 RemoveView (aSubviewIter, isContextRemoved);
1578 // Activate another view if it's active now
1579 if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
1581 if (ViewerTest_myViews.Extent() > 1)
1583 for (ViewerTest_ViewerCommandsViewMap::Iterator anIter (ViewerTest_myViews);
1584 anIter.More(); anIter.Next())
1586 if (anIter.Key1() != theViewName)
1588 ActivateView (anIter.Key2(), true);
1595 VT_GetWindow().Nullify();
1596 ViewerTest::CurrentView (Handle(V3d_View)());
1597 if (isContextRemoved)
1599 Handle(AIS_InteractiveContext) anEmptyContext;
1600 ViewerTest::SetAISContext(anEmptyContext);
1605 // Delete view, name will be removed too
1606 const TCollection_AsciiString aCopyString(theViewName);
1607 ViewerTest_myViews.UnBind1(theViewName);
1608 if (!aView->Window().IsNull())
1610 aView->Window()->Unmap();
1614 #if defined(HAVE_XLIB)
1615 XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
1618 // Keep context opened only if the closed view is last to avoid
1619 // unused empty contexts
1620 if (!aCurrentContext.IsNull())
1622 // Check if there are more defined views in the viewer
1623 if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
1624 && aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
1626 // Remove driver if there is no viewers that use it
1627 Standard_Boolean isRemoveDriver = Standard_True;
1628 for(ViewerTest_ViewerCommandsInteractiveContextMap::Iterator
1629 anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
1631 if (aCurrentContext != anIter.Key2() &&
1632 aCurrentContext->CurrentViewer()->Driver() == anIter.Key2()->CurrentViewer()->Driver())
1634 isRemoveDriver = Standard_False;
1639 aCurrentContext->RemoveAll (Standard_False);
1642 ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
1643 #if defined(HAVE_XLIB)
1644 Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
1648 ViewerTest_myContexts.UnBind2(aCurrentContext);
1651 Message::SendInfo() << "3D View - " << aCopyString << " was deleted.\n";
1652 if (ViewerTest_EventManager::ToExitOnCloseView())
1654 Draw_Interprete ("exit");
1658 //==============================================================================
1660 //purpose : Remove the view defined by its name
1661 //==============================================================================
1663 static int VClose (Draw_Interpretor& /*theDi*/,
1664 Standard_Integer theArgsNb,
1665 const char** theArgVec)
1667 NCollection_List<TCollection_AsciiString> aViewList;
1670 TCollection_AsciiString anArg (theArgVec[1]);
1672 if (anArg.IsEqual ("ALL")
1673 || anArg.IsEqual ("*"))
1675 for (ViewerTest_ViewerCommandsViewMap::Iterator anIter (ViewerTest_myViews);
1676 anIter.More(); anIter.Next())
1678 aViewList.Append (anIter.Key1());
1680 if (aViewList.IsEmpty())
1682 std::cout << "No view to close\n";
1688 ViewerTest_Names aViewName (theArgVec[1]);
1689 if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
1691 Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
1694 aViewList.Append (aViewName.GetViewName());
1699 // close active view
1700 if (ViewerTest::CurrentView().IsNull())
1702 Message::SendFail ("Error: no active view");
1705 aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1708 Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
1709 for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
1710 anIter.More(); anIter.Next())
1712 ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
1718 //==============================================================================
1719 //function : VActivate
1720 //purpose : Activate the view defined by its ID
1721 //==============================================================================
1723 static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1727 theDi.Eval("vviewlist");
1731 TCollection_AsciiString aNameString;
1732 Standard_Boolean toUpdate = Standard_True;
1733 Standard_Boolean toActivate = Standard_True;
1734 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
1736 TCollection_AsciiString anArg (theArgVec[anArgIter]);
1739 && anArg == "-noupdate")
1741 toUpdate = Standard_False;
1744 && aNameString.IsEmpty()
1747 ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
1748 VT_GetWindow().Nullify();
1749 ViewerTest::CurrentView (Handle(V3d_View)());
1750 ViewerTest::ResetEventManager();
1751 theDi << theArgVec[0] << ": all views are inactive\n";
1752 toActivate = Standard_False;
1755 && aNameString.IsEmpty())
1757 aNameString = theArgVec[anArgIter];
1761 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
1770 else if (aNameString.IsEmpty())
1772 Message::SendFail ("Syntax error: wrong number of arguments");
1776 // Check if this view exists in the viewer with the driver
1777 ViewerTest_Names aViewNames (aNameString);
1778 if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
1780 theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
1784 // Check if it is active already
1785 if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
1787 theDi << theArgVec[0] << ": the view is active already\n";
1791 ActivateView (aViewNames.GetViewName(), toUpdate);
1795 //==============================================================================
1796 //function : VViewList
1797 //purpose : Print current list of views per viewer and graphic driver ID
1798 // shared between viewers
1799 //==============================================================================
1801 static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
1805 theDi << theArgVec[0] << ": Wrong number of command arguments\n"
1806 << "Usage: " << theArgVec[0] << " name";
1809 if (ViewerTest_myContexts.Size() < 1)
1812 Standard_Boolean isTreeView =
1813 (( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
1817 theDi << theArgVec[0] <<":\n";
1820 for (ViewerTest_ViewerCommandsGraphicDriverMap::Iterator aDriverIter (ViewerTest_myDrivers);
1821 aDriverIter.More(); aDriverIter.Next())
1824 theDi << aDriverIter.Key1() << ":\n";
1826 for (ViewerTest_ViewerCommandsInteractiveContextMap::Iterator
1827 aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
1829 if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
1833 TCollection_AsciiString aContextName(aContextIter.Key1());
1834 theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
1837 for (ViewerTest_ViewerCommandsViewMap::Iterator aViewIter (ViewerTest_myViews);
1838 aViewIter.More(); aViewIter.Next())
1840 if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
1842 TCollection_AsciiString aViewName(aViewIter.Key1());
1845 if (aViewIter.Key2() == ViewerTest::CurrentView())
1846 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
1848 theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
1852 theDi << aViewName << " ";
1862 //==============================================================================
1863 //function : GetMousePosition
1865 //==============================================================================
1866 void ViewerTest::GetMousePosition (Standard_Integer& theX,
1867 Standard_Integer& theY)
1869 if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
1871 theX = aViewCtrl->LastMousePosition().x();
1872 theY = aViewCtrl->LastMousePosition().y();
1876 //==============================================================================
1877 //function : VViewProj
1878 //purpose : Switch view projection
1879 //==============================================================================
1880 static int VViewProj (Draw_Interpretor& ,
1881 Standard_Integer theNbArgs,
1882 const char** theArgVec)
1884 static Standard_Boolean isYup = Standard_False;
1885 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
1888 Message::SendFail ("Error: no active viewer");
1892 TCollection_AsciiString aCmdName (theArgVec[0]);
1893 Standard_Boolean isGeneralCmd = Standard_False;
1894 if (aCmdName == "vfront")
1896 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1898 else if (aCmdName == "vback")
1900 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1902 else if (aCmdName == "vtop")
1904 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1906 else if (aCmdName == "vbottom")
1908 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1910 else if (aCmdName == "vleft")
1912 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1914 else if (aCmdName == "vright")
1916 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1918 else if (aCmdName == "vaxo")
1920 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
1924 isGeneralCmd = Standard_True;
1925 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
1927 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
1928 anArgCase.LowerCase();
1929 if (anArgCase == "-zup")
1931 isYup = Standard_False;
1933 else if (anArgCase == "-yup")
1935 isYup = Standard_True;
1937 else if (anArgCase == "-front"
1938 || anArgCase == "front"
1939 || anArgCase == "-f"
1940 || anArgCase == "f")
1942 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
1944 else if (anArgCase == "-back"
1945 || anArgCase == "back"
1946 || anArgCase == "-b"
1947 || anArgCase == "b")
1949 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
1951 else if (anArgCase == "-top"
1952 || anArgCase == "top"
1953 || anArgCase == "-t"
1954 || anArgCase == "t")
1956 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
1958 else if (anArgCase == "-bottom"
1959 || anArgCase == "bottom"
1960 || anArgCase == "-bot"
1961 || anArgCase == "bot"
1962 || anArgCase == "-b"
1963 || anArgCase == "b")
1965 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
1967 else if (anArgCase == "-left"
1968 || anArgCase == "left"
1969 || anArgCase == "-l"
1970 || anArgCase == "l")
1972 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
1974 else if (anArgCase == "-right"
1975 || anArgCase == "right"
1976 || anArgCase == "-r"
1977 || anArgCase == "r")
1979 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
1981 else if (anArgCase == "-axoleft"
1982 || anArgCase == "-leftaxo"
1983 || anArgCase == "axoleft"
1984 || anArgCase == "leftaxo")
1986 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
1988 else if (anArgCase == "-axo"
1989 || anArgCase == "axo"
1990 || anArgCase == "-a"
1992 || anArgCase == "-axoright"
1993 || anArgCase == "-rightaxo"
1994 || anArgCase == "axoright"
1995 || anArgCase == "rightaxo")
1997 aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
1999 else if (anArgCase == "+x")
2001 aView->SetProj (V3d_Xpos, isYup);
2003 else if (anArgCase == "-x")
2005 aView->SetProj (V3d_Xneg, isYup);
2007 else if (anArgCase == "+y")
2009 aView->SetProj (V3d_Ypos, isYup);
2011 else if (anArgCase == "-y")
2013 aView->SetProj (V3d_Yneg, isYup);
2015 else if (anArgCase == "+z")
2017 aView->SetProj (V3d_Zpos, isYup);
2019 else if (anArgCase == "-z")
2021 aView->SetProj (V3d_Zneg, isYup);
2023 else if (anArgCase == "+x+y+z")
2025 aView->SetProj (V3d_XposYposZpos, isYup);
2027 else if (anArgCase == "+x+y-z")
2029 aView->SetProj (V3d_XposYposZneg, isYup);
2031 else if (anArgCase == "+x-y+z")
2033 aView->SetProj (V3d_XposYnegZpos, isYup);
2035 else if (anArgCase == "+x-y-z")
2037 aView->SetProj (V3d_XposYnegZneg, isYup);
2039 else if (anArgCase == "-x+y+z")
2041 aView->SetProj (V3d_XnegYposZpos, isYup);
2043 else if (anArgCase == "-x+y-z")
2045 aView->SetProj (V3d_XnegYposZneg, isYup);
2047 else if (anArgCase == "-x-y+z")
2049 aView->SetProj (V3d_XnegYnegZpos, isYup);
2051 else if (anArgCase == "-x-y-z")
2053 aView->SetProj (V3d_XnegYnegZneg, isYup);
2055 else if (anArgCase == "+x+y")
2057 aView->SetProj (V3d_XposYpos, isYup);
2059 else if (anArgCase == "+x-y")
2061 aView->SetProj (V3d_XposYneg, isYup);
2063 else if (anArgCase == "-x+y")
2065 aView->SetProj (V3d_XnegYpos, isYup);
2067 else if (anArgCase == "-x-y")
2069 aView->SetProj (V3d_XnegYneg, isYup);
2071 else if (anArgCase == "+x+z")
2073 aView->SetProj (V3d_XposZpos, isYup);
2075 else if (anArgCase == "+x-z")
2077 aView->SetProj (V3d_XposZneg, isYup);
2079 else if (anArgCase == "-x+z")
2081 aView->SetProj (V3d_XnegZpos, isYup);
2083 else if (anArgCase == "-x-z")
2085 aView->SetProj (V3d_XnegZneg, isYup);
2087 else if (anArgCase == "+y+z")
2089 aView->SetProj (V3d_YposZpos, isYup);
2091 else if (anArgCase == "+y-z")
2093 aView->SetProj (V3d_YposZneg, isYup);
2095 else if (anArgCase == "-y+z")
2097 aView->SetProj (V3d_YnegZpos, isYup);
2099 else if (anArgCase == "-y-z")
2101 aView->SetProj (V3d_YnegZneg, isYup);
2103 else if (anArgIter + 1 < theNbArgs
2104 && anArgCase == "-frame"
2105 && TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
2107 TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
2108 aFrameDef.LowerCase();
2109 gp_Dir aRight, anUp;
2110 if (aFrameDef.Value (2) == aFrameDef.Value (4))
2112 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2116 if (aFrameDef.Value (2) == 'x')
2118 aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
2120 else if (aFrameDef.Value (2) == 'y')
2122 aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
2124 else if (aFrameDef.Value (2) == 'z')
2126 aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
2130 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2134 if (aFrameDef.Value (4) == 'x')
2136 anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
2138 else if (aFrameDef.Value (4) == 'y')
2140 anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
2142 else if (aFrameDef.Value (4) == 'z')
2144 anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
2148 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2152 const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
2153 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
2154 const gp_Dir aDir = anUp.Crossed (aRight);
2155 aCamera->SetCenter (gp_Pnt (0, 0, 0));
2156 aCamera->SetDirection (aDir);
2157 aCamera->SetUp (anUp);
2158 aCamera->OrthogonalizeUp();
2160 aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
2165 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
2174 Message::SendFail ("Syntax error: wrong number of arguments");
2180 //==============================================================================
2182 //purpose : Dsiplay help on viewer Keyboead and mouse commands
2183 //Draw arg : No args
2184 //==============================================================================
2186 static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
2188 di << "=========================\n";
2189 di << "F : FitAll\n";
2190 di << "T : TopView\n";
2191 di << "B : BottomView\n";
2192 di << "R : RightView\n";
2193 di << "L : LeftView\n";
2194 di << "Backspace : AxonometricView\n";
2196 di << "=========================\n";
2197 di << "W, S : Fly forward/backward\n";
2198 di << "A, D : Slide left/right\n";
2199 di << "Q, E : Bank left/right\n";
2200 di << "-, + : Change flying speed\n";
2201 di << "Arrows : look left/right/up/down\n";
2202 di << "Arrows+Shift : slide left/right/up/down\n";
2204 di << "=========================\n";
2205 di << "S + Ctrl : Shading\n";
2206 di << "W + Ctrl : Wireframe\n";
2207 di << "H : HiddenLineRemoval\n";
2208 di << "U : Unset display mode\n";
2209 di << "Delete : Remove selection from viewer\n";
2211 di << "=========================\n";
2212 di << "Selection mode \n";
2213 di << "0 : Shape\n";
2214 di << "1 : Vertex\n";
2218 di << "5 : Shell\n";
2219 di << "6 : Solid\n";
2220 di << "7 : Compound\n";
2222 di << "=========================\n";
2223 di << "< : Hilight next detected\n";
2224 di << "> : Hilight previous detected\n";
2231 static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
2236 if (ViewerTest_myViews.IsEmpty())
2238 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2245 // Delete view from map of views
2246 ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
2251 if (LOWORD(wParam) == WA_CLICKACTIVE
2252 || LOWORD(wParam) == WA_ACTIVE
2253 || ViewerTest::CurrentView().IsNull())
2255 // Activate inactive window
2256 if (VT_GetWindow().IsNull()
2257 || (HWND )VT_GetWindow()->HWindow() != theWinHandle)
2259 ActivateView (FindViewIdByWindowHandle (theWinHandle));
2266 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2268 && !VT_GetWindow().IsNull())
2271 aMsg.hwnd = theWinHandle;
2272 aMsg.message = theMsg;
2273 aMsg.wParam = wParam;
2274 aMsg.lParam = lParam;
2275 if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
2282 return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
2285 //==============================================================================
2286 //function : ViewerMainLoop
2287 //purpose : Get a Event on the view and dispatch it
2288 //==============================================================================
2290 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2292 Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
2293 if (aViewCtrl.IsNull()
2299 aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2301 std::cout << "Start picking\n";
2305 while (aViewCtrl->ToPickPoint())
2307 // Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
2308 if (GetMessageW (&aMsg, NULL, 0, 0))
2310 TranslateMessage (&aMsg);
2311 DispatchMessageW (&aMsg);
2315 std::cout << "Picking done\n";
2319 #elif defined(HAVE_XLIB)
2321 int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
2323 static XEvent aReport;
2324 const Standard_Boolean toPick = theNbArgs > 0;
2327 if (ViewerTest::CurrentEventManager().IsNull())
2331 ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
2334 Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
2335 XNextEvent (aDisplay, &aReport);
2337 // Handle event for the chosen display connection
2338 switch (aReport.type)
2342 if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
2345 ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
2346 return toPick ? 0 : 1;
2352 // Activate inactive view
2353 Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
2354 if (aWindow != aReport.xfocus.window)
2356 ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
2362 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
2364 && !VT_GetWindow().IsNull())
2366 VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
2371 return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
2374 //==============================================================================
2375 //function : VProcessEvents
2376 //purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
2377 //==============================================================================
2378 static void VProcessEvents (ClientData theDispX, int)
2380 Display* aDispX = (Display* )theDispX;
2381 Handle(Aspect_DisplayConnection) aDispConn;
2382 for (ViewerTest_ViewerCommandsGraphicDriverMap::Iterator
2383 aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
2385 const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
2386 if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
2388 aDispConn = aDispConnTmp;
2392 if (aDispConn.IsNull())
2394 Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
2398 // process new events in queue
2399 SetDisplayConnection (aDispConn);
2401 for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
2403 const int anEventResult = ViewerMainLoop (0, NULL);
2404 if (anEventResult == 0)
2409 aNbRemain = XPending (aDispX);
2410 if (++anEventIter >= aNbEventsMax
2417 // Listening X events through Tcl_CreateFileHandler() callback is fragile,
2418 // it is possible that new events will arrive to queue before the end of this callback
2419 // so that either this callback should go into an infinite loop (blocking processing of other events)
2420 // or to keep unprocessed events till the next queue update (which can arrive not soon).
2421 // Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
2425 memset (&aDummyEvent, 0, sizeof(aDummyEvent));
2426 aDummyEvent.type = ClientMessage;
2427 aDummyEvent.xclient.format = 32;
2428 XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
2432 if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
2434 SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
2437 #elif !defined(__APPLE__)
2438 // =======================================================================
2439 // function : ViewerMainLoop
2441 // =======================================================================
2442 int ViewerMainLoop (Standard_Integer , const char** )
2449 //==============================================================================
2452 //==============================================================================
2454 static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
2456 const Handle(V3d_View) aView = ViewerTest::CurrentView();
2459 Message::SendFail ("Error: no active viewer");
2463 Standard_Boolean toFit = Standard_True;
2464 ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
2465 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2467 TCollection_AsciiString anArg (theArgv[anArgIter]);
2469 if (anUpdateTool.parseRedrawMode (anArg))
2473 else if (anArg == "-selected")
2475 ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
2476 toFit = Standard_False;
2480 Message::SendFail() << "Syntax error at '" << anArg << "'";
2486 aView->FitAll (0.01, Standard_False);
2491 //=======================================================================
2492 //function : VFitArea
2493 //purpose : Fit view to show area located between two points
2494 // : given in world 2D or 3D coordinates.
2495 //=======================================================================
2496 static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
2498 Handle(V3d_View) aView = ViewerTest::CurrentView();
2501 Message::SendFail ("Error: No active viewer");
2506 gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
2507 gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
2511 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2512 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2513 aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
2514 aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
2516 else if (theArgNb == 7)
2518 aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
2519 aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
2520 aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
2521 aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
2522 aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
2523 aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
2527 Message::SendFail ("Syntax error: Invalid number of arguments");
2528 theDI.PrintHelp(theArgVec[0]);
2532 // Convert model coordinates to view space
2533 Handle(Graphic3d_Camera) aCamera = aView->Camera();
2534 gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
2535 gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
2537 // Determine fit area
2538 gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
2539 gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
2541 Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
2543 if (aDiagonal < Precision::Confusion())
2545 Message::SendFail ("Error: view area is too small");
2549 aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
2553 //==============================================================================
2555 //purpose : ZFitall, no DRAW arguments
2556 //Draw arg : No args
2557 //==============================================================================
2558 static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
2560 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
2562 if (aCurrentView.IsNull())
2564 Message::SendFail ("Error: no active viewer");
2570 aCurrentView->ZFitAll();
2571 aCurrentView->Redraw();
2575 Standard_Real aScale = 1.0;
2579 aScale = Draw::Atoi (theArgVec[1]);
2582 aCurrentView->ZFitAll (aScale);
2583 aCurrentView->Redraw();
2588 //==============================================================================
2589 //function : VRepaint
2591 //==============================================================================
2592 static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
2594 Handle(V3d_View) aView = ViewerTest::CurrentView();
2597 Message::SendFail ("Error: no active viewer");
2601 Standard_Boolean isImmediateUpdate = Standard_False;
2602 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
2604 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2606 if (anArg == "-immediate"
2609 isImmediateUpdate = Standard_True;
2610 if (anArgIter + 1 < theArgNb
2611 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
2616 else if (anArg == "-continuous"
2619 || anArg == "-framerate")
2621 Standard_Real aFps = -1.0;
2622 if (anArgIter + 1 < theArgNb
2623 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
2625 aFps = Draw::Atof (theArgVec[++anArgIter]);
2628 ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
2629 ViewerTest::CurrentEventManager()->SetContinuousRedraw (false);
2632 aRedrawer.Start (aView, aFps);
2634 else if (aFps < 0.0)
2636 if (ViewerTest::GetViewerFromContext()->ActiveViews().Extent() == 1)
2639 ViewerTest::CurrentEventManager()->SetContinuousRedraw (true);
2640 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
2643 aRedrawer.Start (aView, aFps);
2652 Message::SendFail() << "Syntax error at '" << anArg << "'";
2657 if (isImmediateUpdate)
2659 aView->RedrawImmediate();
2668 //==============================================================================
2670 //purpose : Remove all the object from the viewer
2671 //Draw arg : No args
2672 //==============================================================================
2674 static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
2676 Handle(V3d_View) V = ViewerTest::CurrentView();
2678 ViewerTest::Clear();
2682 //==============================================================================
2685 //==============================================================================
2687 static int VPick (Draw_Interpretor& ,
2688 Standard_Integer theNbArgs,
2689 const char** theArgVec)
2691 if (ViewerTest::CurrentView().IsNull())
2698 Message::SendFail ("Syntax error: wrong number of arguments");
2702 while (ViewerMainLoop (theNbArgs, theArgVec))
2710 //! Parse image fill method.
2711 static bool parseImageMode (const TCollection_AsciiString& theName,
2712 Aspect_FillMethod& theMode)
2714 TCollection_AsciiString aName = theName;
2716 if (aName == "none")
2718 theMode = Aspect_FM_NONE;
2720 else if (aName == "centered")
2722 theMode = Aspect_FM_CENTERED;
2724 else if (aName == "tiled")
2726 theMode = Aspect_FM_TILED;
2728 else if (aName == "stretch")
2730 theMode = Aspect_FM_STRETCH;
2739 //! Parse gradient fill method.
2740 static bool parseGradientMode (const TCollection_AsciiString& theName,
2741 Aspect_GradientFillMethod& theMode)
2743 TCollection_AsciiString aName = theName;
2745 if (aName == "none")
2747 theMode = Aspect_GradientFillMethod_None;
2749 else if (aName == "hor"
2750 || aName == "horizontal")
2752 theMode = Aspect_GradientFillMethod_Horizontal;
2754 else if (aName == "ver"
2756 || aName == "vertical")
2758 theMode = Aspect_GradientFillMethod_Vertical;
2760 else if (aName == "diag"
2761 || aName == "diagonal"
2763 || aName == "diagonal1")
2765 theMode = Aspect_GradientFillMethod_Diagonal1;
2767 else if (aName == "diag2"
2768 || aName == "diagonal2")
2770 theMode = Aspect_GradientFillMethod_Diagonal2;
2772 else if (aName == "corner1")
2774 theMode = Aspect_GradientFillMethod_Corner1;
2776 else if (aName == "corner2")
2778 theMode = Aspect_GradientFillMethod_Corner2;
2780 else if (aName == "corner3")
2782 theMode = Aspect_GradientFillMethod_Corner3;
2784 else if (aName == "corner4")
2786 theMode = Aspect_GradientFillMethod_Corner4;
2788 else if (aName == "ellip"
2789 || aName == "elliptical")
2791 theMode = Aspect_GradientFillMethod_Elliptical;
2800 //==============================================================================
2801 //function : VBackground
2803 //==============================================================================
2804 static int VBackground (Draw_Interpretor& theDI,
2805 Standard_Integer theNbArgs,
2806 const char** theArgVec)
2810 theDI << "Syntax error: wrong number of arguments";
2814 const TCollection_AsciiString aCmdName (theArgVec[0]);
2815 bool isDefault = aCmdName == "vsetdefaultbg";
2816 Standard_Integer aNbColors = 0;
2817 Quantity_ColorRGBA aColors[2];
2819 Aspect_GradientFillMethod aGradientMode = Aspect_GradientFillMethod_None;
2820 bool hasGradientMode = false;
2822 TCollection_AsciiString anImagePath;
2823 Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
2824 bool hasImageMode = false;
2826 bool isSkydomeBg = false;
2827 Aspect_SkydomeBackground aSkydomeAspect;
2829 NCollection_Sequence<TCollection_AsciiString> aCubeMapSeq;
2830 Graphic3d_CubeMapOrder aCubeOrder = Graphic3d_CubeMapOrder::Default();
2831 bool isCubeZInverted = false;
2836 Handle(V3d_View) aView = ViewerTest::CurrentView();
2837 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
2838 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2840 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2842 if (anUpdateTool.parseRedrawMode (anArg))
2846 else if (anArg == "-default"
2851 else if (anArgIter + 1 < theNbArgs
2852 && (anArg == "-imagefile"
2853 || anArg == "-imgfile"
2854 || anArg == "-image"
2855 || anArg == "-img"))
2857 anImagePath = theArgVec[++anArgIter];
2859 else if (anArg == "-skydome"
2864 else if (anArgIter + 3 < theNbArgs
2866 && anArg == "-sundir")
2868 float aX = (float) Draw::Atof (theArgVec[++anArgIter]);
2869 float aY = (float) Draw::Atof (theArgVec[++anArgIter]);
2870 float aZ = (float) Draw::Atof (theArgVec[++anArgIter]);
2871 aSkydomeAspect.SetSunDirection (gp_Dir(aX, aY, aZ));
2873 else if (anArgIter + 1 < theNbArgs
2875 && anArg == "-cloud")
2877 float aCloudy = (float) Draw::Atof (theArgVec[++anArgIter]);
2878 aSkydomeAspect.SetCloudiness (aCloudy);
2880 else if (anArgIter + 1 < theNbArgs
2882 && anArg == "-time")
2884 float aTime = (float) Draw::Atof (theArgVec[++anArgIter]);
2885 aSkydomeAspect.SetTimeParameter (aTime);
2887 else if (anArgIter + 1 < theNbArgs
2891 float aFoggy = (float) Draw::Atof (theArgVec[++anArgIter]);
2892 aSkydomeAspect.SetFogginess (aFoggy);
2894 else if (anArgIter + 1 < theNbArgs
2896 && anArg == "-size")
2898 Standard_Integer aSize = Draw::Atoi (theArgVec[++anArgIter]);
2899 aSkydomeAspect.SetSize (aSize);
2901 else if (anArgIter + 1 < theNbArgs
2902 && aCubeMapSeq.IsEmpty()
2903 && (anArg == "-cubemap"
2907 aCubeMapSeq.Append (theArgVec[++anArgIter]);
2908 for (Standard_Integer aCubeSideIter = 1; anArgIter + aCubeSideIter < theNbArgs; ++aCubeSideIter)
2910 TCollection_AsciiString aSideArg (theArgVec[anArgIter + aCubeSideIter]);
2911 if (!aSideArg.IsEmpty()
2912 && aSideArg.Value (1) == '-')
2917 aCubeMapSeq.Append (aSideArg);
2918 if (aCubeMapSeq.Size() == 6)
2925 if (aCubeMapSeq.Size() > 1
2926 && aCubeMapSeq.Size() < 6)
2928 aCubeMapSeq.Remove (2, aCubeMapSeq.Size());
2931 else if (anArgIter + 6 < theNbArgs
2932 && anArg == "-order")
2934 for (Standard_Integer aCubeSideIter = 0; aCubeSideIter < 6; ++aCubeSideIter)
2936 Standard_Integer aSideArg = 0;
2937 if (!Draw::ParseInteger (theArgVec[anArgIter + aCubeSideIter + 1], aSideArg)
2941 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2944 aCubeOrder.Set ((Graphic3d_CubeMapSide )aCubeSideIter, (unsigned char )aSideArg);
2946 if (!aCubeOrder.IsValid())
2948 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2953 else if (anArg == "-invertedz"
2954 || anArg == "-noinvertedz"
2956 || anArg == "-noinvz")
2958 isCubeZInverted = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2960 else if (anArg == "-pbrenv"
2961 || anArg == "-nopbrenv"
2963 || anArg == "-noibl")
2965 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2966 if (anArgIter + 1 < theNbArgs)
2968 TCollection_AsciiString anIblArg (theArgVec[anArgIter + 1]);
2969 anIblArg.LowerCase();
2970 if (anIblArg == "keep"
2971 || anIblArg == "-1")
2976 else if (anIblArg == "ibl"
2978 || anIblArg == "on")
2980 toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
2983 else if (anIblArg == "noibl"
2985 || anIblArg == "off")
2987 toUseIBL = !anArg.StartsWith ("-no") ? 0 : 1;
2992 else if (anArg == "-srgb"
2993 || anArg == "-nosrgb")
2995 isSRgb = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2997 else if (aNbColors < 2
2998 && (anArg == "-color"
2999 || anArg == "-col"))
3001 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3002 theArgVec + (anArgIter + 1),
3003 aColors[aNbColors].ChangeRGB());
3006 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3009 anArgIter += aNbParsed;
3012 else if (anArgIter + 1 < theNbArgs
3013 && (anArg == "-gradientmode"
3014 || anArg == "-gradmode"
3015 || anArg == "-gradmd"
3016 || anArg == "-grmode"
3017 || anArg == "-grmd")
3018 && parseGradientMode (theArgVec[anArgIter + 1], aGradientMode))
3021 hasGradientMode = true;
3023 else if (anArgIter + 1 < theNbArgs
3024 && (anArg == "-imagemode"
3025 || anArg == "-imgmode"
3026 || anArg == "-imagemd"
3027 || anArg == "-imgmd")
3028 && parseImageMode (theArgVec[anArgIter + 1], anImageMode))
3031 hasImageMode = true;
3033 else if (aNbColors == 0
3034 && anArgIter + 2 < theNbArgs
3035 && (anArg == "-gradient"
3039 Standard_Integer aNbParsed1 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3040 theArgVec + (anArgIter + 1),
3041 aColors[aNbColors].ChangeRGB());
3042 anArgIter += aNbParsed1;
3044 if (aNbParsed1 == 0)
3046 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3049 Standard_Integer aNbParsed2 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
3050 theArgVec + (anArgIter + 1),
3051 aColors[aNbColors].ChangeRGB());
3052 anArgIter += aNbParsed2;
3054 if (aNbParsed2 == 0)
3056 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3060 else if (parseGradientMode (theArgVec[anArgIter], aGradientMode))
3062 hasGradientMode = true;
3064 else if (aNbColors < 2
3065 && (Quantity_ColorRGBA::ColorFromName(theArgVec[anArgIter], aColors[aNbColors])
3066 || Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColors[aNbColors])))
3070 else if (anImagePath.IsEmpty()
3073 && aCubeMapSeq.IsEmpty())
3075 anImagePath = theArgVec[anArgIter];
3079 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
3087 theDI << "Error: no active viewer";
3092 && !hasGradientMode)
3094 theDI << "Syntax error at '-default'";
3102 ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
3103 ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
3104 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_None;
3105 ViewerTest_DefaultBackground.FlatColor = aColors[0].GetRGB();
3106 ViewerTest_DefaultBackground.SetDefaultGradient();
3107 ViewerTest_DefaultBackground.SetDefaultColor();
3111 aView->SetBgGradientStyle (hasGradientMode ? aGradientMode : Aspect_GradientFillMethod_None);
3112 aView->SetBackgroundColor (aColors[0].GetRGB());
3115 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
3119 else if (aNbColors == 2)
3123 ViewerTest_DefaultBackground.GradientColor1 = aColors[0].GetRGB();
3124 ViewerTest_DefaultBackground.GradientColor2 = aColors[1].GetRGB();
3125 if (hasGradientMode)
3127 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
3129 else if (ViewerTest_DefaultBackground.FillMethod == Aspect_GradientFillMethod_None)
3131 ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_Vertical;
3133 ViewerTest_DefaultBackground.SetDefaultGradient();
3137 if (!hasGradientMode)
3139 aGradientMode = aView->GradientBackground().BgGradientFillMethod();
3140 if (aGradientMode == Aspect_GradientFillMethod_None)
3142 aGradientMode = Aspect_GradientFillMethod_Vertical;
3145 aView->SetBgGradientColors (aColors[0].GetRGB(), aColors[1].GetRGB(), aGradientMode);
3148 aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
3152 else if (hasGradientMode)
3156 ViewerTest_DefaultBackground.FillMethod = aGradientMode;
3157 ViewerTest_DefaultBackground.SetDefaultGradient();
3161 aView->SetBgGradientStyle (aGradientMode);
3165 if (!anImagePath.IsEmpty())
3167 Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2D (anImagePath);
3168 aTextureMap->DisableModulate();
3169 aTextureMap->SetColorMap (isSRgb);
3170 if (!aTextureMap->IsDone())
3172 theDI << "Syntax error at '" << anImagePath << "'";
3175 aView->SetBackgroundImage (aTextureMap, anImageMode);
3177 else if (hasImageMode)
3179 aView->SetBgImageStyle (anImageMode);
3184 aView->SetBackgroundSkydome (aSkydomeAspect, toUseIBL != -1);
3187 if (!aCubeMapSeq.IsEmpty())
3189 Handle(Graphic3d_CubeMap) aCubeMap;
3190 if (aCubeMapSeq.Size() == 1)
3192 aCubeMap = new Graphic3d_CubeMapPacked (aCubeMapSeq.First(), aCubeOrder.Validated());
3196 NCollection_Array1<TCollection_AsciiString> aCubeMapArr (0, 5);
3197 Standard_Integer aCubeSide = 0;
3198 for (NCollection_Sequence<TCollection_AsciiString>::Iterator aFileIter (aCubeMapSeq); aFileIter.More(); aFileIter.Next(), ++aCubeSide)
3200 aCubeMapArr[aCubeSide] = aFileIter.Value();
3202 aCubeMap = new Graphic3d_CubeMapSeparate (aCubeMapArr);
3205 aCubeMap->SetZInversion (isCubeZInverted);
3206 aCubeMap->SetColorMap (isSRgb);
3208 aCubeMap->GetParams()->SetFilter (Graphic3d_TOTF_BILINEAR);
3209 aCubeMap->GetParams()->SetRepeat (false);
3210 aCubeMap->GetParams()->SetTextureUnit (Graphic3d_TextureUnit_EnvMap);
3212 aView->SetBackgroundCubeMap (aCubeMap, toUseIBL != -1);
3217 aView->SetImageBasedLighting (toUseIBL == 1);
3223 //==============================================================================
3225 //purpose : View Scaling
3226 //==============================================================================
3228 static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3230 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3231 if ( V3dView.IsNull() ) return 1;
3234 di << argv[0] << "Invalid number of arguments\n";
3237 V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
3240 //==============================================================================
3241 //function : VZBuffTrihedron
3243 //==============================================================================
3245 static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
3246 Standard_Integer theArgNb,
3247 const char** theArgVec)
3249 Handle(V3d_View) aView = ViewerTest::CurrentView();
3252 Message::SendFail ("Error: no active viewer");
3256 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
3258 Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
3259 V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
3260 Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
3261 Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
3262 Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
3263 Quantity_Color anArrowColorX = Quantity_NOC_RED;
3264 Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
3265 Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
3266 Standard_Real aScale = 0.1;
3267 Standard_Real aSizeRatio = 0.8;
3268 Standard_Real anArrowDiam = 0.05;
3269 Standard_Integer aNbFacets = 12;
3270 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3272 Standard_CString anArg = theArgVec[anArgIter];
3273 TCollection_AsciiString aFlag (anArg);
3275 if (anUpdateTool.parseRedrawMode (aFlag))
3279 else if (aFlag == "-on")
3283 else if (aFlag == "-off")
3285 aView->TriedronErase();
3288 else if (aFlag == "-pos"
3289 || aFlag == "-position"
3290 || aFlag == "-corner")
3292 if (++anArgIter >= theArgNb)
3294 Message::SendFail() << "Syntax error at '" << anArg << "'";
3298 if (!ViewerTest::ParseCorner (theArgVec[anArgIter], aPosition))
3300 Message::SendFail() << "Syntax error at '" << anArg << "' - unknown position '" << theArgVec[anArgIter] << "'";
3304 else if (aFlag == "-type")
3306 if (++anArgIter >= theArgNb)
3308 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3312 TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
3313 aTypeName.LowerCase();
3314 if (aTypeName == "wireframe"
3315 || aTypeName == "wire")
3317 aVisType = V3d_WIREFRAME;
3319 else if (aTypeName == "zbuffer"
3320 || aTypeName == "shaded")
3322 aVisType = V3d_ZBUFFER;
3326 Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
3329 else if (aFlag == "-scale")
3331 if (++anArgIter >= theArgNb)
3333 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3337 aScale = Draw::Atof (theArgVec[anArgIter]);
3339 else if (aFlag == "-size"
3340 || aFlag == "-sizeratio")
3342 if (++anArgIter >= theArgNb)
3344 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3348 aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
3350 else if (aFlag == "-arrowdiam"
3351 || aFlag == "-arrowdiameter")
3353 if (++anArgIter >= theArgNb)
3355 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3359 anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
3361 else if (aFlag == "-nbfacets")
3363 if (++anArgIter >= theArgNb)
3365 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3369 aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
3371 else if (aFlag == "-colorlabel"
3372 || aFlag == "-colorlabels"
3373 || aFlag == "-colorlabelx"
3374 || aFlag == "-colorlabely"
3375 || aFlag == "-colorlabelz"
3376 || aFlag == "-colorarrowx"
3377 || aFlag == "-colorarrowy"
3378 || aFlag == "-colorarrowz")
3380 Quantity_Color aColor;
3381 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
3382 theArgVec + anArgIter + 1,
3386 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3390 if (aFlag == "-colorarrowx")
3392 anArrowColorX = aColor;
3394 else if (aFlag == "-colorarrowy")
3396 anArrowColorY = aColor;
3398 else if (aFlag == "-colorarrowz")
3400 anArrowColorZ = aColor;
3402 else if (aFlag == "-colorlabelx")
3404 aLabelsColorX = aColor;
3406 else if (aFlag == "-colorlabely")
3408 aLabelsColorY = aColor;
3410 else if (aFlag == "-colorlabelz")
3412 aLabelsColorZ = aColor;
3416 aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
3418 anArgIter += aNbParsed;
3422 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3427 const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
3428 aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
3429 aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
3430 aTrihedron->SetSizeRatio (aSizeRatio);
3431 aTrihedron->SetNbFacets (aNbFacets);
3432 aTrihedron->SetArrowDiameter(anArrowDiam);
3433 aTrihedron->SetScale (aScale);
3434 aTrihedron->SetPosition (aPosition);
3435 aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
3436 aTrihedron->Display (aView);
3442 //==============================================================================
3443 //function : VRotate
3444 //purpose : Camera Rotating
3445 //==============================================================================
3447 static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
3449 Handle(V3d_View) aView = ViewerTest::CurrentView();
3452 Message::SendFail ("Error: no active viewer");
3456 Standard_Boolean hasFlags = Standard_False;
3457 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3459 Standard_CString anArg (theArgVec[anArgIter]);
3460 TCollection_AsciiString aFlag (anArg);
3462 if (aFlag == "-mousestart"
3463 || aFlag == "-mousefrom")
3465 hasFlags = Standard_True;
3466 if (anArgIter + 2 >= theArgNb)
3468 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3472 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3473 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3474 aView->StartRotation (anX, anY);
3476 else if (aFlag == "-mousemove")
3478 hasFlags = Standard_True;
3479 if (anArgIter + 2 >= theArgNb)
3481 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3485 Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
3486 Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
3487 aView->Rotation (anX, anY);
3489 else if (theArgNb != 4
3492 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3501 else if (theArgNb == 4)
3503 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3504 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3505 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3506 aView->Rotate (anAX, anAY, anAZ);
3509 else if (theArgNb == 7)
3511 Standard_Real anAX = Draw::Atof (theArgVec[1]);
3512 Standard_Real anAY = Draw::Atof (theArgVec[2]);
3513 Standard_Real anAZ = Draw::Atof (theArgVec[3]);
3515 Standard_Real anX = Draw::Atof (theArgVec[4]);
3516 Standard_Real anY = Draw::Atof (theArgVec[5]);
3517 Standard_Real anZ = Draw::Atof (theArgVec[6]);
3519 aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
3523 Message::SendFail ("Error: Invalid number of arguments");
3527 //==============================================================================
3529 //purpose : View zoom in / out (relative to current zoom)
3530 //==============================================================================
3532 static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3533 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3534 if ( V3dView.IsNull() ) {
3539 Standard_Real coef = Draw::Atof(argv[1]);
3540 if ( coef <= 0.0 ) {
3541 di << argv[1] << "Invalid value\n";
3544 V3dView->SetZoom( Draw::Atof(argv[1]) );
3547 di << argv[0] << " Invalid number of arguments\n";
3552 //==============================================================================
3554 //purpose : View panning (in pixels)
3555 //==============================================================================
3557 static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
3558 Handle(V3d_View) V3dView = ViewerTest::CurrentView();
3559 if ( V3dView.IsNull() ) return 1;
3562 V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
3565 di << argv[0] << " Invalid number of arguments\n";
3570 //==============================================================================
3572 //purpose : Place the point (in pixels) at the center of the window
3573 //==============================================================================
3574 static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
3576 Handle(V3d_View) aView = ViewerTest::CurrentView();
3579 Message::SendFail ("Error: no active viewer");
3585 Message::SendFail ("Syntax error: wrong number of arguments");
3589 aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
3594 static int VColorScale (Draw_Interpretor& theDI,
3595 Standard_Integer theArgNb,
3596 const char** theArgVec)
3598 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3599 Handle(V3d_View) aView = ViewerTest::CurrentView();
3600 if (aContext.IsNull())
3602 Message::SendFail ("Error: no active viewer");
3607 Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
3611 Handle(AIS_ColorScale) aColorScale;
3612 if (GetMapOfAIS().IsBound2 (theArgVec[1]))
3614 // find existing object
3615 aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
3616 if (aColorScale.IsNull())
3618 Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
3625 if (aColorScale.IsNull())
3627 Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
3631 theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
3632 << "Min range: " << aColorScale->GetMin() << "\n"
3633 << "Max range: " << aColorScale->GetMax() << "\n"
3634 << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
3635 << "Text height: " << aColorScale->GetTextHeight() << "\n"
3636 << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
3637 << "Color scale title: " << aColorScale->GetTitle() << "\n"
3638 << "Label position: ";
3639 switch (aColorScale->GetLabelPosition())
3641 case Aspect_TOCSP_NONE:
3644 case Aspect_TOCSP_LEFT:
3647 case Aspect_TOCSP_RIGHT:
3650 case Aspect_TOCSP_CENTER:
3651 theDI << "Center\n";
3657 if (aColorScale.IsNull())
3659 aColorScale = new AIS_ColorScale();
3660 aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
3661 aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
3664 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
3665 for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
3667 Standard_CString anArg = theArgVec[anArgIter];
3668 TCollection_AsciiString aFlag (anArg);
3670 if (anUpdateTool.parseRedrawMode (aFlag))
3674 else if (aFlag == "-range")
3676 if (anArgIter + 3 >= theArgNb)
3678 Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
3682 const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
3683 const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
3684 const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
3685 if (!aRangeMin.IsRealValue (Standard_True)
3686 || !aRangeMax.IsRealValue (Standard_True))
3688 Message::SendFail ("Syntax error: the range values should be real");
3691 else if (!aNbIntervals.IsIntegerValue())
3693 Message::SendFail ("Syntax error: the number of intervals should be integer");
3697 aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
3698 aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
3700 else if (aFlag == "-font")
3702 if (anArgIter + 1 >= theArgNb)
3704 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3707 TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
3708 if (!aFontArg.IsIntegerValue())
3710 Message::SendFail ("Syntax error: HeightFont value should be integer");
3714 aColorScale->SetTextHeight (aFontArg.IntegerValue());
3717 else if (aFlag == "-textpos")
3719 if (anArgIter + 1 >= theArgNb)
3721 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3725 TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
3726 aTextPosArg.LowerCase();
3727 Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
3728 if (aTextPosArg == "none")
3730 aLabPosition = Aspect_TOCSP_NONE;
3732 else if (aTextPosArg == "left")
3734 aLabPosition = Aspect_TOCSP_LEFT;
3736 else if (aTextPosArg == "right")
3738 aLabPosition = Aspect_TOCSP_RIGHT;
3740 else if (aTextPosArg == "center")
3742 aLabPosition = Aspect_TOCSP_CENTER;
3746 Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
3749 aColorScale->SetLabelPosition (aLabPosition);
3751 else if (aFlag == "-logarithmic"
3754 if (anArgIter + 1 >= theArgNb)
3756 Message::SendFail() << "Synta error at argument '" << anArg << "'";
3760 Standard_Boolean IsLog;
3761 if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
3763 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3766 aColorScale->SetLogarithmic (IsLog);
3768 else if (aFlag == "-huerange"
3771 if (anArgIter + 2 >= theArgNb)
3773 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3777 const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
3778 const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
3779 aColorScale->SetHueRange (aHueMin, aHueMax);
3781 else if (aFlag == "-colorrange")
3783 Quantity_Color aColorMin, aColorMax;
3784 Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3785 theArgVec + (anArgIter + 1),
3787 anArgIter += aNbParsed1;
3788 Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
3789 theArgVec + (anArgIter + 1),
3791 anArgIter += aNbParsed2;
3795 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3799 aColorScale->SetColorRange (aColorMin, aColorMax);
3801 else if (aFlag == "-reversed"
3802 || aFlag == "-inverted"
3803 || aFlag == "-topdown"
3804 || aFlag == "-bottomup")
3806 Standard_Boolean toEnable = Standard_True;
3807 if (anArgIter + 1 < theArgNb
3808 && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
3812 aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
3814 else if (aFlag == "-smooth"
3815 || aFlag == "-smoothtransition")
3817 Standard_Boolean toEnable = Standard_True;
3818 if (anArgIter + 1 < theArgNb
3819 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3823 aColorScale->SetSmoothTransition (toEnable);
3825 else if (aFlag == "-xy")
3827 if (anArgIter + 2 >= theArgNb)
3829 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3833 const TCollection_AsciiString anX (theArgVec[++anArgIter]);
3834 const TCollection_AsciiString anY (theArgVec[++anArgIter]);
3835 if (!anX.IsIntegerValue()
3836 || !anY.IsIntegerValue())
3838 Message::SendFail ("Syntax error: coordinates should be integer values");
3842 aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
3844 else if (aFlag == "-width"
3846 || aFlag == "-breadth")
3848 if (anArgIter + 1 >= theArgNb)
3850 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3854 const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
3855 if (!aBreadth.IsIntegerValue())
3857 Message::SendFail ("Syntax error: a width should be an integer value");
3860 aColorScale->SetBreadth (aBreadth.IntegerValue());
3862 else if (aFlag == "-height"
3865 if (anArgIter + 1 >= theArgNb)
3867 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3871 const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
3872 if (!aHeight.IsIntegerValue())
3874 Message::SendFail ("Syntax error: a width should be an integer value");
3877 aColorScale->SetHeight (aHeight.IntegerValue());
3879 else if (aFlag == "-color")
3881 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3883 Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
3886 else if (anArgIter + 2 >= theArgNb)
3888 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3892 const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
3893 if (!anInd.IsIntegerValue())
3895 Message::SendFail ("Syntax error: Index value should be integer");
3898 const Standard_Integer anIndex = anInd.IntegerValue();
3899 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
3901 Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
3905 Quantity_Color aColor;
3906 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3907 theArgVec + (anArgIter + 1),
3911 Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
3914 aColorScale->SetIntervalColor (aColor, anIndex);
3915 aColorScale->SetColorType (Aspect_TOCSD_USER);
3916 anArgIter += aNbParsed;
3918 else if (aFlag == "-label")
3920 if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
3922 Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
3925 else if (anArgIter + 2 >= theArgNb)
3927 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3931 Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
3932 if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
3934 Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
3938 TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
3939 aColorScale->SetLabel (aText, anIndex);
3940 aColorScale->SetLabelType (Aspect_TOCSD_USER);
3943 else if (aFlag == "-labelat"
3944 || aFlag == "-labat"
3945 || aFlag == "-labelatborder"
3946 || aFlag == "-labatborder"
3947 || aFlag == "-labelatcenter"
3948 || aFlag == "-labatcenter")
3950 Standard_Boolean toEnable = Standard_True;
3951 if (aFlag == "-labelat"
3952 || aFlag == "-labat")
3954 Standard_Integer aLabAtBorder = -1;
3955 if (++anArgIter >= theArgNb)
3957 TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
3958 anAtBorder.LowerCase();
3959 if (anAtBorder == "border")
3963 else if (anAtBorder == "center")
3968 if (aLabAtBorder == -1)
3970 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
3973 toEnable = (aLabAtBorder == 1);
3975 else if (anArgIter + 1 < theArgNb
3976 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
3980 aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
3981 || aFlag == "-labatcenter"
3985 else if (aFlag == "-colors")
3987 Aspect_SequenceOfColor aSeq;
3990 Quantity_Color aColor;
3991 Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
3992 theArgVec + (anArgIter + 1),
3998 anArgIter += aNbParsed;
3999 aSeq.Append (aColor);
4001 if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
4003 Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
4004 << aColorScale->GetNumberOfIntervals() << " intervals";
4008 aColorScale->SetColors (aSeq);
4009 aColorScale->SetColorType (Aspect_TOCSD_USER);
4011 else if (aFlag == "-uniform")
4013 const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
4014 const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
4015 const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
4016 aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
4017 aColorScale->SetColorType (Aspect_TOCSD_USER);
4019 else if (aFlag == "-labels"
4020 || aFlag == "-freelabels")
4022 if (anArgIter + 1 >= theArgNb)
4024 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4028 Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
4029 ? aColorScale->GetNumberOfIntervals() + 1
4030 : aColorScale->GetNumberOfIntervals();
4031 if (aFlag == "-freelabels")
4034 aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
4036 if (anArgIter + aNbLabels >= theArgNb)
4038 Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
4042 TColStd_SequenceOfExtendedString aSeq;
4043 for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
4045 aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
4047 aColorScale->SetLabels (aSeq);
4048 aColorScale->SetLabelType (Aspect_TOCSD_USER);
4050 else if (aFlag == "-title")
4052 if (anArgIter + 1 >= theArgNb)
4054 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4058 Standard_Boolean isTwoArgs = Standard_False;
4059 if (anArgIter + 2 < theArgNb)
4061 TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
4062 aSecondArg.LowerCase();
4063 Standard_DISABLE_DEPRECATION_WARNINGS
4064 if (aSecondArg == "none")
4066 aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
4067 isTwoArgs = Standard_True;
4069 else if (aSecondArg == "left")
4071 aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
4072 isTwoArgs = Standard_True;
4074 else if (aSecondArg == "right")
4076 aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
4077 isTwoArgs = Standard_True;
4079 else if (aSecondArg == "center")
4081 aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
4082 isTwoArgs = Standard_True;
4084 Standard_ENABLE_DEPRECATION_WARNINGS
4087 TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
4088 aColorScale->SetTitle (aTitle);
4095 else if (aFlag == "-demoversion"
4096 || aFlag == "-demo")
4098 aColorScale->SetPosition (0, 0);
4099 aColorScale->SetTextHeight (16);
4100 aColorScale->SetRange (0.0, 100.0);
4101 aColorScale->SetNumberOfIntervals (10);
4102 aColorScale->SetBreadth (0);
4103 aColorScale->SetHeight (0);
4104 aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
4105 aColorScale->SetColorType (Aspect_TOCSD_AUTO);
4106 aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
4108 else if (aFlag == "-findcolor")
4110 if (anArgIter + 1 >= theArgNb)
4112 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
4116 TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
4118 if (!anArg1.IsRealValue (Standard_True))
4120 Message::SendFail ("Syntax error: the value should be real");
4124 Quantity_Color aColor;
4125 aColorScale->FindColor (anArg1.RealValue(), aColor);
4126 theDI << Quantity_Color::StringName (aColor.Name());
4131 Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
4136 Standard_Integer aWinWidth = 0, aWinHeight = 0;
4137 aView->Window()->Size (aWinWidth, aWinHeight);
4138 if (aColorScale->GetBreadth() == 0)
4140 aColorScale->SetBreadth (aWinWidth);
4142 if (aColorScale->GetHeight() == 0)
4144 aColorScale->SetHeight (aWinHeight);
4146 aColorScale->SetToUpdate();
4147 ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
4151 //==============================================================================
4152 //function : VGraduatedTrihedron
4153 //purpose : Displays or hides a graduated trihedron
4154 //==============================================================================
4155 static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
4156 Quantity_Color& theColor)
4158 Quantity_NameOfColor aColorName;
4159 TCollection_AsciiString aVal = theValue;
4161 if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
4163 return Standard_False;
4165 theColor = Quantity_Color (aColorName);
4166 return Standard_True;
4169 static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
4173 Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
4174 << theArgs[0] <<"' for more information";
4178 NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
4179 TCollection_AsciiString aParseKey;
4180 for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
4182 TCollection_AsciiString anArg (theArgs [anArgIt]);
4184 if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
4187 aParseKey.Remove (1);
4188 aParseKey.LowerCase();
4189 aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
4193 if (aParseKey.IsEmpty())
4198 aMapOfArgs(aParseKey)->Append (anArg);
4202 for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
4203 aMapIt.More(); aMapIt.Next())
4205 const TCollection_AsciiString& aKey = aMapIt.Key();
4206 const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
4208 // Bool key, without arguments
4209 if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
4210 && anArgs->IsEmpty())
4216 if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
4217 && anArgs->Length() == 1)
4223 if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
4224 || aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
4225 || aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
4226 || aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
4227 && anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
4232 // One string argument
4233 if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
4234 || aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
4235 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4240 // One integer argument
4241 if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
4242 || aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
4243 || aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
4244 || aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
4245 && anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
4250 // One real argument
4251 if ( aKey.IsEqual ("arrowlength")
4252 && anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
4257 // Two string arguments
4258 if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
4259 && anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
4264 TCollection_AsciiString aLowerKey;
4267 aLowerKey.LowerCase();
4268 Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
4269 << "Type help for more information";
4273 Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4274 if (anAISContext.IsNull())
4276 Message::SendFail ("Error: no active viewer");
4280 Standard_Boolean toDisplay = Standard_True;
4281 Quantity_Color aColor;
4282 Graphic3d_GraduatedTrihedron aTrihedronData;
4283 // Process parameters
4284 Handle(TColStd_HSequenceOfAsciiString) aValues;
4285 if (aMapOfArgs.Find ("off", aValues))
4287 toDisplay = Standard_False;
4291 if (aMapOfArgs.Find ("xname", aValues))
4293 aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
4295 if (aMapOfArgs.Find ("yname", aValues))
4297 aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
4299 if (aMapOfArgs.Find ("zname", aValues))
4301 aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
4303 if (aMapOfArgs.Find ("xdrawname", aValues))
4305 aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4307 if (aMapOfArgs.Find ("ydrawname", aValues))
4309 aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4311 if (aMapOfArgs.Find ("zdrawname", aValues))
4313 aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
4315 if (aMapOfArgs.Find ("xnameoffset", aValues))
4317 aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4319 if (aMapOfArgs.Find ("ynameoffset", aValues))
4321 aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4323 if (aMapOfArgs.Find ("znameoffset", aValues))
4325 aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
4329 if (aMapOfArgs.Find ("xnamecolor", aValues))
4331 if (!GetColor (aValues->Value(1), aColor))
4333 Message::SendFail ("Syntax error: -xnamecolor wrong color name");
4336 aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
4338 if (aMapOfArgs.Find ("ynamecolor", aValues))
4340 if (!GetColor (aValues->Value(1), aColor))
4342 Message::SendFail ("Syntax error: -ynamecolor wrong color name");
4345 aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
4347 if (aMapOfArgs.Find ("znamecolor", aValues))
4349 if (!GetColor (aValues->Value(1), aColor))
4351 Message::SendFail ("Syntax error: -znamecolor wrong color name");
4354 aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
4356 if (aMapOfArgs.Find ("xcolor", aValues))
4358 if (!GetColor (aValues->Value(1), aColor))
4360 Message::SendFail ("Syntax error: -xcolor wrong color name");
4363 aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
4365 if (aMapOfArgs.Find ("ycolor", aValues))
4367 if (!GetColor (aValues->Value(1), aColor))
4369 Message::SendFail ("Syntax error: -ycolor wrong color name");
4372 aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
4374 if (aMapOfArgs.Find ("zcolor", aValues))
4376 if (!GetColor (aValues->Value(1), aColor))
4378 Message::SendFail ("Syntax error: -zcolor wrong color name");
4381 aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
4385 if (aMapOfArgs.Find ("xticks", aValues))
4387 aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4389 if (aMapOfArgs.Find ("yticks", aValues))
4391 aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4393 if (aMapOfArgs.Find ("zticks", aValues))
4395 aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
4397 if (aMapOfArgs.Find ("xticklength", aValues))
4399 aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4401 if (aMapOfArgs.Find ("yticklength", aValues))
4403 aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4405 if (aMapOfArgs.Find ("zticklength", aValues))
4407 aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
4409 if (aMapOfArgs.Find ("xdrawticks", aValues))
4411 aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4413 if (aMapOfArgs.Find ("ydrawticks", aValues))
4415 aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4417 if (aMapOfArgs.Find ("zdrawticks", aValues))
4419 aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
4423 if (aMapOfArgs.Find ("xdrawvalues", aValues))
4425 aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4427 if (aMapOfArgs.Find ("ydrawvalues", aValues))
4429 aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4431 if (aMapOfArgs.Find ("zdrawvalues", aValues))
4433 aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
4435 if (aMapOfArgs.Find ("xvaluesoffset", aValues))
4437 aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4439 if (aMapOfArgs.Find ("yvaluesoffset", aValues))
4441 aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4443 if (aMapOfArgs.Find ("zvaluesoffset", aValues))
4445 aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
4449 if (aMapOfArgs.Find ("arrowlength", aValues))
4451 aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
4455 if (aMapOfArgs.Find ("namefont", aValues))
4457 aTrihedronData.SetNamesFont (aValues->Value(1));
4459 if (aMapOfArgs.Find ("valuesfont", aValues))
4461 aTrihedronData.SetValuesFont (aValues->Value(1));
4464 if (aMapOfArgs.Find ("drawgrid", aValues))
4466 aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
4468 if (aMapOfArgs.Find ("drawaxes", aValues))
4470 aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
4473 // The final step: display of erase trihedron
4476 ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
4480 ViewerTest::CurrentView()->GraduatedTrihedronErase();
4483 ViewerTest::GetAISContext()->UpdateCurrentViewer();
4484 ViewerTest::CurrentView()->Redraw();
4489 //==============================================================================
4492 //==============================================================================
4493 static int VTile (Draw_Interpretor& theDI,
4494 Standard_Integer theArgNb,
4495 const char** theArgVec)
4497 Handle(V3d_View) aView = ViewerTest::CurrentView();
4500 Message::SendFail ("Error: no active viewer");
4504 Graphic3d_CameraTile aTile = aView->Camera()->Tile();
4507 theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
4508 << "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
4509 << "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
4513 aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
4514 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
4516 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4518 if (anArg == "-lowerleft"
4519 || anArg == "-upperleft")
4521 if (anArgIter + 3 < theArgNb)
4523 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4526 aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
4527 aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4528 aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4530 else if (anArg == "-total"
4531 || anArg == "-totalsize"
4532 || anArg == "-viewsize")
4534 if (anArgIter + 3 < theArgNb)
4536 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4539 aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4540 aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4541 if (aTile.TotalSize.x() < 1
4542 || aTile.TotalSize.y() < 1)
4544 Message::SendFail ("Error: total size is incorrect");
4548 else if (anArg == "-tilesize")
4550 if (anArgIter + 3 < theArgNb)
4552 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
4556 aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
4557 aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
4558 if (aTile.TileSize.x() < 1
4559 || aTile.TileSize.y() < 1)
4561 Message::SendFail ("Error: tile size is incorrect");
4565 else if (anArg == "-unset")
4567 aView->Camera()->SetTile (Graphic3d_CameraTile());
4573 if (aTile.TileSize.x() < 1
4574 || aTile.TileSize.y() < 1)
4576 Message::SendFail ("Error: tile size is undefined");
4579 else if (aTile.TotalSize.x() < 1
4580 || aTile.TotalSize.y() < 1)
4582 Message::SendFail ("Error: total size is undefined");
4586 aView->Camera()->SetTile (aTile);
4591 //! Format ZLayer ID.
4592 inline const char* formZLayerId (const Standard_Integer theLayerId)
4596 case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
4597 case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
4598 case Graphic3d_ZLayerId_Top: return "[TOP]";
4599 case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
4600 case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
4601 case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
4606 //! Print the ZLayer information.
4607 inline void printZLayerInfo (Draw_Interpretor& theDI,
4608 const Graphic3d_ZLayerSettings& theLayer)
4610 if (!theLayer.Name().IsEmpty())
4612 theDI << " Name: " << theLayer.Name() << "\n";
4614 if (theLayer.IsImmediate())
4616 theDI << " Immediate: TRUE\n";
4618 theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
4619 theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
4620 theDI << " Culling size: " << theLayer.CullingSize() << "\n";
4621 theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
4622 theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
4623 theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
4624 if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
4626 theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
4630 //==============================================================================
4631 //function : VZLayer
4632 //purpose : Test z layer operations for v3d viewer
4633 //==============================================================================
4634 static int VZLayer (Draw_Interpretor& theDI,
4635 Standard_Integer theArgNb,
4636 const char** theArgVec)
4638 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
4639 if (aContextAIS.IsNull())
4641 Message::SendFail ("Error: no active viewer");
4645 const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
4648 TColStd_SequenceOfInteger aLayers;
4649 aViewer->GetAllZLayers (aLayers);
4650 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4652 theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
4653 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
4654 printZLayerInfo (theDI, aSettings);
4659 Standard_Integer anArgIter = 1;
4660 Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4661 ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
4662 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
4668 TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
4669 if (aFirstArg.IsIntegerValue())
4672 aLayerId = aFirstArg.IntegerValue();
4676 if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
4683 Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
4684 for (; anArgIter < theArgNb; ++anArgIter)
4686 // perform operation
4687 TCollection_AsciiString anArg (theArgVec[anArgIter]);
4689 if (anUpdateTool.parseRedrawMode (anArg))
4693 else if (anArg == "-add"
4696 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4697 if (!aViewer->AddZLayer (aLayerId))
4699 Message::SendFail ("Error: can not add a new z layer");
4705 else if (anArg == "-insertbefore"
4706 && anArgIter + 1 < theArgNb
4707 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4710 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4711 if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4713 Message::SendFail ("Error: can not add a new z layer");
4719 else if (anArg == "-insertafter"
4720 && anArgIter + 1 < theArgNb
4721 && ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
4724 aLayerId = Graphic3d_ZLayerId_UNKNOWN;
4725 if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
4727 Message::SendFail ("Error: can not add a new z layer");
4733 else if (anArg == "-del"
4734 || anArg == "-delete"
4737 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4739 if (++anArgIter >= theArgNb)
4741 Message::SendFail ("Syntax error: id of z layer to remove is missing");
4745 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4748 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
4749 || aLayerId == Graphic3d_ZLayerId_Default
4750 || aLayerId == Graphic3d_ZLayerId_Top
4751 || aLayerId == Graphic3d_ZLayerId_Topmost
4752 || aLayerId == Graphic3d_ZLayerId_TopOSD
4753 || aLayerId == Graphic3d_ZLayerId_BotOSD)
4755 Message::SendFail ("Syntax error: standard Z layer can not be removed");
4759 // move all object displayed in removing layer to default layer
4760 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
4761 anObjIter.More(); anObjIter.Next())
4763 const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
4765 || aPrs->ZLayer() != aLayerId)
4769 aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
4772 if (!aViewer->RemoveZLayer (aLayerId))
4774 Message::SendFail ("Z layer can not be removed");
4778 theDI << aLayerId << " ";
4781 else if (anArg == "-get"
4784 TColStd_SequenceOfInteger aLayers;
4785 aViewer->GetAllZLayers (aLayers);
4786 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
4788 theDI << aLayeriter.Value() << " ";
4793 else if (anArg == "-name")
4795 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4797 Message::SendFail ("Syntax error: id of Z layer is missing");
4801 if (++anArgIter >= theArgNb)
4803 Message::SendFail ("Syntax error: name is missing");
4807 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4808 aSettings.SetName (theArgVec[anArgIter]);
4809 aViewer->SetZLayerSettings (aLayerId, aSettings);
4811 else if (anArg == "-origin")
4813 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4815 Message::SendFail ("Syntax error: id of Z layer is missing");
4819 if (anArgIter + 2 >= theArgNb)
4821 Message::SendFail ("Syntax error: origin coordinates are missing");
4825 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4827 anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
4828 anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
4829 anOrigin.SetZ (0.0);
4830 if (anArgIter + 3 < theArgNb)
4832 anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
4839 aSettings.SetOrigin (anOrigin);
4840 aViewer->SetZLayerSettings (aLayerId, aSettings);
4842 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4843 && anArgIter + 1 < theArgNb
4844 && (anArg == "-cullingdistance"
4845 || anArg == "-cullingdist"
4846 || anArg == "-culldistance"
4847 || anArg == "-culldist"
4848 || anArg == "-distcull"
4849 || anArg == "-distculling"
4850 || anArg == "-distanceculling"))
4852 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4853 const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
4854 aSettings.SetCullingDistance (aDist);
4855 aViewer->SetZLayerSettings (aLayerId, aSettings);
4857 else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
4858 && anArgIter + 1 < theArgNb
4859 && (anArg == "-cullingsize"
4860 || anArg == "-cullsize"
4861 || anArg == "-sizecull"
4862 || anArg == "-sizeculling"))
4864 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4865 const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
4866 aSettings.SetCullingSize (aSize);
4867 aViewer->SetZLayerSettings (aLayerId, aSettings);
4869 else if (anArg == "-settings"
4870 || anArg == "settings")
4872 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4874 if (++anArgIter >= theArgNb)
4876 Message::SendFail ("Syntax error: id of Z layer is missing");
4880 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4883 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4884 printZLayerInfo (theDI, aSettings);
4886 else if (anArg == "-enable"
4887 || anArg == "enable"
4888 || anArg == "-disable"
4889 || anArg == "disable")
4891 const Standard_Boolean toEnable = anArg == "-enable"
4892 || anArg == "enable";
4893 if (++anArgIter >= theArgNb)
4895 Message::SendFail ("Syntax error: option name is missing");
4899 TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
4901 if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
4903 if (++anArgIter >= theArgNb)
4905 Message::SendFail ("Syntax error: id of Z layer is missing");
4909 aLayerId = Draw::Atoi (theArgVec[anArgIter]);
4912 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
4913 if (aSubOp == "depthtest"
4914 || aSubOp == "test")
4916 aSettings.SetEnableDepthTest (toEnable);
4918 else if (aSubOp == "depthwrite"
4919 || aSubOp == "write")
4921 aSettings.SetEnableDepthWrite (toEnable);
4923 else if (aSubOp == "depthclear"
4924 || aSubOp == "clear")
4926 aSettings.SetClearDepth (toEnable);
4928 else if (aSubOp == "depthoffset"
4929 || aSubOp == "offset")
4931 Graphic3d_PolygonOffset aParams;
4932 aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
4935 if (anArgIter + 2 >= theArgNb)
4937 Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
4941 aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4942 aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
4944 aSettings.SetPolygonOffset (aParams);
4946 else if (aSubOp == "positiveoffset"
4947 || aSubOp == "poffset")
4951 aSettings.SetDepthOffsetPositive();
4955 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
4958 else if (aSubOp == "negativeoffset"
4959 || aSubOp == "noffset")
4963 aSettings.SetDepthOffsetNegative();
4967 aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
4970 else if (aSubOp == "textureenv")
4972 aSettings.SetEnvironmentTexture (toEnable);
4974 else if (aSubOp == "raytracing")
4976 aSettings.SetRaytracable (toEnable);
4979 aViewer->SetZLayerSettings (aLayerId, aSettings);
4983 Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
4991 // The interactive presentation of 2d layer item
4992 // for "vlayerline" command it provides a presentation of
4993 // line with user-defined linewidth, linetype and transparency.
4994 class V3d_LineItem : public AIS_InteractiveObject
4998 DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
5001 Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5002 Standard_Real X2, Standard_Real Y2,
5003 Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
5004 Standard_Real theWidth = 0.5,
5005 Standard_Real theTransp = 1.0);
5009 virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
5010 const Handle(Prs3d_Presentation)& thePrs,
5011 const Standard_Integer theMode) Standard_OVERRIDE;
5013 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
5014 const Standard_Integer ) Standard_OVERRIDE
5019 Standard_Real myX1, myY1, myX2, myY2;
5020 Aspect_TypeOfLine myType;
5021 Standard_Real myWidth;
5024 // default constructor for line item
5025 V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
5026 Standard_Real X2, Standard_Real Y2,
5027 Aspect_TypeOfLine theType,
5028 Standard_Real theWidth,
5029 Standard_Real theTransp) :
5030 myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
5031 myType(theType), myWidth(theWidth)
5033 SetTransparency (1-theTransp);
5037 void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
5038 const Handle(Prs3d_Presentation)& thePresentation,
5039 const Standard_Integer )
5041 thePresentation->Clear();
5042 Quantity_Color aColor (Quantity_NOC_RED);
5043 Standard_Integer aWidth, aHeight;
5044 ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
5045 Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
5046 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
5047 aPrim->AddVertex(myX1, aHeight-myY1, 0.);
5048 aPrim->AddVertex(myX2, aHeight-myY2, 0.);
5049 Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
5050 aGroup->SetPrimitivesAspect (anAspect->Aspect());
5051 aGroup->AddPrimitiveArray (aPrim);
5054 //=============================================================================
5055 //function : VLayerLine
5056 //purpose : Draws line in the v3d view layer with given attributes: linetype,
5057 // : linewidth, transparency coefficient
5058 //============================================================================
5059 static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
5061 // get the active view
5062 Handle(V3d_View) aView = ViewerTest::CurrentView();
5065 di << "Call vinit before!\n";
5070 di << "Use: " << argv[0];
5071 di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
5072 di << " linetype : { 0 | 1 | 2 | 3 } \n";
5073 di << " 0 - solid \n";
5074 di << " 1 - dashed \n";
5075 di << " 2 - dot \n";
5076 di << " 3 - dashdot\n";
5077 di << " transparency : { 0.0 - 1.0 } \n";
5078 di << " 0.0 - transparent\n";
5079 di << " 1.0 - visible \n";
5083 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5084 // get the input params
5085 Standard_Real X1 = Draw::Atof(argv[1]);
5086 Standard_Real Y1 = Draw::Atof(argv[2]);
5087 Standard_Real X2 = Draw::Atof(argv[3]);
5088 Standard_Real Y2 = Draw::Atof(argv[4]);
5090 Standard_Real aWidth = 0.5;
5091 Standard_Real aTransparency = 1.0;
5095 aWidth = Draw::Atof(argv[5]);
5097 // select appropriate line type
5098 Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
5100 && !ViewerTest::ParseLineType (argv[6], aLineType))
5102 Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
5109 aTransparency = Draw::Atof(argv[7]);
5110 if (aTransparency < 0 || aTransparency > 1.0)
5111 aTransparency = 1.0;
5114 static Handle (V3d_LineItem) aLine;
5115 if (!aLine.IsNull())
5117 aContext->Erase (aLine, Standard_False);
5119 aLine = new V3d_LineItem (X1, Y1, X2, Y2,
5123 aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
5124 aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
5125 aLine->SetToUpdate();
5126 aContext->Display (aLine, Standard_True);
5132 //==============================================================================
5135 //==============================================================================
5137 static int VGrid (Draw_Interpretor& /*theDI*/,
5138 Standard_Integer theArgNb,
5139 const char** theArgVec)
5141 Handle(V3d_View) aView = ViewerTest::CurrentView();
5142 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5143 if (aView.IsNull() || aViewer.IsNull())
5145 Message::SendFail ("Error: no active viewer");
5149 Aspect_GridType aType = aViewer->GridType();
5150 Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
5151 Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
5152 Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
5153 bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
5154 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
5155 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5157 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5159 if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
5163 else if (anArgIter + 1 < theArgNb
5164 && anArg == "-type")
5166 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5167 anArgNext.LowerCase();
5168 if (anArgNext == "r"
5169 || anArgNext == "rect"
5170 || anArgNext == "rectangular")
5172 aType = Aspect_GT_Rectangular;
5174 else if (anArgNext == "c"
5175 || anArgNext == "circ"
5176 || anArgNext == "circular")
5178 aType = Aspect_GT_Circular;
5182 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5186 else if (anArgIter + 1 < theArgNb
5187 && anArg == "-mode")
5189 TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
5190 anArgNext.LowerCase();
5191 if (anArgNext == "l"
5192 || anArgNext == "line"
5193 || anArgNext == "lines")
5195 aMode = Aspect_GDM_Lines;
5197 else if (anArgNext == "p"
5198 || anArgNext == "point"
5199 || anArgNext == "points")
5201 aMode = Aspect_GDM_Points;
5205 Message::SendFail() << "Syntax error at '" << anArgNext << "'";
5209 else if (anArgIter + 2 < theArgNb
5210 && (anArg == "-origin"
5211 || anArg == "-orig"))
5214 aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5215 Draw::Atof (theArgVec[anArgIter + 2]));
5218 else if (anArgIter + 2 < theArgNb
5219 && anArg == "-step")
5222 aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5223 Draw::Atof (theArgVec[anArgIter + 2]));
5224 if (aNewStepXY.x() <= 0.0
5225 || aNewStepXY.y() <= 0.0)
5227 Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5232 else if (anArgIter + 1 < theArgNb
5233 && (anArg == "-angle"
5234 || anArg == "-rotangle"
5235 || anArg == "-rotationangle"))
5238 aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
5240 else if (anArgIter + 1 < theArgNb
5241 && (anArg == "-zoffset"
5245 aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
5247 else if (anArgIter + 1 < theArgNb
5248 && anArg == "-radius")
5252 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
5253 if (aNewStepXY.x() <= 0.0)
5255 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
5259 else if (anArgIter + 2 < theArgNb
5260 && anArg == "-size")
5263 aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
5264 Draw::Atof (theArgVec[anArgIter + 2]));
5265 if (aNewStepXY.x() <= 0.0
5266 || aNewStepXY.y() <= 0.0)
5268 Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
5273 else if (anArg == "r"
5275 || anArg == "rectangular")
5277 aType = Aspect_GT_Rectangular;
5279 else if (anArg == "c"
5281 || anArg == "circular")
5283 aType = Aspect_GT_Circular;
5285 else if (anArg == "l"
5287 || anArg == "lines")
5289 aMode = Aspect_GDM_Lines;
5291 else if (anArg == "p"
5293 || anArg == "points")
5295 aMode = Aspect_GDM_Points;
5297 else if (anArgIter + 1 >= theArgNb
5300 aViewer->DeactivateGrid();
5305 Message::SendFail() << "Syntax error at '" << anArg << "'";
5310 if (aType == Aspect_GT_Rectangular)
5312 Graphic3d_Vec2d anOrigXY, aStepXY;
5313 Standard_Real aRotAngle = 0.0;
5314 aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5317 anOrigXY = aNewOriginXY;
5321 aStepXY = aNewStepXY;
5325 aRotAngle = aNewRotAngle;
5327 aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
5328 if (hasSize || hasZOffset)
5330 Graphic3d_Vec3d aSize;
5331 aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5334 aSize.x() = aNewSizeXY.x();
5335 aSize.y() = aNewSizeXY.y();
5339 aSize.z() = aNewZOffset;
5341 aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
5344 else if (aType == Aspect_GT_Circular)
5346 Graphic3d_Vec2d anOrigXY;
5347 Standard_Real aRadiusStep;
5348 Standard_Integer aDivisionNumber;
5349 Standard_Real aRotAngle = 0.0;
5350 aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5353 anOrigXY = aNewOriginXY;
5357 aRadiusStep = aNewStepXY[0];
5358 aDivisionNumber = (int )aNewStepXY[1];
5359 if (aDivisionNumber < 1)
5361 Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
5367 aRotAngle = aNewRotAngle;
5370 aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
5371 if (hasSize || hasZOffset)
5373 Standard_Real aRadius = 0.0, aZOffset = 0.0;
5374 aViewer->CircularGridGraphicValues (aRadius, aZOffset);
5377 aRadius = aNewSizeXY.x();
5378 if (aNewSizeXY.y() != 0.0)
5380 Message::SendFail ("Syntax error: circular size should be specified as radius");
5386 aZOffset = aNewZOffset;
5388 aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
5391 aViewer->ActivateGrid (aType, aMode);
5395 //==============================================================================
5396 //function : VPriviledgedPlane
5398 //==============================================================================
5400 static int VPriviledgedPlane (Draw_Interpretor& theDI,
5401 Standard_Integer theArgNb,
5402 const char** theArgVec)
5404 if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
5406 Message::SendFail ("Error: wrong number of arguments! See usage:");
5407 theDI.PrintHelp (theArgVec[0]);
5411 // get the active viewer
5412 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
5413 if (aViewer.IsNull())
5415 Message::SendFail ("Error: no active viewer");
5421 gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
5422 const gp_Pnt& anOrig = aPriviledgedPlane.Location();
5423 const gp_Dir& aNorm = aPriviledgedPlane.Direction();
5424 const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
5425 theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
5426 << "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
5427 << "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
5431 Standard_Integer anArgIdx = 1;
5432 Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
5433 Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
5434 Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
5435 Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
5436 Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
5437 Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
5439 gp_Ax3 aPriviledgedPlane;
5440 gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
5441 gp_Dir aNorm (aNormX, aNormY, aNormZ);
5444 Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
5445 Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
5446 Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
5447 gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
5448 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
5452 aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
5455 aViewer->SetPrivilegedPlane (aPriviledgedPlane);
5460 //==============================================================================
5461 //function : VConvert
5463 //==============================================================================
5465 static int VConvert (Draw_Interpretor& theDI,
5466 Standard_Integer theArgNb,
5467 const char** theArgVec)
5469 // get the active view
5470 Handle(V3d_View) aView = ViewerTest::CurrentView();
5473 Message::SendFail ("Error: no active viewer");
5477 enum { Model, Ray, View, Window, Grid } aMode = Model;
5479 // access coordinate arguments
5480 TColStd_SequenceOfReal aCoord;
5481 Standard_Integer anArgIdx = 1;
5482 for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
5484 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5485 if (!anArg.IsRealValue (Standard_True))
5489 aCoord.Append (anArg.RealValue());
5492 // non-numeric argument too early
5493 if (aCoord.IsEmpty())
5495 Message::SendFail ("Error: wrong number of arguments! See usage:");
5496 theDI.PrintHelp (theArgVec[0]);
5500 // collect all other arguments and options
5501 for (; anArgIdx < theArgNb; ++anArgIdx)
5503 TCollection_AsciiString anArg (theArgVec[anArgIdx]);
5505 if (anArg == "window") aMode = Window;
5506 else if (anArg == "view") aMode = View;
5507 else if (anArg == "grid") aMode = Grid;
5508 else if (anArg == "ray") aMode = Ray;
5511 Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
5512 theDI.PrintHelp (theArgVec[0]);
5517 // complete input checks
5518 if ((aCoord.Length() == 1 && theArgNb > 3) ||
5519 (aCoord.Length() == 2 && theArgNb > 4) ||
5520 (aCoord.Length() == 3 && theArgNb > 5))
5522 Message::SendFail ("Error: wrong number of arguments! See usage:");
5523 theDI.PrintHelp (theArgVec[0]);
5527 Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
5528 Standard_Integer aXYp[2] = {0, 0};
5530 // convert one-dimensional coordinate
5531 if (aCoord.Length() == 1)
5535 case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
5536 case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
5538 Message::SendFail ("Error: wrong arguments! See usage:");
5539 theDI.PrintHelp (theArgVec[0]);
5544 // convert 2D coordinates from projection or view reference space
5545 if (aCoord.Length() == 2)
5550 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5551 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5555 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
5556 theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
5560 aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
5561 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5565 aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
5566 aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
5567 theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5571 aView->ConvertWithProj ((Standard_Integer) aCoord (1),
5572 (Standard_Integer) aCoord (2),
5573 aXYZ[0], aXYZ[1], aXYZ[2],
5574 aXYZ[3], aXYZ[4], aXYZ[5]);
5575 theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
5579 Message::SendFail ("Error: wrong arguments! See usage:");
5580 theDI.PrintHelp (theArgVec[0]);
5585 // convert 3D coordinates from view reference space
5586 else if (aCoord.Length() == 3)
5591 aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
5592 theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
5596 aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
5597 theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
5601 Message::SendFail ("Error: wrong arguments! See usage:");
5602 theDI.PrintHelp (theArgVec[0]);
5610 //==============================================================================
5613 //==============================================================================
5615 static int VFps (Draw_Interpretor& theDI,
5616 Standard_Integer theArgNb,
5617 const char** theArgVec)
5619 // get the active view
5620 Handle(V3d_View) aView = ViewerTest::CurrentView();
5623 Message::SendFail ("Error: no active viewer");
5627 Standard_Integer aFramesNb = -1;
5628 Standard_Real aDuration = -1.0;
5629 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5631 TCollection_AsciiString anArg (theArgVec[anArgIter]);
5634 && anArgIter + 1 < theArgNb
5635 && (anArg == "-duration"
5637 || anArg == "-time"))
5639 aDuration = Draw::Atof (theArgVec[++anArgIter]);
5641 else if (aFramesNb < 0
5642 && anArg.IsIntegerValue())
5644 aFramesNb = anArg.IntegerValue();
5647 Message::SendFail() << "Syntax error at '" << anArg << "'";
5653 Message::SendFail() << "Syntax error at '" << anArg << "'";
5657 if (aFramesNb < 0 && aDuration < 0.0)
5662 // the time is meaningless for first call
5663 // due to async OpenGl rendering
5666 // redraw view in loop to estimate average values
5669 Standard_Integer aFrameIter = 1;
5670 for (;; ++aFrameIter)
5674 && aFrameIter >= aFramesNb)
5676 && aTimer.ElapsedTime() >= aDuration))
5683 const Standard_Real aTime = aTimer.ElapsedTime();
5684 aTimer.OSD_Chronometer::Show (aCpu);
5686 const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
5687 const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
5689 // return statistics
5690 theDI << "FPS: " << aFpsAver << "\n"
5691 << "CPU: " << (1000.0 * aCpuAver) << " msec\n";
5693 // compute additional statistics in ray-tracing mode
5694 const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
5695 if (aParams.Method == Graphic3d_RM_RAYTRACING)
5697 Graphic3d_Vec2i aWinSize (0, 0);
5698 aView->Window()->Size (aWinSize.x(), aWinSize.y());
5700 // 1 shadow ray and 1 secondary ray pew each bounce
5701 const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
5702 theDI << "MRays/sec (upper bound): " << aMRays << "\n";
5709 //==============================================================================
5710 //function : VMemGpu
5712 //==============================================================================
5714 static int VMemGpu (Draw_Interpretor& theDI,
5715 Standard_Integer theArgNb,
5716 const char** theArgVec)
5719 Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
5720 if (aContextAIS.IsNull())
5722 Message::SendFail ("Error: no active viewer");
5726 Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
5727 if (aDriver.IsNull())
5729 Message::SendFail ("Error: graphic driver not available");
5733 Standard_Size aFreeBytes = 0;
5734 TCollection_AsciiString anInfo;
5735 if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
5737 Message::SendFail ("Error: information not available");
5741 if (theArgNb > 1 && *theArgVec[1] == 'f')
5743 theDI << Standard_Real (aFreeBytes);
5753 // ==============================================================================
5754 // function : VReadPixel
5756 // ==============================================================================
5757 static int VReadPixel (Draw_Interpretor& theDI,
5758 Standard_Integer theArgNb,
5759 const char** theArgVec)
5761 // get the active view
5762 Handle(V3d_View) aView = ViewerTest::CurrentView();
5765 Message::SendFail ("Error: no active viewer");
5768 else if (theArgNb < 3)
5770 Message::SendFail() << "Syntax error: wrong number of arguments.\n"
5771 << "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
5775 Image_Format aFormat = Image_Format_RGBA;
5776 Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
5778 Standard_Integer aWidth, aHeight;
5779 aView->Window()->Size (aWidth, aHeight);
5780 const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
5781 const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
5782 if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
5784 Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
5788 bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
5789 for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
5791 TCollection_AsciiString aParam (theArgVec[anIter]);
5793 if (aParam == "-rgb"
5795 || aParam == "-srgb"
5796 || aParam == "srgb")
5798 aFormat = Image_Format_RGB;
5799 aBufferType = Graphic3d_BT_RGB;
5800 toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
5802 else if (aParam == "-hls"
5805 aFormat = Image_Format_RGB;
5806 aBufferType = Graphic3d_BT_RGB;
5807 toShowHls = Standard_True;
5809 else if (aParam == "-rgbf"
5810 || aParam == "rgbf")
5812 aFormat = Image_Format_RGBF;
5813 aBufferType = Graphic3d_BT_RGB;
5815 else if (aParam == "-rgba"
5817 || aParam == "-srgba"
5818 || aParam == "srgba")
5820 aFormat = Image_Format_RGBA;
5821 aBufferType = Graphic3d_BT_RGBA;
5822 toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
5824 else if (aParam == "-rgbaf"
5825 || aParam == "rgbaf")
5827 aFormat = Image_Format_RGBAF;
5828 aBufferType = Graphic3d_BT_RGBA;
5830 else if (aParam == "-depth"
5831 || aParam == "depth")
5833 aFormat = Image_Format_GrayF;
5834 aBufferType = Graphic3d_BT_Depth;
5836 else if (aParam == "-name"
5837 || aParam == "name")
5839 toShowName = Standard_True;
5841 else if (aParam == "-hex"
5844 toShowHex = Standard_True;
5848 Message::SendFail() << "Syntax error at '" << aParam << "'";
5853 Image_PixMap anImage;
5854 if (!anImage.InitTrash (aFormat, aWidth, aHeight))
5856 Message::SendFail ("Error: image allocation failed");
5859 else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
5861 Message::SendFail ("Error: image dump failed");
5865 // redirect possible warning messages that could have been added by ToPixMap
5866 // into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
5867 // contaminate result of the command
5868 Standard_CString aWarnLog = theDI.Result();
5869 if (aWarnLog != NULL && aWarnLog[0] != '\0')
5871 std::cout << aWarnLog << std::endl;
5875 Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
5878 if (aBufferType == Graphic3d_BT_RGBA)
5880 theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
5884 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
5889 if (aBufferType == Graphic3d_BT_RGBA)
5891 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
5895 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
5900 switch (aBufferType)
5903 case Graphic3d_BT_RGB:
5907 theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
5909 else if (toShow_sRGB)
5911 const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
5912 theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
5916 theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
5920 case Graphic3d_BT_RGBA:
5922 const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
5923 theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
5926 case Graphic3d_BT_Depth:
5928 theDI << aColor.GetRGB().Red();
5937 //! Auxiliary presentation for an image plane.
5938 class ViewerTest_ImagePrs : public AIS_InteractiveObject
5941 //! Main constructor.
5942 ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
5943 const Standard_Real theWidth,
5944 const Standard_Real theHeight,
5945 const TCollection_AsciiString& theLabel)
5946 : myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
5950 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
5952 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
5953 const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
5954 Graphic3d_MaterialAspect aMat;
5955 aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
5956 aMat.SetAmbientColor (Quantity_NOC_BLACK);
5957 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
5958 aMat.SetSpecularColor (Quantity_NOC_BLACK);
5959 aMat.SetEmissiveColor (Quantity_NOC_BLACK);
5960 aFillAspect->SetFrontMaterial (aMat);
5961 aFillAspect->SetTextureMap (new Graphic3d_Texture2D (theImage));
5962 aFillAspect->SetTextureMapOn();
5965 Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
5966 aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
5967 aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
5968 myDrawer->SetTextAspect (aTextAspect);
5971 const gp_Dir aNorm (0.0, 0.0, 1.0);
5972 myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
5973 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
5974 myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
5975 myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
5976 myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
5977 myTris->AddEdge (1);
5978 myTris->AddEdge (2);
5979 myTris->AddEdge (3);
5980 myTris->AddEdge (3);
5981 myTris->AddEdge (2);
5982 myTris->AddEdge (4);
5984 myRect = new Graphic3d_ArrayOfPolylines (4);
5985 myRect->AddVertex (myTris->Vertice (1));
5986 myRect->AddVertex (myTris->Vertice (3));
5987 myRect->AddVertex (myTris->Vertice (4));
5988 myRect->AddVertex (myTris->Vertice (2));
5992 //! Returns TRUE for accepted display modes.
5993 virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
5995 //! Compute presentation.
5996 virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
5997 const Handle(Prs3d_Presentation)& thePrs,
5998 const Standard_Integer theMode) Standard_OVERRIDE
6004 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6005 aGroup->AddPrimitiveArray (myTris);
6006 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
6007 aGroup->AddPrimitiveArray (myRect);
6008 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6013 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
6014 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
6015 aGroup->AddPrimitiveArray (myRect);
6016 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
6022 //! Compute selection.
6023 virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
6027 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
6028 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
6029 aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
6030 theSel->Add (aSensitive);
6035 Handle(Graphic3d_ArrayOfTriangles) myTris;
6036 Handle(Graphic3d_ArrayOfPolylines) myRect;
6037 TCollection_AsciiString myLabel;
6038 Standard_Real myWidth;
6039 Standard_Real myHeight;
6042 //==============================================================================
6043 //function : VDiffImage
6044 //purpose : The draw-command compares two images.
6045 //==============================================================================
6047 static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
6051 Message::SendFail ("Syntax error: not enough arguments");
6055 Standard_Integer anArgIter = 1;
6056 TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
6057 TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
6058 TCollection_AsciiString aDiffImagePath;
6059 Standard_Real aTolColor = -1.0;
6060 Standard_Integer toBlackWhite = -1;
6061 Standard_Integer isBorderFilterOn = -1;
6062 Standard_Boolean isOldSyntax = Standard_False;
6063 TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
6064 for (; anArgIter < theArgNb; ++anArgIter)
6066 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6068 if (anArgIter + 1 < theArgNb
6069 && (anArg == "-toleranceofcolor"
6070 || anArg == "-tolerancecolor"
6071 || anArg == "-tolerance"
6072 || anArg == "-toler"))
6074 aTolColor = Atof (theArgVec[++anArgIter]);
6075 if (aTolColor < 0.0 || aTolColor > 1.0)
6077 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6081 else if (anArg == "-blackwhite")
6083 Standard_Boolean toEnable = Standard_True;
6084 if (anArgIter + 1 < theArgNb
6085 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6089 toBlackWhite = toEnable ? 1 : 0;
6091 else if (anArg == "-borderfilter")
6093 Standard_Boolean toEnable = Standard_True;
6094 if (anArgIter + 1 < theArgNb
6095 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
6099 isBorderFilterOn = toEnable ? 1 : 0;
6101 else if (anArg == "-exitonclose")
6103 ViewerTest_EventManager::ToExitOnCloseView() = true;
6104 if (anArgIter + 1 < theArgNb
6105 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
6110 else if (anArg == "-closeonescape"
6111 || anArg == "-closeonesc")
6113 ViewerTest_EventManager::ToCloseViewOnEscape() = true;
6114 if (anArgIter + 1 < theArgNb
6115 && Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
6120 else if (anArgIter + 3 < theArgNb
6121 && anArg == "-display")
6123 aViewName = theArgVec[++anArgIter];
6124 aPrsNameRef = theArgVec[++anArgIter];
6125 aPrsNameNew = theArgVec[++anArgIter];
6126 if (anArgIter + 1 < theArgNb
6127 && *theArgVec[anArgIter + 1] != '-')
6129 aPrsNameDiff = theArgVec[++anArgIter];
6132 else if (aTolColor < 0.0
6133 && anArg.IsRealValue (Standard_True))
6135 isOldSyntax = Standard_True;
6136 aTolColor = anArg.RealValue();
6137 if (aTolColor < 0.0 || aTolColor > 1.0)
6139 Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
6143 else if (isOldSyntax
6144 && toBlackWhite == -1
6145 && (anArg == "0" || anArg == "1"))
6147 toBlackWhite = anArg == "1" ? 1 : 0;
6149 else if (isOldSyntax
6150 && isBorderFilterOn == -1
6151 && (anArg == "0" || anArg == "1"))
6153 isBorderFilterOn = anArg == "1" ? 1 : 0;
6155 else if (aDiffImagePath.IsEmpty())
6157 aDiffImagePath = theArgVec[anArgIter];
6161 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6166 Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
6167 Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
6168 if (!anImgRef->Load (anImgPathRef))
6170 Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
6173 if (!anImgNew->Load (anImgPathNew))
6175 Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
6179 // compare the images
6180 Image_Diff aComparer;
6181 Standard_Integer aDiffColorsNb = -1;
6182 if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
6184 aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
6185 aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
6186 aDiffColorsNb = aComparer.Compare();
6187 theDI << aDiffColorsNb << "\n";
6190 // save image of difference
6191 Handle(Image_AlienPixMap) aDiff;
6192 if (aDiffColorsNb > 0
6193 && (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
6195 aDiff = new Image_AlienPixMap();
6196 if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
6198 Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
6201 aComparer.SaveDiffImage (*aDiff);
6202 if (!aDiffImagePath.IsEmpty()
6203 && !aDiff->Save (aDiffImagePath))
6205 Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
6210 if (aViewName.IsEmpty())
6215 ViewerTest_Names aViewNames (aViewName);
6216 if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
6218 TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
6219 theDI.Eval (aCommand.ToCString());
6222 ViewerTest_VinitParams aParams;
6223 aParams.ViewName = aViewName;
6224 aParams.Size.x() = float(anImgRef->SizeX() * 2);
6225 aParams.Size.y() = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
6226 ? float(anImgRef->SizeY() * 2)
6227 : float(anImgRef->SizeY());
6228 TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
6230 Standard_Real aRatio = anImgRef->Ratio();
6231 Standard_Real aSizeX = 1.0;
6232 Standard_Real aSizeY = aSizeX / aRatio;
6234 OSD_Path aPath (anImgPathRef);
6235 TCollection_AsciiString aLabelRef;
6236 if (!aPath.Name().IsEmpty())
6238 aLabelRef = aPath.Name() + aPath.Extension();
6240 aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
6242 Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
6244 aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
6245 anImgRefPrs->SetLocalTransformation (aTrsfRef);
6246 ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
6249 OSD_Path aPath (anImgPathNew);
6250 TCollection_AsciiString aLabelNew;
6251 if (!aPath.Name().IsEmpty())
6253 aLabelNew = aPath.Name() + aPath.Extension();
6255 aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
6257 Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
6259 aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
6260 anImgNewPrs->SetLocalTransformation (aTrsfRef);
6261 ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
6263 Handle(ViewerTest_ImagePrs) anImgDiffPrs;
6264 if (!aDiff.IsNull())
6266 anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
6268 aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
6269 anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
6271 if (!aPrsNameDiff.IsEmpty())
6273 ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
6275 ViewerTest::CurrentView()->SetProj (V3d_Zpos);
6276 ViewerTest::CurrentView()->FitAll();
6280 //=======================================================================
6281 //function : VSelect
6282 //purpose : Emulates different types of selection by mouse:
6283 // 1) single click selection
6284 // 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
6285 // 3) selection with polygon having corners at
6286 // pixel positions (x1,y1),...,(xn,yn)
6287 // 4) any of these selections with shift button pressed
6288 //=======================================================================
6289 static Standard_Integer VSelect (Draw_Interpretor& ,
6290 Standard_Integer theNbArgs,
6291 const char** theArgVec)
6293 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
6296 Message::SendFail ("Error: no active viewer");
6300 NCollection_Sequence<Graphic3d_Vec2i> aPnts;
6301 bool toAllowOverlap = false;
6302 AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
6303 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6305 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6307 if (anArg == "-allowoverlap")
6309 toAllowOverlap = true;
6310 if (anArgIter + 1 < theNbArgs
6311 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
6316 else if (anArg == "-replace")
6318 aSelScheme = AIS_SelectionScheme_Replace;
6320 else if (anArg == "-replaceextra")
6322 aSelScheme = AIS_SelectionScheme_ReplaceExtra;
6324 else if (anArg == "-xor"
6325 || anArg == "-shift")
6327 aSelScheme = AIS_SelectionScheme_XOR;
6329 else if (anArg == "-add")
6331 aSelScheme = AIS_SelectionScheme_Add;
6333 else if (anArg == "-remove")
6335 aSelScheme = AIS_SelectionScheme_Remove;
6337 else if (anArgIter + 1 < theNbArgs
6338 && anArg.IsIntegerValue()
6339 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
6341 const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
6342 aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
6344 else if (anArgIter + 1 == theNbArgs
6345 && anArg.IsIntegerValue())
6347 if (anArg.IntegerValue() == 1)
6349 aSelScheme = AIS_SelectionScheme_XOR;
6354 Message::SendFail() << "Syntax error at '" << anArg << "'";
6361 aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
6364 Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
6365 if (aPnts.IsEmpty())
6367 aCtx->SelectDetected (aSelScheme);
6368 aCtx->CurrentViewer()->Invalidate();
6370 else if (aPnts.Length() == 2)
6373 && aPnts.First().y() < aPnts.Last().y())
6375 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6377 else if (!toAllowOverlap
6378 && aPnts.First().y() > aPnts.Last().y())
6380 std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
6383 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6387 aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
6389 aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
6393 //=======================================================================
6394 //function : VMoveTo
6395 //purpose : Emulates cursor movement to defined pixel position
6396 //=======================================================================
6397 static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
6398 Standard_Integer theNbArgs,
6399 const char** theArgVec)
6401 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6402 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6403 if (aContext.IsNull())
6405 Message::SendFail ("Error: no active viewer");
6409 Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
6410 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6412 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6413 anArgStr.LowerCase();
6414 if (anArgStr == "-reset"
6415 || anArgStr == "-clear")
6417 if (anArgIter + 1 < theNbArgs)
6419 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
6423 const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
6424 && aContext->CurrentViewer()->GridEcho();
6427 aContext->CurrentViewer()->HideGridEcho (aView);
6429 if (aContext->ClearDetected() || toEchoGrid)
6431 aContext->CurrentViewer()->RedrawImmediate();
6435 else if (aMousePos.x() == IntegerLast()
6436 && anArgStr.IsIntegerValue())
6438 aMousePos.x() = anArgStr.IntegerValue();
6440 else if (aMousePos.y() == IntegerLast()
6441 && anArgStr.IsIntegerValue())
6443 aMousePos.y() = anArgStr.IntegerValue();
6447 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6452 if (aMousePos.x() == IntegerLast()
6453 || aMousePos.y() == IntegerLast())
6455 Message::SendFail ("Syntax error: wrong number of arguments");
6459 ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
6460 ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
6461 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
6463 gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
6464 const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
6465 for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
6467 if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
6469 aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
6473 theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
6477 //=======================================================================
6478 //function : VSelectByAxis
6480 //=======================================================================
6481 static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
6482 Standard_Integer theNbArgs,
6483 const char** theArgVec)
6485 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
6486 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
6487 if (aContext.IsNull())
6489 Message::SendFail ("Error: no active viewer");
6493 TCollection_AsciiString aName;
6494 gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
6495 gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
6496 Standard_Boolean isOnlyTop = true;
6497 Standard_Boolean toShowNormal = false;
6498 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
6500 TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
6501 anArgStr.LowerCase();
6502 if (anArgStr == "-display")
6504 if (anArgIter + 1 >= theNbArgs)
6506 Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
6509 aName = theArgVec[++anArgIter];
6511 else if (anArgStr == "-onlytop")
6514 if (anArgIter + 1 < theNbArgs
6515 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
6520 else if (anArgStr == "-shownormal")
6522 toShowNormal = true;
6523 if (anArgIter + 1 < theNbArgs
6524 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
6529 else if (Precision::IsInfinite(anAxisLocation.X())
6530 && anArgStr.IsRealValue())
6532 anAxisLocation.SetX (anArgStr.RealValue());
6534 else if (Precision::IsInfinite(anAxisLocation.Y())
6535 && anArgStr.IsRealValue())
6537 anAxisLocation.SetY (anArgStr.RealValue());
6539 else if (Precision::IsInfinite(anAxisLocation.Z())
6540 && anArgStr.IsRealValue())
6542 anAxisLocation.SetZ (anArgStr.RealValue());
6544 else if (Precision::IsInfinite(anAxisDirection.X())
6545 && anArgStr.IsRealValue())
6547 anAxisDirection.SetX (anArgStr.RealValue());
6549 else if (Precision::IsInfinite(anAxisDirection.Y())
6550 && anArgStr.IsRealValue())
6552 anAxisDirection.SetY (anArgStr.RealValue());
6554 else if (Precision::IsInfinite(anAxisDirection.Z())
6555 && anArgStr.IsRealValue())
6557 anAxisDirection.SetZ (anArgStr.RealValue());
6561 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
6566 if (Precision::IsInfinite (anAxisLocation.X()) ||
6567 Precision::IsInfinite (anAxisLocation.Y()) ||
6568 Precision::IsInfinite (anAxisLocation.Z()) ||
6569 Precision::IsInfinite (anAxisDirection.X()) ||
6570 Precision::IsInfinite (anAxisDirection.Y()) ||
6571 Precision::IsInfinite (anAxisDirection.Z()))
6573 Message::SendFail() << "Invalid axis location and direction";
6577 gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
6579 if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
6581 theDI << "There are no any intersections with this axis.";
6584 NCollection_Sequence<gp_Pnt> aPoints;
6585 NCollection_Sequence<Graphic3d_Vec3> aNormals;
6586 NCollection_Sequence<Standard_Real> aNormalLengths;
6587 for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
6589 const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
6590 aPoints.Append (aPickedData.Point);
6591 aNormals.Append (aPickedData.Normal);
6592 Standard_Real aNormalLength = 1.0;
6593 if (!aPickedData.Entity.IsNull())
6595 aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
6597 aNormalLengths.Append (aNormalLength);
6599 if (!aName.IsEmpty())
6601 Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
6602 aContext->SetAutoActivateSelection (false);
6605 Quantity_Color anAxisColor = Quantity_NOC_GREEN;
6606 Handle(Geom_Axis2Placement) anAx2Axis =
6607 new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
6608 Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
6609 anAISAxis->SetColor (anAxisColor);
6610 ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
6612 // Display axis start point
6613 Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
6614 anAISStartPnt->SetMarker (Aspect_TOM_O);
6615 anAISStartPnt->SetColor (anAxisColor);
6616 ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
6618 Standard_Integer anIndex = 0;
6619 for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
6621 const gp_Pnt& aPoint = aPntIter.Value();
6623 // Display normals in intersection points
6626 const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
6627 Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
6628 if (aNormal.SquareModulus() > ShortRealEpsilon())
6630 gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
6631 Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
6632 anAISNormal->SetColor (Quantity_NOC_BLUE);
6633 anAISNormal->SetInfiniteState (false);
6634 ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
6638 // Display intersection points
6639 Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
6640 Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
6641 anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
6642 anAISIntersectPoint->SetColor (Quantity_NOC_RED);
6643 ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
6646 aContext->SetAutoActivateSelection (wasAuto);
6649 Standard_Integer anIndex = 0;
6650 for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
6652 const gp_Pnt& aPnt = anIter.Value();
6653 theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
6660 //! Global map storing all animations registered in ViewerTest.
6661 static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
6663 //! The animation calling the Draw Harness command.
6664 class ViewerTest_AnimationProc : public AIS_Animation
6666 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
6669 //! Main constructor.
6670 ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
6671 Draw_Interpretor* theDI,
6672 const TCollection_AsciiString& theCommand)
6673 : AIS_Animation (theAnimationName),
6675 myCommand (theCommand)
6682 //! Evaluate the command.
6683 virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
6685 TCollection_AsciiString aCmd = myCommand;
6686 replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
6687 replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
6688 replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
6689 replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
6690 replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
6691 myDrawInter->Eval (aCmd.ToCString());
6694 //! Find the keyword in the command and replace it with value.
6695 //! @return the position of the keyword to pass value
6696 void replace (TCollection_AsciiString& theCmd,
6697 const TCollection_AsciiString& theKey,
6698 const TCollection_AsciiString& theVal)
6700 TCollection_AsciiString aCmd (theCmd);
6702 const Standard_Integer aPos = aCmd.Search (theKey);
6708 TCollection_AsciiString aPart1, aPart2;
6709 Standard_Integer aPart1To = aPos - 1;
6711 && aPart1To <= theCmd.Length())
6713 aPart1 = theCmd.SubString (1, aPart1To);
6716 Standard_Integer aPart2From = aPos + theKey.Length();
6718 && aPart2From <= theCmd.Length())
6720 aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
6723 theCmd = aPart1 + theVal + aPart2;
6728 Draw_Interpretor* myDrawInter;
6729 TCollection_AsciiString myCommand;
6733 //! Auxiliary animation holder.
6734 class ViewerTest_AnimationHolder : public AIS_AnimationCamera
6736 DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
6738 ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
6739 const Handle(V3d_View)& theView,
6740 const Standard_Boolean theIsFreeView)
6741 : AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
6743 if (theAnim->Timer().IsNull())
6745 theAnim->SetTimer (new Media_Timer());
6747 myTimer = theAnim->Timer();
6751 myCamStart = new Graphic3d_Camera (theView->Camera());
6757 virtual void StartTimer (const Standard_Real theStartPts,
6758 const Standard_Real thePlaySpeed,
6759 const Standard_Boolean theToUpdate,
6760 const Standard_Boolean theToStopTimer) Standard_OVERRIDE
6762 base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
6769 //! Pause animation.
6770 virtual void Pause() Standard_OVERRIDE
6772 myState = AnimationState_Paused;
6773 // default implementation would stop all children,
6774 // but we want to keep wrapped animation paused
6775 myAnimations.First()->Pause();
6780 virtual void Stop() Standard_OVERRIDE
6786 //! Process one step of the animation according to the input time progress, including all children.
6787 virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
6789 Handle(V3d_View) aView = myView;
6791 && !myCamStart.IsNull())
6793 myCamStart->Copy (aView->Camera());
6795 base_type::updateWithChildren (thePosition);
6797 && !myCamStart.IsNull())
6799 aView->Camera()->Copy (myCamStart);
6803 void abortPlayback()
6805 if (!myView.IsNull())
6812 //! Replace the animation with the new one.
6813 static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
6814 Handle(AIS_Animation)& theAnimation,
6815 const Handle(AIS_Animation)& theAnimationNew)
6817 theAnimationNew->CopyFrom (theAnimation);
6818 if (!theParentAnimation.IsNull())
6820 theParentAnimation->Replace (theAnimation, theAnimationNew);
6824 ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
6825 ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
6827 theAnimation = theAnimationNew;
6830 //! Parse the point.
6831 static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
6833 const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
6834 if (!anXYZ[0].IsRealValue (Standard_True)
6835 || !anXYZ[1].IsRealValue (Standard_True)
6836 || !anXYZ[2].IsRealValue (Standard_True))
6838 return Standard_False;
6841 thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
6842 return Standard_True;
6845 //! Parse the quaternion.
6846 static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
6848 const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
6849 if (!anXYZW[0].IsRealValue (Standard_True)
6850 || !anXYZW[1].IsRealValue (Standard_True)
6851 || !anXYZW[2].IsRealValue (Standard_True)
6852 || !anXYZW[3].IsRealValue (Standard_True))
6854 return Standard_False;
6857 theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
6858 return Standard_True;
6861 //! Auxiliary class for flipping image upside-down.
6866 //! Empty constructor.
6867 ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
6869 //! Perform flipping.
6870 Standard_Boolean FlipY (Image_PixMap& theImage)
6872 if (theImage.IsEmpty()
6873 || theImage.SizeX() == 0
6874 || theImage.SizeY() == 0)
6876 return Standard_False;
6879 const Standard_Size aRowSize = theImage.SizeRowBytes();
6880 if (myTmp.Size() < aRowSize
6881 && !myTmp.Allocate (aRowSize))
6883 return Standard_False;
6886 // for odd height middle row should be left as is
6887 Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
6888 for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
6890 Standard_Byte* aTop = theImage.ChangeRow (aRowT);
6891 Standard_Byte* aBot = theImage.ChangeRow (aRowB);
6892 memcpy (myTmp.ChangeData(), aTop, aRowSize);
6893 memcpy (aTop, aBot, aRowSize);
6894 memcpy (aBot, myTmp.Data(), aRowSize);
6896 return Standard_True;
6900 NCollection_Buffer myTmp;
6905 //=================================================================================================
6906 //function : VViewParams
6907 //purpose : Gets or sets AIS View characteristics
6908 //=================================================================================================
6909 static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
6911 Handle(V3d_View) aView = ViewerTest::CurrentView();
6914 Message::SendFail ("Error: no active viewer");
6918 Standard_Boolean toSetProj = Standard_False;
6919 Standard_Boolean toSetUp = Standard_False;
6920 Standard_Boolean toSetAt = Standard_False;
6921 Standard_Boolean toSetEye = Standard_False;
6922 Standard_Boolean toSetScale = Standard_False;
6923 Standard_Boolean toSetSize = Standard_False;
6924 Standard_Boolean toSetCenter2d = Standard_False;
6925 Standard_Real aViewScale = aView->Scale();
6926 Standard_Real aViewAspect = aView->Camera()->Aspect();
6927 Standard_Real aViewSize = 1.0;
6928 Graphic3d_Vec2i aCenter2d;
6929 gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
6930 aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
6931 aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
6932 aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
6933 aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
6934 const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
6935 const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
6938 // print all of the available view parameters
6943 "Proj: %12g %12g %12g\n"
6944 "Up: %12g %12g %12g\n"
6945 "At: %12g %12g %12g\n"
6946 "Eye: %12g %12g %12g\n"
6947 "OrientMat: %12g %12g %12g %12g\n"
6948 " %12g %12g %12g %12g\n"
6949 " %12g %12g %12g %12g\n"
6950 " %12g %12g %12g %12g\n"
6951 "ProjMat: %12g %12g %12g %12g\n"
6952 " %12g %12g %12g %12g\n"
6953 " %12g %12g %12g %12g\n"
6954 " %12g %12g %12g %12g\n",
6955 aViewScale, aViewAspect,
6956 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6957 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6958 aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
6959 aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
6960 anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
6961 anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
6962 anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
6963 anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
6964 aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
6965 aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
6966 aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
6967 aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
6972 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
6973 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
6975 TCollection_AsciiString anArg (theArgVec[anArgIter]);
6977 if (anUpdateTool.parseRedrawMode (anArg))
6981 else if (anArg == "-cmd"
6982 || anArg == "-command"
6983 || anArg == "-args")
6992 aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
6993 aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
6994 aViewAt.X(), aViewAt.Y(), aViewAt.Z());
6997 else if (anArg == "-scale"
6998 || anArg == "-size")
7000 if (anArgIter + 1 < theArgsNb
7001 && *theArgVec[anArgIter + 1] != '-')
7003 const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
7004 if (aValueArg.IsRealValue (Standard_True))
7007 if (anArg == "-scale")
7009 toSetScale = Standard_True;
7010 aViewScale = aValueArg.RealValue();
7012 else if (anArg == "-size")
7014 toSetSize = Standard_True;
7015 aViewSize = aValueArg.RealValue();
7020 if (anArg == "-scale")
7022 theDi << "Scale: " << aView->Scale() << "\n";
7024 else if (anArg == "-size")
7026 Graphic3d_Vec2d aSizeXY;
7027 aView->Size (aSizeXY.x(), aSizeXY.y());
7028 theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
7031 else if (anArg == "-eye"
7034 || anArg == "-proj")
7036 if (anArgIter + 3 < theArgsNb)
7039 if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
7042 if (anArg == "-eye")
7044 toSetEye = Standard_True;
7047 else if (anArg == "-at")
7049 toSetAt = Standard_True;
7052 else if (anArg == "-up")
7054 toSetUp = Standard_True;
7057 else if (anArg == "-proj")
7059 toSetProj = Standard_True;
7066 if (anArg == "-eye")
7068 theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
7070 else if (anArg == "-at")
7072 theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
7074 else if (anArg == "-up")
7076 theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
7078 else if (anArg == "-proj")
7080 theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
7083 else if (anArg == "-center")
7085 if (anArgIter + 2 < theArgsNb)
7087 const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
7088 const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
7089 if (anX.IsIntegerValue()
7090 && anY.IsIntegerValue())
7092 toSetCenter2d = Standard_True;
7093 aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
7099 Message::SendFail() << "Syntax error at '" << anArg << "'";
7104 // change view parameters in proper order
7107 aView->SetScale (aViewScale);
7111 aView->SetSize (aViewSize);
7115 aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
7119 aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
7123 aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
7127 aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
7131 aView->SetCenter (aCenter2d.x(), aCenter2d.y());
7137 //==============================================================================
7138 //function : V2DMode
7140 //==============================================================================
7141 static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
7143 bool is2dMode = true;
7144 Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
7145 if (aV3dView.IsNull())
7147 Message::SendFail ("Error: no active viewer");
7150 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
7152 const TCollection_AsciiString anArg = theArgVec[anArgIt];
7153 TCollection_AsciiString anArgCase = anArg;
7154 anArgCase.LowerCase();
7155 if (anArgIt + 1 < theArgsNb
7156 && anArgCase == "-name")
7158 ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
7159 const TCollection_AsciiString& aViewName = aViewNames.GetViewName();
7160 if (!ViewerTest_myViews.IsBound1 (aViewName))
7162 Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
7165 aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
7167 else if (anArgCase == "-mode")
7169 if (anArgIt + 1 < theArgsNb
7170 && Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
7175 else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
7181 Message::SendFail() << "Syntax error: unknown argument " << anArg;
7186 aV3dView->SetView2DMode (is2dMode);
7190 //==============================================================================
7191 //function : VAnimation
7193 //==============================================================================
7194 static Standard_Integer VAnimation (Draw_Interpretor& theDI,
7195 Standard_Integer theArgNb,
7196 const char** theArgVec)
7198 Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
7201 for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
7202 anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
7204 theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
7210 Message::SendFail ("Error: no active viewer");
7214 Standard_Integer anArgIter = 1;
7215 TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
7216 if (aNameArg.IsEmpty())
7218 Message::SendFail ("Syntax error: animation name is not defined");
7222 TCollection_AsciiString aNameArgLower = aNameArg;
7223 aNameArgLower.LowerCase();
7224 if (aNameArgLower == "-reset"
7225 || aNameArgLower == "-clear")
7227 ViewerTest_AnimationTimelineMap.Clear();
7230 else if (aNameArg.Value (1) == '-')
7232 Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
7236 const char* aNameSplitter = "/";
7237 Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
7238 if (aSplitPos == -1)
7240 aNameSplitter = ".";
7241 aSplitPos = aNameArg.Search (aNameSplitter);
7244 // find existing or create a new animation by specified name within syntax "parent.child".
7245 Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
7246 for (; !aNameArg.IsEmpty();)
7248 TCollection_AsciiString aNameParent;
7249 if (aSplitPos != -1)
7251 if (aSplitPos == aNameArg.Length())
7253 Message::SendFail ("Syntax error: animation name is not defined");
7257 aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
7258 aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
7260 aSplitPos = aNameArg.Search (aNameSplitter);
7264 aNameParent = aNameArg;
7268 if (anAnimation.IsNull())
7270 if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
7272 anAnimation = new AIS_Animation (aNameParent);
7273 ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
7275 aRootAnimation = anAnimation;
7279 aParentAnimation = anAnimation;
7280 anAnimation = aParentAnimation->Find (aNameParent);
7281 if (anAnimation.IsNull())
7283 anAnimation = new AIS_Animation (aNameParent);
7284 aParentAnimation->Add (anAnimation);
7288 if (anAnimation.IsNull())
7290 Message::SendFail() << "Syntax error: wrong number of arguments";
7294 if (anArgIter >= theArgNb)
7296 // just print the list of children
7297 for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
7299 theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
7304 // animation parameters
7305 Standard_Boolean toPlay = Standard_False;
7306 Standard_Real aPlaySpeed = 1.0;
7307 Standard_Real aPlayStartTime = anAnimation->StartPts();
7308 Standard_Real aPlayDuration = anAnimation->Duration();
7309 Standard_Boolean isFreeCamera = Standard_False;
7310 Standard_Boolean toPauseOnClick = Standard_True;
7311 Standard_Boolean isLockLoop = Standard_False;
7312 Standard_Boolean toPrintElapsedTime = Standard_False;
7314 // video recording parameters
7315 TCollection_AsciiString aRecFile;
7316 Image_VideoParams aRecParams;
7318 Handle(V3d_View) aView = ViewerTest::CurrentView();
7319 for (; anArgIter < theArgNb; ++anArgIter)
7321 TCollection_AsciiString anArg (theArgVec[anArgIter]);
7324 if (anArg == "-reset"
7325 || anArg == "-clear")
7327 anAnimation->Clear();
7329 else if (anArg == "-remove"
7331 || anArg == "-delete")
7333 if (aParentAnimation.IsNull())
7335 ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
7339 aParentAnimation->Remove (anAnimation);
7343 else if (anArg == "-play")
7345 toPlay = Standard_True;
7346 if (++anArgIter < theArgNb)
7348 if (*theArgVec[anArgIter] == '-')
7353 aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
7355 if (++anArgIter < theArgNb)
7357 if (*theArgVec[anArgIter] == '-')
7362 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7366 else if (anArg == "-elapsedtime"
7367 || anArg == "-elapsed")
7369 toPrintElapsedTime = Standard_True;
7371 else if (anArg == "-resume")
7373 toPlay = Standard_True;
7374 aPlayStartTime = anAnimation->ElapsedTime();
7375 if (++anArgIter < theArgNb)
7377 if (*theArgVec[anArgIter] == '-')
7383 aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
7386 else if (anArg == "-pause")
7388 anAnimation->Pause();
7390 else if (anArg == "-stop")
7392 anAnimation->Stop();
7394 else if (anArg == "-playspeed"
7395 || anArg == "-speed")
7397 if (++anArgIter >= theArgNb)
7399 Message::SendFail() << "Syntax error at " << anArg << "";
7402 aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
7404 else if (anArg == "-lock"
7405 || anArg == "-lockloop"
7406 || anArg == "-playlockloop")
7408 isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
7410 else if (anArg == "-freecamera"
7411 || anArg == "-nofreecamera"
7412 || anArg == "-playfreecamera"
7413 || anArg == "-noplayfreecamera"
7414 || anArg == "-freelook"
7415 || anArg == "-nofreelook")
7417 isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7419 else if (anArg == "-pauseonclick"
7420 || anArg == "-nopauseonclick"
7421 || anArg == "-nopause")
7423 toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
7425 // video recodring options
7426 else if (anArg == "-rec"
7427 || anArg == "-record")
7429 if (++anArgIter >= theArgNb)
7431 Message::SendFail() << "Syntax error at " << anArg;
7435 aRecFile = theArgVec[anArgIter];
7436 if (aRecParams.FpsNum <= 0)
7438 aRecParams.FpsNum = 24;
7441 if (anArgIter + 2 < theArgNb
7442 && *theArgVec[anArgIter + 1] != '-'
7443 && *theArgVec[anArgIter + 2] != '-')
7445 TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
7446 TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
7447 if (aWidthArg .IsIntegerValue()
7448 && aHeightArg.IsIntegerValue())
7450 aRecParams.Width = aWidthArg .IntegerValue();
7451 aRecParams.Height = aHeightArg.IntegerValue();
7456 else if (anArg == "-fps")
7458 if (++anArgIter >= theArgNb)
7460 Message::SendFail() << "Syntax error at " << anArg;
7464 TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
7465 Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
7466 if (aSplitIndex == 0)
7468 aRecParams.FpsNum = aFpsArg.IntegerValue();
7472 const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
7473 aFpsArg.Split (aFpsArg.Length() - 1);
7474 const TCollection_AsciiString aNumStr = aFpsArg;
7475 aRecParams.FpsNum = aNumStr.IntegerValue();
7476 aRecParams.FpsDen = aDenStr.IntegerValue();
7477 if (aRecParams.FpsDen < 1)
7479 Message::SendFail() << "Syntax error at " << anArg;
7484 else if (anArg == "-format")
7486 if (++anArgIter >= theArgNb)
7488 Message::SendFail() << "Syntax error at " << anArg;
7491 aRecParams.Format = theArgVec[anArgIter];
7493 else if (anArg == "-pix_fmt"
7494 || anArg == "-pixfmt"
7495 || anArg == "-pixelformat")
7497 if (++anArgIter >= theArgNb)
7499 Message::SendFail() << "Syntax error at " << anArg;
7502 aRecParams.PixelFormat = theArgVec[anArgIter];
7504 else if (anArg == "-codec"
7505 || anArg == "-vcodec"
7506 || anArg == "-videocodec")
7508 if (++anArgIter >= theArgNb)
7510 Message::SendFail() << "Syntax error at " << anArg;
7513 aRecParams.VideoCodec = theArgVec[anArgIter];
7515 else if (anArg == "-crf"
7516 || anArg == "-preset"
7519 const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
7520 if (++anArgIter >= theArgNb)
7522 Message::SendFail() << "Syntax error at " << anArg;
7526 aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
7528 // animation definition options
7529 else if (anArg == "-start"
7530 || anArg == "-starttime"
7531 || anArg == "-startpts")
7533 if (++anArgIter >= theArgNb)
7535 Message::SendFail() << "Syntax error at " << anArg;
7539 anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
7540 aRootAnimation->UpdateTotalDuration();
7542 else if (anArg == "-end"
7543 || anArg == "-endtime"
7544 || anArg == "-endpts")
7546 if (++anArgIter >= theArgNb)
7548 Message::SendFail() << "Syntax error at " << anArg;
7552 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
7553 aRootAnimation->UpdateTotalDuration();
7555 else if (anArg == "-dur"
7556 || anArg == "-duration")
7558 if (++anArgIter >= theArgNb)
7560 Message::SendFail() << "Syntax error at " << anArg;
7564 anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
7565 aRootAnimation->UpdateTotalDuration();
7567 else if (anArg == "-command"
7569 || anArg == "-invoke"
7571 || anArg == "-proc")
7573 if (++anArgIter >= theArgNb)
7575 Message::SendFail() << "Syntax error at " << anArg;
7579 Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
7580 replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
7582 else if (anArg == "-objecttrsf"
7583 || anArg == "-objectransformation"
7584 || anArg == "-objtransformation"
7585 || anArg == "-objtrsf"
7586 || anArg == "-object"
7589 if (++anArgIter >= theArgNb)
7591 Message::SendFail() << "Syntax error at " << anArg;
7595 TCollection_AsciiString anObjName (theArgVec[anArgIter]);
7596 const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
7597 Handle(AIS_InteractiveObject) anObject;
7598 if (!aMapOfAIS.Find2 (anObjName, anObject))
7600 Message::SendFail() << "Syntax error: wrong object name at " << anArg;
7604 gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
7605 gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
7606 gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
7607 Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
7608 Standard_Boolean isTrsfSet = Standard_False;
7611 Standard_Real anAngles[2] = { 0.0, 0.0 };
7612 Standard_Boolean isAxisRotationSet = Standard_False;
7614 Standard_Integer aTrsfArgIter = anArgIter + 1;
7615 for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
7617 TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
7618 aTrsfArg.LowerCase();
7619 const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
7620 if (aTrsfArg.StartsWith ("-rotation")
7621 || aTrsfArg.StartsWith ("-rot"))
7623 isTrsfSet = Standard_True;
7624 if (aTrsfArgIter + 4 >= theArgNb
7625 || !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
7627 Message::SendFail() << "Syntax error at " << aTrsfArg;
7632 else if (aTrsfArg.StartsWith ("-location")
7633 || aTrsfArg.StartsWith ("-loc"))
7635 isTrsfSet = Standard_True;
7636 if (aTrsfArgIter + 3 >= theArgNb
7637 || !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
7639 Message::SendFail() << "Syntax error at " << aTrsfArg;
7644 else if (aTrsfArg.StartsWith ("-scale"))
7646 isTrsfSet = Standard_True;
7647 if (++aTrsfArgIter >= theArgNb)
7649 Message::SendFail() << "Syntax error at " << aTrsfArg;
7653 const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
7654 if (!aScaleStr.IsRealValue (Standard_True))
7656 Message::SendFail() << "Syntax error at " << aTrsfArg;
7659 aScales[anIndex] = aScaleStr.RealValue();
7661 else if (aTrsfArg == "-axis")
7663 isAxisRotationSet = Standard_True;
7664 gp_XYZ anOrigin, aDirection;
7665 if (aTrsfArgIter + 6 >= theArgNb
7666 || !parseXYZ (theArgVec + aTrsfArgIter + 1, anOrigin)
7667 || !parseXYZ (theArgVec + aTrsfArgIter + 4, aDirection))
7669 Message::SendFail() << "Syntax error at " << aTrsfArg;
7672 anAxis.SetLocation (anOrigin);
7673 anAxis.SetDirection (aDirection);
7676 else if (aTrsfArg.StartsWith ("-ang"))
7678 isAxisRotationSet = Standard_True;
7679 if (++aTrsfArgIter >= theArgNb)
7681 Message::SendFail() << "Syntax error at " << aTrsfArg;
7685 const TCollection_AsciiString anAngleStr (theArgVec[aTrsfArgIter]);
7686 if (!anAngleStr.IsRealValue (Standard_True))
7688 Message::SendFail() << "Syntax error at " << aTrsfArg;
7691 anAngles[anIndex] = anAngleStr.RealValue();
7695 anArgIter = aTrsfArgIter - 1;
7699 if (!isTrsfSet && !isAxisRotationSet)
7701 Message::SendFail() << "Syntax error at " << anArg;
7704 else if (aTrsfArgIter >= theArgNb)
7706 anArgIter = theArgNb;
7708 Handle(AIS_BaseAnimationObject) anObjAnimation;
7711 aTrsfs[0].SetRotation (aRotQuats[0]);
7712 aTrsfs[1].SetRotation (aRotQuats[1]);
7713 aTrsfs[0].SetTranslationPart (aLocPnts[0]);
7714 aTrsfs[1].SetTranslationPart (aLocPnts[1]);
7715 aTrsfs[0].SetScaleFactor (aScales[0]);
7716 aTrsfs[1].SetScaleFactor (aScales[1]);
7718 anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
7722 anObjAnimation = new AIS_AnimationAxisRotation (anAnimation->Name(), aCtx, anObject, anAxis,
7723 anAngles[0] * (M_PI / 180.0), anAngles[1] * (M_PI / 180.0));
7725 replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
7727 else if (anArg == "-viewtrsf"
7728 || anArg == "-view")
7730 Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
7731 if (aCamAnimation.IsNull())
7733 aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
7734 replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
7737 Handle(Graphic3d_Camera) aCams[2] =
7739 new Graphic3d_Camera (aCamAnimation->View()->Camera()),
7740 new Graphic3d_Camera (aCamAnimation->View()->Camera())
7743 Standard_Boolean isTrsfSet = Standard_False;
7744 Standard_Integer aViewArgIter = anArgIter + 1;
7745 for (; aViewArgIter < theArgNb; ++aViewArgIter)
7747 TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
7748 aViewArg.LowerCase();
7749 const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
7750 if (aViewArg.StartsWith ("-scale"))
7752 isTrsfSet = Standard_True;
7753 if (++aViewArgIter >= theArgNb)
7755 Message::SendFail() << "Syntax error at " << anArg;
7759 const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
7760 if (!aScaleStr.IsRealValue (Standard_True))
7762 Message::SendFail() << "Syntax error at " << aViewArg;
7765 Standard_Real aScale = aScaleStr.RealValue();
7766 aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
7767 aCams[anIndex]->SetScale (aScale);
7769 else if (aViewArg.StartsWith ("-eye")
7770 || aViewArg.StartsWith ("-center")
7771 || aViewArg.StartsWith ("-at")
7772 || aViewArg.StartsWith ("-up"))
7774 isTrsfSet = Standard_True;
7776 if (aViewArgIter + 3 >= theArgNb
7777 || !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
7779 Message::SendFail() << "Syntax error at " << aViewArg;
7784 if (aViewArg.StartsWith ("-eye"))
7786 aCams[anIndex]->SetEye (anXYZ);
7788 else if (aViewArg.StartsWith ("-center")
7789 || aViewArg.StartsWith ("-at"))
7791 aCams[anIndex]->SetCenter (anXYZ);
7793 else if (aViewArg.StartsWith ("-up"))
7795 aCams[anIndex]->SetUp (anXYZ);
7800 anArgIter = aViewArgIter - 1;
7806 Message::SendFail() << "Syntax error at " << anArg;
7809 else if (aViewArgIter >= theArgNb)
7811 anArgIter = theArgNb;
7814 aCamAnimation->SetCameraStart(aCams[0]);
7815 aCamAnimation->SetCameraEnd (aCams[1]);
7819 Message::SendFail() << "Syntax error at " << anArg;
7824 if (anAnimation.IsNull() || anAnimation->IsStopped())
7826 ViewerTest::CurrentEventManager()->AbortViewAnimation();
7827 ViewerTest::CurrentEventManager()->SetObjectsAnimation(Handle(AIS_Animation)());
7830 if (toPrintElapsedTime)
7832 theDI << "Elapsed Time: " << anAnimation->ElapsedTime() << " s\n";
7835 if (!toPlay && aRecFile.IsEmpty())
7840 // Start animation timeline and process frame updating.
7841 if (aRecParams.FpsNum <= 0
7844 Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
7845 aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7846 ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
7847 ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
7848 ViewerTest::CurrentEventManager()->ProcessExpose();
7852 // Perform video recording
7853 const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
7854 const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
7855 anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
7857 OSD_Timer aPerfTimer;
7860 Handle(Image_VideoRecorder) aRecorder;
7861 ImageFlipper aFlipper;
7862 Handle(Draw_ProgressIndicator) aProgress;
7863 if (!aRecFile.IsEmpty())
7865 if (aRecParams.Width <= 0
7866 || aRecParams.Height <= 0)
7868 aView->Window()->Size (aRecParams.Width, aRecParams.Height);
7871 aRecorder = new Image_VideoRecorder();
7872 if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
7874 Message::SendFail ("Error: failed to open video file for recording");
7878 aProgress = new Draw_ProgressIndicator (theDI, 1);
7881 // Manage frame-rated animation here
7882 Standard_Real aPts = aPlayStartTime;
7883 int64_t aNbFrames = 0;
7884 Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
7885 "Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
7886 Standard_Integer aSecondsProgress = 0;
7887 for (; aPts <= anUpperPts && aPS.More();)
7889 Standard_Real aRecPts = 0.0;
7890 if (aRecParams.FpsNum > 0)
7892 aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
7896 aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
7899 aPts = aPlayStartTime + aRecPts;
7901 if (!anAnimation->Update (aPts))
7906 if (!aRecorder.IsNull())
7908 V3d_ImageDumpOptions aDumpParams;
7909 aDumpParams.Width = aRecParams.Width;
7910 aDumpParams.Height = aRecParams.Height;
7911 aDumpParams.BufferType = Graphic3d_BT_RGBA;
7912 aDumpParams.StereoOptions = V3d_SDO_MONO;
7913 aDumpParams.ToAdjustAspect = Standard_True;
7914 if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
7916 Message::SendFail ("Error: view dump is failed");
7919 aFlipper.FlipY (aRecorder->ChangeFrame());
7920 if (!aRecorder->PushFrame())
7930 while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
7938 anAnimation->Stop();
7939 const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
7940 theDI << "Average FPS: " << aRecFps << "\n"
7941 << "Nb. Frames: " << Standard_Real(aNbFrames);
7944 aView->SetImmediateUpdate (wasImmediateUpdate);
7949 //=======================================================================
7950 //function : VChangeSelected
7951 //purpose : Adds the shape to selection or remove one from it
7952 //=======================================================================
7953 static Standard_Integer VChangeSelected (Draw_Interpretor& di,
7954 Standard_Integer argc,
7959 di<<"Usage : " << argv[0] << " shape \n";
7963 TCollection_AsciiString aName(argv[1]);
7964 Handle(AIS_InteractiveObject) anAISObject;
7965 if (!GetMapOfAIS().Find2 (aName, anAISObject)
7966 || anAISObject.IsNull())
7968 di<<"Use 'vdisplay' before";
7972 ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
7976 //=======================================================================
7977 //function : VNbSelected
7978 //purpose : Returns number of selected objects
7979 //=======================================================================
7980 static Standard_Integer VNbSelected (Draw_Interpretor& di,
7981 Standard_Integer argc,
7986 di << "Usage : " << argv[0] << "\n";
7989 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
7990 if(aContext.IsNull())
7992 di << "use 'vinit' command before " << argv[0] << "\n";
7995 di << aContext->NbSelected() << "\n";
7999 //=======================================================================
8000 //function : VSetViewSize
8002 //=======================================================================
8003 static Standard_Integer VSetViewSize (Draw_Interpretor& di,
8004 Standard_Integer argc,
8007 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8008 if(aContext.IsNull())
8010 di << "use 'vinit' command before " << argv[0] << "\n";
8015 di<<"Usage : " << argv[0] << " Size\n";
8018 Standard_Real aSize = Draw::Atof (argv[1]);
8021 di<<"Bad Size value : " << aSize << "\n";
8025 Handle(V3d_View) aView = ViewerTest::CurrentView();
8026 aView->SetSize(aSize);
8030 //=======================================================================
8031 //function : VMoveView
8033 //=======================================================================
8034 static Standard_Integer VMoveView (Draw_Interpretor& di,
8035 Standard_Integer argc,
8038 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8039 if(aContext.IsNull())
8041 di << "use 'vinit' command before " << argv[0] << "\n";
8044 if(argc < 4 || argc > 5)
8046 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8049 Standard_Real Dx = Draw::Atof (argv[1]);
8050 Standard_Real Dy = Draw::Atof (argv[2]);
8051 Standard_Real Dz = Draw::Atof (argv[3]);
8052 Standard_Boolean aStart = Standard_True;
8055 aStart = (Draw::Atoi (argv[4]) > 0);
8058 Handle(V3d_View) aView = ViewerTest::CurrentView();
8059 aView->Move(Dx,Dy,Dz,aStart);
8063 //=======================================================================
8064 //function : VTranslateView
8066 //=======================================================================
8067 static Standard_Integer VTranslateView (Draw_Interpretor& di,
8068 Standard_Integer argc,
8071 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8072 if(aContext.IsNull())
8074 di << "use 'vinit' command before " << argv[0] << "\n";
8077 if(argc < 4 || argc > 5)
8079 di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
8082 Standard_Real Dx = Draw::Atof (argv[1]);
8083 Standard_Real Dy = Draw::Atof (argv[2]);
8084 Standard_Real Dz = Draw::Atof (argv[3]);
8085 Standard_Boolean aStart = Standard_True;
8088 aStart = (Draw::Atoi (argv[4]) > 0);
8091 Handle(V3d_View) aView = ViewerTest::CurrentView();
8092 aView->Translate(Dx,Dy,Dz,aStart);
8096 //=======================================================================
8097 //function : VTurnView
8099 //=======================================================================
8100 static Standard_Integer VTurnView (Draw_Interpretor& di,
8101 Standard_Integer argc,
8104 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
8105 if(aContext.IsNull()) {
8106 di << "use 'vinit' command before " << argv[0] << "\n";
8109 if(argc < 4 || argc > 5){
8110 di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
8113 Standard_Real Ax = Draw::Atof (argv[1]);
8114 Standard_Real Ay = Draw::Atof (argv[2]);
8115 Standard_Real Az = Draw::Atof (argv[3]);
8116 Standard_Boolean aStart = Standard_True;
8119 aStart = (Draw::Atoi (argv[4]) > 0);
8122 Handle(V3d_View) aView = ViewerTest::CurrentView();
8123 aView->Turn(Ax,Ay,Az,aStart);
8127 //==============================================================================
8128 //function : VTextureEnv
8129 //purpose : ENables or disables environment mapping
8130 //==============================================================================
8131 class OCC_TextureEnv : public Graphic3d_TextureEnv
8134 OCC_TextureEnv(const Standard_CString FileName);
8135 OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
8136 void SetTextureParameters(const Standard_Boolean theRepeatFlag,
8137 const Standard_Boolean theModulateFlag,
8138 const Graphic3d_TypeOfTextureFilter theFilter,
8139 const Standard_ShortReal theXScale,
8140 const Standard_ShortReal theYScale,
8141 const Standard_ShortReal theXShift,
8142 const Standard_ShortReal theYShift,
8143 const Standard_ShortReal theAngle);
8144 DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
8146 DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
8148 OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
8149 : Graphic3d_TextureEnv(theFileName)
8153 OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
8154 : Graphic3d_TextureEnv(theTexId)
8158 void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
8159 const Standard_Boolean theModulateFlag,
8160 const Graphic3d_TypeOfTextureFilter theFilter,
8161 const Standard_ShortReal theXScale,
8162 const Standard_ShortReal theYScale,
8163 const Standard_ShortReal theXShift,
8164 const Standard_ShortReal theYShift,
8165 const Standard_ShortReal theAngle)
8167 myParams->SetRepeat (theRepeatFlag);
8168 myParams->SetModulate (theModulateFlag);
8169 myParams->SetFilter (theFilter);
8170 myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
8171 myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
8172 myParams->SetRotation (theAngle);
8175 static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
8177 // get the active view
8178 Handle(V3d_View) aView = ViewerTest::CurrentView();
8181 Message::SendFail ("Error: no active viewer");
8185 // Checking the input arguments
8186 Standard_Boolean anEnableFlag = Standard_False;
8187 Standard_Boolean isOk = theArgNb >= 2;
8190 TCollection_AsciiString anEnableOpt(theArgVec[1]);
8191 anEnableFlag = anEnableOpt.IsEqual("on");
8192 isOk = anEnableFlag || anEnableOpt.IsEqual("off");
8196 isOk = (theArgNb == 3 || theArgNb == 11);
8199 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8200 isOk = (!aTextureOpt.IsIntegerValue() ||
8201 (aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
8203 if (isOk && theArgNb == 11)
8205 TCollection_AsciiString aRepeatOpt (theArgVec[3]),
8206 aModulateOpt(theArgVec[4]),
8207 aFilterOpt (theArgVec[5]),
8208 aSScaleOpt (theArgVec[6]),
8209 aTScaleOpt (theArgVec[7]),
8210 aSTransOpt (theArgVec[8]),
8211 aTTransOpt (theArgVec[9]),
8212 anAngleOpt (theArgVec[10]);
8213 isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
8214 (aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
8215 (aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
8216 aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
8217 aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
8218 anAngleOpt.IsRealValue (Standard_True));
8225 Message::SendFail() << "Usage:\n"
8226 << theArgVec[0] << " off\n"
8227 << 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]";
8233 TCollection_AsciiString aTextureOpt(theArgVec[2]);
8234 Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
8235 new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
8236 new OCC_TextureEnv(theArgVec[2]);
8240 TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
8241 aTexEnv->SetTextureParameters(
8242 aRepeatOpt. IsEqual("repeat"),
8243 aModulateOpt.IsEqual("modulate"),
8244 aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
8245 aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
8246 Graphic3d_TOTF_TRILINEAR,
8247 (Standard_ShortReal)Draw::Atof(theArgVec[6]),
8248 (Standard_ShortReal)Draw::Atof(theArgVec[7]),
8249 (Standard_ShortReal)Draw::Atof(theArgVec[8]),
8250 (Standard_ShortReal)Draw::Atof(theArgVec[9]),
8251 (Standard_ShortReal)Draw::Atof(theArgVec[10])
8254 aView->SetTextureEnv(aTexEnv);
8256 else // Disabling environment mapping
8258 Handle(Graphic3d_TextureEnv) aTexture;
8259 aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
8268 typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
8270 //! Remove registered clipping plane from all views and objects.
8271 static void removePlane (MapOfPlanes& theRegPlanes,
8272 const TCollection_AsciiString& theName)
8274 Handle(Graphic3d_ClipPlane) aClipPlane;
8275 if (!theRegPlanes.Find (theName, aClipPlane))
8277 Message::SendWarning ("Warning: no such plane");
8281 theRegPlanes.UnBind (theName);
8282 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
8283 anIObjIt.More(); anIObjIt.Next())
8285 const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
8286 aPrs->RemoveClipPlane (aClipPlane);
8289 for (ViewerTest_ViewerCommandsViewMap::Iterator aViewIt(ViewerTest_myViews);
8290 aViewIt.More(); aViewIt.Next())
8292 const Handle(V3d_View)& aView = aViewIt.Key2();
8293 aView->RemoveClipPlane(aClipPlane);
8296 ViewerTest::RedrawAllViews();
8300 //===============================================================================================
8301 //function : VClipPlane
8303 //===============================================================================================
8304 static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8306 // use short-cut for created clip planes map of created (or "registered by name") clip planes
8307 static MapOfPlanes aRegPlanes;
8311 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
8313 theDi << aPlaneIter.Key() << " ";
8318 TCollection_AsciiString aCommand (theArgVec[1]);
8319 aCommand.LowerCase();
8320 const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
8321 if (anActiveView.IsNull())
8323 Message::SendFail ("Error: no active viewer");
8327 // print maximum number of planes for current viewer
8328 if (aCommand == "-maxplanes"
8329 || aCommand == "maxplanes")
8331 theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
8332 << " plane slots provided by driver.\n";
8336 // create / delete plane instance
8337 if (aCommand == "-create"
8338 || aCommand == "create"
8339 || aCommand == "-delete"
8340 || aCommand == "delete"
8341 || aCommand == "-clone"
8342 || aCommand == "clone")
8346 Message::SendFail ("Syntax error: plane name is required");
8350 Standard_Boolean toCreate = aCommand == "-create"
8351 || aCommand == "create";
8352 Standard_Boolean toClone = aCommand == "-clone"
8353 || aCommand == "clone";
8354 Standard_Boolean toDelete = aCommand == "-delete"
8355 || aCommand == "delete";
8356 TCollection_AsciiString aPlane (theArgVec[2]);
8360 if (aRegPlanes.IsBound (aPlane))
8362 std::cout << "Warning: existing plane has been overridden.\n";
8367 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8371 else if (toClone) // toClone
8373 if (!aRegPlanes.IsBound (aPlane))
8375 Message::SendFail ("Error: no such plane");
8378 else if (theArgsNb < 4)
8380 Message::SendFail ("Syntax error: enter name for new plane");
8384 TCollection_AsciiString aClone (theArgVec[3]);
8385 if (aRegPlanes.IsBound (aClone))
8387 Message::SendFail ("Error: plane name is in use");
8391 const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
8393 aRegPlanes.Bind (aClone, aClipPlane->Clone());
8403 for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
8405 aPlane = aPlaneIter.Key();
8406 removePlane (aRegPlanes, aPlane);
8407 aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
8412 removePlane (aRegPlanes, aPlane);
8418 aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
8423 // set / unset plane command
8424 if (aCommand == "set"
8425 || aCommand == "unset")
8429 Message::SendFail ("Syntax error: need more arguments");
8433 // redirect to new syntax
8434 NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
8435 anArgVec.SetValue (1, theArgVec[0]);
8436 anArgVec.SetValue (2, theArgVec[2]);
8437 anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
8438 for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
8440 anArgVec.SetValue (anIt, theArgVec[anIt]);
8443 return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
8446 // change plane command
8447 TCollection_AsciiString aPlaneName;
8448 Handle(Graphic3d_ClipPlane) aClipPlane;
8449 Standard_Integer anArgIter = 0;
8450 if (aCommand == "-change"
8451 || aCommand == "change")
8453 // old syntax support
8456 Message::SendFail ("Syntax error: need more arguments");
8461 aPlaneName = theArgVec[2];
8462 if (!aRegPlanes.Find (aPlaneName, aClipPlane))
8464 Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
8468 else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
8471 aPlaneName = theArgVec[1];
8476 aPlaneName = theArgVec[1];
8477 aClipPlane = new Graphic3d_ClipPlane();
8478 aRegPlanes.Bind (aPlaneName, aClipPlane);
8479 theDi << "Created new plane " << aPlaneName << ".\n";
8482 if (theArgsNb - anArgIter < 1)
8484 Message::SendFail ("Syntax error: need more arguments");
8488 for (; anArgIter < theArgsNb; ++anArgIter)
8490 const char** aChangeArgs = theArgVec + anArgIter;
8491 Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
8492 TCollection_AsciiString aChangeArg (aChangeArgs[0]);
8493 aChangeArg.LowerCase();
8495 Standard_Boolean toEnable = Standard_True;
8496 if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
8498 aClipPlane->SetOn (toEnable);
8500 else if (aChangeArg.StartsWith ("-equation")
8501 || aChangeArg.StartsWith ("equation"))
8503 if (aNbChangeArgs < 5)
8505 Message::SendFail ("Syntax error: need more arguments");
8509 Standard_Integer aSubIndex = 1;
8510 Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
8511 if (aPrefixLen < aChangeArg.Length())
8513 TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
8514 if (!aSubStr.IsIntegerValue()
8515 || aSubStr.IntegerValue() <= 0)
8517 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8520 aSubIndex = aSubStr.IntegerValue();
8523 Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
8524 Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
8525 Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
8526 Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
8527 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8528 for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
8530 if (aSubPln->ChainNextPlane().IsNull())
8532 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8534 aSubPln = aSubPln->ChainNextPlane();
8536 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8537 aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
8540 else if ((aChangeArg == "-boxinterior"
8541 || aChangeArg == "-boxint"
8542 || aChangeArg == "-box")
8543 && aNbChangeArgs >= 7)
8545 Graphic3d_BndBox3d aBndBox;
8546 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
8547 aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
8550 Standard_Integer aNbSubPlanes = 6;
8551 const Graphic3d_Vec3d aDirArray[6] =
8553 Graphic3d_Vec3d (-1, 0, 0),
8554 Graphic3d_Vec3d ( 1, 0, 0),
8555 Graphic3d_Vec3d ( 0,-1, 0),
8556 Graphic3d_Vec3d ( 0, 1, 0),
8557 Graphic3d_Vec3d ( 0, 0,-1),
8558 Graphic3d_Vec3d ( 0, 0, 1),
8560 Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
8561 for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
8563 const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
8564 const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
8565 aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
8566 if (aSubPlaneIter + 1 == aNbSubPlanes)
8568 aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
8572 aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
8574 aSubPln = aSubPln->ChainNextPlane();
8577 else if (aChangeArg == "-capping"
8578 || aChangeArg == "capping")
8580 if (aNbChangeArgs < 2)
8582 Message::SendFail ("Syntax error: need more arguments");
8586 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8588 aClipPlane->SetCapping (toEnable);
8593 // just skip otherwise (old syntax)
8596 else if (aChangeArg == "-useobjectmaterial"
8597 || aChangeArg == "-useobjectmat"
8598 || aChangeArg == "-useobjmat"
8599 || aChangeArg == "-useobjmaterial")
8601 if (aNbChangeArgs < 2)
8603 Message::SendFail ("Syntax error: need more arguments");
8607 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8609 aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
8613 else if (aChangeArg == "-useobjecttexture"
8614 || aChangeArg == "-useobjecttex"
8615 || aChangeArg == "-useobjtexture"
8616 || aChangeArg == "-useobjtex")
8618 if (aNbChangeArgs < 2)
8620 Message::SendFail ("Syntax error: need more arguments");
8624 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8626 aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
8630 else if (aChangeArg == "-useobjectshader"
8631 || aChangeArg == "-useobjshader")
8633 if (aNbChangeArgs < 2)
8635 Message::SendFail ("Syntax error: need more arguments");
8639 if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
8641 aClipPlane->SetUseObjectShader (toEnable == Standard_True);
8645 else if (aChangeArg == "-color"
8646 || aChangeArg == "color")
8648 Quantity_Color aColor;
8649 Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
8654 Message::SendFail ("Syntax error: need more arguments");
8657 aClipPlane->SetCappingColor (aColor);
8658 anArgIter += aNbParsed;
8660 else if (aNbChangeArgs >= 1
8661 && (aChangeArg == "-material"
8662 || aChangeArg == "material"))
8665 Graphic3d_NameOfMaterial aMatName;
8666 if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
8668 Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
8671 aClipPlane->SetCappingMaterial (aMatName);
8673 else if ((aChangeArg == "-transparency"
8674 || aChangeArg == "-transp")
8675 && aNbChangeArgs >= 2)
8677 TCollection_AsciiString aValStr (aChangeArgs[1]);
8678 Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
8679 if (aValStr.IsRealValue (Standard_True))
8681 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
8682 aMat.SetTransparency ((float )aValStr.RealValue());
8683 anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
8684 aClipPlane->SetCappingMaterial (aMat);
8688 aValStr.LowerCase();
8689 Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
8690 if (aValStr == "opaque")
8692 aMode = Graphic3d_AlphaMode_Opaque;
8694 else if (aValStr == "mask")
8696 aMode = Graphic3d_AlphaMode_Mask;
8698 else if (aValStr == "blend")
8700 aMode = Graphic3d_AlphaMode_Blend;
8702 else if (aValStr == "maskblend"
8703 || aValStr == "blendmask")
8705 aMode = Graphic3d_AlphaMode_MaskBlend;
8707 else if (aValStr == "blendauto")
8709 aMode = Graphic3d_AlphaMode_BlendAuto;
8713 Message::SendFail() << "Syntax error at '" << aValStr << "'";
8716 anAspect->SetAlphaMode (aMode);
8717 aClipPlane->SetCappingAspect (anAspect);
8721 else if (aChangeArg == "-texname"
8722 || aChangeArg == "texname")
8724 if (aNbChangeArgs < 2)
8726 Message::SendFail ("Syntax error: need more arguments");
8730 TCollection_AsciiString aTextureName (aChangeArgs[1]);
8731 Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D (aTextureName);
8732 if (!aTexture->IsDone())
8734 aClipPlane->SetCappingTexture (NULL);
8738 aTexture->EnableModulate();
8739 aTexture->EnableRepeat();
8740 aClipPlane->SetCappingTexture (aTexture);
8744 else if (aChangeArg == "-texscale"
8745 || aChangeArg == "texscale")
8747 if (aClipPlane->CappingTexture().IsNull())
8749 Message::SendFail ("Error: no texture is set");
8753 if (aNbChangeArgs < 3)
8755 Message::SendFail ("Syntax error: need more arguments");
8759 Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8760 Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8761 aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
8764 else if (aChangeArg == "-texorigin"
8765 || aChangeArg == "texorigin") // texture origin
8767 if (aClipPlane->CappingTexture().IsNull())
8769 Message::SendFail ("Error: no texture is set");
8773 if (aNbChangeArgs < 3)
8775 Message::SendFail ("Syntax error: need more arguments");
8779 Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8780 Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
8782 aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
8785 else if (aChangeArg == "-texrotate"
8786 || aChangeArg == "texrotate") // texture rotation
8788 if (aClipPlane->CappingTexture().IsNull())
8790 Message::SendFail ("Error: no texture is set");
8794 if (aNbChangeArgs < 2)
8796 Message::SendFail ("Syntax error: need more arguments");
8800 Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
8801 aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
8804 else if (aChangeArg == "-hatch"
8805 || aChangeArg == "hatch")
8807 if (aNbChangeArgs < 2)
8809 Message::SendFail ("Syntax error: need more arguments");
8813 TCollection_AsciiString aHatchStr (aChangeArgs[1]);
8814 aHatchStr.LowerCase();
8815 if (aHatchStr == "on")
8817 aClipPlane->SetCappingHatchOn();
8819 else if (aHatchStr == "off")
8821 aClipPlane->SetCappingHatchOff();
8825 aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
8829 else if (aChangeArg == "-delete"
8830 || aChangeArg == "delete")
8832 removePlane (aRegPlanes, aPlaneName);
8835 else if (aChangeArg == "-set"
8836 || aChangeArg == "-unset"
8837 || aChangeArg == "-setoverrideglobal")
8839 // set / unset plane command
8840 const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
8841 const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
8842 Standard_Integer anIt = 1;
8843 for (; anIt < aNbChangeArgs; ++anIt)
8845 TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
8846 if (anEntityName.IsEmpty()
8847 || anEntityName.Value (1) == '-')
8851 else if (!toOverrideGlobal
8852 && ViewerTest_myViews.IsBound1 (anEntityName))
8854 const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (anEntityName);
8857 aView->AddClipPlane (aClipPlane);
8861 aView->RemoveClipPlane (aClipPlane);
8865 else if (GetMapOfAIS().IsBound2 (anEntityName))
8867 Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
8870 aIObj->AddClipPlane (aClipPlane);
8874 aIObj->RemoveClipPlane (aClipPlane);
8876 if (!aIObj->ClipPlanes().IsNull())
8878 aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
8883 Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
8890 // apply to active view
8893 anActiveView->AddClipPlane (aClipPlane);
8897 anActiveView->RemoveClipPlane (aClipPlane);
8902 anArgIter = anArgIter + anIt - 1;
8907 Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
8912 ViewerTest::RedrawAllViews();
8916 //===============================================================================================
8917 //function : VZRange
8919 //===============================================================================================
8920 static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8922 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8924 if (aCurrentView.IsNull())
8926 Message::SendFail ("Error: no active viewer");
8930 Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
8934 theDi << "ZNear: " << aCamera->ZNear() << "\n";
8935 theDi << "ZFar: " << aCamera->ZFar() << "\n";
8941 Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
8942 Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
8944 if (aNewZNear >= aNewZFar)
8946 Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
8950 if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
8952 Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
8956 aCamera->SetZRange (aNewZNear, aNewZFar);
8960 Message::SendFail ("Syntax error: wrong command arguments");
8964 aCurrentView->Redraw();
8969 //===============================================================================================
8970 //function : VAutoZFit
8972 //===============================================================================================
8973 static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
8975 const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
8977 if (aCurrentView.IsNull())
8979 Message::SendFail ("Error: no active viewer");
8983 Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
8987 Message::SendFail ("Syntax error: wrong command arguments");
8993 theDi << "Auto z-fit mode: \n"
8994 << "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
8995 << "Scale: " << aScale << "\n";
8999 Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
9003 aScale = Draw::Atoi (theArgVec[2]);
9006 aCurrentView->SetAutoZFitMode (isOn, aScale);
9007 aCurrentView->Redraw();
9011 //! Auxiliary function to print projection type
9012 inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
9014 switch (theProjType)
9016 case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
9017 case Graphic3d_Camera::Projection_Perspective: return "perspective";
9018 case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
9019 case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
9020 case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
9025 //===============================================================================================
9026 //function : VCamera
9028 //===============================================================================================
9029 static int VCamera (Draw_Interpretor& theDI,
9030 Standard_Integer theArgsNb,
9031 const char** theArgVec)
9033 Handle(V3d_View) aView = ViewerTest::CurrentView();
9036 Message::SendFail ("Error: no active viewer");
9040 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9043 theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
9044 theDI << "FOVy: " << aCamera->FOVy() << "\n";
9045 theDI << "FOVx: " << aCamera->FOVx() << "\n";
9046 theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
9047 theDI << "Distance: " << aCamera->Distance() << "\n";
9048 theDI << "IOD: " << aCamera->IOD() << "\n";
9049 theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
9050 theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
9051 theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
9052 theDI << "ZNear: " << aCamera->ZNear() << "\n";
9053 theDI << "ZFar: " << aCamera->ZFar() << "\n";
9057 TCollection_AsciiString aPrsName;
9058 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9060 Standard_CString anArg = theArgVec[anArgIter];
9061 TCollection_AsciiString anArgCase (anArg);
9062 anArgCase.LowerCase();
9063 if (anArgCase == "-proj"
9064 || anArgCase == "-projection"
9065 || anArgCase == "-projtype"
9066 || anArgCase == "-projectiontype")
9068 theDI << projTypeName (aCamera->ProjectionType()) << " ";
9070 else if (anArgCase == "-ortho"
9071 || anArgCase == "-orthographic")
9073 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
9075 else if (anArgCase == "-persp"
9076 || anArgCase == "-perspective"
9077 || anArgCase == "-perspmono"
9078 || anArgCase == "-perspectivemono"
9079 || anArgCase == "-mono")
9081 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9083 else if (anArgCase == "-stereo"
9084 || anArgCase == "-stereoscopic"
9085 || anArgCase == "-perspstereo"
9086 || anArgCase == "-perspectivestereo")
9088 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9090 else if (anArgCase == "-left"
9091 || anArgCase == "-lefteye"
9092 || anArgCase == "-monoleft"
9093 || anArgCase == "-monolefteye"
9094 || anArgCase == "-perpsleft"
9095 || anArgCase == "-perpslefteye")
9097 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
9099 else if (anArgCase == "-right"
9100 || anArgCase == "-righteye"
9101 || anArgCase == "-monoright"
9102 || anArgCase == "-monorighteye"
9103 || anArgCase == "-perpsright")
9105 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
9107 else if (anArgCase == "-dist"
9108 || anArgCase == "-distance")
9110 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9111 if (anArgValue != NULL
9112 && *anArgValue != '-')
9115 aCamera->SetDistance (Draw::Atof (anArgValue));
9118 theDI << aCamera->Distance() << " ";
9120 else if (anArgCase == "-iod")
9122 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9123 if (anArgValue != NULL
9124 && *anArgValue != '-')
9127 aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
9130 theDI << aCamera->IOD() << " ";
9132 else if (anArgCase == "-iodtype")
9134 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9135 TCollection_AsciiString anValueCase (anArgValue);
9136 anValueCase.LowerCase();
9137 if (anValueCase == "abs"
9138 || anValueCase == "absolute")
9141 aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
9144 else if (anValueCase == "rel"
9145 || anValueCase == "relative")
9148 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
9151 else if (*anArgValue != '-')
9153 Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
9156 switch (aCamera->GetIODType())
9158 case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
9159 case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
9162 else if (anArgCase == "-zfocus")
9164 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9165 if (anArgValue != NULL
9166 && *anArgValue != '-')
9169 aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
9172 theDI << aCamera->ZFocus() << " ";
9174 else if (anArgCase == "-zfocustype")
9176 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
9177 TCollection_AsciiString anValueCase (anArgValue);
9178 anValueCase.LowerCase();
9179 if (anValueCase == "abs"
9180 || anValueCase == "absolute")
9183 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
9186 else if (anValueCase == "rel"
9187 || anValueCase == "relative")
9190 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
9193 else if (*anArgValue != '-')
9195 Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
9198 switch (aCamera->ZFocusType())
9200 case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
9201 case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
9204 else if (anArgCase == "-lockzup"
9205 || anArgCase == "-turntable")
9207 bool toLockUp = true;
9208 if (++anArgIter < theArgsNb
9209 && !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
9213 ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
9215 else if (anArgCase == "-rotationmode"
9216 || anArgCase == "-rotmode")
9218 AIS_RotationMode aRotMode = AIS_RotationMode_BndBoxActive;
9219 TCollection_AsciiString aRotStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9220 aRotStr.LowerCase();
9221 if (aRotStr == "bndboxactive"
9222 || aRotStr == "active")
9224 aRotMode = AIS_RotationMode_BndBoxActive;
9226 else if (aRotStr == "picklast"
9227 || aRotStr == "pick")
9229 aRotMode = AIS_RotationMode_PickLast;
9231 else if (aRotStr == "pickcenter")
9233 aRotMode = AIS_RotationMode_PickCenter;
9235 else if (aRotStr == "cameraat"
9236 || aRotStr == "cameracenter")
9238 aRotMode = AIS_RotationMode_CameraAt;
9240 else if (aRotStr == "bndboxscene"
9241 || aRotStr == "boxscene")
9243 aRotMode = AIS_RotationMode_BndBoxScene;
9247 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9251 ViewerTest::CurrentEventManager()->SetRotationMode (aRotMode);
9254 else if (anArgCase == "-navigationmode"
9255 || anArgCase == "-navmode")
9257 AIS_NavigationMode aNavMode = AIS_NavigationMode_Orbit;
9258 TCollection_AsciiString aNavStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
9259 aNavStr.LowerCase();
9260 if (aNavStr == "orbit")
9262 aNavMode = AIS_NavigationMode_Orbit;
9264 else if (aNavStr == "flight"
9266 || aNavStr == "copter"
9267 || aNavStr == "helicopter")
9269 aNavMode = AIS_NavigationMode_FirstPersonFlight;
9271 else if (aNavStr == "walk"
9272 || aNavStr == "shooter")
9274 aNavMode = AIS_NavigationMode_FirstPersonWalk;
9278 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
9282 Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
9283 aViewMgr->SetNavigationMode (aNavMode);
9284 if (aNavMode == AIS_NavigationMode_Orbit)
9286 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateOrbit);
9290 aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateView);
9294 else if (anArgCase == "-fov"
9295 || anArgCase == "-fovy"
9296 || anArgCase == "-fovx"
9297 || anArgCase == "-fov2d")
9299 Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
9300 if (anArgValue != NULL
9301 && *anArgValue != '-')
9304 if (anArgCase == "-fov2d")
9306 aCamera->SetFOV2d (Draw::Atof (anArgValue));
9308 else if (anArgCase == "-fovx")
9310 aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
9314 aCamera->SetFOVy (Draw::Atof (anArgValue));
9318 if (anArgCase == "-fov2d")
9320 theDI << aCamera->FOV2d() << " ";
9322 else if (anArgCase == "-fovx")
9324 theDI << aCamera->FOVx() << " ";
9328 theDI << aCamera->FOVy() << " ";
9331 else if (anArgIter + 1 < theArgsNb
9332 && anArgCase == "-xrpose")
9334 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
9335 anXRArg.LowerCase();
9336 if (anXRArg == "base")
9338 aCamera = aView->View()->BaseXRCamera();
9340 else if (anXRArg == "head")
9342 aCamera = aView->View()->PosedXRCamera();
9346 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
9349 if (aCamera.IsNull())
9351 Message::SendFail() << "Error: undefined XR pose";
9354 if (aView->AutoZFitMode())
9356 const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
9357 const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
9358 aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
9361 else if (aPrsName.IsEmpty()
9362 && !anArgCase.StartsWith ("-"))
9368 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
9373 if (aPrsName.IsEmpty()
9379 if (!aPrsName.IsEmpty())
9381 Handle(AIS_CameraFrustum) aCameraFrustum;
9382 if (GetMapOfAIS().IsBound2 (aPrsName))
9384 // find existing object
9385 aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
9386 if (aCameraFrustum.IsNull())
9388 Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
9393 if (aCameraFrustum.IsNull())
9395 aCameraFrustum = new AIS_CameraFrustum();
9399 // not include displayed object of old camera frustum in the new one.
9400 ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
9403 aCameraFrustum->SetCameraFrustum (aCamera);
9405 ViewerTest::Display (aPrsName, aCameraFrustum);
9411 //! Parse stereo output mode
9412 inline Standard_Boolean parseStereoMode (Standard_CString theArg,
9413 Graphic3d_StereoMode& theMode)
9415 TCollection_AsciiString aFlag (theArg);
9417 if (aFlag == "quadbuffer")
9419 theMode = Graphic3d_StereoMode_QuadBuffer;
9421 else if (aFlag == "anaglyph")
9423 theMode = Graphic3d_StereoMode_Anaglyph;
9425 else if (aFlag == "row"
9426 || aFlag == "rowinterlaced")
9428 theMode = Graphic3d_StereoMode_RowInterlaced;
9430 else if (aFlag == "col"
9431 || aFlag == "colinterlaced"
9432 || aFlag == "columninterlaced")
9434 theMode = Graphic3d_StereoMode_ColumnInterlaced;
9436 else if (aFlag == "chess"
9437 || aFlag == "chessboard")
9439 theMode = Graphic3d_StereoMode_ChessBoard;
9441 else if (aFlag == "sbs"
9442 || aFlag == "sidebyside")
9444 theMode = Graphic3d_StereoMode_SideBySide;
9446 else if (aFlag == "ou"
9447 || aFlag == "overunder")
9449 theMode = Graphic3d_StereoMode_OverUnder;
9451 else if (aFlag == "pageflip"
9452 || aFlag == "softpageflip")
9454 theMode = Graphic3d_StereoMode_SoftPageFlip;
9456 else if (aFlag == "openvr"
9459 theMode = Graphic3d_StereoMode_OpenVR;
9463 return Standard_False;
9465 return Standard_True;
9468 //! Parse anaglyph filter
9469 inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
9470 Graphic3d_RenderingParams::Anaglyph& theFilter)
9472 TCollection_AsciiString aFlag (theArg);
9474 if (aFlag == "redcyansimple")
9476 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9478 else if (aFlag == "redcyan"
9479 || aFlag == "redcyanoptimized")
9481 theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
9483 else if (aFlag == "yellowbluesimple")
9485 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
9487 else if (aFlag == "yellowblue"
9488 || aFlag == "yellowblueoptimized")
9490 theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
9492 else if (aFlag == "greenmagenta"
9493 || aFlag == "greenmagentasimple")
9495 theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
9499 return Standard_False;
9501 return Standard_True;
9504 //==============================================================================
9505 //function : VStereo
9507 //==============================================================================
9509 static int VStereo (Draw_Interpretor& theDI,
9510 Standard_Integer theArgNb,
9511 const char** theArgVec)
9513 Handle(V3d_View) aView = ViewerTest::CurrentView();
9516 Message::SendFail ("Error: no active viewer");
9520 Handle(Graphic3d_Camera) aCamera = aView->Camera();
9521 Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
9524 Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
9525 theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
9528 TCollection_AsciiString aMode;
9529 switch (aView->RenderingParams().StereoMode)
9531 case Graphic3d_StereoMode_QuadBuffer:
9533 aMode = "quadBuffer";
9536 case Graphic3d_StereoMode_RowInterlaced:
9538 aMode = "rowInterlaced";
9539 if (aView->RenderingParams().ToSmoothInterlacing)
9541 aMode.AssignCat (" (smoothed)");
9545 case Graphic3d_StereoMode_ColumnInterlaced:
9547 aMode = "columnInterlaced";
9548 if (aView->RenderingParams().ToSmoothInterlacing)
9550 aMode.AssignCat (" (smoothed)");
9554 case Graphic3d_StereoMode_ChessBoard:
9556 aMode = "chessBoard";
9557 if (aView->RenderingParams().ToSmoothInterlacing)
9559 aMode.AssignCat (" (smoothed)");
9563 case Graphic3d_StereoMode_SideBySide:
9565 aMode = "sideBySide";
9568 case Graphic3d_StereoMode_OverUnder:
9570 aMode = "overUnder";
9573 case Graphic3d_StereoMode_SoftPageFlip:
9575 aMode = "softPageFlip";
9578 case Graphic3d_StereoMode_OpenVR:
9583 case Graphic3d_StereoMode_Anaglyph:
9586 switch (aView->RenderingParams().AnaglyphFilter)
9588 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
9589 case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
9590 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
9591 case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
9592 case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
9593 case Graphic3d_RenderingParams::Anaglyph_UserDefined : aMode.AssignCat (" (userDefined)"); break;
9597 theDI << "Mode " << aMode << "\n";
9602 Graphic3d_StereoMode aMode = aParams->StereoMode;
9603 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
9604 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
9606 Standard_CString anArg = theArgVec[anArgIter];
9607 TCollection_AsciiString aFlag (anArg);
9609 if (anUpdateTool.parseRedrawMode (aFlag))
9613 else if (aFlag == "0"
9616 if (++anArgIter < theArgNb)
9618 Message::SendFail ("Error: wrong number of arguments");
9622 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
9624 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
9628 else if (aFlag == "1"
9631 if (++anArgIter < theArgNb)
9633 Message::SendFail ("Error: wrong number of arguments");
9637 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9638 if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
9643 else if (aFlag == "-reverse"
9644 || aFlag == "-noreverse"
9645 || aFlag == "-reversed"
9647 || aFlag == "-noswap")
9649 aParams->ToReverseStereo = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
9651 else if (aFlag == "-mode"
9652 || aFlag == "-stereomode")
9654 if (++anArgIter >= theArgNb
9655 || !parseStereoMode (theArgVec[anArgIter], aMode))
9657 Message::SendFail() << "Syntax error at '" << anArg << "'";
9661 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9663 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9666 else if (aFlag == "-anaglyph"
9667 || aFlag == "-anaglyphfilter")
9669 Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
9670 if (++anArgIter >= theArgNb
9671 || !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
9673 Message::SendFail() << "Syntax error at '" << anArg << "'";
9677 aMode = Graphic3d_StereoMode_Anaglyph;
9678 aParams->AnaglyphFilter = aFilter;
9680 else if (parseStereoMode (anArg, aMode)) // short syntax
9682 if (aMode == Graphic3d_StereoMode_QuadBuffer)
9684 Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
9687 else if (anArgIter + 1 < theArgNb
9688 && aFlag == "-hmdfov2d")
9690 aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
9691 if (aParams->HmdFov2d < 10.0f
9692 || aParams->HmdFov2d > 180.0f)
9694 Message::SendFail() << "Error: FOV is out of range";
9698 else if (aFlag == "-mirror"
9699 || aFlag == "-mirrorcomposer")
9701 aParams->ToMirrorComposer = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);;
9703 else if (aFlag == "-smooth"
9704 || aFlag == "-nosmooth"
9705 || aFlag == "-smoothinterlacing"
9706 || aFlag == "-nosmoothinterlacing")
9708 aParams->ToSmoothInterlacing = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
9710 else if (anArgIter + 1 < theArgNb
9711 && (aFlag == "-unitfactor"
9712 || aFlag == "-unitscale"))
9714 aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
9718 Message::SendFail() << "Syntax error at '" << anArg << "'";
9723 aParams->StereoMode = aMode;
9724 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
9725 if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
9727 // initiate implicit continuous rendering
9728 ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
9733 //===============================================================================================
9734 //function : VDefaults
9736 //===============================================================================================
9737 static int VDefaults (Draw_Interpretor& theDi,
9738 Standard_Integer theArgsNb,
9739 const char** theArgVec)
9741 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9744 Message::SendFail ("Error: no active viewer");
9748 Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
9751 if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
9753 theDi << "DeflType: relative\n"
9754 << "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
9758 theDi << "DeflType: absolute\n"
9759 << "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
9761 theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
9762 theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
9766 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
9768 TCollection_AsciiString anArg (theArgVec[anArgIter]);
9770 if (anArg == "-ABSDEFL"
9771 || anArg == "-ABSOLUTEDEFLECTION"
9773 || anArg == "-DEFLECTION")
9775 if (++anArgIter >= theArgsNb)
9777 Message::SendFail() << "Syntax error at " << anArg;
9780 aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
9781 aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
9783 else if (anArg == "-RELDEFL"
9784 || anArg == "-RELATIVEDEFLECTION"
9785 || anArg == "-DEVCOEFF"
9786 || anArg == "-DEVIATIONCOEFF"
9787 || anArg == "-DEVIATIONCOEFFICIENT")
9789 if (++anArgIter >= theArgsNb)
9791 Message::SendFail() << "Syntax error at " << anArg;
9794 aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
9795 aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
9797 else if (anArg == "-ANGDEFL"
9798 || anArg == "-ANGULARDEFL"
9799 || anArg == "-ANGULARDEFLECTION")
9801 if (++anArgIter >= theArgsNb)
9803 Message::SendFail() << "Syntax error at " << anArg;
9806 aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
9808 else if (anArg == "-AUTOTR"
9809 || anArg == "-AUTOTRIANG"
9810 || anArg == "-AUTOTRIANGULATION")
9813 bool toTurnOn = true;
9814 if (anArgIter >= theArgsNb
9815 || !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
9817 Message::SendFail() << "Syntax error at '" << anArg << "'";
9820 aDefParams->SetAutoTriangulation (toTurnOn);
9824 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
9832 //! Parse light source type from string.
9833 static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
9834 Graphic3d_TypeOfLightSource& theType)
9836 TCollection_AsciiString aType (theTypeName);
9839 || aType == "ambient"
9840 || aType == "amblight")
9842 theType = Graphic3d_TypeOfLightSource_Ambient;
9844 else if (aType == "directional"
9845 || aType == "dirlight")
9847 theType = Graphic3d_TypeOfLightSource_Directional;
9849 else if (aType == "spot"
9850 || aType == "spotlight")
9852 theType = Graphic3d_TypeOfLightSource_Spot;
9854 else if (aType == "poslight"
9855 || aType == "positional"
9859 theType = Graphic3d_TypeOfLightSource_Positional;
9868 //! Find existing light by name or index.
9869 static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
9871 Handle(V3d_Light) aLight;
9872 Standard_Integer aLightIndex = -1;
9873 Draw::ParseInteger (theName.ToCString(), aLightIndex);
9874 Standard_Integer aLightIt = 0;
9875 Handle(V3d_View) aView = ViewerTest::CurrentView();
9876 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
9878 if (aLightIndex != -1)
9880 if (aLightIt == aLightIndex)
9882 return aLightIter.Value();
9885 else if (aLightIter.Value()->GetId() == theName
9886 || aLightIter.Value()->Name() == theName)
9888 if (!aLight.IsNull())
9890 Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
9893 aLight = aLightIter.Value();
9899 //===============================================================================================
9902 //===============================================================================================
9903 static int VLight (Draw_Interpretor& theDi,
9904 Standard_Integer theArgsNb,
9905 const char** theArgVec)
9907 Handle(V3d_View) aView = ViewerTest::CurrentView();
9908 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
9909 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
9911 || aViewer.IsNull())
9913 Message::SendFail ("Error: no active viewer");
9919 // print lights info
9920 Standard_Integer aLightId = 0;
9921 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
9923 Handle(V3d_Light) aLight = aLightIter.Value();
9924 const Quantity_Color aColor = aLight->Color();
9925 theDi << "Light #" << aLightId
9926 << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
9927 << " [" << aLight->GetId() << "] "
9928 << (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
9929 switch (aLight->Type())
9931 case Graphic3d_TypeOfLightSource_Ambient:
9933 theDi << " Type: Ambient\n"
9934 << " Intensity: " << aLight->Intensity() << "\n";
9937 case Graphic3d_TypeOfLightSource_Directional:
9939 theDi << " Type: Directional\n"
9940 << " Intensity: " << aLight->Intensity() << "\n"
9941 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9942 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9943 << " Smoothness: " << aLight->Smoothness() << "\n"
9944 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
9947 case Graphic3d_TypeOfLightSource_Positional:
9949 theDi << " Type: Positional\n"
9950 << " Intensity: " << aLight->Intensity() << "\n"
9951 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9952 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9953 << " Smoothness: " << aLight->Smoothness() << "\n"
9954 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9955 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9956 << " Range: " << aLight->Range() << "\n";
9959 case Graphic3d_TypeOfLightSource_Spot:
9961 theDi << " Type: Spot\n"
9962 << " Intensity: " << aLight->Intensity() << "\n"
9963 << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
9964 << " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
9965 << " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
9966 << " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
9967 << " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
9968 << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
9969 << " Exponent: " << aLight->Concentration() << "\n"
9970 << " Range: " << aLight->Range() << "\n";
9975 theDi << " Type: UNKNOWN\n";
9979 theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
9983 Handle(V3d_Light) aLightOld, aLightNew;
9984 Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
9985 bool isGlobal = true;
9986 ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
9987 Handle(AIS_LightSource) aLightPrs;
9988 for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
9990 const TCollection_AsciiString anArg (theArgVec[anArgIt]);
9991 TCollection_AsciiString anArgCase (anArg);
9992 anArgCase.LowerCase();
9993 if (anUpdateTool.parseRedrawMode (anArg))
9997 else if (anArgCase == "-new"
9998 || anArgCase == "-add"
9999 || anArgCase == "-create"
10000 || anArgCase == "-type"
10001 || (anArgCase == "-reset"
10002 && !aLightNew.IsNull())
10003 || (anArgCase == "-defaults"
10004 && !aLightNew.IsNull())
10005 || anArgCase == "add"
10006 || anArgCase == "new"
10007 || anArgCase == "create")
10009 Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
10010 if (anArgCase == "-reset")
10012 aType = aLightNew->Type();
10014 else if (anArgIt + 1 >= theArgsNb
10015 || !parseLightSourceType (theArgVec[++anArgIt], aType))
10017 theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
10021 TCollection_AsciiString aName;
10022 if (!aLightNew.IsNull())
10024 aName = aLightNew->Name();
10028 case Graphic3d_TypeOfLightSource_Ambient:
10030 aLightNew = new V3d_AmbientLight();
10033 case Graphic3d_TypeOfLightSource_Directional:
10035 aLightNew = new V3d_DirectionalLight();
10038 case Graphic3d_TypeOfLightSource_Spot:
10040 aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
10043 case Graphic3d_TypeOfLightSource_Positional:
10045 aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
10050 if (anArgCase == "-type"
10051 && !aLightOld.IsNull())
10053 aLightNew->CopyFrom (aLightOld);
10055 aLightNew->SetName (aName);
10057 else if ((anArgCase == "-layer"
10058 || anArgCase == "-zlayer")
10059 && anArgIt + 1 < theArgsNb)
10061 if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
10062 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10064 Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
10068 else if (anArgCase == "-glob"
10069 || anArgCase == "-global"
10070 || anArgCase == "-loc"
10071 || anArgCase == "-local")
10073 isGlobal = anArgCase.StartsWith ("-glob");
10075 else if (anArgCase == "-def"
10076 || anArgCase == "-defaults"
10077 || anArgCase == "-reset")
10079 aViewer->SetDefaultLights();
10080 aLightOld.Nullify();
10081 aLightNew.Nullify();
10082 aLightPrs.Nullify();
10084 else if (anArgCase == "-clr"
10085 || anArgCase == "-clear"
10086 || anArgCase == "clear")
10088 TColStd_SequenceOfInteger aLayers;
10089 aViewer->GetAllZLayers (aLayers);
10090 for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
10092 if (aLayeriter.Value() == aLayer
10093 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10095 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
10096 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10097 aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
10098 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10105 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10107 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
10108 for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
10110 Handle(V3d_Light) aLight = aLightIter.Value();
10111 Handle(AIS_InteractiveObject) aPrsObject;
10112 GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
10113 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10115 aCtx->Remove (aLightSourceDel, false);
10116 aMap.UnBind1 (aLightSourceDel);
10118 aViewer->DelLight (aLight);
10119 aLightIter = aView->ActiveLightIterator();
10123 aLightOld.Nullify();
10124 aLightNew.Nullify();
10125 aLightPrs.Nullify();
10127 else if (!aLightNew.IsNull()
10128 && (anArgCase == "-display"
10129 || anArgCase == "-disp"
10130 || anArgCase == "-presentation"
10131 || anArgCase == "-prs"))
10133 TCollection_AsciiString aLightName = aLightNew->Name();
10134 if (anArgIt + 1 < theArgsNb
10135 && theArgVec[anArgIt + 1][0] != '-')
10138 aLightName = theArgVec[++anArgIt];
10139 if (aLightNew->Name() != aLightName)
10141 if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
10143 theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
10146 aLightNew->SetName (aLightName);
10149 if (aLightName.IsEmpty())
10151 Message::SendFail() << "Error: nameless light source cannot be displayed";
10154 if (aLightPrs.IsNull())
10156 aLightPrs = new AIS_LightSource (aLightNew);
10158 theDi << aLightName << " ";
10160 else if (!aLightNew.IsNull()
10161 && (anArgCase == "-disable"
10162 || anArgCase == "-disabled"
10163 || anArgCase == "-enable"
10164 || anArgCase == "-enabled"))
10166 bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10167 if (anArgCase == "-disable"
10168 || anArgCase == "-disabled")
10170 toEnable = !toEnable;
10172 aLightNew->SetEnabled (toEnable);
10174 else if (!aLightNew.IsNull()
10175 && (anArgCase == "-color"
10176 || anArgCase == "-colour"
10177 || anArgCase == "color"))
10179 Quantity_Color aColor;
10180 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
10181 theArgVec + anArgIt + 1,
10183 anArgIt += aNbParsed;
10184 if (aNbParsed == 0)
10186 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10189 aLightNew->SetColor (aColor);
10191 else if (!aLightNew.IsNull()
10192 && (anArgCase == "-pos"
10193 || anArgCase == "-position"
10194 || anArgCase == "-prsposition"
10195 || anArgCase == "-prspos"
10196 || anArgCase == "pos"
10197 || anArgCase == "position")
10198 && (anArgIt + 3) < theArgsNb)
10201 if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
10203 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10208 if (anArgCase == "-prsposition"
10209 || anArgCase == "-prspos")
10211 aLightNew->SetDisplayPosition (aPosXYZ);
10215 if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
10216 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
10218 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10222 aLightNew->SetPosition (aPosXYZ);
10225 else if (!aLightNew.IsNull()
10226 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
10227 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10228 && (anArgCase == "-dir"
10229 || anArgCase == "-direction")
10230 && (anArgIt + 3) < theArgsNb)
10233 if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
10235 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10240 aLightNew->SetDirection (gp_Dir (aDirXYZ));
10242 else if (!aLightNew.IsNull()
10243 && (anArgCase == "-smoothangle"
10244 || anArgCase == "-smoothradius"
10245 || anArgCase == "-sm"
10246 || anArgCase == "-smoothness")
10247 && anArgIt + 1 < theArgsNb)
10249 Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10250 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10252 aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
10254 if (Abs (aSmoothness) <= ShortRealEpsilon())
10256 aLightNew->SetIntensity (1.f);
10258 else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
10260 aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
10264 Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
10265 aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
10268 if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10270 aLightNew->SetSmoothRadius (aSmoothness);
10272 else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
10274 aLightNew->SetSmoothAngle (aSmoothness);
10277 else if (!aLightNew.IsNull()
10278 && (anArgCase == "-int"
10279 || anArgCase == "-intensity")
10280 && anArgIt + 1 < theArgsNb)
10282 Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10283 aLightNew->SetIntensity (aIntensity);
10285 else if (!aLightNew.IsNull()
10286 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10287 && (anArgCase == "-spotangle"
10288 || anArgCase == "-ang"
10289 || anArgCase == "-angle")
10290 && anArgIt + 1 < theArgsNb)
10292 Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10293 anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
10294 aLightNew->SetAngle (anAngle);
10296 else if (!aLightNew.IsNull()
10297 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10298 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10299 && (anArgCase == "-constatten"
10300 || anArgCase == "-constattenuation")
10301 && anArgIt + 1 < theArgsNb)
10303 const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10304 aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
10306 else if (!aLightNew.IsNull()
10307 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
10308 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
10309 && (anArgCase == "-linatten"
10310 || anArgCase == "-linearatten"
10311 || anArgCase == "-linearattenuation")
10312 && anArgIt + 1 < theArgsNb)
10314 const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
10315 aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
10317 else if (!aLightNew.IsNull()
10318 && aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10319 && (anArgCase == "-spotexp"
10320 || anArgCase == "-spotexponent"
10321 || anArgCase == "-exp"
10322 || anArgCase == "-exponent")
10323 && anArgIt + 1 < theArgsNb)
10325 aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
10327 else if (!aLightNew.IsNull()
10328 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10329 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
10330 && anArgCase == "-range"
10331 && anArgIt + 1 < theArgsNb)
10333 Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
10334 aLightNew->SetRange (aRange);
10336 else if (!aLightNew.IsNull()
10337 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10338 && (anArgCase == "-head"
10339 || anArgCase == "-headlight"))
10341 Standard_Boolean isHeadLight = Standard_True;
10342 if (anArgIt + 1 < theArgsNb
10343 && Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
10347 aLightNew->SetHeadlight (isHeadLight);
10349 else if (!aLightNew.IsNull()
10350 && anArgCase == "-name"
10351 && anArgIt + 1 < theArgsNb)
10353 const TCollection_AsciiString aName = theArgVec[++anArgIt];
10354 if (aLightNew->Name() == aName)
10359 if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
10361 theDi << "Syntax error: light with name '" << aName << "' is already defined";
10364 aLightNew->SetName (aName);
10366 else if (!aLightPrs.IsNull()
10367 && (anArgCase == "-showzoomable"
10368 || anArgCase == "-prszoomable"
10369 || anArgCase == "-zoomable"))
10371 const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10372 aLightPrs->SetZoomable (isZoomable);
10374 else if (!aLightPrs.IsNull()
10375 && (anArgCase == "-showdraggable"
10376 || anArgCase == "-prsdraggable"
10377 || anArgCase == "-draggable"))
10379 const bool isDraggable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10380 aLightPrs->SetDraggable (isDraggable);
10382 else if (!aLightPrs.IsNull()
10383 && (anArgCase == "-showname"
10384 || anArgCase == "-prsname"))
10386 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10387 aLightPrs->SetDisplayName (toDisplay);
10389 else if (!aLightPrs.IsNull()
10390 && (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
10391 || aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
10392 && (anArgCase == "-showrange"
10393 || anArgCase == "-prsrange"))
10395 const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
10396 aLightPrs->SetDisplayRange (toDisplay);
10398 else if (!aLightPrs.IsNull()
10399 && (anArgCase == "-showsize"
10400 || anArgCase == "-prssize")
10401 && anArgIt + 1 < theArgsNb)
10403 Standard_Real aSize = 0.0;
10404 if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
10406 || aLightPrs.IsNull())
10408 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10412 aLightPrs->SetSize (aSize);
10414 else if (!aLightPrs.IsNull()
10415 && (anArgCase == "-dirarcsize"
10416 || anArgCase == "-arcsize"
10417 || anArgCase == "-arc")
10418 && anArgIt + 1 < theArgsNb)
10420 Standard_Integer aSize = 0;
10421 if (!Draw::ParseInteger (theArgVec[anArgIt + 1], aSize)
10423 || aLightPrs->Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
10425 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10429 aLightPrs->SetArcSize (aSize);
10431 else if (!aLightNew.IsNull()
10432 && aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
10433 && (anArgCase == "-castshadow"
10434 || anArgCase == "-castshadows"
10435 || anArgCase == "-shadows"))
10437 bool toCastShadows = true;
10438 if (anArgIt + 1 < theArgsNb
10439 && Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
10443 aLightNew->SetCastShadows (toCastShadows);
10445 else if (anArgCase == "-del"
10446 || anArgCase == "-delete"
10447 || anArgCase == "-remove"
10448 || anArgCase == "del"
10449 || anArgCase == "delete"
10450 || anArgCase == "remove")
10452 if (aLightOld.IsNull())
10454 if (!aLightNew.IsNull())
10456 aLightNew.Nullify();
10460 if (++anArgIt >= theArgsNb)
10462 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
10466 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10467 aLightOld = findLightSource (anOldName);
10468 if (aLightOld.IsNull())
10470 Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
10475 aLightNew.Nullify();
10476 aLightPrs.Nullify();
10478 else if (anArgCase == "-change"
10479 || anArgCase == "change")
10481 // just skip old syntax
10483 else if (aLightNew.IsNull()
10484 && !anArgCase.StartsWith ("-"))
10486 if (!aLightNew.IsNull())
10491 const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
10492 aLightOld = findLightSource (anOldName);
10493 if (!aLightOld.IsNull())
10495 aLightNew = aLightOld;
10497 Handle(AIS_InteractiveObject) aPrsObject;
10498 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10499 aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
10503 Standard_Integer aLightIndex = -1;
10504 Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
10505 if (aLightIndex != -1)
10507 Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
10511 aLightNew = new V3d_AmbientLight();
10512 aLightNew->SetName (anOldName);
10517 Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
10522 // delete old light source
10523 if (!aLightOld.IsNull()
10524 && aLightOld != aLightNew)
10526 TColStd_SequenceOfInteger aLayers;
10527 aViewer->GetAllZLayers (aLayers);
10528 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
10530 if (aLayerIter.Value() == aLayer
10531 || aLayer == Graphic3d_ZLayerId_UNKNOWN)
10533 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
10534 if (!aSettings.Lights().IsNull())
10536 aSettings.Lights()->Remove (aLightOld);
10537 if (aSettings.Lights()->IsEmpty())
10539 aSettings.SetLights (Handle(Graphic3d_LightSet)());
10542 aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
10543 if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
10550 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10552 Handle(AIS_InteractiveObject) aPrsObject;
10553 GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
10554 if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
10556 aCtx->Remove (aLightSourceDel, false);
10557 GetMapOfAIS().UnBind1 (aLightSourceDel);
10559 aViewer->DelLight (aLightOld);
10561 aLightOld.Nullify();
10564 // add new light source
10565 if (!aLightNew.IsNull())
10567 if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
10569 aViewer->AddLight (aLightNew);
10572 aViewer->SetLightOn (aLightNew);
10576 aView->SetLightOn (aLightNew);
10581 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
10582 if (aSettings.Lights().IsNull())
10584 aSettings.SetLights (new Graphic3d_LightSet());
10586 aSettings.Lights()->Add (aLightNew);
10587 aViewer->SetZLayerSettings (aLayer, aSettings);
10590 if (!aLightPrs.IsNull())
10592 aLightPrs->SetLight (aLightNew);
10593 ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
10597 // manage presentations
10598 struct LightPrsSort
10600 bool operator() (const Handle(AIS_LightSource)& theLeft,
10601 const Handle(AIS_LightSource)& theRight)
10603 return theLeft->Light()->GetId() < theRight->Light()->GetId();
10607 AIS_ListOfInteractive aPrsList;
10608 aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
10609 if (!aPrsList.IsEmpty())
10611 // update light source presentations
10612 std::vector<Handle(AIS_LightSource)> aLightPrsVec;
10613 for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
10615 if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
10617 aLightPrsVec.push_back (aLightPrs2);
10621 // sort objects by id as AIS_InteractiveContext stores them in unordered map
10622 std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
10624 Standard_Integer aTopStack = 0;
10625 for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
10627 Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
10628 if (!aLightPrs2->TransformPersistence().IsNull()
10629 && aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
10631 const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
10632 aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
10633 aTopStack += aPrsSize + aPrsSize / 2;
10635 aCtx->Redisplay (aLightPrs2, false);
10636 aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
10642 //===============================================================================================
10643 //function : VPBREnvironment
10645 //===============================================================================================
10646 static int VPBREnvironment (Draw_Interpretor&,
10647 Standard_Integer theArgsNb,
10648 const char** theArgVec)
10652 Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
10656 Handle(V3d_View) aView = ViewerTest::CurrentView();
10657 if (aView.IsNull())
10659 Message::SendFail ("Error: no active viewer");
10663 TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
10666 if (anArg == "-generate"
10667 || anArg == "-gen")
10669 aView->GeneratePBREnvironment (Standard_True);
10671 else if (anArg == "-clear")
10673 aView->ClearPBREnvironment (Standard_True);
10677 Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
10684 //! Read Graphic3d_RenderingParams::PerfCounters flag.
10685 static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
10686 Standard_Boolean& theToReset,
10687 Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
10688 Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
10690 Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
10691 TCollection_AsciiString aVal = theValue;
10692 Standard_Boolean toReverse = Standard_False;
10693 if (aVal == "none")
10695 theToReset = Standard_True;
10696 return Standard_True;
10698 else if (aVal.StartsWith ("-"))
10700 toReverse = Standard_True;
10701 aVal = aVal.SubString (2, aVal.Length());
10703 else if (aVal.StartsWith ("no"))
10705 toReverse = Standard_True;
10706 aVal = aVal.SubString (3, aVal.Length());
10708 else if (aVal.StartsWith ("+"))
10710 aVal = aVal.SubString (2, aVal.Length());
10714 theToReset = Standard_True;
10718 || aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
10719 else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
10720 else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
10721 else if (aVal == "structs"
10722 || aVal == "structures"
10723 || aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
10724 else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
10725 else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
10726 else if (aVal == "tris"
10727 || aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
10728 else if (aVal == "pnts"
10729 || aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
10730 else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
10731 else if (aVal == "mem"
10732 || aVal == "gpumem"
10733 || aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
10734 else if (aVal == "skipimmediate"
10735 || aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
10736 else if (aVal == "frametime"
10737 || aVal == "frametimers"
10738 || aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
10739 else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
10740 else if (aVal == "extended"
10741 || aVal == "verbose"
10742 || aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
10743 else if (aVal == "full"
10744 || aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
10747 return Standard_False;
10752 theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
10756 theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
10758 return Standard_True;
10761 //! Read Graphic3d_RenderingParams::PerfCounters flags.
10762 static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
10763 Graphic3d_RenderingParams::PerfCounters& theFlags)
10765 TCollection_AsciiString aValue = theValue;
10766 Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
10767 Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
10768 Standard_Boolean toReset = Standard_False;
10771 Standard_Integer aSplitPos = aValue.Search ("|");
10772 if (aSplitPos <= 0)
10774 if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
10776 return Standard_False;
10780 theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
10782 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
10783 theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
10784 return Standard_True;
10789 TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
10790 if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
10792 return Standard_False;
10795 aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
10799 //=======================================================================
10800 //function : VRenderParams
10801 //purpose : Enables/disables rendering features
10802 //=======================================================================
10804 static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
10805 Standard_Integer theArgNb,
10806 const char** theArgVec)
10808 Handle(V3d_View) aView = ViewerTest::CurrentView();
10809 if (aView.IsNull())
10811 Message::SendFail ("Error: no active viewer");
10815 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
10816 TCollection_AsciiString aCmdName (theArgVec[0]);
10817 aCmdName.LowerCase();
10818 if (aCmdName == "vraytrace")
10822 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
10825 else if (theArgNb == 2)
10827 TCollection_AsciiString aValue (theArgVec[1]);
10828 aValue.LowerCase();
10832 aParams.Method = Graphic3d_RM_RAYTRACING;
10836 else if (aValue == "off"
10839 aParams.Method = Graphic3d_RM_RASTERIZATION;
10845 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
10851 Message::SendFail ("Syntax error: wrong number of arguments");
10858 theDI << "renderMode: ";
10859 switch (aParams.Method)
10861 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
10862 case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
10865 theDI << "transparency: ";
10866 switch (aParams.TransparencyMethod)
10868 case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
10869 case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
10870 << TCollection_AsciiString (aParams.OitDepthFactor); break;
10871 case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
10872 << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
10875 theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
10876 theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
10877 theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
10878 theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
10879 theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
10880 theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
10881 theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
10882 theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
10883 theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
10884 theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
10885 theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
10886 theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
10887 theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
10888 theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
10889 theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
10890 theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
10891 theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
10892 theDI << "shadingModel: ";
10893 switch (aView->ShadingModel())
10895 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
10896 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit"; break;
10897 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat"; break;
10898 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud"; break;
10899 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong"; break;
10900 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
10901 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
10905 theDI << "perfCounters:";
10906 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
10910 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
10914 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
10916 theDI << " structs";
10918 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
10920 theDI << " groups";
10922 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
10924 theDI << " arrays";
10926 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
10930 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
10934 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
10938 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
10940 theDI << " gpumem";
10942 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
10944 theDI << " frameTime";
10946 if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
10948 theDI << " skipimmediate";
10950 if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
10956 theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
10957 theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
10958 theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
10959 aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
10960 "noUpdate") << "\n";
10965 bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
10966 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
10967 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
10969 Standard_CString anArg (theArgVec[anArgIter]);
10970 TCollection_AsciiString aFlag (anArg);
10972 if (anUpdateTool.parseRedrawMode (aFlag))
10976 else if (aFlag == "-echo"
10977 || aFlag == "-print")
10979 toPrint = Standard_True;
10980 anUpdateTool.Invalidate();
10982 else if (aFlag == "-reset")
10984 aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
10986 else if (aFlag == "-sync"
10987 && (anArgIter + 1 < theArgNb))
10989 TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
10990 aSyncFlag.LowerCase();
10991 if (aSyncFlag == "default"
10992 || aSyncFlag == "defaults"
10993 || aSyncFlag == "viewer")
10995 toSyncDefaults = true;
10997 else if (aSyncFlag == "allviews"
10998 || aSyncFlag == "views")
11000 toSyncAllViews = true;
11004 Message::SendFail ("Syntax error: unknown parameter to -sync argument");
11008 else if (aFlag == "-mode"
11009 || aFlag == "-rendermode"
11010 || aFlag == "-render_mode")
11014 switch (aParams.Method)
11016 case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
11017 case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
11023 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11027 else if (aFlag == "-ray"
11028 || aFlag == "-raytrace")
11032 theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
11036 bool isRayTrace = true;
11037 if (anArgIter + 1 < theArgNb
11038 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
11042 aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
11044 else if (aFlag == "-rast"
11045 || aFlag == "-raster"
11046 || aFlag == "-rasterization")
11050 theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
11054 bool isRaster = true;
11055 if (anArgIter + 1 < theArgNb
11056 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
11060 aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
11062 else if (aFlag == "-msaa")
11066 theDI << aParams.NbMsaaSamples << " ";
11069 else if (++anArgIter >= theArgNb)
11071 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11075 const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11076 if (aNbSamples < 0)
11078 Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
11083 aParams.NbMsaaSamples = aNbSamples;
11086 else if (aFlag == "-linefeather"
11087 || aFlag == "-edgefeather"
11088 || aFlag == "-feather")
11092 theDI << " " << aParams.LineFeather << " ";
11095 else if (++anArgIter >= theArgNb)
11097 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11101 TCollection_AsciiString aParam = theArgVec[anArgIter];
11102 const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11103 if (aFeather <= 0.0f)
11105 Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
11108 aParams.LineFeather = aFeather;
11110 else if (aFlag == "-oit")
11114 if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
11116 theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
11118 else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
11120 theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
11124 theDI << "off" << " ";
11128 else if (++anArgIter >= theArgNb)
11130 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11134 TCollection_AsciiString aParam = theArgVec[anArgIter];
11135 aParam.LowerCase();
11136 if (aParam == "peeling"
11137 || aParam == "peel")
11139 aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
11140 if (anArgIter + 1 < theArgNb
11141 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
11144 const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11147 Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
11150 aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
11153 else if (aParam == "weighted"
11154 || aParam == "weight")
11156 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11157 if (anArgIter + 1 < theArgNb
11158 && TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
11161 const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
11162 if (aWeight < 0.f || aWeight > 1.f)
11164 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11167 aParams.OitDepthFactor = aWeight;
11170 else if (aParam.IsRealValue())
11172 const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
11173 if (aWeight < 0.f || aWeight > 1.f)
11175 Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
11179 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
11180 aParams.OitDepthFactor = aWeight;
11182 else if (aParam == "off")
11184 aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
11188 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11192 else if (aFlag == "-fonthinting"
11193 || aFlag == "-fonthint")
11197 if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11199 theDI << "normal" << " ";
11201 else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
11203 theDI << "light" << " ";
11207 theDI << "off" << " ";
11211 else if (anArgIter + 1 >= theArgNb)
11213 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11217 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11218 aHintStyle.LowerCase();
11219 if (aHintStyle == "normal"
11220 || aHintStyle == "on"
11221 || aHintStyle == "1")
11223 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11224 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
11226 else if (aHintStyle == "light")
11228 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11229 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
11231 else if (aHintStyle == "no"
11232 || aHintStyle == "off"
11233 || aHintStyle == "0")
11235 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
11236 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
11240 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11244 else if (aFlag == "-fontautohinting"
11245 || aFlag == "-fontautohint")
11249 if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
11251 theDI << "force" << " ";
11253 else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
11255 theDI << "disallow" << " ";
11259 theDI << "auto" << " ";
11263 else if (anArgIter + 1 >= theArgNb)
11265 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11269 TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
11270 aHintStyle.LowerCase();
11271 if (aHintStyle == "force")
11273 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11274 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
11276 else if (aHintStyle == "disallow"
11277 || aHintStyle == "no")
11279 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11280 aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
11282 else if (aHintStyle == "auto")
11284 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
11285 aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
11289 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
11293 else if (aFlag == "-depthprepass")
11297 theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
11300 aParams.ToEnableDepthPrepass = Standard_True;
11301 if (anArgIter + 1 < theArgNb
11302 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
11307 else if (aFlag == "-samplealphatocoverage"
11308 || aFlag == "-alphatocoverage")
11312 theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
11315 aParams.ToEnableAlphaToCoverage = Standard_True;
11316 if (anArgIter + 1 < theArgNb
11317 && Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
11322 else if (aFlag == "-rendscale"
11323 || aFlag == "-renderscale"
11324 || aFlag == "-renderresolutionscale")
11328 theDI << aParams.RenderResolutionScale << " ";
11331 else if (++anArgIter >= theArgNb)
11333 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11337 const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
11340 Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
11345 aParams.RenderResolutionScale = Standard_ShortReal(aScale);
11348 else if (aFlag == "-raydepth"
11349 || aFlag == "-ray_depth")
11353 theDI << aParams.RaytracingDepth << " ";
11356 else if (++anArgIter >= theArgNb)
11358 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11362 const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
11364 // We allow RaytracingDepth be more than 10 in case of GI enabled
11365 if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
11367 Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
11372 aParams.RaytracingDepth = aDepth;
11375 else if (aFlag == "-shad"
11376 || aFlag == "-shadows")
11380 theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
11384 Standard_Boolean toEnable = Standard_True;
11385 if (++anArgIter < theArgNb
11386 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11390 aParams.IsShadowEnabled = toEnable;
11392 else if (aFlag == "-shadowmapresolution"
11393 || aFlag == "-shadowmap")
11397 theDI << aParams.ShadowMapResolution << " ";
11400 else if (++anArgIter >= theArgNb)
11402 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11406 aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
11408 else if (aFlag == "-shadowmapbias")
11412 theDI << aParams.ShadowMapBias << " ";
11415 else if (++anArgIter >= theArgNb)
11417 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11421 aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
11423 else if (aFlag == "-refl"
11424 || aFlag == "-reflections")
11428 theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
11432 Standard_Boolean toEnable = Standard_True;
11433 if (++anArgIter < theArgNb
11434 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11438 aParams.IsReflectionEnabled = toEnable;
11440 else if (aFlag == "-fsaa")
11444 theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
11448 Standard_Boolean toEnable = Standard_True;
11449 if (++anArgIter < theArgNb
11450 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11454 aParams.IsAntialiasingEnabled = toEnable;
11456 else if (aFlag == "-gleam")
11460 theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
11464 Standard_Boolean toEnable = Standard_True;
11465 if (++anArgIter < theArgNb
11466 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11470 aParams.IsTransparentShadowEnabled = toEnable;
11472 else if (aFlag == "-gi")
11476 theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
11480 Standard_Boolean toEnable = Standard_True;
11481 if (++anArgIter < theArgNb
11482 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11486 aParams.IsGlobalIlluminationEnabled = toEnable;
11489 aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
11492 else if (aFlag == "-blockedrng"
11493 || aFlag == "-brng")
11497 theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
11501 Standard_Boolean toEnable = Standard_True;
11502 if (++anArgIter < theArgNb
11503 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11507 aParams.CoherentPathTracingMode = toEnable;
11509 else if (aFlag == "-maxrad")
11513 theDI << aParams.RadianceClampingValue << " ";
11516 else if (++anArgIter >= theArgNb)
11518 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11522 const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
11523 if (!aMaxRadStr.IsRealValue (Standard_True))
11525 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11529 const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
11530 if (aMaxRadiance <= 0.0)
11532 Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
11537 aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
11540 else if (aFlag == "-iss")
11544 theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
11548 Standard_Boolean toEnable = Standard_True;
11549 if (++anArgIter < theArgNb
11550 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11554 aParams.AdaptiveScreenSampling = toEnable;
11556 else if (aFlag == "-issatomic")
11560 theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
11564 Standard_Boolean toEnable = Standard_True;
11565 if (++anArgIter < theArgNb
11566 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11570 aParams.AdaptiveScreenSamplingAtomic = toEnable;
11572 else if (aFlag == "-issd")
11576 theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
11580 Standard_Boolean toEnable = Standard_True;
11581 if (++anArgIter < theArgNb
11582 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11586 aParams.ShowSamplingTiles = toEnable;
11588 else if (aFlag == "-tilesize")
11592 theDI << aParams.RayTracingTileSize << " ";
11595 else if (++anArgIter >= theArgNb)
11597 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11601 const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
11604 Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
11607 aParams.RayTracingTileSize = aTileSize;
11609 else if (aFlag == "-nbtiles")
11613 theDI << aParams.NbRayTracingTiles << " ";
11616 else if (++anArgIter >= theArgNb)
11618 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11622 const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
11625 Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
11628 else if (aNbTiles > 0
11630 || aNbTiles > 1024))
11632 Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
11634 aParams.NbRayTracingTiles = aNbTiles;
11636 else if (aFlag == "-env")
11640 theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
11644 Standard_Boolean toEnable = Standard_True;
11645 if (++anArgIter < theArgNb
11646 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11650 aParams.UseEnvironmentMapBackground = toEnable;
11652 else if (aFlag == "-ignorenormalmap")
11656 theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
11660 Standard_Boolean toEnable = Standard_True;
11661 if (++anArgIter < theArgNb
11662 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11666 aParams.ToIgnoreNormalMapInRayTracing = toEnable;
11668 else if (aFlag == "-twoside")
11672 theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
11676 Standard_Boolean toEnable = Standard_True;
11677 if (++anArgIter < theArgNb
11678 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11682 aParams.TwoSidedBsdfModels = toEnable;
11684 else if (aFlag == "-shademodel"
11685 || aFlag == "-shadingmodel"
11686 || aFlag == "-shading")
11690 switch (aView->ShadingModel())
11692 case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
11693 case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit "; break;
11694 case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat "; break;
11695 case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud "; break;
11696 case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong "; break;
11697 case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
11698 case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
11703 if (++anArgIter >= theArgNb)
11705 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11708 Graphic3d_TypeOfShadingModel aModel = Graphic3d_TypeOfShadingModel_DEFAULT;
11709 if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
11710 && aModel != Graphic3d_TypeOfShadingModel_DEFAULT)
11712 aView->SetShadingModel (aModel);
11716 Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
11720 else if (aFlag == "-pbrenvpow2size"
11721 || aFlag == "-pbrenvp2s"
11722 || aFlag == "-pep2s")
11724 if (++anArgIter >= theArgNb)
11726 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11730 const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
11731 if (aPbrEnvPow2Size < 1)
11733 Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
11736 aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
11738 else if (aFlag == "-pbrenvspecmaplevelsnumber"
11739 || aFlag == "-pbrenvspecmapnblevels"
11740 || aFlag == "-pbrenvspecmaplevels"
11741 || aFlag == "-pbrenvsmln"
11742 || aFlag == "-pesmln")
11744 if (++anArgIter >= theArgNb)
11746 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11750 const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
11751 if (aPbrEnvSpecMapNbLevels < 2)
11753 Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
11756 aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
11758 else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
11759 || aFlag == "-pbrenvbakingdiffsamples"
11760 || aFlag == "-pbrenvbdsn")
11762 if (++anArgIter >= theArgNb)
11764 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11768 const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
11769 if (aPbrEnvBakingDiffNbSamples < 1)
11771 Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
11774 aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
11776 else if (aFlag == "-pbrenvbakngspecsamplesnumber"
11777 || aFlag == "-pbrenvbakingspecsamples"
11778 || aFlag == "-pbrenvbssn")
11780 if (++anArgIter >= theArgNb)
11782 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11786 const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
11787 if (aPbrEnvBakingSpecNbSamples < 1)
11789 Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
11792 aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
11794 else if (aFlag == "-pbrenvbakingprobability"
11795 || aFlag == "-pbrenvbp")
11797 if (++anArgIter >= theArgNb)
11799 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11802 const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
11803 if (aPbrEnvBakingProbability < 0.f
11804 || aPbrEnvBakingProbability > 1.f)
11806 Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
11809 aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
11811 else if (aFlag == "-resolution")
11813 if (++anArgIter >= theArgNb)
11815 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11819 TCollection_AsciiString aResolution (theArgVec[anArgIter]);
11820 if (aResolution.IsIntegerValue())
11822 aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
11826 Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
11830 else if (aFlag == "-rebuildglsl"
11831 || aFlag == "-rebuild")
11835 theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
11839 Standard_Boolean toEnable = Standard_True;
11840 if (++anArgIter < theArgNb
11841 && !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
11845 aParams.RebuildRayTracingShaders = toEnable;
11847 else if (aFlag == "-focal")
11849 if (++anArgIter >= theArgNb)
11851 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11855 TCollection_AsciiString aParam (theArgVec[anArgIter]);
11856 if (aParam.IsRealValue (Standard_True))
11858 float aFocalDist = static_cast<float> (aParam.RealValue());
11859 if (aFocalDist < 0)
11861 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11864 aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
11868 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11872 else if (aFlag == "-aperture")
11874 if (++anArgIter >= theArgNb)
11876 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11880 TCollection_AsciiString aParam(theArgVec[anArgIter]);
11881 if (aParam.IsRealValue (Standard_True))
11883 float aApertureSize = static_cast<float> (aParam.RealValue());
11884 if (aApertureSize < 0)
11886 Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
11889 aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
11893 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11897 else if (aFlag == "-exposure")
11899 if (++anArgIter >= theArgNb)
11901 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11905 TCollection_AsciiString anExposure (theArgVec[anArgIter]);
11906 if (anExposure.IsRealValue (Standard_True))
11908 aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
11912 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11916 else if (aFlag == "-whitepoint")
11918 if (++anArgIter >= theArgNb)
11920 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11924 TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
11925 if (aWhitePoint.IsRealValue (Standard_True))
11927 aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
11931 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11935 else if (aFlag == "-tonemapping")
11937 if (++anArgIter >= theArgNb)
11939 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11943 TCollection_AsciiString aMode (theArgVec[anArgIter]);
11946 if (aMode == "disabled")
11948 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
11950 else if (aMode == "filmic")
11952 aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
11956 Message::SendFail() << "Syntax error at argument'" << anArg << "'";
11960 else if (aFlag == "-performancestats"
11961 || aFlag == "-performancecounters"
11962 || aFlag == "-perfstats"
11963 || aFlag == "-perfcounters"
11964 || aFlag == "-stats")
11966 if (++anArgIter >= theArgNb)
11968 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11972 TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
11973 aFlagsStr.LowerCase();
11974 Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
11975 if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
11977 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11980 aView->ChangeRenderingParams().CollectedStats = aFlags;
11981 aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
11983 else if (aFlag == "-perfupdateinterval"
11984 || aFlag == "-statsupdateinterval")
11986 if (++anArgIter >= theArgNb)
11988 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
11991 aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
11993 else if (aFlag == "-perfchart"
11994 || aFlag == "-statschart")
11996 if (++anArgIter >= theArgNb)
11998 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12001 aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
12003 else if (aFlag == "-perfchartmax"
12004 || aFlag == "-statschartmax")
12006 if (++anArgIter >= theArgNb)
12008 Message::SendFail() << "Syntax error at argument '" << anArg << "'";
12011 aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
12013 else if (aFlag == "-frustumculling"
12014 || aFlag == "-culling")
12018 theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
12019 (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
12020 "noUpdate") << " ";
12024 Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
12025 if (++anArgIter < theArgNb)
12027 TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
12028 aStateStr.LowerCase();
12029 bool toEnable = true;
12030 if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
12032 aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
12034 else if (aStateStr == "noupdate"
12035 || aStateStr == "freeze")
12037 aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
12044 aParams.FrustumCullingState = aState;
12048 Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
12053 // set current view parameters as defaults
12054 if (toSyncDefaults)
12056 ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
12058 if (toSyncAllViews)
12060 for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
12062 aViewIter.Value()->ChangeRenderingParams() = aParams;
12068 //=======================================================================
12069 //function : searchInfo
12071 //=======================================================================
12072 inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
12073 const TCollection_AsciiString& theKey)
12075 for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
12077 if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
12079 return anIter.Value();
12082 return TCollection_AsciiString();
12085 //=======================================================================
12086 //function : VStatProfiler
12088 //=======================================================================
12089 static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
12090 Standard_Integer theArgNb,
12091 const char** theArgVec)
12093 Handle(V3d_View) aView = ViewerTest::CurrentView();
12094 if (aView.IsNull())
12096 Message::SendFail ("Error: no active viewer");
12100 Standard_Boolean toRedraw = Standard_True;
12101 Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
12102 Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
12103 Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
12104 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12106 Standard_CString anArg (theArgVec[anArgIter]);
12107 TCollection_AsciiString aFlag (anArg);
12109 if (aFlag == "-noredraw")
12111 toRedraw = Standard_False;
12115 Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
12116 if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
12117 else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
12118 else if (aFlag == "alllayers"
12119 || aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
12120 else if (aFlag == "allstructs"
12121 || aFlag == "allstructures"
12122 || aFlag == "structs"
12123 || aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
12124 else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
12125 else if (aFlag == "allarrays"
12126 || aFlag == "fillarrays"
12127 || aFlag == "linearrays"
12128 || aFlag == "pointarrays"
12129 || aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
12130 else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
12131 else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
12132 else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
12133 else if (aFlag == "geommem"
12134 || aFlag == "texturemem"
12135 || aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
12136 else if (aFlag == "elapsedframe"
12137 || aFlag == "cpuframeaverage"
12138 || aFlag == "cpupickingaverage"
12139 || aFlag == "cpucullingaverage"
12140 || aFlag == "cpudynaverage"
12141 || aFlag == "cpuframemax"
12142 || aFlag == "cpupickingmax"
12143 || aFlag == "cpucullingmax"
12144 || aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
12147 Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
12151 aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
12155 if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
12157 aView->ChangeRenderingParams().CollectedStats =
12158 Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
12162 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12164 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12167 TColStd_IndexedDataMapOfStringString aDict;
12168 aView->StatisticInformation (aDict);
12170 aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
12172 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
12174 Standard_CString anArg(theArgVec[anArgIter]);
12175 TCollection_AsciiString aFlag(anArg);
12177 if (aFlag == "fps")
12179 theDI << searchInfo (aDict, "FPS") << " ";
12181 else if (aFlag == "cpu")
12183 theDI << searchInfo (aDict, "CPU FPS") << " ";
12185 else if (aFlag == "alllayers")
12187 theDI << searchInfo (aDict, "Layers") << " ";
12189 else if (aFlag == "layers")
12191 theDI << searchInfo (aDict, "Rendered layers") << " ";
12193 else if (aFlag == "allstructs"
12194 || aFlag == "allstructures")
12196 theDI << searchInfo (aDict, "Structs") << " ";
12198 else if (aFlag == "structs"
12199 || aFlag == "structures")
12201 TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
12202 if (aRend.IsEmpty()) // all structures rendered
12204 aRend = searchInfo (aDict, "Structs");
12206 theDI << aRend << " ";
12208 else if (aFlag == "groups")
12210 theDI << searchInfo (aDict, "Rendered groups") << " ";
12212 else if (aFlag == "allarrays")
12214 theDI << searchInfo (aDict, "Rendered arrays") << " ";
12216 else if (aFlag == "fillarrays")
12218 theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
12220 else if (aFlag == "linearrays")
12222 theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
12224 else if (aFlag == "pointarrays")
12226 theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
12228 else if (aFlag == "textarrays")
12230 theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
12232 else if (aFlag == "triangles")
12234 theDI << searchInfo (aDict, "Rendered triangles") << " ";
12236 else if (aFlag == "points")
12238 theDI << searchInfo (aDict, "Rendered points") << " ";
12240 else if (aFlag == "geommem")
12242 theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
12244 else if (aFlag == "texturemem")
12246 theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
12248 else if (aFlag == "framemem")
12250 theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
12252 else if (aFlag == "elapsedframe")
12254 theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
12256 else if (aFlag == "cpuframe_average")
12258 theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
12260 else if (aFlag == "cpupicking_average")
12262 theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
12264 else if (aFlag == "cpuculling_average")
12266 theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
12268 else if (aFlag == "cpudyn_average")
12270 theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
12272 else if (aFlag == "cpuframe_max")
12274 theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
12276 else if (aFlag == "cpupicking_max")
12278 theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
12280 else if (aFlag == "cpuculling_max")
12282 theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
12284 else if (aFlag == "cpudyn_max")
12286 theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
12294 aView->ChangeRenderingParams().StatsUpdateInterval = -1;
12296 aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
12298 theDI << "Statistic info:\n" << aView->StatisticInformation();
12303 //=======================================================================
12304 //function : VXRotate
12306 //=======================================================================
12307 static Standard_Integer VXRotate (Draw_Interpretor& di,
12308 Standard_Integer argc,
12309 const char ** argv)
12311 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
12312 if (aContext.IsNull())
12314 di << argv[0] << "ERROR : use 'vinit' command before \n";
12320 di << "ERROR : Usage : " << argv[0] << " name angle\n";
12324 TCollection_AsciiString aName (argv[1]);
12325 Standard_Real anAngle = Draw::Atof (argv[2]);
12328 ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
12329 Handle(AIS_InteractiveObject) anIObj;
12330 if (!aMap.Find2 (aName, anIObj))
12332 di << "Use 'vdisplay' before\n";
12336 gp_Trsf aTransform;
12337 aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
12338 aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
12340 aContext->SetLocation (anIObj, aTransform);
12341 aContext->UpdateCurrentViewer();
12347 //! Structure for setting AIS_Manipulator::SetPart() property.
12348 struct ManipAxisModeOnOff
12350 Standard_Integer Axis;
12351 AIS_ManipulatorMode Mode;
12352 Standard_Boolean ToEnable;
12354 ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
12357 enum ManipAjustPosition
12359 ManipAjustPosition_Off,
12360 ManipAjustPosition_Center,
12361 ManipAjustPosition_Location,
12362 ManipAjustPosition_ShapeLocation,
12366 //===============================================================================================
12367 //function : VManipulator
12369 //===============================================================================================
12370 static int VManipulator (Draw_Interpretor& theDi,
12371 Standard_Integer theArgsNb,
12372 const char** theArgVec)
12374 Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
12375 Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
12376 if (aCurrentView.IsNull()
12377 || aViewer.IsNull())
12379 Message::SendFail ("Error: no active viewer");
12383 ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
12384 Standard_Integer anArgIter = 1;
12385 Handle(AIS_Manipulator) aManipulator;
12386 ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
12387 TCollection_AsciiString aName;
12389 Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
12390 Standard_Real aGap = -1.0, aSize = -1.0;
12391 NCollection_Sequence<ManipAxisModeOnOff> aParts;
12392 gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
12394 bool toDetach = false;
12395 AIS_Manipulator::OptionsForAttach anAttachOptions;
12396 Handle(AIS_InteractiveObject) anAttachObject;
12397 Handle(V3d_View) aViewAffinity;
12398 ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
12400 Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
12401 Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
12402 Standard_Integer toStopMouseTransform = -1;
12403 // explicit transformation
12406 Standard_Real aTmpReal = 0.0;
12407 gp_XYZ aRotPnt, aRotAxis;
12408 for (; anArgIter < theArgsNb; ++anArgIter)
12410 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12412 if (anUpdateTool.parseRedrawMode (anArg))
12416 else if (anArg == "-help")
12418 theDi.PrintHelp (theArgVec[0]);
12422 else if (anArg == "-autoactivate"
12423 || anArg == "-noautoactivate")
12425 toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12427 else if (anArg == "-followtranslation"
12428 || anArg == "-nofollowtranslation")
12430 toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12432 else if (anArg == "-followrotation"
12433 || anArg == "-nofollowrotation")
12435 toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12437 else if (anArg == "-followdragging"
12438 || anArg == "-nofollowdragging")
12440 toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12442 else if (anArg == "-gap"
12443 && anArgIter + 1 < theArgsNb
12444 && Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
12449 else if (anArg == "-size"
12450 && anArgIter + 1 < theArgsNb
12451 && Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
12456 else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
12457 || (anArg == "-parts" && anArgIter + 2 < theArgsNb))
12459 ManipAxisModeOnOff aPart;
12460 Standard_Integer aMode = 0;
12461 if (anArg == "-part")
12463 if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
12464 || aPart.Axis < 0 || aPart.Axis > 3)
12466 Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
12470 if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
12471 || aMode < 1 || aMode > 4)
12473 Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
12476 if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
12478 Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
12481 aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
12482 aParts.Append (aPart);
12484 else if (anArg == "-pos"
12485 && anArgIter + 3 < theArgsNb
12486 && parseXYZ (theArgVec + anArgIter + 1, aLocation))
12489 if (anArgIter + 3 < theArgsNb
12490 && parseXYZ (theArgVec + anArgIter + 1, aVDir)
12491 && aVDir.Modulus() > Precision::Confusion())
12495 if (anArgIter + 3 < theArgsNb
12496 && parseXYZ (theArgVec + anArgIter + 1, anXDir)
12497 && anXDir.Modulus() > Precision::Confusion())
12502 else if (anArg == "-zoomable"
12503 || anArg == "-notzoomable")
12505 isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
12508 else if (anArg == "-adjustposition"
12509 || anArg == "-noadjustposition")
12511 anAttachPos = ManipAjustPosition_Center;
12512 if (anArgIter + 1 < theArgsNb)
12514 TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
12515 aPosName.LowerCase();
12516 if (aPosName == "0")
12518 anAttachPos = ManipAjustPosition_Off;
12520 else if (aPosName == "1"
12521 || aPosName == "center")
12523 anAttachPos = ManipAjustPosition_Center;
12525 else if (aPosName == "transformation"
12526 || aPosName == "trsf"
12527 || aPosName == "location"
12528 || aPosName == "loc")
12530 anAttachPos = ManipAjustPosition_Location;
12532 else if (aPosName == "shapelocation"
12533 || aPosName == "shapeloc")
12535 anAttachPos = ManipAjustPosition_ShapeLocation;
12542 anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
12544 else if (anArg == "-adjustsize"
12545 || anArg == "-noadjustsize")
12547 anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12549 else if (anArg == "-enablemodes"
12550 || anArg == "-enablemodes")
12552 anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
12555 else if (anArg == "-starttransform"
12556 && anArgIter + 2 < theArgsNb
12557 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
12558 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
12562 else if (anArg == "-transform"
12563 && anArgIter + 2 < theArgsNb
12564 && Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
12565 && Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
12569 else if (anArg == "-stoptransform")
12571 toStopMouseTransform = 1;
12572 if (anArgIter + 1 < theArgsNb
12573 && TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
12576 toStopMouseTransform = 0;
12580 else if (anArg == "-move"
12581 && anArgIter + 3 < theArgsNb
12582 && parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
12585 aTrsf.SetTranslationPart (aTmpXYZ);
12587 else if (anArg == "-scale"
12588 && anArgIter + 1 < theArgsNb
12589 && Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
12592 aTrsf.SetScale (gp_Pnt(), aTmpReal);
12594 else if (anArg == "-rotate"
12595 && anArgIter + 7 < theArgsNb
12596 && parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
12597 && parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
12598 && Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
12601 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
12604 else if (anArg == "-detach")
12608 else if (anArg == "-attach"
12609 && anArgIter + 1 < theArgsNb)
12611 TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
12612 if (!aMapAIS.Find2 (anObjName, anAttachObject))
12614 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
12618 for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
12620 Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
12621 if (!aManip.IsNull()
12622 && aManip->IsAttached()
12623 && aManip->Object() == anAttachObject)
12625 Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
12630 else if (anArg == "-view"
12631 && anArgIter + 1 < theArgsNb
12632 && aViewAffinity.IsNull())
12634 TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
12635 if (aViewString == "active")
12637 aViewAffinity = ViewerTest::CurrentView();
12639 else // Check view name
12641 ViewerTest_Names aViewNames (aViewString);
12642 if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
12644 Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
12647 aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
12648 if (aViewAffinity.IsNull())
12650 Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
12655 else if (aName.IsEmpty())
12657 aName = theArgVec[anArgIter];
12658 if (!aMapAIS.IsBound2 (aName))
12660 aManipulator = new AIS_Manipulator();
12661 aManipulator->SetModeActivationOnDetection (true);
12662 aMapAIS.Bind (aManipulator, aName);
12666 aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
12667 if (aManipulator.IsNull())
12669 Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
12676 theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
12680 if (aName.IsEmpty())
12682 Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
12686 && aManipulator.IsNull())
12688 aManipulator = new AIS_Manipulator();
12689 aManipulator->SetModeActivationOnDetection (true);
12690 aMapAIS.Bind (aManipulator, aName);
12693 // -----------------------------------------
12694 // change properties of manipulator instance
12695 // -----------------------------------------
12697 if (toAutoActivate != -1)
12699 aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
12701 if (toFollowTranslation != -1)
12703 aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
12705 if (toFollowRotation != -1)
12707 aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
12709 if (toFollowDragging != -1)
12711 aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
12715 aManipulator->SetGap ((float )aGap);
12718 for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
12720 const ManipAxisModeOnOff& aPart = aPartIter.Value();
12721 if (aPart.Axis == -1)
12723 aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
12727 aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
12733 aManipulator->SetSize ((float )aSize);
12735 if (isZoomable != -1)
12737 aManipulator->SetZoomPersistence (isZoomable == 0);
12739 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12741 ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
12742 ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
12746 // ----------------------------------
12747 // detach existing manipulator object
12748 // ----------------------------------
12752 aManipulator->Detach();
12753 aMapAIS.UnBind2 (aName);
12754 ViewerTest::GetAISContext()->Remove (aManipulator, false);
12757 // ---------------------------------------------------
12758 // attach, detach or access manipulator from an object
12759 // ---------------------------------------------------
12761 if (!anAttachObject.IsNull())
12763 aManipulator->Attach (anAttachObject, anAttachOptions);
12765 if (!aViewAffinity.IsNull())
12767 for (ViewerTest_ViewerCommandsViewMap::Iterator anIter (ViewerTest_myViews);
12768 anIter.More(); anIter.Next())
12770 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Key2(), false);
12772 ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
12775 if (anAttachPos != ManipAjustPosition_Off
12776 && aManipulator->IsAttached()
12777 && (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
12779 gp_Ax2 aPosition = gp::XOY();
12780 const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
12781 switch (anAttachPos)
12783 case ManipAjustPosition_Off:
12787 case ManipAjustPosition_Location:
12789 aPosition = gp::XOY().Transformed (aBaseTrsf);
12792 case ManipAjustPosition_ShapeLocation:
12794 if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
12796 aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
12800 Message::SendFail() << "Syntax error: manipulator is not attached to shape";
12805 case ManipAjustPosition_Center:
12808 for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
12811 anObjIter.Value()->BoundingBox (anObjBox);
12812 aBox.Add (anObjBox);
12814 aBox = aBox.FinitePart();
12815 if (!aBox.IsVoid())
12817 const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
12818 aPosition.SetLocation (aCenter);
12823 aManipulator->SetPosition (aPosition);
12825 if (!Precision::IsInfinite (aLocation.X()))
12827 if (aVDir.Modulus() <= Precision::Confusion())
12829 aVDir = aManipulator->Position().Direction().XYZ();
12831 if (anXDir.Modulus() <= Precision::Confusion())
12833 anXDir = aManipulator->Position().XDirection().XYZ();
12835 aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
12838 // --------------------------------------
12839 // apply transformation using manipulator
12840 // --------------------------------------
12842 if (aMousePosFrom.x() != IntegerLast())
12844 aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
12846 if (aMousePosTo.x() != IntegerLast())
12848 aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
12850 if (toStopMouseTransform != -1)
12852 aManipulator->StopTransform (toStopMouseTransform == 1);
12855 if (aTrsf.Form() != gp_Identity)
12857 aManipulator->Transform (aTrsf);
12860 if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
12862 ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
12867 //===============================================================================================
12868 //function : VSelectionProperties
12870 //===============================================================================================
12871 static int VSelectionProperties (Draw_Interpretor& theDi,
12872 Standard_Integer theArgsNb,
12873 const char** theArgVec)
12875 const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
12878 Message::SendFail ("Error: no active viewer");
12882 if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
12884 // handle obsolete alias
12885 bool toEnable = true;
12888 theDi << (aCtx->ToHilightSelected() ? "on" : "off");
12891 else if (theArgsNb != 2
12892 || !Draw::ParseOnOff (theArgVec[1], toEnable))
12894 Message::SendFail ("Syntax error: wrong number of parameters");
12897 if (toEnable != aCtx->ToHilightSelected())
12899 aCtx->ClearDetected();
12900 aCtx->SetToHilightSelected (toEnable);
12905 Standard_Boolean toPrint = theArgsNb == 1;
12906 Standard_Boolean toRedraw = Standard_False;
12907 Standard_Integer anArgIter = 1;
12908 Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
12909 if (anArgIter < theArgsNb)
12911 TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
12912 anArgFirst.LowerCase();
12914 if (anArgFirst == "dynhighlight"
12915 || anArgFirst == "dynhilight"
12916 || anArgFirst == "dynamichighlight"
12917 || anArgFirst == "dynamichilight")
12919 aType = Prs3d_TypeOfHighlight_Dynamic;
12921 else if (anArgFirst == "localdynhighlight"
12922 || anArgFirst == "localdynhilight"
12923 || anArgFirst == "localdynamichighlight"
12924 || anArgFirst == "localdynamichilight")
12926 aType = Prs3d_TypeOfHighlight_LocalDynamic;
12928 else if (anArgFirst == "selhighlight"
12929 || anArgFirst == "selhilight"
12930 || anArgFirst == "selectedhighlight"
12931 || anArgFirst == "selectedhilight")
12933 aType = Prs3d_TypeOfHighlight_Selected;
12935 else if (anArgFirst == "localselhighlight"
12936 || anArgFirst == "localselhilight"
12937 || anArgFirst == "localselectedhighlight"
12938 || anArgFirst == "localselectedhilight")
12940 aType = Prs3d_TypeOfHighlight_LocalSelected;
12947 for (; anArgIter < theArgsNb; ++anArgIter)
12949 TCollection_AsciiString anArg (theArgVec[anArgIter]);
12951 if (anArg == "-help")
12953 theDi.PrintHelp (theArgVec[0]);
12956 else if (anArg == "-print")
12958 toPrint = Standard_True;
12960 else if (anArg == "-autoactivate")
12962 Standard_Boolean toEnable = Standard_True;
12963 if (anArgIter + 1 < theArgsNb
12964 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12968 aCtx->SetAutoActivateSelection (toEnable);
12970 else if (anArg == "-automatichighlight"
12971 || anArg == "-automatichilight"
12972 || anArg == "-autohighlight"
12973 || anArg == "-autohilight")
12975 Standard_Boolean toEnable = Standard_True;
12976 if (anArgIter + 1 < theArgsNb
12977 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12981 aCtx->ClearSelected (false);
12982 aCtx->ClearDetected();
12983 aCtx->SetAutomaticHilight (toEnable);
12986 else if (anArg == "-highlightselected"
12987 || anArg == "-hilightselected")
12989 Standard_Boolean toEnable = Standard_True;
12990 if (anArgIter + 1 < theArgsNb
12991 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
12995 aCtx->ClearDetected();
12996 aCtx->SetToHilightSelected (toEnable);
12999 else if (anArg == "-pickstrategy"
13000 || anArg == "-pickingstrategy")
13002 if (++anArgIter >= theArgsNb)
13004 Message::SendFail ("Syntax error: type of highlighting is undefined");
13008 SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13009 TCollection_AsciiString aVal (theArgVec[anArgIter]);
13011 if (aVal == "first"
13012 || aVal == "firstaccepted"
13013 || aVal == "firstacceptable")
13015 aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
13017 else if (aVal == "topmost"
13018 || aVal == "onlyTopmost")
13020 aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
13024 Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
13028 aCtx->SetPickingStrategy (aStrategy);
13030 else if (anArg == "-pixtol"
13031 && anArgIter + 1 < theArgsNb)
13033 aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
13035 else if (anArg == "-preferclosest")
13037 bool toPreferClosest = true;
13038 if (anArgIter + 1 < theArgsNb
13039 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
13043 aCtx->MainSelector()->SetPickClosest (toPreferClosest);
13045 else if ((anArg == "-depthtol"
13046 || anArg == "-depthtolerance")
13047 && anArgIter + 1 < theArgsNb)
13049 TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
13050 aTolType.LowerCase();
13051 if (aTolType == "uniform")
13053 if (anArgIter + 1 >= theArgsNb)
13055 Message::SendFail() << "Syntax error: wrong number of arguments";
13058 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
13059 Draw::Atof (theArgVec[++anArgIter]));
13061 else if (aTolType == "uniformpx")
13063 if (anArgIter + 1 >= theArgsNb)
13065 Message::SendFail() << "Syntax error: wrong number of arguments";
13068 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
13069 Draw::Atof (theArgVec[++anArgIter]));
13071 else if (aTolType == "sensfactor")
13073 aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
13077 Message::SendFail() << "Syntax error at '" << aTolType << "'";
13081 else if ((anArg == "-mode"
13082 || anArg == "-dispmode")
13083 && anArgIter + 1 < theArgsNb)
13085 if (aType == Prs3d_TypeOfHighlight_None)
13087 Message::SendFail ("Syntax error: type of highlighting is undefined");
13091 const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
13092 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13093 aStyle->SetDisplayMode (aDispMode);
13094 toRedraw = Standard_True;
13096 else if (anArg == "-layer"
13097 && anArgIter + 1 < theArgsNb)
13099 if (aType == Prs3d_TypeOfHighlight_None)
13101 Message::SendFail ("Syntax error: type of highlighting is undefined");
13106 Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
13107 if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
13109 Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
13113 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13114 aStyle->SetZLayer (aNewLayer);
13115 toRedraw = Standard_True;
13117 else if (anArg == "-hicolor"
13118 || anArg == "-selcolor"
13119 || anArg == "-color")
13121 if (anArg.StartsWith ("-hi"))
13123 aType = Prs3d_TypeOfHighlight_Dynamic;
13125 else if (anArg.StartsWith ("-sel"))
13127 aType = Prs3d_TypeOfHighlight_Selected;
13129 else if (aType == Prs3d_TypeOfHighlight_None)
13131 Message::SendFail ("Syntax error: type of highlighting is undefined");
13135 Quantity_Color aColor;
13136 Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
13137 theArgVec + anArgIter + 1,
13139 if (aNbParsed == 0)
13141 Message::SendFail ("Syntax error: need more arguments");
13144 anArgIter += aNbParsed;
13146 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13147 aStyle->SetColor (aColor);
13148 toRedraw = Standard_True;
13150 else if ((anArg == "-transp"
13151 || anArg == "-transparency"
13152 || anArg == "-hitransp"
13153 || anArg == "-seltransp"
13154 || anArg == "-hitransplocal"
13155 || anArg == "-seltransplocal")
13156 && anArgIter + 1 < theArgsNb)
13158 if (anArg.StartsWith ("-hi"))
13160 aType = Prs3d_TypeOfHighlight_Dynamic;
13162 else if (anArg.StartsWith ("-sel"))
13164 aType = Prs3d_TypeOfHighlight_Selected;
13166 else if (aType == Prs3d_TypeOfHighlight_None)
13168 Message::SendFail ("Syntax error: type of highlighting is undefined");
13172 const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
13173 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13174 aStyle->SetTransparency ((Standard_ShortReal )aTransp);
13175 toRedraw = Standard_True;
13177 else if ((anArg == "-mat"
13178 || anArg == "-material")
13179 && anArgIter + 1 < theArgsNb)
13181 if (aType == Prs3d_TypeOfHighlight_None)
13183 Message::SendFail ("Syntax error: type of highlighting is undefined");
13187 const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
13188 Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
13189 if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
13192 Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
13193 *anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
13194 Graphic3d_MaterialAspect aMat (aMatName);
13195 aMat.SetColor (aStyle->Color());
13196 aMat.SetTransparency (aStyle->Transparency());
13197 anAspect->SetFrontMaterial (aMat);
13198 anAspect->SetInteriorColor (aStyle->Color());
13199 aStyle->SetBasicFillAreaAspect (anAspect);
13203 aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
13205 toRedraw = Standard_True;
13209 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
13216 const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
13217 const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
13218 theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
13219 theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
13220 theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
13221 theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
13222 theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
13223 theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
13224 theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
13225 theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
13226 theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
13227 theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
13228 theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
13229 theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
13232 if (aCtx->NbSelected() != 0 && toRedraw)
13234 aCtx->HilightSelected (Standard_True);
13240 //===============================================================================================
13241 //function : VDumpSelectionImage
13243 //===============================================================================================
13244 static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
13245 Standard_Integer theArgsNb,
13246 const char** theArgVec)
13248 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13249 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13250 if (aContext.IsNull())
13252 Message::SendFail ("Error: no active viewer");
13256 TCollection_AsciiString aFile;
13257 StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13258 Handle(Graphic3d_Camera) aCustomCam;
13259 Image_Format anImgFormat = Image_Format_BGR;
13260 Standard_Integer aPickedIndex = 1;
13261 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13263 TCollection_AsciiString aParam (theArgVec[anArgIter]);
13264 aParam.LowerCase();
13265 if (aParam == "-type")
13267 if (++anArgIter >= theArgsNb)
13269 Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
13273 TCollection_AsciiString aValue (theArgVec[anArgIter]);
13274 aValue.LowerCase();
13275 if (aValue == "depth"
13276 || aValue == "normdepth"
13277 || aValue == "normalizeddepth")
13279 aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
13280 anImgFormat = Image_Format_GrayF;
13282 else if (aValue == "depthinverted"
13283 || aValue == "normdepthinverted"
13284 || aValue == "normalizeddepthinverted"
13285 || aValue == "inverted")
13287 aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
13288 anImgFormat = Image_Format_GrayF;
13290 else if (aValue == "unnormdepth"
13291 || aValue == "unnormalizeddepth")
13293 aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
13294 anImgFormat = Image_Format_GrayF;
13296 else if (aValue == "objectcolor"
13297 || aValue == "object"
13298 || aValue == "color")
13300 aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
13302 else if (aValue == "entitycolor"
13303 || aValue == "entity")
13305 aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
13307 else if (aValue == "entitytypecolor"
13308 || aValue == "entitytype")
13310 aType = StdSelect_TypeOfSelectionImage_ColoredEntityType;
13312 else if (aValue == "ownercolor"
13313 || aValue == "owner")
13315 aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
13317 else if (aValue == "selectionmodecolor"
13318 || aValue == "selectionmode"
13319 || aValue == "selmodecolor"
13320 || aValue == "selmode")
13322 aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
13324 else if (aValue == "surfnormal"
13325 || aValue == "surfacenormal"
13326 || aValue == "normal")
13328 aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
13332 Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
13336 else if (aParam == "-picked"
13337 || aParam == "-pickeddepth"
13338 || aParam == "-pickedindex")
13340 if (++anArgIter >= theArgsNb)
13342 Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
13346 aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
13348 else if (anArgIter + 1 < theArgsNb
13349 && aParam == "-xrpose")
13351 TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
13352 anXRArg.LowerCase();
13353 if (anXRArg == "base")
13355 aCustomCam = aView->View()->BaseXRCamera();
13357 else if (anXRArg == "head")
13359 aCustomCam = aView->View()->PosedXRCamera();
13363 Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
13366 if (aCustomCam.IsNull())
13368 Message::SendFail() << "Error: undefined XR pose";
13372 else if (aFile.IsEmpty())
13374 aFile = theArgVec[anArgIter];
13378 Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13382 if (aFile.IsEmpty())
13384 Message::SendFail ("Syntax error: image file name is missing");
13388 Standard_Integer aWidth = 0, aHeight = 0;
13389 aView->Window()->Size (aWidth, aHeight);
13391 Image_AlienPixMap aPixMap;
13392 if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
13394 Message::SendFail ("Error: can't allocate image");
13398 const bool wasImmUpdate = aView->SetImmediateUpdate (false);
13399 Handle(Graphic3d_Camera) aCamBack = aView->Camera();
13400 if (!aCustomCam.IsNull())
13402 aView->SetCamera (aCustomCam);
13404 if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
13406 Message::SendFail ("Error: can't generate selection image");
13409 if (!aCustomCam.IsNull())
13411 aView->SetCamera (aCamBack);
13413 aView->SetImmediateUpdate (wasImmUpdate);
13415 if (!aPixMap.Save (aFile))
13417 Message::SendFail ("Error: can't save selection image");
13423 //===============================================================================================
13424 //function : VViewCube
13426 //===============================================================================================
13427 static int VViewCube (Draw_Interpretor& ,
13428 Standard_Integer theNbArgs,
13429 const char** theArgVec)
13431 const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
13432 const Handle(V3d_View)& aView = ViewerTest::CurrentView();
13433 if (aContext.IsNull() || aView.IsNull())
13435 Message::SendFail ("Error: no active viewer");
13438 else if (theNbArgs < 2)
13440 Message::SendFail ("Syntax error: wrong number arguments");
13444 Handle(AIS_ViewCube) aViewCube;
13445 ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
13446 Quantity_Color aColorRgb;
13447 TCollection_AsciiString aName;
13448 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13450 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13452 if (anUpdateTool.parseRedrawMode (anArg))
13456 else if (aViewCube.IsNull())
13458 aName = theArgVec[anArgIter];
13459 if (aName.StartsWith ("-"))
13461 Message::SendFail ("Syntax error: object name should be specified");
13464 Handle(AIS_InteractiveObject) aPrs;
13465 GetMapOfAIS().Find2 (aName, aPrs);
13466 aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
13467 if (aViewCube.IsNull())
13469 aViewCube = new AIS_ViewCube();
13470 aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
13471 aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
13472 aViewCube->SetFixedAnimationLoop (false);
13475 else if (anArg == "-reset")
13477 aViewCube->ResetStyles();
13479 else if (anArg == "-color"
13480 || anArg == "-boxcolor"
13481 || anArg == "-boxsidecolor"
13482 || anArg == "-sidecolor"
13483 || anArg == "-boxedgecolor"
13484 || anArg == "-edgecolor"
13485 || anArg == "-boxcornercolor"
13486 || anArg == "-cornercolor"
13487 || anArg == "-innercolor"
13488 || anArg == "-textcolor"
13489 || anArg == "-xaxistextcolor"
13490 || anArg == "-yaxistextcolor"
13491 || anArg == "-zaxistextcolor")
13493 Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
13494 theArgVec + anArgIter + 1,
13496 if (aNbParsed == 0)
13498 Message::SendFail() << "Syntax error at '" << anArg << "'";
13501 anArgIter += aNbParsed;
13502 if (anArg == "-boxcolor")
13504 aViewCube->SetBoxColor (aColorRgb);
13506 else if (anArg == "-boxsidecolor"
13507 || anArg == "-sidecolor")
13509 aViewCube->BoxSideStyle()->SetColor (aColorRgb);
13510 aViewCube->SynchronizeAspects();
13512 else if (anArg == "-boxedgecolor"
13513 || anArg == "-edgecolor")
13515 aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
13516 aViewCube->SynchronizeAspects();
13518 else if (anArg == "-boxcornercolor"
13519 || anArg == "-cornercolor")
13521 aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
13522 aViewCube->SynchronizeAspects();
13524 else if (anArg == "-innercolor")
13526 aViewCube->SetInnerColor (aColorRgb);
13528 else if (anArg == "-textcolor")
13530 aViewCube->SetTextColor (aColorRgb);
13532 else if (anArg == "-xaxistextcolor"
13533 || anArg == "-yaxistextcolor"
13534 || anArg == "-zaxistextcolor")
13536 Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
13537 ? Prs3d_DatumParts_XAxis
13538 : (anArg.Value (2) == 'y'
13539 ? Prs3d_DatumParts_YAxis
13540 : Prs3d_DatumParts_ZAxis);
13541 aViewCube->Attributes()->SetOwnDatumAspects();
13542 aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
13546 aViewCube->SetColor (aColorRgb);
13549 else if (anArgIter + 1 < theNbArgs
13550 && (anArg == "-transparency"
13551 || anArg == "-boxtransparency"))
13553 const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
13554 if (aValue < 0.0 || aValue > 1.0)
13556 Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
13560 if (anArg == "-boxtransparency")
13562 aViewCube->SetBoxTransparency (aValue);
13566 aViewCube->SetTransparency (aValue);
13569 else if (anArg == "-axes"
13570 || anArg == "-edges"
13571 || anArg == "-vertices"
13572 || anArg == "-vertexes"
13573 || anArg == "-fixedanimation")
13575 bool toShow = true;
13576 if (anArgIter + 1 < theNbArgs
13577 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
13581 if (anArg == "-fixedanimation")
13583 aViewCube->SetFixedAnimationLoop (toShow);
13585 else if (anArg == "-axes")
13587 aViewCube->SetDrawAxes (toShow);
13589 else if (anArg == "-edges")
13591 aViewCube->SetDrawEdges (toShow);
13595 aViewCube->SetDrawVertices (toShow);
13598 else if (anArg == "-yup"
13599 || anArg == "-zup")
13602 if (anArgIter + 1 < theNbArgs
13603 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
13607 if (anArg == "-yup")
13609 aViewCube->SetYup (isOn);
13613 aViewCube->SetYup (!isOn);
13616 else if (anArgIter + 1 < theNbArgs
13617 && anArg == "-font")
13619 aViewCube->SetFont (theArgVec[++anArgIter]);
13621 else if (anArgIter + 1 < theNbArgs
13622 && anArg == "-fontheight")
13624 aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
13626 else if (anArgIter + 1 < theNbArgs
13627 && (anArg == "-size"
13628 || anArg == "-boxsize"))
13630 aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
13631 anArg != "-boxsize");
13633 else if (anArgIter + 1 < theNbArgs
13634 && (anArg == "-boxfacet"
13635 || anArg == "-boxfacetextension"
13636 || anArg == "-facetextension"
13637 || anArg == "-extension"))
13639 aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
13641 else if (anArgIter + 1 < theNbArgs
13642 && (anArg == "-boxedgegap"
13643 || anArg == "-edgegap"))
13645 aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
13647 else if (anArgIter + 1 < theNbArgs
13648 && (anArg == "-boxedgeminsize"
13649 || anArg == "-edgeminsize"))
13651 aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
13653 else if (anArgIter + 1 < theNbArgs
13654 && (anArg == "-boxcornerminsize"
13655 || anArg == "-cornerminsize"))
13657 aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
13659 else if (anArgIter + 1 < theNbArgs
13660 && anArg == "-axespadding")
13662 aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
13664 else if (anArgIter + 1 < theNbArgs
13665 && anArg == "-roundradius")
13667 aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
13669 else if (anArgIter + 1 < theNbArgs
13670 && anArg == "-duration")
13672 aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
13674 else if (anArgIter + 1 < theNbArgs
13675 && anArg == "-axesradius")
13677 aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
13679 else if (anArgIter + 1 < theNbArgs
13680 && anArg == "-axesconeradius")
13682 aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
13684 else if (anArgIter + 1 < theNbArgs
13685 && anArg == "-axessphereradius")
13687 aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
13689 else if (anArg == "-orthopers")
13691 const Handle(Graphic3d_TransformPers)& aTrsfPers = aViewCube->TransformPersistence();
13692 Handle(Graphic3d_TransformPers) anOrthoPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers | Graphic3d_TMF_OrthoPers, aTrsfPers->Corner2d(), aTrsfPers->Offset2d());
13693 aViewCube->SetTransformPersistence (anOrthoPers);
13697 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13701 if (aViewCube.IsNull())
13703 Message::SendFail ("Syntax error: wrong number of arguments");
13707 ViewerTest::Display (aName, aViewCube, false);
13711 //! Parse color type argument.
13712 static bool parseColorType (const char* theString,
13713 Quantity_TypeOfColor& theType)
13715 TCollection_AsciiString aType (theString);
13717 if (aType == "rgb") { theType = Quantity_TOC_RGB; }
13718 else if (aType == "srgb") { theType = Quantity_TOC_sRGB; }
13719 else if (aType == "hex") { theType = Quantity_TOC_sRGB; }
13720 else if (aType == "name") { theType = Quantity_TOC_sRGB; }
13721 else if (aType == "hls") { theType = Quantity_TOC_HLS; }
13722 else if (aType == "lab") { theType = Quantity_TOC_CIELab; }
13723 else if (aType == "lch") { theType = Quantity_TOC_CIELch; }
13724 else { return false; }
13728 //===============================================================================================
13729 //function : VColorConvert
13731 //===============================================================================================
13732 static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13734 Quantity_TypeOfColor aTypeFrom = Quantity_TOC_RGB, aTypeTo = Quantity_TOC_RGB;
13735 double anInput[4] = {};
13736 Quantity_ColorRGBA aColor (0.0f, 0.0f, 0.0f, 1.0f);
13737 bool toPrintHex = false, toPrintName = false, hasAlpha = false;
13738 for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13740 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
13741 anArgCase.LowerCase();
13742 if ((anArgCase == "-from"
13743 || anArgCase == "from")
13744 && anArgIter + 1 < theNbArgs
13745 && parseColorType (theArgVec[anArgIter + 1], aTypeFrom))
13749 else if ((anArgCase == "-to"
13750 || anArgCase == "to")
13751 && anArgIter + 1 < theNbArgs
13752 && parseColorType (theArgVec[anArgIter + 1], aTypeTo))
13754 TCollection_AsciiString aToStr (theArgVec[++anArgIter]);
13755 aToStr.LowerCase();
13756 toPrintHex = (aToStr == "hex");
13757 toPrintName = (aToStr == "name");
13759 else if (Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColor))
13761 hasAlpha = anArgCase.Length() >= 8;
13763 else if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aColor.ChangeRGB()))
13767 else if (anArgIter + 2 < theNbArgs
13768 && Draw::ParseReal (theArgVec[anArgIter + 0], anInput[0])
13769 && Draw::ParseReal (theArgVec[anArgIter + 1], anInput[1])
13770 && Draw::ParseReal (theArgVec[anArgIter + 2], anInput[2]))
13772 if (anArgIter + 3 < theNbArgs
13773 && Draw::ParseReal (theArgVec[anArgIter + 3], anInput[3]))
13776 aColor.SetAlpha ((float )anInput[3]);
13780 aColor.ChangeRGB().SetValues (anInput[0], anInput[1], anInput[2], aTypeFrom);
13784 theDI << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
13791 if (hasAlpha || aColor.Alpha() < 1.0f)
13793 theDI << Quantity_ColorRGBA::ColorToHex (aColor);
13797 theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
13800 else if (toPrintName)
13802 theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
13806 double anOutput[3] = {};
13807 aColor.GetRGB().Values (anOutput[0], anOutput[1], anOutput[2], aTypeTo);
13809 // print values with 6 decimal digits
13810 char aBuffer[1024];
13811 if (hasAlpha || aColor.Alpha() < 1.0f)
13813 Sprintf (aBuffer, "%.6f %.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2], aColor.Alpha());
13817 Sprintf (aBuffer, "%.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2]);
13824 //===============================================================================================
13825 //function : VColorDiff
13827 //===============================================================================================
13828 static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
13830 if (theNbArgs != 7)
13832 std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
13836 double aR1 = Draw::Atof (theArgVec[1]);
13837 double aG1 = Draw::Atof (theArgVec[2]);
13838 double aB1 = Draw::Atof (theArgVec[3]);
13839 double aR2 = Draw::Atof (theArgVec[4]);
13840 double aG2 = Draw::Atof (theArgVec[5]);
13841 double aB2 = Draw::Atof (theArgVec[6]);
13843 Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
13844 Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
13846 theDI << aColor1.DeltaE2000 (aColor2);
13851 //===============================================================================================
13852 //function : VSelBvhBuild
13854 //===============================================================================================
13855 static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
13857 const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
13860 Message::SendFail ("Error: no active viewer");
13866 Message::SendFail ("Error: command syntax is incorrect, see help");
13870 Standard_Integer toEnable = -1;
13871 Standard_Integer aThreadsNb = -1;
13872 Standard_Boolean toWait = Standard_False;
13874 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
13876 TCollection_AsciiString anArg (theArgVec[anArgIter]);
13879 if (anArg == "-nbthreads"
13880 && anArgIter + 1 < theNbArgs)
13882 aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
13883 if (aThreadsNb < 1)
13885 aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
13888 else if (anArg == "-wait")
13890 toWait = Standard_True;
13892 else if (toEnable == -1)
13894 Standard_Boolean toEnableValue = Standard_True;
13895 if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
13897 toEnable = toEnableValue ? 1 : 0;
13901 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13907 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
13912 if (aThreadsNb == -1)
13916 if (toEnable != -1)
13918 aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
13922 aCtx->MainSelector()->WaitForBVHBuild();
13928 //=======================================================================
13929 //function : VChangeMouseGesture
13931 //=======================================================================
13932 static int VChangeMouseGesture (Draw_Interpretor&,
13933 Standard_Integer theArgsNb,
13934 const char** theArgVec)
13936 Handle(V3d_View) aView = ViewerTest::CurrentView();
13937 if (aView.IsNull())
13939 Message::SendFail ("Error: no active viewer");
13943 NCollection_DoubleMap<TCollection_AsciiString, AIS_MouseGesture> aGestureMap;
13945 aGestureMap.Bind ("none", AIS_MouseGesture_NONE);
13946 aGestureMap.Bind ("selectrectangle", AIS_MouseGesture_SelectRectangle);
13947 aGestureMap.Bind ("selectlasso", AIS_MouseGesture_SelectLasso);
13948 aGestureMap.Bind ("zoom", AIS_MouseGesture_Zoom);
13949 aGestureMap.Bind ("zoomwindow", AIS_MouseGesture_ZoomWindow);
13950 aGestureMap.Bind ("pan", AIS_MouseGesture_Pan);
13951 aGestureMap.Bind ("rotateorbit", AIS_MouseGesture_RotateOrbit);
13952 aGestureMap.Bind ("rotateview", AIS_MouseGesture_RotateView);
13953 aGestureMap.Bind ("drag", AIS_MouseGesture_Drag);
13955 NCollection_DoubleMap<TCollection_AsciiString, Standard_UInteger> aMouseButtonMap;
13957 aMouseButtonMap.Bind ("none", (Standard_UInteger )Aspect_VKeyMouse_NONE);
13958 aMouseButtonMap.Bind ("left", (Standard_UInteger )Aspect_VKeyMouse_LeftButton);
13959 aMouseButtonMap.Bind ("middle", (Standard_UInteger )Aspect_VKeyMouse_MiddleButton);
13960 aMouseButtonMap.Bind ("right", (Standard_UInteger )Aspect_VKeyMouse_RightButton);
13963 Standard_UInteger aButton = (Standard_UInteger )Aspect_VKeyMouse_LeftButton;
13964 AIS_MouseGesture aGesture = AIS_MouseGesture_RotateOrbit;
13965 for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
13967 Standard_CString anArg = theArgVec[anArgIter];
13968 TCollection_AsciiString anArgCase (anArg);
13969 anArgCase.LowerCase();
13970 if (anArgCase == "-button")
13972 TCollection_AsciiString aButtonStr = theArgVec[++anArgIter];
13973 aButtonStr.LowerCase();
13974 aButton = aMouseButtonMap.Find1 (aButtonStr);
13976 else if (anArgCase == "-gesture")
13978 TCollection_AsciiString aGestureStr = theArgVec[++anArgIter];
13979 aGestureStr.LowerCase();
13980 aGesture = aGestureMap.Find1 (aGestureStr);
13984 Message::SendFail() << "Error: unknown argument '" << anArg << "'";
13989 Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
13990 aViewMgr->ChangeMouseGestureMap().Bind (aButton, aGesture);
13995 //=======================================================================
13996 //function : ViewerTest_ExitProc
13998 //=======================================================================
13999 static void ViewerTest_ExitProc (ClientData )
14001 NCollection_List<TCollection_AsciiString> aViewList;
14002 for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
14003 anIter.More(); anIter.Next())
14005 aViewList.Append (anIter.Key1());
14008 for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
14009 anIter.More(); anIter.Next())
14011 ViewerTest::RemoveView (anIter.Value(), true);
14015 //=======================================================================
14016 //function : ViewerCommands
14018 //=======================================================================
14020 void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
14022 static bool TheIsInitialized = false;
14023 if (TheIsInitialized)
14028 TheIsInitialized = true;
14029 // define destruction callback to destroy views in a well-defined order
14030 Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
14032 const char* aGroup = "AIS Viewer";
14033 const char* aFileName = __FILE__;
14034 auto addCmd = [&](const char* theName, Draw_Interpretor::CommandFunction theFunc, const char* theHelp)
14036 theCommands.Add (theName, theHelp, aFileName, theFunc, aGroup);
14039 addCmd ("vdriver", VDriver, /* [vdriver] */ R"(
14040 vdriver [-list] [-default DriverName] [-load DriverName]
14041 Manages active graphic driver factory.
14042 Prints current active driver when called without arguments.
14043 Makes specified driver active when ActiveName argument is specified.
14044 -list print registered factories
14045 -default define which factory should be used by default (to be used by next vinit call)
14046 -load try loading factory plugin and set it as default one
14047 )" /* [vdriver] */);
14049 addCmd ("vinit", VInit, /* [vinit] */ R"(
14050 vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]
14051 [-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {0|1}]=0 [-2d_mode {0|1}]=0
14052 [-display displayName] [-dpiAware {0|1}]=0
14053 [-subview] [-parent OtherView] [-composer {0|1}]=0 [-margins DX DY]=0
14054 Creates new View window with specified name viewName.
14055 By default the new view is created in the viewer and in graphic driver shared with active view.
14056 -name {driverName/viewerName/viewName | viewerName/viewName | viewName}
14057 if driverName isn't specified the driver will be shared with active view;
14058 if viewerName isn't specified the viewer will be shared with active view.
14059 -display HostName.DisplayNumber[:ScreenNumber]
14061 Display name will be used within creation of graphic driver, when specified.
14062 -left, -top pixel position of left top corner of the window.
14063 -width, -height width and height of window respectively.
14064 -cloneActive flag to copy camera and dimensions of active view.
14065 -exitOnClose when specified, closing the view will exit application.
14066 -closeOnEscape when specified, view will be closed on pressing Escape.
14067 -virtual create an offscreen window within interactive session
14068 -subview create a subview within another view
14069 -2d_mode when on, view will not react on rotate scene events
14070 -dpiAware override dpi aware hint (Windows platform)
14071 Additional commands for operations with views: vclose, vactivate, vviewlist.
14074 addCmd ("vclose", VClose, /* [vclose] */ R"(
14075 vclose [view_id [keep_context=0|1]]
14076 or vclose ALL - to remove all created views
14077 - removes view(viewer window) defined by its view_id.
14078 - keep_context: by default 0; if 1 and the last view is deleted the current context is not removed.
14079 )" /* [vclose] */);
14081 addCmd ("vactivate", VActivate, /* [vactivate] */ R"(
14082 vactivate view_id [-noUpdate]
14083 Activates view(viewer window) defined by its view_id.
14084 )" /* [vactivate] */);
14086 addCmd ("vviewlist", VViewList, /* [vviewlist] */ R"(
14087 vviewlist [format={tree, long}]=tree
14088 Prints current list of views per viewer and graphic_driver ID shared between viewers
14089 - format: format of result output, if tree the output is a tree view;
14090 otherwise it's a list of full view names.
14091 )" /* [vviewlist] */);
14093 addCmd ("vhelp", VHelp, /* [vhelp] */ R"(
14094 vhelp : display help on the viewer commands and list of hotkeys.
14097 addCmd ("vviewproj", VViewProj, /* [vviewproj] */ R"(
14098 vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]
14099 [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]
14100 Setup view direction
14101 -Yup use Y-up convention instead of Zup (which is default).
14102 +-X+-Y+-Z define direction as combination of DX, DY and DZ;
14103 for example '+Z' will show front of the model,
14104 '-X-Y+Z' will define left axonometric view.
14105 -frame define camera Up and Right directions (regardless Up convention);
14106 for example '+X+Z' will show front of the model with Z-up.
14107 )" /* [vviewproj] */);
14109 addCmd ("vtop", VViewProj, /* [vtop] */ R"(
14110 vtop or <T> : Display top view (+X+Y) in the 3D viewer window.
14113 addCmd ("vbottom", VViewProj, /* [vbottom] */ R"(
14114 vbottom : Display bottom view (+X-Y) in the 3D viewer window.
14115 )" /* [vbottom] */);
14117 addCmd ("vleft", VViewProj, /* [vleft] */ R"(
14118 vleft : Display left view (-Y+Z) in the 3D viewer window.
14121 addCmd ("vright", VViewProj, /* [vright] */ R"(
14122 vright : Display right view (+Y+Z) in the 3D viewer window.
14123 )" /* [vright] */);
14125 addCmd ("vaxo", VViewProj, /* [vaxo] */ R"(
14126 vaxo or <A> : Display axonometric view (+X-Y+Z) in the 3D viewer window.
14129 addCmd ("vfront", VViewProj, /* [vfront] */ R"(
14130 vfront : Display front view (+X+Z) in the 3D viewer window.
14131 )" /* [vfront] */);
14133 addCmd ("vback", VViewProj, /* [vfront] */ R"(
14134 vback : Display back view (-X+Z) in the 3D viewer window.
14137 addCmd ("vpick", VPick, /* [vpick] */ R"(
14138 vpick X Y Z [shape subshape]
14141 addCmd ("vfit", VFit, /* [vfit] */ R"(
14142 vfit or <F> [-selected] [-noupdate]
14143 Fit all / selected. Objects in the view are visualized to occupy the maximum surface.
14146 addCmd ("vfitarea", VFitArea, /* [vfitarea] */ R"(
14147 vfitarea [x1 y1 x2 y2] [x1 y1 z1 x2 y2 z2]
14148 Fit view to show area located between two points
14149 given in world 2D or 3D coordinates.
14150 )" /* [vfitarea] */);
14152 addCmd ("vzfit", VZFit, /* [vzfit] */ R"(
14154 Automatic depth panning.
14155 Matches Z near, Z far view volume planes to the displayed objects.
14156 - "scale" specifies factor to scale computed z range.
14159 addCmd ("vrepaint", VRepaint, /* [vrepaint] */ R"(
14160 vrepaint [-immediate] [-continuous FPS]
14161 Force redraw of active View.
14162 -immediate flag performs redraw of immediate layers only;
14163 -continuous activates/deactivates continuous redraw of active View,
14164 0 means no continuous rendering,
14165 -1 means non-stop redraws,
14166 >0 specifies target framerate.
14167 )" /* [vrepaint] */);
14169 addCmd ("vclear", VClear, /* [vclear] */ R"(
14170 vclear : Remove all the object from the viewer
14171 )" /* [vclear] */);
14173 addCmd ("vbackground", VBackground, /* [vbackground] */ R"(
14174 vbackground [-color Color [-default]]
14175 [-gradient Color1 Color2 [-default]
14176 [-gradientMode {NONE|HORIZONTAL|VERTICAL|DIAG1|DIAG2|CORNER1|CORNER2|CORNER3|ELLIPTICAL}]=VERT]
14177 [-imageFile ImageFile [-imageMode {CENTERED|TILED|STRETCH|NONE}]=CENTERED [-srgb {0|1}]=1]
14178 [-cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]=0]
14179 [-skydome [-sunDir X Y Z=0 1 0] [-cloud Cloudy=0.2] [-time Time=0.0]
14180 [-fog Haze=0.0] [-size SizePx=512]]
14181 [-pbrEnv {ibl|noibl|keep}]
14182 Changes background or some background settings.
14183 -color sets background color
14184 -gradient sets background gradient starting and ending colors
14185 -gradientMode sets gradient fill method
14186 -default sets background default gradient or color
14187 -imageFile sets filename of image used as background
14188 -imageMode sets image fill type
14189 -cubemap sets environment cubemap as background
14190 -invertedz sets inversion of Z axis for background cubemap rendering; FALSE when unspecified
14191 -pbrEnv sets on/off Image Based Lighting (IBL) from background cubemap for PBR
14192 -srgb prefer sRGB texture format when applicable; TRUE when unspecified"
14193 -order defines order of tiles in one image cubemap
14194 TileIndexi defubes an index in range [0, 5] for i tile of one image packed cubemap
14195 (has no effect in case of multi-image cubemaps).
14196 Skydome background parameters (generated cubemap):
14197 -skydome sets procedurally generated skydome as background
14198 -sunDir sets direction to the sun, direction with negative y component represents moon direction (-x, -y, -z)
14199 -cloud sets cloud intensity (0.0 - clear sky, 1.0 - very high cloudy)
14200 -time might be tweaked to slightly change appearance of clouds
14201 -fog sets mist intensity (0.0 - no mist at all, 1.0 - high mist)
14202 -size sets size in pixels of cubemap side
14203 )" /* [vbackground] */);
14205 addCmd ("vsetbg", VBackground, /* [vsetbg] */ R"(
14206 Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.
14207 )" /* [vsetbg] */);
14209 addCmd ("vsetbgmode", VBackground, /* [vsetbgmode] */ R"(
14210 Alias for 'vbackground -imageMode FillType'.
14211 )" /* [vsetbgmode] */);
14213 addCmd ("vsetgradientbg", VBackground, /* [vsetgradientbg] */ R"(
14214 Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.
14215 )" /* [vsetgradientbg] */);
14217 addCmd ("vsetgrbgmode", VBackground, /* [vsetgrbgmode] */ R"(
14218 Alias for 'vbackground -gradientMode FillMethod'.
14219 )" /* [vsetgrbgmode] */);
14221 addCmd ("vsetcolorbg", VBackground, /* [vsetcolorbg] */ R"(
14222 Alias for 'vbackground -color Color'.
14223 )" /* [vsetcolorbg] */);
14225 addCmd ("vsetdefaultbg", VBackground, /* [vsetdefaultbg] */ R"(
14226 Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'
14227 and for 'vbackground -default -color Color'.
14228 )" /* [vsetdefaultbg] */);
14230 addCmd ("vscale", VScale, /* [vscale] */ R"(
14232 )" /* [vscale] */);
14234 addCmd ("vzbufftrihedron", VZBuffTrihedron, /* [vzbufftrihedron] */ R"(
14235 vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]
14236 [-position center|left_lower|left_upper|right_lower|right_upper]
14237 [-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]
14238 [-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]
14239 [-nbfacets value=12] [-colorLabels color=WHITE]
14240 [-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]
14241 Displays a trihedron.
14242 )" /* [vzbufftrihedron] */);
14244 addCmd ("vrotate", VRotate, /* [vrotate] */ R"(
14245 vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]
14246 -mouseStart start rotation according to the mouse position;
14247 -mouseMove continue rotation with angle computed
14248 from last and new mouse position.
14249 )" /* [vrotate] */);
14251 addCmd ("vzoom", VZoom, /* [vzoom] */ R"(
14255 addCmd ("vpan", VPan, /* [vpan] */ R"(
14259 addCmd ("vcolorscale", VColorScale, /* [vcolorscale] */ R"(
14260 vcolorscale name [-noupdate|-update] [-demo]
14261 [-range RangeMin=0 RangeMax=1 NbIntervals=10]
14262 [-font HeightFont=20]
14263 [-logarithmic {on|off}=off] [-reversed {on|off}=off]
14264 [-smoothTransition {on|off}=off]
14265 [-hueRange MinAngle=230 MaxAngle=0]
14266 [-colorRange MinColor=BLUE1 MaxColor=RED]
14267 [-textPos {left|right|center|none}=right]
14268 [-labelAtBorder {on|off}=on]
14269 [-colors Color1 Color2 ...] [-color Index Color]
14270 [-labels Label1 Label2 ...] [-label Index Label]
14271 [-freeLabels NbOfLabels Label1 Label2 ...]
14272 [-xy Left=0 Bottom=0]
14273 [-uniform lightness hue_from hue_to]
14274 -demo display a color scale with demonstration values
14275 -colors set colors for all intervals
14276 -color set color for specific interval
14277 -uniform generate colors with the same lightness
14278 -textpos horizontal label position relative to color scale bar
14279 -labelAtBorder vertical label position relative to color interval;
14280 at border means the value inbetween neighbor intervals,
14281 at center means the center value within current interval
14282 -labels set labels for all intervals
14283 -freeLabels same as -labels but does not require
14284 matching the number of intervals
14285 -label set label for specific interval
14287 -reversed setup smooth color transition between intervals
14288 -smoothTransition swap colorscale direction
14289 -hueRange set hue angles corresponding to minimum and maximum values
14290 )" /* [vcolorscale] */);
14292 addCmd ("vgraduatedtrihedron", VGraduatedTrihedron, /* [vgraduatedtrihedron] */ R"(
14293 vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]
14294 [-namefont Name] [-valuesfont Name]
14295 [-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]
14296 [-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]
14297 [-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]
14298 [-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]
14299 [-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]
14300 [-xcolor Color] [-ycolor Color] [-zcolor Color]
14301 [-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]
14302 [-xticks Number] [-yticks Number] [-zticks Number]
14303 [-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]
14304 [-drawgrid on/off] [-drawaxes on/off]
14305 Display or erase graduated trihedron
14306 - xname, yname, zname - names of axes, default: X, Y, Z
14307 - namefont - font of axes names. Default: Arial
14308 - xnameoffset, ynameoffset, znameoffset - offset of name
14309 from values or tickmarks or axis. Default: 30
14310 - xnamecolor, ynamecolor, znamecolor - colors of axes names
14311 - xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values
14312 from tickmarks or axis. Default: 10
14313 - valuesfont - font of axes values. Default: Arial
14314 - xcolor, ycolor, zcolor - color of axis and values
14315 - xticks, yticks, xzicks - number of tickmark on axes. Default: 5
14316 - xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10
14317 )" /* [vgraduatedtrihedron] */);
14319 addCmd ("vtile", VTile, /* [vtile] */ R"(
14320 vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]
14321 Setup view to draw a tile (a part of virtual bigger viewport).
14322 -totalSize the size of virtual bigger viewport
14323 -tileSize tile size (the view size will be used if omitted)
14324 -lowerLeft tile offset as lower left corner
14325 -upperLeft tile offset as upper left corner
14328 addCmd ("vzlayer", VZLayer, /* [vzlayer] */ R"(
14330 [-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]
14331 [-origin X Y Z] [-cullDist Distance] [-cullSize Size]
14332 [-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]
14333 [-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]
14334 ZLayer list management
14335 -add add new z layer to viewer and print its id
14336 -insertBefore add new z layer and insert it before existing one
14337 -insertAfter add new z layer and insert it after existing one
14338 -delete delete z layer
14339 -get print sequence of z layers
14340 -settings print status of z layer settings
14341 -disable disables given setting
14342 -enable enables given setting
14343 )" /* [vzlayer] */);
14345 addCmd ("vlayerline", VLayerLine, /* [vlayerline] */ R"(
14346 vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]
14347 )" /* [vlayerline] */);
14349 addCmd ("vgrid", VGrid, /* [vgrid] */ R"(
14350 vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]
14351 [-step X Y] [-size DX DY]
14352 [-step StepRadius NbDivisions] [-radius Radius]
14355 addCmd ("vpriviledgedplane", VPriviledgedPlane, /* [vpriviledgedplane] */ R"(
14356 vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]
14357 Sets or prints viewer's priviledged plane geometry:
14358 Ox, Oy, Oz - plane origin;
14359 Nx, Ny, Nz - plane normal direction;
14360 Xx, Xy, Xz - plane x-reference axis direction.
14361 )" /* [vpriviledgedplane] */);
14363 addCmd ("vconvert", VConvert, /* [vconvert] */ R"(
14364 vconvert v [Mode={window|view}]
14365 vconvert x y [Mode={window|view|grid|ray}]
14366 vconvert x y z [Mode={window|grid}]
14367 Convert the given coordinates to window/view/model space:
14368 - window - convert to window coordinates, pixels;
14369 - view - convert to view projection plane;
14370 - grid - convert to model coordinates, given on grid;
14371 - ray - convert projection ray to model coordinates.
14372 )" /* [vconvert] */);
14374 addCmd ("vfps", VFps, /* [vfps] */ R"(
14375 vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view.
14378 addCmd ("vstereo", VStereo, /* [vstereo] */ R"(
14379 vstereo [0|1] [-mode Mode] [-reverse {0|1}]
14380 [-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]
14381 [-anaglyph Filter] [-smoothInterlacing]
14382 Control stereo output mode. Available modes for -mode:
14383 quadBuffer OpenGL QuadBuffer stereo;
14384 requires driver support;
14385 should be called BEFORE vinit!
14386 anaglyph Anaglyph glasses, filters for -anaglyph:
14387 redCyan, redCyanSimple, yellowBlue, yellowBlueSimple, greenMagentaSimple.
14388 rowInterlaced row-interlaced display
14389 smooth smooth interlaced output for better text readability
14390 columnInterlaced column-interlaced display
14391 chessBoard chess-board output
14392 sideBySide horizontal pair
14393 overUnder vertical pair
14394 openVR OpenVR (HMD), extra options:
14395 -mirrorComposer flag to mirror VR frame in the window (debug);
14396 -unitFactor specifies meters scale factor for mapping VR input.
14397 )" /* [vstereo] */);
14399 addCmd ("vmemgpu", VMemGpu, /* [vmemgpu] */ R"(
14400 vmemgpu [f]: print system-dependent GPU memory information if available;
14401 with f option returns free memory in bytes.
14402 )" /* [vmemgpu] */);
14404 addCmd ("vreadpixel", VReadPixel, /* [vreadpixel] */ R"(
14405 vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]
14406 Read pixel value for active view.
14407 )" /* [vreadpixel] */);
14409 addCmd ("diffimage", VDiffImage, /* [diffimage] */ R"(
14410 diffimage imageFile1 imageFile2 [diffImageFile]
14411 [-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]
14412 [-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]
14413 Compare two images by content and generate difference image.
14414 When -exitOnClose is specified, closing the view will exit application.
14415 When -closeOnEscape is specified, view will be closed on pressing Escape.
14416 )" /* [diffimage] */);
14418 addCmd ("vselect", VSelect, /* [vselect] */ R"(
14419 vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1]
14420 [-replace|-replaceextra|-xor|-add|-remove]
14421 Emulate different types of selection:
14422 1) Single click selection.
14423 2) Selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2).
14424 3) Selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn).
14425 4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.
14426 If the flag is set to 1, both sensitives that were included completely
14427 and overlapped partially by defined rectangle or polygon will be detected,
14428 otherwise algorithm will chose only fully included sensitives.
14429 Default behavior is to detect only full inclusion
14430 (partial inclusion - overlap - is not allowed by default).
14431 5) Selection scheme replace, replaceextra, xor, add or remove (replace by default).
14432 )" /* [vselect] */);
14434 addCmd ("vmoveto", VMoveTo, /* [vmoveto] */ R"(
14435 vmoveto [x y] [-reset]
14436 Emulate cursor movement to pixel position (x,y).
14437 -reset resets current highlighting.
14438 )" /* [vmoveto] */);
14440 addCmd ("vselaxis", VSelectByAxis, /* [vselaxis] */ R"(
14441 vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
14442 Provides intersection by given axis and print result intersection points.
14443 -onlyTop switches On/Off mode to find only top point or all;
14444 -display Name displays intersecting axis and result intersection points for debug goals;
14445 -showNormal adds displaying of normal in intersection point or not.
14446 )" /* [vselaxis] */);
14448 addCmd ("vviewparams", VViewParams, /* [vviewparams] */ R"(
14449 vviewparams [-args] [-scale [s]]
14450 [-eye [x y z]] [-at [x y z]] [-up [x y z]]
14451 [-proj [x y z]] [-center x y] [-size sx]
14452 Manage current view parameters (camera orientation) or prints all
14453 current values when called without argument.
14454 -scale [s] prints or sets viewport relative scale
14455 -eye [x y z] prints or sets eye location
14456 -at [x y z] prints or sets center of look
14457 -up [x y z] prints or sets direction of up vector
14458 -proj [x y z] prints or sets direction of look
14459 -center x y sets location of center of the screen in pixels
14460 -size [sx] prints viewport projection width and height sizes
14461 or changes the size of its maximum dimension
14462 -args prints vviewparams arguments for restoring current view
14463 )" /* [vviewparams] */);
14465 addCmd ("v2dmode", V2DMode, /* [v2dmode] */ R"(
14466 v2dmode [-name viewName] [-mode {-on|-off}=-on]
14467 name - name of existing view, if not defined, the active view is changed;
14468 mode - switches On/Off rotation mode.
14469 Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:
14470 - rotation of the view by 3rd mouse button with Ctrl active
14471 - set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right
14472 View camera position might be changed only by commands.
14473 )" /* [v2dmode] */);
14475 addCmd ("vanimation", VAnimation, /* [vanimation] */ R"(
14477 )" /* [vanimation] */);
14479 addCmd ("vanim", VAnimation, /* [vanim] */ R"(
14480 List existing animations:
14483 Animation playback:
14484 vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]] [-speed Coeff]
14485 [-freeLook] [-noPauseOnClick] [-lockLoop] [-elapsedTime]
14487 -speed playback speed (1.0 is normal speed)
14488 -freeLook skip camera animations
14489 -noPauseOnClick do not pause animation on mouse click
14490 -lockLoop disable any interactions
14491 -elapsedTime prints elapsed time in seconds"
14493 Animation definition:
14494 vanim Name/sub/name [-clear] [-delete]
14495 [-start TimeSec] [-duration TimeSec] [-end TimeSec]
14497 Animation name defined in path-style (anim/name or anim.name)
14498 specifies nested animations.
14499 There is no syntax to explicitly add new animation,
14500 and all non-existing animations within the name will be
14501 implicitly created on first use (including parents).
14503 Each animation might define the SINGLE action (see below),
14504 like camera transition, object transformation or custom callback.
14505 Child animations can be used for defining concurrent actions.
14508 vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]
14509 [-at1 X Y Z] [-at2 X Y Z]
14510 [-up1 X Y Z] [-up2 X Y Z]
14511 [-scale1 Scale] [-scale2 Scale]
14512 -eyeX camera Eye positions pair (start and end)
14513 -atX camera Center positions pair
14514 -upX camera Up directions pair
14515 -scaleX camera Scale factors pair
14518 vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]
14519 [-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]
14520 [-scale1 Scale] [-scale2 Scale]
14521 -locX object Location points pair (translation)
14522 -rotX object Orientations pair (quaternions)
14523 -scaleX object Scale factors pair (quaternions)
14525 vanim name -object [-axis OX OY OZ DX DY DZ] [-ang1 A] [-ang2 A]
14526 -axis rotation axis
14527 -ang1 start rotation angle in degrees
14528 -ang2 end rotation angle in degrees
14531 vanim name -invoke "Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN"
14533 %Pts overall animation presentation timestamp
14534 %LocalPts local animation timestamp
14535 %Normalized local animation normalized value in range 0..1
14538 vanim name -record FileName [Width Height] [-fps FrameRate=24]
14539 [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]
14540 [-crf Value] [-preset Preset]
14541 -fps video framerate
14542 -format file format, container (matroska, etc.)
14543 -vcodec video codec identifier (ffv1, mjpeg, etc.)
14544 -pix_fmt image pixel format (yuv420p, rgb24, etc.)
14545 -crf constant rate factor (specific to codec)
14546 -preset codec parameters preset (specific to codec)
14549 addCmd ("vchangeselected", VChangeSelected, /* [vchangeselected] */ R"(
14550 vchangeselected shape : Add shape to selection or remove one from it.
14551 )" /* [vchangeselected] */);
14553 addCmd ("vnbselected", VNbSelected, /* [vnbselected] */ R"(
14554 vnbselected : Returns number of selected objects in the interactive context.
14555 )" /* [vnbselected] */);
14557 addCmd ("vcamera", VCamera, /* [vcamera] */ R"(
14558 vcamera [PrsName] [-ortho] [-projtype]
14560 [-fovy [Angle]] [-distance [Distance]]
14561 [-stereo] [-leftEye] [-rightEye]
14562 [-iod [Distance]] [-iodType [absolute|relative]]
14563 [-zfocus [Value]] [-zfocusType [absolute|relative]]
14564 [-fov2d [Angle]] [-lockZup {0|1}]
14565 [-rotationMode {active|pick|pickCenter|cameraAt|scene}]
14566 [-navigationMode {orbit|walk|flight}]
14567 [-xrPose base|head=base]
14568 Manages camera parameters.
14569 Displays frustum when presentation name PrsName is specified.
14570 Prints current value when option called without argument.
14572 Orthographic camera:
14573 -ortho activate orthographic projection.
14575 Perspective camera:
14576 -persp activate perspective projection (mono);
14577 -fovy field of view in y axis, in degrees;
14578 -fov2d field of view limit for 2d on-screen elements;
14579 -distance distance of eye from camera center;
14580 -lockZup lock Z up (turntable mode);
14581 -rotationMode rotation mode (gravity point);
14582 -navigationMode navigation mode.
14584 Stereoscopic camera:
14585 -stereo perspective projection (stereo);
14586 -leftEye perspective projection (left eye);
14587 -rightEye perspective projection (right eye);
14588 -iod intraocular distance value;
14589 -iodType distance type, absolute or relative;
14590 -zfocus stereographic focus value;
14591 -zfocusType focus type, absolute or relative.
14592 )" /* [vcamera] */);
14594 addCmd ("vautozfit", VAutoZFit, /* [vautozfit] */ R"(
14595 vautozfit [on={1|0}] [scale]
14596 Prints or changes parameters of automatic z-fit mode:
14597 "on" - turns automatic z-fit on or off;
14598 "scale" - specifies factor to scale computed z range.
14599 )" /* [vautozfit] */);
14601 addCmd ("vzrange", VZRange, /* [vzrange] */ R"(
14602 vzrange [znear] [zfar]
14603 Applies provided znear/zfar to view or prints current values.
14604 )" /* [vzrange] */);
14606 addCmd ("vsetviewsize", VSetViewSize, /* [vsetviewsize] */ R"(
14608 )" /* [vsetviewsize] */);
14610 addCmd ("vmoveview", VMoveView, /* [vmoveview] */ R"(
14611 vmoveview Dx Dy Dz [Start = 1|0]
14612 )" /* [vmoveview] */);
14614 addCmd ("vtranslateview", VTranslateView, /* [vtranslateview] */ R"(
14615 vtranslateview Dx Dy Dz [Start = 1|0)]
14616 )" /* [vtranslateview] */);
14618 addCmd ("vturnview", VTurnView, /* [vturnview] */ R"(
14619 vturnview Ax Ay Az [Start = 1|0]
14620 )" /* [vturnview] */);
14622 addCmd ("vtextureenv", VTextureEnv, /* [vtextureenv] */ R"(
14623 vtextureenv {on|off} {image_file}
14624 [{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} ss st ts tt rot]
14625 Enables or disables environment mapping in the 3D view, loading the texture from the given standard
14626 or user-defined file and optionally applying texture mapping parameters.
14627 ss, st - scale factors for s and t texture coordinates;
14628 ts, tt - translation for s and t texture coordinates;
14629 rot - texture rotation angle in degrees.
14630 )" /* [vtextureenv] */);
14632 addCmd ("vhlr", VHLR, /* [vhlr] */ R"(
14633 vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]
14634 Hidden Line Removal algorithm.
14635 -showHidden if set ON, hidden lines are drawn as dotted ones;
14636 -algoType type of HLR algorithm:
14637 'algo' - exact HLR algorithm is applied;
14638 'polyAlgo' - polygonal HLR algorithm is applied.
14641 addCmd ("vhlrtype", VHLRType, /* [vhlrtype] */ R"(
14642 vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]
14643 Changes the type of HLR algorithm using for shapes:
14644 'algo' - exact HLR algorithm is applied;
14645 'polyAlgo' - polygonal HLR algorithm is applied.
14646 If shapes are not given - option is applied to all shapes in the view.
14647 )" /* [vhlrtype] */);
14649 addCmd ("vclipplane", VClipPlane, /* [vclipplane] */ R"(
14650 vclipplane planeName [{0|1}]
14651 [-equation1 A B C D]
14652 [-equation2 A B C D]
14653 [-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]
14654 [-set|-unset|-setOverrideGlobal [objects|views]]
14657 [-color R G B] [-transparency Value] [-hatch {on|off|ID}]
14658 [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]
14660 [-useObjMaterial {0|1}] [-useObjTexture {0|1}]
14661 [-useObjShader {0|1}]
14663 Clipping planes management:
14664 -maxPlanes print plane limit for view;
14665 -delete delete plane with given name;
14666 {off|on|0|1} turn clipping on/off;
14667 -set|-unset set/unset plane for Object or View list;
14668 applied to active View when list is omitted;
14669 -equation A B C D change plane equation;
14670 -clone SourcePlane NewPlane clone the plane definition.
14673 -capping {off|on|0|1} turn capping on/off;
14674 -color R G B set capping color;
14675 -transparency Value set capping transparency 0..1;
14676 -texName Texture set capping texture;
14677 -texScale SX SY set capping tex scale;
14678 -texOrigin TX TY set capping tex origin;
14679 -texRotate Angle set capping tex rotation;
14680 -hatch {on|off|ID} set capping hatching mask;
14681 -useObjMaterial {off|on|0|1} use material of clipped object;
14682 -useObjTexture {off|on|0|1} use texture of clipped object;
14683 -useObjShader {off|on|0|1} use shader program of object.
14684 )" /* [vclipplane] */);
14686 addCmd ("vdefaults", VDefaults, /* [vdefaults] */ R"(
14687 vdefaults [-absDefl value] [-devCoeff value] [-angDefl value]
14688 [-autoTriang {off/on | 0/1}]
14689 )" /* [vdefaults] */);
14691 addCmd ("vlight", VLight, /* [vlight] */ R"(
14692 vlight [lightName] [-noupdate]
14693 [-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]
14694 [-type {ambient|directional|spotlight|positional}] [-name value]
14695 [-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]
14696 [-headlight 0|1] [-castShadows 0|1]
14697 [-range value] [-constAttenuation value] [-linearAttenuation value]
14698 [-spotExponent value] [-spotAngle angleDeg]
14699 [-smoothAngle value] [-smoothRadius value]
14700 [-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]
14703 Command manages light sources. Without arguments shows list of lights.
14704 Arguments affecting the list of defined/active lights:
14705 -clear remove all light sources;
14706 -defaults defines two standard light sources;
14707 -reset resets light source parameters to default values;
14708 -type sets type of light source;
14709 -name sets new name to light source;
14710 -global assigns light source to all views (default state);
14711 -local assigns light source to active view;
14712 -zlayer assigns light source to specified Z-Layer.
14714 Ambient light parameters:
14715 -color sets (normalized) light color;
14716 -intensity sets intensity of light source, 1.0 by default;
14717 affects also environment cubemap intensity.
14719 Point light parameters:
14720 -color sets (normalized) light color;
14721 -intensity sets PBR intensity;
14722 -range sets clamping distance;
14723 -constAtten (obsolete) sets constant attenuation factor;
14724 -linearAtten (obsolete) sets linear attenuation factor;
14725 -smoothRadius sets PBR smoothing radius.
14727 Directional light parameters:
14728 -color sets (normalized) light color;
14729 -intensity sets PBR intensity;
14730 -direction sets direction;
14731 -headlight sets headlight flag;
14732 -castShadows enables/disables shadow casting;
14733 -smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range.
14735 Spot light parameters:
14736 -color sets (normalized) light color;
14737 -intensity sets PBR intensity;
14738 -range sets clamping distance;
14739 -position sets position;
14740 -direction sets direction;
14741 -spotAngle sets spotlight angle;
14742 -spotExp sets spotlight exponenta;
14743 -headlight sets headlight flag;
14744 -castShadows enables/disables shadow casting;
14745 -constAtten (obsolete) sets constant attenuation factor;
14746 -linearAtten (obsolete) sets linear attenuation factor.
14748 Light presentation parameters:
14749 -display adds light source presentation;
14750 -showName shows/hides the name of light source; 1 by default;
14751 -showRange shows/hides the range of spot/positional light source; 1 by default;
14752 -prsZoomable makes light presentation zoomable/non-zoomable;
14753 -prsDraggable makes light presentation draggable/non-draggable;
14754 -prsSize sets light presentation size;
14755 -arcSize sets arc presentation size(in pixels)
14756 for rotation directional light source; 25 by default.
14759 vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED
14760 vlight redlight -delete
14761 )" /* [vlight] */);
14763 addCmd ("vpbrenv", VPBREnvironment, /* [vpbrenv] */ R"(
14764 vpbrenv -clear|-generate
14765 Clears or generates PBR environment map of active view.
14766 -clear clears PBR environment (fills by white color);
14767 -generate generates PBR environment from current background cubemap.
14768 )" /* [vpbrenv] */);
14770 addCmd ("vraytrace", VRenderParams, /* [vraytrace] */ R"(
14771 vraytrace [0|1] : Turns on/off ray-tracing renderer.
14772 'vraytrace 0' alias for 'vrenderparams -raster'.
14773 'vraytrace 1' alias for 'vrenderparams -rayTrace'.
14774 )" /* [vraytrace] */);
14776 addCmd ("vrenderparams", VRenderParams, /* [vrenderparams] */ R"(
14777 Manages rendering parameters, affecting visual appearance, quality and performance.
14778 Should be applied taking into account GPU hardware capabilities and performance.
14781 vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]
14782 [-msaa 0..8=0] [-rendScale scale=1]
14783 [-resolution value=72] [-fontHinting {off|normal|light}=off]
14784 [-fontAutoHinting {auto|force|disallow}=auto]
14785 [-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]
14786 [-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]
14787 [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]
14788 [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]
14789 [-sync {default|views}] [-reset]
14790 -raster Disables GPU ray-tracing.
14791 -shadingModel Controls shading model.
14792 -msaa Specifies number of samples for MSAA.
14793 -rendScale Rendering resolution scale factor (supersampling, alternative to MSAA).
14794 -resolution Sets new pixels density (PPI) used as text scaling factor.
14795 -fontHinting Enables/disables font hinting for better readability on low-resolution screens.
14796 -fontAutoHinting Manages font autohinting.
14797 -lineFeather Sets line feather factor while displaying mesh edges.
14798 -alphaToCoverage Enables/disables alpha to coverage (needs MSAA).
14799 -oit Enables/disables order-independent transparency (OIT) rendering;
14800 off unordered transparency (but opaque objects implicitly draw first);
14801 weighted weight OIT is managed by depth weight factor 0.0..1.0;
14802 peeling depth peeling OIT is managed by number of peeling layers.
14803 -shadows Enables/disables shadows rendering.
14804 -shadowMapResolution Shadow texture map resolution.
14805 -shadowMapBias Shadow map bias.
14806 -depthPrePass Enables/disables depth pre-pass.
14807 -frustumCulling Enables/disables objects frustum clipping or
14808 sets state to check structures culled previously.
14809 -sync Sets active View parameters as Viewer defaults / to other Views.
14810 -reset Resets active View parameters to Viewer defaults.
14812 Diagnostic output (on-screen overlay):
14813 vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points
14814 |gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]
14815 [-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]
14816 -perfCounters Show/hide performance counters (flags can be combined).
14817 -perfUpdateInterval Performance counters update interval.
14818 -perfChart Show frame timers chart limited by specified number of frames.
14819 -perfChartMax Maximum time in seconds with the chart.
14821 Ray-Tracing options:
14822 vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]
14823 [-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]
14824 [-gi {on|off}=off] [-brng {on|off}=off]
14825 [-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]
14826 [-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]
14827 [-maxRad {value>0}=30.0]
14828 [-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]
14829 [-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]
14830 -rayTrace Enables GPU ray-tracing.
14831 -rayDepth Defines maximum ray-tracing depth.
14832 -reflections Enables/disables specular reflections.
14833 -fsaa Enables/disables adaptive anti-aliasing.
14834 -gleam Enables/disables transparency shadow effects.
14835 -gi Enables/disables global illumination effects (Path-Tracing).
14836 -env Enables/disables environment map background.
14837 -ignoreNormalMap Enables/disables normal map ignoring during path tracing.
14838 -twoSide Enables/disables two-sided BSDF models (PT mode).
14839 -iss Enables/disables adaptive screen sampling (PT mode).
14840 -maxRad Value used for clamping radiance estimation (PT mode).
14841 -tileSize Specifies size of screen tiles in ISS mode (32 by default).
14842 -nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default).
14843 -aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF).
14844 -focal Focal distance of perspective camera for depth-of-field effect.
14845 -exposure Exposure value for tone mapping (0.0 value disables the effect).
14846 -whitePoint White point value for filmic tone mapping.
14847 -toneMapping Tone mapping mode (disabled, filmic).
14849 PBR environment baking parameters (advanced/debug):
14850 vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]
14851 [-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]
14852 -pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size).
14853 -pbrEnvSMLN Controls number of mipmap levels used in specular IBL map.
14854 -pbrEnvBDSN Controls number of samples in Monte-Carlo integration during
14855 diffuse IBL map's sherical harmonics calculation.
14856 -pbrEnvBSSN Controls maximum number of samples per mipmap level
14857 in Monte-Carlo integration during specular IBL maps generation.
14858 -pbrEnvBP Controls strength of samples number reducing
14859 during specular IBL maps generation (1 disables reducing).
14862 vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]
14863 -issd Shows screen sampling distribution in ISS mode.
14864 -rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging).
14865 -brng Enables/disables blocked RNG (fast coherent PT).
14866 )" /* [vrenderparams] */);
14868 addCmd ("vstatprofiler", VStatProfiler, /* [vstatprofiler] */ R"(
14869 vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups
14870 |allArrays|fillArrays|lineArrays|pointArrays|textArrays
14871 |triangles|points|geomMem|textureMem|frameMem
14872 |elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage
14873 |cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]
14875 Prints rendering statistics for specified counters or for all when unspecified.
14876 Set '-noredraw' flag to avoid additional redraw call and use already collected values.
14877 )" /* [vstatprofiler] */);
14879 addCmd ("vplace", VPlace, /* [vplace] */ R"(
14880 vplace dx dy : Places the point (in pixels) at the center of the window
14881 )" /* [vplace] */);
14883 addCmd ("vxrotate", VXRotate, /* [vxrotate] */ R"(
14885 )" /* [vxrotate] */);
14887 addCmd ("vmanipulator", VManipulator, /* [vmanipulator] */ R"(
14888 vmanipulator Name [-attach AISObject | -detach | ...]
14889 Tool to create and manage AIS manipulators.
14891 '-attach AISObject' attach manipulator to AISObject
14892 '-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching
14893 '-adjustSize {0|1}' adjust size when attaching
14894 '-enableModes {0|1}' enable modes when attaching
14895 '-view {active | [name of view]}' display manipulator only in defined view,
14896 by default it is displayed in all views of the current viewer
14897 '-detach' detach manipulator
14898 '-startTransform mouse_x mouse_y' - invoke start of transformation
14899 '-transform mouse_x mouse_y' - invoke transformation
14900 '-stopTransform [abort]' - invoke stop of transformation
14901 '-move x y z' - move attached object
14902 '-rotate x y z dx dy dz angle' - rotate attached object
14903 '-scale factor' - scale attached object
14904 '-autoActivate {0|1}' - set activation on detection
14905 '-followTranslation {0|1}' - set following translation transform
14906 '-followRotation {0|1}' - set following rotation transform
14907 '-followDragging {0|1}' - set following dragging transform
14908 '-gap value' - set gap between sub-parts
14909 '-part axis mode {0|1}' - set visual part
14910 '-parts axis mode {0|1}' - set visual part
14911 '-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator
14912 '-size value' - set size of manipulator
14913 '-zoomable {0|1}' - set zoom persistence
14914 )" /* [vmanipulator] */);
14916 addCmd ("vselprops", VSelectionProperties, /* [vselprops] */ R"(
14917 vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]
14918 Customizes selection and dynamic highlight parameters for the whole interactive context:
14919 -autoActivate {0|1} disables|enables default computation
14920 and activation of global selection mode
14921 -autoHighlight {0|1} disables|enables automatic highlighting in 3D Viewer
14922 -highlightSelected {0|1} disables|enables highlighting of detected object in selected state
14923 -pickStrategy {first|topmost} : defines picking strategy
14924 'first' to pick first acceptable (default)
14925 'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)
14926 -pixTol value sets up pixel tolerance
14927 -depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth
14928 -depthTol {sensfactor} use sensitive factor for sorting results by depth
14929 -preferClosest {0|1} sets if depth should take precedence over priority while sorting results
14930 -dispMode dispMode sets display mode for highlighting
14931 -layer ZLayer sets ZLayer for highlighting
14932 -color {name|r g b} sets highlight color
14933 -transp value sets transparency coefficient for highlight
14934 -material material sets highlight material
14935 -print prints current state of all mentioned parameters
14936 )" /* [vselprops] */);
14938 addCmd ("vhighlightselected", VSelectionProperties, /* [vhighlightselected] */ R"(
14939 vhighlightselected [0|1] : alias for vselprops -highlightSelected.
14940 )" /* [vhighlightselected] */);
14942 addCmd ("vseldump", VDumpSelectionImage, /* [vseldump] */ R"(
14943 vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|entityType|surfNormal}=depth
14944 -pickedIndex Index=1
14945 [-xrPose base|head=base]
14946 Generate an image based on detection results:
14947 depth normalized depth values
14948 unnormDepth unnormalized depth values
14949 object color of detected object
14950 owner color of detected owner
14951 selMode color of selection mode
14952 entity color of detected entity
14953 entityType color of detected entity type
14954 surfNormal normal direction values
14955 )" /* [vseldump] */);
14957 addCmd ("vviewcube", VViewCube, /* [vviewcube] */ R"(
14959 Displays interactive view manipulation object. Options:
14960 -reset reset geometric and visual attributes
14961 -size Size adapted size of View Cube
14962 -boxSize Size box size
14963 -axes {0|1} show/hide axes (trihedron)
14964 -edges {0|1} show/hide edges of View Cube
14965 -vertices {0|1} show/hide vertices of View Cube
14966 -Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation
14967 -color Color color of View Cube
14968 -boxColor Color box color
14969 -boxSideColor Color box sides color
14970 -boxEdgeColor Color box edges color
14971 -boxCornerColor Color box corner color
14972 -textColor Color color of side text of view cube
14973 -innerColor Color inner box color
14974 -transparency Value transparency of object within [0, 1] range
14975 -boxTransparency Value transparency of box within [0, 1] range
14976 -xAxisTextColor Color color of X axis label
14977 -yAxisTextColor Color color of Y axis label
14978 -zAxisTextColor Color color of Z axis label
14979 -font Name font name
14980 -fontHeight Value font height
14981 -boxFacetExtension Value box facet extension
14982 -boxEdgeGap Value gap between box edges and box sides
14983 -boxEdgeMinSize Value minimal box edge size
14984 -boxCornerMinSize Value minimal box corner size
14985 -axesPadding Value padding between box and arrows
14986 -roundRadius Value relative radius of corners of sides within [0.0, 0.5] range
14987 -axesRadius Value radius of axes of the trihedron
14988 -axesConeRadius Value radius of the cone (arrow) of the trihedron
14989 -axesSphereRadius Value radius of the sphere (central point) of trihedron
14990 -fixedAnimation {0|1} uninterruptible animation loop
14991 -duration Seconds animation duration in seconds
14992 -orthoPers force orthographic projection persistence.
14993 )" /* [vviewcube] */);
14995 addCmd ("vcolorconvert", VColorConvert, /* [vcolorconvert] */ R"(
14996 vcolorconvert [-from {sRGB|HLS|Lab|Lch|RGB}]=RGB [-to {sRGB|HLS|Lab|Lch|RGB|hex|name}]=RGB C1 C2 C2
14997 To convert color from specified color space to linear RGB:
14998 vcolorconvert -from {sRGB|HLS|Lab|Lch|RGB} C1 C2 C2
14999 To convert linear RGB color to specified color space:
15000 vcolorconvert -to {sRGB|HLS|Lab|Lch|RGB|hex|name} R G B
15001 )" /* [vcolorconvert] */);
15003 addCmd ("vcolordiff", VColorDiff, /* [vcolordiff] */ R"(
15004 vcolordiff R1 G1 B1 R2 G2 B2 : returns CIEDE2000 color difference between two RGB colors.
15005 )" /* [vcolordiff] */);
15007 addCmd ("vselbvhbuild", VSelBvhBuild, /* [vselbvhbuild] */ R"(
15008 vselbvhbuild [{0|1}] [-nbThreads value] [-wait]
15009 Turns on/off prebuilding of BVH within background thread(s).
15010 -nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1);
15011 -wait waits for building all of BVH.
15012 )" /* [vselbvhbuild] */);
15014 addCmd ("vchangemousegesture", VChangeMouseGesture, /* [vchangemousegesture] */ R"(
15015 vchangemousegesture -button {none|left|middle|right}=left
15016 -gesture {none|selectRectangle|selectLasso|zoom|zoomWindow|pan|rotateOrbit|rotateView|drag}=rotateOrbit
15017 Changes the gesture for the mouse button.
15018 -button the mouse button;
15019 -gesture the new gesture for the button.
15020 )" /* [vchangemousegesture] */);