mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
Fixed problem of usage of objects dragging during zoom and pan Added new draw command to change gesture for muse buttons Added test
15006 lines
479 KiB
C++
15006 lines
479 KiB
C++
// Created on: 1998-09-01
|
|
// Created by: Robert COUBLANC
|
|
// Copyright (c) 1998-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#if defined(_WIN32)
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <ViewerTest.hxx>
|
|
|
|
#include <AIS_AnimationAxisRotation.hxx>
|
|
#include <AIS_AnimationCamera.hxx>
|
|
#include <AIS_AnimationObject.hxx>
|
|
#include <AIS_Axis.hxx>
|
|
#include <AIS_CameraFrustum.hxx>
|
|
#include <AIS_ColorScale.hxx>
|
|
#include <AIS_InteractiveContext.hxx>
|
|
#include <AIS_LightSource.hxx>
|
|
#include <AIS_ListOfInteractive.hxx>
|
|
#include <AIS_Manipulator.hxx>
|
|
#include <AIS_ViewCube.hxx>
|
|
#include <AIS_Shape.hxx>
|
|
#include <AIS_Point.hxx>
|
|
#include <Aspect_DisplayConnection.hxx>
|
|
#include <Aspect_Grid.hxx>
|
|
#include <Aspect_TypeOfLine.hxx>
|
|
#include <Draw_Appli.hxx>
|
|
#include <Draw_Interpretor.hxx>
|
|
#include <Draw_ProgressIndicator.hxx>
|
|
#include <gp_Dir.hxx>
|
|
#include <gp_Pln.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <Geom_Axis2Placement.hxx>
|
|
#include <Geom_CartesianPoint.hxx>
|
|
#include <Graphic3d_ArrayOfPolylines.hxx>
|
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
|
#include <Graphic3d_ClipPlane.hxx>
|
|
#include <Graphic3d_CubeMapPacked.hxx>
|
|
#include <Graphic3d_CubeMapSeparate.hxx>
|
|
#include <Graphic3d_GraduatedTrihedron.hxx>
|
|
#include <Graphic3d_GraphicDriver.hxx>
|
|
#include <Graphic3d_GraphicDriverFactory.hxx>
|
|
#include <Graphic3d_NameOfTextureEnv.hxx>
|
|
#include <Graphic3d_Texture2D.hxx>
|
|
#include <Graphic3d_TextureEnv.hxx>
|
|
#include <Graphic3d_TextureParams.hxx>
|
|
#include <Graphic3d_TypeOfTextureFilter.hxx>
|
|
#include <Image_AlienPixMap.hxx>
|
|
#include <Image_Diff.hxx>
|
|
#include <Image_VideoRecorder.hxx>
|
|
#include <Message.hxx>
|
|
#include <Message_ProgressScope.hxx>
|
|
#include <NCollection_DataMap.hxx>
|
|
#include <NCollection_List.hxx>
|
|
#include <NCollection_LocalArray.hxx>
|
|
#include <OSD_Parallel.hxx>
|
|
#include <OSD_Timer.hxx>
|
|
#include <Prs3d_ShadingAspect.hxx>
|
|
#include <Prs3d_DatumAspect.hxx>
|
|
#include <Prs3d_Drawer.hxx>
|
|
#include <Prs3d_LineAspect.hxx>
|
|
#include <Prs3d_Text.hxx>
|
|
#include <Select3D_SensitivePrimitiveArray.hxx>
|
|
#include <TColStd_HSequenceOfAsciiString.hxx>
|
|
#include <TColStd_SequenceOfInteger.hxx>
|
|
#include <TColStd_HSequenceOfReal.hxx>
|
|
#include <ViewerTest_AutoUpdater.hxx>
|
|
#include <ViewerTest_ContinuousRedrawer.hxx>
|
|
#include <ViewerTest_EventManager.hxx>
|
|
#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
|
|
#include <ViewerTest_CmdParser.hxx>
|
|
#include <ViewerTest_V3dView.hxx>
|
|
#include <V3d_AmbientLight.hxx>
|
|
#include <V3d_DirectionalLight.hxx>
|
|
#include <V3d_PositionalLight.hxx>
|
|
#include <V3d_SpotLight.hxx>
|
|
#include <V3d_Trihedron.hxx>
|
|
#include <V3d_Viewer.hxx>
|
|
#include <UnitsAPI.hxx>
|
|
|
|
#include <tcl.h>
|
|
|
|
#if defined(_WIN32)
|
|
#include <WNT_WClass.hxx>
|
|
#include <WNT_Window.hxx>
|
|
#elif defined(HAVE_XLIB)
|
|
#include <Xw_Window.hxx>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#elif defined(__APPLE__)
|
|
#include <Cocoa_Window.hxx>
|
|
#elif defined(__EMSCRIPTEN__)
|
|
#include <Wasm_Window.hxx>
|
|
#include <emscripten/emscripten.h>
|
|
#else
|
|
#include <Aspect_NeutralWindow.hxx>
|
|
#endif
|
|
|
|
//==============================================================================
|
|
// VIEWER GLOBAL VARIABLES
|
|
//==============================================================================
|
|
|
|
Standard_IMPORT Standard_Boolean Draw_VirtualWindows;
|
|
Standard_IMPORT Standard_Boolean Draw_Interprete (const char* theCommand);
|
|
|
|
Standard_EXPORT int ViewerMainLoop(Standard_Integer , const char** argv);
|
|
extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
|
|
|
|
#if defined(_WIN32)
|
|
typedef WNT_Window ViewerTest_Window;
|
|
#elif defined(HAVE_XLIB)
|
|
typedef Xw_Window ViewerTest_Window;
|
|
static void VProcessEvents(ClientData,int);
|
|
#elif defined(__APPLE__)
|
|
typedef Cocoa_Window ViewerTest_Window;
|
|
extern void ViewerTest_SetCocoaEventManagerView (const Handle(Cocoa_Window)& theWindow);
|
|
extern void GetCocoaScreenResolution (Standard_Integer& theWidth, Standard_Integer& theHeight);
|
|
#elif defined(__EMSCRIPTEN__)
|
|
typedef Wasm_Window ViewerTest_Window;
|
|
#else
|
|
typedef Aspect_NeutralWindow ViewerTest_Window;
|
|
#endif
|
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
//! Return DOM id of default WebGL canvas from Module.canvas.
|
|
EM_JS(char*, occJSModuleCanvasId, (), {
|
|
const aCanvasId = Module.canvas.id;
|
|
const aNbBytes = lengthBytesUTF8 (aCanvasId) + 1;
|
|
const aStrPtr = Module._malloc (aNbBytes);
|
|
stringToUTF8 (aCanvasId, aStrPtr, aNbBytes);
|
|
return aStrPtr;
|
|
});
|
|
|
|
//! Return DOM id of default WebGL canvas from Module.canvas.
|
|
static TCollection_AsciiString getModuleCanvasId()
|
|
{
|
|
char* aRawId = occJSModuleCanvasId();
|
|
TCollection_AsciiString anId (aRawId != NULL ? aRawId : "");
|
|
free (aRawId);
|
|
return anId;
|
|
}
|
|
#endif
|
|
|
|
static Handle(ViewerTest_Window)& VT_GetWindow()
|
|
{
|
|
static Handle(ViewerTest_Window) aWindow;
|
|
return aWindow;
|
|
}
|
|
|
|
static Handle(Aspect_DisplayConnection)& GetDisplayConnection()
|
|
{
|
|
static Handle(Aspect_DisplayConnection) aDisplayConnection;
|
|
return aDisplayConnection;
|
|
}
|
|
|
|
static void SetDisplayConnection (const Handle(Aspect_DisplayConnection)& theDisplayConnection)
|
|
{
|
|
GetDisplayConnection() = theDisplayConnection;
|
|
}
|
|
|
|
NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)> ViewerTest_myViews;
|
|
static NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)> ViewerTest_myContexts;
|
|
static NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)> ViewerTest_myDrivers;
|
|
|
|
static struct
|
|
{
|
|
Quantity_Color FlatColor;
|
|
Quantity_Color GradientColor1;
|
|
Quantity_Color GradientColor2;
|
|
Aspect_GradientFillMethod FillMethod;
|
|
|
|
//! Sets the gradient filling for a background in a default viewer.
|
|
void SetDefaultGradient()
|
|
{
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator aCtxIter (ViewerTest_myContexts);
|
|
aCtxIter.More(); aCtxIter.Next())
|
|
{
|
|
const Handle (V3d_Viewer)& aViewer = aCtxIter.Value()->CurrentViewer();
|
|
aViewer->SetDefaultBgGradientColors (GradientColor1, GradientColor2, FillMethod);
|
|
}
|
|
}
|
|
|
|
//! Sets the color used for filling a background in a default viewer.
|
|
void SetDefaultColor()
|
|
{
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle (AIS_InteractiveContext)>::Iterator aCtxIter (ViewerTest_myContexts);
|
|
aCtxIter.More(); aCtxIter.Next())
|
|
{
|
|
const Handle (V3d_Viewer)& aViewer = aCtxIter.Value()->CurrentViewer();
|
|
aViewer->SetDefaultBackgroundColor (FlatColor);
|
|
}
|
|
}
|
|
|
|
} ViewerTest_DefaultBackground = { Quantity_NOC_BLACK, Quantity_NOC_BLACK, Quantity_NOC_BLACK, Aspect_GradientFillMethod_None };
|
|
|
|
//==============================================================================
|
|
// EVENT GLOBAL VARIABLES
|
|
//==============================================================================
|
|
|
|
#ifdef _WIN32
|
|
static LRESULT WINAPI AdvViewerWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
#endif
|
|
|
|
//==============================================================================
|
|
//function : WClass
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
const Handle(WNT_WClass)& ViewerTest::WClass()
|
|
{
|
|
static Handle(WNT_WClass) theWClass;
|
|
#if defined(_WIN32)
|
|
if (theWClass.IsNull())
|
|
{
|
|
theWClass = new WNT_WClass ("GW3D_Class", (Standard_Address )AdvViewerWindowProc,
|
|
CS_VREDRAW | CS_HREDRAW, 0, 0,
|
|
::LoadCursor (NULL, IDC_ARROW));
|
|
}
|
|
#endif
|
|
return theWClass;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : CreateName
|
|
//purpose : Create numerical name for new object in theMap
|
|
//==============================================================================
|
|
template <typename ObjectType>
|
|
TCollection_AsciiString CreateName (const NCollection_DoubleMap <TCollection_AsciiString, ObjectType>& theObjectMap,
|
|
const TCollection_AsciiString& theDefaultString)
|
|
{
|
|
if (theObjectMap.IsEmpty())
|
|
return theDefaultString + TCollection_AsciiString(1);
|
|
|
|
Standard_Integer aNextKey = 1;
|
|
Standard_Boolean isFound = Standard_False;
|
|
while (!isFound)
|
|
{
|
|
TCollection_AsciiString aStringKey = theDefaultString + TCollection_AsciiString(aNextKey);
|
|
// Look for objects with default names
|
|
if (theObjectMap.IsBound1(aStringKey))
|
|
{
|
|
aNextKey++;
|
|
}
|
|
else
|
|
isFound = Standard_True;
|
|
}
|
|
|
|
return theDefaultString + TCollection_AsciiString(aNextKey);
|
|
}
|
|
|
|
//==============================================================================
|
|
//structure : ViewerTest_Names
|
|
//purpose : Allow to operate with full view name: driverName/viewerName/viewName
|
|
//==============================================================================
|
|
struct ViewerTest_Names
|
|
{
|
|
private:
|
|
TCollection_AsciiString myDriverName;
|
|
TCollection_AsciiString myViewerName;
|
|
TCollection_AsciiString myViewName;
|
|
|
|
public:
|
|
|
|
const TCollection_AsciiString& GetDriverName () const
|
|
{
|
|
return myDriverName;
|
|
}
|
|
void SetDriverName (const TCollection_AsciiString& theDriverName)
|
|
{
|
|
myDriverName = theDriverName;
|
|
}
|
|
const TCollection_AsciiString& GetViewerName () const
|
|
{
|
|
return myViewerName;
|
|
}
|
|
void SetViewerName (const TCollection_AsciiString& theViewerName)
|
|
{
|
|
myViewerName = theViewerName;
|
|
}
|
|
const TCollection_AsciiString& GetViewName () const
|
|
{
|
|
return myViewName;
|
|
}
|
|
void SetViewName (const TCollection_AsciiString& theViewName)
|
|
{
|
|
myViewName = theViewName;
|
|
}
|
|
|
|
//===========================================================================
|
|
//function : Constructor for ViewerTest_Names
|
|
//purpose : Get view, viewer, driver names from custom string
|
|
//===========================================================================
|
|
|
|
ViewerTest_Names (const TCollection_AsciiString& theInputString)
|
|
{
|
|
TCollection_AsciiString aName(theInputString);
|
|
if (theInputString.IsEmpty())
|
|
{
|
|
// Get current configuration
|
|
if (ViewerTest_myDrivers.IsEmpty())
|
|
myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
|
|
(ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
|
|
else
|
|
myDriverName = ViewerTest_myDrivers.Find2
|
|
(ViewerTest::GetAISContext()->CurrentViewer()->Driver());
|
|
|
|
if(ViewerTest_myContexts.IsEmpty())
|
|
{
|
|
myViewerName = CreateName <Handle(AIS_InteractiveContext)>
|
|
(ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
|
|
}
|
|
else
|
|
{
|
|
myViewerName = ViewerTest_myContexts.Find2 (ViewerTest::GetAISContext());
|
|
}
|
|
|
|
myViewName = CreateName <Handle(V3d_View)> (ViewerTest_myViews, TCollection_AsciiString(myViewerName + "/View"));
|
|
}
|
|
else
|
|
{
|
|
// There is at least view name
|
|
Standard_Integer aParserNumber = 0;
|
|
for (Standard_Integer i = 0; i < 3; ++i)
|
|
{
|
|
Standard_Integer aParserPos = aName.SearchFromEnd("/");
|
|
if(aParserPos != -1)
|
|
{
|
|
aParserNumber++;
|
|
aName.Split(aParserPos-1);
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
if (aParserNumber == 0)
|
|
{
|
|
// Only view name
|
|
if (!ViewerTest::GetAISContext().IsNull())
|
|
{
|
|
myDriverName = ViewerTest_myDrivers.Find2
|
|
(ViewerTest::GetAISContext()->CurrentViewer()->Driver());
|
|
myViewerName = ViewerTest_myContexts.Find2
|
|
(ViewerTest::GetAISContext());
|
|
}
|
|
else
|
|
{
|
|
// There is no opened contexts here, need to create names for viewer and driver
|
|
myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
|
|
(ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
|
|
|
|
myViewerName = CreateName <Handle(AIS_InteractiveContext)>
|
|
(ViewerTest_myContexts, TCollection_AsciiString (myDriverName + "/Viewer"));
|
|
}
|
|
myViewName = TCollection_AsciiString(myViewerName + "/" + theInputString);
|
|
}
|
|
else if (aParserNumber == 1)
|
|
{
|
|
// Here is viewerName/viewName
|
|
if (!ViewerTest::GetAISContext().IsNull())
|
|
myDriverName = ViewerTest_myDrivers.Find2
|
|
(ViewerTest::GetAISContext()->CurrentViewer()->Driver());
|
|
else
|
|
{
|
|
// There is no opened contexts here, need to create name for driver
|
|
myDriverName = CreateName<Handle(Graphic3d_GraphicDriver)>
|
|
(ViewerTest_myDrivers, TCollection_AsciiString("Driver"));
|
|
}
|
|
myViewerName = TCollection_AsciiString(myDriverName + "/" + aName);
|
|
|
|
myViewName = TCollection_AsciiString(myDriverName + "/" + theInputString);
|
|
}
|
|
else
|
|
{
|
|
//Here is driverName/viewerName/viewName
|
|
myDriverName = TCollection_AsciiString(aName);
|
|
|
|
TCollection_AsciiString aViewerName(theInputString);
|
|
aViewerName.Split(aViewerName.SearchFromEnd("/") - 1);
|
|
myViewerName = TCollection_AsciiString(aViewerName);
|
|
|
|
myViewName = TCollection_AsciiString(theInputString);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//==============================================================================
|
|
//function : FindContextByView
|
|
//purpose : Find AIS_InteractiveContext by View
|
|
//==============================================================================
|
|
|
|
Handle(AIS_InteractiveContext) FindContextByView (const Handle(V3d_View)& theView)
|
|
{
|
|
Handle(AIS_InteractiveContext) anAISContext;
|
|
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
|
|
anIter (ViewerTest_myContexts); anIter.More(); anIter.Next())
|
|
{
|
|
if (anIter.Value()->CurrentViewer() == theView->Viewer())
|
|
return anIter.Key2();
|
|
}
|
|
return anAISContext;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : IsWindowOverlapped
|
|
//purpose : Check if theWindow overlapp another view
|
|
//==============================================================================
|
|
|
|
Standard_Boolean IsWindowOverlapped (const Standard_Integer thePxLeft,
|
|
const Standard_Integer thePxTop,
|
|
const Standard_Integer thePxRight,
|
|
const Standard_Integer thePxBottom,
|
|
TCollection_AsciiString& theViewId)
|
|
{
|
|
for(NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
|
|
anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
|
|
{
|
|
Standard_Integer aTop = 0,
|
|
aLeft = 0,
|
|
aRight = 0,
|
|
aBottom = 0;
|
|
anIter.Value()->Window()->Position(aLeft, aTop, aRight, aBottom);
|
|
if ((thePxLeft >= aLeft && thePxLeft <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
|
|
(thePxLeft >= aLeft && thePxLeft <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom) ||
|
|
(thePxRight >= aLeft && thePxRight <= aRight && thePxTop >= aTop && thePxTop <= aBottom) ||
|
|
(thePxRight >= aLeft && thePxRight <= aRight && thePxBottom >= aTop && thePxBottom <= aBottom))
|
|
{
|
|
theViewId = anIter.Key1();
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
// Workaround: to create and delete non-orthographic views outside ViewerTest
|
|
void ViewerTest::RemoveViewName (const TCollection_AsciiString& theName)
|
|
{
|
|
ViewerTest_myViews.UnBind1 (theName);
|
|
}
|
|
|
|
void ViewerTest::InitViewName (const TCollection_AsciiString& theName,
|
|
const Handle(V3d_View)& theView)
|
|
{
|
|
ViewerTest_myViews.Bind (theName, theView);
|
|
}
|
|
|
|
TCollection_AsciiString ViewerTest::GetCurrentViewName ()
|
|
{
|
|
return ViewerTest_myViews.Find2( ViewerTest::CurrentView());
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : ViewerInit
|
|
//purpose : Create the window viewer and initialize all the global variable
|
|
//==============================================================================
|
|
|
|
TCollection_AsciiString ViewerTest::ViewerInit (const ViewerTest_VinitParams& theParams)
|
|
{
|
|
// Default position and dimension of the viewer window.
|
|
// Note that left top corner is set to be sufficiently small to have
|
|
// window fit in the small screens (actual for remote desktops, see #23003).
|
|
// The position corresponds to the window's client area, thus some
|
|
// gap is added for window frame to be visible.
|
|
Graphic3d_Vec2d aPxTopLeft (20, 40);
|
|
Graphic3d_Vec2d aPxSize (409, 409);
|
|
Standard_Boolean isDefViewSize = Standard_True;
|
|
Standard_Boolean toCreateViewer = Standard_False;
|
|
const Standard_Boolean isVirtual = Draw_VirtualWindows || theParams.IsVirtual;
|
|
if (!theParams.ViewToClone.IsNull())
|
|
{
|
|
Graphic3d_Vec2i aCloneSize;
|
|
theParams.ViewToClone->Window()->Size (aCloneSize.x(), aCloneSize.y());
|
|
aPxSize = Graphic3d_Vec2d (aCloneSize);
|
|
isDefViewSize = Standard_False;
|
|
#if !defined(__EMSCRIPTEN__)
|
|
(void )isDefViewSize;
|
|
#endif
|
|
}
|
|
|
|
Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
|
|
if (aFactory.IsNull())
|
|
{
|
|
Draw::GetInterpretor().Eval ("pload OPENGL");
|
|
aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
|
|
if (aFactory.IsNull())
|
|
{
|
|
Draw::GetInterpretor().Eval ("pload GLES");
|
|
aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory();
|
|
if (aFactory.IsNull())
|
|
{
|
|
throw Standard_ProgramError("Error: no graphic driver factory found");
|
|
}
|
|
}
|
|
}
|
|
|
|
Handle(Graphic3d_GraphicDriver) aGraphicDriver;
|
|
ViewerTest_Names aViewNames (theParams.ViewName);
|
|
if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
|
|
{
|
|
aViewNames.SetViewName (aViewNames.GetViewerName() + "/" + CreateName<Handle(V3d_View)>(ViewerTest_myViews, "View"));
|
|
}
|
|
|
|
// Get graphic driver (create it or get from another view)
|
|
const bool isNewDriver = !ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName());
|
|
if (isNewDriver)
|
|
{
|
|
// Get connection string
|
|
#if defined(HAVE_XLIB)
|
|
if (!theParams.DisplayName.IsEmpty())
|
|
{
|
|
SetDisplayConnection (new Aspect_DisplayConnection (theParams.DisplayName));
|
|
}
|
|
else
|
|
{
|
|
Aspect_XDisplay* aDispX = NULL;
|
|
// create dedicated display connection instead of reusing Tk connection
|
|
// so that to proceed events independently through VProcessEvents()/ViewerMainLoop() callbacks
|
|
/*Draw_Interpretor& aCommands = Draw::GetInterpretor();
|
|
Tcl_Interp* aTclInterp = aCommands.Interp();
|
|
Tk_Window aMainWindow = Tk_MainWindow (aTclInterp);
|
|
aDispX = aMainWindow != NULL ? Tk_Display (aMainWindow) : NULL;*/
|
|
SetDisplayConnection (new Aspect_DisplayConnection (aDispX));
|
|
}
|
|
#else
|
|
SetDisplayConnection (new Aspect_DisplayConnection ());
|
|
#endif
|
|
|
|
aGraphicDriver = aFactory->CreateDriver (GetDisplayConnection());
|
|
if (isVirtual)
|
|
{
|
|
// don't waste the time waiting for VSync when window is not displayed on the screen
|
|
aGraphicDriver->SetVerticalSync (false);
|
|
}
|
|
|
|
ViewerTest_myDrivers.Bind (aViewNames.GetDriverName(), aGraphicDriver);
|
|
toCreateViewer = Standard_True;
|
|
}
|
|
else
|
|
{
|
|
aGraphicDriver = ViewerTest_myDrivers.Find1 (aViewNames.GetDriverName());
|
|
}
|
|
|
|
// Get screen resolution
|
|
Graphic3d_Vec2i aScreenSize;
|
|
#if defined(_WIN32)
|
|
RECT aWindowSize;
|
|
GetClientRect(GetDesktopWindow(), &aWindowSize);
|
|
aScreenSize.SetValues (aWindowSize.right, aWindowSize.bottom);
|
|
#elif defined(HAVE_XLIB)
|
|
::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
|
|
Screen* aScreen = DefaultScreenOfDisplay(aDispX);
|
|
aScreenSize.x() = WidthOfScreen(aScreen);
|
|
aScreenSize.y() = HeightOfScreen(aScreen);
|
|
#elif defined(__APPLE__)
|
|
GetCocoaScreenResolution (aScreenSize.x(), aScreenSize.y());
|
|
#else
|
|
// not implemented
|
|
#endif
|
|
|
|
if (!theParams.ParentView.IsNull())
|
|
{
|
|
aPxTopLeft.SetValues (0, 0);
|
|
}
|
|
if (theParams.Offset.x() != 0)
|
|
{
|
|
aPxTopLeft.x() = theParams.Offset.x();
|
|
}
|
|
if (theParams.Offset.y() != 0)
|
|
{
|
|
aPxTopLeft.y() = theParams.Offset.y();
|
|
}
|
|
if (theParams.Size.x() != 0)
|
|
{
|
|
isDefViewSize = Standard_False;
|
|
aPxSize.x() = theParams.Size.x();
|
|
if (aPxSize.x() <= 1.0
|
|
&& aScreenSize.x() > 0
|
|
&& theParams.ParentView.IsNull())
|
|
{
|
|
aPxSize.x() = aPxSize.x() * double(aScreenSize.x());
|
|
}
|
|
}
|
|
if (theParams.Size.y() != 0)
|
|
{
|
|
isDefViewSize = Standard_False;
|
|
aPxSize.y() = theParams.Size.y();
|
|
if (aPxSize.y() <= 1.0
|
|
&& aScreenSize.y() > 0
|
|
&& theParams.ParentView.IsNull())
|
|
{
|
|
aPxSize.y() = aPxSize.y() * double(aScreenSize.y());
|
|
}
|
|
}
|
|
|
|
//Dispose the window if input parameters are default
|
|
if (!ViewerTest_myViews.IsEmpty()
|
|
&& theParams.ParentView.IsNull()
|
|
&& theParams.Offset.x() == 0
|
|
&& theParams.Offset.y() == 0)
|
|
{
|
|
Standard_Integer aTop = 0, aLeft = 0, aRight = 0, aBottom = 0;
|
|
TCollection_AsciiString anOverlappedViewId("");
|
|
while (IsWindowOverlapped ((int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
|
|
(int )aPxTopLeft.x() + (int )aPxSize.x(),
|
|
(int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId))
|
|
{
|
|
ViewerTest_myViews.Find1(anOverlappedViewId)->Window()->Position (aLeft, aTop, aRight, aBottom);
|
|
|
|
if (IsWindowOverlapped (aRight + 20, (int )aPxTopLeft.y(), aRight + 20 + (int )aPxSize.x(),
|
|
(int )aPxTopLeft.y() + (int )aPxSize.y(), anOverlappedViewId)
|
|
&& aRight + 2 * aPxSize.x() + 40 > aScreenSize.x())
|
|
{
|
|
if (aBottom + aPxSize.y() + 40 > aScreenSize.y())
|
|
{
|
|
aPxTopLeft.x() = 20;
|
|
aPxTopLeft.y() = 40;
|
|
break;
|
|
}
|
|
aPxTopLeft.x() = 20;
|
|
aPxTopLeft.y() = aBottom + 40;
|
|
}
|
|
else
|
|
{
|
|
aPxTopLeft.x() = aRight + 20;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get viewer name
|
|
TCollection_AsciiString aTitle("3D View - ");
|
|
aTitle = aTitle + aViewNames.GetViewName() + "(*)";
|
|
|
|
// Change name of current active window
|
|
if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
|
|
{
|
|
aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
|
|
}
|
|
|
|
// Create viewer
|
|
Handle(V3d_Viewer) a3DViewer;
|
|
// If it's the single view, we first look for empty context
|
|
if (ViewerTest_myViews.IsEmpty() && !ViewerTest_myContexts.IsEmpty())
|
|
{
|
|
NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
|
|
anIter(ViewerTest_myContexts);
|
|
if (anIter.More())
|
|
ViewerTest::SetAISContext (anIter.Value());
|
|
a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
|
|
}
|
|
else if (ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName()))
|
|
{
|
|
ViewerTest::SetAISContext(ViewerTest_myContexts.Find1(aViewNames.GetViewerName()));
|
|
a3DViewer = ViewerTest::GetAISContext()->CurrentViewer();
|
|
}
|
|
else if (a3DViewer.IsNull())
|
|
{
|
|
toCreateViewer = Standard_True;
|
|
a3DViewer = new V3d_Viewer(aGraphicDriver);
|
|
a3DViewer->SetDefaultBackgroundColor (ViewerTest_DefaultBackground.FlatColor);
|
|
a3DViewer->SetDefaultBgGradientColors (ViewerTest_DefaultBackground.GradientColor1,
|
|
ViewerTest_DefaultBackground.GradientColor2,
|
|
ViewerTest_DefaultBackground.FillMethod);
|
|
}
|
|
|
|
// AIS context setup
|
|
if (ViewerTest::GetAISContext().IsNull() ||
|
|
!(ViewerTest_myContexts.IsBound1(aViewNames.GetViewerName())))
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (a3DViewer);
|
|
ViewerTest::SetAISContext (aContext);
|
|
ViewerTest_myContexts.Bind (aViewNames.GetViewerName(), ViewerTest::GetAISContext());
|
|
}
|
|
else
|
|
{
|
|
ViewerTest::ResetEventManager();
|
|
}
|
|
|
|
// Create window
|
|
if (!theParams.ParentView.IsNull())
|
|
{
|
|
VT_GetWindow() = Handle(ViewerTest_Window)::DownCast (theParams.ParentView->Window());
|
|
}
|
|
else
|
|
{
|
|
#if defined(_WIN32)
|
|
VT_GetWindow() = new WNT_Window (aTitle.ToCString(), WClass(),
|
|
isVirtual ? WS_POPUP : WS_OVERLAPPEDWINDOW,
|
|
(int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
|
|
(int )aPxSize.x(), (int )aPxSize.y(),
|
|
Quantity_NOC_BLACK);
|
|
VT_GetWindow()->RegisterRawInputDevices (WNT_Window::RawInputMask_SpaceMouse);
|
|
#elif defined(HAVE_XLIB)
|
|
VT_GetWindow() = new Xw_Window (aGraphicDriver->GetDisplayConnection(),
|
|
aTitle.ToCString(),
|
|
(int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
|
|
(int )aPxSize.x(), (int )aPxSize.y());
|
|
#elif defined(__APPLE__)
|
|
VT_GetWindow() = new Cocoa_Window (aTitle.ToCString(),
|
|
(int )aPxTopLeft.x(), (int )aPxTopLeft.y(),
|
|
(int )aPxSize.x(), (int )aPxSize.y());
|
|
ViewerTest_SetCocoaEventManagerView (VT_GetWindow());
|
|
#elif defined(__EMSCRIPTEN__)
|
|
// current EGL implementation in Emscripten supports only one global WebGL canvas returned by Module.canvas property;
|
|
// the code should be revised for handling multiple canvas elements (which is technically also possible)
|
|
TCollection_AsciiString aCanvasId = getModuleCanvasId();
|
|
if (!aCanvasId.IsEmpty())
|
|
{
|
|
aCanvasId = TCollection_AsciiString("#") + aCanvasId;
|
|
}
|
|
|
|
VT_GetWindow() = new Wasm_Window (aCanvasId);
|
|
Graphic3d_Vec2i aRealSize;
|
|
VT_GetWindow()->Size (aRealSize.x(), aRealSize.y());
|
|
if (!isDefViewSize || (aRealSize.x() <= 0 && aRealSize.y() <= 0))
|
|
{
|
|
// Wasm_Window wraps an existing HTML element without creating a new one.
|
|
// Keep size defined on a web page instead of defaulting to 409x409 (as in case of other platform),
|
|
// but resize canvas if vinit has been called with explicitly specified dimensions.
|
|
VT_GetWindow()->SetSizeLogical (Graphic3d_Vec2d (aPxSize));
|
|
}
|
|
#else
|
|
// not implemented
|
|
VT_GetWindow() = new Aspect_NeutralWindow();
|
|
VT_GetWindow()->SetSize ((int )aPxSize.x(), (int )aPxSize.y());
|
|
#endif
|
|
VT_GetWindow()->SetVirtual (isVirtual);
|
|
}
|
|
|
|
// View setup
|
|
Handle(V3d_View) aView;
|
|
if (!theParams.ViewToClone.IsNull())
|
|
{
|
|
aView = new ViewerTest_V3dView (a3DViewer, theParams.ViewToClone);
|
|
}
|
|
else
|
|
{
|
|
aView = new ViewerTest_V3dView (a3DViewer, a3DViewer->DefaultTypeOfView());
|
|
}
|
|
|
|
aView->View()->SetSubviewComposer (theParams.IsComposer);
|
|
if (!theParams.ParentView.IsNull())
|
|
{
|
|
aView->SetWindow (theParams.ParentView, aPxSize, theParams.Corner, aPxTopLeft, theParams.SubviewMargins);
|
|
}
|
|
else
|
|
{
|
|
aView->SetWindow (VT_GetWindow());
|
|
}
|
|
ViewerTest::GetAISContext()->RedrawImmediate (a3DViewer);
|
|
|
|
ViewerTest::CurrentView(aView);
|
|
ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView);
|
|
|
|
// Setup for X11 or NT
|
|
SetDisplayConnection (ViewerTest::CurrentView()->Viewer()->Driver()->GetDisplayConnection());
|
|
ViewerTest_EventManager::SetupWindowCallbacks (VT_GetWindow());
|
|
|
|
// Set parameters for V3d_View and V3d_Viewer
|
|
const Handle (V3d_View) aV3dView = ViewerTest::CurrentView();
|
|
aV3dView->SetComputedMode(Standard_False);
|
|
|
|
a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
|
|
if (toCreateViewer)
|
|
{
|
|
a3DViewer->SetDefaultLights();
|
|
a3DViewer->SetLightOn();
|
|
}
|
|
|
|
#if defined(HAVE_XLIB)
|
|
if (isNewDriver)
|
|
{
|
|
::Display* aDispX = (::Display* )GetDisplayConnection()->GetDisplayAspect();
|
|
Tcl_CreateFileHandler (XConnectionNumber (aDispX), TCL_READABLE, VProcessEvents, (ClientData )aDispX);
|
|
}
|
|
#endif
|
|
|
|
VT_GetWindow()->Map();
|
|
|
|
// Set the handle of created view in the event manager
|
|
ViewerTest::ResetEventManager();
|
|
|
|
ViewerTest::CurrentView()->Redraw();
|
|
|
|
aView.Nullify();
|
|
a3DViewer.Nullify();
|
|
|
|
return aViewNames.GetViewName();
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : RedrawAllViews
|
|
//purpose : Redraw all created views
|
|
//==============================================================================
|
|
void ViewerTest::RedrawAllViews()
|
|
{
|
|
NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
|
|
for (; aViewIt.More(); aViewIt.Next())
|
|
{
|
|
const Handle(V3d_View)& aView = aViewIt.Key2();
|
|
aView->Redraw();
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VDriver
|
|
//purpose :
|
|
//==============================================================================
|
|
static int VDriver (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
if (theArgsNb == 1)
|
|
{
|
|
theDi << "Registered: ";
|
|
for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
|
|
aFactoryIter.More(); aFactoryIter.Next())
|
|
{
|
|
const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
|
|
theDi << aFactory->Name() << " ";
|
|
}
|
|
|
|
theDi << "\n";
|
|
theDi << "Default: ";
|
|
if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
|
|
{
|
|
theDi << aFactory->Name();
|
|
}
|
|
else
|
|
{
|
|
theDi << "NONE";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TCollection_AsciiString aNewActive;
|
|
bool toLoad = false;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
|
|
anArgCase.LowerCase();
|
|
if (anArgCase == "-list")
|
|
{
|
|
for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
|
|
aFactoryIter.More(); aFactoryIter.Next())
|
|
{
|
|
const Handle(Graphic3d_GraphicDriverFactory)& aFactory = aFactoryIter.Value();
|
|
theDi << aFactory->Name() << " ";
|
|
}
|
|
}
|
|
else if ((anArgCase == "-default"
|
|
|| anArgCase == "-load")
|
|
&& aNewActive.IsEmpty())
|
|
{
|
|
toLoad = (anArgCase == "-load");
|
|
if (anArgIter + 1 < theArgsNb)
|
|
{
|
|
aNewActive = theArgVec[++anArgIter];
|
|
}
|
|
else if (toLoad)
|
|
{
|
|
theDi << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if (Handle(Graphic3d_GraphicDriverFactory) aFactory = Graphic3d_GraphicDriverFactory::DefaultDriverFactory())
|
|
{
|
|
theDi << aFactory->Name();
|
|
}
|
|
else
|
|
{
|
|
theDi << "NONE";
|
|
}
|
|
}
|
|
}
|
|
else if (aNewActive.IsEmpty())
|
|
{
|
|
aNewActive = theArgVec[anArgIter];
|
|
}
|
|
else
|
|
{
|
|
theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!aNewActive.IsEmpty())
|
|
{
|
|
const TCollection_AsciiString aNameCopy = aNewActive;
|
|
if (TCollection_AsciiString::IsSameString (aNewActive, "gl", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "opengl", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "tkopengl", false))
|
|
{
|
|
aNewActive = "tkopengl";
|
|
}
|
|
else if (TCollection_AsciiString::IsSameString (aNewActive, "gles", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "opengles", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "tkopengles", false))
|
|
{
|
|
aNewActive = "tkopengles";
|
|
}
|
|
else if (TCollection_AsciiString::IsSameString (aNewActive, "d3d", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "d3dhost", false)
|
|
|| TCollection_AsciiString::IsSameString (aNewActive, "tkd3dhost", false))
|
|
{
|
|
aNewActive = "tkd3dhost";
|
|
}
|
|
|
|
if (toLoad)
|
|
{
|
|
if (aNewActive == "tkopengl")
|
|
{
|
|
Draw::GetInterpretor().Eval ("pload OPENGL");
|
|
}
|
|
else if (aNewActive == "tkopengles")
|
|
{
|
|
Draw::GetInterpretor().Eval ("pload GLES");
|
|
}
|
|
else if (aNewActive == "tkd3dhost")
|
|
{
|
|
Draw::GetInterpretor().Eval ("pload D3DHOST");
|
|
}
|
|
else
|
|
{
|
|
theDi << "Syntax error: unable to load plugin for unknown driver factory '" << aNameCopy << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
bool isFound = false;
|
|
for (Graphic3d_GraphicDriverFactoryList::Iterator aFactoryIter (Graphic3d_GraphicDriverFactory::DriverFactories());
|
|
aFactoryIter.More(); aFactoryIter.Next())
|
|
{
|
|
Handle(Graphic3d_GraphicDriverFactory) aFactory = aFactoryIter.Value();
|
|
if (TCollection_AsciiString::IsSameString (aFactory->Name(), aNewActive, false))
|
|
{
|
|
Graphic3d_GraphicDriverFactory::RegisterFactory (aFactory, true);
|
|
isFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isFound)
|
|
{
|
|
theDi << "Syntax error: driver factory '" << aNameCopy << "' not found";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : Vinit
|
|
//purpose : Create the window viewer and initialize all the global variable
|
|
// Use Tcl_CreateFileHandler on UNIX to catch the X11 Viewer event
|
|
//==============================================================================
|
|
static int VInit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
ViewerTest_VinitParams aParams;
|
|
TCollection_AsciiString aName, aValue;
|
|
int is2dMode = -1, aDpiAware = -1;
|
|
for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
|
|
{
|
|
const TCollection_AsciiString anArg = theArgVec[anArgIt];
|
|
TCollection_AsciiString anArgCase = anArg;
|
|
anArgCase.LowerCase();
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& anArgCase == "-name")
|
|
{
|
|
aParams.ViewName = theArgVec[++anArgIt];
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-left"
|
|
|| anArgCase == "-l")
|
|
&& Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.x()))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-top"
|
|
|| anArgCase == "-t")
|
|
&& Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Offset.y()))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-width"
|
|
|| anArgCase == "-w")
|
|
&& Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.x()))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-height"
|
|
|| anArgCase == "-h")
|
|
&& Draw::ParseReal (theArgVec[anArgIt + 1], aParams.Size.y()))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-pos"
|
|
|| anArgCase == "-position"
|
|
|| anArgCase == "-corner")
|
|
&& ViewerTest::ParseCorner (theArgVec[anArgIt + 1], aParams.Corner))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
else if (anArgIt + 2 < theArgsNb
|
|
&& anArgCase == "-margins"
|
|
&& Draw::ParseInteger (theArgVec[anArgIt + 1], aParams.SubviewMargins.x())
|
|
&& Draw::ParseInteger (theArgVec[anArgIt + 2], aParams.SubviewMargins.y()))
|
|
{
|
|
anArgIt += 2;
|
|
}
|
|
else if (anArgCase == "-virtual"
|
|
|| anArgCase == "-offscreen")
|
|
{
|
|
aParams.IsVirtual = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
|
|
}
|
|
else if (anArgCase == "-composer")
|
|
{
|
|
aParams.IsComposer = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
}
|
|
else if (anArgCase == "-exitonclose")
|
|
{
|
|
ViewerTest_EventManager::ToExitOnCloseView() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
|
|
}
|
|
else if (anArgCase == "-closeonescape"
|
|
|| anArgCase == "-closeonesc")
|
|
{
|
|
ViewerTest_EventManager::ToCloseViewOnEscape() = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
|
|
}
|
|
else if (anArgCase == "-2d_mode"
|
|
|| anArgCase == "-2dmode"
|
|
|| anArgCase == "-2d")
|
|
{
|
|
bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);;
|
|
is2dMode = toEnable ? 1 : 0;
|
|
}
|
|
else if (anArgIt + 1 < theArgsNb
|
|
&& (anArgCase == "-disp"
|
|
|| anArgCase == "-display"))
|
|
{
|
|
aParams.DisplayName = theArgVec[++anArgIt];
|
|
}
|
|
else if (anArgCase == "-dpiaware")
|
|
{
|
|
aDpiAware = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt) ? 1 : 0;
|
|
}
|
|
else if (!ViewerTest::CurrentView().IsNull()
|
|
&& aParams.ViewToClone.IsNull()
|
|
&& (anArgCase == "-copy"
|
|
|| anArgCase == "-clone"
|
|
|| anArgCase == "-cloneactive"
|
|
|| anArgCase == "-cloneactiveview"))
|
|
{
|
|
aParams.ViewToClone = ViewerTest::CurrentView();
|
|
}
|
|
else if (!ViewerTest::CurrentView().IsNull()
|
|
&& aParams.ParentView.IsNull()
|
|
&& anArgCase == "-subview")
|
|
{
|
|
aParams.ParentView = ViewerTest::CurrentView();
|
|
if (aParams.ParentView.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: cannot create of subview without parent";
|
|
return 1;
|
|
}
|
|
if (aParams.ParentView->IsSubview())
|
|
{
|
|
aParams.ParentView = aParams.ParentView->ParentView();
|
|
}
|
|
}
|
|
else if (!ViewerTest::CurrentView().IsNull()
|
|
&& aParams.ParentView.IsNull()
|
|
&& anArgCase == "-parent"
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
TCollection_AsciiString aParentStr (theArgVec[++anArgIt]);
|
|
ViewerTest_Names aViewNames (aParentStr);
|
|
if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
|
|
{
|
|
Message::SendFail() << "Syntax error: parent view '" << aParentStr << "' not found";
|
|
return 1;
|
|
}
|
|
|
|
aParams.ParentView = ViewerTest_myViews.Find1(aViewNames.GetViewName());
|
|
if (aParams.ParentView->IsSubview())
|
|
{
|
|
aParams.ParentView = aParams.ParentView->ParentView();
|
|
}
|
|
}
|
|
// old syntax
|
|
else if (ViewerTest::SplitParameter (anArg, aName, aValue))
|
|
{
|
|
aName.LowerCase();
|
|
if (aName == "name")
|
|
{
|
|
aParams.ViewName = aValue;
|
|
}
|
|
else if (aName == "l"
|
|
|| aName == "left")
|
|
{
|
|
aParams.Offset.x() = (float)aValue.RealValue();
|
|
}
|
|
else if (aName == "t"
|
|
|| aName == "top")
|
|
{
|
|
aParams.Offset.y() = (float)aValue.RealValue();
|
|
}
|
|
else if (aName == "disp"
|
|
|| aName == "display")
|
|
{
|
|
aParams.DisplayName = aValue;
|
|
}
|
|
else if (aName == "w"
|
|
|| aName == "width")
|
|
{
|
|
aParams.Size.x() = (float )aValue.RealValue();
|
|
}
|
|
else if (aName == "h"
|
|
|| aName == "height")
|
|
{
|
|
aParams.Size.y() = (float)aValue.RealValue();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument " << anArg;
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aParams.ViewName.IsEmpty())
|
|
{
|
|
aParams.ViewName = anArg;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument " << anArg;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
#if defined(_WIN32)
|
|
if (aDpiAware != -1)
|
|
{
|
|
typedef void* (WINAPI *SetThreadDpiAwarenessContext_t)(void*);
|
|
if (HMODULE aUser32Module = GetModuleHandleW (L"User32"))
|
|
{
|
|
SetThreadDpiAwarenessContext_t aSetDpiAware = (SetThreadDpiAwarenessContext_t )GetProcAddress (aUser32Module, "SetThreadDpiAwarenessContext");
|
|
if (aDpiAware == 1)
|
|
{
|
|
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
|
if (aSetDpiAware ((void* )-4) == NULL)
|
|
{
|
|
// DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE for older systems
|
|
if (aSetDpiAware ((void* )-3) == NULL)
|
|
{
|
|
Message::SendFail() << "Error: unable to enable DPI awareness";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// DPI_AWARENESS_CONTEXT_UNAWARE
|
|
if (aSetDpiAware ((void* )-1) == NULL)
|
|
{
|
|
Message::SendFail() << "Error: unable to disable DPI awareness";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
(void )aDpiAware;
|
|
#if !defined(HAVE_XLIB)
|
|
if (!aParams.DisplayName.IsEmpty())
|
|
{
|
|
aParams.DisplayName.Clear();
|
|
Message::SendWarning() << "Warning: display parameter will be ignored.\n";
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
ViewerTest_Names aViewNames (aParams.ViewName);
|
|
if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
|
|
{
|
|
TCollection_AsciiString aCommand = TCollection_AsciiString ("vactivate ") + aViewNames.GetViewName();
|
|
theDi.Eval (aCommand.ToCString());
|
|
if (is2dMode != -1)
|
|
{
|
|
ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
|
|
if (is2dMode != -1)
|
|
{
|
|
ViewerTest_V3dView::SetCurrentView2DMode (is2dMode == 1);
|
|
}
|
|
theDi << aViewId;
|
|
return 0;
|
|
}
|
|
|
|
//! Parse HLR algo type.
|
|
static Standard_Boolean parseHlrAlgoType (const char* theName,
|
|
Prs3d_TypeOfHLR& theType)
|
|
{
|
|
TCollection_AsciiString aName (theName);
|
|
aName.LowerCase();
|
|
if (aName == "polyalgo")
|
|
{
|
|
theType = Prs3d_TOH_PolyAlgo;
|
|
}
|
|
else if (aName == "algo")
|
|
{
|
|
theType = Prs3d_TOH_Algo;
|
|
}
|
|
else
|
|
{
|
|
return Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VHLR
|
|
//purpose : hidden lines removal algorithm
|
|
//==============================================================================
|
|
|
|
static int VHLR (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
|
{
|
|
const Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean hasHlrOnArg = Standard_False;
|
|
Standard_Boolean hasShowHiddenArg = Standard_False;
|
|
Standard_Boolean isHLROn = Standard_False;
|
|
Standard_Boolean toShowHidden = aCtx->DefaultDrawer()->DrawHiddenLine();
|
|
Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
|
|
ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (argv[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArg == "-showhidden"
|
|
&& anArgIter + 1 < argc
|
|
&& Draw::ParseOnOff (argv[anArgIter + 1], toShowHidden))
|
|
{
|
|
++anArgIter;
|
|
hasShowHiddenArg = Standard_True;
|
|
continue;
|
|
}
|
|
else if ((anArg == "-type"
|
|
|| anArg == "-algo"
|
|
|| anArg == "-algotype")
|
|
&& anArgIter + 1 < argc
|
|
&& parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
|
|
{
|
|
++anArgIter;
|
|
continue;
|
|
}
|
|
else if (!hasHlrOnArg
|
|
&& Draw::ParseOnOff (argv[anArgIter], isHLROn))
|
|
{
|
|
hasHlrOnArg = Standard_True;
|
|
continue;
|
|
}
|
|
// old syntax
|
|
else if (!hasShowHiddenArg
|
|
&& Draw::ParseOnOff(argv[anArgIter], toShowHidden))
|
|
{
|
|
hasShowHiddenArg = Standard_True;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << argv[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
if (!hasHlrOnArg)
|
|
{
|
|
di << "HLR: " << aView->ComputedMode() << "\n";
|
|
di << "HiddenLine: " << aCtx->DefaultDrawer()->DrawHiddenLine() << "\n";
|
|
di << "HlrAlgo: ";
|
|
switch (aCtx->DefaultDrawer()->TypeOfHLR())
|
|
{
|
|
case Prs3d_TOH_NotSet: di << "NotSet\n"; break;
|
|
case Prs3d_TOH_PolyAlgo: di << "PolyAlgo\n"; break;
|
|
case Prs3d_TOH_Algo: di << "Algo\n"; break;
|
|
}
|
|
anUpdateTool.Invalidate();
|
|
return 0;
|
|
}
|
|
|
|
Standard_Boolean toRecompute = Standard_False;
|
|
if (aTypeOfHLR != Prs3d_TOH_NotSet
|
|
&& aTypeOfHLR != aCtx->DefaultDrawer()->TypeOfHLR())
|
|
{
|
|
toRecompute = Standard_True;
|
|
aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
|
|
}
|
|
if (toShowHidden != aCtx->DefaultDrawer()->DrawHiddenLine())
|
|
{
|
|
toRecompute = Standard_True;
|
|
if (toShowHidden)
|
|
{
|
|
aCtx->DefaultDrawer()->EnableDrawHiddenLine();
|
|
}
|
|
else
|
|
{
|
|
aCtx->DefaultDrawer()->DisableDrawHiddenLine();
|
|
}
|
|
}
|
|
|
|
// redisplay shapes
|
|
if (aView->ComputedMode() && isHLROn && toRecompute)
|
|
{
|
|
AIS_ListOfInteractive aListOfShapes;
|
|
aCtx->DisplayedObjects (aListOfShapes);
|
|
for (AIS_ListIteratorOfListOfInteractive anIter (aListOfShapes); anIter.More(); anIter.Next())
|
|
{
|
|
if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value()))
|
|
{
|
|
aCtx->Redisplay (aShape, Standard_False);
|
|
}
|
|
}
|
|
}
|
|
|
|
aView->SetComputedMode (isHLROn);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VHLRType
|
|
//purpose : change type of using HLR algorithm
|
|
//==============================================================================
|
|
|
|
static int VHLRType (Draw_Interpretor& , Standard_Integer argc, const char** argv)
|
|
{
|
|
const Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Prs3d_TypeOfHLR aTypeOfHLR = Prs3d_TOH_NotSet;
|
|
ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
|
|
AIS_ListOfInteractive aListOfShapes;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < argc; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (argv[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if ((anArg == "-type"
|
|
|| anArg == "-algo"
|
|
|| anArg == "-algotype")
|
|
&& anArgIter + 1 < argc
|
|
&& parseHlrAlgoType (argv[anArgIter + 1], aTypeOfHLR))
|
|
{
|
|
++anArgIter;
|
|
continue;
|
|
}
|
|
// old syntax
|
|
else if (aTypeOfHLR == Prs3d_TOH_NotSet
|
|
&& parseHlrAlgoType (argv[anArgIter], aTypeOfHLR))
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
|
|
TCollection_AsciiString aName (argv[anArgIter]);
|
|
if (!aMap.IsBound2 (aName))
|
|
{
|
|
Message::SendFail() << "Syntax error: Wrong shape name '" << aName << "'";
|
|
return 1;
|
|
}
|
|
|
|
Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aMap.Find2 (aName));
|
|
if (aShape.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: '" << aName << "' is not a shape presentation";
|
|
return 1;
|
|
}
|
|
aListOfShapes.Append (aShape);
|
|
continue;
|
|
}
|
|
}
|
|
if (aTypeOfHLR == Prs3d_TOH_NotSet)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Boolean isGlobal = aListOfShapes.IsEmpty();
|
|
if (isGlobal)
|
|
{
|
|
aCtx->DisplayedObjects (aListOfShapes);
|
|
aCtx->DefaultDrawer()->SetTypeOfHLR (aTypeOfHLR);
|
|
}
|
|
|
|
for (AIS_ListIteratorOfListOfInteractive anIter(aListOfShapes); anIter.More(); anIter.Next())
|
|
{
|
|
Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anIter.Value());
|
|
if (aShape.IsNull())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const bool toUpdateShape = aShape->TypeOfHLR() != aTypeOfHLR
|
|
&& aView->ComputedMode();
|
|
if (!isGlobal
|
|
|| aShape->TypeOfHLR() != aTypeOfHLR)
|
|
{
|
|
aShape->SetTypeOfHLR (aTypeOfHLR);
|
|
}
|
|
if (toUpdateShape)
|
|
{
|
|
aCtx->Redisplay (aShape, Standard_False);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : FindViewIdByWindowHandle
|
|
//purpose : Find theView Id in the map of views by window handle
|
|
//==============================================================================
|
|
#if defined(_WIN32) || defined(HAVE_XLIB)
|
|
static TCollection_AsciiString FindViewIdByWindowHandle (Aspect_Drawable theWindowHandle)
|
|
{
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator
|
|
anIter(ViewerTest_myViews); anIter.More(); anIter.Next())
|
|
{
|
|
Aspect_Drawable aWindowHandle = anIter.Value()->Window()->NativeHandle();
|
|
if (aWindowHandle == theWindowHandle)
|
|
return anIter.Key1();
|
|
}
|
|
return TCollection_AsciiString("");
|
|
}
|
|
#endif
|
|
|
|
//! Make the view active
|
|
void ActivateView (const TCollection_AsciiString& theViewName,
|
|
Standard_Boolean theToUpdate = Standard_True)
|
|
{
|
|
if (const Handle(V3d_View)& aView = ViewerTest_myViews.Find1(theViewName))
|
|
{
|
|
ViewerTest::ActivateView (aView, theToUpdate);
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : ActivateView
|
|
//purpose :
|
|
//==============================================================================
|
|
void ViewerTest::ActivateView (const Handle(V3d_View)& theView,
|
|
Standard_Boolean theToUpdate)
|
|
{
|
|
const Handle(V3d_View)& aView = theView;
|
|
const TCollection_AsciiString* aViewName = ViewerTest_myViews.Seek2 (aView);
|
|
if (aViewName == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(AIS_InteractiveContext) anAISContext = FindContextByView(aView);
|
|
if (anAISContext.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView())
|
|
{
|
|
if (!aCurrentView->Window().IsNull())
|
|
{
|
|
aCurrentView->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (aCurrentView));
|
|
}
|
|
}
|
|
|
|
ViewerTest::CurrentView (aView);
|
|
ViewerTest::SetAISContext (anAISContext);
|
|
if (aView->IsSubview())
|
|
{
|
|
aView->ParentView()->Window()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
|
|
VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->View()->ParentView()->Window());
|
|
}
|
|
else
|
|
{
|
|
VT_GetWindow() = Handle(ViewerTest_Window)::DownCast(aView->Window());
|
|
}
|
|
if (!VT_GetWindow().IsNull())
|
|
{
|
|
VT_GetWindow()->SetTitle (TCollection_AsciiString("3D View - ") + *aViewName + "(*)");
|
|
}
|
|
SetDisplayConnection(aView->Viewer()->Driver()->GetDisplayConnection());
|
|
if (theToUpdate)
|
|
{
|
|
aView->Redraw();
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : RemoveView
|
|
//purpose :
|
|
//==============================================================================
|
|
void ViewerTest::RemoveView (const Handle(V3d_View)& theView,
|
|
const Standard_Boolean theToRemoveContext)
|
|
{
|
|
if (!ViewerTest_myViews.IsBound2 (theView))
|
|
{
|
|
return;
|
|
}
|
|
|
|
const TCollection_AsciiString& aViewName = ViewerTest_myViews.Find2 (theView);
|
|
RemoveView (aViewName, theToRemoveContext);
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : RemoveView
|
|
//purpose : Close and remove view from display, clear maps if necessary
|
|
//==============================================================================
|
|
void ViewerTest::RemoveView (const TCollection_AsciiString& theViewName, const Standard_Boolean isContextRemoved)
|
|
{
|
|
if (!ViewerTest_myViews.IsBound1(theViewName))
|
|
{
|
|
Message::SendFail() << "Wrong view name";
|
|
return;
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest_myViews.Find1(theViewName);
|
|
Handle(AIS_InteractiveContext) aCurrentContext = FindContextByView(aView);
|
|
ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
|
|
aRedrawer.Stop (aView);
|
|
if (!aView->Subviews().IsEmpty())
|
|
{
|
|
NCollection_Sequence<Handle(V3d_View)> aSubviews = aView->Subviews();
|
|
for (const Handle(V3d_View)& aSubviewIter : aSubviews)
|
|
{
|
|
RemoveView (aSubviewIter, isContextRemoved);
|
|
}
|
|
}
|
|
|
|
// Activate another view if it's active now
|
|
if (ViewerTest_myViews.Find1(theViewName) == ViewerTest::CurrentView())
|
|
{
|
|
if (ViewerTest_myViews.Extent() > 1)
|
|
{
|
|
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
if (anIter.Key1() != theViewName)
|
|
{
|
|
ActivateView (anIter.Value(), true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
VT_GetWindow().Nullify();
|
|
ViewerTest::CurrentView (Handle(V3d_View)());
|
|
if (isContextRemoved)
|
|
{
|
|
Handle(AIS_InteractiveContext) anEmptyContext;
|
|
ViewerTest::SetAISContext(anEmptyContext);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete view
|
|
ViewerTest_myViews.UnBind1(theViewName);
|
|
if (!aView->Window().IsNull())
|
|
{
|
|
aView->Window()->Unmap();
|
|
}
|
|
aView->Remove();
|
|
|
|
#if defined(HAVE_XLIB)
|
|
XFlush ((::Display* )GetDisplayConnection()->GetDisplayAspect());
|
|
#endif
|
|
|
|
// Keep context opened only if the closed view is last to avoid
|
|
// unused empty contexts
|
|
if (!aCurrentContext.IsNull())
|
|
{
|
|
// Check if there are more defined views in the viewer
|
|
if ((isContextRemoved || ViewerTest_myContexts.Size() != 1)
|
|
&& aCurrentContext->CurrentViewer()->DefinedViews().IsEmpty())
|
|
{
|
|
// Remove driver if there is no viewers that use it
|
|
Standard_Boolean isRemoveDriver = Standard_True;
|
|
for(NCollection_DoubleMap<TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
|
|
anIter(ViewerTest_myContexts); anIter.More(); anIter.Next())
|
|
{
|
|
if (aCurrentContext != anIter.Key2() &&
|
|
aCurrentContext->CurrentViewer()->Driver() == anIter.Value()->CurrentViewer()->Driver())
|
|
{
|
|
isRemoveDriver = Standard_False;
|
|
break;
|
|
}
|
|
}
|
|
|
|
aCurrentContext->RemoveAll (Standard_False);
|
|
if(isRemoveDriver)
|
|
{
|
|
ViewerTest_myDrivers.UnBind2 (aCurrentContext->CurrentViewer()->Driver());
|
|
#if defined(HAVE_XLIB)
|
|
Tcl_DeleteFileHandler (XConnectionNumber ((::Display* )aCurrentContext->CurrentViewer()->Driver()->GetDisplayConnection()->GetDisplayAspect()));
|
|
#endif
|
|
}
|
|
|
|
ViewerTest_myContexts.UnBind2(aCurrentContext);
|
|
}
|
|
}
|
|
Message::SendInfo() << "3D View - " << theViewName << " was deleted.\n";
|
|
if (ViewerTest_EventManager::ToExitOnCloseView())
|
|
{
|
|
Draw_Interprete ("exit");
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VClose
|
|
//purpose : Remove the view defined by its name
|
|
//==============================================================================
|
|
|
|
static int VClose (Draw_Interpretor& /*theDi*/,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
NCollection_List<TCollection_AsciiString> aViewList;
|
|
if (theArgsNb > 1)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[1]);
|
|
anArg.UpperCase();
|
|
if (anArg.IsEqual ("ALL")
|
|
|| anArg.IsEqual ("*"))
|
|
{
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
aViewList.Append (anIter.Key1());
|
|
}
|
|
if (aViewList.IsEmpty())
|
|
{
|
|
std::cout << "No view to close\n";
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ViewerTest_Names aViewName (theArgVec[1]);
|
|
if (!ViewerTest_myViews.IsBound1 (aViewName.GetViewName()))
|
|
{
|
|
Message::SendFail() << "Error: the view with name '" << theArgVec[1] << "' does not exist";
|
|
return 1;
|
|
}
|
|
aViewList.Append (aViewName.GetViewName());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// close active view
|
|
if (ViewerTest::CurrentView().IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active view");
|
|
return 1;
|
|
}
|
|
aViewList.Append (ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
|
|
}
|
|
|
|
Standard_Boolean toRemoveContext = (theArgsNb != 3 || Draw::Atoi (theArgVec[2]) != 1);
|
|
for (NCollection_List<TCollection_AsciiString>::Iterator anIter(aViewList);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
ViewerTest::RemoveView (anIter.Value(), toRemoveContext);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VActivate
|
|
//purpose : Activate the view defined by its ID
|
|
//==============================================================================
|
|
|
|
static int VActivate (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
if (theArgsNb == 1)
|
|
{
|
|
theDi.Eval("vviewlist");
|
|
return 0;
|
|
}
|
|
|
|
TCollection_AsciiString aNameString;
|
|
Standard_Boolean toUpdate = Standard_True;
|
|
Standard_Boolean toActivate = Standard_True;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (toUpdate
|
|
&& anArg == "-noupdate")
|
|
{
|
|
toUpdate = Standard_False;
|
|
}
|
|
else if (toActivate
|
|
&& aNameString.IsEmpty()
|
|
&& anArg == "none")
|
|
{
|
|
ViewerTest::CurrentView()->Window()->SetTitle (TCollection_AsciiString ("3D View - ") + ViewerTest_myViews.Find2 (ViewerTest::CurrentView()));
|
|
VT_GetWindow().Nullify();
|
|
ViewerTest::CurrentView (Handle(V3d_View)());
|
|
ViewerTest::ResetEventManager();
|
|
theDi << theArgVec[0] << ": all views are inactive\n";
|
|
toActivate = Standard_False;
|
|
}
|
|
else if (toActivate
|
|
&& aNameString.IsEmpty())
|
|
{
|
|
aNameString = theArgVec[anArgIter];
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!toActivate)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (aNameString.IsEmpty())
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
// Check if this view exists in the viewer with the driver
|
|
ViewerTest_Names aViewNames (aNameString);
|
|
if (!ViewerTest_myViews.IsBound1(aViewNames.GetViewName()))
|
|
{
|
|
theDi << "Syntax error: wrong view name '" << aNameString << "'\n";
|
|
return 1;
|
|
}
|
|
|
|
// Check if it is active already
|
|
if (ViewerTest::CurrentView() == ViewerTest_myViews.Find1(aViewNames.GetViewName()))
|
|
{
|
|
theDi << theArgVec[0] << ": the view is active already\n";
|
|
return 0;
|
|
}
|
|
|
|
ActivateView (aViewNames.GetViewName(), toUpdate);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VViewList
|
|
//purpose : Print current list of views per viewer and graphic driver ID
|
|
// shared between viewers
|
|
//==============================================================================
|
|
|
|
static int VViewList (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
if (theArgsNb > 2)
|
|
{
|
|
theDi << theArgVec[0] << ": Wrong number of command arguments\n"
|
|
<< "Usage: " << theArgVec[0] << " name";
|
|
return 1;
|
|
}
|
|
if (ViewerTest_myContexts.Size() < 1)
|
|
return 0;
|
|
|
|
Standard_Boolean isTreeView =
|
|
(( theArgsNb==1 ) || ( strcasecmp( theArgVec[1], "long" ) != 0 ));
|
|
|
|
if (isTreeView)
|
|
{
|
|
theDi << theArgVec[0] <<":\n";
|
|
}
|
|
|
|
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator aDriverIter (ViewerTest_myDrivers);
|
|
aDriverIter.More(); aDriverIter.Next())
|
|
{
|
|
if (isTreeView)
|
|
theDi << aDriverIter.Key1() << ":\n";
|
|
|
|
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(AIS_InteractiveContext)>::Iterator
|
|
aContextIter(ViewerTest_myContexts); aContextIter.More(); aContextIter.Next())
|
|
{
|
|
if (aContextIter.Key1().Search(aDriverIter.Key1()) != -1)
|
|
{
|
|
if (isTreeView)
|
|
{
|
|
TCollection_AsciiString aContextName(aContextIter.Key1());
|
|
theDi << " " << aContextName.Split(aDriverIter.Key1().Length() + 1) << ":\n";
|
|
}
|
|
|
|
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIter (ViewerTest_myViews);
|
|
aViewIter.More(); aViewIter.Next())
|
|
{
|
|
if (aViewIter.Key1().Search(aContextIter.Key1()) != -1)
|
|
{
|
|
TCollection_AsciiString aViewName(aViewIter.Key1());
|
|
if (isTreeView)
|
|
{
|
|
if (aViewIter.Value() == ViewerTest::CurrentView())
|
|
theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "(*)\n";
|
|
else
|
|
theDi << " " << aViewName.Split(aContextIter.Key1().Length() + 1) << "\n";
|
|
}
|
|
else
|
|
{
|
|
theDi << aViewName << " ";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : GetMousePosition
|
|
//purpose :
|
|
//==============================================================================
|
|
void ViewerTest::GetMousePosition (Standard_Integer& theX,
|
|
Standard_Integer& theY)
|
|
{
|
|
if (Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager())
|
|
{
|
|
theX = aViewCtrl->LastMousePosition().x();
|
|
theY = aViewCtrl->LastMousePosition().y();
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VViewProj
|
|
//purpose : Switch view projection
|
|
//==============================================================================
|
|
static int VViewProj (Draw_Interpretor& ,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
static Standard_Boolean isYup = Standard_False;
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aCmdName (theArgVec[0]);
|
|
Standard_Boolean isGeneralCmd = Standard_False;
|
|
if (aCmdName == "vfront")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
|
|
}
|
|
else if (aCmdName == "vback")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
|
|
}
|
|
else if (aCmdName == "vtop")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
|
|
}
|
|
else if (aCmdName == "vbottom")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
|
|
}
|
|
else if (aCmdName == "vleft")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
|
|
}
|
|
else if (aCmdName == "vright")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
|
|
}
|
|
else if (aCmdName == "vaxo")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
|
|
}
|
|
else
|
|
{
|
|
isGeneralCmd = Standard_True;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
|
|
anArgCase.LowerCase();
|
|
if (anArgCase == "-zup")
|
|
{
|
|
isYup = Standard_False;
|
|
}
|
|
else if (anArgCase == "-yup")
|
|
{
|
|
isYup = Standard_True;
|
|
}
|
|
else if (anArgCase == "-front"
|
|
|| anArgCase == "front"
|
|
|| anArgCase == "-f"
|
|
|| anArgCase == "f")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
|
|
}
|
|
else if (anArgCase == "-back"
|
|
|| anArgCase == "back"
|
|
|| anArgCase == "-b"
|
|
|| anArgCase == "b")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
|
|
}
|
|
else if (anArgCase == "-top"
|
|
|| anArgCase == "top"
|
|
|| anArgCase == "-t"
|
|
|| anArgCase == "t")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
|
|
}
|
|
else if (anArgCase == "-bottom"
|
|
|| anArgCase == "bottom"
|
|
|| anArgCase == "-bot"
|
|
|| anArgCase == "bot"
|
|
|| anArgCase == "-b"
|
|
|| anArgCase == "b")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
|
|
}
|
|
else if (anArgCase == "-left"
|
|
|| anArgCase == "left"
|
|
|| anArgCase == "-l"
|
|
|| anArgCase == "l")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
|
|
}
|
|
else if (anArgCase == "-right"
|
|
|| anArgCase == "right"
|
|
|| anArgCase == "-r"
|
|
|| anArgCase == "r")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
|
|
}
|
|
else if (anArgCase == "-axoleft"
|
|
|| anArgCase == "-leftaxo"
|
|
|| anArgCase == "axoleft"
|
|
|| anArgCase == "leftaxo")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
|
|
}
|
|
else if (anArgCase == "-axo"
|
|
|| anArgCase == "axo"
|
|
|| anArgCase == "-a"
|
|
|| anArgCase == "a"
|
|
|| anArgCase == "-axoright"
|
|
|| anArgCase == "-rightaxo"
|
|
|| anArgCase == "axoright"
|
|
|| anArgCase == "rightaxo")
|
|
{
|
|
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
|
|
}
|
|
else if (anArgCase == "+x")
|
|
{
|
|
aView->SetProj (V3d_Xpos, isYup);
|
|
}
|
|
else if (anArgCase == "-x")
|
|
{
|
|
aView->SetProj (V3d_Xneg, isYup);
|
|
}
|
|
else if (anArgCase == "+y")
|
|
{
|
|
aView->SetProj (V3d_Ypos, isYup);
|
|
}
|
|
else if (anArgCase == "-y")
|
|
{
|
|
aView->SetProj (V3d_Yneg, isYup);
|
|
}
|
|
else if (anArgCase == "+z")
|
|
{
|
|
aView->SetProj (V3d_Zpos, isYup);
|
|
}
|
|
else if (anArgCase == "-z")
|
|
{
|
|
aView->SetProj (V3d_Zneg, isYup);
|
|
}
|
|
else if (anArgCase == "+x+y+z")
|
|
{
|
|
aView->SetProj (V3d_XposYposZpos, isYup);
|
|
}
|
|
else if (anArgCase == "+x+y-z")
|
|
{
|
|
aView->SetProj (V3d_XposYposZneg, isYup);
|
|
}
|
|
else if (anArgCase == "+x-y+z")
|
|
{
|
|
aView->SetProj (V3d_XposYnegZpos, isYup);
|
|
}
|
|
else if (anArgCase == "+x-y-z")
|
|
{
|
|
aView->SetProj (V3d_XposYnegZneg, isYup);
|
|
}
|
|
else if (anArgCase == "-x+y+z")
|
|
{
|
|
aView->SetProj (V3d_XnegYposZpos, isYup);
|
|
}
|
|
else if (anArgCase == "-x+y-z")
|
|
{
|
|
aView->SetProj (V3d_XnegYposZneg, isYup);
|
|
}
|
|
else if (anArgCase == "-x-y+z")
|
|
{
|
|
aView->SetProj (V3d_XnegYnegZpos, isYup);
|
|
}
|
|
else if (anArgCase == "-x-y-z")
|
|
{
|
|
aView->SetProj (V3d_XnegYnegZneg, isYup);
|
|
}
|
|
else if (anArgCase == "+x+y")
|
|
{
|
|
aView->SetProj (V3d_XposYpos, isYup);
|
|
}
|
|
else if (anArgCase == "+x-y")
|
|
{
|
|
aView->SetProj (V3d_XposYneg, isYup);
|
|
}
|
|
else if (anArgCase == "-x+y")
|
|
{
|
|
aView->SetProj (V3d_XnegYpos, isYup);
|
|
}
|
|
else if (anArgCase == "-x-y")
|
|
{
|
|
aView->SetProj (V3d_XnegYneg, isYup);
|
|
}
|
|
else if (anArgCase == "+x+z")
|
|
{
|
|
aView->SetProj (V3d_XposZpos, isYup);
|
|
}
|
|
else if (anArgCase == "+x-z")
|
|
{
|
|
aView->SetProj (V3d_XposZneg, isYup);
|
|
}
|
|
else if (anArgCase == "-x+z")
|
|
{
|
|
aView->SetProj (V3d_XnegZpos, isYup);
|
|
}
|
|
else if (anArgCase == "-x-z")
|
|
{
|
|
aView->SetProj (V3d_XnegZneg, isYup);
|
|
}
|
|
else if (anArgCase == "+y+z")
|
|
{
|
|
aView->SetProj (V3d_YposZpos, isYup);
|
|
}
|
|
else if (anArgCase == "+y-z")
|
|
{
|
|
aView->SetProj (V3d_YposZneg, isYup);
|
|
}
|
|
else if (anArgCase == "-y+z")
|
|
{
|
|
aView->SetProj (V3d_YnegZpos, isYup);
|
|
}
|
|
else if (anArgCase == "-y-z")
|
|
{
|
|
aView->SetProj (V3d_YnegZneg, isYup);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArgCase == "-frame"
|
|
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
|
|
{
|
|
TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
|
|
aFrameDef.LowerCase();
|
|
gp_Dir aRight, anUp;
|
|
if (aFrameDef.Value (2) == aFrameDef.Value (4))
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
if (aFrameDef.Value (2) == 'x')
|
|
{
|
|
aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
|
|
}
|
|
else if (aFrameDef.Value (2) == 'y')
|
|
{
|
|
aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
|
|
}
|
|
else if (aFrameDef.Value (2) == 'z')
|
|
{
|
|
aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
if (aFrameDef.Value (4) == 'x')
|
|
{
|
|
anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
|
|
}
|
|
else if (aFrameDef.Value (4) == 'y')
|
|
{
|
|
anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
|
|
}
|
|
else if (aFrameDef.Value (4) == 'z')
|
|
{
|
|
anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
|
|
const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
|
|
const gp_Dir aDir = anUp.Crossed (aRight);
|
|
aCamera->SetCenter (gp_Pnt (0, 0, 0));
|
|
aCamera->SetDirection (aDir);
|
|
aCamera->SetUp (anUp);
|
|
aCamera->OrthogonalizeUp();
|
|
|
|
aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
|
|
aView->Update();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isGeneralCmd
|
|
&& theNbArgs != 1)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VHelp
|
|
//purpose : Dsiplay help on viewer Keyboead and mouse commands
|
|
//Draw arg : No args
|
|
//==============================================================================
|
|
|
|
static int VHelp(Draw_Interpretor& di, Standard_Integer , const char** )
|
|
{
|
|
di << "=========================\n";
|
|
di << "F : FitAll\n";
|
|
di << "T : TopView\n";
|
|
di << "B : BottomView\n";
|
|
di << "R : RightView\n";
|
|
di << "L : LeftView\n";
|
|
di << "Backspace : AxonometricView\n";
|
|
|
|
di << "=========================\n";
|
|
di << "W, S : Fly forward/backward\n";
|
|
di << "A, D : Slide left/right\n";
|
|
di << "Q, E : Bank left/right\n";
|
|
di << "-, + : Change flying speed\n";
|
|
di << "Arrows : look left/right/up/down\n";
|
|
di << "Arrows+Shift : slide left/right/up/down\n";
|
|
|
|
di << "=========================\n";
|
|
di << "S + Ctrl : Shading\n";
|
|
di << "W + Ctrl : Wireframe\n";
|
|
di << "H : HiddenLineRemoval\n";
|
|
di << "U : Unset display mode\n";
|
|
di << "Delete : Remove selection from viewer\n";
|
|
|
|
di << "=========================\n";
|
|
di << "Selection mode \n";
|
|
di << "0 : Shape\n";
|
|
di << "1 : Vertex\n";
|
|
di << "2 : Edge\n";
|
|
di << "3 : Wire\n";
|
|
di << "4 : Face\n";
|
|
di << "5 : Shell\n";
|
|
di << "6 : Solid\n";
|
|
di << "7 : Compound\n";
|
|
|
|
di << "=========================\n";
|
|
di << "< : Hilight next detected\n";
|
|
di << "> : Hilight previous detected\n";
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
static LRESULT WINAPI AdvViewerWindowProc (HWND theWinHandle,
|
|
UINT theMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam )
|
|
{
|
|
if (ViewerTest_myViews.IsEmpty())
|
|
{
|
|
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
|
}
|
|
|
|
switch (theMsg)
|
|
{
|
|
case WM_CLOSE:
|
|
{
|
|
// Delete view from map of views
|
|
ViewerTest::RemoveView (FindViewIdByWindowHandle (theWinHandle));
|
|
return 0;
|
|
}
|
|
case WM_ACTIVATE:
|
|
{
|
|
if (LOWORD(wParam) == WA_CLICKACTIVE
|
|
|| LOWORD(wParam) == WA_ACTIVE
|
|
|| ViewerTest::CurrentView().IsNull())
|
|
{
|
|
// Activate inactive window
|
|
if (VT_GetWindow().IsNull()
|
|
|| (HWND )VT_GetWindow()->HWindow() != theWinHandle)
|
|
{
|
|
ActivateView (FindViewIdByWindowHandle (theWinHandle));
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (!aView.IsNull()
|
|
&& !VT_GetWindow().IsNull())
|
|
{
|
|
MSG aMsg = {};
|
|
aMsg.hwnd = theWinHandle;
|
|
aMsg.message = theMsg;
|
|
aMsg.wParam = wParam;
|
|
aMsg.lParam = lParam;
|
|
if (VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aMsg))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return DefWindowProcW (theWinHandle, theMsg, wParam, lParam);
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : ViewerMainLoop
|
|
//purpose : Get a Event on the view and dispatch it
|
|
//==============================================================================
|
|
|
|
int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
|
{
|
|
Handle(ViewerTest_EventManager) aViewCtrl = ViewerTest::CurrentEventManager();
|
|
if (aViewCtrl.IsNull()
|
|
|| theNbArgs < 4)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
aViewCtrl->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
|
|
|
|
std::cout << "Start picking\n";
|
|
|
|
MSG aMsg;
|
|
aMsg.wParam = 1;
|
|
while (aViewCtrl->ToPickPoint())
|
|
{
|
|
// Wait for a VT_ProcessButton1Press() to toggle pick to 1 or 0
|
|
if (GetMessageW (&aMsg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage (&aMsg);
|
|
DispatchMessageW (&aMsg);
|
|
}
|
|
}
|
|
|
|
std::cout << "Picking done\n";
|
|
return 0;
|
|
}
|
|
|
|
#elif defined(HAVE_XLIB)
|
|
|
|
int ViewerMainLoop (Standard_Integer theNbArgs, const char** theArgVec)
|
|
{
|
|
static XEvent aReport;
|
|
const Standard_Boolean toPick = theNbArgs > 0;
|
|
if (theNbArgs > 0)
|
|
{
|
|
if (ViewerTest::CurrentEventManager().IsNull())
|
|
{
|
|
return 0;
|
|
}
|
|
ViewerTest::CurrentEventManager()->StartPickPoint (theArgVec[1], theArgVec[2], theArgVec[3]);
|
|
}
|
|
|
|
Display* aDisplay = (Display* )GetDisplayConnection()->GetDisplayAspect();
|
|
XNextEvent (aDisplay, &aReport);
|
|
|
|
// Handle event for the chosen display connection
|
|
switch (aReport.type)
|
|
{
|
|
case ClientMessage:
|
|
{
|
|
if ((Atom)aReport.xclient.data.l[0] == GetDisplayConnection()->GetAtom(Aspect_XA_DELETE_WINDOW))
|
|
{
|
|
// Close the window
|
|
ViewerTest::RemoveView(FindViewIdByWindowHandle (aReport.xclient.window));
|
|
return toPick ? 0 : 1;
|
|
}
|
|
break;
|
|
}
|
|
case FocusIn:
|
|
{
|
|
// Activate inactive view
|
|
Window aWindow = !VT_GetWindow().IsNull() ? VT_GetWindow()->XWindow() : 0;
|
|
if (aWindow != aReport.xfocus.window)
|
|
{
|
|
ActivateView (FindViewIdByWindowHandle (aReport.xfocus.window));
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (!aView.IsNull()
|
|
&& !VT_GetWindow().IsNull())
|
|
{
|
|
VT_GetWindow()->ProcessMessage (*ViewerTest::CurrentEventManager(), aReport);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return (!toPick || ViewerTest::CurrentEventManager()->ToPickPoint()) ? 1 : 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VProcessEvents
|
|
//purpose : manage the event in the Viewer window (see Tcl_CreateFileHandler())
|
|
//==============================================================================
|
|
static void VProcessEvents (ClientData theDispX, int)
|
|
{
|
|
Display* aDispX = (Display* )theDispX;
|
|
Handle(Aspect_DisplayConnection) aDispConn;
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(Graphic3d_GraphicDriver)>::Iterator
|
|
aDriverIter (ViewerTest_myDrivers); aDriverIter.More(); aDriverIter.Next())
|
|
{
|
|
const Handle(Aspect_DisplayConnection)& aDispConnTmp = aDriverIter.Key2()->GetDisplayConnection();
|
|
if ((Display* )aDispConnTmp->GetDisplayAspect() == aDispX)
|
|
{
|
|
aDispConn = aDispConnTmp;
|
|
break;
|
|
}
|
|
}
|
|
if (aDispConn.IsNull())
|
|
{
|
|
Message::SendFail ("Error: ViewerTest is unable processing messages for unknown X Display");
|
|
return;
|
|
}
|
|
|
|
// process new events in queue
|
|
SetDisplayConnection (aDispConn);
|
|
int aNbRemain = 0;
|
|
for (int aNbEventsMax = XPending (aDispX), anEventIter (0);;)
|
|
{
|
|
const int anEventResult = ViewerMainLoop (0, NULL);
|
|
if (anEventResult == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
aNbRemain = XPending (aDispX);
|
|
if (++anEventIter >= aNbEventsMax
|
|
|| aNbRemain <= 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Listening X events through Tcl_CreateFileHandler() callback is fragile,
|
|
// it is possible that new events will arrive to queue before the end of this callback
|
|
// so that either this callback should go into an infinite loop (blocking processing of other events)
|
|
// or to keep unprocessed events till the next queue update (which can arrive not soon).
|
|
// Sending a dummy event in this case is a simple workaround (still, it is possible that new event will be queued in-between).
|
|
if (aNbRemain != 0)
|
|
{
|
|
XEvent aDummyEvent;
|
|
memset (&aDummyEvent, 0, sizeof(aDummyEvent));
|
|
aDummyEvent.type = ClientMessage;
|
|
aDummyEvent.xclient.format = 32;
|
|
XSendEvent (aDispX, InputFocus, False, 0, &aDummyEvent);
|
|
XFlush (aDispX);
|
|
}
|
|
|
|
if (const Handle(AIS_InteractiveContext)& anActiveCtx = ViewerTest::GetAISContext())
|
|
{
|
|
SetDisplayConnection (anActiveCtx->CurrentViewer()->Driver()->GetDisplayConnection());
|
|
}
|
|
}
|
|
#elif !defined(__APPLE__)
|
|
// =======================================================================
|
|
// function : ViewerMainLoop
|
|
// purpose :
|
|
// =======================================================================
|
|
int ViewerMainLoop (Standard_Integer , const char** )
|
|
{
|
|
// unused
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
//==============================================================================
|
|
//function : VFit
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgv)
|
|
{
|
|
const Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean toFit = Standard_True;
|
|
ViewerTest_AutoUpdater anUpdateTool (Handle(AIS_InteractiveContext)(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgv[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArg == "-selected")
|
|
{
|
|
ViewerTest::GetAISContext()->FitSelected (aView, 0.01, Standard_False);
|
|
toFit = Standard_False;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
}
|
|
}
|
|
|
|
if (toFit)
|
|
{
|
|
aView->FitAll (0.01, Standard_False);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VFitArea
|
|
//purpose : Fit view to show area located between two points
|
|
// : given in world 2D or 3D coordinates.
|
|
//=======================================================================
|
|
static int VFitArea (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: No active viewer");
|
|
return 1;
|
|
}
|
|
|
|
// Parse arguments.
|
|
gp_Pnt aWorldPnt1 (0.0, 0.0, 0.0);
|
|
gp_Pnt aWorldPnt2 (0.0, 0.0, 0.0);
|
|
|
|
if (theArgNb == 5)
|
|
{
|
|
aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
|
|
aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
|
|
aWorldPnt2.SetX (Draw::Atof (theArgVec[3]));
|
|
aWorldPnt2.SetY (Draw::Atof (theArgVec[4]));
|
|
}
|
|
else if (theArgNb == 7)
|
|
{
|
|
aWorldPnt1.SetX (Draw::Atof (theArgVec[1]));
|
|
aWorldPnt1.SetY (Draw::Atof (theArgVec[2]));
|
|
aWorldPnt1.SetZ (Draw::Atof (theArgVec[3]));
|
|
aWorldPnt2.SetX (Draw::Atof (theArgVec[4]));
|
|
aWorldPnt2.SetY (Draw::Atof (theArgVec[5]));
|
|
aWorldPnt2.SetZ (Draw::Atof (theArgVec[6]));
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail ("Syntax error: Invalid number of arguments");
|
|
theDI.PrintHelp(theArgVec[0]);
|
|
return 1;
|
|
}
|
|
|
|
// Convert model coordinates to view space
|
|
Handle(Graphic3d_Camera) aCamera = aView->Camera();
|
|
gp_Pnt aViewPnt1 = aCamera->ConvertWorld2View (aWorldPnt1);
|
|
gp_Pnt aViewPnt2 = aCamera->ConvertWorld2View (aWorldPnt2);
|
|
|
|
// Determine fit area
|
|
gp_Pnt2d aMinCorner (Min (aViewPnt1.X(), aViewPnt2.X()), Min (aViewPnt1.Y(), aViewPnt2.Y()));
|
|
gp_Pnt2d aMaxCorner (Max (aViewPnt1.X(), aViewPnt2.X()), Max (aViewPnt1.Y(), aViewPnt2.Y()));
|
|
|
|
Standard_Real aDiagonal = aMinCorner.Distance (aMaxCorner);
|
|
|
|
if (aDiagonal < Precision::Confusion())
|
|
{
|
|
Message::SendFail ("Error: view area is too small");
|
|
return 1;
|
|
}
|
|
|
|
aView->FitAll (aMinCorner.X(), aMinCorner.Y(), aMaxCorner.X(), aMaxCorner.Y());
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VZFit
|
|
//purpose : ZFitall, no DRAW arguments
|
|
//Draw arg : No args
|
|
//==============================================================================
|
|
static int VZFit (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
|
|
|
|
if (aCurrentView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgsNb == 1)
|
|
{
|
|
aCurrentView->ZFitAll();
|
|
aCurrentView->Redraw();
|
|
return 0;
|
|
}
|
|
|
|
Standard_Real aScale = 1.0;
|
|
|
|
if (theArgsNb >= 2)
|
|
{
|
|
aScale = Draw::Atoi (theArgVec[1]);
|
|
}
|
|
|
|
aCurrentView->ZFitAll (aScale);
|
|
aCurrentView->Redraw();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VRepaint
|
|
//purpose :
|
|
//==============================================================================
|
|
static int VRepaint (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean isImmediateUpdate = Standard_False;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anArg == "-immediate"
|
|
|| anArg == "-imm")
|
|
{
|
|
isImmediateUpdate = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isImmediateUpdate))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (anArg == "-continuous"
|
|
|| anArg == "-cont"
|
|
|| anArg == "-fps"
|
|
|| anArg == "-framerate")
|
|
{
|
|
Standard_Real aFps = -1.0;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue (Standard_True))
|
|
{
|
|
aFps = Draw::Atof (theArgVec[++anArgIter]);
|
|
}
|
|
|
|
ViewerTest_ContinuousRedrawer& aRedrawer = ViewerTest_ContinuousRedrawer::Instance();
|
|
ViewerTest::CurrentEventManager()->SetContinuousRedraw (false);
|
|
if (aFps >= 1.0)
|
|
{
|
|
aRedrawer.Start (aView, aFps);
|
|
}
|
|
else if (aFps < 0.0)
|
|
{
|
|
if (ViewerTest::GetViewerFromContext()->ActiveViews().Extent() == 1)
|
|
{
|
|
aRedrawer.Stop();
|
|
ViewerTest::CurrentEventManager()->SetContinuousRedraw (true);
|
|
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), ViewerTest::CurrentView(), true);
|
|
continue;
|
|
}
|
|
aRedrawer.Start (aView, aFps);
|
|
}
|
|
else
|
|
{
|
|
aRedrawer.Stop();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (isImmediateUpdate)
|
|
{
|
|
aView->RedrawImmediate();
|
|
}
|
|
else
|
|
{
|
|
aView->Redraw();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VClear
|
|
//purpose : Remove all the object from the viewer
|
|
//Draw arg : No args
|
|
//==============================================================================
|
|
|
|
static int VClear(Draw_Interpretor& , Standard_Integer , const char** )
|
|
{
|
|
Handle(V3d_View) V = ViewerTest::CurrentView();
|
|
if(!V.IsNull())
|
|
ViewerTest::Clear();
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VPick
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VPick (Draw_Interpretor& ,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
if (ViewerTest::CurrentView().IsNull())
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (theNbArgs < 4)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
while (ViewerMainLoop (theNbArgs, theArgVec))
|
|
{
|
|
//
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//! Parse image fill method.
|
|
static bool parseImageMode (const TCollection_AsciiString& theName,
|
|
Aspect_FillMethod& theMode)
|
|
{
|
|
TCollection_AsciiString aName = theName;
|
|
aName.LowerCase();
|
|
if (aName == "none")
|
|
{
|
|
theMode = Aspect_FM_NONE;
|
|
}
|
|
else if (aName == "centered")
|
|
{
|
|
theMode = Aspect_FM_CENTERED;
|
|
}
|
|
else if (aName == "tiled")
|
|
{
|
|
theMode = Aspect_FM_TILED;
|
|
}
|
|
else if (aName == "stretch")
|
|
{
|
|
theMode = Aspect_FM_STRETCH;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//! Parse gradient fill method.
|
|
static bool parseGradientMode (const TCollection_AsciiString& theName,
|
|
Aspect_GradientFillMethod& theMode)
|
|
{
|
|
TCollection_AsciiString aName = theName;
|
|
aName.LowerCase();
|
|
if (aName == "none")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_None;
|
|
}
|
|
else if (aName == "hor"
|
|
|| aName == "horizontal")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Horizontal;
|
|
}
|
|
else if (aName == "ver"
|
|
|| aName == "vert"
|
|
|| aName == "vertical")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Vertical;
|
|
}
|
|
else if (aName == "diag"
|
|
|| aName == "diagonal"
|
|
|| aName == "diag1"
|
|
|| aName == "diagonal1")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Diagonal1;
|
|
}
|
|
else if (aName == "diag2"
|
|
|| aName == "diagonal2")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Diagonal2;
|
|
}
|
|
else if (aName == "corner1")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Corner1;
|
|
}
|
|
else if (aName == "corner2")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Corner2;
|
|
}
|
|
else if (aName == "corner3")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Corner3;
|
|
}
|
|
else if (aName == "corner4")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Corner4;
|
|
}
|
|
else if (aName == "ellip"
|
|
|| aName == "elliptical")
|
|
{
|
|
theMode = Aspect_GradientFillMethod_Elliptical;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VBackground
|
|
//purpose :
|
|
//==============================================================================
|
|
static int VBackground (Draw_Interpretor& theDI,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
if (theNbArgs < 2)
|
|
{
|
|
theDI << "Syntax error: wrong number of arguments";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aCmdName (theArgVec[0]);
|
|
bool isDefault = aCmdName == "vsetdefaultbg";
|
|
Standard_Integer aNbColors = 0;
|
|
Quantity_ColorRGBA aColors[2];
|
|
|
|
Aspect_GradientFillMethod aGradientMode = Aspect_GradientFillMethod_None;
|
|
bool hasGradientMode = false;
|
|
|
|
TCollection_AsciiString anImagePath;
|
|
Aspect_FillMethod anImageMode = Aspect_FM_CENTERED;
|
|
bool hasImageMode = false;
|
|
|
|
bool isSkydomeBg = false;
|
|
Aspect_SkydomeBackground aSkydomeAspect;
|
|
|
|
NCollection_Sequence<TCollection_AsciiString> aCubeMapSeq;
|
|
Graphic3d_CubeMapOrder aCubeOrder = Graphic3d_CubeMapOrder::Default();
|
|
bool isCubeZInverted = false;
|
|
bool isSRgb = true;
|
|
|
|
int toUseIBL = 1;
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArg == "-default"
|
|
|| anArg == "-def")
|
|
{
|
|
isDefault = true;
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-imagefile"
|
|
|| anArg == "-imgfile"
|
|
|| anArg == "-image"
|
|
|| anArg == "-img"))
|
|
{
|
|
anImagePath = theArgVec[++anArgIter];
|
|
}
|
|
else if (anArg == "-skydome"
|
|
|| anArg == "-sky")
|
|
{
|
|
isSkydomeBg = true;
|
|
}
|
|
else if (anArgIter + 3 < theNbArgs
|
|
&& isSkydomeBg
|
|
&& anArg == "-sundir")
|
|
{
|
|
float aX = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
float aY = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
float aZ = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
aSkydomeAspect.SetSunDirection (gp_Dir(aX, aY, aZ));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& isSkydomeBg
|
|
&& anArg == "-cloud")
|
|
{
|
|
float aCloudy = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
aSkydomeAspect.SetCloudiness (aCloudy);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& isSkydomeBg
|
|
&& anArg == "-time")
|
|
{
|
|
float aTime = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
aSkydomeAspect.SetTimeParameter (aTime);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& isSkydomeBg
|
|
&& anArg == "-fog")
|
|
{
|
|
float aFoggy = (float) Draw::Atof (theArgVec[++anArgIter]);
|
|
aSkydomeAspect.SetFogginess (aFoggy);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& isSkydomeBg
|
|
&& anArg == "-size")
|
|
{
|
|
Standard_Integer aSize = Draw::Atoi (theArgVec[++anArgIter]);
|
|
aSkydomeAspect.SetSize (aSize);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& aCubeMapSeq.IsEmpty()
|
|
&& (anArg == "-cubemap"
|
|
|| anArg == "-cmap"
|
|
|| anArg == "-cm"))
|
|
{
|
|
aCubeMapSeq.Append (theArgVec[++anArgIter]);
|
|
for (Standard_Integer aCubeSideIter = 1; anArgIter + aCubeSideIter < theNbArgs; ++aCubeSideIter)
|
|
{
|
|
TCollection_AsciiString aSideArg (theArgVec[anArgIter + aCubeSideIter]);
|
|
if (!aSideArg.IsEmpty()
|
|
&& aSideArg.Value (1) == '-')
|
|
{
|
|
break;
|
|
}
|
|
|
|
aCubeMapSeq.Append (aSideArg);
|
|
if (aCubeMapSeq.Size() == 6)
|
|
{
|
|
anArgIter += 5;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (aCubeMapSeq.Size() > 1
|
|
&& aCubeMapSeq.Size() < 6)
|
|
{
|
|
aCubeMapSeq.Remove (2, aCubeMapSeq.Size());
|
|
}
|
|
}
|
|
else if (anArgIter + 6 < theNbArgs
|
|
&& anArg == "-order")
|
|
{
|
|
for (Standard_Integer aCubeSideIter = 0; aCubeSideIter < 6; ++aCubeSideIter)
|
|
{
|
|
Standard_Integer aSideArg = 0;
|
|
if (!Draw::ParseInteger (theArgVec[anArgIter + aCubeSideIter + 1], aSideArg)
|
|
|| aSideArg < 0
|
|
|| aSideArg > 5)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
aCubeOrder.Set ((Graphic3d_CubeMapSide )aCubeSideIter, (unsigned char )aSideArg);
|
|
}
|
|
if (!aCubeOrder.IsValid())
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
anArgIter += 6;
|
|
}
|
|
else if (anArg == "-invertedz"
|
|
|| anArg == "-noinvertedz"
|
|
|| anArg == "-invz"
|
|
|| anArg == "-noinvz")
|
|
{
|
|
isCubeZInverted = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
}
|
|
else if (anArg == "-pbrenv"
|
|
|| anArg == "-nopbrenv"
|
|
|| anArg == "-ibl"
|
|
|| anArg == "-noibl")
|
|
{
|
|
toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
|
|
if (anArgIter + 1 < theNbArgs)
|
|
{
|
|
TCollection_AsciiString anIblArg (theArgVec[anArgIter + 1]);
|
|
anIblArg.LowerCase();
|
|
if (anIblArg == "keep"
|
|
|| anIblArg == "-1")
|
|
{
|
|
toUseIBL = -1;
|
|
++anArgIter;
|
|
}
|
|
else if (anIblArg == "ibl"
|
|
|| anIblArg == "1"
|
|
|| anIblArg == "on")
|
|
{
|
|
toUseIBL = !anArg.StartsWith ("-no") ? 1 : 0;
|
|
++anArgIter;
|
|
}
|
|
else if (anIblArg == "noibl"
|
|
|| anIblArg == "0"
|
|
|| anIblArg == "off")
|
|
{
|
|
toUseIBL = !anArg.StartsWith ("-no") ? 0 : 1;
|
|
++anArgIter;
|
|
}
|
|
}
|
|
}
|
|
else if (anArg == "-srgb"
|
|
|| anArg == "-nosrgb")
|
|
{
|
|
isSRgb = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
|
|
}
|
|
else if (aNbColors < 2
|
|
&& (anArg == "-color"
|
|
|| anArg == "-col"))
|
|
{
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColors[aNbColors].ChangeRGB());
|
|
if (aNbParsed == 0)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
anArgIter += aNbParsed;
|
|
++aNbColors;
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-gradientmode"
|
|
|| anArg == "-gradmode"
|
|
|| anArg == "-gradmd"
|
|
|| anArg == "-grmode"
|
|
|| anArg == "-grmd")
|
|
&& parseGradientMode (theArgVec[anArgIter + 1], aGradientMode))
|
|
{
|
|
++anArgIter;
|
|
hasGradientMode = true;
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-imagemode"
|
|
|| anArg == "-imgmode"
|
|
|| anArg == "-imagemd"
|
|
|| anArg == "-imgmd")
|
|
&& parseImageMode (theArgVec[anArgIter + 1], anImageMode))
|
|
{
|
|
++anArgIter;
|
|
hasImageMode = true;
|
|
}
|
|
else if (aNbColors == 0
|
|
&& anArgIter + 2 < theNbArgs
|
|
&& (anArg == "-gradient"
|
|
|| anArg == "-grad"
|
|
|| anArg == "-gr"))
|
|
{
|
|
Standard_Integer aNbParsed1 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColors[aNbColors].ChangeRGB());
|
|
anArgIter += aNbParsed1;
|
|
++aNbColors;
|
|
if (aNbParsed1 == 0)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
Standard_Integer aNbParsed2 = Draw::ParseColor (theNbArgs - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColors[aNbColors].ChangeRGB());
|
|
anArgIter += aNbParsed2;
|
|
++aNbColors;
|
|
if (aNbParsed2 == 0)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (parseGradientMode (theArgVec[anArgIter], aGradientMode))
|
|
{
|
|
hasGradientMode = true;
|
|
}
|
|
else if (aNbColors < 2
|
|
&& (Quantity_ColorRGBA::ColorFromName(theArgVec[anArgIter], aColors[aNbColors])
|
|
|| Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColors[aNbColors])))
|
|
{
|
|
++aNbColors;
|
|
}
|
|
else if (anImagePath.IsEmpty()
|
|
&& aNbColors == 0
|
|
&& !hasGradientMode
|
|
&& aCubeMapSeq.IsEmpty())
|
|
{
|
|
anImagePath = theArgVec[anArgIter];
|
|
}
|
|
else
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!isDefault
|
|
&& aView.IsNull())
|
|
{
|
|
theDI << "Error: no active viewer";
|
|
return 1;
|
|
}
|
|
else if (isDefault
|
|
&& aNbColors == 0
|
|
&& !hasGradientMode)
|
|
{
|
|
theDI << "Syntax error at '-default'";
|
|
return 1;
|
|
}
|
|
|
|
if (aNbColors == 1)
|
|
{
|
|
if (isDefault)
|
|
{
|
|
ViewerTest_DefaultBackground.GradientColor1 = Quantity_Color();
|
|
ViewerTest_DefaultBackground.GradientColor2 = Quantity_Color();
|
|
ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_None;
|
|
ViewerTest_DefaultBackground.FlatColor = aColors[0].GetRGB();
|
|
ViewerTest_DefaultBackground.SetDefaultGradient();
|
|
ViewerTest_DefaultBackground.SetDefaultColor();
|
|
}
|
|
else
|
|
{
|
|
aView->SetBgGradientStyle (hasGradientMode ? aGradientMode : Aspect_GradientFillMethod_None);
|
|
aView->SetBackgroundColor (aColors[0].GetRGB());
|
|
if (toUseIBL != -1)
|
|
{
|
|
aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
|
|
}
|
|
}
|
|
}
|
|
else if (aNbColors == 2)
|
|
{
|
|
if (isDefault)
|
|
{
|
|
ViewerTest_DefaultBackground.GradientColor1 = aColors[0].GetRGB();
|
|
ViewerTest_DefaultBackground.GradientColor2 = aColors[1].GetRGB();
|
|
if (hasGradientMode)
|
|
{
|
|
ViewerTest_DefaultBackground.FillMethod = aGradientMode;
|
|
}
|
|
else if (ViewerTest_DefaultBackground.FillMethod == Aspect_GradientFillMethod_None)
|
|
{
|
|
ViewerTest_DefaultBackground.FillMethod = Aspect_GradientFillMethod_Vertical;
|
|
}
|
|
ViewerTest_DefaultBackground.SetDefaultGradient();
|
|
}
|
|
else
|
|
{
|
|
if (!hasGradientMode)
|
|
{
|
|
aGradientMode = aView->GradientBackground().BgGradientFillMethod();
|
|
if (aGradientMode == Aspect_GradientFillMethod_None)
|
|
{
|
|
aGradientMode = Aspect_GradientFillMethod_Vertical;
|
|
}
|
|
}
|
|
aView->SetBgGradientColors (aColors[0].GetRGB(), aColors[1].GetRGB(), aGradientMode);
|
|
if (toUseIBL != -1)
|
|
{
|
|
aView->SetBackgroundCubeMap (Handle(Graphic3d_CubeMap)(), true);
|
|
}
|
|
}
|
|
}
|
|
else if (hasGradientMode)
|
|
{
|
|
if (isDefault)
|
|
{
|
|
ViewerTest_DefaultBackground.FillMethod = aGradientMode;
|
|
ViewerTest_DefaultBackground.SetDefaultGradient();
|
|
}
|
|
else
|
|
{
|
|
aView->SetBgGradientStyle (aGradientMode);
|
|
}
|
|
}
|
|
|
|
if (!anImagePath.IsEmpty())
|
|
{
|
|
Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2D (anImagePath);
|
|
aTextureMap->DisableModulate();
|
|
aTextureMap->SetColorMap (isSRgb);
|
|
if (!aTextureMap->IsDone())
|
|
{
|
|
theDI << "Syntax error at '" << anImagePath << "'";
|
|
return 1;
|
|
}
|
|
aView->SetBackgroundImage (aTextureMap, anImageMode);
|
|
}
|
|
else if (hasImageMode)
|
|
{
|
|
aView->SetBgImageStyle (anImageMode);
|
|
}
|
|
|
|
if (isSkydomeBg)
|
|
{
|
|
aView->SetBackgroundSkydome (aSkydomeAspect, toUseIBL != -1);
|
|
}
|
|
|
|
if (!aCubeMapSeq.IsEmpty())
|
|
{
|
|
Handle(Graphic3d_CubeMap) aCubeMap;
|
|
if (aCubeMapSeq.Size() == 1)
|
|
{
|
|
aCubeMap = new Graphic3d_CubeMapPacked (aCubeMapSeq.First(), aCubeOrder.Validated());
|
|
}
|
|
else
|
|
{
|
|
NCollection_Array1<TCollection_AsciiString> aCubeMapArr (0, 5);
|
|
Standard_Integer aCubeSide = 0;
|
|
for (NCollection_Sequence<TCollection_AsciiString>::Iterator aFileIter (aCubeMapSeq); aFileIter.More(); aFileIter.Next(), ++aCubeSide)
|
|
{
|
|
aCubeMapArr[aCubeSide] = aFileIter.Value();
|
|
}
|
|
aCubeMap = new Graphic3d_CubeMapSeparate (aCubeMapArr);
|
|
}
|
|
|
|
aCubeMap->SetZInversion (isCubeZInverted);
|
|
aCubeMap->SetColorMap (isSRgb);
|
|
|
|
aCubeMap->GetParams()->SetFilter (Graphic3d_TOTF_BILINEAR);
|
|
aCubeMap->GetParams()->SetRepeat (false);
|
|
aCubeMap->GetParams()->SetTextureUnit (Graphic3d_TextureUnit_EnvMap);
|
|
|
|
aView->SetBackgroundCubeMap (aCubeMap, toUseIBL != -1);
|
|
}
|
|
if (toUseIBL != -1
|
|
&& !aView.IsNull())
|
|
{
|
|
aView->SetImageBasedLighting (toUseIBL == 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VScale
|
|
//purpose : View Scaling
|
|
//==============================================================================
|
|
|
|
static int VScale(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
|
{
|
|
Handle(V3d_View) V3dView = ViewerTest::CurrentView();
|
|
if ( V3dView.IsNull() ) return 1;
|
|
|
|
if ( argc != 4 ) {
|
|
di << argv[0] << "Invalid number of arguments\n";
|
|
return 1;
|
|
}
|
|
V3dView->SetAxialScale( Draw::Atof(argv[1]), Draw::Atof(argv[2]), Draw::Atof(argv[3]) );
|
|
return 0;
|
|
}
|
|
//==============================================================================
|
|
//function : VZBuffTrihedron
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VZBuffTrihedron (Draw_Interpretor& /*theDI*/,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
|
|
Aspect_TypeOfTriedronPosition aPosition = Aspect_TOTP_LEFT_LOWER;
|
|
V3d_TypeOfVisualization aVisType = V3d_ZBUFFER;
|
|
Quantity_Color aLabelsColorX = Quantity_NOC_WHITE;
|
|
Quantity_Color aLabelsColorY = Quantity_NOC_WHITE;
|
|
Quantity_Color aLabelsColorZ = Quantity_NOC_WHITE;
|
|
Quantity_Color anArrowColorX = Quantity_NOC_RED;
|
|
Quantity_Color anArrowColorY = Quantity_NOC_GREEN;
|
|
Quantity_Color anArrowColorZ = Quantity_NOC_BLUE1;
|
|
Standard_Real aScale = 0.1;
|
|
Standard_Real aSizeRatio = 0.8;
|
|
Standard_Real anArrowDiam = 0.05;
|
|
Standard_Integer aNbFacets = 12;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg = theArgVec[anArgIter];
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (aFlag))
|
|
{
|
|
continue;
|
|
}
|
|
else if (aFlag == "-on")
|
|
{
|
|
continue;
|
|
}
|
|
else if (aFlag == "-off")
|
|
{
|
|
aView->TriedronErase();
|
|
return 0;
|
|
}
|
|
else if (aFlag == "-pos"
|
|
|| aFlag == "-position"
|
|
|| aFlag == "-corner")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
if (!ViewerTest::ParseCorner (theArgVec[anArgIter], aPosition))
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "' - unknown position '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-type")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aTypeName (theArgVec[anArgIter]);
|
|
aTypeName.LowerCase();
|
|
if (aTypeName == "wireframe"
|
|
|| aTypeName == "wire")
|
|
{
|
|
aVisType = V3d_WIREFRAME;
|
|
}
|
|
else if (aTypeName == "zbuffer"
|
|
|| aTypeName == "shaded")
|
|
{
|
|
aVisType = V3d_ZBUFFER;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "' - unknown type '" << aTypeName << "'";
|
|
}
|
|
}
|
|
else if (aFlag == "-scale")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aScale = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-size"
|
|
|| aFlag == "-sizeratio")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aSizeRatio = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-arrowdiam"
|
|
|| aFlag == "-arrowdiameter")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
anArrowDiam = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-nbfacets")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aNbFacets = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-colorlabel"
|
|
|| aFlag == "-colorlabels"
|
|
|| aFlag == "-colorlabelx"
|
|
|| aFlag == "-colorlabely"
|
|
|| aFlag == "-colorlabelz"
|
|
|| aFlag == "-colorarrowx"
|
|
|| aFlag == "-colorarrowy"
|
|
|| aFlag == "-colorarrowz")
|
|
{
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - anArgIter - 1,
|
|
theArgVec + anArgIter + 1,
|
|
aColor);
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
if (aFlag == "-colorarrowx")
|
|
{
|
|
anArrowColorX = aColor;
|
|
}
|
|
else if (aFlag == "-colorarrowy")
|
|
{
|
|
anArrowColorY = aColor;
|
|
}
|
|
else if (aFlag == "-colorarrowz")
|
|
{
|
|
anArrowColorZ = aColor;
|
|
}
|
|
else if (aFlag == "-colorlabelx")
|
|
{
|
|
aLabelsColorX = aColor;
|
|
}
|
|
else if (aFlag == "-colorlabely")
|
|
{
|
|
aLabelsColorY = aColor;
|
|
}
|
|
else if (aFlag == "-colorlabelz")
|
|
{
|
|
aLabelsColorZ = aColor;
|
|
}
|
|
else
|
|
{
|
|
aLabelsColorZ = aLabelsColorY = aLabelsColorX = aColor;
|
|
}
|
|
anArgIter += aNbParsed;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
const Handle(V3d_Trihedron)& aTrihedron = aView->Trihedron();
|
|
aTrihedron->SetArrowsColor (anArrowColorX, anArrowColorY, anArrowColorZ);
|
|
aTrihedron->SetLabelsColor (aLabelsColorX, aLabelsColorY, aLabelsColorZ);
|
|
aTrihedron->SetSizeRatio (aSizeRatio);
|
|
aTrihedron->SetNbFacets (aNbFacets);
|
|
aTrihedron->SetArrowDiameter(anArrowDiam);
|
|
aTrihedron->SetScale (aScale);
|
|
aTrihedron->SetPosition (aPosition);
|
|
aTrihedron->SetWireframe (aVisType == V3d_WIREFRAME);
|
|
aTrihedron->Display (aView);
|
|
|
|
aView->ZFitAll();
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VRotate
|
|
//purpose : Camera Rotating
|
|
//==============================================================================
|
|
|
|
static int VRotate (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean hasFlags = Standard_False;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg (theArgVec[anArgIter]);
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (aFlag == "-mousestart"
|
|
|| aFlag == "-mousefrom")
|
|
{
|
|
hasFlags = Standard_True;
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
|
|
Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
|
|
aView->StartRotation (anX, anY);
|
|
}
|
|
else if (aFlag == "-mousemove")
|
|
{
|
|
hasFlags = Standard_True;
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer anX = Draw::Atoi (theArgVec[++anArgIter]);
|
|
Standard_Integer anY = Draw::Atoi (theArgVec[++anArgIter]);
|
|
aView->Rotation (anX, anY);
|
|
}
|
|
else if (theArgNb != 4
|
|
&& theArgNb != 7)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (hasFlags)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (theArgNb == 4)
|
|
{
|
|
Standard_Real anAX = Draw::Atof (theArgVec[1]);
|
|
Standard_Real anAY = Draw::Atof (theArgVec[2]);
|
|
Standard_Real anAZ = Draw::Atof (theArgVec[3]);
|
|
aView->Rotate (anAX, anAY, anAZ);
|
|
return 0;
|
|
}
|
|
else if (theArgNb == 7)
|
|
{
|
|
Standard_Real anAX = Draw::Atof (theArgVec[1]);
|
|
Standard_Real anAY = Draw::Atof (theArgVec[2]);
|
|
Standard_Real anAZ = Draw::Atof (theArgVec[3]);
|
|
|
|
Standard_Real anX = Draw::Atof (theArgVec[4]);
|
|
Standard_Real anY = Draw::Atof (theArgVec[5]);
|
|
Standard_Real anZ = Draw::Atof (theArgVec[6]);
|
|
|
|
aView->Rotate (anAX, anAY, anAZ, anX, anY, anZ);
|
|
return 0;
|
|
}
|
|
|
|
Message::SendFail ("Error: Invalid number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VZoom
|
|
//purpose : View zoom in / out (relative to current zoom)
|
|
//==============================================================================
|
|
|
|
static int VZoom( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
|
|
Handle(V3d_View) V3dView = ViewerTest::CurrentView();
|
|
if ( V3dView.IsNull() ) {
|
|
return 1;
|
|
}
|
|
|
|
if ( argc == 2 ) {
|
|
Standard_Real coef = Draw::Atof(argv[1]);
|
|
if ( coef <= 0.0 ) {
|
|
di << argv[1] << "Invalid value\n";
|
|
return 1;
|
|
}
|
|
V3dView->SetZoom( Draw::Atof(argv[1]) );
|
|
return 0;
|
|
} else {
|
|
di << argv[0] << " Invalid number of arguments\n";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VPan
|
|
//purpose : View panning (in pixels)
|
|
//==============================================================================
|
|
|
|
static int VPan( Draw_Interpretor& di, Standard_Integer argc, const char** argv ) {
|
|
Handle(V3d_View) V3dView = ViewerTest::CurrentView();
|
|
if ( V3dView.IsNull() ) return 1;
|
|
|
|
if ( argc == 3 ) {
|
|
V3dView->Pan( Draw::Atoi(argv[1]), Draw::Atoi(argv[2]) );
|
|
return 0;
|
|
} else {
|
|
di << argv[0] << " Invalid number of arguments\n";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VPlace
|
|
//purpose : Place the point (in pixels) at the center of the window
|
|
//==============================================================================
|
|
static int VPlace (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNb, const char** theArgs)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgNb != 3)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
aView->Place (Draw::Atoi (theArgs[1]), Draw::Atoi (theArgs[2]), aView->Scale());
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int VColorScale (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aContext.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
if (theArgNb <= 1)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at command '" << theArgVec[0] << "'";
|
|
return 1;
|
|
}
|
|
|
|
Handle(AIS_ColorScale) aColorScale;
|
|
if (GetMapOfAIS().IsBound2 (theArgVec[1]))
|
|
{
|
|
// find existing object
|
|
aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
|
|
if (aColorScale.IsNull())
|
|
{
|
|
Message::SendFail() << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (theArgNb <= 2)
|
|
{
|
|
if (aColorScale.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: colorscale with a given name does not exist";
|
|
return 1;
|
|
}
|
|
|
|
theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n"
|
|
<< "Min range: " << aColorScale->GetMin() << "\n"
|
|
<< "Max range: " << aColorScale->GetMax() << "\n"
|
|
<< "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n"
|
|
<< "Text height: " << aColorScale->GetTextHeight() << "\n"
|
|
<< "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n"
|
|
<< "Color scale title: " << aColorScale->GetTitle() << "\n"
|
|
<< "Label position: ";
|
|
switch (aColorScale->GetLabelPosition())
|
|
{
|
|
case Aspect_TOCSP_NONE:
|
|
theDI << "None\n";
|
|
break;
|
|
case Aspect_TOCSP_LEFT:
|
|
theDI << "Left\n";
|
|
break;
|
|
case Aspect_TOCSP_RIGHT:
|
|
theDI << "Right\n";
|
|
break;
|
|
case Aspect_TOCSP_CENTER:
|
|
theDI << "Center\n";
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (aColorScale.IsNull())
|
|
{
|
|
aColorScale = new AIS_ColorScale();
|
|
aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD);
|
|
aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
|
|
}
|
|
|
|
ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
|
|
for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg = theArgVec[anArgIter];
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (aFlag))
|
|
{
|
|
continue;
|
|
}
|
|
else if (aFlag == "-range")
|
|
{
|
|
if (anArgIter + 3 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]);
|
|
const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]);
|
|
const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]);
|
|
if (!aRangeMin.IsRealValue (Standard_True)
|
|
|| !aRangeMax.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail ("Syntax error: the range values should be real");
|
|
return 1;
|
|
}
|
|
else if (!aNbIntervals.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: the number of intervals should be integer");
|
|
return 1;
|
|
}
|
|
|
|
aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue());
|
|
aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue());
|
|
}
|
|
else if (aFlag == "-font")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
TCollection_AsciiString aFontArg(theArgVec[anArgIter + 1]);
|
|
if (!aFontArg.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: HeightFont value should be integer");
|
|
return 1;
|
|
}
|
|
|
|
aColorScale->SetTextHeight (aFontArg.IntegerValue());
|
|
anArgIter += 1;
|
|
}
|
|
else if (aFlag == "-textpos")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]);
|
|
aTextPosArg.LowerCase();
|
|
Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE;
|
|
if (aTextPosArg == "none")
|
|
{
|
|
aLabPosition = Aspect_TOCSP_NONE;
|
|
}
|
|
else if (aTextPosArg == "left")
|
|
{
|
|
aLabPosition = Aspect_TOCSP_LEFT;
|
|
}
|
|
else if (aTextPosArg == "right")
|
|
{
|
|
aLabPosition = Aspect_TOCSP_RIGHT;
|
|
}
|
|
else if (aTextPosArg == "center")
|
|
{
|
|
aLabPosition = Aspect_TOCSP_CENTER;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown position '" << aTextPosArg << "'";
|
|
return 1;
|
|
}
|
|
aColorScale->SetLabelPosition (aLabPosition);
|
|
}
|
|
else if (aFlag == "-logarithmic"
|
|
|| aFlag == "-log")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Synta error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean IsLog;
|
|
if (!Draw::ParseOnOff(theArgVec[++anArgIter], IsLog))
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aColorScale->SetLogarithmic (IsLog);
|
|
}
|
|
else if (aFlag == "-huerange"
|
|
|| aFlag == "-hue")
|
|
{
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]);
|
|
const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]);
|
|
aColorScale->SetHueRange (aHueMin, aHueMax);
|
|
}
|
|
else if (aFlag == "-colorrange")
|
|
{
|
|
Quantity_Color aColorMin, aColorMax;
|
|
Standard_Integer aNbParsed1 = Draw::ParseColor (theArgNb - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColorMin);
|
|
anArgIter += aNbParsed1;
|
|
Standard_Integer aNbParsed2 = Draw::ParseColor (theArgNb - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColorMax);
|
|
anArgIter += aNbParsed2;
|
|
if (aNbParsed1 == 0
|
|
|| aNbParsed2 == 0)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aColorScale->SetColorRange (aColorMin, aColorMax);
|
|
}
|
|
else if (aFlag == "-reversed"
|
|
|| aFlag == "-inverted"
|
|
|| aFlag == "-topdown"
|
|
|| aFlag == "-bottomup")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable);
|
|
}
|
|
else if (aFlag == "-smooth"
|
|
|| aFlag == "-smoothtransition")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aColorScale->SetSmoothTransition (toEnable);
|
|
}
|
|
else if (aFlag == "-xy")
|
|
{
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString anX (theArgVec[++anArgIter]);
|
|
const TCollection_AsciiString anY (theArgVec[++anArgIter]);
|
|
if (!anX.IsIntegerValue()
|
|
|| !anY.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: coordinates should be integer values");
|
|
return 1;
|
|
}
|
|
|
|
aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue());
|
|
}
|
|
else if (aFlag == "-width"
|
|
|| aFlag == "-w"
|
|
|| aFlag == "-breadth")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]);
|
|
if (!aBreadth.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: a width should be an integer value");
|
|
return 1;
|
|
}
|
|
aColorScale->SetBreadth (aBreadth.IntegerValue());
|
|
}
|
|
else if (aFlag == "-height"
|
|
|| aFlag == "-h")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aHeight (theArgVec[++anArgIter]);
|
|
if (!aHeight.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: a width should be an integer value");
|
|
return 1;
|
|
}
|
|
aColorScale->SetHeight (aHeight.IntegerValue());
|
|
}
|
|
else if (aFlag == "-color")
|
|
{
|
|
if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong color type. Call -colors before to set user-specified colors");
|
|
return 1;
|
|
}
|
|
else if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString anInd (theArgVec[++anArgIter]);
|
|
if (!anInd.IsIntegerValue())
|
|
{
|
|
Message::SendFail ("Syntax error: Index value should be integer");
|
|
return 1;
|
|
}
|
|
const Standard_Integer anIndex = anInd.IntegerValue();
|
|
if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals())
|
|
{
|
|
Message::SendFail() << "Syntax error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals();
|
|
return 1;
|
|
}
|
|
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColor);
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aColorScale->SetIntervalColor (aColor, anIndex);
|
|
aColorScale->SetColorType (Aspect_TOCSD_USER);
|
|
anArgIter += aNbParsed;
|
|
}
|
|
else if (aFlag == "-label")
|
|
{
|
|
if (aColorScale->GetColorType() != Aspect_TOCSD_USER)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong label type. Call -labels before to set user-specified labels");
|
|
return 1;
|
|
}
|
|
else if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]);
|
|
if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1)
|
|
{
|
|
Message::SendFail() << "Syntax error: Index value should be within range 1.." << (aColorScale->GetNumberOfIntervals() + 1);
|
|
return 1;
|
|
}
|
|
|
|
TCollection_ExtendedString aText (theArgVec[anArgIter + 2], Standard_True);
|
|
aColorScale->SetLabel (aText, anIndex);
|
|
aColorScale->SetLabelType (Aspect_TOCSD_USER);
|
|
anArgIter += 2;
|
|
}
|
|
else if (aFlag == "-labelat"
|
|
|| aFlag == "-labat"
|
|
|| aFlag == "-labelatborder"
|
|
|| aFlag == "-labatborder"
|
|
|| aFlag == "-labelatcenter"
|
|
|| aFlag == "-labatcenter")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (aFlag == "-labelat"
|
|
|| aFlag == "-labat")
|
|
{
|
|
Standard_Integer aLabAtBorder = -1;
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
TCollection_AsciiString anAtBorder (theArgVec[anArgIter]);
|
|
anAtBorder.LowerCase();
|
|
if (anAtBorder == "border")
|
|
{
|
|
aLabAtBorder = 1;
|
|
}
|
|
else if (anAtBorder == "center")
|
|
{
|
|
aLabAtBorder = 0;
|
|
}
|
|
}
|
|
if (aLabAtBorder == -1)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
toEnable = (aLabAtBorder == 1);
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter"
|
|
|| aFlag == "-labatcenter"
|
|
? !toEnable
|
|
: toEnable);
|
|
}
|
|
else if (aFlag == "-colors")
|
|
{
|
|
Aspect_SequenceOfColor aSeq;
|
|
for (;;)
|
|
{
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theArgNb - (anArgIter + 1),
|
|
theArgVec + (anArgIter + 1),
|
|
aColor);
|
|
if (aNbParsed == 0)
|
|
{
|
|
break;
|
|
}
|
|
anArgIter += aNbParsed;
|
|
aSeq.Append (aColor);
|
|
}
|
|
if (aSeq.Length() != aColorScale->GetNumberOfIntervals())
|
|
{
|
|
Message::SendFail() << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the "
|
|
<< aColorScale->GetNumberOfIntervals() << " intervals";
|
|
return 1;
|
|
}
|
|
|
|
aColorScale->SetColors (aSeq);
|
|
aColorScale->SetColorType (Aspect_TOCSD_USER);
|
|
}
|
|
else if (aFlag == "-uniform")
|
|
{
|
|
const Standard_Real aLightness = Draw::Atof (theArgVec[++anArgIter]);
|
|
const Standard_Real aHueStart = Draw::Atof (theArgVec[++anArgIter]);
|
|
const Standard_Real aHueEnd = Draw::Atof (theArgVec[++anArgIter]);
|
|
aColorScale->SetUniformColors (aLightness, aHueStart, aHueEnd);
|
|
aColorScale->SetColorType (Aspect_TOCSD_USER);
|
|
}
|
|
else if (aFlag == "-labels"
|
|
|| aFlag == "-freelabels")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder()
|
|
? aColorScale->GetNumberOfIntervals() + 1
|
|
: aColorScale->GetNumberOfIntervals();
|
|
if (aFlag == "-freelabels")
|
|
{
|
|
++anArgIter;
|
|
aNbLabels = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
if (anArgIter + aNbLabels >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error: not enough arguments. " << aNbLabels << " text labels are expected";
|
|
return 1;
|
|
}
|
|
|
|
TColStd_SequenceOfExtendedString aSeq;
|
|
for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter)
|
|
{
|
|
aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter], Standard_True));
|
|
}
|
|
aColorScale->SetLabels (aSeq);
|
|
aColorScale->SetLabelType (Aspect_TOCSD_USER);
|
|
}
|
|
else if (aFlag == "-title")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean isTwoArgs = Standard_False;
|
|
if (anArgIter + 2 < theArgNb)
|
|
{
|
|
TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]);
|
|
aSecondArg.LowerCase();
|
|
Standard_DISABLE_DEPRECATION_WARNINGS
|
|
if (aSecondArg == "none")
|
|
{
|
|
aColorScale->SetTitlePosition (Aspect_TOCSP_NONE);
|
|
isTwoArgs = Standard_True;
|
|
}
|
|
else if (aSecondArg == "left")
|
|
{
|
|
aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT);
|
|
isTwoArgs = Standard_True;
|
|
}
|
|
else if (aSecondArg == "right")
|
|
{
|
|
aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT);
|
|
isTwoArgs = Standard_True;
|
|
}
|
|
else if (aSecondArg == "center")
|
|
{
|
|
aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER);
|
|
isTwoArgs = Standard_True;
|
|
}
|
|
Standard_ENABLE_DEPRECATION_WARNINGS
|
|
}
|
|
|
|
TCollection_ExtendedString aTitle(theArgVec[anArgIter + 1], Standard_True);
|
|
aColorScale->SetTitle (aTitle);
|
|
if (isTwoArgs)
|
|
{
|
|
anArgIter += 1;
|
|
}
|
|
anArgIter += 1;
|
|
}
|
|
else if (aFlag == "-demoversion"
|
|
|| aFlag == "-demo")
|
|
{
|
|
aColorScale->SetPosition (0, 0);
|
|
aColorScale->SetTextHeight (16);
|
|
aColorScale->SetRange (0.0, 100.0);
|
|
aColorScale->SetNumberOfIntervals (10);
|
|
aColorScale->SetBreadth (0);
|
|
aColorScale->SetHeight (0);
|
|
aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT);
|
|
aColorScale->SetColorType (Aspect_TOCSD_AUTO);
|
|
aColorScale->SetLabelType (Aspect_TOCSD_AUTO);
|
|
}
|
|
else if (aFlag == "-findcolor")
|
|
{
|
|
if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString anArg1 (theArgVec[++anArgIter]);
|
|
|
|
if (!anArg1.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail ("Syntax error: the value should be real");
|
|
return 1;
|
|
}
|
|
|
|
Quantity_Color aColor;
|
|
aColorScale->FindColor (anArg1.RealValue(), aColor);
|
|
theDI << Quantity_Color::StringName (aColor.Name());
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg << " - unknown argument";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Standard_Integer aWinWidth = 0, aWinHeight = 0;
|
|
aView->Window()->Size (aWinWidth, aWinHeight);
|
|
if (aColorScale->GetBreadth() == 0)
|
|
{
|
|
aColorScale->SetBreadth (aWinWidth);
|
|
}
|
|
if (aColorScale->GetHeight() == 0)
|
|
{
|
|
aColorScale->SetHeight (aWinHeight);
|
|
}
|
|
aColorScale->SetToUpdate();
|
|
ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VGraduatedTrihedron
|
|
//purpose : Displays or hides a graduated trihedron
|
|
//==============================================================================
|
|
static Standard_Boolean GetColor (const TCollection_AsciiString& theValue,
|
|
Quantity_Color& theColor)
|
|
{
|
|
Quantity_NameOfColor aColorName;
|
|
TCollection_AsciiString aVal = theValue;
|
|
aVal.UpperCase();
|
|
if (!Quantity_Color::ColorFromName (aVal.ToCString(), aColorName))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
theColor = Quantity_Color (aColorName);
|
|
return Standard_True;
|
|
}
|
|
|
|
static int VGraduatedTrihedron (Draw_Interpretor& /*theDi*/, Standard_Integer theArgNum, const char** theArgs)
|
|
{
|
|
if (theArgNum < 2)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number of parameters. Type 'help"
|
|
<< theArgs[0] <<"' for more information";
|
|
return 1;
|
|
}
|
|
|
|
NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
|
|
TCollection_AsciiString aParseKey;
|
|
for (Standard_Integer anArgIt = 1; anArgIt < theArgNum; ++anArgIt)
|
|
{
|
|
TCollection_AsciiString anArg (theArgs [anArgIt]);
|
|
|
|
if (anArg.Value (1) == '-' && !anArg.IsRealValue (Standard_True))
|
|
{
|
|
aParseKey = anArg;
|
|
aParseKey.Remove (1);
|
|
aParseKey.LowerCase();
|
|
aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
|
|
continue;
|
|
}
|
|
|
|
if (aParseKey.IsEmpty())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
aMapOfArgs(aParseKey)->Append (anArg);
|
|
}
|
|
|
|
// Check parameters
|
|
for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
|
|
aMapIt.More(); aMapIt.Next())
|
|
{
|
|
const TCollection_AsciiString& aKey = aMapIt.Key();
|
|
const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
|
|
|
|
// Bool key, without arguments
|
|
if ((aKey.IsEqual ("on") || aKey.IsEqual ("off"))
|
|
&& anArgs->IsEmpty())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// One argument
|
|
if ( (aKey.IsEqual ("xname") || aKey.IsEqual ("yname") || aKey.IsEqual ("zname"))
|
|
&& anArgs->Length() == 1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// On/off arguments
|
|
if ((aKey.IsEqual ("xdrawname") || aKey.IsEqual ("ydrawname") || aKey.IsEqual ("zdrawname")
|
|
|| aKey.IsEqual ("xdrawticks") || aKey.IsEqual ("ydrawticks") || aKey.IsEqual ("zdrawticks")
|
|
|| aKey.IsEqual ("xdrawvalues") || aKey.IsEqual ("ydrawvalues") || aKey.IsEqual ("zdrawvalues")
|
|
|| aKey.IsEqual ("drawgrid") || aKey.IsEqual ("drawaxes"))
|
|
&& anArgs->Length() == 1 && (anArgs->Value(1).IsEqual ("on") || anArgs->Value(1).IsEqual ("off")))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// One string argument
|
|
if ( (aKey.IsEqual ("xnamecolor") || aKey.IsEqual ("ynamecolor") || aKey.IsEqual ("znamecolor")
|
|
|| aKey.IsEqual ("xcolor") || aKey.IsEqual ("ycolor") || aKey.IsEqual ("zcolor"))
|
|
&& anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// One integer argument
|
|
if ( (aKey.IsEqual ("xticks") || aKey.IsEqual ("yticks") || aKey.IsEqual ("zticks")
|
|
|| aKey.IsEqual ("xticklength") || aKey.IsEqual ("yticklength") || aKey.IsEqual ("zticklength")
|
|
|| aKey.IsEqual ("xnameoffset") || aKey.IsEqual ("ynameoffset") || aKey.IsEqual ("znameoffset")
|
|
|| aKey.IsEqual ("xvaluesoffset") || aKey.IsEqual ("yvaluesoffset") || aKey.IsEqual ("zvaluesoffset"))
|
|
&& anArgs->Length() == 1 && anArgs->Value(1).IsIntegerValue())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// One real argument
|
|
if ( aKey.IsEqual ("arrowlength")
|
|
&& anArgs->Length() == 1 && (anArgs->Value(1).IsIntegerValue() || anArgs->Value(1).IsRealValue (Standard_True)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Two string arguments
|
|
if ( (aKey.IsEqual ("namefont") || aKey.IsEqual ("valuesfont"))
|
|
&& anArgs->Length() == 1 && !anArgs->Value(1).IsIntegerValue() && !anArgs->Value(1).IsRealValue (Standard_True))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
TCollection_AsciiString aLowerKey;
|
|
aLowerKey = "-";
|
|
aLowerKey += aKey;
|
|
aLowerKey.LowerCase();
|
|
Message::SendFail() << "Syntax error: " << aLowerKey << " is unknown option, or the arguments are unacceptable.\n"
|
|
<< "Type help for more information";
|
|
return 1;
|
|
}
|
|
|
|
Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
|
|
if (anAISContext.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean toDisplay = Standard_True;
|
|
Quantity_Color aColor;
|
|
Graphic3d_GraduatedTrihedron aTrihedronData;
|
|
// Process parameters
|
|
Handle(TColStd_HSequenceOfAsciiString) aValues;
|
|
if (aMapOfArgs.Find ("off", aValues))
|
|
{
|
|
toDisplay = Standard_False;
|
|
}
|
|
|
|
// AXES NAMES
|
|
if (aMapOfArgs.Find ("xname", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetName (aValues->Value(1));
|
|
}
|
|
if (aMapOfArgs.Find ("yname", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetName (aValues->Value(1));
|
|
}
|
|
if (aMapOfArgs.Find ("zname", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetName (aValues->Value(1));
|
|
}
|
|
if (aMapOfArgs.Find ("xdrawname", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("ydrawname", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("zdrawname", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetDrawName (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("xnameoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("ynameoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("znameoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetNameOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
|
|
// COLORS
|
|
if (aMapOfArgs.Find ("xnamecolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -xnamecolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeXAxisAspect().SetNameColor (aColor);
|
|
}
|
|
if (aMapOfArgs.Find ("ynamecolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -ynamecolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeYAxisAspect().SetNameColor (aColor);
|
|
}
|
|
if (aMapOfArgs.Find ("znamecolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -znamecolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeZAxisAspect().SetNameColor (aColor);
|
|
}
|
|
if (aMapOfArgs.Find ("xcolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -xcolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeXAxisAspect().SetColor (aColor);
|
|
}
|
|
if (aMapOfArgs.Find ("ycolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -ycolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeYAxisAspect().SetColor (aColor);
|
|
}
|
|
if (aMapOfArgs.Find ("zcolor", aValues))
|
|
{
|
|
if (!GetColor (aValues->Value(1), aColor))
|
|
{
|
|
Message::SendFail ("Syntax error: -zcolor wrong color name");
|
|
return 1;
|
|
}
|
|
aTrihedronData.ChangeZAxisAspect().SetColor (aColor);
|
|
}
|
|
|
|
// TICKMARKS
|
|
if (aMapOfArgs.Find ("xticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("yticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("zticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetTickmarksNumber (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("xticklength", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("yticklength", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("zticklength", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetTickmarksLength (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("xdrawticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("ydrawticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("zdrawticks", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetDrawTickmarks (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
|
|
// VALUES
|
|
if (aMapOfArgs.Find ("xdrawvalues", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("ydrawvalues", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("zdrawvalues", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetDrawValues (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("xvaluesoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeXAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("yvaluesoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeYAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
if (aMapOfArgs.Find ("zvaluesoffset", aValues))
|
|
{
|
|
aTrihedronData.ChangeZAxisAspect().SetValuesOffset (aValues->Value(1).IntegerValue());
|
|
}
|
|
|
|
// ARROWS
|
|
if (aMapOfArgs.Find ("arrowlength", aValues))
|
|
{
|
|
aTrihedronData.SetArrowsLength ((Standard_ShortReal) aValues->Value(1).RealValue());
|
|
}
|
|
|
|
// FONTS
|
|
if (aMapOfArgs.Find ("namefont", aValues))
|
|
{
|
|
aTrihedronData.SetNamesFont (aValues->Value(1));
|
|
}
|
|
if (aMapOfArgs.Find ("valuesfont", aValues))
|
|
{
|
|
aTrihedronData.SetValuesFont (aValues->Value(1));
|
|
}
|
|
|
|
if (aMapOfArgs.Find ("drawgrid", aValues))
|
|
{
|
|
aTrihedronData.SetDrawGrid (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
if (aMapOfArgs.Find ("drawaxes", aValues))
|
|
{
|
|
aTrihedronData.SetDrawAxes (aValues->Value(1).IsEqual ("on"));
|
|
}
|
|
|
|
// The final step: display of erase trihedron
|
|
if (toDisplay)
|
|
{
|
|
ViewerTest::CurrentView()->GraduatedTrihedronDisplay (aTrihedronData);
|
|
}
|
|
else
|
|
{
|
|
ViewerTest::CurrentView()->GraduatedTrihedronErase();
|
|
}
|
|
|
|
ViewerTest::GetAISContext()->UpdateCurrentViewer();
|
|
ViewerTest::CurrentView()->Redraw();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VTile
|
|
//purpose :
|
|
//==============================================================================
|
|
static int VTile (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Graphic3d_CameraTile aTile = aView->Camera()->Tile();
|
|
if (theArgNb < 2)
|
|
{
|
|
theDI << "Total size: " << aTile.TotalSize.x() << " " << aTile.TotalSize.y() << "\n"
|
|
<< "Tile size: " << aTile.TileSize.x() << " " << aTile.TileSize.y() << "\n"
|
|
<< "Lower left: " << aTile.Offset.x() << " " << aTile.Offset.y() << "\n";
|
|
return 0;
|
|
}
|
|
|
|
aView->Window()->Size (aTile.TileSize.x(), aTile.TileSize.y());
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anArg == "-lowerleft"
|
|
|| anArg == "-upperleft")
|
|
{
|
|
if (anArgIter + 3 < theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
aTile.IsTopDown = (anArg == "-upperleft") == Standard_True;
|
|
aTile.Offset.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
|
|
aTile.Offset.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
|
|
}
|
|
else if (anArg == "-total"
|
|
|| anArg == "-totalsize"
|
|
|| anArg == "-viewsize")
|
|
{
|
|
if (anArgIter + 3 < theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
aTile.TotalSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
|
|
aTile.TotalSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
|
|
if (aTile.TotalSize.x() < 1
|
|
|| aTile.TotalSize.y() < 1)
|
|
{
|
|
Message::SendFail ("Error: total size is incorrect");
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArg == "-tilesize")
|
|
{
|
|
if (anArgIter + 3 < theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
aTile.TileSize.x() = Draw::Atoi (theArgVec[anArgIter + 1]);
|
|
aTile.TileSize.y() = Draw::Atoi (theArgVec[anArgIter + 2]);
|
|
if (aTile.TileSize.x() < 1
|
|
|| aTile.TileSize.y() < 1)
|
|
{
|
|
Message::SendFail ("Error: tile size is incorrect");
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArg == "-unset")
|
|
{
|
|
aView->Camera()->SetTile (Graphic3d_CameraTile());
|
|
aView->Redraw();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (aTile.TileSize.x() < 1
|
|
|| aTile.TileSize.y() < 1)
|
|
{
|
|
Message::SendFail ("Error: tile size is undefined");
|
|
return 1;
|
|
}
|
|
else if (aTile.TotalSize.x() < 1
|
|
|| aTile.TotalSize.y() < 1)
|
|
{
|
|
Message::SendFail ("Error: total size is undefined");
|
|
return 1;
|
|
}
|
|
|
|
aView->Camera()->SetTile (aTile);
|
|
aView->Redraw();
|
|
return 0;
|
|
}
|
|
|
|
//! Format ZLayer ID.
|
|
inline const char* formZLayerId (const Standard_Integer theLayerId)
|
|
{
|
|
switch (theLayerId)
|
|
{
|
|
case Graphic3d_ZLayerId_UNKNOWN: return "[INVALID]";
|
|
case Graphic3d_ZLayerId_Default: return "[DEFAULT]";
|
|
case Graphic3d_ZLayerId_Top: return "[TOP]";
|
|
case Graphic3d_ZLayerId_Topmost: return "[TOPMOST]";
|
|
case Graphic3d_ZLayerId_TopOSD: return "[OVERLAY]";
|
|
case Graphic3d_ZLayerId_BotOSD: return "[UNDERLAY]";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//! Print the ZLayer information.
|
|
inline void printZLayerInfo (Draw_Interpretor& theDI,
|
|
const Graphic3d_ZLayerSettings& theLayer)
|
|
{
|
|
if (!theLayer.Name().IsEmpty())
|
|
{
|
|
theDI << " Name: " << theLayer.Name() << "\n";
|
|
}
|
|
if (theLayer.IsImmediate())
|
|
{
|
|
theDI << " Immediate: TRUE\n";
|
|
}
|
|
theDI << " Origin: " << theLayer.Origin().X() << " " << theLayer.Origin().Y() << " " << theLayer.Origin().Z() << "\n";
|
|
theDI << " Culling distance: " << theLayer.CullingDistance() << "\n";
|
|
theDI << " Culling size: " << theLayer.CullingSize() << "\n";
|
|
theDI << " Depth test: " << (theLayer.ToEnableDepthTest() ? "enabled" : "disabled") << "\n";
|
|
theDI << " Depth write: " << (theLayer.ToEnableDepthWrite() ? "enabled" : "disabled") << "\n";
|
|
theDI << " Depth buffer clearing: " << (theLayer.ToClearDepth() ? "enabled" : "disabled") << "\n";
|
|
if (theLayer.PolygonOffset().Mode != Aspect_POM_None)
|
|
{
|
|
theDI << " Depth offset: " << theLayer.PolygonOffset().Factor << " " << theLayer.PolygonOffset().Units << "\n";
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VZLayer
|
|
//purpose : Test z layer operations for v3d viewer
|
|
//==============================================================================
|
|
static int VZLayer (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
|
|
if (aContextAIS.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
|
|
if (theArgNb < 2)
|
|
{
|
|
TColStd_SequenceOfInteger aLayers;
|
|
aViewer->GetAllZLayers (aLayers);
|
|
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
|
|
{
|
|
theDI << "ZLayer " << aLayeriter.Value() << " " << formZLayerId (aLayeriter.Value()) << "\n";
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
|
|
printZLayerInfo (theDI, aSettings);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Standard_Integer anArgIter = 1;
|
|
Standard_Integer aLayerId = Graphic3d_ZLayerId_UNKNOWN;
|
|
ViewerTest_AutoUpdater anUpdateTool (aContextAIS, ViewerTest::CurrentView());
|
|
if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
|
|
{
|
|
TCollection_AsciiString aFirstArg (theArgVec[anArgIter]);
|
|
if (aFirstArg.IsIntegerValue())
|
|
{
|
|
++anArgIter;
|
|
aLayerId = aFirstArg.IntegerValue();
|
|
}
|
|
else
|
|
{
|
|
if (ViewerTest::ParseZLayerName (aFirstArg.ToCString(), aLayerId))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
}
|
|
|
|
Graphic3d_ZLayerId anOtherLayerId = Graphic3d_ZLayerId_UNKNOWN;
|
|
for (; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
// perform operation
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
//
|
|
}
|
|
else if (anArg == "-add"
|
|
|| anArg == "add")
|
|
{
|
|
aLayerId = Graphic3d_ZLayerId_UNKNOWN;
|
|
if (!aViewer->AddZLayer (aLayerId))
|
|
{
|
|
Message::SendFail ("Error: can not add a new z layer");
|
|
return 0;
|
|
}
|
|
|
|
theDI << aLayerId;
|
|
}
|
|
else if (anArg == "-insertbefore"
|
|
&& anArgIter + 1 < theArgNb
|
|
&& ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
|
|
{
|
|
++anArgIter;
|
|
aLayerId = Graphic3d_ZLayerId_UNKNOWN;
|
|
if (!aViewer->InsertLayerBefore (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
|
|
{
|
|
Message::SendFail ("Error: can not add a new z layer");
|
|
return 0;
|
|
}
|
|
|
|
theDI << aLayerId;
|
|
}
|
|
else if (anArg == "-insertafter"
|
|
&& anArgIter + 1 < theArgNb
|
|
&& ViewerTest::ParseZLayer (theArgVec[anArgIter + 1], anOtherLayerId))
|
|
{
|
|
++anArgIter;
|
|
aLayerId = Graphic3d_ZLayerId_UNKNOWN;
|
|
if (!aViewer->InsertLayerAfter (aLayerId, Graphic3d_ZLayerSettings(), anOtherLayerId))
|
|
{
|
|
Message::SendFail ("Error: can not add a new z layer");
|
|
return 0;
|
|
}
|
|
|
|
theDI << aLayerId;
|
|
}
|
|
else if (anArg == "-del"
|
|
|| anArg == "-delete"
|
|
|| anArg == "del")
|
|
{
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: id of z layer to remove is missing");
|
|
return 1;
|
|
}
|
|
|
|
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN
|
|
|| aLayerId == Graphic3d_ZLayerId_Default
|
|
|| aLayerId == Graphic3d_ZLayerId_Top
|
|
|| aLayerId == Graphic3d_ZLayerId_Topmost
|
|
|| aLayerId == Graphic3d_ZLayerId_TopOSD
|
|
|| aLayerId == Graphic3d_ZLayerId_BotOSD)
|
|
{
|
|
Message::SendFail ("Syntax error: standard Z layer can not be removed");
|
|
return 1;
|
|
}
|
|
|
|
// move all object displayed in removing layer to default layer
|
|
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anObjIter (GetMapOfAIS());
|
|
anObjIter.More(); anObjIter.Next())
|
|
{
|
|
const Handle(AIS_InteractiveObject)& aPrs = anObjIter.Key1();
|
|
if (aPrs.IsNull()
|
|
|| aPrs->ZLayer() != aLayerId)
|
|
{
|
|
continue;
|
|
}
|
|
aPrs->SetZLayer (Graphic3d_ZLayerId_Default);
|
|
}
|
|
|
|
if (!aViewer->RemoveZLayer (aLayerId))
|
|
{
|
|
Message::SendFail ("Z layer can not be removed");
|
|
}
|
|
else
|
|
{
|
|
theDI << aLayerId << " ";
|
|
}
|
|
}
|
|
else if (anArg == "-get"
|
|
|| anArg == "get")
|
|
{
|
|
TColStd_SequenceOfInteger aLayers;
|
|
aViewer->GetAllZLayers (aLayers);
|
|
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
|
|
{
|
|
theDI << aLayeriter.Value() << " ";
|
|
}
|
|
|
|
theDI << "\n";
|
|
}
|
|
else if (anArg == "-name")
|
|
{
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Message::SendFail ("Syntax error: id of Z layer is missing");
|
|
return 1;
|
|
}
|
|
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: name is missing");
|
|
return 1;
|
|
}
|
|
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
aSettings.SetName (theArgVec[anArgIter]);
|
|
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
|
}
|
|
else if (anArg == "-origin")
|
|
{
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Message::SendFail ("Syntax error: id of Z layer is missing");
|
|
return 1;
|
|
}
|
|
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: origin coordinates are missing");
|
|
return 1;
|
|
}
|
|
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
gp_XYZ anOrigin;
|
|
anOrigin.SetX (Draw::Atof (theArgVec[anArgIter + 1]));
|
|
anOrigin.SetY (Draw::Atof (theArgVec[anArgIter + 2]));
|
|
anOrigin.SetZ (0.0);
|
|
if (anArgIter + 3 < theArgNb)
|
|
{
|
|
anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter + 3]));
|
|
anArgIter += 3;
|
|
}
|
|
else
|
|
{
|
|
anArgIter += 2;
|
|
}
|
|
aSettings.SetOrigin (anOrigin);
|
|
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
|
}
|
|
else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
|
|
&& anArgIter + 1 < theArgNb
|
|
&& (anArg == "-cullingdistance"
|
|
|| anArg == "-cullingdist"
|
|
|| anArg == "-culldistance"
|
|
|| anArg == "-culldist"
|
|
|| anArg == "-distcull"
|
|
|| anArg == "-distculling"
|
|
|| anArg == "-distanceculling"))
|
|
{
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
const Standard_Real aDist = Draw::Atof (theArgVec[++anArgIter]);
|
|
aSettings.SetCullingDistance (aDist);
|
|
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
|
}
|
|
else if (aLayerId != Graphic3d_ZLayerId_UNKNOWN
|
|
&& anArgIter + 1 < theArgNb
|
|
&& (anArg == "-cullingsize"
|
|
|| anArg == "-cullsize"
|
|
|| anArg == "-sizecull"
|
|
|| anArg == "-sizeculling"))
|
|
{
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
const Standard_Real aSize = Draw::Atof (theArgVec[++anArgIter]);
|
|
aSettings.SetCullingSize (aSize);
|
|
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
|
}
|
|
else if (anArg == "-settings"
|
|
|| anArg == "settings")
|
|
{
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: id of Z layer is missing");
|
|
return 1;
|
|
}
|
|
|
|
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
printZLayerInfo (theDI, aSettings);
|
|
}
|
|
else if (anArg == "-enable"
|
|
|| anArg == "enable"
|
|
|| anArg == "-disable"
|
|
|| anArg == "disable")
|
|
{
|
|
const Standard_Boolean toEnable = anArg == "-enable"
|
|
|| anArg == "enable";
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: option name is missing");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aSubOp (theArgVec[anArgIter]);
|
|
aSubOp.LowerCase();
|
|
if (aLayerId == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: id of Z layer is missing");
|
|
return 1;
|
|
}
|
|
|
|
aLayerId = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerId);
|
|
if (aSubOp == "depthtest"
|
|
|| aSubOp == "test")
|
|
{
|
|
aSettings.SetEnableDepthTest (toEnable);
|
|
}
|
|
else if (aSubOp == "depthwrite"
|
|
|| aSubOp == "write")
|
|
{
|
|
aSettings.SetEnableDepthWrite (toEnable);
|
|
}
|
|
else if (aSubOp == "depthclear"
|
|
|| aSubOp == "clear")
|
|
{
|
|
aSettings.SetClearDepth (toEnable);
|
|
}
|
|
else if (aSubOp == "depthoffset"
|
|
|| aSubOp == "offset")
|
|
{
|
|
Graphic3d_PolygonOffset aParams;
|
|
aParams.Mode = toEnable ? Aspect_POM_Fill : Aspect_POM_None;
|
|
if (toEnable)
|
|
{
|
|
if (anArgIter + 2 >= theArgNb)
|
|
{
|
|
Message::SendFail ("Syntax error: factor and units values for depth offset are missing");
|
|
return 1;
|
|
}
|
|
|
|
aParams.Factor = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
|
|
aParams.Units = static_cast<Standard_ShortReal> (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
aSettings.SetPolygonOffset (aParams);
|
|
}
|
|
else if (aSubOp == "positiveoffset"
|
|
|| aSubOp == "poffset")
|
|
{
|
|
if (toEnable)
|
|
{
|
|
aSettings.SetDepthOffsetPositive();
|
|
}
|
|
else
|
|
{
|
|
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
|
}
|
|
}
|
|
else if (aSubOp == "negativeoffset"
|
|
|| aSubOp == "noffset")
|
|
{
|
|
if (toEnable)
|
|
{
|
|
aSettings.SetDepthOffsetNegative();
|
|
}
|
|
else
|
|
{
|
|
aSettings.SetPolygonOffset(Graphic3d_PolygonOffset());
|
|
}
|
|
}
|
|
else if (aSubOp == "textureenv")
|
|
{
|
|
aSettings.SetEnvironmentTexture (toEnable);
|
|
}
|
|
else if (aSubOp == "raytracing")
|
|
{
|
|
aSettings.SetRaytracable (toEnable);
|
|
}
|
|
|
|
aViewer->SetZLayerSettings (aLayerId, aSettings);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown option " << theArgVec[anArgIter];
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// The interactive presentation of 2d layer item
|
|
// for "vlayerline" command it provides a presentation of
|
|
// line with user-defined linewidth, linetype and transparency.
|
|
class V3d_LineItem : public AIS_InteractiveObject
|
|
{
|
|
public:
|
|
// CASCADE RTTI
|
|
DEFINE_STANDARD_RTTI_INLINE(V3d_LineItem,AIS_InteractiveObject)
|
|
|
|
// constructor
|
|
Standard_EXPORT V3d_LineItem(Standard_Real X1, Standard_Real Y1,
|
|
Standard_Real X2, Standard_Real Y2,
|
|
Aspect_TypeOfLine theType = Aspect_TOL_SOLID,
|
|
Standard_Real theWidth = 0.5,
|
|
Standard_Real theTransp = 1.0);
|
|
|
|
private:
|
|
|
|
virtual void Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
|
|
const Handle(Prs3d_Presentation)& thePrs,
|
|
const Standard_Integer theMode) Standard_OVERRIDE;
|
|
|
|
virtual void ComputeSelection (const Handle(SelectMgr_Selection)& ,
|
|
const Standard_Integer ) Standard_OVERRIDE
|
|
{}
|
|
|
|
private:
|
|
|
|
Standard_Real myX1, myY1, myX2, myY2;
|
|
Aspect_TypeOfLine myType;
|
|
Standard_Real myWidth;
|
|
};
|
|
|
|
// default constructor for line item
|
|
V3d_LineItem::V3d_LineItem(Standard_Real X1, Standard_Real Y1,
|
|
Standard_Real X2, Standard_Real Y2,
|
|
Aspect_TypeOfLine theType,
|
|
Standard_Real theWidth,
|
|
Standard_Real theTransp) :
|
|
myX1(X1), myY1(Y1), myX2(X2), myY2(Y2),
|
|
myType(theType), myWidth(theWidth)
|
|
{
|
|
SetTransparency (1-theTransp);
|
|
}
|
|
|
|
// render line
|
|
void V3d_LineItem::Compute (const Handle(PrsMgr_PresentationManager)& ,
|
|
const Handle(Prs3d_Presentation)& thePresentation,
|
|
const Standard_Integer )
|
|
{
|
|
thePresentation->Clear();
|
|
Quantity_Color aColor (Quantity_NOC_RED);
|
|
Standard_Integer aWidth, aHeight;
|
|
ViewerTest::CurrentView()->Window()->Size (aWidth, aHeight);
|
|
Handle(Graphic3d_Group) aGroup = thePresentation->CurrentGroup();
|
|
Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
|
|
aPrim->AddVertex(myX1, aHeight-myY1, 0.);
|
|
aPrim->AddVertex(myX2, aHeight-myY2, 0.);
|
|
Handle(Prs3d_LineAspect) anAspect = new Prs3d_LineAspect (aColor, (Aspect_TypeOfLine)myType, myWidth);
|
|
aGroup->SetPrimitivesAspect (anAspect->Aspect());
|
|
aGroup->AddPrimitiveArray (aPrim);
|
|
}
|
|
|
|
//=============================================================================
|
|
//function : VLayerLine
|
|
//purpose : Draws line in the v3d view layer with given attributes: linetype,
|
|
// : linewidth, transparency coefficient
|
|
//============================================================================
|
|
static int VLayerLine(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
|
{
|
|
// get the active view
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
di << "Call vinit before!\n";
|
|
return 1;
|
|
}
|
|
else if (argc < 5)
|
|
{
|
|
di << "Use: " << argv[0];
|
|
di << " x1 y1 x2 y2 [linewidth = 0.5] [linetype = 0] [transparency = 1]\n";
|
|
di << " linetype : { 0 | 1 | 2 | 3 } \n";
|
|
di << " 0 - solid \n";
|
|
di << " 1 - dashed \n";
|
|
di << " 2 - dot \n";
|
|
di << " 3 - dashdot\n";
|
|
di << " transparency : { 0.0 - 1.0 } \n";
|
|
di << " 0.0 - transparent\n";
|
|
di << " 1.0 - visible \n";
|
|
return 1;
|
|
}
|
|
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
// get the input params
|
|
Standard_Real X1 = Draw::Atof(argv[1]);
|
|
Standard_Real Y1 = Draw::Atof(argv[2]);
|
|
Standard_Real X2 = Draw::Atof(argv[3]);
|
|
Standard_Real Y2 = Draw::Atof(argv[4]);
|
|
|
|
Standard_Real aWidth = 0.5;
|
|
Standard_Real aTransparency = 1.0;
|
|
|
|
// has width
|
|
if (argc > 5)
|
|
aWidth = Draw::Atof(argv[5]);
|
|
|
|
// select appropriate line type
|
|
Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
|
|
if (argc > 6
|
|
&& !ViewerTest::ParseLineType (argv[6], aLineType))
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown line type '" << argv[6] << "'";
|
|
return 1;
|
|
}
|
|
|
|
// has transparency
|
|
if (argc > 7)
|
|
{
|
|
aTransparency = Draw::Atof(argv[7]);
|
|
if (aTransparency < 0 || aTransparency > 1.0)
|
|
aTransparency = 1.0;
|
|
}
|
|
|
|
static Handle (V3d_LineItem) aLine;
|
|
if (!aLine.IsNull())
|
|
{
|
|
aContext->Erase (aLine, Standard_False);
|
|
}
|
|
aLine = new V3d_LineItem (X1, Y1, X2, Y2,
|
|
aLineType, aWidth,
|
|
aTransparency);
|
|
|
|
aContext->SetTransformPersistence (aLine, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER));
|
|
aLine->SetZLayer (Graphic3d_ZLayerId_TopOSD);
|
|
aLine->SetToUpdate();
|
|
aContext->Display (aLine, Standard_True);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//function : VGrid
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VGrid (Draw_Interpretor& /*theDI*/,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
|
|
if (aView.IsNull() || aViewer.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Aspect_GridType aType = aViewer->GridType();
|
|
Aspect_GridDrawMode aMode = aViewer->GridDrawMode();
|
|
Graphic3d_Vec2d aNewOriginXY, aNewStepXY, aNewSizeXY;
|
|
Standard_Real aNewRotAngle = 0.0, aNewZOffset = 0.0;
|
|
bool hasOrigin = false, hasStep = false, hasRotAngle = false, hasSize = false, hasZOffset = false;
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& anArg == "-type")
|
|
{
|
|
TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
|
|
anArgNext.LowerCase();
|
|
if (anArgNext == "r"
|
|
|| anArgNext == "rect"
|
|
|| anArgNext == "rectangular")
|
|
{
|
|
aType = Aspect_GT_Rectangular;
|
|
}
|
|
else if (anArgNext == "c"
|
|
|| anArgNext == "circ"
|
|
|| anArgNext == "circular")
|
|
{
|
|
aType = Aspect_GT_Circular;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArgNext << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& anArg == "-mode")
|
|
{
|
|
TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
|
|
anArgNext.LowerCase();
|
|
if (anArgNext == "l"
|
|
|| anArgNext == "line"
|
|
|| anArgNext == "lines")
|
|
{
|
|
aMode = Aspect_GDM_Lines;
|
|
}
|
|
else if (anArgNext == "p"
|
|
|| anArgNext == "point"
|
|
|| anArgNext == "points")
|
|
{
|
|
aMode = Aspect_GDM_Points;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArgNext << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArgIter + 2 < theArgNb
|
|
&& (anArg == "-origin"
|
|
|| anArg == "-orig"))
|
|
{
|
|
hasOrigin = true;
|
|
aNewOriginXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
|
|
Draw::Atof (theArgVec[anArgIter + 2]));
|
|
anArgIter += 2;
|
|
}
|
|
else if (anArgIter + 2 < theArgNb
|
|
&& anArg == "-step")
|
|
{
|
|
hasStep = true;
|
|
aNewStepXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
|
|
Draw::Atof (theArgVec[anArgIter + 2]));
|
|
if (aNewStepXY.x() <= 0.0
|
|
|| aNewStepXY.y() <= 0.0)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong step '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
|
|
return 1;
|
|
}
|
|
anArgIter += 2;
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& (anArg == "-angle"
|
|
|| anArg == "-rotangle"
|
|
|| anArg == "-rotationangle"))
|
|
{
|
|
hasRotAngle = true;
|
|
aNewRotAngle = Draw::Atof (theArgVec[++anArgIter]);
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& (anArg == "-zoffset"
|
|
|| anArg == "-dz"))
|
|
{
|
|
hasZOffset = true;
|
|
aNewZOffset = Draw::Atof (theArgVec[++anArgIter]);
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& anArg == "-radius")
|
|
{
|
|
hasSize = true;
|
|
++anArgIter;
|
|
aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter]), 0.0);
|
|
if (aNewStepXY.x() <= 0.0)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArgIter + 2 < theArgNb
|
|
&& anArg == "-size")
|
|
{
|
|
hasSize = true;
|
|
aNewSizeXY.SetValues (Draw::Atof (theArgVec[anArgIter + 1]),
|
|
Draw::Atof (theArgVec[anArgIter + 2]));
|
|
if (aNewStepXY.x() <= 0.0
|
|
|| aNewStepXY.y() <= 0.0)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong size '" << theArgVec[anArgIter + 1] << " " << theArgVec[anArgIter + 2] << "'";
|
|
return 1;
|
|
}
|
|
anArgIter += 2;
|
|
}
|
|
else if (anArg == "r"
|
|
|| anArg == "rect"
|
|
|| anArg == "rectangular")
|
|
{
|
|
aType = Aspect_GT_Rectangular;
|
|
}
|
|
else if (anArg == "c"
|
|
|| anArg == "circ"
|
|
|| anArg == "circular")
|
|
{
|
|
aType = Aspect_GT_Circular;
|
|
}
|
|
else if (anArg == "l"
|
|
|| anArg == "line"
|
|
|| anArg == "lines")
|
|
{
|
|
aMode = Aspect_GDM_Lines;
|
|
}
|
|
else if (anArg == "p"
|
|
|| anArg == "point"
|
|
|| anArg == "points")
|
|
{
|
|
aMode = Aspect_GDM_Points;
|
|
}
|
|
else if (anArgIter + 1 >= theArgNb
|
|
&& anArg == "off")
|
|
{
|
|
aViewer->DeactivateGrid();
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aType == Aspect_GT_Rectangular)
|
|
{
|
|
Graphic3d_Vec2d anOrigXY, aStepXY;
|
|
Standard_Real aRotAngle = 0.0;
|
|
aViewer->RectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
|
|
if (hasOrigin)
|
|
{
|
|
anOrigXY = aNewOriginXY;
|
|
}
|
|
if (hasStep)
|
|
{
|
|
aStepXY = aNewStepXY;
|
|
}
|
|
if (hasRotAngle)
|
|
{
|
|
aRotAngle = aNewRotAngle;
|
|
}
|
|
aViewer->SetRectangularGridValues (anOrigXY.x(), anOrigXY.y(), aStepXY.x(), aStepXY.y(), aRotAngle);
|
|
if (hasSize || hasZOffset)
|
|
{
|
|
Graphic3d_Vec3d aSize;
|
|
aViewer->RectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
|
|
if (hasSize)
|
|
{
|
|
aSize.x() = aNewSizeXY.x();
|
|
aSize.y() = aNewSizeXY.y();
|
|
}
|
|
if (hasZOffset)
|
|
{
|
|
aSize.z() = aNewZOffset;
|
|
}
|
|
aViewer->SetRectangularGridGraphicValues (aSize.x(), aSize.y(), aSize.z());
|
|
}
|
|
}
|
|
else if (aType == Aspect_GT_Circular)
|
|
{
|
|
Graphic3d_Vec2d anOrigXY;
|
|
Standard_Real aRadiusStep;
|
|
Standard_Integer aDivisionNumber;
|
|
Standard_Real aRotAngle = 0.0;
|
|
aViewer->CircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
|
|
if (hasOrigin)
|
|
{
|
|
anOrigXY = aNewOriginXY;
|
|
}
|
|
if (hasStep)
|
|
{
|
|
aRadiusStep = aNewStepXY[0];
|
|
aDivisionNumber = (int )aNewStepXY[1];
|
|
if (aDivisionNumber < 1)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid division number '" << aNewStepXY[1] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
if (hasRotAngle)
|
|
{
|
|
aRotAngle = aNewRotAngle;
|
|
}
|
|
|
|
aViewer->SetCircularGridValues (anOrigXY.x(), anOrigXY.y(), aRadiusStep, aDivisionNumber, aRotAngle);
|
|
if (hasSize || hasZOffset)
|
|
{
|
|
Standard_Real aRadius = 0.0, aZOffset = 0.0;
|
|
aViewer->CircularGridGraphicValues (aRadius, aZOffset);
|
|
if (hasSize)
|
|
{
|
|
aRadius = aNewSizeXY.x();
|
|
if (aNewSizeXY.y() != 0.0)
|
|
{
|
|
Message::SendFail ("Syntax error: circular size should be specified as radius");
|
|
return 1;
|
|
}
|
|
}
|
|
if (hasZOffset)
|
|
{
|
|
aZOffset = aNewZOffset;
|
|
}
|
|
aViewer->SetCircularGridGraphicValues (aRadius, aZOffset);
|
|
}
|
|
}
|
|
aViewer->ActivateGrid (aType, aMode);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VPriviledgedPlane
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VPriviledgedPlane (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
if (theArgNb != 1 && theArgNb != 7 && theArgNb != 10)
|
|
{
|
|
Message::SendFail ("Error: wrong number of arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
|
|
// get the active viewer
|
|
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
|
|
if (aViewer.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgNb == 1)
|
|
{
|
|
gp_Ax3 aPriviledgedPlane = aViewer->PrivilegedPlane();
|
|
const gp_Pnt& anOrig = aPriviledgedPlane.Location();
|
|
const gp_Dir& aNorm = aPriviledgedPlane.Direction();
|
|
const gp_Dir& aXDir = aPriviledgedPlane.XDirection();
|
|
theDI << "Origin: " << anOrig.X() << " " << anOrig.Y() << " " << anOrig.Z() << " "
|
|
<< "Normal: " << aNorm.X() << " " << aNorm.Y() << " " << aNorm.Z() << " "
|
|
<< "X-dir: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
|
|
return 0;
|
|
}
|
|
|
|
Standard_Integer anArgIdx = 1;
|
|
Standard_Real anOrigX = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real anOrigY = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real anOrigZ = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real aNormX = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real aNormY = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real aNormZ = Draw::Atof (theArgVec[anArgIdx++]);
|
|
|
|
gp_Ax3 aPriviledgedPlane;
|
|
gp_Pnt anOrig (anOrigX, anOrigY, anOrigZ);
|
|
gp_Dir aNorm (aNormX, aNormY, aNormZ);
|
|
if (theArgNb > 7)
|
|
{
|
|
Standard_Real aXDirX = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real aXDirY = Draw::Atof (theArgVec[anArgIdx++]);
|
|
Standard_Real aXDirZ = Draw::Atof (theArgVec[anArgIdx++]);
|
|
gp_Dir aXDir (aXDirX, aXDirY, aXDirZ);
|
|
aPriviledgedPlane = gp_Ax3 (anOrig, aNorm, aXDir);
|
|
}
|
|
else
|
|
{
|
|
aPriviledgedPlane = gp_Ax3 (anOrig, aNorm);
|
|
}
|
|
|
|
aViewer->SetPrivilegedPlane (aPriviledgedPlane);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VConvert
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VConvert (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
// get the active view
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
enum { Model, Ray, View, Window, Grid } aMode = Model;
|
|
|
|
// access coordinate arguments
|
|
TColStd_SequenceOfReal aCoord;
|
|
Standard_Integer anArgIdx = 1;
|
|
for (; anArgIdx < 4 && anArgIdx < theArgNb; ++anArgIdx)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIdx]);
|
|
if (!anArg.IsRealValue (Standard_True))
|
|
{
|
|
break;
|
|
}
|
|
aCoord.Append (anArg.RealValue());
|
|
}
|
|
|
|
// non-numeric argument too early
|
|
if (aCoord.IsEmpty())
|
|
{
|
|
Message::SendFail ("Error: wrong number of arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
|
|
// collect all other arguments and options
|
|
for (; anArgIdx < theArgNb; ++anArgIdx)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIdx]);
|
|
anArg.LowerCase();
|
|
if (anArg == "window") aMode = Window;
|
|
else if (anArg == "view") aMode = View;
|
|
else if (anArg == "grid") aMode = Grid;
|
|
else if (anArg == "ray") aMode = Ray;
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: wrong argument " << anArg << "! See usage:";
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// complete input checks
|
|
if ((aCoord.Length() == 1 && theArgNb > 3) ||
|
|
(aCoord.Length() == 2 && theArgNb > 4) ||
|
|
(aCoord.Length() == 3 && theArgNb > 5))
|
|
{
|
|
Message::SendFail ("Error: wrong number of arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
|
|
Standard_Real aXYZ[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
|
Standard_Integer aXYp[2] = {0, 0};
|
|
|
|
// convert one-dimensional coordinate
|
|
if (aCoord.Length() == 1)
|
|
{
|
|
switch (aMode)
|
|
{
|
|
case View : theDI << "View Vv: " << aView->Convert ((Standard_Integer)aCoord (1)); return 0;
|
|
case Window : theDI << "Window Vp: " << aView->Convert (aCoord (1)); return 0;
|
|
default:
|
|
Message::SendFail ("Error: wrong arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// convert 2D coordinates from projection or view reference space
|
|
if (aCoord.Length() == 2)
|
|
{
|
|
switch (aMode)
|
|
{
|
|
case Model :
|
|
aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
|
|
theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
|
|
return 0;
|
|
|
|
case View :
|
|
aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1]);
|
|
theDI << "View Xv,Yv: " << aXYZ[0] << " " << aXYZ[1] << "\n";
|
|
return 0;
|
|
|
|
case Window :
|
|
aView->Convert (aCoord (1), aCoord (2), aXYp[0], aXYp[1]);
|
|
theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
|
|
return 0;
|
|
|
|
case Grid :
|
|
aView->Convert ((Standard_Integer) aCoord (1), (Standard_Integer) aCoord (2), aXYZ[0], aXYZ[1], aXYZ[2]);
|
|
aView->ConvertToGrid (aXYZ[0], aXYZ[1], aXYZ[2], aXYZ[3], aXYZ[4], aXYZ[5]);
|
|
theDI << "Model X,Y,Z: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
|
|
return 0;
|
|
|
|
case Ray :
|
|
aView->ConvertWithProj ((Standard_Integer) aCoord (1),
|
|
(Standard_Integer) aCoord (2),
|
|
aXYZ[0], aXYZ[1], aXYZ[2],
|
|
aXYZ[3], aXYZ[4], aXYZ[5]);
|
|
theDI << "Model DX,DY,DZ: " << aXYZ[3] << " " << aXYZ[4] << " " << aXYZ[5] << "\n";
|
|
return 0;
|
|
|
|
default:
|
|
Message::SendFail ("Error: wrong arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// convert 3D coordinates from view reference space
|
|
else if (aCoord.Length() == 3)
|
|
{
|
|
switch (aMode)
|
|
{
|
|
case Window :
|
|
aView->Convert (aCoord (1), aCoord (2), aCoord (3), aXYp[0], aXYp[1]);
|
|
theDI << "Window Xp,Yp: " << aXYp[0] << " " << aXYp[1] << "\n";
|
|
return 0;
|
|
|
|
case Grid :
|
|
aView->ConvertToGrid (aCoord (1), aCoord (2), aCoord (3), aXYZ[0], aXYZ[1], aXYZ[2]);
|
|
theDI << "Model X,Y,Z: " << aXYZ[0] << " " << aXYZ[1] << " " << aXYZ[2] << "\n";
|
|
return 0;
|
|
|
|
default:
|
|
Message::SendFail ("Error: wrong arguments! See usage:");
|
|
theDI.PrintHelp (theArgVec[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VFps
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VFps (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
// get the active view
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer aFramesNb = -1;
|
|
Standard_Real aDuration = -1.0;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (aDuration < 0.0
|
|
&& anArgIter + 1 < theArgNb
|
|
&& (anArg == "-duration"
|
|
|| anArg == "-dur"
|
|
|| anArg == "-time"))
|
|
{
|
|
aDuration = Draw::Atof (theArgVec[++anArgIter]);
|
|
}
|
|
else if (aFramesNb < 0
|
|
&& anArg.IsIntegerValue())
|
|
{
|
|
aFramesNb = anArg.IntegerValue();
|
|
if (aFramesNb <= 0)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
if (aFramesNb < 0 && aDuration < 0.0)
|
|
{
|
|
aFramesNb = 100;
|
|
}
|
|
|
|
// the time is meaningless for first call
|
|
// due to async OpenGl rendering
|
|
aView->Redraw();
|
|
|
|
// redraw view in loop to estimate average values
|
|
OSD_Timer aTimer;
|
|
aTimer.Start();
|
|
Standard_Integer aFrameIter = 1;
|
|
for (;; ++aFrameIter)
|
|
{
|
|
aView->Redraw();
|
|
if ((aFramesNb > 0
|
|
&& aFrameIter >= aFramesNb)
|
|
|| (aDuration > 0.0
|
|
&& aTimer.ElapsedTime() >= aDuration))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
aTimer.Stop();
|
|
Standard_Real aCpu;
|
|
const Standard_Real aTime = aTimer.ElapsedTime();
|
|
aTimer.OSD_Chronometer::Show (aCpu);
|
|
|
|
const Standard_Real aFpsAver = Standard_Real(aFrameIter) / aTime;
|
|
const Standard_Real aCpuAver = aCpu / Standard_Real(aFrameIter);
|
|
|
|
// return statistics
|
|
theDI << "FPS: " << aFpsAver << "\n"
|
|
<< "CPU: " << (1000.0 * aCpuAver) << " msec\n";
|
|
|
|
// compute additional statistics in ray-tracing mode
|
|
const Graphic3d_RenderingParams& aParams = aView->RenderingParams();
|
|
if (aParams.Method == Graphic3d_RM_RAYTRACING)
|
|
{
|
|
Graphic3d_Vec2i aWinSize (0, 0);
|
|
aView->Window()->Size (aWinSize.x(), aWinSize.y());
|
|
|
|
// 1 shadow ray and 1 secondary ray pew each bounce
|
|
const Standard_Real aMRays = aWinSize.x() * aWinSize.y() * aFpsAver * aParams.RaytracingDepth * 2 / 1.0e6f;
|
|
theDI << "MRays/sec (upper bound): " << aMRays << "\n";
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//function : VMemGpu
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VMemGpu (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
// get the context
|
|
Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
|
|
if (aContextAIS.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Handle(Graphic3d_GraphicDriver) aDriver = aContextAIS->CurrentViewer()->Driver();
|
|
if (aDriver.IsNull())
|
|
{
|
|
Message::SendFail ("Error: graphic driver not available");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Size aFreeBytes = 0;
|
|
TCollection_AsciiString anInfo;
|
|
if (!aDriver->MemoryInfo (aFreeBytes, anInfo))
|
|
{
|
|
Message::SendFail ("Error: information not available");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgNb > 1 && *theArgVec[1] == 'f')
|
|
{
|
|
theDI << Standard_Real (aFreeBytes);
|
|
}
|
|
else
|
|
{
|
|
theDI << anInfo;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ==============================================================================
|
|
// function : VReadPixel
|
|
// purpose :
|
|
// ==============================================================================
|
|
static int VReadPixel (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
// get the active view
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
else if (theArgNb < 3)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number of arguments.\n"
|
|
<< "Usage: " << theArgVec[0] << " xPixel yPixel [{rgb|rgba|depth|hls|rgbf|rgbaf}=rgba] [name]";
|
|
return 1;
|
|
}
|
|
|
|
Image_Format aFormat = Image_Format_RGBA;
|
|
Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
|
|
|
|
Standard_Integer aWidth, aHeight;
|
|
aView->Window()->Size (aWidth, aHeight);
|
|
const Standard_Integer anX = Draw::Atoi (theArgVec[1]);
|
|
const Standard_Integer anY = Draw::Atoi (theArgVec[2]);
|
|
if (anX < 0 || anX >= aWidth || anY < 0 || anY > aHeight)
|
|
{
|
|
Message::SendFail() << "Error: pixel coordinates (" << anX << "; " << anY << ") are out of view (" << aWidth << " x " << aHeight << ")";
|
|
return 1;
|
|
}
|
|
|
|
bool toShowName = false, toShowHls = false, toShowHex = false, toShow_sRGB = false;
|
|
for (Standard_Integer anIter = 3; anIter < theArgNb; ++anIter)
|
|
{
|
|
TCollection_AsciiString aParam (theArgVec[anIter]);
|
|
aParam.LowerCase();
|
|
if (aParam == "-rgb"
|
|
|| aParam == "rgb"
|
|
|| aParam == "-srgb"
|
|
|| aParam == "srgb")
|
|
{
|
|
aFormat = Image_Format_RGB;
|
|
aBufferType = Graphic3d_BT_RGB;
|
|
toShow_sRGB = aParam == "-srgb" || aParam == "srgb";
|
|
}
|
|
else if (aParam == "-hls"
|
|
|| aParam == "hls")
|
|
{
|
|
aFormat = Image_Format_RGB;
|
|
aBufferType = Graphic3d_BT_RGB;
|
|
toShowHls = Standard_True;
|
|
}
|
|
else if (aParam == "-rgbf"
|
|
|| aParam == "rgbf")
|
|
{
|
|
aFormat = Image_Format_RGBF;
|
|
aBufferType = Graphic3d_BT_RGB;
|
|
}
|
|
else if (aParam == "-rgba"
|
|
|| aParam == "rgba"
|
|
|| aParam == "-srgba"
|
|
|| aParam == "srgba")
|
|
{
|
|
aFormat = Image_Format_RGBA;
|
|
aBufferType = Graphic3d_BT_RGBA;
|
|
toShow_sRGB = aParam == "-srgba" || aParam == "srgba";
|
|
}
|
|
else if (aParam == "-rgbaf"
|
|
|| aParam == "rgbaf")
|
|
{
|
|
aFormat = Image_Format_RGBAF;
|
|
aBufferType = Graphic3d_BT_RGBA;
|
|
}
|
|
else if (aParam == "-depth"
|
|
|| aParam == "depth")
|
|
{
|
|
aFormat = Image_Format_GrayF;
|
|
aBufferType = Graphic3d_BT_Depth;
|
|
}
|
|
else if (aParam == "-name"
|
|
|| aParam == "name")
|
|
{
|
|
toShowName = Standard_True;
|
|
}
|
|
else if (aParam == "-hex"
|
|
|| aParam == "hex")
|
|
{
|
|
toShowHex = Standard_True;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << aParam << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Image_PixMap anImage;
|
|
if (!anImage.InitTrash (aFormat, aWidth, aHeight))
|
|
{
|
|
Message::SendFail ("Error: image allocation failed");
|
|
return 1;
|
|
}
|
|
else if (!aView->ToPixMap (anImage, aWidth, aHeight, aBufferType))
|
|
{
|
|
Message::SendFail ("Error: image dump failed");
|
|
return 1;
|
|
}
|
|
|
|
// redirect possible warning messages that could have been added by ToPixMap
|
|
// into the Tcl interpretor (via DefaultMessenger) to cout, so that they do not
|
|
// contaminate result of the command
|
|
Standard_CString aWarnLog = theDI.Result();
|
|
if (aWarnLog != NULL && aWarnLog[0] != '\0')
|
|
{
|
|
std::cout << aWarnLog << std::endl;
|
|
}
|
|
theDI.Reset();
|
|
|
|
Quantity_ColorRGBA aColor = anImage.PixelColor (anX, anY, true);
|
|
if (toShowName)
|
|
{
|
|
if (aBufferType == Graphic3d_BT_RGBA)
|
|
{
|
|
theDI << Quantity_Color::StringName (aColor.GetRGB().Name()) << " " << aColor.Alpha();
|
|
}
|
|
else
|
|
{
|
|
theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
|
|
}
|
|
}
|
|
else if (toShowHex)
|
|
{
|
|
if (aBufferType == Graphic3d_BT_RGBA)
|
|
{
|
|
theDI << Quantity_ColorRGBA::ColorToHex (aColor);
|
|
}
|
|
else
|
|
{
|
|
theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (aBufferType)
|
|
{
|
|
default:
|
|
case Graphic3d_BT_RGB:
|
|
{
|
|
if (toShowHls)
|
|
{
|
|
theDI << aColor.GetRGB().Hue() << " " << aColor.GetRGB().Light() << " " << aColor.GetRGB().Saturation();
|
|
}
|
|
else if (toShow_sRGB)
|
|
{
|
|
const Graphic3d_Vec4 aColor_sRGB = Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor);
|
|
theDI << aColor_sRGB.r() << " " << aColor_sRGB.g() << " " << aColor_sRGB.b();
|
|
}
|
|
else
|
|
{
|
|
theDI << aColor.GetRGB().Red() << " " << aColor.GetRGB().Green() << " " << aColor.GetRGB().Blue();
|
|
}
|
|
break;
|
|
}
|
|
case Graphic3d_BT_RGBA:
|
|
{
|
|
const Graphic3d_Vec4 aVec4 = toShow_sRGB ? Quantity_ColorRGBA::Convert_LinearRGB_To_sRGB ((Graphic3d_Vec4 )aColor) : (Graphic3d_Vec4 )aColor;
|
|
theDI << aVec4.r() << " " << aVec4.g() << " " << aVec4.b() << " " << aVec4.a();
|
|
break;
|
|
}
|
|
case Graphic3d_BT_Depth:
|
|
{
|
|
theDI << aColor.GetRGB().Red();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//! Auxiliary presentation for an image plane.
|
|
class ViewerTest_ImagePrs : public AIS_InteractiveObject
|
|
{
|
|
public:
|
|
//! Main constructor.
|
|
ViewerTest_ImagePrs (const Handle(Image_PixMap)& theImage,
|
|
const Standard_Real theWidth,
|
|
const Standard_Real theHeight,
|
|
const TCollection_AsciiString& theLabel)
|
|
: myLabel (theLabel), myWidth (theWidth), myHeight(theHeight)
|
|
{
|
|
SetDisplayMode (0);
|
|
SetHilightMode (1);
|
|
myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
|
|
{
|
|
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
|
|
const Handle(Graphic3d_AspectFillArea3d)& aFillAspect = myDrawer->ShadingAspect()->Aspect();
|
|
Graphic3d_MaterialAspect aMat;
|
|
aMat.SetMaterialType (Graphic3d_MATERIAL_PHYSIC);
|
|
aMat.SetAmbientColor (Quantity_NOC_BLACK);
|
|
aMat.SetDiffuseColor (Quantity_NOC_WHITE);
|
|
aMat.SetSpecularColor (Quantity_NOC_BLACK);
|
|
aMat.SetEmissiveColor (Quantity_NOC_BLACK);
|
|
aFillAspect->SetFrontMaterial (aMat);
|
|
aFillAspect->SetTextureMap (new Graphic3d_Texture2D (theImage));
|
|
aFillAspect->SetTextureMapOn();
|
|
}
|
|
{
|
|
Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
|
|
aTextAspect->SetHorizontalJustification (Graphic3d_HTA_CENTER);
|
|
aTextAspect->SetVerticalJustification (Graphic3d_VTA_CENTER);
|
|
myDrawer->SetTextAspect (aTextAspect);
|
|
}
|
|
{
|
|
const gp_Dir aNorm (0.0, 0.0, 1.0);
|
|
myTris = new Graphic3d_ArrayOfTriangles (4, 6, true, false, true);
|
|
myTris->AddVertex (gp_Pnt(-myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 0.0));
|
|
myTris->AddVertex (gp_Pnt( myWidth * 0.5, -myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 0.0));
|
|
myTris->AddVertex (gp_Pnt(-myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (0.0, 1.0));
|
|
myTris->AddVertex (gp_Pnt( myWidth * 0.5, myHeight * 0.5, 0.0), aNorm, gp_Pnt2d (1.0, 1.0));
|
|
myTris->AddEdge (1);
|
|
myTris->AddEdge (2);
|
|
myTris->AddEdge (3);
|
|
myTris->AddEdge (3);
|
|
myTris->AddEdge (2);
|
|
myTris->AddEdge (4);
|
|
|
|
myRect = new Graphic3d_ArrayOfPolylines (4);
|
|
myRect->AddVertex (myTris->Vertice (1));
|
|
myRect->AddVertex (myTris->Vertice (3));
|
|
myRect->AddVertex (myTris->Vertice (4));
|
|
myRect->AddVertex (myTris->Vertice (2));
|
|
}
|
|
}
|
|
|
|
//! Returns TRUE for accepted display modes.
|
|
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0 || theMode == 1; }
|
|
|
|
//! Compute presentation.
|
|
virtual void Compute (const Handle(PrsMgr_PresentationManager)& ,
|
|
const Handle(Prs3d_Presentation)& thePrs,
|
|
const Standard_Integer theMode) Standard_OVERRIDE
|
|
{
|
|
switch (theMode)
|
|
{
|
|
case 0:
|
|
{
|
|
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
|
aGroup->AddPrimitiveArray (myTris);
|
|
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
|
|
aGroup->AddPrimitiveArray (myRect);
|
|
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
|
|
return;
|
|
}
|
|
case 1:
|
|
{
|
|
Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), myLabel, gp_Pnt(0.0, 0.0, 0.0));
|
|
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
|
aGroup->AddPrimitiveArray (myRect);
|
|
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//! Compute selection.
|
|
virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) Standard_OVERRIDE
|
|
{
|
|
if (theMode == 0)
|
|
{
|
|
Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 5);
|
|
Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anEntityOwner);
|
|
aSensitive->InitTriangulation (myTris->Attributes(), myTris->Indices(), TopLoc_Location());
|
|
theSel->Add (aSensitive);
|
|
}
|
|
}
|
|
|
|
private:
|
|
Handle(Graphic3d_ArrayOfTriangles) myTris;
|
|
Handle(Graphic3d_ArrayOfPolylines) myRect;
|
|
TCollection_AsciiString myLabel;
|
|
Standard_Real myWidth;
|
|
Standard_Real myHeight;
|
|
};
|
|
|
|
//==============================================================================
|
|
//function : VDiffImage
|
|
//purpose : The draw-command compares two images.
|
|
//==============================================================================
|
|
|
|
static int VDiffImage (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
|
|
{
|
|
if (theArgNb < 3)
|
|
{
|
|
Message::SendFail ("Syntax error: not enough arguments");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer anArgIter = 1;
|
|
TCollection_AsciiString anImgPathRef (theArgVec[anArgIter++]);
|
|
TCollection_AsciiString anImgPathNew (theArgVec[anArgIter++]);
|
|
TCollection_AsciiString aDiffImagePath;
|
|
Standard_Real aTolColor = -1.0;
|
|
Standard_Integer toBlackWhite = -1;
|
|
Standard_Integer isBorderFilterOn = -1;
|
|
Standard_Boolean isOldSyntax = Standard_False;
|
|
TCollection_AsciiString aViewName, aPrsNameRef, aPrsNameNew, aPrsNameDiff;
|
|
for (; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anArgIter + 1 < theArgNb
|
|
&& (anArg == "-toleranceofcolor"
|
|
|| anArg == "-tolerancecolor"
|
|
|| anArg == "-tolerance"
|
|
|| anArg == "-toler"))
|
|
{
|
|
aTolColor = Atof (theArgVec[++anArgIter]);
|
|
if (aTolColor < 0.0 || aTolColor > 1.0)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArg == "-blackwhite")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
toBlackWhite = toEnable ? 1 : 0;
|
|
}
|
|
else if (anArg == "-borderfilter")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
isBorderFilterOn = toEnable ? 1 : 0;
|
|
}
|
|
else if (anArg == "-exitonclose")
|
|
{
|
|
ViewerTest_EventManager::ToExitOnCloseView() = true;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToExitOnCloseView()))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (anArg == "-closeonescape"
|
|
|| anArg == "-closeonesc")
|
|
{
|
|
ViewerTest_EventManager::ToCloseViewOnEscape() = true;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], ViewerTest_EventManager::ToCloseViewOnEscape()))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (anArgIter + 3 < theArgNb
|
|
&& anArg == "-display")
|
|
{
|
|
aViewName = theArgVec[++anArgIter];
|
|
aPrsNameRef = theArgVec[++anArgIter];
|
|
aPrsNameNew = theArgVec[++anArgIter];
|
|
if (anArgIter + 1 < theArgNb
|
|
&& *theArgVec[anArgIter + 1] != '-')
|
|
{
|
|
aPrsNameDiff = theArgVec[++anArgIter];
|
|
}
|
|
}
|
|
else if (aTolColor < 0.0
|
|
&& anArg.IsRealValue (Standard_True))
|
|
{
|
|
isOldSyntax = Standard_True;
|
|
aTolColor = anArg.RealValue();
|
|
if (aTolColor < 0.0 || aTolColor > 1.0)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << " " << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (isOldSyntax
|
|
&& toBlackWhite == -1
|
|
&& (anArg == "0" || anArg == "1"))
|
|
{
|
|
toBlackWhite = anArg == "1" ? 1 : 0;
|
|
}
|
|
else if (isOldSyntax
|
|
&& isBorderFilterOn == -1
|
|
&& (anArg == "0" || anArg == "1"))
|
|
{
|
|
isBorderFilterOn = anArg == "1" ? 1 : 0;
|
|
}
|
|
else if (aDiffImagePath.IsEmpty())
|
|
{
|
|
aDiffImagePath = theArgVec[anArgIter];
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Handle(Image_AlienPixMap) anImgRef = new Image_AlienPixMap();
|
|
Handle(Image_AlienPixMap) anImgNew = new Image_AlienPixMap();
|
|
if (!anImgRef->Load (anImgPathRef))
|
|
{
|
|
Message::SendFail() << "Error: image file '" << anImgPathRef << "' cannot be read";
|
|
return 1;
|
|
}
|
|
if (!anImgNew->Load (anImgPathNew))
|
|
{
|
|
Message::SendFail() << "Error: image file '" << anImgPathNew << "' cannot be read";
|
|
return 1;
|
|
}
|
|
|
|
// compare the images
|
|
Image_Diff aComparer;
|
|
Standard_Integer aDiffColorsNb = -1;
|
|
if (aComparer.Init (anImgRef, anImgNew, toBlackWhite == 1))
|
|
{
|
|
aComparer.SetColorTolerance (aTolColor >= 0.0 ? aTolColor : 0.0);
|
|
aComparer.SetBorderFilterOn (isBorderFilterOn == 1);
|
|
aDiffColorsNb = aComparer.Compare();
|
|
theDI << aDiffColorsNb << "\n";
|
|
}
|
|
|
|
// save image of difference
|
|
Handle(Image_AlienPixMap) aDiff;
|
|
if (aDiffColorsNb > 0
|
|
&& (!aDiffImagePath.IsEmpty() || !aPrsNameDiff.IsEmpty()))
|
|
{
|
|
aDiff = new Image_AlienPixMap();
|
|
if (!aDiff->InitTrash (Image_Format_Gray, anImgRef->SizeX(), anImgRef->SizeY()))
|
|
{
|
|
Message::SendFail() << "Error: cannot allocate memory for diff image " << anImgRef->SizeX() << "x" << anImgRef->SizeY();
|
|
return 1;
|
|
}
|
|
aComparer.SaveDiffImage (*aDiff);
|
|
if (!aDiffImagePath.IsEmpty()
|
|
&& !aDiff->Save (aDiffImagePath))
|
|
{
|
|
Message::SendFail() << "Error: diff image file '" << aDiffImagePath << "' cannot be written";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aViewName.IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
ViewerTest_Names aViewNames (aViewName);
|
|
if (ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
|
|
{
|
|
TCollection_AsciiString aCommand = TCollection_AsciiString ("vclose ") + aViewNames.GetViewName();
|
|
theDI.Eval (aCommand.ToCString());
|
|
}
|
|
|
|
ViewerTest_VinitParams aParams;
|
|
aParams.ViewName = aViewName;
|
|
aParams.Size.x() = float(anImgRef->SizeX() * 2);
|
|
aParams.Size.y() = !aDiff.IsNull() && !aPrsNameDiff.IsEmpty()
|
|
? float(anImgRef->SizeY() * 2)
|
|
: float(anImgRef->SizeY());
|
|
TCollection_AsciiString aViewId = ViewerTest::ViewerInit (aParams);
|
|
|
|
Standard_Real aRatio = anImgRef->Ratio();
|
|
Standard_Real aSizeX = 1.0;
|
|
Standard_Real aSizeY = aSizeX / aRatio;
|
|
{
|
|
OSD_Path aPath (anImgPathRef);
|
|
TCollection_AsciiString aLabelRef;
|
|
if (!aPath.Name().IsEmpty())
|
|
{
|
|
aLabelRef = aPath.Name() + aPath.Extension();
|
|
}
|
|
aLabelRef += TCollection_AsciiString() + "\n" + int(anImgRef->SizeX()) + "x" + int(anImgRef->SizeY());
|
|
|
|
Handle(ViewerTest_ImagePrs) anImgRefPrs = new ViewerTest_ImagePrs (anImgRef, aSizeX, aSizeY, aLabelRef);
|
|
gp_Trsf aTrsfRef;
|
|
aTrsfRef.SetTranslationPart (gp_Vec (-aSizeX * 0.5, 0.0, 0.0));
|
|
anImgRefPrs->SetLocalTransformation (aTrsfRef);
|
|
ViewerTest::Display (aPrsNameRef, anImgRefPrs, false, true);
|
|
}
|
|
{
|
|
OSD_Path aPath (anImgPathNew);
|
|
TCollection_AsciiString aLabelNew;
|
|
if (!aPath.Name().IsEmpty())
|
|
{
|
|
aLabelNew = aPath.Name() + aPath.Extension();
|
|
}
|
|
aLabelNew += TCollection_AsciiString() + "\n" + int(anImgNew->SizeX()) + "x" + int(anImgNew->SizeY());
|
|
|
|
Handle(ViewerTest_ImagePrs) anImgNewPrs = new ViewerTest_ImagePrs (anImgNew, aSizeX, aSizeY, aLabelNew);
|
|
gp_Trsf aTrsfRef;
|
|
aTrsfRef.SetTranslationPart (gp_Vec (aSizeX * 0.5, 0.0, 0.0));
|
|
anImgNewPrs->SetLocalTransformation (aTrsfRef);
|
|
ViewerTest::Display (aPrsNameNew, anImgNewPrs, false, true);
|
|
}
|
|
Handle(ViewerTest_ImagePrs) anImgDiffPrs;
|
|
if (!aDiff.IsNull())
|
|
{
|
|
anImgDiffPrs = new ViewerTest_ImagePrs (aDiff, aSizeX, aSizeY, TCollection_AsciiString() + "Difference: " + aDiffColorsNb + " pixels");
|
|
gp_Trsf aTrsfDiff;
|
|
aTrsfDiff.SetTranslationPart (gp_Vec (0.0, -aSizeY, 0.0));
|
|
anImgDiffPrs->SetLocalTransformation (aTrsfDiff);
|
|
}
|
|
if (!aPrsNameDiff.IsEmpty())
|
|
{
|
|
ViewerTest::Display (aPrsNameDiff, anImgDiffPrs, false, true);
|
|
}
|
|
ViewerTest::CurrentView()->SetProj (V3d_Zpos);
|
|
ViewerTest::CurrentView()->FitAll();
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VSelect
|
|
//purpose : Emulates different types of selection by mouse:
|
|
// 1) single click selection
|
|
// 2) selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2)
|
|
// 3) selection with polygon having corners at
|
|
// pixel positions (x1,y1),...,(xn,yn)
|
|
// 4) any of these selections with shift button pressed
|
|
//=======================================================================
|
|
static Standard_Integer VSelect (Draw_Interpretor& ,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
|
if (aCtx.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
NCollection_Sequence<Graphic3d_Vec2i> aPnts;
|
|
bool toAllowOverlap = false;
|
|
AIS_SelectionScheme aSelScheme = AIS_SelectionScheme_Replace;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anArg == "-allowoverlap")
|
|
{
|
|
toAllowOverlap = true;
|
|
if (anArgIter + 1 < theNbArgs
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toAllowOverlap))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (anArg == "-replace")
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_Replace;
|
|
}
|
|
else if (anArg == "-replaceextra")
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_ReplaceExtra;
|
|
}
|
|
else if (anArg == "-xor"
|
|
|| anArg == "-shift")
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_XOR;
|
|
}
|
|
else if (anArg == "-add")
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_Add;
|
|
}
|
|
else if (anArg == "-remove")
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_Remove;
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg.IsIntegerValue()
|
|
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
|
|
{
|
|
const TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
|
|
aPnts.Append (Graphic3d_Vec2i (anArg.IntegerValue(), anArgNext.IntegerValue()));
|
|
}
|
|
else if (anArgIter + 1 == theNbArgs
|
|
&& anArg.IsIntegerValue())
|
|
{
|
|
if (anArg.IntegerValue() == 1)
|
|
{
|
|
aSelScheme = AIS_SelectionScheme_XOR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (toAllowOverlap)
|
|
{
|
|
aCtx->MainSelector()->AllowOverlapDetection (toAllowOverlap);
|
|
}
|
|
|
|
Handle(ViewerTest_EventManager) aCurrentEventManager = ViewerTest::CurrentEventManager();
|
|
if (aPnts.IsEmpty())
|
|
{
|
|
aCtx->SelectDetected (aSelScheme);
|
|
aCtx->CurrentViewer()->Invalidate();
|
|
}
|
|
else if (aPnts.Length() == 2)
|
|
{
|
|
if (toAllowOverlap
|
|
&& aPnts.First().y() < aPnts.Last().y())
|
|
{
|
|
std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
|
|
}
|
|
else if (!toAllowOverlap
|
|
&& aPnts.First().y() > aPnts.Last().y())
|
|
{
|
|
std::swap (aPnts.ChangeFirst(), aPnts.ChangeLast());
|
|
}
|
|
|
|
aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
|
|
}
|
|
else
|
|
{
|
|
aCurrentEventManager->SelectInViewer (aPnts, aSelScheme);
|
|
}
|
|
aCurrentEventManager->FlushViewEvents (aCtx, ViewerTest::CurrentView(), true);
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VMoveTo
|
|
//purpose : Emulates cursor movement to defined pixel position
|
|
//=======================================================================
|
|
static Standard_Integer VMoveTo (Draw_Interpretor& theDI,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (aContext.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Graphic3d_Vec2i aMousePos (IntegerLast(), IntegerLast());
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
|
|
anArgStr.LowerCase();
|
|
if (anArgStr == "-reset"
|
|
|| anArgStr == "-clear")
|
|
{
|
|
if (anArgIter + 1 < theNbArgs)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter + 1] << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Boolean toEchoGrid = aContext->CurrentViewer()->IsGridActive()
|
|
&& aContext->CurrentViewer()->GridEcho();
|
|
if (toEchoGrid)
|
|
{
|
|
aContext->CurrentViewer()->HideGridEcho (aView);
|
|
}
|
|
if (aContext->ClearDetected() || toEchoGrid)
|
|
{
|
|
aContext->CurrentViewer()->RedrawImmediate();
|
|
}
|
|
return 0;
|
|
}
|
|
else if (aMousePos.x() == IntegerLast()
|
|
&& anArgStr.IsIntegerValue())
|
|
{
|
|
aMousePos.x() = anArgStr.IntegerValue();
|
|
}
|
|
else if (aMousePos.y() == IntegerLast()
|
|
&& anArgStr.IsIntegerValue())
|
|
{
|
|
aMousePos.y() = anArgStr.IntegerValue();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aMousePos.x() == IntegerLast()
|
|
|| aMousePos.y() == IntegerLast())
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest::CurrentEventManager()->ResetPreviousMoveTo();
|
|
ViewerTest::CurrentEventManager()->UpdateMousePosition (aMousePos, Aspect_VKeyMouse_NONE, Aspect_VKeyFlags_NONE, false);
|
|
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
|
|
|
|
gp_Pnt aTopPnt (RealLast(), RealLast(), RealLast());
|
|
const Handle(SelectMgr_EntityOwner)& aDetOwner = aContext->DetectedOwner();
|
|
for (Standard_Integer aDetIter = 1; aDetIter <= aContext->MainSelector()->NbPicked(); ++aDetIter)
|
|
{
|
|
if (aContext->MainSelector()->Picked (aDetIter) == aDetOwner)
|
|
{
|
|
aTopPnt = aContext->MainSelector()->PickedPoint (aDetIter);
|
|
break;
|
|
}
|
|
}
|
|
theDI << aTopPnt.X() << " " << aTopPnt.Y() << " " << aTopPnt.Z();
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VSelectByAxis
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VSelectByAxis (Draw_Interpretor& theDI,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (aContext.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aName;
|
|
gp_XYZ anAxisLocation(RealLast(), RealLast(), RealLast());
|
|
gp_XYZ anAxisDirection(RealLast(), RealLast(), RealLast());
|
|
Standard_Boolean isOnlyTop = true;
|
|
Standard_Boolean toShowNormal = false;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArgStr (theArgVec[anArgIter]);
|
|
anArgStr.LowerCase();
|
|
if (anArgStr == "-display")
|
|
{
|
|
if (anArgIter + 1 >= theNbArgs)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArgStr << "'";
|
|
return 1;
|
|
}
|
|
aName = theArgVec[++anArgIter];
|
|
}
|
|
else if (anArgStr == "-onlytop")
|
|
{
|
|
isOnlyTop = true;
|
|
if (anArgIter + 1 < theNbArgs
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isOnlyTop))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (anArgStr == "-shownormal")
|
|
{
|
|
toShowNormal = true;
|
|
if (anArgIter + 1 < theNbArgs
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toShowNormal))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (Precision::IsInfinite(anAxisLocation.X())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisLocation.SetX (anArgStr.RealValue());
|
|
}
|
|
else if (Precision::IsInfinite(anAxisLocation.Y())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisLocation.SetY (anArgStr.RealValue());
|
|
}
|
|
else if (Precision::IsInfinite(anAxisLocation.Z())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisLocation.SetZ (anArgStr.RealValue());
|
|
}
|
|
else if (Precision::IsInfinite(anAxisDirection.X())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisDirection.SetX (anArgStr.RealValue());
|
|
}
|
|
else if (Precision::IsInfinite(anAxisDirection.Y())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisDirection.SetY (anArgStr.RealValue());
|
|
}
|
|
else if (Precision::IsInfinite(anAxisDirection.Z())
|
|
&& anArgStr.IsRealValue())
|
|
{
|
|
anAxisDirection.SetZ (anArgStr.RealValue());
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (Precision::IsInfinite (anAxisLocation.X()) ||
|
|
Precision::IsInfinite (anAxisLocation.Y()) ||
|
|
Precision::IsInfinite (anAxisLocation.Z()) ||
|
|
Precision::IsInfinite (anAxisDirection.X()) ||
|
|
Precision::IsInfinite (anAxisDirection.Y()) ||
|
|
Precision::IsInfinite (anAxisDirection.Z()))
|
|
{
|
|
Message::SendFail() << "Invalid axis location and direction";
|
|
return 1;
|
|
}
|
|
|
|
gp_Ax1 anAxis(anAxisLocation, anAxisDirection);
|
|
gp_Pnt aTopPnt;
|
|
if (!ViewerTest::CurrentEventManager()->PickAxis (aTopPnt, aContext, aView, anAxis))
|
|
{
|
|
theDI << "There are no any intersections with this axis.";
|
|
return 0;
|
|
}
|
|
NCollection_Sequence<gp_Pnt> aPoints;
|
|
NCollection_Sequence<Graphic3d_Vec3> aNormals;
|
|
NCollection_Sequence<Standard_Real> aNormalLengths;
|
|
for (Standard_Integer aPickIter = 1; aPickIter <= aContext->MainSelector()->NbPicked(); ++aPickIter)
|
|
{
|
|
const SelectMgr_SortCriterion& aPickedData = aContext->MainSelector()->PickedData (aPickIter);
|
|
aPoints.Append (aPickedData.Point);
|
|
aNormals.Append (aPickedData.Normal);
|
|
Standard_Real aNormalLength = 1.0;
|
|
if (!aPickedData.Entity.IsNull())
|
|
{
|
|
aNormalLength = 0.2 * aPickedData.Entity->BoundingBox().Size().maxComp();
|
|
}
|
|
aNormalLengths.Append (aNormalLength);
|
|
}
|
|
if (!aName.IsEmpty())
|
|
{
|
|
Standard_Boolean wasAuto = aContext->GetAutoActivateSelection();
|
|
aContext->SetAutoActivateSelection (false);
|
|
|
|
// Display axis
|
|
Quantity_Color anAxisColor = Quantity_NOC_GREEN;
|
|
Handle(Geom_Axis2Placement) anAx2Axis =
|
|
new Geom_Axis2Placement (gp_Ax2(anAxisLocation, anAxisDirection));
|
|
Handle(AIS_Axis) anAISAxis = new AIS_Axis (gp_Ax1 (anAxisLocation, anAxisDirection));
|
|
anAISAxis->SetColor (anAxisColor);
|
|
ViewerTest::Display (TCollection_AsciiString (aName) + "_axis", anAISAxis, false);
|
|
|
|
// Display axis start point
|
|
Handle(AIS_Point) anAISStartPnt = new AIS_Point (new Geom_CartesianPoint (anAxisLocation));
|
|
anAISStartPnt->SetMarker (Aspect_TOM_O);
|
|
anAISStartPnt->SetColor (anAxisColor);
|
|
ViewerTest::Display (TCollection_AsciiString(aName) + "_start", anAISStartPnt, false);
|
|
|
|
Standard_Integer anIndex = 0;
|
|
for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter(aPoints); aPntIter.More(); aPntIter.Next(), anIndex++)
|
|
{
|
|
const gp_Pnt& aPoint = aPntIter.Value();
|
|
|
|
// Display normals in intersection points
|
|
if (toShowNormal)
|
|
{
|
|
const Graphic3d_Vec3& aNormal = aNormals.Value (anIndex + 1);
|
|
Standard_Real aNormalLength = aNormalLengths.Value (anIndex + 1);
|
|
if (aNormal.SquareModulus() > ShortRealEpsilon())
|
|
{
|
|
gp_Dir aNormalDir ((Standard_Real)aNormal.x(), (Standard_Real)aNormal.y(), (Standard_Real)aNormal.z());
|
|
Handle(AIS_Axis) anAISNormal = new AIS_Axis (gp_Ax1 (aPoint, aNormalDir), aNormalLength);
|
|
anAISNormal->SetColor (Quantity_NOC_BLUE);
|
|
anAISNormal->SetInfiniteState (false);
|
|
ViewerTest::Display (TCollection_AsciiString(aName) + "_normal_" + anIndex, anAISNormal, false);
|
|
}
|
|
}
|
|
|
|
// Display intersection points
|
|
Handle(Geom_CartesianPoint) anIntersectPnt = new Geom_CartesianPoint (aPoint);
|
|
Handle(AIS_Point) anAISIntersectPoint = new AIS_Point (anIntersectPnt);
|
|
anAISIntersectPoint->SetMarker (Aspect_TOM_PLUS);
|
|
anAISIntersectPoint->SetColor (Quantity_NOC_RED);
|
|
ViewerTest::Display (TCollection_AsciiString(aName) + "_intersect_" + anIndex, anAISIntersectPoint, true);
|
|
}
|
|
|
|
aContext->SetAutoActivateSelection (wasAuto);
|
|
}
|
|
|
|
Standard_Integer anIndex = 0;
|
|
for (NCollection_Sequence<gp_Pnt>::Iterator anIter(aPoints); anIter.More(); anIter.Next(), anIndex++)
|
|
{
|
|
const gp_Pnt& aPnt = anIter.Value();
|
|
theDI << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
//! Global map storing all animations registered in ViewerTest.
|
|
static NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)> ViewerTest_AnimationTimelineMap;
|
|
|
|
//! The animation calling the Draw Harness command.
|
|
class ViewerTest_AnimationProc : public AIS_Animation
|
|
{
|
|
DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationProc, AIS_Animation)
|
|
public:
|
|
|
|
//! Main constructor.
|
|
ViewerTest_AnimationProc (const TCollection_AsciiString& theAnimationName,
|
|
Draw_Interpretor* theDI,
|
|
const TCollection_AsciiString& theCommand)
|
|
: AIS_Animation (theAnimationName),
|
|
myDrawInter(theDI),
|
|
myCommand (theCommand)
|
|
{
|
|
//
|
|
}
|
|
|
|
protected:
|
|
|
|
//! Evaluate the command.
|
|
virtual void update (const AIS_AnimationProgress& theProgress) Standard_OVERRIDE
|
|
{
|
|
TCollection_AsciiString aCmd = myCommand;
|
|
replace (aCmd, "%pts", TCollection_AsciiString(theProgress.Pts));
|
|
replace (aCmd, "%localpts", TCollection_AsciiString(theProgress.LocalPts));
|
|
replace (aCmd, "%ptslocal", TCollection_AsciiString(theProgress.LocalPts));
|
|
replace (aCmd, "%normalized", TCollection_AsciiString(theProgress.LocalNormalized));
|
|
replace (aCmd, "%localnormalized", TCollection_AsciiString(theProgress.LocalNormalized));
|
|
myDrawInter->Eval (aCmd.ToCString());
|
|
}
|
|
|
|
//! Find the keyword in the command and replace it with value.
|
|
//! @return the position of the keyword to pass value
|
|
void replace (TCollection_AsciiString& theCmd,
|
|
const TCollection_AsciiString& theKey,
|
|
const TCollection_AsciiString& theVal)
|
|
{
|
|
TCollection_AsciiString aCmd (theCmd);
|
|
aCmd.LowerCase();
|
|
const Standard_Integer aPos = aCmd.Search (theKey);
|
|
if (aPos == -1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TCollection_AsciiString aPart1, aPart2;
|
|
Standard_Integer aPart1To = aPos - 1;
|
|
if (aPart1To >= 1
|
|
&& aPart1To <= theCmd.Length())
|
|
{
|
|
aPart1 = theCmd.SubString (1, aPart1To);
|
|
}
|
|
|
|
Standard_Integer aPart2From = aPos + theKey.Length();
|
|
if (aPart2From >= 1
|
|
&& aPart2From <= theCmd.Length())
|
|
{
|
|
aPart2 = theCmd.SubString (aPart2From, theCmd.Length());
|
|
}
|
|
|
|
theCmd = aPart1 + theVal + aPart2;
|
|
}
|
|
|
|
protected:
|
|
|
|
Draw_Interpretor* myDrawInter;
|
|
TCollection_AsciiString myCommand;
|
|
|
|
};
|
|
|
|
//! Auxiliary animation holder.
|
|
class ViewerTest_AnimationHolder : public AIS_AnimationCamera
|
|
{
|
|
DEFINE_STANDARD_RTTI_INLINE(ViewerTest_AnimationHolder, AIS_AnimationCamera)
|
|
public:
|
|
ViewerTest_AnimationHolder (const Handle(AIS_Animation)& theAnim,
|
|
const Handle(V3d_View)& theView,
|
|
const Standard_Boolean theIsFreeView)
|
|
: AIS_AnimationCamera ("ViewerTest_AnimationHolder", Handle(V3d_View)())
|
|
{
|
|
if (theAnim->Timer().IsNull())
|
|
{
|
|
theAnim->SetTimer (new Media_Timer());
|
|
}
|
|
myTimer = theAnim->Timer();
|
|
myView = theView;
|
|
if (theIsFreeView)
|
|
{
|
|
myCamStart = new Graphic3d_Camera (theView->Camera());
|
|
}
|
|
Add (theAnim);
|
|
}
|
|
|
|
//! Start playback.
|
|
virtual void StartTimer (const Standard_Real theStartPts,
|
|
const Standard_Real thePlaySpeed,
|
|
const Standard_Boolean theToUpdate,
|
|
const Standard_Boolean theToStopTimer) Standard_OVERRIDE
|
|
{
|
|
base_type::StartTimer (theStartPts, thePlaySpeed, theToUpdate, theToStopTimer);
|
|
if (theToStopTimer)
|
|
{
|
|
abortPlayback();
|
|
}
|
|
}
|
|
|
|
//! Pause animation.
|
|
virtual void Pause() Standard_OVERRIDE
|
|
{
|
|
myState = AnimationState_Paused;
|
|
// default implementation would stop all children,
|
|
// but we want to keep wrapped animation paused
|
|
myAnimations.First()->Pause();
|
|
abortPlayback();
|
|
}
|
|
|
|
//! Stop animation.
|
|
virtual void Stop() Standard_OVERRIDE
|
|
{
|
|
base_type::Stop();
|
|
abortPlayback();
|
|
}
|
|
|
|
//! Process one step of the animation according to the input time progress, including all children.
|
|
virtual void updateWithChildren (const AIS_AnimationProgress& thePosition) Standard_OVERRIDE
|
|
{
|
|
Handle(V3d_View) aView = myView;
|
|
if (!aView.IsNull()
|
|
&& !myCamStart.IsNull())
|
|
{
|
|
myCamStart->Copy (aView->Camera());
|
|
}
|
|
base_type::updateWithChildren (thePosition);
|
|
if (!aView.IsNull()
|
|
&& !myCamStart.IsNull())
|
|
{
|
|
aView->Camera()->Copy (myCamStart);
|
|
}
|
|
}
|
|
private:
|
|
void abortPlayback()
|
|
{
|
|
if (!myView.IsNull())
|
|
{
|
|
myView.Nullify();
|
|
}
|
|
}
|
|
};
|
|
|
|
//! Replace the animation with the new one.
|
|
static void replaceAnimation (const Handle(AIS_Animation)& theParentAnimation,
|
|
Handle(AIS_Animation)& theAnimation,
|
|
const Handle(AIS_Animation)& theAnimationNew)
|
|
{
|
|
theAnimationNew->CopyFrom (theAnimation);
|
|
if (!theParentAnimation.IsNull())
|
|
{
|
|
theParentAnimation->Replace (theAnimation, theAnimationNew);
|
|
}
|
|
else
|
|
{
|
|
ViewerTest_AnimationTimelineMap.UnBind (theAnimationNew->Name());
|
|
ViewerTest_AnimationTimelineMap.Bind (theAnimationNew->Name(), theAnimationNew);
|
|
}
|
|
theAnimation = theAnimationNew;
|
|
}
|
|
|
|
//! Parse the point.
|
|
static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
|
|
{
|
|
const TCollection_AsciiString anXYZ[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
|
|
if (!anXYZ[0].IsRealValue (Standard_True)
|
|
|| !anXYZ[1].IsRealValue (Standard_True)
|
|
|| !anXYZ[2].IsRealValue (Standard_True))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
thePnt.SetCoord (anXYZ[0].RealValue(), anXYZ[1].RealValue(), anXYZ[2].RealValue());
|
|
return Standard_True;
|
|
}
|
|
|
|
//! Parse the quaternion.
|
|
static Standard_Boolean parseQuaternion (const char** theArgVec, gp_Quaternion& theQRot)
|
|
{
|
|
const TCollection_AsciiString anXYZW[4] = {theArgVec[0], theArgVec[1], theArgVec[2], theArgVec[3]};
|
|
if (!anXYZW[0].IsRealValue (Standard_True)
|
|
|| !anXYZW[1].IsRealValue (Standard_True)
|
|
|| !anXYZW[2].IsRealValue (Standard_True)
|
|
|| !anXYZW[3].IsRealValue (Standard_True))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
theQRot.Set (anXYZW[0].RealValue(), anXYZW[1].RealValue(), anXYZW[2].RealValue(), anXYZW[3].RealValue());
|
|
return Standard_True;
|
|
}
|
|
|
|
//! Auxiliary class for flipping image upside-down.
|
|
class ImageFlipper
|
|
{
|
|
public:
|
|
|
|
//! Empty constructor.
|
|
ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
|
|
|
|
//! Perform flipping.
|
|
Standard_Boolean FlipY (Image_PixMap& theImage)
|
|
{
|
|
if (theImage.IsEmpty()
|
|
|| theImage.SizeX() == 0
|
|
|| theImage.SizeY() == 0)
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
const Standard_Size aRowSize = theImage.SizeRowBytes();
|
|
if (myTmp.Size() < aRowSize
|
|
&& !myTmp.Allocate (aRowSize))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
// for odd height middle row should be left as is
|
|
Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
|
|
for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
|
|
{
|
|
Standard_Byte* aTop = theImage.ChangeRow (aRowT);
|
|
Standard_Byte* aBot = theImage.ChangeRow (aRowB);
|
|
memcpy (myTmp.ChangeData(), aTop, aRowSize);
|
|
memcpy (aTop, aBot, aRowSize);
|
|
memcpy (aBot, myTmp.Data(), aRowSize);
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
private:
|
|
NCollection_Buffer myTmp;
|
|
};
|
|
|
|
}
|
|
|
|
//=================================================================================================
|
|
//function : VViewParams
|
|
//purpose : Gets or sets AIS View characteristics
|
|
//=================================================================================================
|
|
static int VViewParams (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean toSetProj = Standard_False;
|
|
Standard_Boolean toSetUp = Standard_False;
|
|
Standard_Boolean toSetAt = Standard_False;
|
|
Standard_Boolean toSetEye = Standard_False;
|
|
Standard_Boolean toSetScale = Standard_False;
|
|
Standard_Boolean toSetSize = Standard_False;
|
|
Standard_Boolean toSetCenter2d = Standard_False;
|
|
Standard_Real aViewScale = aView->Scale();
|
|
Standard_Real aViewAspect = aView->Camera()->Aspect();
|
|
Standard_Real aViewSize = 1.0;
|
|
Graphic3d_Vec2i aCenter2d;
|
|
gp_XYZ aViewProj, aViewUp, aViewAt, aViewEye;
|
|
aView->Proj (aViewProj.ChangeCoord (1), aViewProj.ChangeCoord (2), aViewProj.ChangeCoord (3));
|
|
aView->Up (aViewUp .ChangeCoord (1), aViewUp .ChangeCoord (2), aViewUp .ChangeCoord (3));
|
|
aView->At (aViewAt .ChangeCoord (1), aViewAt .ChangeCoord (2), aViewAt .ChangeCoord (3));
|
|
aView->Eye (aViewEye .ChangeCoord (1), aViewEye .ChangeCoord (2), aViewEye .ChangeCoord (3));
|
|
const Graphic3d_Mat4d& anOrientMat = aView->Camera()->OrientationMatrix();
|
|
const Graphic3d_Mat4d& aProjMat = aView->Camera()->ProjectionMatrix();
|
|
if (theArgsNb == 1)
|
|
{
|
|
// print all of the available view parameters
|
|
char aText[4096];
|
|
Sprintf (aText,
|
|
"Scale: %g\n"
|
|
"Aspect: %g\n"
|
|
"Proj: %12g %12g %12g\n"
|
|
"Up: %12g %12g %12g\n"
|
|
"At: %12g %12g %12g\n"
|
|
"Eye: %12g %12g %12g\n"
|
|
"OrientMat: %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n"
|
|
"ProjMat: %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n"
|
|
" %12g %12g %12g %12g\n",
|
|
aViewScale, aViewAspect,
|
|
aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
|
|
aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
|
|
aViewAt.X(), aViewAt.Y(), aViewAt.Z(),
|
|
aViewEye.X(), aViewEye.Y(), aViewEye.Z(),
|
|
anOrientMat.GetValue (0, 0), anOrientMat.GetValue (0, 1), anOrientMat.GetValue (0, 2), anOrientMat.GetValue (0, 3),
|
|
anOrientMat.GetValue (1, 0), anOrientMat.GetValue (1, 1), anOrientMat.GetValue (1, 2), anOrientMat.GetValue (1, 3),
|
|
anOrientMat.GetValue (2, 0), anOrientMat.GetValue (2, 1), anOrientMat.GetValue (2, 2), anOrientMat.GetValue (2, 3),
|
|
anOrientMat.GetValue (3, 0), anOrientMat.GetValue (3, 1), anOrientMat.GetValue (3, 2), anOrientMat.GetValue (3, 3),
|
|
aProjMat.GetValue (0, 0), aProjMat.GetValue (0, 1), aProjMat.GetValue (0, 2), aProjMat.GetValue (0, 3),
|
|
aProjMat.GetValue (1, 0), aProjMat.GetValue (1, 1), aProjMat.GetValue (1, 2), aProjMat.GetValue (1, 3),
|
|
aProjMat.GetValue (2, 0), aProjMat.GetValue (2, 1), aProjMat.GetValue (2, 2), aProjMat.GetValue (2, 3),
|
|
aProjMat.GetValue (3, 0), aProjMat.GetValue (3, 1), aProjMat.GetValue (3, 2), aProjMat.GetValue (3, 3));
|
|
theDi << aText;
|
|
return 0;
|
|
}
|
|
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArg == "-cmd"
|
|
|| anArg == "-command"
|
|
|| anArg == "-args")
|
|
{
|
|
char aText[4096];
|
|
Sprintf (aText,
|
|
"-scale %g "
|
|
"-proj %g %g %g "
|
|
"-up %g %g %g "
|
|
"-at %g %g %g\n",
|
|
aViewScale,
|
|
aViewProj.X(), aViewProj.Y(), aViewProj.Z(),
|
|
aViewUp.X(), aViewUp.Y(), aViewUp.Z(),
|
|
aViewAt.X(), aViewAt.Y(), aViewAt.Z());
|
|
theDi << aText;
|
|
}
|
|
else if (anArg == "-scale"
|
|
|| anArg == "-size")
|
|
{
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& *theArgVec[anArgIter + 1] != '-')
|
|
{
|
|
const TCollection_AsciiString aValueArg (theArgVec[anArgIter + 1]);
|
|
if (aValueArg.IsRealValue (Standard_True))
|
|
{
|
|
++anArgIter;
|
|
if (anArg == "-scale")
|
|
{
|
|
toSetScale = Standard_True;
|
|
aViewScale = aValueArg.RealValue();
|
|
}
|
|
else if (anArg == "-size")
|
|
{
|
|
toSetSize = Standard_True;
|
|
aViewSize = aValueArg.RealValue();
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
if (anArg == "-scale")
|
|
{
|
|
theDi << "Scale: " << aView->Scale() << "\n";
|
|
}
|
|
else if (anArg == "-size")
|
|
{
|
|
Graphic3d_Vec2d aSizeXY;
|
|
aView->Size (aSizeXY.x(), aSizeXY.y());
|
|
theDi << "Size: " << aSizeXY.x() << " " << aSizeXY.y() << "\n";
|
|
}
|
|
}
|
|
else if (anArg == "-eye"
|
|
|| anArg == "-at"
|
|
|| anArg == "-up"
|
|
|| anArg == "-proj")
|
|
{
|
|
if (anArgIter + 3 < theArgsNb)
|
|
{
|
|
gp_XYZ anXYZ;
|
|
if (parseXYZ (theArgVec + anArgIter + 1, anXYZ))
|
|
{
|
|
anArgIter += 3;
|
|
if (anArg == "-eye")
|
|
{
|
|
toSetEye = Standard_True;
|
|
aViewEye = anXYZ;
|
|
}
|
|
else if (anArg == "-at")
|
|
{
|
|
toSetAt = Standard_True;
|
|
aViewAt = anXYZ;
|
|
}
|
|
else if (anArg == "-up")
|
|
{
|
|
toSetUp = Standard_True;
|
|
aViewUp = anXYZ;
|
|
}
|
|
else if (anArg == "-proj")
|
|
{
|
|
toSetProj = Standard_True;
|
|
aViewProj = anXYZ;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (anArg == "-eye")
|
|
{
|
|
theDi << "Eye: " << aViewEye.X() << " " << aViewEye.Y() << " " << aViewEye.Z() << "\n";
|
|
}
|
|
else if (anArg == "-at")
|
|
{
|
|
theDi << "At: " << aViewAt.X() << " " << aViewAt.Y() << " " << aViewAt.Z() << "\n";
|
|
}
|
|
else if (anArg == "-up")
|
|
{
|
|
theDi << "Up: " << aViewUp.X() << " " << aViewUp.Y() << " " << aViewUp.Z() << "\n";
|
|
}
|
|
else if (anArg == "-proj")
|
|
{
|
|
theDi << "Proj: " << aViewProj.X() << " " << aViewProj.Y() << " " << aViewProj.Z() << "\n";
|
|
}
|
|
}
|
|
else if (anArg == "-center")
|
|
{
|
|
if (anArgIter + 2 < theArgsNb)
|
|
{
|
|
const TCollection_AsciiString anX (theArgVec[anArgIter + 1]);
|
|
const TCollection_AsciiString anY (theArgVec[anArgIter + 2]);
|
|
if (anX.IsIntegerValue()
|
|
&& anY.IsIntegerValue())
|
|
{
|
|
toSetCenter2d = Standard_True;
|
|
aCenter2d = Graphic3d_Vec2i (anX.IntegerValue(), anY.IntegerValue());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// change view parameters in proper order
|
|
if (toSetScale)
|
|
{
|
|
aView->SetScale (aViewScale);
|
|
}
|
|
if (toSetSize)
|
|
{
|
|
aView->SetSize (aViewSize);
|
|
}
|
|
if (toSetEye)
|
|
{
|
|
aView->SetEye (aViewEye.X(), aViewEye.Y(), aViewEye.Z());
|
|
}
|
|
if (toSetAt)
|
|
{
|
|
aView->SetAt (aViewAt.X(), aViewAt.Y(), aViewAt.Z());
|
|
}
|
|
if (toSetProj)
|
|
{
|
|
aView->SetProj (aViewProj.X(), aViewProj.Y(), aViewProj.Z());
|
|
}
|
|
if (toSetUp)
|
|
{
|
|
aView->SetUp (aViewUp.X(), aViewUp.Y(), aViewUp.Z());
|
|
}
|
|
if (toSetCenter2d)
|
|
{
|
|
aView->SetCenter (aCenter2d.x(), aCenter2d.y());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : V2DMode
|
|
//purpose :
|
|
//==============================================================================
|
|
static Standard_Integer V2DMode (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
bool is2dMode = true;
|
|
Handle(ViewerTest_V3dView) aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest::CurrentView());
|
|
if (aV3dView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
|
|
{
|
|
const TCollection_AsciiString anArg = theArgVec[anArgIt];
|
|
TCollection_AsciiString anArgCase = anArg;
|
|
anArgCase.LowerCase();
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& anArgCase == "-name")
|
|
{
|
|
ViewerTest_Names aViewNames (theArgVec[++anArgIt]);
|
|
const TCollection_AsciiString& aViewName = aViewNames.GetViewName();
|
|
if (!ViewerTest_myViews.IsBound1 (aViewName))
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown view '" << theArgVec[anArgIt - 1] << "'";
|
|
return 1;
|
|
}
|
|
aV3dView = Handle(ViewerTest_V3dView)::DownCast (ViewerTest_myViews.Find1 (aViewName));
|
|
}
|
|
else if (anArgCase == "-mode")
|
|
{
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIt + 1], is2dMode))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
}
|
|
else if (Draw::ParseOnOff (theArgVec[anArgIt], is2dMode))
|
|
{
|
|
//
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument " << anArg;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
aV3dView->SetView2DMode (is2dMode);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VAnimation
|
|
//purpose :
|
|
//==============================================================================
|
|
static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
|
if (theArgNb < 2)
|
|
{
|
|
for (NCollection_DataMap<TCollection_AsciiString, Handle(AIS_Animation)>::Iterator
|
|
anAnimIter (ViewerTest_AnimationTimelineMap); anAnimIter.More(); anAnimIter.Next())
|
|
{
|
|
theDI << anAnimIter.Key() << " " << anAnimIter.Value()->Duration() << " sec\n";
|
|
}
|
|
return 0;
|
|
}
|
|
if (aCtx.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer anArgIter = 1;
|
|
TCollection_AsciiString aNameArg (theArgVec[anArgIter++]);
|
|
if (aNameArg.IsEmpty())
|
|
{
|
|
Message::SendFail ("Syntax error: animation name is not defined");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aNameArgLower = aNameArg;
|
|
aNameArgLower.LowerCase();
|
|
if (aNameArgLower == "-reset"
|
|
|| aNameArgLower == "-clear")
|
|
{
|
|
ViewerTest_AnimationTimelineMap.Clear();
|
|
return 0;
|
|
}
|
|
else if (aNameArg.Value (1) == '-')
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid animation name '" << aNameArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const char* aNameSplitter = "/";
|
|
Standard_Integer aSplitPos = aNameArg.Search (aNameSplitter);
|
|
if (aSplitPos == -1)
|
|
{
|
|
aNameSplitter = ".";
|
|
aSplitPos = aNameArg.Search (aNameSplitter);
|
|
}
|
|
|
|
// find existing or create a new animation by specified name within syntax "parent.child".
|
|
Handle(AIS_Animation) aRootAnimation, aParentAnimation, anAnimation;
|
|
for (; !aNameArg.IsEmpty();)
|
|
{
|
|
TCollection_AsciiString aNameParent;
|
|
if (aSplitPos != -1)
|
|
{
|
|
if (aSplitPos == aNameArg.Length())
|
|
{
|
|
Message::SendFail ("Syntax error: animation name is not defined");
|
|
return 1;
|
|
}
|
|
|
|
aNameParent = aNameArg.SubString ( 1, aSplitPos - 1);
|
|
aNameArg = aNameArg.SubString (aSplitPos + 1, aNameArg.Length());
|
|
|
|
aSplitPos = aNameArg.Search (aNameSplitter);
|
|
}
|
|
else
|
|
{
|
|
aNameParent = aNameArg;
|
|
aNameArg.Clear();
|
|
}
|
|
|
|
if (anAnimation.IsNull())
|
|
{
|
|
if (!ViewerTest_AnimationTimelineMap.Find (aNameParent, anAnimation))
|
|
{
|
|
anAnimation = new AIS_Animation (aNameParent);
|
|
ViewerTest_AnimationTimelineMap.Bind (aNameParent, anAnimation);
|
|
}
|
|
aRootAnimation = anAnimation;
|
|
}
|
|
else
|
|
{
|
|
aParentAnimation = anAnimation;
|
|
anAnimation = aParentAnimation->Find (aNameParent);
|
|
if (anAnimation.IsNull())
|
|
{
|
|
anAnimation = new AIS_Animation (aNameParent);
|
|
aParentAnimation->Add (anAnimation);
|
|
}
|
|
}
|
|
}
|
|
if (anAnimation.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number of arguments";
|
|
return 1;
|
|
}
|
|
|
|
if (anArgIter >= theArgNb)
|
|
{
|
|
// just print the list of children
|
|
for (NCollection_Sequence<Handle(AIS_Animation)>::Iterator anAnimIter (anAnimation->Children()); anAnimIter.More(); anAnimIter.Next())
|
|
{
|
|
theDI << anAnimIter.Value()->Name() << " " << anAnimIter.Value()->Duration() << " sec\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// animation parameters
|
|
Standard_Boolean toPlay = Standard_False;
|
|
Standard_Real aPlaySpeed = 1.0;
|
|
Standard_Real aPlayStartTime = anAnimation->StartPts();
|
|
Standard_Real aPlayDuration = anAnimation->Duration();
|
|
Standard_Boolean isFreeCamera = Standard_False;
|
|
Standard_Boolean toPauseOnClick = Standard_True;
|
|
Standard_Boolean isLockLoop = Standard_False;
|
|
Standard_Boolean toPrintElapsedTime = Standard_False;
|
|
|
|
// video recording parameters
|
|
TCollection_AsciiString aRecFile;
|
|
Image_VideoParams aRecParams;
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
for (; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
// general options
|
|
if (anArg == "-reset"
|
|
|| anArg == "-clear")
|
|
{
|
|
anAnimation->Clear();
|
|
}
|
|
else if (anArg == "-remove"
|
|
|| anArg == "-del"
|
|
|| anArg == "-delete")
|
|
{
|
|
if (aParentAnimation.IsNull())
|
|
{
|
|
ViewerTest_AnimationTimelineMap.UnBind (anAnimation->Name());
|
|
}
|
|
else
|
|
{
|
|
aParentAnimation->Remove (anAnimation);
|
|
}
|
|
}
|
|
// playback options
|
|
else if (anArg == "-play")
|
|
{
|
|
toPlay = Standard_True;
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
if (*theArgVec[anArgIter] == '-')
|
|
{
|
|
--anArgIter;
|
|
continue;
|
|
}
|
|
aPlayStartTime = Draw::Atof (theArgVec[anArgIter]);
|
|
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
if (*theArgVec[anArgIter] == '-')
|
|
{
|
|
--anArgIter;
|
|
continue;
|
|
}
|
|
aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
}
|
|
}
|
|
else if (anArg == "-elapsedtime"
|
|
|| anArg == "-elapsed")
|
|
{
|
|
toPrintElapsedTime = Standard_True;
|
|
}
|
|
else if (anArg == "-resume")
|
|
{
|
|
toPlay = Standard_True;
|
|
aPlayStartTime = anAnimation->ElapsedTime();
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
if (*theArgVec[anArgIter] == '-')
|
|
{
|
|
--anArgIter;
|
|
continue;
|
|
}
|
|
|
|
aPlayDuration = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
}
|
|
else if (anArg == "-pause")
|
|
{
|
|
anAnimation->Pause();
|
|
}
|
|
else if (anArg == "-stop")
|
|
{
|
|
anAnimation->Stop();
|
|
}
|
|
else if (anArg == "-playspeed"
|
|
|| anArg == "-speed")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg << "";
|
|
return 1;
|
|
}
|
|
aPlaySpeed = Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (anArg == "-lock"
|
|
|| anArg == "-lockloop"
|
|
|| anArg == "-playlockloop")
|
|
{
|
|
isLockLoop = Draw::ParseOnOffIterator (theArgNb, theArgVec, anArgIter);
|
|
}
|
|
else if (anArg == "-freecamera"
|
|
|| anArg == "-nofreecamera"
|
|
|| anArg == "-playfreecamera"
|
|
|| anArg == "-noplayfreecamera"
|
|
|| anArg == "-freelook"
|
|
|| anArg == "-nofreelook")
|
|
{
|
|
isFreeCamera = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
|
|
}
|
|
else if (anArg == "-pauseonclick"
|
|
|| anArg == "-nopauseonclick"
|
|
|| anArg == "-nopause")
|
|
{
|
|
toPauseOnClick = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
|
|
}
|
|
// video recodring options
|
|
else if (anArg == "-rec"
|
|
|| anArg == "-record")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
aRecFile = theArgVec[anArgIter];
|
|
if (aRecParams.FpsNum <= 0)
|
|
{
|
|
aRecParams.FpsNum = 24;
|
|
}
|
|
|
|
if (anArgIter + 2 < theArgNb
|
|
&& *theArgVec[anArgIter + 1] != '-'
|
|
&& *theArgVec[anArgIter + 2] != '-')
|
|
{
|
|
TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
|
|
TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
|
|
if (aWidthArg .IsIntegerValue()
|
|
&& aHeightArg.IsIntegerValue())
|
|
{
|
|
aRecParams.Width = aWidthArg .IntegerValue();
|
|
aRecParams.Height = aHeightArg.IntegerValue();
|
|
anArgIter += 2;
|
|
}
|
|
}
|
|
}
|
|
else if (anArg == "-fps")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aFpsArg (theArgVec[anArgIter]);
|
|
Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
|
|
if (aSplitIndex == 0)
|
|
{
|
|
aRecParams.FpsNum = aFpsArg.IntegerValue();
|
|
}
|
|
else
|
|
{
|
|
const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
|
|
aFpsArg.Split (aFpsArg.Length() - 1);
|
|
const TCollection_AsciiString aNumStr = aFpsArg;
|
|
aRecParams.FpsNum = aNumStr.IntegerValue();
|
|
aRecParams.FpsDen = aDenStr.IntegerValue();
|
|
if (aRecParams.FpsDen < 1)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else if (anArg == "-format")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aRecParams.Format = theArgVec[anArgIter];
|
|
}
|
|
else if (anArg == "-pix_fmt"
|
|
|| anArg == "-pixfmt"
|
|
|| anArg == "-pixelformat")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aRecParams.PixelFormat = theArgVec[anArgIter];
|
|
}
|
|
else if (anArg == "-codec"
|
|
|| anArg == "-vcodec"
|
|
|| anArg == "-videocodec")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aRecParams.VideoCodec = theArgVec[anArgIter];
|
|
}
|
|
else if (anArg == "-crf"
|
|
|| anArg == "-preset"
|
|
|| anArg == "-qp")
|
|
{
|
|
const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
|
|
}
|
|
// animation definition options
|
|
else if (anArg == "-start"
|
|
|| anArg == "-starttime"
|
|
|| anArg == "-startpts")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
anAnimation->SetStartPts (Draw::Atof (theArgVec[anArgIter]));
|
|
aRootAnimation->UpdateTotalDuration();
|
|
}
|
|
else if (anArg == "-end"
|
|
|| anArg == "-endtime"
|
|
|| anArg == "-endpts")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]) - anAnimation->StartPts());
|
|
aRootAnimation->UpdateTotalDuration();
|
|
}
|
|
else if (anArg == "-dur"
|
|
|| anArg == "-duration")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
anAnimation->SetOwnDuration (Draw::Atof (theArgVec[anArgIter]));
|
|
aRootAnimation->UpdateTotalDuration();
|
|
}
|
|
else if (anArg == "-command"
|
|
|| anArg == "-cmd"
|
|
|| anArg == "-invoke"
|
|
|| anArg == "-eval"
|
|
|| anArg == "-proc")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
Handle(ViewerTest_AnimationProc) aCmdAnimation = new ViewerTest_AnimationProc (anAnimation->Name(), &theDI, theArgVec[anArgIter]);
|
|
replaceAnimation (aParentAnimation, anAnimation, aCmdAnimation);
|
|
}
|
|
else if (anArg == "-objecttrsf"
|
|
|| anArg == "-objectransformation"
|
|
|| anArg == "-objtransformation"
|
|
|| anArg == "-objtrsf"
|
|
|| anArg == "-object"
|
|
|| anArg == "-obj")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString anObjName (theArgVec[anArgIter]);
|
|
const ViewerTest_DoubleMapOfInteractiveAndName& aMapOfAIS = GetMapOfAIS();
|
|
Handle(AIS_InteractiveObject) anObject;
|
|
if (!aMapOfAIS.Find2 (anObjName, anObject))
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong object name at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
gp_Trsf aTrsfs [2] = { anObject->LocalTransformation(), anObject->LocalTransformation() };
|
|
gp_Quaternion aRotQuats[2] = { aTrsfs[0].GetRotation(), aTrsfs[1].GetRotation() };
|
|
gp_XYZ aLocPnts [2] = { aTrsfs[0].TranslationPart(), aTrsfs[1].TranslationPart() };
|
|
Standard_Real aScales [2] = { aTrsfs[0].ScaleFactor(), aTrsfs[1].ScaleFactor() };
|
|
Standard_Boolean isTrsfSet = Standard_False;
|
|
|
|
gp_Ax1 anAxis;
|
|
Standard_Real anAngles[2] = { 0.0, 0.0 };
|
|
Standard_Boolean isAxisRotationSet = Standard_False;
|
|
|
|
Standard_Integer aTrsfArgIter = anArgIter + 1;
|
|
for (; aTrsfArgIter < theArgNb; ++aTrsfArgIter)
|
|
{
|
|
TCollection_AsciiString aTrsfArg (theArgVec[aTrsfArgIter]);
|
|
aTrsfArg.LowerCase();
|
|
const Standard_Integer anIndex = aTrsfArg.EndsWith ("1") ? 0 : 1;
|
|
if (aTrsfArg.StartsWith ("-rotation")
|
|
|| aTrsfArg.StartsWith ("-rot"))
|
|
{
|
|
isTrsfSet = Standard_True;
|
|
if (aTrsfArgIter + 4 >= theArgNb
|
|
|| !parseQuaternion (theArgVec + aTrsfArgIter + 1, aRotQuats[anIndex]))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
aTrsfArgIter += 4;
|
|
}
|
|
else if (aTrsfArg.StartsWith ("-location")
|
|
|| aTrsfArg.StartsWith ("-loc"))
|
|
{
|
|
isTrsfSet = Standard_True;
|
|
if (aTrsfArgIter + 3 >= theArgNb
|
|
|| !parseXYZ (theArgVec + aTrsfArgIter + 1, aLocPnts[anIndex]))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
aTrsfArgIter += 3;
|
|
}
|
|
else if (aTrsfArg.StartsWith ("-scale"))
|
|
{
|
|
isTrsfSet = Standard_True;
|
|
if (++aTrsfArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aScaleStr (theArgVec[aTrsfArgIter]);
|
|
if (!aScaleStr.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
aScales[anIndex] = aScaleStr.RealValue();
|
|
}
|
|
else if (aTrsfArg == "-axis")
|
|
{
|
|
isAxisRotationSet = Standard_True;
|
|
gp_XYZ anOrigin, aDirection;
|
|
if (aTrsfArgIter + 6 >= theArgNb
|
|
|| !parseXYZ (theArgVec + aTrsfArgIter + 1, anOrigin)
|
|
|| !parseXYZ (theArgVec + aTrsfArgIter + 4, aDirection))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
anAxis.SetLocation (anOrigin);
|
|
anAxis.SetDirection (aDirection);
|
|
aTrsfArgIter += 6;
|
|
}
|
|
else if (aTrsfArg.StartsWith ("-ang"))
|
|
{
|
|
isAxisRotationSet = Standard_True;
|
|
if (++aTrsfArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString anAngleStr (theArgVec[aTrsfArgIter]);
|
|
if (!anAngleStr.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aTrsfArg;
|
|
return 1;
|
|
}
|
|
anAngles[anIndex] = anAngleStr.RealValue();
|
|
}
|
|
else
|
|
{
|
|
anArgIter = aTrsfArgIter - 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!isTrsfSet && !isAxisRotationSet)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
else if (aTrsfArgIter >= theArgNb)
|
|
{
|
|
anArgIter = theArgNb;
|
|
}
|
|
Handle(AIS_BaseAnimationObject) anObjAnimation;
|
|
if (isTrsfSet)
|
|
{
|
|
aTrsfs[0].SetRotation (aRotQuats[0]);
|
|
aTrsfs[1].SetRotation (aRotQuats[1]);
|
|
aTrsfs[0].SetTranslationPart (aLocPnts[0]);
|
|
aTrsfs[1].SetTranslationPart (aLocPnts[1]);
|
|
aTrsfs[0].SetScaleFactor (aScales[0]);
|
|
aTrsfs[1].SetScaleFactor (aScales[1]);
|
|
|
|
anObjAnimation = new AIS_AnimationObject (anAnimation->Name(), aCtx, anObject, aTrsfs[0], aTrsfs[1]);
|
|
}
|
|
else
|
|
{
|
|
anObjAnimation = new AIS_AnimationAxisRotation (anAnimation->Name(), aCtx, anObject, anAxis,
|
|
anAngles[0] * (M_PI / 180.0), anAngles[1] * (M_PI / 180.0));
|
|
}
|
|
replaceAnimation (aParentAnimation, anAnimation, anObjAnimation);
|
|
}
|
|
else if (anArg == "-viewtrsf"
|
|
|| anArg == "-view")
|
|
{
|
|
Handle(AIS_AnimationCamera) aCamAnimation = Handle(AIS_AnimationCamera)::DownCast (anAnimation);
|
|
if (aCamAnimation.IsNull())
|
|
{
|
|
aCamAnimation = new AIS_AnimationCamera (anAnimation->Name(), aView);
|
|
replaceAnimation (aParentAnimation, anAnimation, aCamAnimation);
|
|
}
|
|
|
|
Handle(Graphic3d_Camera) aCams[2] =
|
|
{
|
|
new Graphic3d_Camera (aCamAnimation->View()->Camera()),
|
|
new Graphic3d_Camera (aCamAnimation->View()->Camera())
|
|
};
|
|
|
|
Standard_Boolean isTrsfSet = Standard_False;
|
|
Standard_Integer aViewArgIter = anArgIter + 1;
|
|
for (; aViewArgIter < theArgNb; ++aViewArgIter)
|
|
{
|
|
TCollection_AsciiString aViewArg (theArgVec[aViewArgIter]);
|
|
aViewArg.LowerCase();
|
|
const Standard_Integer anIndex = aViewArg.EndsWith("1") ? 0 : 1;
|
|
if (aViewArg.StartsWith ("-scale"))
|
|
{
|
|
isTrsfSet = Standard_True;
|
|
if (++aViewArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aScaleStr (theArgVec[aViewArgIter]);
|
|
if (!aScaleStr.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aViewArg;
|
|
return 1;
|
|
}
|
|
Standard_Real aScale = aScaleStr.RealValue();
|
|
aScale = aCamAnimation->View()->DefaultCamera()->Scale() / aScale;
|
|
aCams[anIndex]->SetScale (aScale);
|
|
}
|
|
else if (aViewArg.StartsWith ("-eye")
|
|
|| aViewArg.StartsWith ("-center")
|
|
|| aViewArg.StartsWith ("-at")
|
|
|| aViewArg.StartsWith ("-up"))
|
|
{
|
|
isTrsfSet = Standard_True;
|
|
gp_XYZ anXYZ;
|
|
if (aViewArgIter + 3 >= theArgNb
|
|
|| !parseXYZ (theArgVec + aViewArgIter + 1, anXYZ))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << aViewArg;
|
|
return 1;
|
|
}
|
|
aViewArgIter += 3;
|
|
|
|
if (aViewArg.StartsWith ("-eye"))
|
|
{
|
|
aCams[anIndex]->SetEye (anXYZ);
|
|
}
|
|
else if (aViewArg.StartsWith ("-center")
|
|
|| aViewArg.StartsWith ("-at"))
|
|
{
|
|
aCams[anIndex]->SetCenter (anXYZ);
|
|
}
|
|
else if (aViewArg.StartsWith ("-up"))
|
|
{
|
|
aCams[anIndex]->SetUp (anXYZ);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
anArgIter = aViewArgIter - 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!isTrsfSet)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
else if (aViewArgIter >= theArgNb)
|
|
{
|
|
anArgIter = theArgNb;
|
|
}
|
|
|
|
aCamAnimation->SetCameraStart(aCams[0]);
|
|
aCamAnimation->SetCameraEnd (aCams[1]);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (anAnimation.IsNull() || anAnimation->IsStopped())
|
|
{
|
|
ViewerTest::CurrentEventManager()->AbortViewAnimation();
|
|
ViewerTest::CurrentEventManager()->SetObjectsAnimation(Handle(AIS_Animation)());
|
|
}
|
|
|
|
if (toPrintElapsedTime)
|
|
{
|
|
theDI << "Elapsed Time: " << anAnimation->ElapsedTime() << " s\n";
|
|
}
|
|
|
|
if (!toPlay && aRecFile.IsEmpty())
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Start animation timeline and process frame updating.
|
|
if (aRecParams.FpsNum <= 0
|
|
&& !isLockLoop)
|
|
{
|
|
Handle(ViewerTest_AnimationHolder) aHolder = new ViewerTest_AnimationHolder (anAnimation, aView, isFreeCamera);
|
|
aHolder->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
|
|
ViewerTest::CurrentEventManager()->SetPauseObjectsAnimation (toPauseOnClick);
|
|
ViewerTest::CurrentEventManager()->SetObjectsAnimation (aHolder);
|
|
ViewerTest::CurrentEventManager()->ProcessExpose();
|
|
return 0;
|
|
}
|
|
|
|
// Perform video recording
|
|
const Standard_Boolean wasImmediateUpdate = aView->SetImmediateUpdate (Standard_False);
|
|
const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
|
|
anAnimation->StartTimer (aPlayStartTime, aPlaySpeed, Standard_True, aPlayDuration <= 0.0);
|
|
|
|
OSD_Timer aPerfTimer;
|
|
aPerfTimer.Start();
|
|
|
|
Handle(Image_VideoRecorder) aRecorder;
|
|
ImageFlipper aFlipper;
|
|
Handle(Draw_ProgressIndicator) aProgress;
|
|
if (!aRecFile.IsEmpty())
|
|
{
|
|
if (aRecParams.Width <= 0
|
|
|| aRecParams.Height <= 0)
|
|
{
|
|
aView->Window()->Size (aRecParams.Width, aRecParams.Height);
|
|
}
|
|
|
|
aRecorder = new Image_VideoRecorder();
|
|
if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
|
|
{
|
|
Message::SendFail ("Error: failed to open video file for recording");
|
|
return 0;
|
|
}
|
|
|
|
aProgress = new Draw_ProgressIndicator (theDI, 1);
|
|
}
|
|
|
|
// Manage frame-rated animation here
|
|
Standard_Real aPts = aPlayStartTime;
|
|
int64_t aNbFrames = 0;
|
|
Message_ProgressScope aPS(Message_ProgressIndicator::Start(aProgress),
|
|
"Video recording, sec", Max(1, Standard_Integer(aPlayDuration / aPlaySpeed)));
|
|
Standard_Integer aSecondsProgress = 0;
|
|
for (; aPts <= anUpperPts && aPS.More();)
|
|
{
|
|
Standard_Real aRecPts = 0.0;
|
|
if (aRecParams.FpsNum > 0)
|
|
{
|
|
aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
|
|
}
|
|
else
|
|
{
|
|
aRecPts = aPlaySpeed * aPerfTimer.ElapsedTime();
|
|
}
|
|
|
|
aPts = aPlayStartTime + aRecPts;
|
|
++aNbFrames;
|
|
if (!anAnimation->Update (aPts))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!aRecorder.IsNull())
|
|
{
|
|
V3d_ImageDumpOptions aDumpParams;
|
|
aDumpParams.Width = aRecParams.Width;
|
|
aDumpParams.Height = aRecParams.Height;
|
|
aDumpParams.BufferType = Graphic3d_BT_RGBA;
|
|
aDumpParams.StereoOptions = V3d_SDO_MONO;
|
|
aDumpParams.ToAdjustAspect = Standard_True;
|
|
if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
|
|
{
|
|
Message::SendFail ("Error: view dump is failed");
|
|
return 0;
|
|
}
|
|
aFlipper.FlipY (aRecorder->ChangeFrame());
|
|
if (!aRecorder->PushFrame())
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aView->Redraw();
|
|
}
|
|
|
|
while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
|
|
{
|
|
aPS.Next();
|
|
++aSecondsProgress;
|
|
}
|
|
}
|
|
|
|
aPerfTimer.Stop();
|
|
anAnimation->Stop();
|
|
const Standard_Real aRecFps = Standard_Real(aNbFrames) / aPerfTimer.ElapsedTime();
|
|
theDI << "Average FPS: " << aRecFps << "\n"
|
|
<< "Nb. Frames: " << Standard_Real(aNbFrames);
|
|
|
|
aView->Redraw();
|
|
aView->SetImmediateUpdate (wasImmediateUpdate);
|
|
return 0;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : VChangeSelected
|
|
//purpose : Adds the shape to selection or remove one from it
|
|
//=======================================================================
|
|
static Standard_Integer VChangeSelected (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
if(argc != 2)
|
|
{
|
|
di<<"Usage : " << argv[0] << " shape \n";
|
|
return 1;
|
|
}
|
|
//get AIS_Shape:
|
|
TCollection_AsciiString aName(argv[1]);
|
|
Handle(AIS_InteractiveObject) anAISObject;
|
|
if (!GetMapOfAIS().Find2 (aName, anAISObject)
|
|
|| anAISObject.IsNull())
|
|
{
|
|
di<<"Use 'vdisplay' before";
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest::GetAISContext()->AddOrRemoveSelected(anAISObject, Standard_True);
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VNbSelected
|
|
//purpose : Returns number of selected objects
|
|
//=======================================================================
|
|
static Standard_Integer VNbSelected (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
if(argc != 1)
|
|
{
|
|
di << "Usage : " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if(aContext.IsNull())
|
|
{
|
|
di << "use 'vinit' command before " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
di << aContext->NbSelected() << "\n";
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VSetViewSize
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VSetViewSize (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if(aContext.IsNull())
|
|
{
|
|
di << "use 'vinit' command before " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
if(argc != 2)
|
|
{
|
|
di<<"Usage : " << argv[0] << " Size\n";
|
|
return 1;
|
|
}
|
|
Standard_Real aSize = Draw::Atof (argv[1]);
|
|
if (aSize <= 0.)
|
|
{
|
|
di<<"Bad Size value : " << aSize << "\n";
|
|
return 1;
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
aView->SetSize(aSize);
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VMoveView
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VMoveView (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if(aContext.IsNull())
|
|
{
|
|
di << "use 'vinit' command before " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
if(argc < 4 || argc > 5)
|
|
{
|
|
di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
|
|
return 1;
|
|
}
|
|
Standard_Real Dx = Draw::Atof (argv[1]);
|
|
Standard_Real Dy = Draw::Atof (argv[2]);
|
|
Standard_Real Dz = Draw::Atof (argv[3]);
|
|
Standard_Boolean aStart = Standard_True;
|
|
if (argc == 5)
|
|
{
|
|
aStart = (Draw::Atoi (argv[4]) > 0);
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
aView->Move(Dx,Dy,Dz,aStart);
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VTranslateView
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VTranslateView (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if(aContext.IsNull())
|
|
{
|
|
di << "use 'vinit' command before " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
if(argc < 4 || argc > 5)
|
|
{
|
|
di<<"Usage : " << argv[0] << " Dx Dy Dz [Start = 1|0]\n";
|
|
return 1;
|
|
}
|
|
Standard_Real Dx = Draw::Atof (argv[1]);
|
|
Standard_Real Dy = Draw::Atof (argv[2]);
|
|
Standard_Real Dz = Draw::Atof (argv[3]);
|
|
Standard_Boolean aStart = Standard_True;
|
|
if (argc == 5)
|
|
{
|
|
aStart = (Draw::Atoi (argv[4]) > 0);
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
aView->Translate(Dx,Dy,Dz,aStart);
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VTurnView
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VTurnView (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if(aContext.IsNull()) {
|
|
di << "use 'vinit' command before " << argv[0] << "\n";
|
|
return 1;
|
|
}
|
|
if(argc < 4 || argc > 5){
|
|
di<<"Usage : " << argv[0] << " Ax Ay Az [Start = 1|0]\n";
|
|
return 1;
|
|
}
|
|
Standard_Real Ax = Draw::Atof (argv[1]);
|
|
Standard_Real Ay = Draw::Atof (argv[2]);
|
|
Standard_Real Az = Draw::Atof (argv[3]);
|
|
Standard_Boolean aStart = Standard_True;
|
|
if (argc == 5)
|
|
{
|
|
aStart = (Draw::Atoi (argv[4]) > 0);
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
aView->Turn(Ax,Ay,Az,aStart);
|
|
return 0;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VTextureEnv
|
|
//purpose : ENables or disables environment mapping
|
|
//==============================================================================
|
|
class OCC_TextureEnv : public Graphic3d_TextureEnv
|
|
{
|
|
public:
|
|
OCC_TextureEnv(const Standard_CString FileName);
|
|
OCC_TextureEnv(const Graphic3d_NameOfTextureEnv aName);
|
|
void SetTextureParameters(const Standard_Boolean theRepeatFlag,
|
|
const Standard_Boolean theModulateFlag,
|
|
const Graphic3d_TypeOfTextureFilter theFilter,
|
|
const Standard_ShortReal theXScale,
|
|
const Standard_ShortReal theYScale,
|
|
const Standard_ShortReal theXShift,
|
|
const Standard_ShortReal theYShift,
|
|
const Standard_ShortReal theAngle);
|
|
DEFINE_STANDARD_RTTI_INLINE(OCC_TextureEnv,Graphic3d_TextureEnv)
|
|
};
|
|
DEFINE_STANDARD_HANDLE(OCC_TextureEnv, Graphic3d_TextureEnv)
|
|
|
|
OCC_TextureEnv::OCC_TextureEnv(const Standard_CString theFileName)
|
|
: Graphic3d_TextureEnv(theFileName)
|
|
{
|
|
}
|
|
|
|
OCC_TextureEnv::OCC_TextureEnv(const Graphic3d_NameOfTextureEnv theTexId)
|
|
: Graphic3d_TextureEnv(theTexId)
|
|
{
|
|
}
|
|
|
|
void OCC_TextureEnv::SetTextureParameters(const Standard_Boolean theRepeatFlag,
|
|
const Standard_Boolean theModulateFlag,
|
|
const Graphic3d_TypeOfTextureFilter theFilter,
|
|
const Standard_ShortReal theXScale,
|
|
const Standard_ShortReal theYScale,
|
|
const Standard_ShortReal theXShift,
|
|
const Standard_ShortReal theYShift,
|
|
const Standard_ShortReal theAngle)
|
|
{
|
|
myParams->SetRepeat (theRepeatFlag);
|
|
myParams->SetModulate (theModulateFlag);
|
|
myParams->SetFilter (theFilter);
|
|
myParams->SetScale (Graphic3d_Vec2(theXScale, theYScale));
|
|
myParams->SetTranslation(Graphic3d_Vec2(theXShift, theYShift));
|
|
myParams->SetRotation (theAngle);
|
|
}
|
|
|
|
static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, const char** theArgVec)
|
|
{
|
|
// get the active view
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
// Checking the input arguments
|
|
Standard_Boolean anEnableFlag = Standard_False;
|
|
Standard_Boolean isOk = theArgNb >= 2;
|
|
if (isOk)
|
|
{
|
|
TCollection_AsciiString anEnableOpt(theArgVec[1]);
|
|
anEnableFlag = anEnableOpt.IsEqual("on");
|
|
isOk = anEnableFlag || anEnableOpt.IsEqual("off");
|
|
}
|
|
if (anEnableFlag)
|
|
{
|
|
isOk = (theArgNb == 3 || theArgNb == 11);
|
|
if (isOk)
|
|
{
|
|
TCollection_AsciiString aTextureOpt(theArgVec[2]);
|
|
isOk = (!aTextureOpt.IsIntegerValue() ||
|
|
(aTextureOpt.IntegerValue() >= 0 && aTextureOpt.IntegerValue() < Graphic3d_NOT_ENV_UNKNOWN));
|
|
|
|
if (isOk && theArgNb == 11)
|
|
{
|
|
TCollection_AsciiString aRepeatOpt (theArgVec[3]),
|
|
aModulateOpt(theArgVec[4]),
|
|
aFilterOpt (theArgVec[5]),
|
|
aSScaleOpt (theArgVec[6]),
|
|
aTScaleOpt (theArgVec[7]),
|
|
aSTransOpt (theArgVec[8]),
|
|
aTTransOpt (theArgVec[9]),
|
|
anAngleOpt (theArgVec[10]);
|
|
isOk = ((aRepeatOpt. IsEqual("repeat") || aRepeatOpt. IsEqual("clamp")) &&
|
|
(aModulateOpt.IsEqual("modulate") || aModulateOpt.IsEqual("decal")) &&
|
|
(aFilterOpt. IsEqual("nearest") || aFilterOpt. IsEqual("bilinear") || aFilterOpt.IsEqual("trilinear")) &&
|
|
aSScaleOpt.IsRealValue (Standard_True) && aTScaleOpt.IsRealValue (Standard_True) &&
|
|
aSTransOpt.IsRealValue (Standard_True) && aTTransOpt.IsRealValue (Standard_True) &&
|
|
anAngleOpt.IsRealValue (Standard_True));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!isOk)
|
|
{
|
|
Message::SendFail() << "Usage:\n"
|
|
<< theArgVec[0] << " off\n"
|
|
<< 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]";
|
|
return 1;
|
|
}
|
|
|
|
if (anEnableFlag)
|
|
{
|
|
TCollection_AsciiString aTextureOpt(theArgVec[2]);
|
|
Handle(OCC_TextureEnv) aTexEnv = aTextureOpt.IsIntegerValue() ?
|
|
new OCC_TextureEnv((Graphic3d_NameOfTextureEnv)aTextureOpt.IntegerValue()) :
|
|
new OCC_TextureEnv(theArgVec[2]);
|
|
|
|
if (theArgNb == 11)
|
|
{
|
|
TCollection_AsciiString aRepeatOpt(theArgVec[3]), aModulateOpt(theArgVec[4]), aFilterOpt(theArgVec[5]);
|
|
aTexEnv->SetTextureParameters(
|
|
aRepeatOpt. IsEqual("repeat"),
|
|
aModulateOpt.IsEqual("modulate"),
|
|
aFilterOpt. IsEqual("nearest") ? Graphic3d_TOTF_NEAREST :
|
|
aFilterOpt.IsEqual("bilinear") ? Graphic3d_TOTF_BILINEAR :
|
|
Graphic3d_TOTF_TRILINEAR,
|
|
(Standard_ShortReal)Draw::Atof(theArgVec[6]),
|
|
(Standard_ShortReal)Draw::Atof(theArgVec[7]),
|
|
(Standard_ShortReal)Draw::Atof(theArgVec[8]),
|
|
(Standard_ShortReal)Draw::Atof(theArgVec[9]),
|
|
(Standard_ShortReal)Draw::Atof(theArgVec[10])
|
|
);
|
|
}
|
|
aView->SetTextureEnv(aTexEnv);
|
|
}
|
|
else // Disabling environment mapping
|
|
{
|
|
Handle(Graphic3d_TextureEnv) aTexture;
|
|
aView->SetTextureEnv(aTexture); // Passing null handle to clear the texture data
|
|
}
|
|
|
|
aView->Redraw();
|
|
return 0;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
typedef NCollection_DataMap<TCollection_AsciiString, Handle(Graphic3d_ClipPlane)> MapOfPlanes;
|
|
|
|
//! Remove registered clipping plane from all views and objects.
|
|
static void removePlane (MapOfPlanes& theRegPlanes,
|
|
const TCollection_AsciiString& theName)
|
|
{
|
|
Handle(Graphic3d_ClipPlane) aClipPlane;
|
|
if (!theRegPlanes.Find (theName, aClipPlane))
|
|
{
|
|
Message::SendWarning ("Warning: no such plane");
|
|
return;
|
|
}
|
|
|
|
theRegPlanes.UnBind (theName);
|
|
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS());
|
|
anIObjIt.More(); anIObjIt.Next())
|
|
{
|
|
const Handle(AIS_InteractiveObject)& aPrs = anIObjIt.Key1();
|
|
aPrs->RemoveClipPlane (aClipPlane);
|
|
}
|
|
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator aViewIt(ViewerTest_myViews);
|
|
aViewIt.More(); aViewIt.Next())
|
|
{
|
|
const Handle(V3d_View)& aView = aViewIt.Key2();
|
|
aView->RemoveClipPlane(aClipPlane);
|
|
}
|
|
|
|
ViewerTest::RedrawAllViews();
|
|
}
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VClipPlane
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
// use short-cut for created clip planes map of created (or "registered by name") clip planes
|
|
static MapOfPlanes aRegPlanes;
|
|
|
|
if (theArgsNb < 2)
|
|
{
|
|
for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More(); aPlaneIter.Next())
|
|
{
|
|
theDi << aPlaneIter.Key() << " ";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TCollection_AsciiString aCommand (theArgVec[1]);
|
|
aCommand.LowerCase();
|
|
const Handle(V3d_View)& anActiveView = ViewerTest::CurrentView();
|
|
if (anActiveView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
// print maximum number of planes for current viewer
|
|
if (aCommand == "-maxplanes"
|
|
|| aCommand == "maxplanes")
|
|
{
|
|
theDi << anActiveView->Viewer()->Driver()->InquirePlaneLimit()
|
|
<< " plane slots provided by driver.\n";
|
|
return 0;
|
|
}
|
|
|
|
// create / delete plane instance
|
|
if (aCommand == "-create"
|
|
|| aCommand == "create"
|
|
|| aCommand == "-delete"
|
|
|| aCommand == "delete"
|
|
|| aCommand == "-clone"
|
|
|| aCommand == "clone")
|
|
{
|
|
if (theArgsNb < 3)
|
|
{
|
|
Message::SendFail ("Syntax error: plane name is required");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean toCreate = aCommand == "-create"
|
|
|| aCommand == "create";
|
|
Standard_Boolean toClone = aCommand == "-clone"
|
|
|| aCommand == "clone";
|
|
Standard_Boolean toDelete = aCommand == "-delete"
|
|
|| aCommand == "delete";
|
|
TCollection_AsciiString aPlane (theArgVec[2]);
|
|
|
|
if (toCreate)
|
|
{
|
|
if (aRegPlanes.IsBound (aPlane))
|
|
{
|
|
std::cout << "Warning: existing plane has been overridden.\n";
|
|
toDelete = true;
|
|
}
|
|
else
|
|
{
|
|
aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
|
|
return 0;
|
|
}
|
|
}
|
|
else if (toClone) // toClone
|
|
{
|
|
if (!aRegPlanes.IsBound (aPlane))
|
|
{
|
|
Message::SendFail ("Error: no such plane");
|
|
return 1;
|
|
}
|
|
else if (theArgsNb < 4)
|
|
{
|
|
Message::SendFail ("Syntax error: enter name for new plane");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aClone (theArgVec[3]);
|
|
if (aRegPlanes.IsBound (aClone))
|
|
{
|
|
Message::SendFail ("Error: plane name is in use");
|
|
return 1;
|
|
}
|
|
|
|
const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane);
|
|
|
|
aRegPlanes.Bind (aClone, aClipPlane->Clone());
|
|
return 0;
|
|
}
|
|
|
|
if (toDelete)
|
|
{
|
|
if (aPlane == "ALL"
|
|
|| aPlane == "all"
|
|
|| aPlane == "*")
|
|
{
|
|
for (MapOfPlanes::Iterator aPlaneIter (aRegPlanes); aPlaneIter.More();)
|
|
{
|
|
aPlane = aPlaneIter.Key();
|
|
removePlane (aRegPlanes, aPlane);
|
|
aPlaneIter = MapOfPlanes::Iterator (aRegPlanes);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
removePlane (aRegPlanes, aPlane);
|
|
}
|
|
}
|
|
|
|
if (toCreate)
|
|
{
|
|
aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// set / unset plane command
|
|
if (aCommand == "set"
|
|
|| aCommand == "unset")
|
|
{
|
|
if (theArgsNb < 5)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
// redirect to new syntax
|
|
NCollection_Array1<const char*> anArgVec (1, theArgsNb - 1);
|
|
anArgVec.SetValue (1, theArgVec[0]);
|
|
anArgVec.SetValue (2, theArgVec[2]);
|
|
anArgVec.SetValue (3, aCommand == "set" ? "-set" : "-unset");
|
|
for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt)
|
|
{
|
|
anArgVec.SetValue (anIt, theArgVec[anIt]);
|
|
}
|
|
|
|
return VClipPlane (theDi, anArgVec.Length(), &anArgVec.ChangeFirst());
|
|
}
|
|
|
|
// change plane command
|
|
TCollection_AsciiString aPlaneName;
|
|
Handle(Graphic3d_ClipPlane) aClipPlane;
|
|
Standard_Integer anArgIter = 0;
|
|
if (aCommand == "-change"
|
|
|| aCommand == "change")
|
|
{
|
|
// old syntax support
|
|
if (theArgsNb < 3)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
anArgIter = 3;
|
|
aPlaneName = theArgVec[2];
|
|
if (!aRegPlanes.Find (aPlaneName, aClipPlane))
|
|
{
|
|
Message::SendFail() << "Error: no such plane '" << aPlaneName << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aRegPlanes.Find (theArgVec[1], aClipPlane))
|
|
{
|
|
anArgIter = 2;
|
|
aPlaneName = theArgVec[1];
|
|
}
|
|
else
|
|
{
|
|
anArgIter = 2;
|
|
aPlaneName = theArgVec[1];
|
|
aClipPlane = new Graphic3d_ClipPlane();
|
|
aRegPlanes.Bind (aPlaneName, aClipPlane);
|
|
theDi << "Created new plane " << aPlaneName << ".\n";
|
|
}
|
|
|
|
if (theArgsNb - anArgIter < 1)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
for (; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
const char** aChangeArgs = theArgVec + anArgIter;
|
|
Standard_Integer aNbChangeArgs = theArgsNb - anArgIter;
|
|
TCollection_AsciiString aChangeArg (aChangeArgs[0]);
|
|
aChangeArg.LowerCase();
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (Draw::ParseOnOff (aChangeArgs[0], toEnable))
|
|
{
|
|
aClipPlane->SetOn (toEnable);
|
|
}
|
|
else if (aChangeArg.StartsWith ("-equation")
|
|
|| aChangeArg.StartsWith ("equation"))
|
|
{
|
|
if (aNbChangeArgs < 5)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer aSubIndex = 1;
|
|
Standard_Integer aPrefixLen = 8 + (aChangeArg.Value (1) == '-' ? 1 : 0);
|
|
if (aPrefixLen < aChangeArg.Length())
|
|
{
|
|
TCollection_AsciiString aSubStr = aChangeArg.SubString (aPrefixLen + 1, aChangeArg.Length());
|
|
if (!aSubStr.IsIntegerValue()
|
|
|| aSubStr.IntegerValue() <= 0)
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
|
|
return 1;
|
|
}
|
|
aSubIndex = aSubStr.IntegerValue();
|
|
}
|
|
|
|
Standard_Real aCoeffA = Draw::Atof (aChangeArgs[1]);
|
|
Standard_Real aCoeffB = Draw::Atof (aChangeArgs[2]);
|
|
Standard_Real aCoeffC = Draw::Atof (aChangeArgs[3]);
|
|
Standard_Real aCoeffD = Draw::Atof (aChangeArgs[4]);
|
|
Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
|
|
for (Standard_Integer aSubPlaneIter = 1; aSubPlaneIter < aSubIndex; ++aSubPlaneIter)
|
|
{
|
|
if (aSubPln->ChainNextPlane().IsNull())
|
|
{
|
|
aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
|
|
}
|
|
aSubPln = aSubPln->ChainNextPlane();
|
|
}
|
|
aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
|
|
aSubPln->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
|
|
anArgIter += 4;
|
|
}
|
|
else if ((aChangeArg == "-boxinterior"
|
|
|| aChangeArg == "-boxint"
|
|
|| aChangeArg == "-box")
|
|
&& aNbChangeArgs >= 7)
|
|
{
|
|
Graphic3d_BndBox3d aBndBox;
|
|
aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[1]), Draw::Atof (aChangeArgs[2]), Draw::Atof (aChangeArgs[3])));
|
|
aBndBox.Add (Graphic3d_Vec3d (Draw::Atof (aChangeArgs[4]), Draw::Atof (aChangeArgs[5]), Draw::Atof (aChangeArgs[6])));
|
|
anArgIter += 6;
|
|
|
|
Standard_Integer aNbSubPlanes = 6;
|
|
const Graphic3d_Vec3d aDirArray[6] =
|
|
{
|
|
Graphic3d_Vec3d (-1, 0, 0),
|
|
Graphic3d_Vec3d ( 1, 0, 0),
|
|
Graphic3d_Vec3d ( 0,-1, 0),
|
|
Graphic3d_Vec3d ( 0, 1, 0),
|
|
Graphic3d_Vec3d ( 0, 0,-1),
|
|
Graphic3d_Vec3d ( 0, 0, 1),
|
|
};
|
|
Handle(Graphic3d_ClipPlane) aSubPln = aClipPlane;
|
|
for (Standard_Integer aSubPlaneIter = 0; aSubPlaneIter < aNbSubPlanes; ++aSubPlaneIter)
|
|
{
|
|
const Graphic3d_Vec3d& aDir = aDirArray[aSubPlaneIter];
|
|
const Standard_Real aW = -aDir.Dot ((aSubPlaneIter % 2 == 1) ? aBndBox.CornerMax() : aBndBox.CornerMin());
|
|
aSubPln->SetEquation (gp_Pln (aDir.x(), aDir.y(), aDir.z(), aW));
|
|
if (aSubPlaneIter + 1 == aNbSubPlanes)
|
|
{
|
|
aSubPln->SetChainNextPlane (Handle(Graphic3d_ClipPlane)());
|
|
}
|
|
else
|
|
{
|
|
aSubPln->SetChainNextPlane (new Graphic3d_ClipPlane (*aSubPln));
|
|
}
|
|
aSubPln = aSubPln->ChainNextPlane();
|
|
}
|
|
}
|
|
else if (aChangeArg == "-capping"
|
|
|| aChangeArg == "capping")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
|
|
{
|
|
aClipPlane->SetCapping (toEnable);
|
|
anArgIter += 1;
|
|
}
|
|
else
|
|
{
|
|
// just skip otherwise (old syntax)
|
|
}
|
|
}
|
|
else if (aChangeArg == "-useobjectmaterial"
|
|
|| aChangeArg == "-useobjectmat"
|
|
|| aChangeArg == "-useobjmat"
|
|
|| aChangeArg == "-useobjmaterial")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
|
|
{
|
|
aClipPlane->SetUseObjectMaterial (toEnable == Standard_True);
|
|
anArgIter += 1;
|
|
}
|
|
}
|
|
else if (aChangeArg == "-useobjecttexture"
|
|
|| aChangeArg == "-useobjecttex"
|
|
|| aChangeArg == "-useobjtexture"
|
|
|| aChangeArg == "-useobjtex")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
|
|
{
|
|
aClipPlane->SetUseObjectTexture (toEnable == Standard_True);
|
|
anArgIter += 1;
|
|
}
|
|
}
|
|
else if (aChangeArg == "-useobjectshader"
|
|
|| aChangeArg == "-useobjshader")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (Draw::ParseOnOff (aChangeArgs[1], toEnable))
|
|
{
|
|
aClipPlane->SetUseObjectShader (toEnable == Standard_True);
|
|
anArgIter += 1;
|
|
}
|
|
}
|
|
else if (aChangeArg == "-color"
|
|
|| aChangeArg == "color")
|
|
{
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (aNbChangeArgs - 1,
|
|
aChangeArgs + 1,
|
|
aColor);
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
aClipPlane->SetCappingColor (aColor);
|
|
anArgIter += aNbParsed;
|
|
}
|
|
else if (aNbChangeArgs >= 1
|
|
&& (aChangeArg == "-material"
|
|
|| aChangeArg == "material"))
|
|
{
|
|
++anArgIter;
|
|
Graphic3d_NameOfMaterial aMatName;
|
|
if (!Graphic3d_MaterialAspect::MaterialFromName (aChangeArgs[1], aMatName))
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown material '" << aChangeArgs[1] << "'";
|
|
return 1;
|
|
}
|
|
aClipPlane->SetCappingMaterial (aMatName);
|
|
}
|
|
else if ((aChangeArg == "-transparency"
|
|
|| aChangeArg == "-transp")
|
|
&& aNbChangeArgs >= 2)
|
|
{
|
|
TCollection_AsciiString aValStr (aChangeArgs[1]);
|
|
Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
|
|
if (aValStr.IsRealValue (Standard_True))
|
|
{
|
|
Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
|
|
aMat.SetTransparency ((float )aValStr.RealValue());
|
|
anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
|
|
aClipPlane->SetCappingMaterial (aMat);
|
|
}
|
|
else
|
|
{
|
|
aValStr.LowerCase();
|
|
Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
|
|
if (aValStr == "opaque")
|
|
{
|
|
aMode = Graphic3d_AlphaMode_Opaque;
|
|
}
|
|
else if (aValStr == "mask")
|
|
{
|
|
aMode = Graphic3d_AlphaMode_Mask;
|
|
}
|
|
else if (aValStr == "blend")
|
|
{
|
|
aMode = Graphic3d_AlphaMode_Blend;
|
|
}
|
|
else if (aValStr == "maskblend"
|
|
|| aValStr == "blendmask")
|
|
{
|
|
aMode = Graphic3d_AlphaMode_MaskBlend;
|
|
}
|
|
else if (aValStr == "blendauto")
|
|
{
|
|
aMode = Graphic3d_AlphaMode_BlendAuto;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << aValStr << "'";
|
|
return 1;
|
|
}
|
|
anAspect->SetAlphaMode (aMode);
|
|
aClipPlane->SetCappingAspect (anAspect);
|
|
}
|
|
anArgIter += 1;
|
|
}
|
|
else if (aChangeArg == "-texname"
|
|
|| aChangeArg == "texname")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aTextureName (aChangeArgs[1]);
|
|
Handle(Graphic3d_Texture2D) aTexture = new Graphic3d_Texture2D (aTextureName);
|
|
if (!aTexture->IsDone())
|
|
{
|
|
aClipPlane->SetCappingTexture (NULL);
|
|
}
|
|
else
|
|
{
|
|
aTexture->EnableModulate();
|
|
aTexture->EnableRepeat();
|
|
aClipPlane->SetCappingTexture (aTexture);
|
|
}
|
|
anArgIter += 1;
|
|
}
|
|
else if (aChangeArg == "-texscale"
|
|
|| aChangeArg == "texscale")
|
|
{
|
|
if (aClipPlane->CappingTexture().IsNull())
|
|
{
|
|
Message::SendFail ("Error: no texture is set");
|
|
return 1;
|
|
}
|
|
|
|
if (aNbChangeArgs < 3)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
Standard_ShortReal aSx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
|
|
Standard_ShortReal aSy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
|
|
aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy));
|
|
anArgIter += 2;
|
|
}
|
|
else if (aChangeArg == "-texorigin"
|
|
|| aChangeArg == "texorigin") // texture origin
|
|
{
|
|
if (aClipPlane->CappingTexture().IsNull())
|
|
{
|
|
Message::SendFail ("Error: no texture is set");
|
|
return 1;
|
|
}
|
|
|
|
if (aNbChangeArgs < 3)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
Standard_ShortReal aTx = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
|
|
Standard_ShortReal aTy = (Standard_ShortReal)Draw::Atof (aChangeArgs[2]);
|
|
|
|
aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy));
|
|
anArgIter += 2;
|
|
}
|
|
else if (aChangeArg == "-texrotate"
|
|
|| aChangeArg == "texrotate") // texture rotation
|
|
{
|
|
if (aClipPlane->CappingTexture().IsNull())
|
|
{
|
|
Message::SendFail ("Error: no texture is set");
|
|
return 1;
|
|
}
|
|
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
Standard_ShortReal aRot = (Standard_ShortReal)Draw::Atof (aChangeArgs[1]);
|
|
aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot);
|
|
anArgIter += 1;
|
|
}
|
|
else if (aChangeArg == "-hatch"
|
|
|| aChangeArg == "hatch")
|
|
{
|
|
if (aNbChangeArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aHatchStr (aChangeArgs[1]);
|
|
aHatchStr.LowerCase();
|
|
if (aHatchStr == "on")
|
|
{
|
|
aClipPlane->SetCappingHatchOn();
|
|
}
|
|
else if (aHatchStr == "off")
|
|
{
|
|
aClipPlane->SetCappingHatchOff();
|
|
}
|
|
else
|
|
{
|
|
aClipPlane->SetCappingHatch ((Aspect_HatchStyle)Draw::Atoi (aChangeArgs[1]));
|
|
}
|
|
anArgIter += 1;
|
|
}
|
|
else if (aChangeArg == "-delete"
|
|
|| aChangeArg == "delete")
|
|
{
|
|
removePlane (aRegPlanes, aPlaneName);
|
|
return 0;
|
|
}
|
|
else if (aChangeArg == "-set"
|
|
|| aChangeArg == "-unset"
|
|
|| aChangeArg == "-setoverrideglobal")
|
|
{
|
|
// set / unset plane command
|
|
const Standard_Boolean toSet = aChangeArg.StartsWith ("-set");
|
|
const Standard_Boolean toOverrideGlobal = aChangeArg == "-setoverrideglobal";
|
|
Standard_Integer anIt = 1;
|
|
for (; anIt < aNbChangeArgs; ++anIt)
|
|
{
|
|
TCollection_AsciiString anEntityName (aChangeArgs[anIt]);
|
|
if (anEntityName.IsEmpty()
|
|
|| anEntityName.Value (1) == '-')
|
|
{
|
|
break;
|
|
}
|
|
else if (!toOverrideGlobal
|
|
&& ViewerTest_myViews.IsBound1 (anEntityName))
|
|
{
|
|
const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (anEntityName);
|
|
if (toSet)
|
|
{
|
|
aView->AddClipPlane (aClipPlane);
|
|
}
|
|
else
|
|
{
|
|
aView->RemoveClipPlane (aClipPlane);
|
|
}
|
|
continue;
|
|
}
|
|
else if (GetMapOfAIS().IsBound2 (anEntityName))
|
|
{
|
|
Handle(AIS_InteractiveObject) aIObj = GetMapOfAIS().Find2 (anEntityName);
|
|
if (toSet)
|
|
{
|
|
aIObj->AddClipPlane (aClipPlane);
|
|
}
|
|
else
|
|
{
|
|
aIObj->RemoveClipPlane (aClipPlane);
|
|
}
|
|
if (!aIObj->ClipPlanes().IsNull())
|
|
{
|
|
aIObj->ClipPlanes()->SetOverrideGlobal (toOverrideGlobal);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: object/view '" << anEntityName << "' is not found";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (anIt == 1)
|
|
{
|
|
// apply to active view
|
|
if (toSet)
|
|
{
|
|
anActiveView->AddClipPlane (aClipPlane);
|
|
}
|
|
else
|
|
{
|
|
anActiveView->RemoveClipPlane (aClipPlane);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
anArgIter = anArgIter + anIt - 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << aChangeArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
ViewerTest::RedrawAllViews();
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VZRange
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VZRange (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
|
|
|
|
if (aCurrentView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Handle(Graphic3d_Camera) aCamera = aCurrentView->Camera();
|
|
|
|
if (theArgsNb < 2)
|
|
{
|
|
theDi << "ZNear: " << aCamera->ZNear() << "\n";
|
|
theDi << "ZFar: " << aCamera->ZFar() << "\n";
|
|
return 0;
|
|
}
|
|
|
|
if (theArgsNb == 3)
|
|
{
|
|
Standard_Real aNewZNear = Draw::Atof (theArgVec[1]);
|
|
Standard_Real aNewZFar = Draw::Atof (theArgVec[2]);
|
|
|
|
if (aNewZNear >= aNewZFar)
|
|
{
|
|
Message::SendFail ("Syntax error: invalid arguments: znear should be less than zfar");
|
|
return 1;
|
|
}
|
|
|
|
if (!aCamera->IsOrthographic() && (aNewZNear <= 0.0 || aNewZFar <= 0.0))
|
|
{
|
|
Message::SendFail ("Syntax error: invalid arguments: znear, zfar should be positive for perspective camera");
|
|
return 1;
|
|
}
|
|
|
|
aCamera->SetZRange (aNewZNear, aNewZFar);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail ("Syntax error: wrong command arguments");
|
|
return 1;
|
|
}
|
|
|
|
aCurrentView->Redraw();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VAutoZFit
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VAutoZFit (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec)
|
|
{
|
|
const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
|
|
|
|
if (aCurrentView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Real aScale = aCurrentView->AutoZFitScaleFactor();
|
|
|
|
if (theArgsNb > 3)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong command arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgsNb < 2)
|
|
{
|
|
theDi << "Auto z-fit mode: \n"
|
|
<< "On: " << (aCurrentView->AutoZFitMode() ? "enabled" : "disabled") << "\n"
|
|
<< "Scale: " << aScale << "\n";
|
|
return 0;
|
|
}
|
|
|
|
Standard_Boolean isOn = Draw::Atoi (theArgVec[1]) == 1;
|
|
|
|
if (theArgsNb >= 3)
|
|
{
|
|
aScale = Draw::Atoi (theArgVec[2]);
|
|
}
|
|
|
|
aCurrentView->SetAutoZFitMode (isOn, aScale);
|
|
aCurrentView->Redraw();
|
|
return 0;
|
|
}
|
|
|
|
//! Auxiliary function to print projection type
|
|
inline const char* projTypeName (Graphic3d_Camera::Projection theProjType)
|
|
{
|
|
switch (theProjType)
|
|
{
|
|
case Graphic3d_Camera::Projection_Orthographic: return "orthographic";
|
|
case Graphic3d_Camera::Projection_Perspective: return "perspective";
|
|
case Graphic3d_Camera::Projection_Stereo: return "stereoscopic";
|
|
case Graphic3d_Camera::Projection_MonoLeftEye: return "monoLeftEye";
|
|
case Graphic3d_Camera::Projection_MonoRightEye: return "monoRightEye";
|
|
}
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VCamera
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VCamera (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Handle(Graphic3d_Camera) aCamera = aView->Camera();
|
|
if (theArgsNb < 2)
|
|
{
|
|
theDI << "ProjType: " << projTypeName (aCamera->ProjectionType()) << "\n";
|
|
theDI << "FOVy: " << aCamera->FOVy() << "\n";
|
|
theDI << "FOVx: " << aCamera->FOVx() << "\n";
|
|
theDI << "FOV2d: " << aCamera->FOV2d() << "\n";
|
|
theDI << "Distance: " << aCamera->Distance() << "\n";
|
|
theDI << "IOD: " << aCamera->IOD() << "\n";
|
|
theDI << "IODType: " << (aCamera->GetIODType() == Graphic3d_Camera::IODType_Absolute ? "absolute" : "relative") << "\n";
|
|
theDI << "ZFocus: " << aCamera->ZFocus() << "\n";
|
|
theDI << "ZFocusType: " << (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Absolute ? "absolute" : "relative") << "\n";
|
|
theDI << "ZNear: " << aCamera->ZNear() << "\n";
|
|
theDI << "ZFar: " << aCamera->ZFar() << "\n";
|
|
return 0;
|
|
}
|
|
|
|
TCollection_AsciiString aPrsName;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg = theArgVec[anArgIter];
|
|
TCollection_AsciiString anArgCase (anArg);
|
|
anArgCase.LowerCase();
|
|
if (anArgCase == "-proj"
|
|
|| anArgCase == "-projection"
|
|
|| anArgCase == "-projtype"
|
|
|| anArgCase == "-projectiontype")
|
|
{
|
|
theDI << projTypeName (aCamera->ProjectionType()) << " ";
|
|
}
|
|
else if (anArgCase == "-ortho"
|
|
|| anArgCase == "-orthographic")
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
|
|
}
|
|
else if (anArgCase == "-persp"
|
|
|| anArgCase == "-perspective"
|
|
|| anArgCase == "-perspmono"
|
|
|| anArgCase == "-perspectivemono"
|
|
|| anArgCase == "-mono")
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
|
|
}
|
|
else if (anArgCase == "-stereo"
|
|
|| anArgCase == "-stereoscopic"
|
|
|| anArgCase == "-perspstereo"
|
|
|| anArgCase == "-perspectivestereo")
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
|
|
}
|
|
else if (anArgCase == "-left"
|
|
|| anArgCase == "-lefteye"
|
|
|| anArgCase == "-monoleft"
|
|
|| anArgCase == "-monolefteye"
|
|
|| anArgCase == "-perpsleft"
|
|
|| anArgCase == "-perpslefteye")
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
|
|
}
|
|
else if (anArgCase == "-right"
|
|
|| anArgCase == "-righteye"
|
|
|| anArgCase == "-monoright"
|
|
|| anArgCase == "-monorighteye"
|
|
|| anArgCase == "-perpsright")
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
|
|
}
|
|
else if (anArgCase == "-dist"
|
|
|| anArgCase == "-distance")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
|
|
if (anArgValue != NULL
|
|
&& *anArgValue != '-')
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetDistance (Draw::Atof (anArgValue));
|
|
continue;
|
|
}
|
|
theDI << aCamera->Distance() << " ";
|
|
}
|
|
else if (anArgCase == "-iod")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
|
|
if (anArgValue != NULL
|
|
&& *anArgValue != '-')
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetIOD (aCamera->GetIODType(), Draw::Atof (anArgValue));
|
|
continue;
|
|
}
|
|
theDI << aCamera->IOD() << " ";
|
|
}
|
|
else if (anArgCase == "-iodtype")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
|
|
TCollection_AsciiString anValueCase (anArgValue);
|
|
anValueCase.LowerCase();
|
|
if (anValueCase == "abs"
|
|
|| anValueCase == "absolute")
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetIOD (Graphic3d_Camera::IODType_Absolute, aCamera->IOD());
|
|
continue;
|
|
}
|
|
else if (anValueCase == "rel"
|
|
|| anValueCase == "relative")
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, aCamera->IOD());
|
|
continue;
|
|
}
|
|
else if (*anArgValue != '-')
|
|
{
|
|
Message::SendFail() << "Error: unknown IOD type '" << anArgValue << "'";
|
|
return 1;
|
|
}
|
|
switch (aCamera->GetIODType())
|
|
{
|
|
case Graphic3d_Camera::IODType_Absolute: theDI << "absolute "; break;
|
|
case Graphic3d_Camera::IODType_Relative: theDI << "relative "; break;
|
|
}
|
|
}
|
|
else if (anArgCase == "-zfocus")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
|
|
if (anArgValue != NULL
|
|
&& *anArgValue != '-')
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetZFocus (aCamera->ZFocusType(), Draw::Atof (anArgValue));
|
|
continue;
|
|
}
|
|
theDI << aCamera->ZFocus() << " ";
|
|
}
|
|
else if (anArgCase == "-zfocustype")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "";
|
|
TCollection_AsciiString anValueCase (anArgValue);
|
|
anValueCase.LowerCase();
|
|
if (anValueCase == "abs"
|
|
|| anValueCase == "absolute")
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetZFocus (Graphic3d_Camera::FocusType_Absolute, aCamera->ZFocus());
|
|
continue;
|
|
}
|
|
else if (anValueCase == "rel"
|
|
|| anValueCase == "relative")
|
|
{
|
|
++anArgIter;
|
|
aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, aCamera->ZFocus());
|
|
continue;
|
|
}
|
|
else if (*anArgValue != '-')
|
|
{
|
|
Message::SendFail() << "Error: unknown ZFocus type '" << anArgValue << "'";
|
|
return 1;
|
|
}
|
|
switch (aCamera->ZFocusType())
|
|
{
|
|
case Graphic3d_Camera::FocusType_Absolute: theDI << "absolute "; break;
|
|
case Graphic3d_Camera::FocusType_Relative: theDI << "relative "; break;
|
|
}
|
|
}
|
|
else if (anArgCase == "-lockzup"
|
|
|| anArgCase == "-turntable")
|
|
{
|
|
bool toLockUp = true;
|
|
if (++anArgIter < theArgsNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toLockUp))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
ViewerTest::CurrentEventManager()->SetLockOrbitZUp (toLockUp);
|
|
}
|
|
else if (anArgCase == "-rotationmode"
|
|
|| anArgCase == "-rotmode")
|
|
{
|
|
AIS_RotationMode aRotMode = AIS_RotationMode_BndBoxActive;
|
|
TCollection_AsciiString aRotStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
|
|
aRotStr.LowerCase();
|
|
if (aRotStr == "bndboxactive"
|
|
|| aRotStr == "active")
|
|
{
|
|
aRotMode = AIS_RotationMode_BndBoxActive;
|
|
}
|
|
else if (aRotStr == "picklast"
|
|
|| aRotStr == "pick")
|
|
{
|
|
aRotMode = AIS_RotationMode_PickLast;
|
|
}
|
|
else if (aRotStr == "pickcenter")
|
|
{
|
|
aRotMode = AIS_RotationMode_PickCenter;
|
|
}
|
|
else if (aRotStr == "cameraat"
|
|
|| aRotStr == "cameracenter")
|
|
{
|
|
aRotMode = AIS_RotationMode_CameraAt;
|
|
}
|
|
else if (aRotStr == "bndboxscene"
|
|
|| aRotStr == "boxscene")
|
|
{
|
|
aRotMode = AIS_RotationMode_BndBoxScene;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest::CurrentEventManager()->SetRotationMode (aRotMode);
|
|
++anArgIter;
|
|
}
|
|
else if (anArgCase == "-navigationmode"
|
|
|| anArgCase == "-navmode")
|
|
{
|
|
AIS_NavigationMode aNavMode = AIS_NavigationMode_Orbit;
|
|
TCollection_AsciiString aNavStr ((anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : "");
|
|
aNavStr.LowerCase();
|
|
if (aNavStr == "orbit")
|
|
{
|
|
aNavMode = AIS_NavigationMode_Orbit;
|
|
}
|
|
else if (aNavStr == "flight"
|
|
|| aNavStr == "fly"
|
|
|| aNavStr == "copter"
|
|
|| aNavStr == "helicopter")
|
|
{
|
|
aNavMode = AIS_NavigationMode_FirstPersonFlight;
|
|
}
|
|
else if (aNavStr == "walk"
|
|
|| aNavStr == "shooter")
|
|
{
|
|
aNavMode = AIS_NavigationMode_FirstPersonWalk;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
|
|
aViewMgr->SetNavigationMode (aNavMode);
|
|
if (aNavMode == AIS_NavigationMode_Orbit)
|
|
{
|
|
aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateOrbit);
|
|
}
|
|
else
|
|
{
|
|
aViewMgr->ChangeMouseGestureMap().Bind (Aspect_VKeyMouse_LeftButton, AIS_MouseGesture_RotateView);
|
|
}
|
|
++anArgIter;
|
|
}
|
|
else if (anArgCase == "-fov"
|
|
|| anArgCase == "-fovy"
|
|
|| anArgCase == "-fovx"
|
|
|| anArgCase == "-fov2d")
|
|
{
|
|
Standard_CString anArgValue = (anArgIter + 1 < theArgsNb) ? theArgVec[anArgIter + 1] : NULL;
|
|
if (anArgValue != NULL
|
|
&& *anArgValue != '-')
|
|
{
|
|
++anArgIter;
|
|
if (anArgCase == "-fov2d")
|
|
{
|
|
aCamera->SetFOV2d (Draw::Atof (anArgValue));
|
|
}
|
|
else if (anArgCase == "-fovx")
|
|
{
|
|
aCamera->SetFOVy (Draw::Atof (anArgValue) / aCamera->Aspect());///
|
|
}
|
|
else
|
|
{
|
|
aCamera->SetFOVy (Draw::Atof (anArgValue));
|
|
}
|
|
continue;
|
|
}
|
|
if (anArgCase == "-fov2d")
|
|
{
|
|
theDI << aCamera->FOV2d() << " ";
|
|
}
|
|
else if (anArgCase == "-fovx")
|
|
{
|
|
theDI << aCamera->FOVx() << " ";
|
|
}
|
|
else
|
|
{
|
|
theDI << aCamera->FOVy() << " ";
|
|
}
|
|
}
|
|
else if (anArgIter + 1 < theArgsNb
|
|
&& anArgCase == "-xrpose")
|
|
{
|
|
TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
|
|
anXRArg.LowerCase();
|
|
if (anXRArg == "base")
|
|
{
|
|
aCamera = aView->View()->BaseXRCamera();
|
|
}
|
|
else if (anXRArg == "head")
|
|
{
|
|
aCamera = aView->View()->PosedXRCamera();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
|
|
return 1;
|
|
}
|
|
if (aCamera.IsNull())
|
|
{
|
|
Message::SendFail() << "Error: undefined XR pose";
|
|
return 0;
|
|
}
|
|
if (aView->AutoZFitMode())
|
|
{
|
|
const Bnd_Box aMinMaxBox = aView->View()->MinMaxValues (false);
|
|
const Bnd_Box aGraphicBox = aView->View()->MinMaxValues (true);
|
|
aCamera->ZFitAll (aView->AutoZFitScaleFactor(), aMinMaxBox, aGraphicBox);
|
|
}
|
|
}
|
|
else if (aPrsName.IsEmpty()
|
|
&& !anArgCase.StartsWith ("-"))
|
|
{
|
|
aPrsName = anArg;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aPrsName.IsEmpty()
|
|
|| theArgsNb > 2)
|
|
{
|
|
aView->Redraw();
|
|
}
|
|
|
|
if (!aPrsName.IsEmpty())
|
|
{
|
|
Handle(AIS_CameraFrustum) aCameraFrustum;
|
|
if (GetMapOfAIS().IsBound2 (aPrsName))
|
|
{
|
|
// find existing object
|
|
aCameraFrustum = Handle(AIS_CameraFrustum)::DownCast (GetMapOfAIS().Find2 (theArgVec[1]));
|
|
if (aCameraFrustum.IsNull())
|
|
{
|
|
Message::SendFail() << "Error: object '" << aPrsName << "'is already defined and is not a camera frustum";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aCameraFrustum.IsNull())
|
|
{
|
|
aCameraFrustum = new AIS_CameraFrustum();
|
|
}
|
|
else
|
|
{
|
|
// not include displayed object of old camera frustum in the new one.
|
|
ViewerTest::GetAISContext()->Erase (aCameraFrustum, false);
|
|
aView->ZFitAll();
|
|
}
|
|
aCameraFrustum->SetCameraFrustum (aCamera);
|
|
|
|
ViewerTest::Display (aPrsName, aCameraFrustum);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//! Parse stereo output mode
|
|
inline Standard_Boolean parseStereoMode (Standard_CString theArg,
|
|
Graphic3d_StereoMode& theMode)
|
|
{
|
|
TCollection_AsciiString aFlag (theArg);
|
|
aFlag.LowerCase();
|
|
if (aFlag == "quadbuffer")
|
|
{
|
|
theMode = Graphic3d_StereoMode_QuadBuffer;
|
|
}
|
|
else if (aFlag == "anaglyph")
|
|
{
|
|
theMode = Graphic3d_StereoMode_Anaglyph;
|
|
}
|
|
else if (aFlag == "row"
|
|
|| aFlag == "rowinterlaced")
|
|
{
|
|
theMode = Graphic3d_StereoMode_RowInterlaced;
|
|
}
|
|
else if (aFlag == "col"
|
|
|| aFlag == "colinterlaced"
|
|
|| aFlag == "columninterlaced")
|
|
{
|
|
theMode = Graphic3d_StereoMode_ColumnInterlaced;
|
|
}
|
|
else if (aFlag == "chess"
|
|
|| aFlag == "chessboard")
|
|
{
|
|
theMode = Graphic3d_StereoMode_ChessBoard;
|
|
}
|
|
else if (aFlag == "sbs"
|
|
|| aFlag == "sidebyside")
|
|
{
|
|
theMode = Graphic3d_StereoMode_SideBySide;
|
|
}
|
|
else if (aFlag == "ou"
|
|
|| aFlag == "overunder")
|
|
{
|
|
theMode = Graphic3d_StereoMode_OverUnder;
|
|
}
|
|
else if (aFlag == "pageflip"
|
|
|| aFlag == "softpageflip")
|
|
{
|
|
theMode = Graphic3d_StereoMode_SoftPageFlip;
|
|
}
|
|
else if (aFlag == "openvr"
|
|
|| aFlag == "vr")
|
|
{
|
|
theMode = Graphic3d_StereoMode_OpenVR;
|
|
}
|
|
else
|
|
{
|
|
return Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//! Parse anaglyph filter
|
|
inline Standard_Boolean parseAnaglyphFilter (Standard_CString theArg,
|
|
Graphic3d_RenderingParams::Anaglyph& theFilter)
|
|
{
|
|
TCollection_AsciiString aFlag (theArg);
|
|
aFlag.LowerCase();
|
|
if (aFlag == "redcyansimple")
|
|
{
|
|
theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
|
|
}
|
|
else if (aFlag == "redcyan"
|
|
|| aFlag == "redcyanoptimized")
|
|
{
|
|
theFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized;
|
|
}
|
|
else if (aFlag == "yellowbluesimple")
|
|
{
|
|
theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple;
|
|
}
|
|
else if (aFlag == "yellowblue"
|
|
|| aFlag == "yellowblueoptimized")
|
|
{
|
|
theFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized;
|
|
}
|
|
else if (aFlag == "greenmagenta"
|
|
|| aFlag == "greenmagentasimple")
|
|
{
|
|
theFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple;
|
|
}
|
|
else
|
|
{
|
|
return Standard_False;
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//==============================================================================
|
|
//function : VStereo
|
|
//purpose :
|
|
//==============================================================================
|
|
|
|
static int VStereo (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 0;
|
|
}
|
|
|
|
Handle(Graphic3d_Camera) aCamera = aView->Camera();
|
|
Graphic3d_RenderingParams* aParams = &aView->ChangeRenderingParams();
|
|
if (theArgNb < 2)
|
|
{
|
|
Standard_Boolean isActive = aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo;
|
|
theDI << "Stereo " << (isActive ? "ON" : "OFF") << "\n";
|
|
if (isActive)
|
|
{
|
|
TCollection_AsciiString aMode;
|
|
switch (aView->RenderingParams().StereoMode)
|
|
{
|
|
case Graphic3d_StereoMode_QuadBuffer:
|
|
{
|
|
aMode = "quadBuffer";
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_RowInterlaced:
|
|
{
|
|
aMode = "rowInterlaced";
|
|
if (aView->RenderingParams().ToSmoothInterlacing)
|
|
{
|
|
aMode.AssignCat (" (smoothed)");
|
|
}
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_ColumnInterlaced:
|
|
{
|
|
aMode = "columnInterlaced";
|
|
if (aView->RenderingParams().ToSmoothInterlacing)
|
|
{
|
|
aMode.AssignCat (" (smoothed)");
|
|
}
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_ChessBoard:
|
|
{
|
|
aMode = "chessBoard";
|
|
if (aView->RenderingParams().ToSmoothInterlacing)
|
|
{
|
|
aMode.AssignCat (" (smoothed)");
|
|
}
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_SideBySide:
|
|
{
|
|
aMode = "sideBySide";
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_OverUnder:
|
|
{
|
|
aMode = "overUnder";
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_SoftPageFlip:
|
|
{
|
|
aMode = "softPageFlip";
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_OpenVR:
|
|
{
|
|
aMode = "openVR";
|
|
break;
|
|
}
|
|
case Graphic3d_StereoMode_Anaglyph:
|
|
{
|
|
aMode = "anaglyph";
|
|
switch (aView->RenderingParams().AnaglyphFilter)
|
|
{
|
|
case Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple : aMode.AssignCat (" (redCyanSimple)"); break;
|
|
case Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized : aMode.AssignCat (" (redCyan)"); break;
|
|
case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Simple : aMode.AssignCat (" (yellowBlueSimple)"); break;
|
|
case Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized: aMode.AssignCat (" (yellowBlue)"); break;
|
|
case Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple : aMode.AssignCat (" (greenMagentaSimple)"); break;
|
|
case Graphic3d_RenderingParams::Anaglyph_UserDefined : aMode.AssignCat (" (userDefined)"); break;
|
|
}
|
|
}
|
|
}
|
|
theDI << "Mode " << aMode << "\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Graphic3d_StereoMode aMode = aParams->StereoMode;
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg = theArgVec[anArgIter];
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (aFlag))
|
|
{
|
|
continue;
|
|
}
|
|
else if (aFlag == "0"
|
|
|| aFlag == "off")
|
|
{
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
Message::SendFail ("Error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
|
|
{
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
|
|
}
|
|
return 0;
|
|
}
|
|
else if (aFlag == "1"
|
|
|| aFlag == "on")
|
|
{
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
Message::SendFail ("Error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
|
|
if (aParams->StereoMode != Graphic3d_StereoMode_OpenVR)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else if (aFlag == "-reverse"
|
|
|| aFlag == "-noreverse"
|
|
|| aFlag == "-reversed"
|
|
|| aFlag == "-swap"
|
|
|| aFlag == "-noswap")
|
|
{
|
|
aParams->ToReverseStereo = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
|
|
}
|
|
else if (aFlag == "-mode"
|
|
|| aFlag == "-stereomode")
|
|
{
|
|
if (++anArgIter >= theArgNb
|
|
|| !parseStereoMode (theArgVec[anArgIter], aMode))
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
if (aMode == Graphic3d_StereoMode_QuadBuffer)
|
|
{
|
|
Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
|
|
}
|
|
}
|
|
else if (aFlag == "-anaglyph"
|
|
|| aFlag == "-anaglyphfilter")
|
|
{
|
|
Graphic3d_RenderingParams::Anaglyph aFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Simple;
|
|
if (++anArgIter >= theArgNb
|
|
|| !parseAnaglyphFilter (theArgVec[anArgIter], aFilter))
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aMode = Graphic3d_StereoMode_Anaglyph;
|
|
aParams->AnaglyphFilter = aFilter;
|
|
}
|
|
else if (parseStereoMode (anArg, aMode)) // short syntax
|
|
{
|
|
if (aMode == Graphic3d_StereoMode_QuadBuffer)
|
|
{
|
|
Message::SendInfo() << "Warning: make sure to call 'vcaps -stereo 1' before creating a view";
|
|
}
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& aFlag == "-hmdfov2d")
|
|
{
|
|
aParams->HmdFov2d = (float )Draw::Atof (theArgVec[++anArgIter]);
|
|
if (aParams->HmdFov2d < 10.0f
|
|
|| aParams->HmdFov2d > 180.0f)
|
|
{
|
|
Message::SendFail() << "Error: FOV is out of range";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-mirror"
|
|
|| aFlag == "-mirrorcomposer")
|
|
{
|
|
aParams->ToMirrorComposer = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);;
|
|
}
|
|
else if (aFlag == "-smooth"
|
|
|| aFlag == "-nosmooth"
|
|
|| aFlag == "-smoothinterlacing"
|
|
|| aFlag == "-nosmoothinterlacing")
|
|
{
|
|
aParams->ToSmoothInterlacing = Draw::ParseOnOffNoIterator (theArgNb, theArgVec, anArgIter);
|
|
}
|
|
else if (anArgIter + 1 < theArgNb
|
|
&& (aFlag == "-unitfactor"
|
|
|| aFlag == "-unitscale"))
|
|
{
|
|
aView->View()->SetUnitFactor (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
aParams->StereoMode = aMode;
|
|
aCamera->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
|
|
if (aParams->StereoMode == Graphic3d_StereoMode_OpenVR)
|
|
{
|
|
// initiate implicit continuous rendering
|
|
ViewerTest::CurrentEventManager()->FlushViewEvents (ViewerTest::GetAISContext(), aView, true);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VDefaults
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VDefaults (Draw_Interpretor& theDi,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
|
if (aCtx.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Handle(Prs3d_Drawer) aDefParams = aCtx->DefaultDrawer();
|
|
if (theArgsNb < 2)
|
|
{
|
|
if (aDefParams->TypeOfDeflection() == Aspect_TOD_RELATIVE)
|
|
{
|
|
theDi << "DeflType: relative\n"
|
|
<< "DeviationCoeff: " << aDefParams->DeviationCoefficient() << "\n";
|
|
}
|
|
else
|
|
{
|
|
theDi << "DeflType: absolute\n"
|
|
<< "AbsoluteDeflection: " << aDefParams->MaximalChordialDeviation() << "\n";
|
|
}
|
|
theDi << "AngularDeflection: " << (180.0 * aDefParams->DeviationAngle() / M_PI) << "\n";
|
|
theDi << "AutoTriangulation: " << (aDefParams->IsAutoTriangulation() ? "on" : "off") << "\n";
|
|
return 0;
|
|
}
|
|
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.UpperCase();
|
|
if (anArg == "-ABSDEFL"
|
|
|| anArg == "-ABSOLUTEDEFLECTION"
|
|
|| anArg == "-DEFL"
|
|
|| anArg == "-DEFLECTION")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aDefParams->SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
|
|
aDefParams->SetMaximalChordialDeviation (Draw::Atof (theArgVec[anArgIter]));
|
|
}
|
|
else if (anArg == "-RELDEFL"
|
|
|| anArg == "-RELATIVEDEFLECTION"
|
|
|| anArg == "-DEVCOEFF"
|
|
|| anArg == "-DEVIATIONCOEFF"
|
|
|| anArg == "-DEVIATIONCOEFFICIENT")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aDefParams->SetTypeOfDeflection (Aspect_TOD_RELATIVE);
|
|
aDefParams->SetDeviationCoefficient (Draw::Atof (theArgVec[anArgIter]));
|
|
}
|
|
else if (anArg == "-ANGDEFL"
|
|
|| anArg == "-ANGULARDEFL"
|
|
|| anArg == "-ANGULARDEFLECTION")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at " << anArg;
|
|
return 1;
|
|
}
|
|
aDefParams->SetDeviationAngle (M_PI * Draw::Atof (theArgVec[anArgIter]) / 180.0);
|
|
}
|
|
else if (anArg == "-AUTOTR"
|
|
|| anArg == "-AUTOTRIANG"
|
|
|| anArg == "-AUTOTRIANGULATION")
|
|
{
|
|
++anArgIter;
|
|
bool toTurnOn = true;
|
|
if (anArgIter >= theArgsNb
|
|
|| !Draw::ParseOnOff (theArgVec[anArgIter], toTurnOn))
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aDefParams->SetAutoTriangulation (toTurnOn);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//! Parse light source type from string.
|
|
static bool parseLightSourceType (const TCollection_AsciiString& theTypeName,
|
|
Graphic3d_TypeOfLightSource& theType)
|
|
{
|
|
TCollection_AsciiString aType (theTypeName);
|
|
aType.LowerCase();
|
|
if (aType == "amb"
|
|
|| aType == "ambient"
|
|
|| aType == "amblight")
|
|
{
|
|
theType = Graphic3d_TypeOfLightSource_Ambient;
|
|
}
|
|
else if (aType == "directional"
|
|
|| aType == "dirlight")
|
|
{
|
|
theType = Graphic3d_TypeOfLightSource_Directional;
|
|
}
|
|
else if (aType == "spot"
|
|
|| aType == "spotlight")
|
|
{
|
|
theType = Graphic3d_TypeOfLightSource_Spot;
|
|
}
|
|
else if (aType == "poslight"
|
|
|| aType == "positional"
|
|
|| aType == "point"
|
|
|| aType == "pnt")
|
|
{
|
|
theType = Graphic3d_TypeOfLightSource_Positional;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//! Find existing light by name or index.
|
|
static Handle(V3d_Light) findLightSource (const TCollection_AsciiString& theName)
|
|
{
|
|
Handle(V3d_Light) aLight;
|
|
Standard_Integer aLightIndex = -1;
|
|
Draw::ParseInteger (theName.ToCString(), aLightIndex);
|
|
Standard_Integer aLightIt = 0;
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
|
|
{
|
|
if (aLightIndex != -1)
|
|
{
|
|
if (aLightIt == aLightIndex)
|
|
{
|
|
return aLightIter.Value();
|
|
}
|
|
}
|
|
else if (aLightIter.Value()->GetId() == theName
|
|
|| aLightIter.Value()->Name() == theName)
|
|
{
|
|
if (!aLight.IsNull())
|
|
{
|
|
Message::SendWarning() << "Warning: ambiguous light name '" << theName << "'";
|
|
break;
|
|
}
|
|
aLight = aLightIter.Value();
|
|
}
|
|
}
|
|
return aLight;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VLight
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VLight (Draw_Interpretor& theDi,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
|
|
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
|
if (aView.IsNull()
|
|
|| aViewer.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (theArgsNb < 2)
|
|
{
|
|
// print lights info
|
|
Standard_Integer aLightId = 0;
|
|
for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightId)
|
|
{
|
|
Handle(V3d_Light) aLight = aLightIter.Value();
|
|
const Quantity_Color aColor = aLight->Color();
|
|
theDi << "Light #" << aLightId
|
|
<< (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
|
|
<< " [" << aLight->GetId() << "] "
|
|
<< (aLight->IsEnabled() ? "ON" : "OFF") << "\n";
|
|
switch (aLight->Type())
|
|
{
|
|
case Graphic3d_TypeOfLightSource_Ambient:
|
|
{
|
|
theDi << " Type: Ambient\n"
|
|
<< " Intensity: " << aLight->Intensity() << "\n";
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Directional:
|
|
{
|
|
theDi << " Type: Directional\n"
|
|
<< " Intensity: " << aLight->Intensity() << "\n"
|
|
<< " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
|
|
<< " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
|
|
<< " Smoothness: " << aLight->Smoothness() << "\n"
|
|
<< " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n";
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Positional:
|
|
{
|
|
theDi << " Type: Positional\n"
|
|
<< " Intensity: " << aLight->Intensity() << "\n"
|
|
<< " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
|
|
<< " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
|
|
<< " Smoothness: " << aLight->Smoothness() << "\n"
|
|
<< " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
|
|
<< " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
|
|
<< " Range: " << aLight->Range() << "\n";
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Spot:
|
|
{
|
|
theDi << " Type: Spot\n"
|
|
<< " Intensity: " << aLight->Intensity() << "\n"
|
|
<< " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"
|
|
<< " CastShadows:" << (aLight->ToCastShadows() ? "TRUE" : "FALSE") << "\n"
|
|
<< " Position: " << aLight->Position().X() << " " << aLight->Position().Y() << " " << aLight->Position().Z() << "\n"
|
|
<< " Direction: " << aLight->PackedDirection().x() << " " << aLight->PackedDirection().y() << " " << aLight->PackedDirection().z() << "\n"
|
|
<< " Atten.: " << aLight->ConstAttenuation() << " " << aLight->LinearAttenuation() << "\n"
|
|
<< " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"
|
|
<< " Exponent: " << aLight->Concentration() << "\n"
|
|
<< " Range: " << aLight->Range() << "\n";
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
theDi << " Type: UNKNOWN\n";
|
|
break;
|
|
}
|
|
}
|
|
theDi << " Color: " << aColor.Red() << " " << aColor.Green() << " " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
|
|
}
|
|
}
|
|
|
|
Handle(V3d_Light) aLightOld, aLightNew;
|
|
Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
|
|
bool isGlobal = true;
|
|
ViewerTest_AutoUpdater anUpdateTool (aCtx, aView);
|
|
Handle(AIS_LightSource) aLightPrs;
|
|
for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
|
|
{
|
|
const TCollection_AsciiString anArg (theArgVec[anArgIt]);
|
|
TCollection_AsciiString anArgCase (anArg);
|
|
anArgCase.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArgCase == "-new"
|
|
|| anArgCase == "-add"
|
|
|| anArgCase == "-create"
|
|
|| anArgCase == "-type"
|
|
|| (anArgCase == "-reset"
|
|
&& !aLightNew.IsNull())
|
|
|| (anArgCase == "-defaults"
|
|
&& !aLightNew.IsNull())
|
|
|| anArgCase == "add"
|
|
|| anArgCase == "new"
|
|
|| anArgCase == "create")
|
|
{
|
|
Graphic3d_TypeOfLightSource aType = Graphic3d_TypeOfLightSource_Ambient;
|
|
if (anArgCase == "-reset")
|
|
{
|
|
aType = aLightNew->Type();
|
|
}
|
|
else if (anArgIt + 1 >= theArgsNb
|
|
|| !parseLightSourceType (theArgVec[++anArgIt], aType))
|
|
{
|
|
theDi << "Syntax error at '" << theArgVec[anArgIt] << "'\n";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aName;
|
|
if (!aLightNew.IsNull())
|
|
{
|
|
aName = aLightNew->Name();
|
|
}
|
|
switch (aType)
|
|
{
|
|
case Graphic3d_TypeOfLightSource_Ambient:
|
|
{
|
|
aLightNew = new V3d_AmbientLight();
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Directional:
|
|
{
|
|
aLightNew = new V3d_DirectionalLight();
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Spot:
|
|
{
|
|
aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
|
|
break;
|
|
}
|
|
case Graphic3d_TypeOfLightSource_Positional:
|
|
{
|
|
aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (anArgCase == "-type"
|
|
&& !aLightOld.IsNull())
|
|
{
|
|
aLightNew->CopyFrom (aLightOld);
|
|
}
|
|
aLightNew->SetName (aName);
|
|
}
|
|
else if ((anArgCase == "-layer"
|
|
|| anArgCase == "-zlayer")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
if (!ViewerTest::ParseZLayer (theArgVec[++anArgIt], aLayer)
|
|
|| aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Message::SendFail() << "Error: wrong syntax at '" << theArgVec[anArgIt] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (anArgCase == "-glob"
|
|
|| anArgCase == "-global"
|
|
|| anArgCase == "-loc"
|
|
|| anArgCase == "-local")
|
|
{
|
|
isGlobal = anArgCase.StartsWith ("-glob");
|
|
}
|
|
else if (anArgCase == "-def"
|
|
|| anArgCase == "-defaults"
|
|
|| anArgCase == "-reset")
|
|
{
|
|
aViewer->SetDefaultLights();
|
|
aLightOld.Nullify();
|
|
aLightNew.Nullify();
|
|
aLightPrs.Nullify();
|
|
}
|
|
else if (anArgCase == "-clr"
|
|
|| anArgCase == "-clear"
|
|
|| anArgCase == "clear")
|
|
{
|
|
TColStd_SequenceOfInteger aLayers;
|
|
aViewer->GetAllZLayers (aLayers);
|
|
for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
|
|
{
|
|
if (aLayeriter.Value() == aLayer
|
|
|| aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
|
|
aSettings.SetLights (Handle(Graphic3d_LightSet)());
|
|
aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
|
|
if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
|
|
for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
|
|
{
|
|
Handle(V3d_Light) aLight = aLightIter.Value();
|
|
Handle(AIS_InteractiveObject) aPrsObject;
|
|
GetMapOfAIS().Find2 (aLight->Name(), aPrsObject);
|
|
if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
|
|
{
|
|
aCtx->Remove (aLightSourceDel, false);
|
|
aMap.UnBind1 (aLightSourceDel);
|
|
}
|
|
aViewer->DelLight (aLight);
|
|
aLightIter = aView->ActiveLightIterator();
|
|
}
|
|
}
|
|
|
|
aLightOld.Nullify();
|
|
aLightNew.Nullify();
|
|
aLightPrs.Nullify();
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-display"
|
|
|| anArgCase == "-disp"
|
|
|| anArgCase == "-presentation"
|
|
|| anArgCase == "-prs"))
|
|
{
|
|
TCollection_AsciiString aLightName = aLightNew->Name();
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& theArgVec[anArgIt + 1][0] != '-')
|
|
{
|
|
// old syntax
|
|
aLightName = theArgVec[++anArgIt];
|
|
if (aLightNew->Name() != aLightName)
|
|
{
|
|
if (Handle(V3d_Light) anOtherLight = findLightSource (aLightName))
|
|
{
|
|
theDi << "Syntax error: light with name '" << aLightName << "' is already defined";
|
|
return 1;
|
|
}
|
|
aLightNew->SetName (aLightName);
|
|
}
|
|
}
|
|
if (aLightName.IsEmpty())
|
|
{
|
|
Message::SendFail() << "Error: nameless light source cannot be displayed";
|
|
return 1;
|
|
}
|
|
if (aLightPrs.IsNull())
|
|
{
|
|
aLightPrs = new AIS_LightSource (aLightNew);
|
|
}
|
|
theDi << aLightName << " ";
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-disable"
|
|
|| anArgCase == "-disabled"
|
|
|| anArgCase == "-enable"
|
|
|| anArgCase == "-enabled"))
|
|
{
|
|
bool toEnable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
if (anArgCase == "-disable"
|
|
|| anArgCase == "-disabled")
|
|
{
|
|
toEnable = !toEnable;
|
|
}
|
|
aLightNew->SetEnabled (toEnable);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-color"
|
|
|| anArgCase == "-colour"
|
|
|| anArgCase == "color"))
|
|
{
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIt - 1,
|
|
theArgVec + anArgIt + 1,
|
|
aColor);
|
|
anArgIt += aNbParsed;
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aLightNew->SetColor (aColor);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-pos"
|
|
|| anArgCase == "-position"
|
|
|| anArgCase == "-prsposition"
|
|
|| anArgCase == "-prspos"
|
|
|| anArgCase == "pos"
|
|
|| anArgCase == "position")
|
|
&& (anArgIt + 3) < theArgsNb)
|
|
{
|
|
gp_XYZ aPosXYZ;
|
|
if (!parseXYZ (theArgVec + anArgIt + 1, aPosXYZ))
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
anArgIt += 3;
|
|
if (anArgCase == "-prsposition"
|
|
|| anArgCase == "-prspos")
|
|
{
|
|
aLightNew->SetDisplayPosition (aPosXYZ);
|
|
}
|
|
else
|
|
{
|
|
if (aLightNew->Type() != Graphic3d_TypeOfLightSource_Positional
|
|
&& aLightNew->Type() != Graphic3d_TypeOfLightSource_Spot)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aLightNew->SetPosition (aPosXYZ);
|
|
}
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional
|
|
|| aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
|
|
&& (anArgCase == "-dir"
|
|
|| anArgCase == "-direction")
|
|
&& (anArgIt + 3) < theArgsNb)
|
|
{
|
|
gp_XYZ aDirXYZ;
|
|
if (!parseXYZ (theArgVec + anArgIt + 1, aDirXYZ))
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
anArgIt += 3;
|
|
aLightNew->SetDirection (gp_Dir (aDirXYZ));
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-smoothangle"
|
|
|| anArgCase == "-smoothradius"
|
|
|| anArgCase == "-sm"
|
|
|| anArgCase == "-smoothness")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
|
|
if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
|
|
{
|
|
aSmoothness = Standard_ShortReal(aSmoothness * M_PI / 180.0);
|
|
}
|
|
if (Abs (aSmoothness) <= ShortRealEpsilon())
|
|
{
|
|
aLightNew->SetIntensity (1.f);
|
|
}
|
|
else if (Abs (aLightNew->Smoothness()) <= ShortRealEpsilon())
|
|
{
|
|
aLightNew->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
|
|
}
|
|
else
|
|
{
|
|
Standard_ShortReal aSmoothnessRatio = static_cast<Standard_ShortReal> (aSmoothness / aLightNew->Smoothness());
|
|
aLightNew->SetIntensity (aLightNew->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
|
|
}
|
|
|
|
if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
|
|
{
|
|
aLightNew->SetSmoothRadius (aSmoothness);
|
|
}
|
|
else if (aLightNew->Type() == Graphic3d_TypeOfLightSource_Directional)
|
|
{
|
|
aLightNew->SetSmoothAngle (aSmoothness);
|
|
}
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (anArgCase == "-int"
|
|
|| anArgCase == "-intensity")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
|
|
aLightNew->SetIntensity (aIntensity);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
|
|
&& (anArgCase == "-spotangle"
|
|
|| anArgCase == "-ang"
|
|
|| anArgCase == "-angle")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
|
|
anAngle = (Standard_ShortReal (anAngle / 180.0 * M_PI));
|
|
aLightNew->SetAngle (anAngle);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
|
|
|| aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
|
|
&& (anArgCase == "-constatten"
|
|
|| anArgCase == "-constattenuation")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
const Standard_ShortReal aConstAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
|
|
aLightNew->SetAttenuation (aConstAtten, aLightNew->LinearAttenuation());
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& (aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional
|
|
|| aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot)
|
|
&& (anArgCase == "-linatten"
|
|
|| anArgCase == "-linearatten"
|
|
|| anArgCase == "-linearattenuation")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
const Standard_ShortReal aLinAtten = (Standard_ShortReal )Atof (theArgVec[++anArgIt]);
|
|
aLightNew->SetAttenuation (aLightNew->ConstAttenuation(), aLinAtten);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
|
|
&& (anArgCase == "-spotexp"
|
|
|| anArgCase == "-spotexponent"
|
|
|| anArgCase == "-exp"
|
|
|| anArgCase == "-exponent")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
aLightNew->SetConcentration ((Standard_ShortReal )Atof (theArgVec[++anArgIt]));
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
|
|
&& aLightNew->Type() != Graphic3d_TypeOfLightSource_Directional
|
|
&& anArgCase == "-range"
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_ShortReal aRange ((Standard_ShortReal)Atof (theArgVec[++anArgIt]));
|
|
aLightNew->SetRange (aRange);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
|
|
&& (anArgCase == "-head"
|
|
|| anArgCase == "-headlight"))
|
|
{
|
|
Standard_Boolean isHeadLight = Standard_True;
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
aLightNew->SetHeadlight (isHeadLight);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& anArgCase == "-name"
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
const TCollection_AsciiString aName = theArgVec[++anArgIt];
|
|
if (aLightNew->Name() == aName)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (Handle(V3d_Light) anOtherLight = findLightSource (aName))
|
|
{
|
|
theDi << "Syntax error: light with name '" << aName << "' is already defined";
|
|
return 1;
|
|
}
|
|
aLightNew->SetName (aName);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (anArgCase == "-showzoomable"
|
|
|| anArgCase == "-prszoomable"
|
|
|| anArgCase == "-zoomable"))
|
|
{
|
|
const bool isZoomable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
aLightPrs->SetZoomable (isZoomable);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (anArgCase == "-showdraggable"
|
|
|| anArgCase == "-prsdraggable"
|
|
|| anArgCase == "-draggable"))
|
|
{
|
|
const bool isDraggable = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
aLightPrs->SetDraggable (isDraggable);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (anArgCase == "-showname"
|
|
|| anArgCase == "-prsname"))
|
|
{
|
|
const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
aLightPrs->SetDisplayName (toDisplay);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (aLightNew->Type() == Graphic3d_TypeOfLightSource_Spot
|
|
|| aLightNew->Type() == Graphic3d_TypeOfLightSource_Positional)
|
|
&& (anArgCase == "-showrange"
|
|
|| anArgCase == "-prsrange"))
|
|
{
|
|
const bool toDisplay = Draw::ParseOnOffIterator (theArgsNb, theArgVec, anArgIt);
|
|
aLightPrs->SetDisplayRange (toDisplay);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (anArgCase == "-showsize"
|
|
|| anArgCase == "-prssize")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_Real aSize = 0.0;
|
|
if (!Draw::ParseReal (theArgVec[++anArgIt], aSize)
|
|
|| aSize <= 0.0
|
|
|| aLightPrs.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aLightPrs->SetSize (aSize);
|
|
}
|
|
else if (!aLightPrs.IsNull()
|
|
&& (anArgCase == "-dirarcsize"
|
|
|| anArgCase == "-arcsize"
|
|
|| anArgCase == "-arc")
|
|
&& anArgIt + 1 < theArgsNb)
|
|
{
|
|
Standard_Integer aSize = 0;
|
|
if (!Draw::ParseInteger (theArgVec[anArgIt + 1], aSize)
|
|
|| aSize <= 0
|
|
|| aLightPrs->Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
++anArgIt;
|
|
aLightPrs->SetArcSize (aSize);
|
|
}
|
|
else if (!aLightNew.IsNull()
|
|
&& aLightNew->Type() != Graphic3d_TypeOfLightSource_Ambient
|
|
&& (anArgCase == "-castshadow"
|
|
|| anArgCase == "-castshadows"
|
|
|| anArgCase == "-shadows"))
|
|
{
|
|
bool toCastShadows = true;
|
|
if (anArgIt + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIt + 1], toCastShadows))
|
|
{
|
|
++anArgIt;
|
|
}
|
|
aLightNew->SetCastShadows (toCastShadows);
|
|
}
|
|
else if (anArgCase == "-del"
|
|
|| anArgCase == "-delete"
|
|
|| anArgCase == "-remove"
|
|
|| anArgCase == "del"
|
|
|| anArgCase == "delete"
|
|
|| anArgCase == "remove")
|
|
{
|
|
if (aLightOld.IsNull())
|
|
{
|
|
if (!aLightNew.IsNull())
|
|
{
|
|
aLightNew.Nullify();
|
|
continue;
|
|
}
|
|
|
|
if (++anArgIt >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
|
|
aLightOld = findLightSource (anOldName);
|
|
if (aLightOld.IsNull())
|
|
{
|
|
Message::SendWarning() << "Warning: light '" << anOldName << "' not found";
|
|
continue;
|
|
}
|
|
}
|
|
|
|
aLightNew.Nullify();
|
|
aLightPrs.Nullify();
|
|
}
|
|
else if (anArgCase == "-change"
|
|
|| anArgCase == "change")
|
|
{
|
|
// just skip old syntax
|
|
}
|
|
else if (aLightNew.IsNull()
|
|
&& !anArgCase.StartsWith ("-"))
|
|
{
|
|
if (!aLightNew.IsNull())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const TCollection_AsciiString anOldName (theArgVec[anArgIt]);
|
|
aLightOld = findLightSource (anOldName);
|
|
if (!aLightOld.IsNull())
|
|
{
|
|
aLightNew = aLightOld;
|
|
|
|
Handle(AIS_InteractiveObject) aPrsObject;
|
|
GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
|
|
aLightPrs = Handle(AIS_LightSource)::DownCast (aPrsObject);
|
|
}
|
|
else
|
|
{
|
|
Standard_Integer aLightIndex = -1;
|
|
Draw::ParseInteger (anOldName.ToCString(), aLightIndex);
|
|
if (aLightIndex != -1)
|
|
{
|
|
Message::SendFail() << "Syntax error: light source with index '" << aLightIndex << "' is not found";
|
|
return 1;
|
|
}
|
|
|
|
aLightNew = new V3d_AmbientLight();
|
|
aLightNew->SetName (anOldName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Warning: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// delete old light source
|
|
if (!aLightOld.IsNull()
|
|
&& aLightOld != aLightNew)
|
|
{
|
|
TColStd_SequenceOfInteger aLayers;
|
|
aViewer->GetAllZLayers (aLayers);
|
|
for (TColStd_SequenceOfInteger::Iterator aLayerIter (aLayers); aLayerIter.More(); aLayerIter.Next())
|
|
{
|
|
if (aLayerIter.Value() == aLayer
|
|
|| aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayerIter.Value());
|
|
if (!aSettings.Lights().IsNull())
|
|
{
|
|
aSettings.Lights()->Remove (aLightOld);
|
|
if (aSettings.Lights()->IsEmpty())
|
|
{
|
|
aSettings.SetLights (Handle(Graphic3d_LightSet)());
|
|
}
|
|
}
|
|
aViewer->SetZLayerSettings (aLayerIter.Value(), aSettings);
|
|
if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
Handle(AIS_InteractiveObject) aPrsObject;
|
|
GetMapOfAIS().Find2 (aLightOld->Name(), aPrsObject);
|
|
if (Handle(AIS_LightSource) aLightSourceDel = Handle(AIS_LightSource)::DownCast (aPrsObject))
|
|
{
|
|
aCtx->Remove (aLightSourceDel, false);
|
|
GetMapOfAIS().UnBind1 (aLightSourceDel);
|
|
}
|
|
aViewer->DelLight (aLightOld);
|
|
}
|
|
aLightOld.Nullify();
|
|
}
|
|
|
|
// add new light source
|
|
if (!aLightNew.IsNull())
|
|
{
|
|
if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
|
|
{
|
|
aViewer->AddLight (aLightNew);
|
|
if (isGlobal)
|
|
{
|
|
aViewer->SetLightOn (aLightNew);
|
|
}
|
|
else
|
|
{
|
|
aView->SetLightOn (aLightNew);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayer);
|
|
if (aSettings.Lights().IsNull())
|
|
{
|
|
aSettings.SetLights (new Graphic3d_LightSet());
|
|
}
|
|
aSettings.Lights()->Add (aLightNew);
|
|
aViewer->SetZLayerSettings (aLayer, aSettings);
|
|
}
|
|
|
|
if (!aLightPrs.IsNull())
|
|
{
|
|
aLightPrs->SetLight (aLightNew);
|
|
ViewerTest::Display (aLightNew->Name(), aLightPrs, false);
|
|
}
|
|
}
|
|
|
|
// manage presentations
|
|
struct LightPrsSort
|
|
{
|
|
bool operator() (const Handle(AIS_LightSource)& theLeft,
|
|
const Handle(AIS_LightSource)& theRight)
|
|
{
|
|
return theLeft->Light()->GetId() < theRight->Light()->GetId();
|
|
}
|
|
};
|
|
|
|
AIS_ListOfInteractive aPrsList;
|
|
aCtx->DisplayedObjects (AIS_KindOfInteractive_LightSource, -1, aPrsList);
|
|
if (!aPrsList.IsEmpty())
|
|
{
|
|
// update light source presentations
|
|
std::vector<Handle(AIS_LightSource)> aLightPrsVec;
|
|
for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More(); aPrsIter.Next())
|
|
{
|
|
if (Handle(AIS_LightSource) aLightPrs2 = Handle(AIS_LightSource)::DownCast (aPrsIter.Value()))
|
|
{
|
|
aLightPrsVec.push_back (aLightPrs2);
|
|
}
|
|
}
|
|
|
|
// sort objects by id as AIS_InteractiveContext stores them in unordered map
|
|
std::sort (aLightPrsVec.begin(), aLightPrsVec.end(), LightPrsSort());
|
|
|
|
Standard_Integer aTopStack = 0;
|
|
for (std::vector<Handle(AIS_LightSource)>::iterator aPrsIter = aLightPrsVec.begin(); aPrsIter != aLightPrsVec.end(); ++aPrsIter)
|
|
{
|
|
Handle(AIS_LightSource) aLightPrs2 = *aPrsIter;
|
|
if (!aLightPrs2->TransformPersistence().IsNull()
|
|
&& aLightPrs2->TransformPersistence()->IsTrihedronOr2d())
|
|
{
|
|
const Standard_Integer aPrsSize = (Standard_Integer )aLightPrs2->Size();
|
|
aLightPrs2->TransformPersistence()->SetOffset2d (Graphic3d_Vec2i (aTopStack + aPrsSize, aPrsSize));
|
|
aTopStack += aPrsSize + aPrsSize / 2;
|
|
}
|
|
aCtx->Redisplay (aLightPrs2, false);
|
|
aCtx->SetTransformPersistence (aLightPrs2, aLightPrs2->TransformPersistence());
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VPBREnvironment
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VPBREnvironment (Draw_Interpretor&,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
if (theArgsNb > 2)
|
|
{
|
|
Message::SendFail ("Syntax error: 'vpbrenv' command has only one argument");
|
|
return 1;
|
|
}
|
|
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString anArg = TCollection_AsciiString (theArgVec[1]);
|
|
anArg.LowerCase();
|
|
|
|
if (anArg == "-generate"
|
|
|| anArg == "-gen")
|
|
{
|
|
aView->GeneratePBREnvironment (Standard_True);
|
|
}
|
|
else if (anArg == "-clear")
|
|
{
|
|
aView->ClearPBREnvironment (Standard_True);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument [" << theArgVec[1] << "] for 'vpbrenv' command";
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//! Read Graphic3d_RenderingParams::PerfCounters flag.
|
|
static Standard_Boolean parsePerfStatsFlag (const TCollection_AsciiString& theValue,
|
|
Standard_Boolean& theToReset,
|
|
Graphic3d_RenderingParams::PerfCounters& theFlagsRem,
|
|
Graphic3d_RenderingParams::PerfCounters& theFlagsAdd)
|
|
{
|
|
Graphic3d_RenderingParams::PerfCounters aFlag = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
TCollection_AsciiString aVal = theValue;
|
|
Standard_Boolean toReverse = Standard_False;
|
|
if (aVal == "none")
|
|
{
|
|
theToReset = Standard_True;
|
|
return Standard_True;
|
|
}
|
|
else if (aVal.StartsWith ("-"))
|
|
{
|
|
toReverse = Standard_True;
|
|
aVal = aVal.SubString (2, aVal.Length());
|
|
}
|
|
else if (aVal.StartsWith ("no"))
|
|
{
|
|
toReverse = Standard_True;
|
|
aVal = aVal.SubString (3, aVal.Length());
|
|
}
|
|
else if (aVal.StartsWith ("+"))
|
|
{
|
|
aVal = aVal.SubString (2, aVal.Length());
|
|
}
|
|
else
|
|
{
|
|
theToReset = Standard_True;
|
|
}
|
|
|
|
if ( aVal == "fps"
|
|
|| aVal == "framerate") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameRate;
|
|
else if (aVal == "cpu") aFlag = Graphic3d_RenderingParams::PerfCounters_CPU;
|
|
else if (aVal == "layers") aFlag = Graphic3d_RenderingParams::PerfCounters_Layers;
|
|
else if (aVal == "structs"
|
|
|| aVal == "structures"
|
|
|| aVal == "objects") aFlag = Graphic3d_RenderingParams::PerfCounters_Structures;
|
|
else if (aVal == "groups") aFlag = Graphic3d_RenderingParams::PerfCounters_Groups;
|
|
else if (aVal == "arrays") aFlag = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
|
|
else if (aVal == "tris"
|
|
|| aVal == "triangles") aFlag = Graphic3d_RenderingParams::PerfCounters_Triangles;
|
|
else if (aVal == "pnts"
|
|
|| aVal == "points") aFlag = Graphic3d_RenderingParams::PerfCounters_Points;
|
|
else if (aVal == "lines") aFlag = Graphic3d_RenderingParams::PerfCounters_Lines;
|
|
else if (aVal == "mem"
|
|
|| aVal == "gpumem"
|
|
|| aVal == "estimmem") aFlag = Graphic3d_RenderingParams::PerfCounters_EstimMem;
|
|
else if (aVal == "skipimmediate"
|
|
|| aVal == "noimmediate") aFlag = Graphic3d_RenderingParams::PerfCounters_SkipImmediate;
|
|
else if (aVal == "frametime"
|
|
|| aVal == "frametimers"
|
|
|| aVal == "time") aFlag = Graphic3d_RenderingParams::PerfCounters_FrameTime;
|
|
else if (aVal == "basic") aFlag = Graphic3d_RenderingParams::PerfCounters_Basic;
|
|
else if (aVal == "extended"
|
|
|| aVal == "verbose"
|
|
|| aVal == "extra") aFlag = Graphic3d_RenderingParams::PerfCounters_Extended;
|
|
else if (aVal == "full"
|
|
|| aVal == "all") aFlag = Graphic3d_RenderingParams::PerfCounters_All;
|
|
else
|
|
{
|
|
return Standard_False;
|
|
}
|
|
|
|
if (toReverse)
|
|
{
|
|
theFlagsRem = Graphic3d_RenderingParams::PerfCounters(theFlagsRem | aFlag);
|
|
}
|
|
else
|
|
{
|
|
theFlagsAdd = Graphic3d_RenderingParams::PerfCounters(theFlagsAdd | aFlag);
|
|
}
|
|
return Standard_True;
|
|
}
|
|
|
|
//! Read Graphic3d_RenderingParams::PerfCounters flags.
|
|
static Standard_Boolean convertToPerfStatsFlags (const TCollection_AsciiString& theValue,
|
|
Graphic3d_RenderingParams::PerfCounters& theFlags)
|
|
{
|
|
TCollection_AsciiString aValue = theValue;
|
|
Graphic3d_RenderingParams::PerfCounters aFlagsRem = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
Graphic3d_RenderingParams::PerfCounters aFlagsAdd = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
Standard_Boolean toReset = Standard_False;
|
|
for (;;)
|
|
{
|
|
Standard_Integer aSplitPos = aValue.Search ("|");
|
|
if (aSplitPos <= 0)
|
|
{
|
|
if (!parsePerfStatsFlag (aValue, toReset, aFlagsRem, aFlagsAdd))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
if (toReset)
|
|
{
|
|
theFlags = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
}
|
|
theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags | aFlagsAdd);
|
|
theFlags = Graphic3d_RenderingParams::PerfCounters(theFlags & ~aFlagsRem);
|
|
return Standard_True;
|
|
}
|
|
|
|
if (aSplitPos > 1)
|
|
{
|
|
TCollection_AsciiString aSubValue = aValue.SubString (1, aSplitPos - 1);
|
|
if (!parsePerfStatsFlag (aSubValue, toReset, aFlagsRem, aFlagsAdd))
|
|
{
|
|
return Standard_False;
|
|
}
|
|
}
|
|
aValue = aValue.SubString (aSplitPos + 1, aValue.Length());
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VRenderParams
|
|
//purpose : Enables/disables rendering features
|
|
//=======================================================================
|
|
|
|
static Standard_Integer VRenderParams (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
|
|
TCollection_AsciiString aCmdName (theArgVec[0]);
|
|
aCmdName.LowerCase();
|
|
if (aCmdName == "vraytrace")
|
|
{
|
|
if (theArgNb == 1)
|
|
{
|
|
theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "on" : "off") << " ";
|
|
return 0;
|
|
}
|
|
else if (theArgNb == 2)
|
|
{
|
|
TCollection_AsciiString aValue (theArgVec[1]);
|
|
aValue.LowerCase();
|
|
if (aValue == "on"
|
|
|| aValue == "1")
|
|
{
|
|
aParams.Method = Graphic3d_RM_RAYTRACING;
|
|
aView->Redraw();
|
|
return 0;
|
|
}
|
|
else if (aValue == "off"
|
|
|| aValue == "0")
|
|
{
|
|
aParams.Method = Graphic3d_RM_RASTERIZATION;
|
|
aView->Redraw();
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[1] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (theArgNb < 2)
|
|
{
|
|
theDI << "renderMode: ";
|
|
switch (aParams.Method)
|
|
{
|
|
case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
|
|
case Graphic3d_RM_RAYTRACING: theDI << "raytrace "; break;
|
|
}
|
|
theDI << "\n";
|
|
theDI << "transparency: ";
|
|
switch (aParams.TransparencyMethod)
|
|
{
|
|
case Graphic3d_RTM_BLEND_UNORDERED: theDI << "Basic blended transparency with non-commuting operator "; break;
|
|
case Graphic3d_RTM_BLEND_OIT: theDI << "Weighted Blended Order-Independent Transparency, depth weight factor: "
|
|
<< TCollection_AsciiString (aParams.OitDepthFactor); break;
|
|
case Graphic3d_RTM_DEPTH_PEELING_OIT: theDI << "Depth Peeling Order-Independent Transparency, Nb.Layers: "
|
|
<< TCollection_AsciiString (aParams.NbOitDepthPeelingLayers); break;
|
|
}
|
|
theDI << "\n";
|
|
theDI << "msaa: " << aParams.NbMsaaSamples << "\n";
|
|
theDI << "rendScale: " << aParams.RenderResolutionScale << "\n";
|
|
theDI << "rayDepth: " << aParams.RaytracingDepth << "\n";
|
|
theDI << "fsaa: " << (aParams.IsAntialiasingEnabled ? "on" : "off") << "\n";
|
|
theDI << "shadows: " << (aParams.IsShadowEnabled ? "on" : "off") << "\n";
|
|
theDI << "shadowMapRes: " << aParams.ShadowMapResolution << "\n";
|
|
theDI << "shadowMapBias: " << aParams.ShadowMapBias << "\n";
|
|
theDI << "reflections: " << (aParams.IsReflectionEnabled ? "on" : "off") << "\n";
|
|
theDI << "gleam: " << (aParams.IsTransparentShadowEnabled ? "on" : "off") << "\n";
|
|
theDI << "GI: " << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << "\n";
|
|
theDI << "blocked RNG: " << (aParams.CoherentPathTracingMode ? "on" : "off") << "\n";
|
|
theDI << "iss: " << (aParams.AdaptiveScreenSampling ? "on" : "off") << "\n";
|
|
theDI << "iss debug: " << (aParams.ShowSamplingTiles ? "on" : "off") << "\n";
|
|
theDI << "two-sided BSDF: " << (aParams.TwoSidedBsdfModels ? "on" : "off") << "\n";
|
|
theDI << "max radiance: " << aParams.RadianceClampingValue << "\n";
|
|
theDI << "nb tiles (iss): " << aParams.NbRayTracingTiles << "\n";
|
|
theDI << "tile size (iss):" << aParams.RayTracingTileSize << "x" << aParams.RayTracingTileSize << "\n";
|
|
theDI << "shadingModel: ";
|
|
switch (aView->ShadingModel())
|
|
{
|
|
case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
|
|
case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit"; break;
|
|
case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat"; break;
|
|
case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud"; break;
|
|
case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong"; break;
|
|
case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
|
|
case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
|
|
}
|
|
theDI << "\n";
|
|
{
|
|
theDI << "perfCounters:";
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameRate) != 0)
|
|
{
|
|
theDI << " fps";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_CPU) != 0)
|
|
{
|
|
theDI << " cpu";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Structures) != 0)
|
|
{
|
|
theDI << " structs";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Groups) != 0)
|
|
{
|
|
theDI << " groups";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_GroupArrays) != 0)
|
|
{
|
|
theDI << " arrays";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Triangles) != 0)
|
|
{
|
|
theDI << " tris";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Lines) != 0)
|
|
{
|
|
theDI << " lines";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_Points) != 0)
|
|
{
|
|
theDI << " pnts";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_EstimMem) != 0)
|
|
{
|
|
theDI << " gpumem";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_FrameTime) != 0)
|
|
{
|
|
theDI << " frameTime";
|
|
}
|
|
if ((aParams.CollectedStats & Graphic3d_RenderingParams::PerfCounters_SkipImmediate) != 0)
|
|
{
|
|
theDI << " skipimmediate";
|
|
}
|
|
if (aParams.CollectedStats == Graphic3d_RenderingParams::PerfCounters_NONE)
|
|
{
|
|
theDI << " none";
|
|
}
|
|
theDI << "\n";
|
|
}
|
|
theDI << "depth pre-pass: " << (aParams.ToEnableDepthPrepass ? "on" : "off") << "\n";
|
|
theDI << "alpha to coverage: " << (aParams.ToEnableAlphaToCoverage ? "on" : "off") << "\n";
|
|
theDI << "frustum culling: " << (aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On ? "on" :
|
|
aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off ? "off" :
|
|
"noUpdate") << "\n";
|
|
theDI << "\n";
|
|
return 0;
|
|
}
|
|
|
|
bool toPrint = false, toSyncDefaults = false, toSyncAllViews = false;
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg (theArgVec[anArgIter]);
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (aFlag))
|
|
{
|
|
continue;
|
|
}
|
|
else if (aFlag == "-echo"
|
|
|| aFlag == "-print")
|
|
{
|
|
toPrint = Standard_True;
|
|
anUpdateTool.Invalidate();
|
|
}
|
|
else if (aFlag == "-reset")
|
|
{
|
|
aParams = ViewerTest::GetViewerFromContext()->DefaultRenderingParams();
|
|
}
|
|
else if (aFlag == "-sync"
|
|
&& (anArgIter + 1 < theArgNb))
|
|
{
|
|
TCollection_AsciiString aSyncFlag (theArgVec[++anArgIter]);
|
|
aSyncFlag.LowerCase();
|
|
if (aSyncFlag == "default"
|
|
|| aSyncFlag == "defaults"
|
|
|| aSyncFlag == "viewer")
|
|
{
|
|
toSyncDefaults = true;
|
|
}
|
|
else if (aSyncFlag == "allviews"
|
|
|| aSyncFlag == "views")
|
|
{
|
|
toSyncAllViews = true;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail ("Syntax error: unknown parameter to -sync argument");
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-mode"
|
|
|| aFlag == "-rendermode"
|
|
|| aFlag == "-render_mode")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
switch (aParams.Method)
|
|
{
|
|
case Graphic3d_RM_RASTERIZATION: theDI << "rasterization "; break;
|
|
case Graphic3d_RM_RAYTRACING: theDI << "ray-tracing "; break;
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-ray"
|
|
|| aFlag == "-raytrace")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.Method == Graphic3d_RM_RAYTRACING ? "true" : "false") << " ";
|
|
continue;
|
|
}
|
|
|
|
bool isRayTrace = true;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isRayTrace))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aParams.Method = isRayTrace ? Graphic3d_RM_RAYTRACING : Graphic3d_RM_RASTERIZATION;
|
|
}
|
|
else if (aFlag == "-rast"
|
|
|| aFlag == "-raster"
|
|
|| aFlag == "-rasterization")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.Method == Graphic3d_RM_RASTERIZATION ? "true" : "false") << " ";
|
|
continue;
|
|
}
|
|
|
|
bool isRaster = true;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isRaster))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aParams.Method = isRaster ? Graphic3d_RM_RASTERIZATION : Graphic3d_RM_RAYTRACING;
|
|
}
|
|
else if (aFlag == "-msaa")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.NbMsaaSamples << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aNbSamples = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aNbSamples < 0)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid number of MSAA samples " << aNbSamples << "";
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
aParams.NbMsaaSamples = aNbSamples;
|
|
}
|
|
}
|
|
else if (aFlag == "-linefeather"
|
|
|| aFlag == "-edgefeather"
|
|
|| aFlag == "-feather")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << " " << aParams.LineFeather << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aParam = theArgVec[anArgIter];
|
|
const Standard_ShortReal aFeather = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
|
|
if (aFeather <= 0.0f)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid value of line width feather " << aFeather << ". Should be > 0";
|
|
return 1;
|
|
}
|
|
aParams.LineFeather = aFeather;
|
|
}
|
|
else if (aFlag == "-oit")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
if (aParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT)
|
|
{
|
|
theDI << "on, depth weight factor: " << TCollection_AsciiString (aParams.OitDepthFactor) << " ";
|
|
}
|
|
else if (aParams.TransparencyMethod == Graphic3d_RTM_DEPTH_PEELING_OIT)
|
|
{
|
|
theDI << "on, depth peeling layers: " << TCollection_AsciiString (aParams.NbOitDepthPeelingLayers) << " ";
|
|
}
|
|
else
|
|
{
|
|
theDI << "off" << " ";
|
|
}
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aParam = theArgVec[anArgIter];
|
|
aParam.LowerCase();
|
|
if (aParam == "peeling"
|
|
|| aParam == "peel")
|
|
{
|
|
aParams.TransparencyMethod = Graphic3d_RTM_DEPTH_PEELING_OIT;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).IsIntegerValue())
|
|
{
|
|
++anArgIter;
|
|
const Standard_Integer aNbLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
|
|
if (aNbLayers < 2)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid layers number specified for Depth Peeling OIT " << aNbLayers;
|
|
return 1;
|
|
}
|
|
aParams.NbOitDepthPeelingLayers = TCollection_AsciiString (theArgVec[anArgIter]).IntegerValue();
|
|
}
|
|
}
|
|
else if (aParam == "weighted"
|
|
|| aParam == "weight")
|
|
{
|
|
aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).IsRealValue())
|
|
{
|
|
++anArgIter;
|
|
const Standard_ShortReal aWeight = (Standard_ShortReal)TCollection_AsciiString (theArgVec[anArgIter]).RealValue();
|
|
if (aWeight < 0.f || aWeight > 1.f)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
|
|
return 1;
|
|
}
|
|
aParams.OitDepthFactor = aWeight;
|
|
}
|
|
}
|
|
else if (aParam.IsRealValue())
|
|
{
|
|
const Standard_ShortReal aWeight = (Standard_ShortReal) Draw::Atof (theArgVec[anArgIter]);
|
|
if (aWeight < 0.f || aWeight > 1.f)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid value of Weighted Order-Independent Transparency depth weight factor " << aWeight << ". Should be within range [0.0; 1.0]";
|
|
return 1;
|
|
}
|
|
|
|
aParams.TransparencyMethod = Graphic3d_RTM_BLEND_OIT;
|
|
aParams.OitDepthFactor = aWeight;
|
|
}
|
|
else if (aParam == "off")
|
|
{
|
|
aParams.TransparencyMethod = Graphic3d_RTM_BLEND_UNORDERED;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-fonthinting"
|
|
|| aFlag == "-fonthint")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
|
|
{
|
|
theDI << "normal" << " ";
|
|
}
|
|
else if ((aParams.FontHinting & Font_Hinting_Normal) != 0)
|
|
{
|
|
theDI << "light" << " ";
|
|
}
|
|
else
|
|
{
|
|
theDI << "off" << " ";
|
|
}
|
|
continue;
|
|
}
|
|
else if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
|
|
aHintStyle.LowerCase();
|
|
if (aHintStyle == "normal"
|
|
|| aHintStyle == "on"
|
|
|| aHintStyle == "1")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Normal);
|
|
}
|
|
else if (aHintStyle == "light")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_Light);
|
|
}
|
|
else if (aHintStyle == "no"
|
|
|| aHintStyle == "off"
|
|
|| aHintStyle == "0")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Normal);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_Light);
|
|
}
|
|
else
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-fontautohinting"
|
|
|| aFlag == "-fontautohint")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
if ((aParams.FontHinting & Font_Hinting_ForceAutohint) != 0)
|
|
{
|
|
theDI << "force" << " ";
|
|
}
|
|
else if ((aParams.FontHinting & Font_Hinting_NoAutohint) != 0)
|
|
{
|
|
theDI << "disallow" << " ";
|
|
}
|
|
else
|
|
{
|
|
theDI << "auto" << " ";
|
|
}
|
|
continue;
|
|
}
|
|
else if (anArgIter + 1 >= theArgNb)
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aHintStyle (theArgVec[++anArgIter]);
|
|
aHintStyle.LowerCase();
|
|
if (aHintStyle == "force")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_ForceAutohint);
|
|
}
|
|
else if (aHintStyle == "disallow"
|
|
|| aHintStyle == "no")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting | Font_Hinting_NoAutohint);
|
|
}
|
|
else if (aHintStyle == "auto")
|
|
{
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_ForceAutohint);
|
|
aParams.FontHinting = Font_Hinting(aParams.FontHinting & ~Font_Hinting_NoAutohint);
|
|
}
|
|
else
|
|
{
|
|
theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-depthprepass")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.ToEnableDepthPrepass ? "on " : "off ");
|
|
continue;
|
|
}
|
|
aParams.ToEnableDepthPrepass = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableDepthPrepass))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (aFlag == "-samplealphatocoverage"
|
|
|| aFlag == "-alphatocoverage")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.ToEnableAlphaToCoverage ? "on " : "off ");
|
|
continue;
|
|
}
|
|
aParams.ToEnableAlphaToCoverage = Standard_True;
|
|
if (anArgIter + 1 < theArgNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableAlphaToCoverage))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
}
|
|
else if (aFlag == "-rendscale"
|
|
|| aFlag == "-renderscale"
|
|
|| aFlag == "-renderresolutionscale")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.RenderResolutionScale << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Real aScale = Draw::Atof (theArgVec[anArgIter]);
|
|
if (aScale < 0.01)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid rendering resolution scale " << aScale << "";
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
aParams.RenderResolutionScale = Standard_ShortReal(aScale);
|
|
}
|
|
}
|
|
else if (aFlag == "-raydepth"
|
|
|| aFlag == "-ray_depth")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.RaytracingDepth << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aDepth = Draw::Atoi (theArgVec[anArgIter]);
|
|
|
|
// We allow RaytracingDepth be more than 10 in case of GI enabled
|
|
if (aDepth < 1 || (aDepth > 10 && !aParams.IsGlobalIlluminationEnabled))
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid ray-tracing depth " << aDepth << ". Should be within range [1; 10]";
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
aParams.RaytracingDepth = aDepth;
|
|
}
|
|
}
|
|
else if (aFlag == "-shad"
|
|
|| aFlag == "-shadows")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.IsShadowEnabled ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.IsShadowEnabled = toEnable;
|
|
}
|
|
else if (aFlag == "-shadowmapresolution"
|
|
|| aFlag == "-shadowmap")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.ShadowMapResolution << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aParams.ShadowMapResolution = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-shadowmapbias")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.ShadowMapBias << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
aParams.ShadowMapBias = (float )Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-refl"
|
|
|| aFlag == "-reflections")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.IsReflectionEnabled ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.IsReflectionEnabled = toEnable;
|
|
}
|
|
else if (aFlag == "-fsaa")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.IsAntialiasingEnabled ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.IsAntialiasingEnabled = toEnable;
|
|
}
|
|
else if (aFlag == "-gleam")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.IsTransparentShadowEnabled ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.IsTransparentShadowEnabled = toEnable;
|
|
}
|
|
else if (aFlag == "-gi")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.IsGlobalIlluminationEnabled ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.IsGlobalIlluminationEnabled = toEnable;
|
|
if (!toEnable)
|
|
{
|
|
aParams.RaytracingDepth = Min (aParams.RaytracingDepth, 10);
|
|
}
|
|
}
|
|
else if (aFlag == "-blockedrng"
|
|
|| aFlag == "-brng")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.CoherentPathTracingMode ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.CoherentPathTracingMode = toEnable;
|
|
}
|
|
else if (aFlag == "-maxrad")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.RadianceClampingValue << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const TCollection_AsciiString aMaxRadStr = theArgVec[anArgIter];
|
|
if (!aMaxRadStr.IsRealValue (Standard_True))
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Real aMaxRadiance = aMaxRadStr.RealValue();
|
|
if (aMaxRadiance <= 0.0)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid radiance clamping value " << aMaxRadiance;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
aParams.RadianceClampingValue = static_cast<Standard_ShortReal> (aMaxRadiance);
|
|
}
|
|
}
|
|
else if (aFlag == "-iss")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.AdaptiveScreenSampling ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.AdaptiveScreenSampling = toEnable;
|
|
}
|
|
else if (aFlag == "-issatomic")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.AdaptiveScreenSamplingAtomic ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.AdaptiveScreenSamplingAtomic = toEnable;
|
|
}
|
|
else if (aFlag == "-issd")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.ShowSamplingTiles ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.ShowSamplingTiles = toEnable;
|
|
}
|
|
else if (aFlag == "-tilesize")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.RayTracingTileSize << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aTileSize = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aTileSize < 1)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid size of ISS tile " << aTileSize;
|
|
return 1;
|
|
}
|
|
aParams.RayTracingTileSize = aTileSize;
|
|
}
|
|
else if (aFlag == "-nbtiles")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << aParams.NbRayTracingTiles << " ";
|
|
continue;
|
|
}
|
|
else if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aNbTiles = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aNbTiles < -1)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid number of ISS tiles " << aNbTiles;
|
|
return 1;
|
|
}
|
|
else if (aNbTiles > 0
|
|
&& (aNbTiles < 64
|
|
|| aNbTiles > 1024))
|
|
{
|
|
Message::SendWarning() << "Warning: suboptimal number of ISS tiles " << aNbTiles << ". Recommended range: [64, 1024].";
|
|
}
|
|
aParams.NbRayTracingTiles = aNbTiles;
|
|
}
|
|
else if (aFlag == "-env")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.UseEnvironmentMapBackground ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.UseEnvironmentMapBackground = toEnable;
|
|
}
|
|
else if (aFlag == "-ignorenormalmap")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.ToIgnoreNormalMapInRayTracing ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.ToIgnoreNormalMapInRayTracing = toEnable;
|
|
}
|
|
else if (aFlag == "-twoside")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.TwoSidedBsdfModels ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.TwoSidedBsdfModels = toEnable;
|
|
}
|
|
else if (aFlag == "-shademodel"
|
|
|| aFlag == "-shadingmodel"
|
|
|| aFlag == "-shading")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
switch (aView->ShadingModel())
|
|
{
|
|
case Graphic3d_TypeOfShadingModel_DEFAULT: theDI << "default"; break;
|
|
case Graphic3d_TypeOfShadingModel_Unlit: theDI << "unlit "; break;
|
|
case Graphic3d_TypeOfShadingModel_PhongFacet: theDI << "flat "; break;
|
|
case Graphic3d_TypeOfShadingModel_Gouraud: theDI << "gouraud "; break;
|
|
case Graphic3d_TypeOfShadingModel_Phong: theDI << "phong "; break;
|
|
case Graphic3d_TypeOfShadingModel_Pbr: theDI << "pbr"; break;
|
|
case Graphic3d_TypeOfShadingModel_PbrFacet: theDI << "pbr_facet"; break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
}
|
|
|
|
Graphic3d_TypeOfShadingModel aModel = Graphic3d_TypeOfShadingModel_DEFAULT;
|
|
if (ViewerTest::ParseShadingModel (theArgVec[anArgIter], aModel)
|
|
&& aModel != Graphic3d_TypeOfShadingModel_DEFAULT)
|
|
{
|
|
aView->SetShadingModel (aModel);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown shading model '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-pbrenvpow2size"
|
|
|| aFlag == "-pbrenvp2s"
|
|
|| aFlag == "-pep2s")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aPbrEnvPow2Size = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aPbrEnvPow2Size < 1)
|
|
{
|
|
Message::SendFail ("Syntax error: 'Pow2Size' of PBR Environment has to be greater or equal 1");
|
|
return 1;
|
|
}
|
|
aParams.PbrEnvPow2Size = aPbrEnvPow2Size;
|
|
}
|
|
else if (aFlag == "-pbrenvspecmaplevelsnumber"
|
|
|| aFlag == "-pbrenvspecmapnblevels"
|
|
|| aFlag == "-pbrenvspecmaplevels"
|
|
|| aFlag == "-pbrenvsmln"
|
|
|| aFlag == "-pesmln")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aPbrEnvSpecMapNbLevels = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aPbrEnvSpecMapNbLevels < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: 'SpecMapLevelsNumber' of PBR Environment has to be greater or equal 2");
|
|
return 1;
|
|
}
|
|
aParams.PbrEnvSpecMapNbLevels = aPbrEnvSpecMapNbLevels;
|
|
}
|
|
else if (aFlag == "-pbrenvbakngdiffsamplesnumber"
|
|
|| aFlag == "-pbrenvbakingdiffsamples"
|
|
|| aFlag == "-pbrenvbdsn")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aPbrEnvBakingDiffNbSamples = Draw::Atoi (theArgVec[anArgIter]);
|
|
if (aPbrEnvBakingDiffNbSamples < 1)
|
|
{
|
|
Message::SendFail ("Syntax error: 'BakingDiffSamplesNumber' of PBR Environment has to be greater or equal 1");
|
|
return 1;
|
|
}
|
|
aParams.PbrEnvBakingDiffNbSamples = aPbrEnvBakingDiffNbSamples;
|
|
}
|
|
else if (aFlag == "-pbrenvbakngspecsamplesnumber"
|
|
|| aFlag == "-pbrenvbakingspecsamples"
|
|
|| aFlag == "-pbrenvbssn")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aPbrEnvBakingSpecNbSamples = Draw::Atoi(theArgVec[anArgIter]);
|
|
if (aPbrEnvBakingSpecNbSamples < 1)
|
|
{
|
|
Message::SendFail ("Syntax error: 'BakingSpecSamplesNumber' of PBR Environment has to be greater or equal 1");
|
|
return 1;
|
|
}
|
|
aParams.PbrEnvBakingSpecNbSamples = aPbrEnvBakingSpecNbSamples;
|
|
}
|
|
else if (aFlag == "-pbrenvbakingprobability"
|
|
|| aFlag == "-pbrenvbp")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
const Standard_ShortReal aPbrEnvBakingProbability = static_cast<Standard_ShortReal>(Draw::Atof (theArgVec[anArgIter]));
|
|
if (aPbrEnvBakingProbability < 0.f
|
|
|| aPbrEnvBakingProbability > 1.f)
|
|
{
|
|
Message::SendFail ("Syntax error: 'BakingProbability' of PBR Environment has to be in range of [0, 1]");
|
|
return 1;
|
|
}
|
|
aParams.PbrEnvBakingProbability = aPbrEnvBakingProbability;
|
|
}
|
|
else if (aFlag == "-resolution")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aResolution (theArgVec[anArgIter]);
|
|
if (aResolution.IsIntegerValue())
|
|
{
|
|
aView->ChangeRenderingParams().Resolution = static_cast<unsigned int> (Draw::Atoi (aResolution.ToCString()));
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong syntax at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-rebuildglsl"
|
|
|| aFlag == "-rebuild")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << (aParams.RebuildRayTracingShaders ? "on" : "off") << " ";
|
|
continue;
|
|
}
|
|
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (++anArgIter < theArgNb
|
|
&& !Draw::ParseOnOff (theArgVec[anArgIter], toEnable))
|
|
{
|
|
--anArgIter;
|
|
}
|
|
aParams.RebuildRayTracingShaders = toEnable;
|
|
}
|
|
else if (aFlag == "-focal")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aParam (theArgVec[anArgIter]);
|
|
if (aParam.IsRealValue (Standard_True))
|
|
{
|
|
float aFocalDist = static_cast<float> (aParam.RealValue());
|
|
if (aFocalDist < 0)
|
|
{
|
|
Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().CameraFocalPlaneDist = aFocalDist;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-aperture")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aParam(theArgVec[anArgIter]);
|
|
if (aParam.IsRealValue (Standard_True))
|
|
{
|
|
float aApertureSize = static_cast<float> (aParam.RealValue());
|
|
if (aApertureSize < 0)
|
|
{
|
|
Message::SendFail() << "Error: parameter can't be negative at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().CameraApertureRadius = aApertureSize;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-exposure")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString anExposure (theArgVec[anArgIter]);
|
|
if (anExposure.IsRealValue (Standard_True))
|
|
{
|
|
aView->ChangeRenderingParams().Exposure = static_cast<float> (anExposure.RealValue());
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-whitepoint")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aWhitePoint (theArgVec[anArgIter]);
|
|
if (aWhitePoint.IsRealValue (Standard_True))
|
|
{
|
|
aView->ChangeRenderingParams().WhitePoint = static_cast<float> (aWhitePoint.RealValue());
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-tonemapping")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aMode (theArgVec[anArgIter]);
|
|
aMode.LowerCase();
|
|
|
|
if (aMode == "disabled")
|
|
{
|
|
aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Disabled;
|
|
}
|
|
else if (aMode == "filmic")
|
|
{
|
|
aView->ChangeRenderingParams().ToneMappingMethod = Graphic3d_ToneMappingMethod_Filmic;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at argument'" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aFlag == "-performancestats"
|
|
|| aFlag == "-performancecounters"
|
|
|| aFlag == "-perfstats"
|
|
|| aFlag == "-perfcounters"
|
|
|| aFlag == "-stats")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aFlagsStr (theArgVec[anArgIter]);
|
|
aFlagsStr.LowerCase();
|
|
Graphic3d_RenderingParams::PerfCounters aFlags = aView->ChangeRenderingParams().CollectedStats;
|
|
if (!convertToPerfStatsFlags (aFlagsStr, aFlags))
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().CollectedStats = aFlags;
|
|
aView->ChangeRenderingParams().ToShowStats = aFlags != Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
}
|
|
else if (aFlag == "-perfupdateinterval"
|
|
|| aFlag == "-statsupdateinterval")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().StatsUpdateInterval = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-perfchart"
|
|
|| aFlag == "-statschart")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().StatsNbFrames = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-perfchartmax"
|
|
|| aFlag == "-statschartmax")
|
|
{
|
|
if (++anArgIter >= theArgNb)
|
|
{
|
|
Message::SendFail() << "Syntax error at argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
aView->ChangeRenderingParams().StatsMaxChartTime = (Standard_ShortReal )Draw::Atof (theArgVec[anArgIter]);
|
|
}
|
|
else if (aFlag == "-frustumculling"
|
|
|| aFlag == "-culling")
|
|
{
|
|
if (toPrint)
|
|
{
|
|
theDI << ((aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On) ? "on" :
|
|
(aParams.FrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_Off) ? "off" :
|
|
"noUpdate") << " ";
|
|
continue;
|
|
}
|
|
|
|
Graphic3d_RenderingParams::FrustumCulling aState = Graphic3d_RenderingParams::FrustumCulling_On;
|
|
if (++anArgIter < theArgNb)
|
|
{
|
|
TCollection_AsciiString aStateStr(theArgVec[anArgIter]);
|
|
aStateStr.LowerCase();
|
|
bool toEnable = true;
|
|
if (Draw::ParseOnOff (aStateStr.ToCString(), toEnable))
|
|
{
|
|
aState = toEnable ? Graphic3d_RenderingParams::FrustumCulling_On : Graphic3d_RenderingParams::FrustumCulling_Off;
|
|
}
|
|
else if (aStateStr == "noupdate"
|
|
|| aStateStr == "freeze")
|
|
{
|
|
aState = Graphic3d_RenderingParams::FrustumCulling_NoUpdate;
|
|
}
|
|
else
|
|
{
|
|
--anArgIter;
|
|
}
|
|
}
|
|
aParams.FrustumCullingState = aState;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown flag '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// set current view parameters as defaults
|
|
if (toSyncDefaults)
|
|
{
|
|
ViewerTest::GetViewerFromContext()->SetDefaultRenderingParams (aParams);
|
|
}
|
|
if (toSyncAllViews)
|
|
{
|
|
for (V3d_ListOfViewIterator aViewIter = ViewerTest::GetViewerFromContext()->DefinedViewIterator(); aViewIter.More(); aViewIter.Next())
|
|
{
|
|
aViewIter.Value()->ChangeRenderingParams() = aParams;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : searchInfo
|
|
//purpose :
|
|
//=======================================================================
|
|
inline TCollection_AsciiString searchInfo (const TColStd_IndexedDataMapOfStringString& theDict,
|
|
const TCollection_AsciiString& theKey)
|
|
{
|
|
for (TColStd_IndexedDataMapOfStringString::Iterator anIter (theDict); anIter.More(); anIter.Next())
|
|
{
|
|
if (TCollection_AsciiString::IsSameString (anIter.Key(), theKey, Standard_False))
|
|
{
|
|
return anIter.Value();
|
|
}
|
|
}
|
|
return TCollection_AsciiString();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VStatProfiler
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VStatProfiler (Draw_Interpretor& theDI,
|
|
Standard_Integer theArgNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Boolean toRedraw = Standard_True;
|
|
Graphic3d_RenderingParams::PerfCounters aPrevCounters = aView->ChangeRenderingParams().CollectedStats;
|
|
Standard_ShortReal aPrevUpdInterval = aView->ChangeRenderingParams().StatsUpdateInterval;
|
|
Graphic3d_RenderingParams::PerfCounters aRenderParams = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg (theArgVec[anArgIter]);
|
|
TCollection_AsciiString aFlag (anArg);
|
|
aFlag.LowerCase();
|
|
if (aFlag == "-noredraw")
|
|
{
|
|
toRedraw = Standard_False;
|
|
}
|
|
else
|
|
{
|
|
Graphic3d_RenderingParams::PerfCounters aParam = Graphic3d_RenderingParams::PerfCounters_NONE;
|
|
if (aFlag == "fps") aParam = Graphic3d_RenderingParams::PerfCounters_FrameRate;
|
|
else if (aFlag == "cpu") aParam = Graphic3d_RenderingParams::PerfCounters_CPU;
|
|
else if (aFlag == "alllayers"
|
|
|| aFlag == "layers") aParam = Graphic3d_RenderingParams::PerfCounters_Layers;
|
|
else if (aFlag == "allstructs"
|
|
|| aFlag == "allstructures"
|
|
|| aFlag == "structs"
|
|
|| aFlag == "structures") aParam = Graphic3d_RenderingParams::PerfCounters_Structures;
|
|
else if (aFlag == "groups") aParam = Graphic3d_RenderingParams::PerfCounters_Groups;
|
|
else if (aFlag == "allarrays"
|
|
|| aFlag == "fillarrays"
|
|
|| aFlag == "linearrays"
|
|
|| aFlag == "pointarrays"
|
|
|| aFlag == "textarrays") aParam = Graphic3d_RenderingParams::PerfCounters_GroupArrays;
|
|
else if (aFlag == "triangles") aParam = Graphic3d_RenderingParams::PerfCounters_Triangles;
|
|
else if (aFlag == "lines") aParam = Graphic3d_RenderingParams::PerfCounters_Lines;
|
|
else if (aFlag == "points") aParam = Graphic3d_RenderingParams::PerfCounters_Points;
|
|
else if (aFlag == "geommem"
|
|
|| aFlag == "texturemem"
|
|
|| aFlag == "framemem") aParam = Graphic3d_RenderingParams::PerfCounters_EstimMem;
|
|
else if (aFlag == "elapsedframe"
|
|
|| aFlag == "cpuframeaverage"
|
|
|| aFlag == "cpupickingaverage"
|
|
|| aFlag == "cpucullingaverage"
|
|
|| aFlag == "cpudynaverage"
|
|
|| aFlag == "cpuframemax"
|
|
|| aFlag == "cpupickingmax"
|
|
|| aFlag == "cpucullingmax"
|
|
|| aFlag == "cpudynmax") aParam = Graphic3d_RenderingParams::PerfCounters_FrameTime;
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: unknown argument '" << theArgVec[anArgIter] << "'";
|
|
continue;
|
|
}
|
|
|
|
aRenderParams = Graphic3d_RenderingParams::PerfCounters (aRenderParams | aParam);
|
|
}
|
|
}
|
|
|
|
if (aRenderParams != Graphic3d_RenderingParams::PerfCounters_NONE)
|
|
{
|
|
aView->ChangeRenderingParams().CollectedStats =
|
|
Graphic3d_RenderingParams::PerfCounters (aView->RenderingParams().CollectedStats | aRenderParams);
|
|
|
|
if (toRedraw)
|
|
{
|
|
aView->ChangeRenderingParams().StatsUpdateInterval = -1;
|
|
aView->Redraw();
|
|
aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
|
|
}
|
|
|
|
TColStd_IndexedDataMapOfStringString aDict;
|
|
aView->StatisticInformation (aDict);
|
|
|
|
aView->ChangeRenderingParams().CollectedStats = aPrevCounters;
|
|
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg(theArgVec[anArgIter]);
|
|
TCollection_AsciiString aFlag(anArg);
|
|
aFlag.LowerCase();
|
|
if (aFlag == "fps")
|
|
{
|
|
theDI << searchInfo (aDict, "FPS") << " ";
|
|
}
|
|
else if (aFlag == "cpu")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU FPS") << " ";
|
|
}
|
|
else if (aFlag == "alllayers")
|
|
{
|
|
theDI << searchInfo (aDict, "Layers") << " ";
|
|
}
|
|
else if (aFlag == "layers")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered layers") << " ";
|
|
}
|
|
else if (aFlag == "allstructs"
|
|
|| aFlag == "allstructures")
|
|
{
|
|
theDI << searchInfo (aDict, "Structs") << " ";
|
|
}
|
|
else if (aFlag == "structs"
|
|
|| aFlag == "structures")
|
|
{
|
|
TCollection_AsciiString aRend = searchInfo (aDict, "Rendered structs");
|
|
if (aRend.IsEmpty()) // all structures rendered
|
|
{
|
|
aRend = searchInfo (aDict, "Structs");
|
|
}
|
|
theDI << aRend << " ";
|
|
}
|
|
else if (aFlag == "groups")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered groups") << " ";
|
|
}
|
|
else if (aFlag == "allarrays")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered arrays") << " ";
|
|
}
|
|
else if (aFlag == "fillarrays")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered [fill] arrays") << " ";
|
|
}
|
|
else if (aFlag == "linearrays")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered [line] arrays") << " ";
|
|
}
|
|
else if (aFlag == "pointarrays")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered [point] arrays") << " ";
|
|
}
|
|
else if (aFlag == "textarrays")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered [text] arrays") << " ";
|
|
}
|
|
else if (aFlag == "triangles")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered triangles") << " ";
|
|
}
|
|
else if (aFlag == "points")
|
|
{
|
|
theDI << searchInfo (aDict, "Rendered points") << " ";
|
|
}
|
|
else if (aFlag == "geommem")
|
|
{
|
|
theDI << searchInfo (aDict, "GPU Memory [geometry]") << " ";
|
|
}
|
|
else if (aFlag == "texturemem")
|
|
{
|
|
theDI << searchInfo (aDict, "GPU Memory [textures]") << " ";
|
|
}
|
|
else if (aFlag == "framemem")
|
|
{
|
|
theDI << searchInfo (aDict, "GPU Memory [frames]") << " ";
|
|
}
|
|
else if (aFlag == "elapsedframe")
|
|
{
|
|
theDI << searchInfo (aDict, "Elapsed Frame (average)") << " ";
|
|
}
|
|
else if (aFlag == "cpuframe_average")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Frame (average)") << " ";
|
|
}
|
|
else if (aFlag == "cpupicking_average")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Picking (average)") << " ";
|
|
}
|
|
else if (aFlag == "cpuculling_average")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Culling (average)") << " ";
|
|
}
|
|
else if (aFlag == "cpudyn_average")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Dynamics (average)") << " ";
|
|
}
|
|
else if (aFlag == "cpuframe_max")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Frame (max)") << " ";
|
|
}
|
|
else if (aFlag == "cpupicking_max")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Picking (max)") << " ";
|
|
}
|
|
else if (aFlag == "cpuculling_max")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Culling (max)") << " ";
|
|
}
|
|
else if (aFlag == "cpudyn_max")
|
|
{
|
|
theDI << searchInfo (aDict, "CPU Dynamics (max)") << " ";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (toRedraw)
|
|
{
|
|
aView->ChangeRenderingParams().StatsUpdateInterval = -1;
|
|
aView->Redraw();
|
|
aView->ChangeRenderingParams().StatsUpdateInterval = aPrevUpdInterval;
|
|
}
|
|
theDI << "Statistic info:\n" << aView->StatisticInformation();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VXRotate
|
|
//purpose :
|
|
//=======================================================================
|
|
static Standard_Integer VXRotate (Draw_Interpretor& di,
|
|
Standard_Integer argc,
|
|
const char ** argv)
|
|
{
|
|
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
|
if (aContext.IsNull())
|
|
{
|
|
di << argv[0] << "ERROR : use 'vinit' command before \n";
|
|
return 1;
|
|
}
|
|
|
|
if (argc != 3)
|
|
{
|
|
di << "ERROR : Usage : " << argv[0] << " name angle\n";
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aName (argv[1]);
|
|
Standard_Real anAngle = Draw::Atof (argv[2]);
|
|
|
|
// find object
|
|
ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
|
|
Handle(AIS_InteractiveObject) anIObj;
|
|
if (!aMap.Find2 (aName, anIObj))
|
|
{
|
|
di << "Use 'vdisplay' before\n";
|
|
return 1;
|
|
}
|
|
|
|
gp_Trsf aTransform;
|
|
aTransform.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Vec (1.0, 0.0, 0.0)), anAngle);
|
|
aTransform.SetTranslationPart (anIObj->LocalTransformation().TranslationPart());
|
|
|
|
aContext->SetLocation (anIObj, aTransform);
|
|
aContext->UpdateCurrentViewer();
|
|
return 0;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
//! Structure for setting AIS_Manipulator::SetPart() property.
|
|
struct ManipAxisModeOnOff
|
|
{
|
|
Standard_Integer Axis;
|
|
AIS_ManipulatorMode Mode;
|
|
Standard_Boolean ToEnable;
|
|
|
|
ManipAxisModeOnOff() : Axis (-1), Mode (AIS_MM_None), ToEnable (false) {}
|
|
};
|
|
|
|
enum ManipAjustPosition
|
|
{
|
|
ManipAjustPosition_Off,
|
|
ManipAjustPosition_Center,
|
|
ManipAjustPosition_Location,
|
|
ManipAjustPosition_ShapeLocation,
|
|
};
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VManipulator
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VManipulator (Draw_Interpretor& theDi,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
|
|
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
|
|
if (aCurrentView.IsNull()
|
|
|| aViewer.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), ViewerTest::CurrentView());
|
|
Standard_Integer anArgIter = 1;
|
|
Handle(AIS_Manipulator) aManipulator;
|
|
ViewerTest_DoubleMapOfInteractiveAndName& aMapAIS = GetMapOfAIS();
|
|
TCollection_AsciiString aName;
|
|
// parameters
|
|
Standard_Integer toAutoActivate = -1, toFollowTranslation = -1, toFollowRotation = -1, toFollowDragging = -1, isZoomable = -1;
|
|
Standard_Real aGap = -1.0, aSize = -1.0;
|
|
NCollection_Sequence<ManipAxisModeOnOff> aParts;
|
|
gp_XYZ aLocation (RealLast(), RealLast(), RealLast()), aVDir, anXDir;
|
|
//
|
|
bool toDetach = false;
|
|
AIS_Manipulator::OptionsForAttach anAttachOptions;
|
|
Handle(AIS_InteractiveObject) anAttachObject;
|
|
Handle(V3d_View) aViewAffinity;
|
|
ManipAjustPosition anAttachPos = ManipAjustPosition_Off;
|
|
//
|
|
Graphic3d_Vec2i aMousePosFrom(IntegerLast(), IntegerLast());
|
|
Graphic3d_Vec2i aMousePosTo (IntegerLast(), IntegerLast());
|
|
Standard_Integer toStopMouseTransform = -1;
|
|
// explicit transformation
|
|
gp_Trsf aTrsf;
|
|
gp_XYZ aTmpXYZ;
|
|
Standard_Real aTmpReal = 0.0;
|
|
gp_XYZ aRotPnt, aRotAxis;
|
|
for (; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
continue;
|
|
}
|
|
else if (anArg == "-help")
|
|
{
|
|
theDi.PrintHelp (theArgVec[0]);
|
|
return 0;
|
|
}
|
|
//
|
|
else if (anArg == "-autoactivate"
|
|
|| anArg == "-noautoactivate")
|
|
{
|
|
toAutoActivate = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
|
|
}
|
|
else if (anArg == "-followtranslation"
|
|
|| anArg == "-nofollowtranslation")
|
|
{
|
|
toFollowTranslation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
|
|
}
|
|
else if (anArg == "-followrotation"
|
|
|| anArg == "-nofollowrotation")
|
|
{
|
|
toFollowRotation = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
|
|
}
|
|
else if (anArg == "-followdragging"
|
|
|| anArg == "-nofollowdragging")
|
|
{
|
|
toFollowDragging = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
|
|
}
|
|
else if (anArg == "-gap"
|
|
&& anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 1], aGap)
|
|
&& aGap >= 0.0)
|
|
{
|
|
++anArgIter;
|
|
}
|
|
else if (anArg == "-size"
|
|
&& anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 1], aSize)
|
|
&& aSize > 0.0)
|
|
{
|
|
++anArgIter;
|
|
}
|
|
else if ((anArg == "-part" && anArgIter + 3 < theArgsNb)
|
|
|| (anArg == "-parts" && anArgIter + 2 < theArgsNb))
|
|
{
|
|
ManipAxisModeOnOff aPart;
|
|
Standard_Integer aMode = 0;
|
|
if (anArg == "-part")
|
|
{
|
|
if (!Draw::ParseInteger (theArgVec[++anArgIter], aPart.Axis)
|
|
|| aPart.Axis < 0 || aPart.Axis > 3)
|
|
{
|
|
Message::SendFail() << "Syntax error: -part axis '" << theArgVec[anArgIter] << "' is out of range [1, 3]";
|
|
return 1;
|
|
}
|
|
}
|
|
if (!Draw::ParseInteger (theArgVec[++anArgIter], aMode)
|
|
|| aMode < 1 || aMode > 4)
|
|
{
|
|
Message::SendFail() << "Syntax error: -part mode '" << theArgVec[anArgIter] << "' is out of range [1, 4]";
|
|
return 1;
|
|
}
|
|
if (!Draw::ParseOnOff (theArgVec[++anArgIter], aPart.ToEnable))
|
|
{
|
|
Message::SendFail() << "Syntax error: -part value on/off '" << theArgVec[anArgIter] << "' is incorrect";
|
|
return 1;
|
|
}
|
|
aPart.Mode = static_cast<AIS_ManipulatorMode> (aMode);
|
|
aParts.Append (aPart);
|
|
}
|
|
else if (anArg == "-pos"
|
|
&& anArgIter + 3 < theArgsNb
|
|
&& parseXYZ (theArgVec + anArgIter + 1, aLocation))
|
|
{
|
|
anArgIter += 3;
|
|
if (anArgIter + 3 < theArgsNb
|
|
&& parseXYZ (theArgVec + anArgIter + 1, aVDir)
|
|
&& aVDir.Modulus() > Precision::Confusion())
|
|
{
|
|
anArgIter += 3;
|
|
}
|
|
if (anArgIter + 3 < theArgsNb
|
|
&& parseXYZ (theArgVec + anArgIter + 1, anXDir)
|
|
&& anXDir.Modulus() > Precision::Confusion())
|
|
{
|
|
anArgIter += 3;
|
|
}
|
|
}
|
|
else if (anArg == "-zoomable"
|
|
|| anArg == "-notzoomable")
|
|
{
|
|
isZoomable = Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0;
|
|
}
|
|
//
|
|
else if (anArg == "-adjustposition"
|
|
|| anArg == "-noadjustposition")
|
|
{
|
|
anAttachPos = ManipAjustPosition_Center;
|
|
if (anArgIter + 1 < theArgsNb)
|
|
{
|
|
TCollection_AsciiString aPosName (theArgVec[++anArgIter]);
|
|
aPosName.LowerCase();
|
|
if (aPosName == "0")
|
|
{
|
|
anAttachPos = ManipAjustPosition_Off;
|
|
}
|
|
else if (aPosName == "1"
|
|
|| aPosName == "center")
|
|
{
|
|
anAttachPos = ManipAjustPosition_Center;
|
|
}
|
|
else if (aPosName == "transformation"
|
|
|| aPosName == "trsf"
|
|
|| aPosName == "location"
|
|
|| aPosName == "loc")
|
|
{
|
|
anAttachPos = ManipAjustPosition_Location;
|
|
}
|
|
else if (aPosName == "shapelocation"
|
|
|| aPosName == "shapeloc")
|
|
{
|
|
anAttachPos = ManipAjustPosition_ShapeLocation;
|
|
}
|
|
else
|
|
{
|
|
--anArgIter;
|
|
}
|
|
}
|
|
anAttachOptions.SetAdjustPosition (anAttachPos == ManipAjustPosition_Center);
|
|
}
|
|
else if (anArg == "-adjustsize"
|
|
|| anArg == "-noadjustsize")
|
|
{
|
|
anAttachOptions.SetAdjustSize (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
|
|
}
|
|
else if (anArg == "-enablemodes"
|
|
|| anArg == "-enablemodes")
|
|
{
|
|
anAttachOptions.SetEnableModes (Draw::ParseOnOffNoIterator (theArgsNb, theArgVec, anArgIter) ? 1 : 0);
|
|
}
|
|
//
|
|
else if (anArg == "-starttransform"
|
|
&& anArgIter + 2 < theArgsNb
|
|
&& Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosFrom.x())
|
|
&& Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosFrom.y()))
|
|
{
|
|
anArgIter += 2;
|
|
}
|
|
else if (anArg == "-transform"
|
|
&& anArgIter + 2 < theArgsNb
|
|
&& Draw::ParseInteger (theArgVec[anArgIter + 1], aMousePosTo.x())
|
|
&& Draw::ParseInteger (theArgVec[anArgIter + 2], aMousePosTo.y()))
|
|
{
|
|
anArgIter += 2;
|
|
}
|
|
else if (anArg == "-stoptransform")
|
|
{
|
|
toStopMouseTransform = 1;
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& TCollection_AsciiString::IsSameString (theArgVec[anArgIter + 1], "abort", false))
|
|
{
|
|
++anArgIter;
|
|
toStopMouseTransform = 0;
|
|
}
|
|
}
|
|
//
|
|
else if (anArg == "-move"
|
|
&& anArgIter + 3 < theArgsNb
|
|
&& parseXYZ (theArgVec + anArgIter + 1, aTmpXYZ))
|
|
{
|
|
anArgIter += 3;
|
|
aTrsf.SetTranslationPart (aTmpXYZ);
|
|
}
|
|
else if (anArg == "-scale"
|
|
&& anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 1], aTmpReal))
|
|
{
|
|
++anArgIter;
|
|
aTrsf.SetScale (gp_Pnt(), aTmpReal);
|
|
}
|
|
else if (anArg == "-rotate"
|
|
&& anArgIter + 7 < theArgsNb
|
|
&& parseXYZ (theArgVec + anArgIter + 1, aRotPnt)
|
|
&& parseXYZ (theArgVec + anArgIter + 4, aRotAxis)
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 7], aTmpReal))
|
|
{
|
|
anArgIter += 7;
|
|
aTrsf.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aTmpReal);
|
|
}
|
|
//
|
|
else if (anArg == "-detach")
|
|
{
|
|
toDetach = true;
|
|
}
|
|
else if (anArg == "-attach"
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
TCollection_AsciiString anObjName (theArgVec[++anArgIter]);
|
|
if (!aMapAIS.Find2 (anObjName, anAttachObject))
|
|
{
|
|
Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' does not exist";
|
|
return 1;
|
|
}
|
|
|
|
for (ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIter (aMapAIS); anIter.More(); anIter.Next())
|
|
{
|
|
Handle(AIS_Manipulator) aManip = Handle(AIS_Manipulator)::DownCast (anIter.Key1());
|
|
if (!aManip.IsNull()
|
|
&& aManip->IsAttached()
|
|
&& aManip->Object() == anAttachObject)
|
|
{
|
|
Message::SendFail() << "Syntax error: AIS object '" << anObjName << "' already has manipulator";
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else if (anArg == "-view"
|
|
&& anArgIter + 1 < theArgsNb
|
|
&& aViewAffinity.IsNull())
|
|
{
|
|
TCollection_AsciiString aViewString (theArgVec[++anArgIter]);
|
|
if (aViewString == "active")
|
|
{
|
|
aViewAffinity = ViewerTest::CurrentView();
|
|
}
|
|
else // Check view name
|
|
{
|
|
ViewerTest_Names aViewNames (aViewString);
|
|
if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong view name '" << aViewString << "'";
|
|
return 1;
|
|
}
|
|
aViewAffinity = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
|
|
if (aViewAffinity.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: cannot find view with name '" << aViewString << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else if (aName.IsEmpty())
|
|
{
|
|
aName = theArgVec[anArgIter];
|
|
if (!aMapAIS.IsBound2 (aName))
|
|
{
|
|
aManipulator = new AIS_Manipulator();
|
|
aManipulator->SetModeActivationOnDetection (true);
|
|
aMapAIS.Bind (aManipulator, aName);
|
|
}
|
|
else
|
|
{
|
|
aManipulator = Handle(AIS_Manipulator)::DownCast (aMapAIS.Find2 (aName));
|
|
if (aManipulator.IsNull())
|
|
{
|
|
Message::SendFail() << "Syntax error: \"" << aName << "\" is not an AIS manipulator";
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
theDi << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
|
|
}
|
|
}
|
|
|
|
if (aName.IsEmpty())
|
|
{
|
|
Message::SendFail ("Syntax error: please specify AIS manipulator's name as the first argument");
|
|
return 1;
|
|
}
|
|
if (!toDetach
|
|
&& aManipulator.IsNull())
|
|
{
|
|
aManipulator = new AIS_Manipulator();
|
|
aManipulator->SetModeActivationOnDetection (true);
|
|
aMapAIS.Bind (aManipulator, aName);
|
|
}
|
|
|
|
// -----------------------------------------
|
|
// change properties of manipulator instance
|
|
// -----------------------------------------
|
|
|
|
if (toAutoActivate != -1)
|
|
{
|
|
aManipulator->SetModeActivationOnDetection (toAutoActivate == 1);
|
|
}
|
|
if (toFollowTranslation != -1)
|
|
{
|
|
aManipulator->ChangeTransformBehavior().SetFollowTranslation (toFollowTranslation == 1);
|
|
}
|
|
if (toFollowRotation != -1)
|
|
{
|
|
aManipulator->ChangeTransformBehavior().SetFollowRotation (toFollowRotation == 1);
|
|
}
|
|
if (toFollowDragging != -1)
|
|
{
|
|
aManipulator->ChangeTransformBehavior().SetFollowDragging (toFollowDragging == 1);
|
|
}
|
|
if (aGap >= 0.0f)
|
|
{
|
|
aManipulator->SetGap ((float )aGap);
|
|
}
|
|
|
|
for (NCollection_Sequence<ManipAxisModeOnOff>::Iterator aPartIter (aParts); aPartIter.More(); aPartIter.Next())
|
|
{
|
|
const ManipAxisModeOnOff& aPart = aPartIter.Value();
|
|
if (aPart.Axis == -1)
|
|
{
|
|
aManipulator->SetPart (aPart.Mode, aPart.ToEnable);
|
|
}
|
|
else
|
|
{
|
|
aManipulator->SetPart (aPart.Axis, aPart.Mode, aPart.ToEnable);
|
|
}
|
|
}
|
|
|
|
if (aSize > 0.0)
|
|
{
|
|
aManipulator->SetSize ((float )aSize);
|
|
}
|
|
if (isZoomable != -1)
|
|
{
|
|
aManipulator->SetZoomPersistence (isZoomable == 0);
|
|
|
|
if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
|
|
{
|
|
ViewerTest::GetAISContext()->Remove (aManipulator, Standard_False);
|
|
ViewerTest::GetAISContext()->Display (aManipulator, Standard_False);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------
|
|
// detach existing manipulator object
|
|
// ----------------------------------
|
|
|
|
if (toDetach)
|
|
{
|
|
aManipulator->Detach();
|
|
aMapAIS.UnBind2 (aName);
|
|
ViewerTest::GetAISContext()->Remove (aManipulator, false);
|
|
}
|
|
|
|
// ---------------------------------------------------
|
|
// attach, detach or access manipulator from an object
|
|
// ---------------------------------------------------
|
|
|
|
if (!anAttachObject.IsNull())
|
|
{
|
|
aManipulator->Attach (anAttachObject, anAttachOptions);
|
|
}
|
|
if (!aViewAffinity.IsNull())
|
|
{
|
|
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), false);
|
|
}
|
|
ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aViewAffinity, true);
|
|
}
|
|
|
|
if (anAttachPos != ManipAjustPosition_Off
|
|
&& aManipulator->IsAttached()
|
|
&& (anAttachObject.IsNull() || anAttachPos != ManipAjustPosition_Center))
|
|
{
|
|
gp_Ax2 aPosition = gp::XOY();
|
|
const gp_Trsf aBaseTrsf = aManipulator->Object()->LocalTransformation();
|
|
switch (anAttachPos)
|
|
{
|
|
case ManipAjustPosition_Off:
|
|
{
|
|
break;
|
|
}
|
|
case ManipAjustPosition_Location:
|
|
{
|
|
aPosition = gp::XOY().Transformed (aBaseTrsf);
|
|
break;
|
|
}
|
|
case ManipAjustPosition_ShapeLocation:
|
|
{
|
|
if (Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast (aManipulator->Object()))
|
|
{
|
|
aPosition = gp::XOY().Transformed (aBaseTrsf * aShapePrs->Shape().Location());
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: manipulator is not attached to shape";
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
case ManipAjustPosition_Center:
|
|
{
|
|
Bnd_Box aBox;
|
|
for (AIS_ManipulatorObjectSequence::Iterator anObjIter (*aManipulator->Objects()); anObjIter.More(); anObjIter.Next())
|
|
{
|
|
Bnd_Box anObjBox;
|
|
anObjIter.Value()->BoundingBox (anObjBox);
|
|
aBox.Add (anObjBox);
|
|
}
|
|
aBox = aBox.FinitePart();
|
|
if (!aBox.IsVoid())
|
|
{
|
|
const gp_Pnt aCenter = (aBox.CornerMin().XYZ() + aBox.CornerMax().XYZ()) * 0.5;
|
|
aPosition.SetLocation (aCenter);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
aManipulator->SetPosition (aPosition);
|
|
}
|
|
if (!Precision::IsInfinite (aLocation.X()))
|
|
{
|
|
if (aVDir.Modulus() <= Precision::Confusion())
|
|
{
|
|
aVDir = aManipulator->Position().Direction().XYZ();
|
|
}
|
|
if (anXDir.Modulus() <= Precision::Confusion())
|
|
{
|
|
anXDir = aManipulator->Position().XDirection().XYZ();
|
|
}
|
|
aManipulator->SetPosition (gp_Ax2 (gp_Pnt (aLocation), gp_Dir (aVDir), gp_Dir (anXDir)));
|
|
}
|
|
|
|
// --------------------------------------
|
|
// apply transformation using manipulator
|
|
// --------------------------------------
|
|
|
|
if (aMousePosFrom.x() != IntegerLast())
|
|
{
|
|
aManipulator->StartTransform (aMousePosFrom.x(), aMousePosFrom.y(), ViewerTest::CurrentView());
|
|
}
|
|
if (aMousePosTo.x() != IntegerLast())
|
|
{
|
|
aManipulator->Transform (aMousePosTo.x(), aMousePosTo.y(), ViewerTest::CurrentView());
|
|
}
|
|
if (toStopMouseTransform != -1)
|
|
{
|
|
aManipulator->StopTransform (toStopMouseTransform == 1);
|
|
}
|
|
|
|
if (aTrsf.Form() != gp_Identity)
|
|
{
|
|
aManipulator->Transform (aTrsf);
|
|
}
|
|
|
|
if (ViewerTest::GetAISContext()->IsDisplayed (aManipulator))
|
|
{
|
|
ViewerTest::GetAISContext()->Redisplay (aManipulator, true);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VSelectionProperties
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VSelectionProperties (Draw_Interpretor& theDi,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext();
|
|
if (aCtx.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (TCollection_AsciiString (theArgVec[0]) == "vhighlightselected")
|
|
{
|
|
// handle obsolete alias
|
|
bool toEnable = true;
|
|
if (theArgsNb < 2)
|
|
{
|
|
theDi << (aCtx->ToHilightSelected() ? "on" : "off");
|
|
return 0;
|
|
}
|
|
else if (theArgsNb != 2
|
|
|| !Draw::ParseOnOff (theArgVec[1], toEnable))
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of parameters");
|
|
return 1;
|
|
}
|
|
if (toEnable != aCtx->ToHilightSelected())
|
|
{
|
|
aCtx->ClearDetected();
|
|
aCtx->SetToHilightSelected (toEnable);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Standard_Boolean toPrint = theArgsNb == 1;
|
|
Standard_Boolean toRedraw = Standard_False;
|
|
Standard_Integer anArgIter = 1;
|
|
Prs3d_TypeOfHighlight aType = Prs3d_TypeOfHighlight_None;
|
|
if (anArgIter < theArgsNb)
|
|
{
|
|
TCollection_AsciiString anArgFirst (theArgVec[anArgIter]);
|
|
anArgFirst.LowerCase();
|
|
++anArgIter;
|
|
if (anArgFirst == "dynhighlight"
|
|
|| anArgFirst == "dynhilight"
|
|
|| anArgFirst == "dynamichighlight"
|
|
|| anArgFirst == "dynamichilight")
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Dynamic;
|
|
}
|
|
else if (anArgFirst == "localdynhighlight"
|
|
|| anArgFirst == "localdynhilight"
|
|
|| anArgFirst == "localdynamichighlight"
|
|
|| anArgFirst == "localdynamichilight")
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_LocalDynamic;
|
|
}
|
|
else if (anArgFirst == "selhighlight"
|
|
|| anArgFirst == "selhilight"
|
|
|| anArgFirst == "selectedhighlight"
|
|
|| anArgFirst == "selectedhilight")
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Selected;
|
|
}
|
|
else if (anArgFirst == "localselhighlight"
|
|
|| anArgFirst == "localselhilight"
|
|
|| anArgFirst == "localselectedhighlight"
|
|
|| anArgFirst == "localselectedhilight")
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_LocalSelected;
|
|
}
|
|
else
|
|
{
|
|
--anArgIter;
|
|
}
|
|
}
|
|
for (; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anArg == "-help")
|
|
{
|
|
theDi.PrintHelp (theArgVec[0]);
|
|
return 0;
|
|
}
|
|
else if (anArg == "-print")
|
|
{
|
|
toPrint = Standard_True;
|
|
}
|
|
else if (anArg == "-autoactivate")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aCtx->SetAutoActivateSelection (toEnable);
|
|
}
|
|
else if (anArg == "-automatichighlight"
|
|
|| anArg == "-automatichilight"
|
|
|| anArg == "-autohighlight"
|
|
|| anArg == "-autohilight")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aCtx->ClearSelected (false);
|
|
aCtx->ClearDetected();
|
|
aCtx->SetAutomaticHilight (toEnable);
|
|
toRedraw = true;
|
|
}
|
|
else if (anArg == "-highlightselected"
|
|
|| anArg == "-hilightselected")
|
|
{
|
|
Standard_Boolean toEnable = Standard_True;
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aCtx->ClearDetected();
|
|
aCtx->SetToHilightSelected (toEnable);
|
|
toRedraw = true;
|
|
}
|
|
else if (anArg == "-pickstrategy"
|
|
|| anArg == "-pickingstrategy")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
SelectMgr_PickingStrategy aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
|
|
TCollection_AsciiString aVal (theArgVec[anArgIter]);
|
|
aVal.LowerCase();
|
|
if (aVal == "first"
|
|
|| aVal == "firstaccepted"
|
|
|| aVal == "firstacceptable")
|
|
{
|
|
aStrategy = SelectMgr_PickingStrategy_FirstAcceptable;
|
|
}
|
|
else if (aVal == "topmost"
|
|
|| aVal == "onlyTopmost")
|
|
{
|
|
aStrategy = SelectMgr_PickingStrategy_OnlyTopmost;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown picking strategy '" << aVal << "'";
|
|
return 1;
|
|
}
|
|
|
|
aCtx->SetPickingStrategy (aStrategy);
|
|
}
|
|
else if (anArg == "-pixtol"
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
aCtx->SetPixelTolerance (Draw::Atoi (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArg == "-preferclosest")
|
|
{
|
|
bool toPreferClosest = true;
|
|
if (anArgIter + 1 < theArgsNb
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toPreferClosest))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
aCtx->MainSelector()->SetPickClosest (toPreferClosest);
|
|
}
|
|
else if ((anArg == "-depthtol"
|
|
|| anArg == "-depthtolerance")
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
TCollection_AsciiString aTolType (theArgVec[++anArgIter]);
|
|
aTolType.LowerCase();
|
|
if (aTolType == "uniform")
|
|
{
|
|
if (anArgIter + 1 >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number of arguments";
|
|
return 1;
|
|
}
|
|
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_Uniform,
|
|
Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (aTolType == "uniformpx")
|
|
{
|
|
if (anArgIter + 1 >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number of arguments";
|
|
return 1;
|
|
}
|
|
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_UniformPixels,
|
|
Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (aTolType == "sensfactor")
|
|
{
|
|
aCtx->MainSelector()->SetDepthTolerance (SelectMgr_TypeOfDepthTolerance_SensitivityFactor, 0.0);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << aTolType << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if ((anArg == "-mode"
|
|
|| anArg == "-dispmode")
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
if (aType == Prs3d_TypeOfHighlight_None)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Integer aDispMode = Draw::Atoi (theArgVec[++anArgIter]);
|
|
const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
|
|
aStyle->SetDisplayMode (aDispMode);
|
|
toRedraw = Standard_True;
|
|
}
|
|
else if (anArg == "-layer"
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
if (aType == Prs3d_TypeOfHighlight_None)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
++anArgIter;
|
|
Graphic3d_ZLayerId aNewLayer = Graphic3d_ZLayerId_UNKNOWN;
|
|
if (!ViewerTest::ParseZLayer (theArgVec[anArgIter], aNewLayer))
|
|
{
|
|
Message::SendFail() << "Syntax error at " << theArgVec[anArgIter];
|
|
return 1;
|
|
}
|
|
|
|
const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
|
|
aStyle->SetZLayer (aNewLayer);
|
|
toRedraw = Standard_True;
|
|
}
|
|
else if (anArg == "-hicolor"
|
|
|| anArg == "-selcolor"
|
|
|| anArg == "-color")
|
|
{
|
|
if (anArg.StartsWith ("-hi"))
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Dynamic;
|
|
}
|
|
else if (anArg.StartsWith ("-sel"))
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Selected;
|
|
}
|
|
else if (aType == Prs3d_TypeOfHighlight_None)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
Quantity_Color aColor;
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theArgsNb - anArgIter - 1,
|
|
theArgVec + anArgIter + 1,
|
|
aColor);
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail ("Syntax error: need more arguments");
|
|
return 1;
|
|
}
|
|
anArgIter += aNbParsed;
|
|
|
|
const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
|
|
aStyle->SetColor (aColor);
|
|
toRedraw = Standard_True;
|
|
}
|
|
else if ((anArg == "-transp"
|
|
|| anArg == "-transparency"
|
|
|| anArg == "-hitransp"
|
|
|| anArg == "-seltransp"
|
|
|| anArg == "-hitransplocal"
|
|
|| anArg == "-seltransplocal")
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
if (anArg.StartsWith ("-hi"))
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Dynamic;
|
|
}
|
|
else if (anArg.StartsWith ("-sel"))
|
|
{
|
|
aType = Prs3d_TypeOfHighlight_Selected;
|
|
}
|
|
else if (aType == Prs3d_TypeOfHighlight_None)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
const Standard_Real aTransp = Draw::Atof (theArgVec[++anArgIter]);
|
|
const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
|
|
aStyle->SetTransparency ((Standard_ShortReal )aTransp);
|
|
toRedraw = Standard_True;
|
|
}
|
|
else if ((anArg == "-mat"
|
|
|| anArg == "-material")
|
|
&& anArgIter + 1 < theArgsNb)
|
|
{
|
|
if (aType == Prs3d_TypeOfHighlight_None)
|
|
{
|
|
Message::SendFail ("Syntax error: type of highlighting is undefined");
|
|
return 1;
|
|
}
|
|
|
|
const Handle(Prs3d_Drawer)& aStyle = aCtx->HighlightStyle (aType);
|
|
Graphic3d_NameOfMaterial aMatName = Graphic3d_MaterialAspect::MaterialFromName (theArgVec[anArgIter + 1]);
|
|
if (aMatName != Graphic3d_NameOfMaterial_DEFAULT)
|
|
{
|
|
++anArgIter;
|
|
Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
|
|
*anAspect = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
|
|
Graphic3d_MaterialAspect aMat (aMatName);
|
|
aMat.SetColor (aStyle->Color());
|
|
aMat.SetTransparency (aStyle->Transparency());
|
|
anAspect->SetFrontMaterial (aMat);
|
|
anAspect->SetInteriorColor (aStyle->Color());
|
|
aStyle->SetBasicFillAreaAspect (anAspect);
|
|
}
|
|
else
|
|
{
|
|
aStyle->SetBasicFillAreaAspect (Handle(Graphic3d_AspectFillArea3d)());
|
|
}
|
|
toRedraw = Standard_True;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (toPrint)
|
|
{
|
|
const Handle(Prs3d_Drawer)& aHiStyle = aCtx->HighlightStyle();
|
|
const Handle(Prs3d_Drawer)& aSelStyle = aCtx->SelectionStyle();
|
|
theDi << "Auto-activation : " << (aCtx->GetAutoActivateSelection() ? "On" : "Off") << "\n";
|
|
theDi << "Auto-highlight : " << (aCtx->AutomaticHilight() ? "On" : "Off") << "\n";
|
|
theDi << "Highlight selected : " << (aCtx->ToHilightSelected() ? "On" : "Off") << "\n";
|
|
theDi << "Selection pixel tolerance : " << aCtx->MainSelector()->PixelTolerance() << "\n";
|
|
theDi << "Selection color : " << Quantity_Color::StringName (aSelStyle->Color().Name()) << "\n";
|
|
theDi << "Dynamic highlight color : " << Quantity_Color::StringName (aHiStyle->Color().Name()) << "\n";
|
|
theDi << "Selection transparency : " << aSelStyle->Transparency() << "\n";
|
|
theDi << "Dynamic highlight transparency : " << aHiStyle->Transparency() << "\n";
|
|
theDi << "Selection mode : " << aSelStyle->DisplayMode() << "\n";
|
|
theDi << "Dynamic highlight mode : " << aHiStyle->DisplayMode() << "\n";
|
|
theDi << "Selection layer : " << aSelStyle->ZLayer() << "\n";
|
|
theDi << "Dynamic layer : " << aHiStyle->ZLayer() << "\n";
|
|
}
|
|
|
|
if (aCtx->NbSelected() != 0 && toRedraw)
|
|
{
|
|
aCtx->HilightSelected (Standard_True);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VDumpSelectionImage
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VDumpSelectionImage (Draw_Interpretor& /*theDi*/,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (aContext.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aFile;
|
|
StdSelect_TypeOfSelectionImage aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
|
|
Handle(Graphic3d_Camera) aCustomCam;
|
|
Image_Format anImgFormat = Image_Format_BGR;
|
|
Standard_Integer aPickedIndex = 1;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString aParam (theArgVec[anArgIter]);
|
|
aParam.LowerCase();
|
|
if (aParam == "-type")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number parameters of flag '-type'");
|
|
return 1;
|
|
}
|
|
|
|
TCollection_AsciiString aValue (theArgVec[anArgIter]);
|
|
aValue.LowerCase();
|
|
if (aValue == "depth"
|
|
|| aValue == "normdepth"
|
|
|| aValue == "normalizeddepth")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_NormalizedDepth;
|
|
anImgFormat = Image_Format_GrayF;
|
|
}
|
|
else if (aValue == "depthinverted"
|
|
|| aValue == "normdepthinverted"
|
|
|| aValue == "normalizeddepthinverted"
|
|
|| aValue == "inverted")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_NormalizedDepthInverted;
|
|
anImgFormat = Image_Format_GrayF;
|
|
}
|
|
else if (aValue == "unnormdepth"
|
|
|| aValue == "unnormalizeddepth")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_UnnormalizedDepth;
|
|
anImgFormat = Image_Format_GrayF;
|
|
}
|
|
else if (aValue == "objectcolor"
|
|
|| aValue == "object"
|
|
|| aValue == "color")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_ColoredDetectedObject;
|
|
}
|
|
else if (aValue == "entitycolor"
|
|
|| aValue == "entity")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_ColoredEntity;
|
|
}
|
|
else if (aValue == "entitytypecolor"
|
|
|| aValue == "entitytype")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_ColoredEntityType;
|
|
}
|
|
else if (aValue == "ownercolor"
|
|
|| aValue == "owner")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_ColoredOwner;
|
|
}
|
|
else if (aValue == "selectionmodecolor"
|
|
|| aValue == "selectionmode"
|
|
|| aValue == "selmodecolor"
|
|
|| aValue == "selmode")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_ColoredSelectionMode;
|
|
}
|
|
else if (aValue == "surfnormal"
|
|
|| aValue == "surfacenormal"
|
|
|| aValue == "normal")
|
|
{
|
|
aType = StdSelect_TypeOfSelectionImage_SurfaceNormal;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown type '" << aValue << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else if (aParam == "-picked"
|
|
|| aParam == "-pickeddepth"
|
|
|| aParam == "-pickedindex")
|
|
{
|
|
if (++anArgIter >= theArgsNb)
|
|
{
|
|
Message::SendFail() << "Syntax error: wrong number parameters at '" << aParam << "'";
|
|
return 1;
|
|
}
|
|
|
|
aPickedIndex = Draw::Atoi (theArgVec[anArgIter]);
|
|
}
|
|
else if (anArgIter + 1 < theArgsNb
|
|
&& aParam == "-xrpose")
|
|
{
|
|
TCollection_AsciiString anXRArg (theArgVec[++anArgIter]);
|
|
anXRArg.LowerCase();
|
|
if (anXRArg == "base")
|
|
{
|
|
aCustomCam = aView->View()->BaseXRCamera();
|
|
}
|
|
else if (anXRArg == "head")
|
|
{
|
|
aCustomCam = aView->View()->PosedXRCamera();
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown XR pose '" << anXRArg << "'";
|
|
return 1;
|
|
}
|
|
if (aCustomCam.IsNull())
|
|
{
|
|
Message::SendFail() << "Error: undefined XR pose";
|
|
return 0;
|
|
}
|
|
}
|
|
else if (aFile.IsEmpty())
|
|
{
|
|
aFile = theArgVec[anArgIter];
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
if (aFile.IsEmpty())
|
|
{
|
|
Message::SendFail ("Syntax error: image file name is missing");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer aWidth = 0, aHeight = 0;
|
|
aView->Window()->Size (aWidth, aHeight);
|
|
|
|
Image_AlienPixMap aPixMap;
|
|
if (!aPixMap.InitZero (anImgFormat, aWidth, aHeight))
|
|
{
|
|
Message::SendFail ("Error: can't allocate image");
|
|
return 1;
|
|
}
|
|
|
|
const bool wasImmUpdate = aView->SetImmediateUpdate (false);
|
|
Handle(Graphic3d_Camera) aCamBack = aView->Camera();
|
|
if (!aCustomCam.IsNull())
|
|
{
|
|
aView->SetCamera (aCustomCam);
|
|
}
|
|
if (!aContext->MainSelector()->ToPixMap (aPixMap, aView, aType, aPickedIndex))
|
|
{
|
|
Message::SendFail ("Error: can't generate selection image");
|
|
return 1;
|
|
}
|
|
if (!aCustomCam.IsNull())
|
|
{
|
|
aView->SetCamera (aCamBack);
|
|
}
|
|
aView->SetImmediateUpdate (wasImmUpdate);
|
|
|
|
if (!aPixMap.Save (aFile))
|
|
{
|
|
Message::SendFail ("Error: can't save selection image");
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VViewCube
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VViewCube (Draw_Interpretor& ,
|
|
Standard_Integer theNbArgs,
|
|
const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext)& aContext = ViewerTest::GetAISContext();
|
|
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
|
|
if (aContext.IsNull() || aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
else if (theNbArgs < 2)
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number arguments");
|
|
return 1;
|
|
}
|
|
|
|
Handle(AIS_ViewCube) aViewCube;
|
|
ViewerTest_AutoUpdater anUpdateTool (aContext, aView);
|
|
Quantity_Color aColorRgb;
|
|
TCollection_AsciiString aName;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
if (anUpdateTool.parseRedrawMode (anArg))
|
|
{
|
|
//
|
|
}
|
|
else if (aViewCube.IsNull())
|
|
{
|
|
aName = theArgVec[anArgIter];
|
|
if (aName.StartsWith ("-"))
|
|
{
|
|
Message::SendFail ("Syntax error: object name should be specified");
|
|
return 1;
|
|
}
|
|
Handle(AIS_InteractiveObject) aPrs;
|
|
GetMapOfAIS().Find2 (aName, aPrs);
|
|
aViewCube = Handle(AIS_ViewCube)::DownCast (aPrs);
|
|
if (aViewCube.IsNull())
|
|
{
|
|
aViewCube = new AIS_ViewCube();
|
|
aViewCube->SetBoxColor (Quantity_NOC_GRAY50);
|
|
aViewCube->SetViewAnimation (ViewerTest::CurrentEventManager()->ViewAnimation());
|
|
aViewCube->SetFixedAnimationLoop (false);
|
|
}
|
|
}
|
|
else if (anArg == "-reset")
|
|
{
|
|
aViewCube->ResetStyles();
|
|
}
|
|
else if (anArg == "-color"
|
|
|| anArg == "-boxcolor"
|
|
|| anArg == "-boxsidecolor"
|
|
|| anArg == "-sidecolor"
|
|
|| anArg == "-boxedgecolor"
|
|
|| anArg == "-edgecolor"
|
|
|| anArg == "-boxcornercolor"
|
|
|| anArg == "-cornercolor"
|
|
|| anArg == "-innercolor"
|
|
|| anArg == "-textcolor"
|
|
|| anArg == "-xaxistextcolor"
|
|
|| anArg == "-yaxistextcolor"
|
|
|| anArg == "-zaxistextcolor")
|
|
{
|
|
Standard_Integer aNbParsed = Draw::ParseColor (theNbArgs - anArgIter - 1,
|
|
theArgVec + anArgIter + 1,
|
|
aColorRgb);
|
|
if (aNbParsed == 0)
|
|
{
|
|
Message::SendFail() << "Syntax error at '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
anArgIter += aNbParsed;
|
|
if (anArg == "-boxcolor")
|
|
{
|
|
aViewCube->SetBoxColor (aColorRgb);
|
|
}
|
|
else if (anArg == "-boxsidecolor"
|
|
|| anArg == "-sidecolor")
|
|
{
|
|
aViewCube->BoxSideStyle()->SetColor (aColorRgb);
|
|
aViewCube->SynchronizeAspects();
|
|
}
|
|
else if (anArg == "-boxedgecolor"
|
|
|| anArg == "-edgecolor")
|
|
{
|
|
aViewCube->BoxEdgeStyle()->SetColor (aColorRgb);
|
|
aViewCube->SynchronizeAspects();
|
|
}
|
|
else if (anArg == "-boxcornercolor"
|
|
|| anArg == "-cornercolor")
|
|
{
|
|
aViewCube->BoxCornerStyle()->SetColor (aColorRgb);
|
|
aViewCube->SynchronizeAspects();
|
|
}
|
|
else if (anArg == "-innercolor")
|
|
{
|
|
aViewCube->SetInnerColor (aColorRgb);
|
|
}
|
|
else if (anArg == "-textcolor")
|
|
{
|
|
aViewCube->SetTextColor (aColorRgb);
|
|
}
|
|
else if (anArg == "-xaxistextcolor"
|
|
|| anArg == "-yaxistextcolor"
|
|
|| anArg == "-zaxistextcolor")
|
|
{
|
|
Prs3d_DatumParts aDatum = anArg.Value (2) == 'x'
|
|
? Prs3d_DatumParts_XAxis
|
|
: (anArg.Value (2) == 'y'
|
|
? Prs3d_DatumParts_YAxis
|
|
: Prs3d_DatumParts_ZAxis);
|
|
aViewCube->Attributes()->SetOwnDatumAspects();
|
|
aViewCube->Attributes()->DatumAspect()->TextAspect (aDatum)->SetColor (aColorRgb);
|
|
}
|
|
else
|
|
{
|
|
aViewCube->SetColor (aColorRgb);
|
|
}
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-transparency"
|
|
|| anArg == "-boxtransparency"))
|
|
{
|
|
const Standard_Real aValue = Draw::Atof (theArgVec[++anArgIter]);
|
|
if (aValue < 0.0 || aValue > 1.0)
|
|
{
|
|
Message::SendFail() << "Syntax error: invalid transparency value " << theArgVec[anArgIter];
|
|
return 1;
|
|
}
|
|
|
|
if (anArg == "-boxtransparency")
|
|
{
|
|
aViewCube->SetBoxTransparency (aValue);
|
|
}
|
|
else
|
|
{
|
|
aViewCube->SetTransparency (aValue);
|
|
}
|
|
}
|
|
else if (anArg == "-axes"
|
|
|| anArg == "-edges"
|
|
|| anArg == "-vertices"
|
|
|| anArg == "-vertexes"
|
|
|| anArg == "-fixedanimation")
|
|
{
|
|
bool toShow = true;
|
|
if (anArgIter + 1 < theNbArgs
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], toShow))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
if (anArg == "-fixedanimation")
|
|
{
|
|
aViewCube->SetFixedAnimationLoop (toShow);
|
|
}
|
|
else if (anArg == "-axes")
|
|
{
|
|
aViewCube->SetDrawAxes (toShow);
|
|
}
|
|
else if (anArg == "-edges")
|
|
{
|
|
aViewCube->SetDrawEdges (toShow);
|
|
}
|
|
else
|
|
{
|
|
aViewCube->SetDrawVertices (toShow);
|
|
}
|
|
}
|
|
else if (anArg == "-yup"
|
|
|| anArg == "-zup")
|
|
{
|
|
bool isOn = true;
|
|
if (anArgIter + 1 < theNbArgs
|
|
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isOn))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
if (anArg == "-yup")
|
|
{
|
|
aViewCube->SetYup (isOn);
|
|
}
|
|
else
|
|
{
|
|
aViewCube->SetYup (!isOn);
|
|
}
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-font")
|
|
{
|
|
aViewCube->SetFont (theArgVec[++anArgIter]);
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-fontheight")
|
|
{
|
|
aViewCube->SetFontHeight (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-size"
|
|
|| anArg == "-boxsize"))
|
|
{
|
|
aViewCube->SetSize (Draw::Atof (theArgVec[++anArgIter]),
|
|
anArg != "-boxsize");
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-boxfacet"
|
|
|| anArg == "-boxfacetextension"
|
|
|| anArg == "-facetextension"
|
|
|| anArg == "-extension"))
|
|
{
|
|
aViewCube->SetBoxFacetExtension (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-boxedgegap"
|
|
|| anArg == "-edgegap"))
|
|
{
|
|
aViewCube->SetBoxEdgeGap (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-boxedgeminsize"
|
|
|| anArg == "-edgeminsize"))
|
|
{
|
|
aViewCube->SetBoxEdgeMinSize (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& (anArg == "-boxcornerminsize"
|
|
|| anArg == "-cornerminsize"))
|
|
{
|
|
aViewCube->SetBoxCornerMinSize (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-axespadding")
|
|
{
|
|
aViewCube->SetAxesPadding (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-roundradius")
|
|
{
|
|
aViewCube->SetRoundRadius (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-duration")
|
|
{
|
|
aViewCube->SetDuration (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-axesradius")
|
|
{
|
|
aViewCube->SetAxesRadius (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-axesconeradius")
|
|
{
|
|
aViewCube->SetAxesConeRadius (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else if (anArgIter + 1 < theNbArgs
|
|
&& anArg == "-axessphereradius")
|
|
{
|
|
aViewCube->SetAxesSphereRadius (Draw::Atof (theArgVec[++anArgIter]));
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
if (aViewCube.IsNull())
|
|
{
|
|
Message::SendFail ("Syntax error: wrong number of arguments");
|
|
return 1;
|
|
}
|
|
|
|
ViewerTest::Display (aName, aViewCube, false);
|
|
return 0;
|
|
}
|
|
|
|
//! Parse color type argument.
|
|
static bool parseColorType (const char* theString,
|
|
Quantity_TypeOfColor& theType)
|
|
{
|
|
TCollection_AsciiString aType (theString);
|
|
aType.LowerCase();
|
|
if (aType == "rgb") { theType = Quantity_TOC_RGB; }
|
|
else if (aType == "srgb") { theType = Quantity_TOC_sRGB; }
|
|
else if (aType == "hex") { theType = Quantity_TOC_sRGB; }
|
|
else if (aType == "name") { theType = Quantity_TOC_sRGB; }
|
|
else if (aType == "hls") { theType = Quantity_TOC_HLS; }
|
|
else if (aType == "lab") { theType = Quantity_TOC_CIELab; }
|
|
else if (aType == "lch") { theType = Quantity_TOC_CIELch; }
|
|
else { return false; }
|
|
return true;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VColorConvert
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VColorConvert (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
|
|
{
|
|
Quantity_TypeOfColor aTypeFrom = Quantity_TOC_RGB, aTypeTo = Quantity_TOC_RGB;
|
|
double anInput[4] = {};
|
|
Quantity_ColorRGBA aColor (0.0f, 0.0f, 0.0f, 1.0f);
|
|
bool toPrintHex = false, toPrintName = false, hasAlpha = false;
|
|
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
|
|
anArgCase.LowerCase();
|
|
if ((anArgCase == "-from"
|
|
|| anArgCase == "from")
|
|
&& anArgIter + 1 < theNbArgs
|
|
&& parseColorType (theArgVec[anArgIter + 1], aTypeFrom))
|
|
{
|
|
++anArgIter;
|
|
}
|
|
else if ((anArgCase == "-to"
|
|
|| anArgCase == "to")
|
|
&& anArgIter + 1 < theNbArgs
|
|
&& parseColorType (theArgVec[anArgIter + 1], aTypeTo))
|
|
{
|
|
TCollection_AsciiString aToStr (theArgVec[++anArgIter]);
|
|
aToStr.LowerCase();
|
|
toPrintHex = (aToStr == "hex");
|
|
toPrintName = (aToStr == "name");
|
|
}
|
|
else if (Quantity_ColorRGBA::ColorFromHex (theArgVec[anArgIter], aColor))
|
|
{
|
|
hasAlpha = anArgCase.Length() >= 8;
|
|
}
|
|
else if (Quantity_Color::ColorFromName (theArgVec[anArgIter], aColor.ChangeRGB()))
|
|
{
|
|
//
|
|
}
|
|
else if (anArgIter + 2 < theNbArgs
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 0], anInput[0])
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 1], anInput[1])
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 2], anInput[2]))
|
|
{
|
|
if (anArgIter + 3 < theNbArgs
|
|
&& Draw::ParseReal (theArgVec[anArgIter + 3], anInput[3]))
|
|
{
|
|
anArgIter += 1;
|
|
aColor.SetAlpha ((float )anInput[3]);
|
|
hasAlpha = true;
|
|
}
|
|
anArgIter += 2;
|
|
aColor.ChangeRGB().SetValues (anInput[0], anInput[1], anInput[2], aTypeFrom);
|
|
}
|
|
else
|
|
{
|
|
theDI << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (toPrintHex)
|
|
{
|
|
if (hasAlpha || aColor.Alpha() < 1.0f)
|
|
{
|
|
theDI << Quantity_ColorRGBA::ColorToHex (aColor);
|
|
}
|
|
else
|
|
{
|
|
theDI << Quantity_Color::ColorToHex (aColor.GetRGB());
|
|
}
|
|
}
|
|
else if (toPrintName)
|
|
{
|
|
theDI << Quantity_Color::StringName (aColor.GetRGB().Name());
|
|
}
|
|
else
|
|
{
|
|
double anOutput[3] = {};
|
|
aColor.GetRGB().Values (anOutput[0], anOutput[1], anOutput[2], aTypeTo);
|
|
|
|
// print values with 6 decimal digits
|
|
char aBuffer[1024];
|
|
if (hasAlpha || aColor.Alpha() < 1.0f)
|
|
{
|
|
Sprintf (aBuffer, "%.6f %.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2], aColor.Alpha());
|
|
}
|
|
else
|
|
{
|
|
Sprintf (aBuffer, "%.6f %.6f %.6f", anOutput[0], anOutput[1], anOutput[2]);
|
|
}
|
|
theDI << aBuffer;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VColorDiff
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VColorDiff (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
|
|
{
|
|
if (theNbArgs != 7)
|
|
{
|
|
std::cerr << "Error: command syntax is incorrect, see help" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
double aR1 = Draw::Atof (theArgVec[1]);
|
|
double aG1 = Draw::Atof (theArgVec[2]);
|
|
double aB1 = Draw::Atof (theArgVec[3]);
|
|
double aR2 = Draw::Atof (theArgVec[4]);
|
|
double aG2 = Draw::Atof (theArgVec[5]);
|
|
double aB2 = Draw::Atof (theArgVec[6]);
|
|
|
|
Quantity_Color aColor1 (aR1, aG1, aB1, Quantity_TOC_RGB);
|
|
Quantity_Color aColor2 (aR2, aG2, aB2, Quantity_TOC_RGB);
|
|
|
|
theDI << aColor1.DeltaE2000 (aColor2);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//function : VSelBvhBuild
|
|
//purpose :
|
|
//===============================================================================================
|
|
static int VSelBvhBuild (Draw_Interpretor& /*theDI*/, Standard_Integer theNbArgs, const char** theArgVec)
|
|
{
|
|
const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
|
|
if (aCtx.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
if (theNbArgs < 2)
|
|
{
|
|
Message::SendFail ("Error: command syntax is incorrect, see help");
|
|
return 1;
|
|
}
|
|
|
|
Standard_Integer toEnable = -1;
|
|
Standard_Integer aThreadsNb = -1;
|
|
Standard_Boolean toWait = Standard_False;
|
|
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
|
|
{
|
|
TCollection_AsciiString anArg (theArgVec[anArgIter]);
|
|
anArg.LowerCase();
|
|
|
|
if (anArg == "-nbthreads"
|
|
&& anArgIter + 1 < theNbArgs)
|
|
{
|
|
aThreadsNb = Draw::Atoi (theArgVec[++anArgIter]);
|
|
if (aThreadsNb < 1)
|
|
{
|
|
aThreadsNb = Max (1, OSD_Parallel::NbLogicalProcessors() - 1);
|
|
}
|
|
}
|
|
else if (anArg == "-wait")
|
|
{
|
|
toWait = Standard_True;
|
|
}
|
|
else if (toEnable == -1)
|
|
{
|
|
Standard_Boolean toEnableValue = Standard_True;
|
|
if (Draw::ParseOnOff (anArg.ToCString(), toEnableValue))
|
|
{
|
|
toEnable = toEnableValue ? 1 : 0;
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (aThreadsNb == -1)
|
|
{
|
|
aThreadsNb = 1;
|
|
}
|
|
if (toEnable != -1)
|
|
{
|
|
aCtx->MainSelector()->SetToPrebuildBVH (toEnable == 1, aThreadsNb);
|
|
}
|
|
if (toWait)
|
|
{
|
|
aCtx->MainSelector()->WaitForBVHBuild();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : VChangeMouseGesture
|
|
//purpose :
|
|
//=======================================================================
|
|
static int VChangeMouseGesture (Draw_Interpretor&,
|
|
Standard_Integer theArgsNb,
|
|
const char** theArgVec)
|
|
{
|
|
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
|
if (aView.IsNull())
|
|
{
|
|
Message::SendFail ("Error: no active viewer");
|
|
return 1;
|
|
}
|
|
|
|
NCollection_DoubleMap<TCollection_AsciiString, AIS_MouseGesture> aGestureMap;
|
|
{
|
|
aGestureMap.Bind ("none", AIS_MouseGesture_NONE);
|
|
aGestureMap.Bind ("selectrectangle", AIS_MouseGesture_SelectRectangle);
|
|
aGestureMap.Bind ("selectlasso", AIS_MouseGesture_SelectLasso);
|
|
aGestureMap.Bind ("zoom", AIS_MouseGesture_Zoom);
|
|
aGestureMap.Bind ("zoomwindow", AIS_MouseGesture_ZoomWindow);
|
|
aGestureMap.Bind ("pan", AIS_MouseGesture_Pan);
|
|
aGestureMap.Bind ("rotateorbit", AIS_MouseGesture_RotateOrbit);
|
|
aGestureMap.Bind ("rotateview", AIS_MouseGesture_RotateView);
|
|
aGestureMap.Bind ("drag", AIS_MouseGesture_Drag);
|
|
}
|
|
NCollection_DoubleMap<TCollection_AsciiString, Standard_UInteger> aMouseButtonMap;
|
|
{
|
|
aMouseButtonMap.Bind ("none", (Standard_UInteger )Aspect_VKeyMouse_NONE);
|
|
aMouseButtonMap.Bind ("left", (Standard_UInteger )Aspect_VKeyMouse_LeftButton);
|
|
aMouseButtonMap.Bind ("middle", (Standard_UInteger )Aspect_VKeyMouse_MiddleButton);
|
|
aMouseButtonMap.Bind ("right", (Standard_UInteger )Aspect_VKeyMouse_RightButton);
|
|
}
|
|
|
|
Standard_UInteger aButton = (Standard_UInteger )Aspect_VKeyMouse_LeftButton;
|
|
AIS_MouseGesture aGesture = AIS_MouseGesture_RotateOrbit;
|
|
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
|
|
{
|
|
Standard_CString anArg = theArgVec[anArgIter];
|
|
TCollection_AsciiString anArgCase (anArg);
|
|
anArgCase.LowerCase();
|
|
if (anArgCase == "-button")
|
|
{
|
|
TCollection_AsciiString aButtonStr = theArgVec[++anArgIter];
|
|
aButtonStr.LowerCase();
|
|
aButton = aMouseButtonMap.Find1 (aButtonStr);
|
|
}
|
|
else if (anArgCase == "-gesture")
|
|
{
|
|
TCollection_AsciiString aGestureStr = theArgVec[++anArgIter];
|
|
aGestureStr.LowerCase();
|
|
aGesture = aGestureMap.Find1 (aGestureStr);
|
|
}
|
|
else
|
|
{
|
|
Message::SendFail() << "Error: unknown argument '" << anArg << "'";
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Handle(ViewerTest_EventManager) aViewMgr = ViewerTest::CurrentEventManager();
|
|
aViewMgr->ChangeMouseGestureMap().Bind (aButton, aGesture);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ViewerTest_ExitProc
|
|
//purpose :
|
|
//=======================================================================
|
|
static void ViewerTest_ExitProc (ClientData )
|
|
{
|
|
NCollection_List<TCollection_AsciiString> aViewList;
|
|
for (NCollection_DoubleMap<TCollection_AsciiString, Handle(V3d_View)>::Iterator anIter (ViewerTest_myViews);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
aViewList.Append (anIter.Key1());
|
|
}
|
|
|
|
for (NCollection_List<TCollection_AsciiString>::Iterator anIter (aViewList);
|
|
anIter.More(); anIter.Next())
|
|
{
|
|
ViewerTest::RemoveView (anIter.Value(), true);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ViewerCommands
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
|
{
|
|
static bool TheIsInitialized = false;
|
|
if (TheIsInitialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TheIsInitialized = true;
|
|
// define destruction callback to destroy views in a well-defined order
|
|
Tcl_CreateExitHandler (ViewerTest_ExitProc, 0);
|
|
|
|
const char* aGroup = "AIS Viewer";
|
|
const char* aFileName = __FILE__;
|
|
auto addCmd = [&](const char* theName, Draw_Interpretor::CommandFunction theFunc, const char* theHelp)
|
|
{
|
|
theCommands.Add (theName, theHelp, aFileName, theFunc, aGroup);
|
|
};
|
|
|
|
addCmd ("vdriver", VDriver, /* [vdriver] */ R"(
|
|
vdriver [-list] [-default DriverName] [-load DriverName]
|
|
Manages active graphic driver factory.
|
|
Prints current active driver when called without arguments.
|
|
Makes specified driver active when ActiveName argument is specified.
|
|
-list print registered factories
|
|
-default define which factory should be used by default (to be used by next vinit call)
|
|
-load try loading factory plugin and set it as default one
|
|
)" /* [vdriver] */);
|
|
|
|
addCmd ("vinit", VInit, /* [vinit] */ R"(
|
|
vinit [-name viewName] [-left leftPx] [-top topPx] [-width widthPx] [-height heightPx]
|
|
[-exitOnClose] [-closeOnEscape] [-cloneActive] [-virtual {0|1}]=0 [-2d_mode {0|1}]=0
|
|
[-display displayName] [-dpiAware {0|1}]=0
|
|
[-subview] [-parent OtherView] [-composer {0|1}]=0 [-margins DX DY]=0
|
|
Creates new View window with specified name viewName.
|
|
By default the new view is created in the viewer and in graphic driver shared with active view.
|
|
-name {driverName/viewerName/viewName | viewerName/viewName | viewName}
|
|
if driverName isn't specified the driver will be shared with active view;
|
|
if viewerName isn't specified the viewer will be shared with active view.
|
|
-display HostName.DisplayNumber[:ScreenNumber]
|
|
|
|
Display name will be used within creation of graphic driver, when specified.
|
|
-left, -top pixel position of left top corner of the window.
|
|
-width, -height width and height of window respectively.
|
|
-cloneActive flag to copy camera and dimensions of active view.
|
|
-exitOnClose when specified, closing the view will exit application.
|
|
-closeOnEscape when specified, view will be closed on pressing Escape.
|
|
-virtual create an offscreen window within interactive session
|
|
-subview create a subview within another view
|
|
-2d_mode when on, view will not react on rotate scene events
|
|
-dpiAware override dpi aware hint (Windows platform)
|
|
Additional commands for operations with views: vclose, vactivate, vviewlist.
|
|
)" /* [vinit] */);
|
|
|
|
addCmd ("vclose", VClose, /* [vclose] */ R"(
|
|
vclose [view_id [keep_context=0|1]]
|
|
or vclose ALL - to remove all created views
|
|
- removes view(viewer window) defined by its view_id.
|
|
- keep_context: by default 0; if 1 and the last view is deleted the current context is not removed.
|
|
)" /* [vclose] */);
|
|
|
|
addCmd ("vactivate", VActivate, /* [vactivate] */ R"(
|
|
vactivate view_id [-noUpdate]
|
|
Activates view(viewer window) defined by its view_id.
|
|
)" /* [vactivate] */);
|
|
|
|
addCmd ("vviewlist", VViewList, /* [vviewlist] */ R"(
|
|
vviewlist [format={tree, long}]=tree
|
|
Prints current list of views per viewer and graphic_driver ID shared between viewers
|
|
- format: format of result output, if tree the output is a tree view;
|
|
otherwise it's a list of full view names.
|
|
)" /* [vviewlist] */);
|
|
|
|
addCmd ("vhelp", VHelp, /* [vhelp] */ R"(
|
|
vhelp : display help on the viewer commands and list of hotkeys.
|
|
)" /* [vhelp] */);
|
|
|
|
addCmd ("vviewproj", VViewProj, /* [vviewproj] */ R"(
|
|
vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]
|
|
[+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]
|
|
Setup view direction
|
|
-Yup use Y-up convention instead of Zup (which is default).
|
|
+-X+-Y+-Z define direction as combination of DX, DY and DZ;
|
|
for example '+Z' will show front of the model,
|
|
'-X-Y+Z' will define left axonometric view.
|
|
-frame define camera Up and Right directions (regardless Up convention);
|
|
for example '+X+Z' will show front of the model with Z-up.
|
|
)" /* [vviewproj] */);
|
|
|
|
addCmd ("vtop", VViewProj, /* [vtop] */ R"(
|
|
vtop or <T> : Display top view (+X+Y) in the 3D viewer window.
|
|
)" /* [vtop] */);
|
|
|
|
addCmd ("vbottom", VViewProj, /* [vbottom] */ R"(
|
|
vbottom : Display bottom view (+X-Y) in the 3D viewer window.
|
|
)" /* [vbottom] */);
|
|
|
|
addCmd ("vleft", VViewProj, /* [vleft] */ R"(
|
|
vleft : Display left view (-Y+Z) in the 3D viewer window.
|
|
)" /* [vleft] */);
|
|
|
|
addCmd ("vright", VViewProj, /* [vright] */ R"(
|
|
vright : Display right view (+Y+Z) in the 3D viewer window.
|
|
)" /* [vright] */);
|
|
|
|
addCmd ("vaxo", VViewProj, /* [vaxo] */ R"(
|
|
vaxo or <A> : Display axonometric view (+X-Y+Z) in the 3D viewer window.
|
|
)" /* [vaxo] */);
|
|
|
|
addCmd ("vfront", VViewProj, /* [vfront] */ R"(
|
|
vfront : Display front view (+X+Z) in the 3D viewer window.
|
|
)" /* [vfront] */);
|
|
|
|
addCmd ("vback", VViewProj, /* [vfront] */ R"(
|
|
vback : Display back view (-X+Z) in the 3D viewer window.
|
|
)" /* [vback] */);
|
|
|
|
addCmd ("vpick", VPick, /* [vpick] */ R"(
|
|
vpick X Y Z [shape subshape]
|
|
)" /* [vpick] */);
|
|
|
|
addCmd ("vfit", VFit, /* [vfit] */ R"(
|
|
vfit or <F> [-selected] [-noupdate]
|
|
Fit all / selected. Objects in the view are visualized to occupy the maximum surface.
|
|
)" /* [vfit] */);
|
|
|
|
addCmd ("vfitarea", VFitArea, /* [vfitarea] */ R"(
|
|
vfitarea [x1 y1 x2 y2] [x1 y1 z1 x2 y2 z2]
|
|
Fit view to show area located between two points
|
|
given in world 2D or 3D coordinates.
|
|
)" /* [vfitarea] */);
|
|
|
|
addCmd ("vzfit", VZFit, /* [vzfit] */ R"(
|
|
vzfit [scale]
|
|
Automatic depth panning.
|
|
Matches Z near, Z far view volume planes to the displayed objects.
|
|
- "scale" specifies factor to scale computed z range.
|
|
)" /* [vzfit] */);
|
|
|
|
addCmd ("vrepaint", VRepaint, /* [vrepaint] */ R"(
|
|
vrepaint [-immediate] [-continuous FPS]
|
|
Force redraw of active View.
|
|
-immediate flag performs redraw of immediate layers only;
|
|
-continuous activates/deactivates continuous redraw of active View,
|
|
0 means no continuous rendering,
|
|
-1 means non-stop redraws,
|
|
>0 specifies target framerate.
|
|
)" /* [vrepaint] */);
|
|
|
|
addCmd ("vclear", VClear, /* [vclear] */ R"(
|
|
vclear : Remove all the object from the viewer
|
|
)" /* [vclear] */);
|
|
|
|
addCmd ("vbackground", VBackground, /* [vbackground] */ R"(
|
|
vbackground [-color Color [-default]]
|
|
[-gradient Color1 Color2 [-default]
|
|
[-gradientMode {NONE|HORIZONTAL|VERTICAL|DIAG1|DIAG2|CORNER1|CORNER2|CORNER3|ELLIPTICAL}]=VERT]
|
|
[-imageFile ImageFile [-imageMode {CENTERED|TILED|STRETCH|NONE}]=CENTERED [-srgb {0|1}]=1]
|
|
[-cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]=0]
|
|
[-skydome [-sunDir X Y Z=0 1 0] [-cloud Cloudy=0.2] [-time Time=0.0]
|
|
[-fog Haze=0.0] [-size SizePx=512]]
|
|
[-pbrEnv {ibl|noibl|keep}]
|
|
Changes background or some background settings.
|
|
-color sets background color
|
|
-gradient sets background gradient starting and ending colors
|
|
-gradientMode sets gradient fill method
|
|
-default sets background default gradient or color
|
|
-imageFile sets filename of image used as background
|
|
-imageMode sets image fill type
|
|
-cubemap sets environment cubemap as background
|
|
-invertedz sets inversion of Z axis for background cubemap rendering; FALSE when unspecified
|
|
-pbrEnv sets on/off Image Based Lighting (IBL) from background cubemap for PBR
|
|
-srgb prefer sRGB texture format when applicable; TRUE when unspecified"
|
|
-order defines order of tiles in one image cubemap
|
|
TileIndexi defubes an index in range [0, 5] for i tile of one image packed cubemap
|
|
(has no effect in case of multi-image cubemaps).
|
|
Skydome background parameters (generated cubemap):
|
|
-skydome sets procedurally generated skydome as background
|
|
-sunDir sets direction to the sun, direction with negative y component represents moon direction (-x, -y, -z)
|
|
-cloud sets cloud intensity (0.0 - clear sky, 1.0 - very high cloudy)
|
|
-time might be tweaked to slightly change appearance of clouds
|
|
-fog sets mist intensity (0.0 - no mist at all, 1.0 - high mist)
|
|
-size sets size in pixels of cubemap side
|
|
)" /* [vbackground] */);
|
|
|
|
addCmd ("vsetbg", VBackground, /* [vsetbg] */ R"(
|
|
Alias for 'vbackground -imageFile ImageFile [-imageMode FillType]'.
|
|
)" /* [vsetbg] */);
|
|
|
|
addCmd ("vsetbgmode", VBackground, /* [vsetbgmode] */ R"(
|
|
Alias for 'vbackground -imageMode FillType'.
|
|
)" /* [vsetbgmode] */);
|
|
|
|
addCmd ("vsetgradientbg", VBackground, /* [vsetgradientbg] */ R"(
|
|
Alias for 'vbackground -gradient Color1 Color2 -gradientMode FillMethod'.
|
|
)" /* [vsetgradientbg] */);
|
|
|
|
addCmd ("vsetgrbgmode", VBackground, /* [vsetgrbgmode] */ R"(
|
|
Alias for 'vbackground -gradientMode FillMethod'.
|
|
)" /* [vsetgrbgmode] */);
|
|
|
|
addCmd ("vsetcolorbg", VBackground, /* [vsetcolorbg] */ R"(
|
|
Alias for 'vbackground -color Color'.
|
|
)" /* [vsetcolorbg] */);
|
|
|
|
addCmd ("vsetdefaultbg", VBackground, /* [vsetdefaultbg] */ R"(
|
|
Alias for 'vbackground -default -gradient Color1 Color2 [-gradientMode FillMethod]'
|
|
and for 'vbackground -default -color Color'.
|
|
)" /* [vsetdefaultbg] */);
|
|
|
|
addCmd ("vscale", VScale, /* [vscale] */ R"(
|
|
vscale X Y Z
|
|
)" /* [vscale] */);
|
|
|
|
addCmd ("vzbufftrihedron", VZBuffTrihedron, /* [vzbufftrihedron] */ R"(
|
|
vzbufftrihedron [{-on|-off}=-on] [-type {wireframe|zbuffer}=zbuffer]
|
|
[-position center|left_lower|left_upper|right_lower|right_upper]
|
|
[-scale value=0.1] [-size value=0.8] [-arrowDiam value=0.05]
|
|
[-colorArrowX color=RED] [-colorArrowY color=GREEN] [-colorArrowZ color=BLUE]
|
|
[-nbfacets value=12] [-colorLabels color=WHITE]
|
|
[-colorLabelX color] [-colorLabelY color] [-colorLabelZ color]
|
|
Displays a trihedron.
|
|
)" /* [vzbufftrihedron] */);
|
|
|
|
addCmd ("vrotate", VRotate, /* [vrotate] */ R"(
|
|
vrotate [[-mouseStart X Y] [-mouseMove X Y]]|[AX AY AZ [X Y Z]]
|
|
-mouseStart start rotation according to the mouse position;
|
|
-mouseMove continue rotation with angle computed
|
|
from last and new mouse position.
|
|
)" /* [vrotate] */);
|
|
|
|
addCmd ("vzoom", VZoom, /* [vzoom] */ R"(
|
|
vzoom coef
|
|
)" /* [vzoom] */);
|
|
|
|
addCmd ("vpan", VPan, /* [vpan] */ R"(
|
|
vpan dx dy
|
|
)" /* [vpan] */);
|
|
|
|
addCmd ("vcolorscale", VColorScale, /* [vcolorscale] */ R"(
|
|
vcolorscale name [-noupdate|-update] [-demo]
|
|
[-range RangeMin=0 RangeMax=1 NbIntervals=10]
|
|
[-font HeightFont=20]
|
|
[-logarithmic {on|off}=off] [-reversed {on|off}=off]
|
|
[-smoothTransition {on|off}=off]
|
|
[-hueRange MinAngle=230 MaxAngle=0]
|
|
[-colorRange MinColor=BLUE1 MaxColor=RED]
|
|
[-textPos {left|right|center|none}=right]
|
|
[-labelAtBorder {on|off}=on]
|
|
[-colors Color1 Color2 ...] [-color Index Color]
|
|
[-labels Label1 Label2 ...] [-label Index Label]
|
|
[-freeLabels NbOfLabels Label1 Label2 ...]
|
|
[-xy Left=0 Bottom=0]
|
|
[-uniform lightness hue_from hue_to]
|
|
-demo display a color scale with demonstration values
|
|
-colors set colors for all intervals
|
|
-color set color for specific interval
|
|
-uniform generate colors with the same lightness
|
|
-textpos horizontal label position relative to color scale bar
|
|
-labelAtBorder vertical label position relative to color interval;
|
|
at border means the value inbetween neighbor intervals,
|
|
at center means the center value within current interval
|
|
-labels set labels for all intervals
|
|
-freeLabels same as -labels but does not require
|
|
matching the number of intervals
|
|
-label set label for specific interval
|
|
-title set title
|
|
-reversed setup smooth color transition between intervals
|
|
-smoothTransition swap colorscale direction
|
|
-hueRange set hue angles corresponding to minimum and maximum values
|
|
)" /* [vcolorscale] */);
|
|
|
|
addCmd ("vgraduatedtrihedron", VGraduatedTrihedron, /* [vgraduatedtrihedron] */ R"(
|
|
vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]
|
|
[-namefont Name] [-valuesfont Name]
|
|
[-xdrawname on/off] [-ydrawname on/off] [-zdrawname on/off]
|
|
[-xnameoffset IntVal] [-ynameoffset IntVal] [-znameoffset IntVal]
|
|
[-xnamecolor Color] [-ynamecolor Color] [-znamecolor Color]
|
|
[-xdrawvalues on/off] [-ydrawvalues on/off] [-zdrawvalues on/off]
|
|
[-xvaluesoffset IntVal] [-yvaluesoffset IntVal] [-zvaluesoffset IntVal]
|
|
[-xcolor Color] [-ycolor Color] [-zcolor Color]
|
|
[-xdrawticks on/off] [-ydrawticks on/off] [-zdrawticks on/off]
|
|
[-xticks Number] [-yticks Number] [-zticks Number]
|
|
[-xticklength IntVal] [-yticklength IntVal] [-zticklength IntVal]
|
|
[-drawgrid on/off] [-drawaxes on/off]
|
|
Display or erase graduated trihedron
|
|
- xname, yname, zname - names of axes, default: X, Y, Z
|
|
- namefont - font of axes names. Default: Arial
|
|
- xnameoffset, ynameoffset, znameoffset - offset of name
|
|
from values or tickmarks or axis. Default: 30
|
|
- xnamecolor, ynamecolor, znamecolor - colors of axes names
|
|
- xvaluesoffset, yvaluesoffset, zvaluesoffset - offset of values
|
|
from tickmarks or axis. Default: 10
|
|
- valuesfont - font of axes values. Default: Arial
|
|
- xcolor, ycolor, zcolor - color of axis and values
|
|
- xticks, yticks, xzicks - number of tickmark on axes. Default: 5
|
|
- xticklength, yticklength, xzicklength - length of tickmark on axes. Default: 10
|
|
)" /* [vgraduatedtrihedron] */);
|
|
|
|
addCmd ("vtile", VTile, /* [vtile] */ R"(
|
|
vtile [-totalSize W H] [-lowerLeft X Y] [-upperLeft X Y] [-tileSize W H]
|
|
Setup view to draw a tile (a part of virtual bigger viewport).
|
|
-totalSize the size of virtual bigger viewport
|
|
-tileSize tile size (the view size will be used if omitted)
|
|
-lowerLeft tile offset as lower left corner
|
|
-upperLeft tile offset as upper left corner
|
|
)" /* [vtile] */);
|
|
|
|
addCmd ("vzlayer", VZLayer, /* [vzlayer] */ R"(
|
|
vzlayer [layerId]
|
|
[-add|-delete|-get|-settings] [-insertBefore AnotherLayer] [-insertAfter AnotherLayer]
|
|
[-origin X Y Z] [-cullDist Distance] [-cullSize Size]
|
|
[-enable|-disable {depthTest|depthWrite|depthClear|depthoffset}]
|
|
[-enable|-disable {positiveOffset|negativeOffset|textureenv|rayTracing}]
|
|
ZLayer list management
|
|
-add add new z layer to viewer and print its id
|
|
-insertBefore add new z layer and insert it before existing one
|
|
-insertAfter add new z layer and insert it after existing one
|
|
-delete delete z layer
|
|
-get print sequence of z layers
|
|
-settings print status of z layer settings
|
|
-disable disables given setting
|
|
-enable enables given setting
|
|
)" /* [vzlayer] */);
|
|
|
|
addCmd ("vlayerline", VLayerLine, /* [vlayerline] */ R"(
|
|
vlayerline x1 y1 x2 y2 [linewidth=0.5] [linetype=0] [transparency=1.0]
|
|
)" /* [vlayerline] */);
|
|
|
|
addCmd ("vgrid", VGrid, /* [vgrid] */ R"(
|
|
vgrid [off] [-type {rect|circ}] [-mode {line|point}] [-origin X Y] [-rotAngle Angle] [-zoffset DZ]
|
|
[-step X Y] [-size DX DY]
|
|
[-step StepRadius NbDivisions] [-radius Radius]
|
|
)" /* [vgrid] */);
|
|
|
|
addCmd ("vpriviledgedplane", VPriviledgedPlane, /* [vpriviledgedplane] */ R"(
|
|
vpriviledgedplane [Ox Oy Oz Nx Ny Nz [Xx Xy Xz]]
|
|
Sets or prints viewer's priviledged plane geometry:
|
|
Ox, Oy, Oz - plane origin;
|
|
Nx, Ny, Nz - plane normal direction;
|
|
Xx, Xy, Xz - plane x-reference axis direction.
|
|
)" /* [vpriviledgedplane] */);
|
|
|
|
addCmd ("vconvert", VConvert, /* [vconvert] */ R"(
|
|
vconvert v [Mode={window|view}]
|
|
vconvert x y [Mode={window|view|grid|ray}]
|
|
vconvert x y z [Mode={window|grid}]
|
|
Convert the given coordinates to window/view/model space:
|
|
- window - convert to window coordinates, pixels;
|
|
- view - convert to view projection plane;
|
|
- grid - convert to model coordinates, given on grid;
|
|
- ray - convert projection ray to model coordinates.
|
|
)" /* [vconvert] */);
|
|
|
|
addCmd ("vfps", VFps, /* [vfps] */ R"(
|
|
vfps [framesNb=100] [-duration seconds] : estimate average frame rate for active view.
|
|
)" /* [vfps] */);
|
|
|
|
addCmd ("vstereo", VStereo, /* [vstereo] */ R"(
|
|
vstereo [0|1] [-mode Mode] [-reverse {0|1}]
|
|
[-mirrorComposer] [-hmdfov2d AngleDegrees] [-unitFactor MetersFactor]
|
|
[-anaglyph Filter] [-smoothInterlacing]
|
|
Control stereo output mode. Available modes for -mode:
|
|
quadBuffer OpenGL QuadBuffer stereo;
|
|
requires driver support;
|
|
should be called BEFORE vinit!
|
|
anaglyph Anaglyph glasses, filters for -anaglyph:
|
|
redCyan, redCyanSimple, yellowBlue, yellowBlueSimple, greenMagentaSimple.
|
|
rowInterlaced row-interlaced display
|
|
smooth smooth interlaced output for better text readability
|
|
columnInterlaced column-interlaced display
|
|
chessBoard chess-board output
|
|
sideBySide horizontal pair
|
|
overUnder vertical pair
|
|
openVR OpenVR (HMD), extra options:
|
|
-mirrorComposer flag to mirror VR frame in the window (debug);
|
|
-unitFactor specifies meters scale factor for mapping VR input.
|
|
)" /* [vstereo] */);
|
|
|
|
addCmd ("vmemgpu", VMemGpu, /* [vmemgpu] */ R"(
|
|
vmemgpu [f]: print system-dependent GPU memory information if available;
|
|
with f option returns free memory in bytes.
|
|
)" /* [vmemgpu] */);
|
|
|
|
addCmd ("vreadpixel", VReadPixel, /* [vreadpixel] */ R"(
|
|
vreadpixel xPixel yPixel [{rgb|rgba|sRGB|sRGBa|depth|hls|rgbf|rgbaf}=rgba] [-name|-hex]
|
|
Read pixel value for active view.
|
|
)" /* [vreadpixel] */);
|
|
|
|
addCmd ("diffimage", VDiffImage, /* [diffimage] */ R"(
|
|
diffimage imageFile1 imageFile2 [diffImageFile]
|
|
[-toleranceOfColor {0..1}=0] [-blackWhite {on|off}=off] [-borderFilter {on|off}=off]
|
|
[-display viewName prsName1 prsName2 prsNameDiff] [-exitOnClose] [-closeOnEscape]
|
|
Compare two images by content and generate difference image.
|
|
When -exitOnClose is specified, closing the view will exit application.
|
|
When -closeOnEscape is specified, view will be closed on pressing Escape.
|
|
)" /* [diffimage] */);
|
|
|
|
addCmd ("vselect", VSelect, /* [vselect] */ R"(
|
|
vselect x1 y1 [x2 y2 [x3 y3 ... xn yn]] [-allowoverlap 0|1]
|
|
[-replace|-replaceextra|-xor|-add|-remove]
|
|
Emulate different types of selection:
|
|
1) Single click selection.
|
|
2) Selection with rectangle having corners at pixel positions (x1,y1) and (x2,y2).
|
|
3) Selection with polygon having corners in pixel positions (x1,y1), (x2,y2),...,(xn,yn).
|
|
4) -allowoverlap manages overlap and inclusion detection in rectangular and polygonal selection.
|
|
If the flag is set to 1, both sensitives that were included completely
|
|
and overlapped partially by defined rectangle or polygon will be detected,
|
|
otherwise algorithm will chose only fully included sensitives.
|
|
Default behavior is to detect only full inclusion
|
|
(partial inclusion - overlap - is not allowed by default).
|
|
5) Selection scheme replace, replaceextra, xor, add or remove (replace by default).
|
|
)" /* [vselect] */);
|
|
|
|
addCmd ("vmoveto", VMoveTo, /* [vmoveto] */ R"(
|
|
vmoveto [x y] [-reset]
|
|
Emulate cursor movement to pixel position (x,y).
|
|
-reset resets current highlighting.
|
|
)" /* [vmoveto] */);
|
|
|
|
addCmd ("vselaxis", VSelectByAxis, /* [vselaxis] */ R"(
|
|
vselaxis x y z dx dy dz [-onlyTop 0|1] [-display Name] [-showNormal 0|1]"
|
|
Provides intersection by given axis and print result intersection points.
|
|
-onlyTop switches On/Off mode to find only top point or all;
|
|
-display Name displays intersecting axis and result intersection points for debug goals;
|
|
-showNormal adds displaying of normal in intersection point or not.
|
|
)" /* [vselaxis] */);
|
|
|
|
addCmd ("vviewparams", VViewParams, /* [vviewparams] */ R"(
|
|
vviewparams [-args] [-scale [s]]
|
|
[-eye [x y z]] [-at [x y z]] [-up [x y z]]
|
|
[-proj [x y z]] [-center x y] [-size sx]
|
|
Manage current view parameters (camera orientation) or prints all
|
|
current values when called without argument.
|
|
-scale [s] prints or sets viewport relative scale
|
|
-eye [x y z] prints or sets eye location
|
|
-at [x y z] prints or sets center of look
|
|
-up [x y z] prints or sets direction of up vector
|
|
-proj [x y z] prints or sets direction of look
|
|
-center x y sets location of center of the screen in pixels
|
|
-size [sx] prints viewport projection width and height sizes
|
|
or changes the size of its maximum dimension
|
|
-args prints vviewparams arguments for restoring current view
|
|
)" /* [vviewparams] */);
|
|
|
|
addCmd ("v2dmode", V2DMode, /* [v2dmode] */ R"(
|
|
v2dmode [-name viewName] [-mode {-on|-off}=-on]
|
|
name - name of existing view, if not defined, the active view is changed;
|
|
mode - switches On/Off rotation mode.
|
|
Set 2D mode of the active viewer manipulating. The following mouse and key actions are disabled:
|
|
- rotation of the view by 3rd mouse button with Ctrl active
|
|
- set view projection using key buttons: A/D/T/B/L/R for AXO, Reset, Top, Bottom, Left, Right
|
|
View camera position might be changed only by commands.
|
|
)" /* [v2dmode] */);
|
|
|
|
addCmd ("vanimation", VAnimation, /* [vanimation] */ R"(
|
|
Alias for vanim
|
|
)" /* [vanimation] */);
|
|
|
|
addCmd ("vanim", VAnimation, /* [vanim] */ R"(
|
|
List existing animations:
|
|
vanim
|
|
|
|
Animation playback:
|
|
vanim name {-play|-resume|-pause|-stop} [playFrom [playDuration]] [-speed Coeff]
|
|
[-freeLook] [-noPauseOnClick] [-lockLoop] [-elapsedTime]
|
|
|
|
-speed playback speed (1.0 is normal speed)
|
|
-freeLook skip camera animations
|
|
-noPauseOnClick do not pause animation on mouse click
|
|
-lockLoop disable any interactions
|
|
-elapsedTime prints elapsed time in seconds"
|
|
|
|
Animation definition:
|
|
vanim Name/sub/name [-clear] [-delete]
|
|
[-start TimeSec] [-duration TimeSec] [-end TimeSec]
|
|
|
|
Animation name defined in path-style (anim/name or anim.name)
|
|
specifies nested animations.
|
|
There is no syntax to explicitly add new animation,
|
|
and all non-existing animations within the name will be
|
|
implicitly created on first use (including parents).
|
|
|
|
Each animation might define the SINGLE action (see below),
|
|
like camera transition, object transformation or custom callback.
|
|
Child animations can be used for defining concurrent actions.
|
|
|
|
Camera animation:
|
|
vanim name -view [-eye1 X Y Z] [-eye2 X Y Z]
|
|
[-at1 X Y Z] [-at2 X Y Z]
|
|
[-up1 X Y Z] [-up2 X Y Z]
|
|
[-scale1 Scale] [-scale2 Scale]
|
|
-eyeX camera Eye positions pair (start and end)
|
|
-atX camera Center positions pair
|
|
-upX camera Up directions pair
|
|
-scaleX camera Scale factors pair
|
|
|
|
Object animation:
|
|
vanim name -object [-loc1 X Y Z] [-loc2 X Y Z]
|
|
[-rot1 QX QY QZ QW] [-rot2 QX QY QZ QW]
|
|
[-scale1 Scale] [-scale2 Scale]
|
|
-locX object Location points pair (translation)
|
|
-rotX object Orientations pair (quaternions)
|
|
-scaleX object Scale factors pair (quaternions)
|
|
|
|
vanim name -object [-axis OX OY OZ DX DY DZ] [-ang1 A] [-ang2 A]
|
|
-axis rotation axis
|
|
-ang1 start rotation angle in degrees
|
|
-ang2 end rotation angle in degrees
|
|
|
|
Custom callback:
|
|
vanim name -invoke "Command Arg1 Arg2 %Pts %LocalPts %Normalized ArgN"
|
|
|
|
%Pts overall animation presentation timestamp
|
|
%LocalPts local animation timestamp
|
|
%Normalized local animation normalized value in range 0..1
|
|
|
|
Video recording:
|
|
vanim name -record FileName [Width Height] [-fps FrameRate=24]
|
|
[-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]
|
|
[-crf Value] [-preset Preset]
|
|
-fps video framerate
|
|
-format file format, container (matroska, etc.)
|
|
-vcodec video codec identifier (ffv1, mjpeg, etc.)
|
|
-pix_fmt image pixel format (yuv420p, rgb24, etc.)
|
|
-crf constant rate factor (specific to codec)
|
|
-preset codec parameters preset (specific to codec)
|
|
)" /* [vanim] */);
|
|
|
|
addCmd ("vchangeselected", VChangeSelected, /* [vchangeselected] */ R"(
|
|
vchangeselected shape : Add shape to selection or remove one from it.
|
|
)" /* [vchangeselected] */);
|
|
|
|
addCmd ("vnbselected", VNbSelected, /* [vnbselected] */ R"(
|
|
vnbselected : Returns number of selected objects in the interactive context.
|
|
)" /* [vnbselected] */);
|
|
|
|
addCmd ("vcamera", VCamera, /* [vcamera] */ R"(
|
|
vcamera [PrsName] [-ortho] [-projtype]
|
|
[-persp]
|
|
[-fovy [Angle]] [-distance [Distance]]
|
|
[-stereo] [-leftEye] [-rightEye]
|
|
[-iod [Distance]] [-iodType [absolute|relative]]
|
|
[-zfocus [Value]] [-zfocusType [absolute|relative]]
|
|
[-fov2d [Angle]] [-lockZup {0|1}]
|
|
[-rotationMode {active|pick|pickCenter|cameraAt|scene}]
|
|
[-navigationMode {orbit|walk|flight}]
|
|
[-xrPose base|head=base]
|
|
Manages camera parameters.
|
|
Displays frustum when presentation name PrsName is specified.
|
|
Prints current value when option called without argument.
|
|
|
|
Orthographic camera:
|
|
-ortho activate orthographic projection.
|
|
|
|
Perspective camera:
|
|
-persp activate perspective projection (mono);
|
|
-fovy field of view in y axis, in degrees;
|
|
-fov2d field of view limit for 2d on-screen elements;
|
|
-distance distance of eye from camera center;
|
|
-lockZup lock Z up (turntable mode);
|
|
-rotationMode rotation mode (gravity point);
|
|
-navigationMode navigation mode.
|
|
|
|
Stereoscopic camera:
|
|
-stereo perspective projection (stereo);
|
|
-leftEye perspective projection (left eye);
|
|
-rightEye perspective projection (right eye);
|
|
-iod intraocular distance value;
|
|
-iodType distance type, absolute or relative;
|
|
-zfocus stereographic focus value;
|
|
-zfocusType focus type, absolute or relative.
|
|
)" /* [vcamera] */);
|
|
|
|
addCmd ("vautozfit", VAutoZFit, /* [vautozfit] */ R"(
|
|
vautozfit [on={1|0}] [scale]
|
|
Prints or changes parameters of automatic z-fit mode:
|
|
"on" - turns automatic z-fit on or off;
|
|
"scale" - specifies factor to scale computed z range.
|
|
)" /* [vautozfit] */);
|
|
|
|
addCmd ("vzrange", VZRange, /* [vzrange] */ R"(
|
|
vzrange [znear] [zfar]
|
|
Applies provided znear/zfar to view or prints current values.
|
|
)" /* [vzrange] */);
|
|
|
|
addCmd ("vsetviewsize", VSetViewSize, /* [vsetviewsize] */ R"(
|
|
vsetviewsize size
|
|
)" /* [vsetviewsize] */);
|
|
|
|
addCmd ("vmoveview", VMoveView, /* [vmoveview] */ R"(
|
|
vmoveview Dx Dy Dz [Start = 1|0]
|
|
)" /* [vmoveview] */);
|
|
|
|
addCmd ("vtranslateview", VTranslateView, /* [vtranslateview] */ R"(
|
|
vtranslateview Dx Dy Dz [Start = 1|0)]
|
|
)" /* [vtranslateview] */);
|
|
|
|
addCmd ("vturnview", VTurnView, /* [vturnview] */ R"(
|
|
vturnview Ax Ay Az [Start = 1|0]
|
|
)" /* [vturnview] */);
|
|
|
|
addCmd ("vtextureenv", VTextureEnv, /* [vtextureenv] */ R"(
|
|
vtextureenv {on|off} {image_file}
|
|
[{clamp|repeat} {decal|modulate} {nearest|bilinear|trilinear} ss st ts tt rot]
|
|
Enables or disables environment mapping in the 3D view, loading the texture from the given standard
|
|
or user-defined file and optionally applying texture mapping parameters.
|
|
ss, st - scale factors for s and t texture coordinates;
|
|
ts, tt - translation for s and t texture coordinates;
|
|
rot - texture rotation angle in degrees.
|
|
)" /* [vtextureenv] */);
|
|
|
|
addCmd ("vhlr", VHLR, /* [vhlr] */ R"(
|
|
vhlr {on|off} [-showHidden={1|0}] [-algoType={algo|polyAlgo}] [-noupdate]
|
|
Hidden Line Removal algorithm.
|
|
-showHidden if set ON, hidden lines are drawn as dotted ones;
|
|
-algoType type of HLR algorithm:
|
|
'algo' - exact HLR algorithm is applied;
|
|
'polyAlgo' - polygonal HLR algorithm is applied.
|
|
)" /* [vhlr] */);
|
|
|
|
addCmd ("vhlrtype", VHLRType, /* [vhlrtype] */ R"(
|
|
vhlrtype {algo|polyAlgo} [shape_1 ... shape_n] [-noupdate]
|
|
Changes the type of HLR algorithm using for shapes:
|
|
'algo' - exact HLR algorithm is applied;
|
|
'polyAlgo' - polygonal HLR algorithm is applied.
|
|
If shapes are not given - option is applied to all shapes in the view.
|
|
)" /* [vhlrtype] */);
|
|
|
|
addCmd ("vclipplane", VClipPlane, /* [vclipplane] */ R"(
|
|
vclipplane planeName [{0|1}]
|
|
[-equation1 A B C D]
|
|
[-equation2 A B C D]
|
|
[-boxInterior MinX MinY MinZ MaxX MaxY MaxZ]
|
|
[-set|-unset|-setOverrideGlobal [objects|views]]
|
|
[-maxPlanes]
|
|
[-capping {0|1}]
|
|
[-color R G B] [-transparency Value] [-hatch {on|off|ID}]
|
|
[-texName Texture] [-texScale SX SY] [-texOrigin TX TY]
|
|
[-texRotate Angle]
|
|
[-useObjMaterial {0|1}] [-useObjTexture {0|1}]
|
|
[-useObjShader {0|1}]
|
|
|
|
Clipping planes management:
|
|
-maxPlanes print plane limit for view;
|
|
-delete delete plane with given name;
|
|
{off|on|0|1} turn clipping on/off;
|
|
-set|-unset set/unset plane for Object or View list;
|
|
applied to active View when list is omitted;
|
|
-equation A B C D change plane equation;
|
|
-clone SourcePlane NewPlane clone the plane definition.
|
|
|
|
Capping options:
|
|
-capping {off|on|0|1} turn capping on/off;
|
|
-color R G B set capping color;
|
|
-transparency Value set capping transparency 0..1;
|
|
-texName Texture set capping texture;
|
|
-texScale SX SY set capping tex scale;
|
|
-texOrigin TX TY set capping tex origin;
|
|
-texRotate Angle set capping tex rotation;
|
|
-hatch {on|off|ID} set capping hatching mask;
|
|
-useObjMaterial {off|on|0|1} use material of clipped object;
|
|
-useObjTexture {off|on|0|1} use texture of clipped object;
|
|
-useObjShader {off|on|0|1} use shader program of object.
|
|
)" /* [vclipplane] */);
|
|
|
|
addCmd ("vdefaults", VDefaults, /* [vdefaults] */ R"(
|
|
vdefaults [-absDefl value] [-devCoeff value] [-angDefl value]
|
|
[-autoTriang {off/on | 0/1}]
|
|
)" /* [vdefaults] */);
|
|
|
|
addCmd ("vlight", VLight, /* [vlight] */ R"(
|
|
vlight [lightName] [-noupdate]
|
|
[-clear|-defaults] [-layer Id] [-local|-global] [-disable|-enable]
|
|
[-type {ambient|directional|spotlight|positional}] [-name value]
|
|
[-position X Y Z] [-direction X Y Z] [-color colorName] [-intensity value]
|
|
[-headlight 0|1] [-castShadows 0|1]
|
|
[-range value] [-constAttenuation value] [-linearAttenuation value]
|
|
[-spotExponent value] [-spotAngle angleDeg]
|
|
[-smoothAngle value] [-smoothRadius value]
|
|
[-display] [-showName 1|0] [-showRange 1|0] [-prsZoomable 1|0] [-prsSize Value]
|
|
[-arcSize Value]
|
|
|
|
Command manages light sources. Without arguments shows list of lights.
|
|
Arguments affecting the list of defined/active lights:
|
|
-clear remove all light sources;
|
|
-defaults defines two standard light sources;
|
|
-reset resets light source parameters to default values;
|
|
-type sets type of light source;
|
|
-name sets new name to light source;
|
|
-global assigns light source to all views (default state);
|
|
-local assigns light source to active view;
|
|
-zlayer assigns light source to specified Z-Layer.
|
|
|
|
Ambient light parameters:
|
|
-color sets (normalized) light color;
|
|
-intensity sets intensity of light source, 1.0 by default;
|
|
affects also environment cubemap intensity.
|
|
|
|
Point light parameters:
|
|
-color sets (normalized) light color;
|
|
-intensity sets PBR intensity;
|
|
-range sets clamping distance;
|
|
-constAtten (obsolete) sets constant attenuation factor;
|
|
-linearAtten (obsolete) sets linear attenuation factor;
|
|
-smoothRadius sets PBR smoothing radius.
|
|
|
|
Directional light parameters:
|
|
-color sets (normalized) light color;
|
|
-intensity sets PBR intensity;
|
|
-direction sets direction;
|
|
-headlight sets headlight flag;
|
|
-castShadows enables/disables shadow casting;
|
|
-smoothAngle sets PBR smoothing angle (in degrees) within 0..90 range.
|
|
|
|
Spot light parameters:
|
|
-color sets (normalized) light color;
|
|
-intensity sets PBR intensity;
|
|
-range sets clamping distance;
|
|
-position sets position;
|
|
-direction sets direction;
|
|
-spotAngle sets spotlight angle;
|
|
-spotExp sets spotlight exponenta;
|
|
-headlight sets headlight flag;
|
|
-castShadows enables/disables shadow casting;
|
|
-constAtten (obsolete) sets constant attenuation factor;
|
|
-linearAtten (obsolete) sets linear attenuation factor.
|
|
|
|
Light presentation parameters:
|
|
-display adds light source presentation;
|
|
-showName shows/hides the name of light source; 1 by default;
|
|
-showRange shows/hides the range of spot/positional light source; 1 by default;
|
|
-prsZoomable makes light presentation zoomable/non-zoomable;
|
|
-prsDraggable makes light presentation draggable/non-draggable;
|
|
-prsSize sets light presentation size;
|
|
-arcSize sets arc presentation size(in pixels)
|
|
for rotation directional light source; 25 by default.
|
|
|
|
Examples:
|
|
vlight redlight -type POSITIONAL -headlight 1 -pos 0 1 1 -color RED
|
|
vlight redlight -delete
|
|
)" /* [vlight] */);
|
|
|
|
addCmd ("vpbrenv", VPBREnvironment, /* [vpbrenv] */ R"(
|
|
vpbrenv -clear|-generate
|
|
Clears or generates PBR environment map of active view.
|
|
-clear clears PBR environment (fills by white color);
|
|
-generate generates PBR environment from current background cubemap.
|
|
)" /* [vpbrenv] */);
|
|
|
|
addCmd ("vraytrace", VRenderParams, /* [vraytrace] */ R"(
|
|
vraytrace [0|1] : Turns on/off ray-tracing renderer.
|
|
'vraytrace 0' alias for 'vrenderparams -raster'.
|
|
'vraytrace 1' alias for 'vrenderparams -rayTrace'.
|
|
)" /* [vraytrace] */);
|
|
|
|
addCmd ("vrenderparams", VRenderParams, /* [vrenderparams] */ R"(
|
|
Manages rendering parameters, affecting visual appearance, quality and performance.
|
|
Should be applied taking into account GPU hardware capabilities and performance.
|
|
|
|
Common parameters:
|
|
vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]
|
|
[-msaa 0..8=0] [-rendScale scale=1]
|
|
[-resolution value=72] [-fontHinting {off|normal|light}=off]
|
|
[-fontAutoHinting {auto|force|disallow}=auto]
|
|
[-oit {off|weight|peel}] [-oit weighted [depthFactor=0.0]] [-oit peeling [nbLayers=4]]
|
|
[-shadows {on|off}=on] [-shadowMapResolution value=1024] [-shadowMapBias value=0.005]
|
|
[-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]
|
|
[-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]
|
|
[-sync {default|views}] [-reset]
|
|
-raster Disables GPU ray-tracing.
|
|
-shadingModel Controls shading model.
|
|
-msaa Specifies number of samples for MSAA.
|
|
-rendScale Rendering resolution scale factor (supersampling, alternative to MSAA).
|
|
-resolution Sets new pixels density (PPI) used as text scaling factor.
|
|
-fontHinting Enables/disables font hinting for better readability on low-resolution screens.
|
|
-fontAutoHinting Manages font autohinting.
|
|
-lineFeather Sets line feather factor while displaying mesh edges.
|
|
-alphaToCoverage Enables/disables alpha to coverage (needs MSAA).
|
|
-oit Enables/disables order-independent transparency (OIT) rendering;
|
|
off unordered transparency (but opaque objects implicitly draw first);
|
|
weighted weight OIT is managed by depth weight factor 0.0..1.0;
|
|
peeling depth peeling OIT is managed by number of peeling layers.
|
|
-shadows Enables/disables shadows rendering.
|
|
-shadowMapResolution Shadow texture map resolution.
|
|
-shadowMapBias Shadow map bias.
|
|
-depthPrePass Enables/disables depth pre-pass.
|
|
-frustumCulling Enables/disables objects frustum clipping or
|
|
sets state to check structures culled previously.
|
|
-sync Sets active View parameters as Viewer defaults / to other Views.
|
|
-reset Resets active View parameters to Viewer defaults.
|
|
|
|
Diagnostic output (on-screen overlay):
|
|
vrenderparams [-perfCounters none|fps|cpu|layers|structures|groups|arrays|triangles|points
|
|
|gpuMem|frameTime|basic|extended|full|nofps|skipImmediate]
|
|
[-perfUpdateInterval nbSeconds=1] [-perfChart nbFrames=1] [-perfChartMax seconds=0.1]
|
|
-perfCounters Show/hide performance counters (flags can be combined).
|
|
-perfUpdateInterval Performance counters update interval.
|
|
-perfChart Show frame timers chart limited by specified number of frames.
|
|
-perfChartMax Maximum time in seconds with the chart.
|
|
|
|
Ray-Tracing options:
|
|
vrenderparams [-rayTrace] [-rayDepth {0..10}=3] [-reflections {on|off}=off]
|
|
[-fsaa {on|off}=off] [-gleam {on|off}=off] [-env {on|off}=off]
|
|
[-gi {on|off}=off] [-brng {on|off}=off]
|
|
[-iss {on|off}=off] [-tileSize {1..4096}=32] [-nbTiles {64..1024}=256]
|
|
[-ignoreNormalMap {on|off}=off] [-twoSide {on|off}=off]
|
|
[-maxRad {value>0}=30.0]
|
|
[-aperture {value>=0}=0.0] [-focal {value>=0.0}=1.0]
|
|
[-exposure value=0.0] [-whitePoint value=1.0] [-toneMapping {disabled|filmic}=disabled]
|
|
-rayTrace Enables GPU ray-tracing.
|
|
-rayDepth Defines maximum ray-tracing depth.
|
|
-reflections Enables/disables specular reflections.
|
|
-fsaa Enables/disables adaptive anti-aliasing.
|
|
-gleam Enables/disables transparency shadow effects.
|
|
-gi Enables/disables global illumination effects (Path-Tracing).
|
|
-env Enables/disables environment map background.
|
|
-ignoreNormalMap Enables/disables normal map ignoring during path tracing.
|
|
-twoSide Enables/disables two-sided BSDF models (PT mode).
|
|
-iss Enables/disables adaptive screen sampling (PT mode).
|
|
-maxRad Value used for clamping radiance estimation (PT mode).
|
|
-tileSize Specifies size of screen tiles in ISS mode (32 by default).
|
|
-nbTiles Specifies number of screen tiles per Redraw in ISS mode (256 by default).
|
|
-aperture Aperture size of perspective camera for depth-of-field effect (0 disables DOF).
|
|
-focal Focal distance of perspective camera for depth-of-field effect.
|
|
-exposure Exposure value for tone mapping (0.0 value disables the effect).
|
|
-whitePoint White point value for filmic tone mapping.
|
|
-toneMapping Tone mapping mode (disabled, filmic).
|
|
|
|
PBR environment baking parameters (advanced/debug):
|
|
vrenderparams [-pbrEnvPow2size {power>0}=9] [-pbrEnvSMLN {levels>1}=6] [-pbrEnvBP {0..1}=0.99]
|
|
[-pbrEnvBDSN {samples>0}=1024] [-pbrEnvBSSN {samples>0}=256]
|
|
-pbrEnvPow2size Controls size of IBL maps (real size can be calculates as 2^pbrenvpow2size).
|
|
-pbrEnvSMLN Controls number of mipmap levels used in specular IBL map.
|
|
-pbrEnvBDSN Controls number of samples in Monte-Carlo integration during
|
|
diffuse IBL map's sherical harmonics calculation.
|
|
-pbrEnvBSSN Controls maximum number of samples per mipmap level
|
|
in Monte-Carlo integration during specular IBL maps generation.
|
|
-pbrEnvBP Controls strength of samples number reducing
|
|
during specular IBL maps generation (1 disables reducing).
|
|
|
|
Debug options:
|
|
vrenderparams [-issd {on|off}=off] [-rebuildGlsl on|off]
|
|
-issd Shows screen sampling distribution in ISS mode.
|
|
-rebuildGlsl Rebuild Ray-Tracing GLSL programs (for debugging).
|
|
-brng Enables/disables blocked RNG (fast coherent PT).
|
|
)" /* [vrenderparams] */);
|
|
|
|
addCmd ("vstatprofiler", VStatProfiler, /* [vstatprofiler] */ R"(
|
|
vstatprofiler [fps|cpu|allLayers|layers|allstructures|structures|groups
|
|
|allArrays|fillArrays|lineArrays|pointArrays|textArrays
|
|
|triangles|points|geomMem|textureMem|frameMem
|
|
|elapsedFrame|cpuFrameAverage|cpuPickingAverage|cpuCullingAverage|cpuDynAverage
|
|
|cpuFrameMax|cpuPickingMax|cpuCullingMax|cpuDynMax]
|
|
[-noredraw]
|
|
Prints rendering statistics for specified counters or for all when unspecified.
|
|
Set '-noredraw' flag to avoid additional redraw call and use already collected values.
|
|
)" /* [vstatprofiler] */);
|
|
|
|
addCmd ("vplace", VPlace, /* [vplace] */ R"(
|
|
vplace dx dy : Places the point (in pixels) at the center of the window
|
|
)" /* [vplace] */);
|
|
|
|
addCmd ("vxrotate", VXRotate, /* [vxrotate] */ R"(
|
|
vxrotate
|
|
)" /* [vxrotate] */);
|
|
|
|
addCmd ("vmanipulator", VManipulator, /* [vmanipulator] */ R"(
|
|
vmanipulator Name [-attach AISObject | -detach | ...]
|
|
Tool to create and manage AIS manipulators.
|
|
Options:
|
|
'-attach AISObject' attach manipulator to AISObject
|
|
'-adjustPosition {0|center|location|shapeLocation}' adjust position when attaching
|
|
'-adjustSize {0|1}' adjust size when attaching
|
|
'-enableModes {0|1}' enable modes when attaching
|
|
'-view {active | [name of view]}' display manipulator only in defined view,
|
|
by default it is displayed in all views of the current viewer
|
|
'-detach' detach manipulator
|
|
'-startTransform mouse_x mouse_y' - invoke start of transformation
|
|
'-transform mouse_x mouse_y' - invoke transformation
|
|
'-stopTransform [abort]' - invoke stop of transformation
|
|
'-move x y z' - move attached object
|
|
'-rotate x y z dx dy dz angle' - rotate attached object
|
|
'-scale factor' - scale attached object
|
|
'-autoActivate {0|1}' - set activation on detection
|
|
'-followTranslation {0|1}' - set following translation transform
|
|
'-followRotation {0|1}' - set following rotation transform
|
|
'-followDragging {0|1}' - set following dragging transform
|
|
'-gap value' - set gap between sub-parts
|
|
'-part axis mode {0|1}' - set visual part
|
|
'-parts axis mode {0|1}' - set visual part
|
|
'-pos x y z [nx ny nz [xx xy xz]' - set position of manipulator
|
|
'-size value' - set size of manipulator
|
|
'-zoomable {0|1}' - set zoom persistence
|
|
)" /* [vmanipulator] */);
|
|
|
|
addCmd ("vselprops", VSelectionProperties, /* [vselprops] */ R"(
|
|
vselprops [dynHighlight|localDynHighlight|selHighlight|localSelHighlight] [options]
|
|
Customizes selection and dynamic highlight parameters for the whole interactive context:
|
|
-autoActivate {0|1} disables|enables default computation
|
|
and activation of global selection mode
|
|
-autoHighlight {0|1} disables|enables automatic highlighting in 3D Viewer
|
|
-highlightSelected {0|1} disables|enables highlighting of detected object in selected state
|
|
-pickStrategy {first|topmost} : defines picking strategy
|
|
'first' to pick first acceptable (default)
|
|
'topmost' to pick only topmost (and nothing, if topmost is rejected by filters)
|
|
-pixTol value sets up pixel tolerance
|
|
-depthTol {uniform|uniformpx} value : sets tolerance for sorting results by depth
|
|
-depthTol {sensfactor} use sensitive factor for sorting results by depth
|
|
-preferClosest {0|1} sets if depth should take precedence over priority while sorting results
|
|
-dispMode dispMode sets display mode for highlighting
|
|
-layer ZLayer sets ZLayer for highlighting
|
|
-color {name|r g b} sets highlight color
|
|
-transp value sets transparency coefficient for highlight
|
|
-material material sets highlight material
|
|
-print prints current state of all mentioned parameters
|
|
)" /* [vselprops] */);
|
|
|
|
addCmd ("vhighlightselected", VSelectionProperties, /* [vhighlightselected] */ R"(
|
|
vhighlightselected [0|1] : alias for vselprops -highlightSelected.
|
|
)" /* [vhighlightselected] */);
|
|
|
|
addCmd ("vseldump", VDumpSelectionImage, /* [vseldump] */ R"(
|
|
vseldump file -type {depth|unnormDepth|object|owner|selMode|entity|entityType|surfNormal}=depth
|
|
-pickedIndex Index=1
|
|
[-xrPose base|head=base]
|
|
Generate an image based on detection results:
|
|
depth normalized depth values
|
|
unnormDepth unnormalized depth values
|
|
object color of detected object
|
|
owner color of detected owner
|
|
selMode color of selection mode
|
|
entity color of detected entity
|
|
entityType color of detected entity type
|
|
surfNormal normal direction values
|
|
)" /* [vseldump] */);
|
|
|
|
addCmd ("vviewcube", VViewCube, /* [vviewcube] */ R"(
|
|
vviewcube name
|
|
Displays interactive view manipulation object. Options:
|
|
-reset reset geometric and visual attributes
|
|
-size Size adapted size of View Cube
|
|
-boxSize Size box size
|
|
-axes {0|1} show/hide axes (trihedron)
|
|
-edges {0|1} show/hide edges of View Cube
|
|
-vertices {0|1} show/hide vertices of View Cube
|
|
-Yup {0|1} -Zup {0|1} set Y-up or Z-up view orientation
|
|
-color Color color of View Cube
|
|
-boxColor Color box color
|
|
-boxSideColor Color box sides color
|
|
-boxEdgeColor Color box edges color
|
|
-boxCornerColor Color box corner color
|
|
-textColor Color color of side text of view cube
|
|
-innerColor Color inner box color
|
|
-transparency Value transparency of object within [0, 1] range
|
|
-boxTransparency Value transparency of box within [0, 1] range
|
|
-xAxisTextColor Color color of X axis label
|
|
-yAxisTextColor Color color of Y axis label
|
|
-zAxisTextColor Color color of Z axis label
|
|
-font Name font name
|
|
-fontHeight Value font height
|
|
-boxFacetExtension Value box facet extension
|
|
-boxEdgeGap Value gap between box edges and box sides
|
|
-boxEdgeMinSize Value minimal box edge size
|
|
-boxCornerMinSize Value minimal box corner size
|
|
-axesPadding Value padding between box and arrows
|
|
-roundRadius Value relative radius of corners of sides within [0.0, 0.5] range
|
|
-axesRadius Value radius of axes of the trihedron
|
|
-axesConeRadius Value radius of the cone (arrow) of the trihedron
|
|
-axesSphereRadius Value radius of the sphere (central point) of trihedron
|
|
-fixedAnimation {0|1} uninterruptible animation loop
|
|
-duration Seconds animation duration in seconds
|
|
)" /* [vviewcube] */);
|
|
|
|
addCmd ("vcolorconvert", VColorConvert, /* [vcolorconvert] */ R"(
|
|
vcolorconvert [-from {sRGB|HLS|Lab|Lch|RGB}]=RGB [-to {sRGB|HLS|Lab|Lch|RGB|hex|name}]=RGB C1 C2 C2
|
|
To convert color from specified color space to linear RGB:
|
|
vcolorconvert -from {sRGB|HLS|Lab|Lch|RGB} C1 C2 C2
|
|
To convert linear RGB color to specified color space:
|
|
vcolorconvert -to {sRGB|HLS|Lab|Lch|RGB|hex|name} R G B
|
|
)" /* [vcolorconvert] */);
|
|
|
|
addCmd ("vcolordiff", VColorDiff, /* [vcolordiff] */ R"(
|
|
vcolordiff R1 G1 B1 R2 G2 B2 : returns CIEDE2000 color difference between two RGB colors.
|
|
)" /* [vcolordiff] */);
|
|
|
|
addCmd ("vselbvhbuild", VSelBvhBuild, /* [vselbvhbuild] */ R"(
|
|
vselbvhbuild [{0|1}] [-nbThreads value] [-wait]
|
|
Turns on/off prebuilding of BVH within background thread(s).
|
|
-nbThreads number of threads, 1 by default; if < 1 then used (NbLogicalProcessors - 1);
|
|
-wait waits for building all of BVH.
|
|
)" /* [vselbvhbuild] */);
|
|
|
|
addCmd ("vchangemousegesture", VChangeMouseGesture, /* [vchangemousegesture] */ R"(
|
|
vchangemousegesture -button {none|left|middle|right}=left
|
|
-gesture {none|selectRectangle|selectLasso|zoom|zoomWindow|pan|rotateOrbit|rotateView|drag}=rotateOrbit
|
|
Changes the gesture for the mouse button.
|
|
-button the mouse button;
|
|
-gesture the new gesture for the button.
|
|
)" /* [vchangemousegesture] */);
|
|
}
|