diff --git a/Documentation/release/dev/spacemouse-plugin.md b/Documentation/release/dev/spacemouse-plugin.md new file mode 100644 index 0000000000000000000000000000000000000000..3c6050c0c9219577075a0566c5b7da7d135f4343 --- /dev/null +++ b/Documentation/release/dev/spacemouse-plugin.md @@ -0,0 +1,10 @@ +## Add SpaceMouseInteractor plugin, controlling the camera with a SpaceMouse + +Using the 3DxWareSDK provided by 3Dconnexion, connect to a SpaceMouse +if it is available, and use it to manipulate the camera in the active +renderview. The 3Dconnexion Settings app provided with the driver +can be used to change the style of interaction from object-centered +to camera-centered (flying). + +Only works on Windows currently. A linux SDK is not available, but +an equivalent Mac implementation is planned. diff --git a/Plugins/SpaceMouseInteractor/CMakeLists.txt b/Plugins/SpaceMouseInteractor/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8e12ddc8a34d4894643f83f3ccfa9f4f7af6819f --- /dev/null +++ b/Plugins/SpaceMouseInteractor/CMakeLists.txt @@ -0,0 +1,52 @@ +# so we can use our local Find3DxWareSDK.cmake +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +set(interfaces) +set(sources) +if (PARAVIEW_USE_QT) + list(APPEND sources + pqSpaceMouseAutoStart.cxx + pqSpaceMouseAutoStart.h) + paraview_plugin_add_auto_start( + CLASS_NAME pqSpaceMouseAutoStart + INTERFACES autostart_interface + SOURCES autostart_sources) + list(APPEND interfaces + ${autostart_interface}) + list(APPEND sources + ${autostart_sources}) + if (WIN32) + list(APPEND sources + pqSpaceMouseImplWin.cxx + pqSpaceMouseImplWin.h) + find_package(3DxWareSDK) + else() + # this is a do-nothing implementation for now + list(APPEND sources + pqSpaceMouseImplLinux.cxx + pqSpaceMouseImplLinux.h) + endif() +endif () + + +set(CMAKE_CXX_STANDARD 11) +paraview_add_plugin(SpaceMouseInteractor + VERSION "1.0" + UI_INTERFACES ${interfaces} + SOURCES ${sources}) + +if (PARAVIEW_USE_QT) + target_link_libraries(SpaceMouseInteractor + PRIVATE + ParaView::RemotingApplication + ParaView::RemotingCore + ParaView::RemotingServerManager + ParaView::RemotingViews + ParaView::pqApplicationComponents) + if (WIN32) + target_link_libraries(SpaceMouseInteractor + PRIVATE + 3Dconnexion::3DxWareSDK) + endif() + target_compile_definitions(SpaceMouseInteractor PRIVATE QT_NO_KEYWORDS) +endif () diff --git a/Plugins/SpaceMouseInteractor/cmake/Find3DxWareSDK.cmake b/Plugins/SpaceMouseInteractor/cmake/Find3DxWareSDK.cmake new file mode 100644 index 0000000000000000000000000000000000000000..bfc387c12071133692f543b2c1ea0589236b52d0 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/cmake/Find3DxWareSDK.cmake @@ -0,0 +1,87 @@ +#[=======================================================================[ +Find3DxWareSDK +-------- + +Find 3DxWareSDK. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines :prop_tgt:`IMPORTED` target ``3Dconnexion::3DxWareSDK`` +if 3DxWareSDK has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``3DxWareSDK_FOUND`` + True if 3DxWareSDK is found. +``3DxWareSDK_INCLUDE_DIRS`` + Include directories for 3DxWareSDK headers. +``3DxWareSDK_LIBRARIES`` + Libraries to link to 3DxWareSDK. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``3DxWareSDK_LIBRARY`` + The lib3DxWareSDK library file. +``3DxWareSDK_INCLUDE_DIR`` + The directory containing ``3DxWareSDK.h``. + +Hints +^^^^^ + +Set ``3DxWareSDK_DIR`` or ``3DxWareSDK_ROOT`` in the environment to specify the +3DxWareSDK installation prefix. +example : 3DxWareSDK_DIR = C:/projects/3DxWare_SDK_v4-0-2_r17624 +#]=======================================================================] +# +# This makes the presumption that you include navlib.h like +# +#include "navlib/navlib.h" + +find_path(3DxWareSDK_INCLUDE_DIR navlib/navlib.h + HINTS + ${3DxWareSDK_ROOT} + ENV 3DxWareSDK_DIR + ENV 3DxWareSDK_ROOT + PATH_SUFFIXES + inc + include + DOC "Path to the 3DxWareSDK include directory" +) +mark_as_advanced(3DxWareSDK_INCLUDE_DIR) + +find_library(3DxWareSDK_LIBRARY + NAMES TDxNavLib + HINTS + ${3DxWareSDK_ROOT} + ENV 3DxWareSDK_DIR + ENV 3DxWareSDK_ROOT + PATH_SUFFIXES + lib/x64 + lib/x86 + lib + DOC "Path to the 3DxWareSDK library" +) +mark_as_advanced(3DxWareSDK_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(3DxWareSDK + REQUIRED_VARS 3DxWareSDK_LIBRARY 3DxWareSDK_INCLUDE_DIR) + +if (3DxWareSDK_FOUND) + set(3DxWareSDK_LIBRARIES ${3DxWareSDK_LIBRARY}) + set(3DxWareSDK_INCLUDE_DIRS ${3DxWareSDK_INCLUDE_DIR}) + + if (NOT TARGET 3Dconnexion::3DxWareSDK) + add_library(3Dconnexion::3DxWareSDK UNKNOWN IMPORTED) + set_target_properties(3Dconnexion::3DxWareSDK PROPERTIES + IMPORTED_LOCATION "${3DxWareSDK_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${3DxWareSDK_INCLUDE_DIR}") + endif () +endif () diff --git a/Plugins/SpaceMouseInteractor/paraview.plugin b/Plugins/SpaceMouseInteractor/paraview.plugin new file mode 100644 index 0000000000000000000000000000000000000000..84ee47975222d23c309f695bbaf46393355baa49 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/paraview.plugin @@ -0,0 +1,18 @@ +NAME + SpaceMouseInteractor +DESCRIPTION + SpaceMouse from 3Dconnexion +REQUIRES_MODULES + ParaView::RemotingApplication + ParaView::RemotingCore + ParaView::RemotingServerManager + ParaView::RemotingViews + ParaView::pqApplicationComponents + ParaView::VTKExtensionsMisc + VTK::CommonCore + VTK::CommonDataModel + VTK::CommonExecutionModel + VTK::CommonMath + VTK::CommonTransforms + VTK::FiltersGeneral + VTK::ImagingCore diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.cxx b/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.cxx new file mode 100644 index 0000000000000000000000000000000000000000..452a3ce89efcd85ecdd1f6f32938055d7755f82b --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.cxx @@ -0,0 +1,85 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseAutoStart.cxx + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4201) // nonstandard extension, nameless union +#endif + +#include "pqSpaceMouseAutoStart.h" +#ifdef _MSC_VER +#include "pqSpaceMouseImplWin.h" +#else +#include "pqSpaceMouseImplLinux.h" +#endif + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "pqActiveObjects.h" + +#include "vtkLogger.h" +#include "vtkObject.h" + +#include + +//----------------------------------------------------------------------------- +pqSpaceMouseAutoStart::pqSpaceMouseAutoStart(QObject* parentObject) + : Superclass(parentObject) + , m_p(new pqSpaceMouseImpl()) +{ +} + +//----------------------------------------------------------------------------- +pqSpaceMouseAutoStart::~pqSpaceMouseAutoStart() +{ + delete m_p; +} + +//----------------------------------------------------------------------------- +void pqSpaceMouseAutoStart::startup() +{ + connect(&pqActiveObjects::instance(), &pqActiveObjects::viewChanged, m_p, + &pqSpaceMouseImpl::setActiveView); + m_p->setActiveView(pqActiveObjects::instance().activeView()); +} + +//----------------------------------------------------------------------------- +void pqSpaceMouseAutoStart::shutdown() +{ + m_p->setActiveView(nullptr); +} + +// void pqSpaceMouseAutoStart::setActiveView(pqView* view) +// { +// m_p->setActiveView(view); +// } diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.h b/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.h new file mode 100644 index 0000000000000000000000000000000000000000..7188761120970ac93db12c2f5e3ec7ac44e2f8f6 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseAutoStart.h @@ -0,0 +1,61 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseAutoStart.h + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#ifndef pqSpaceMouseAutoStart_h +#define pqSpaceMouseAutoStart_h + +#include + +class pqSpaceMouseImpl; +class pqView; + +class pqSpaceMouseAutoStart : public QObject +{ + Q_OBJECT + typedef QObject Superclass; + +public: + pqSpaceMouseAutoStart(QObject* parent = nullptr); + ~pqSpaceMouseAutoStart() override; + + void startup(); + void shutdown(); + + // public Q_SLOTS: + // void setActiveView(pqView* view); + +private: + Q_DISABLE_COPY(pqSpaceMouseAutoStart) + + pqSpaceMouseImpl* m_p; +}; + +#endif diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.cxx b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.cxx new file mode 100644 index 0000000000000000000000000000000000000000..69a7e2cb6880727d13740ffa0abe8d93edcc2884 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.cxx @@ -0,0 +1,83 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseImpl.cxx + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#include "pqSpaceMouseImplLinux.h" + +#include "pqActiveObjects.h" +#include "pqCoreUtilities.h" +#include "pqRenderView.h" +#include "vtkSMPropertyHelper.h" +#include "vtkSMRenderViewProxy.h" + +#include "vtkLogger.h" +#include "vtkMatrix4x4.h" +#include "vtkObject.h" +#include "vtkTransform.h" + +#include + +pqSpaceMouseImpl::pqSpaceMouseImpl() {} + +pqSpaceMouseImpl::~pqSpaceMouseImpl() = default; + +void pqSpaceMouseImpl::setActiveView(pqView* view) +{ + pqRenderView* rview = qobject_cast(view); + vtkSMRenderViewProxy* renPxy = rview ? rview->getRenderViewProxy() : nullptr; + + this->Camera = nullptr; + if (renPxy) + { + // this->Enable3DNavigation(); + this->Camera = renPxy->GetActiveCamera(); + // if (this->Camera) + // { + // pqCoreUtilities::connect( + // this->Camera, vtkCommand::ModifiedEvent, this, SLOT(cameraChanged())); + // } + // this->cameraChanged(); + } + else + { + // this->Disable3DNavigation(); + } +} + +void pqSpaceMouseImpl::cameraChanged() {} + +void pqSpaceMouseImpl::render() +{ + pqRenderView* view = qobject_cast(pqActiveObjects::instance().activeView()); + if (view) + { + view->render(); + } +} diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.h b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.h new file mode 100644 index 0000000000000000000000000000000000000000..e75ab037a03205279b5d6342fbe0076287a7f3e3 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplLinux.h @@ -0,0 +1,62 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseImplLinux.h + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#ifndef pqSpaceMouseImplLinux_h +#define pqSpaceMouseImplLinux_h +#include "vtkCamera.h" +#include "vtkWeakPointer.h" + +#include +class pqView; + +/// Placeholder for non-windows platforms +class pqSpaceMouseImpl : public QObject +{ + Q_OBJECT + +public: + pqSpaceMouseImpl(); + ~pqSpaceMouseImpl() override; + +public Q_SLOTS: + /// which view are we controlling? The active one. + void setActiveView(pqView* view); + /// the active camera changed. + void cameraChanged(); + +public: + void render(); + +protected: + vtkWeakPointer Camera; +}; + +#endif diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.cxx b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a23d9a9533529103394e7c9b07a21e8ca38338a1 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.cxx @@ -0,0 +1,480 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseImpl.cxx + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4201) // nonstandard extension, nameless union +// #pragma warning(disable: 4100) // unused params +#endif + +#include "pqSpaceMouseImplWin.h" + +#include "pqActiveObjects.h" +#include "pqCoreUtilities.h" +#include "pqRenderView.h" +#include "vtkInitializationHelper.h" +#include "vtkSMPropertyHelper.h" +#include "vtkSMRenderViewProxy.h" + +#include "vtkLogger.h" +#include "vtkMatrix4x4.h" +#include "vtkObject.h" +#include "vtkTransform.h" + +#include + +#define _USE_MATH_DEFINES +#include +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 +#endif + +#define APPLICATION_HAS_ANIMATION_LOOP 0 + +pqSpaceMouseImpl::pqSpaceMouseImpl() + : CNavigation3D(false, true) +{ +} + +pqSpaceMouseImpl::~pqSpaceMouseImpl() = default; + +void pqSpaceMouseImpl::setActiveView(pqView* view) +{ + pqRenderView* rview = qobject_cast(view); + vtkSMRenderViewProxy* renPxy = rview ? rview->getRenderViewProxy() : nullptr; + + this->Camera = nullptr; + if (renPxy) + { + this->Enable3DNavigation(); + this->Camera = renPxy->GetActiveCamera(); + // if (this->Camera) + // { + // pqCoreUtilities::connect( + // this->Camera, vtkCommand::ModifiedEvent, this, SLOT(cameraChanged())); + // } + // this->cameraChanged(); + } + else + { + this->Disable3DNavigation(); + } +} + +void pqSpaceMouseImpl::cameraChanged() +{ + // vtkWarningWithObjectMacro(nullptr, "CameraChanged"); + if (this->Camera) + { + double pos[3]; + this->Camera->GetPosition(pos); + double dp[3]; + this->Camera->GetDirectionOfProjection(dp); + double vu[3]; + this->Camera->GetViewUp(vu); + // auto* fp = this->Camera->GetFocalPoint(); + // vtkWarningWithObjectMacro(nullptr, << "ps " << pos[0] << " " << pos[1] << " " << pos[2] ); + // vtkWarningWithObjectMacro(nullptr, << "dp " << dp[0] << " " << dp[1] << " " << dp[2] ); + // vtkWarningWithObjectMacro(nullptr, << "vu " << vu[0] << " " << vu[1] << " " << vu[2] ); + // double m[16], n[16]; + // vtkMatrix4x4::DeepCopy(m, this->Camera->GetModelViewTransformMatrix()); + // vtkWarningWithObjectMacro(nullptr, << "vtkCM [" << m[0] << ", " << m[1] << ", " << m[2] << ", + // " << m[3] << "] [" << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << "] [" << m[8] + // << ", " << m[9] << ", " << m[10] << ", " << m[11] << "] [" << m[12] << ", " << m[13] << ", " + // << m[14] << ", " << m[15] << "] " ); vtkMatrix4x4::Invert(m, n); + // vtkWarningWithObjectMacro(nullptr, << "invCM [" << n[0] << ", " << n[1] << ", " << n[2] << ", + // " << n[3] << "] [" << n[4] << ", " << n[5] << ", " << n[6] << ", " << n[7] << "] [" << n[8] + // << ", " << n[9] << ", " << n[10] << ", " << n[11] << "] [" << n[12] << ", " << n[13] << ", " + // << n[14] << ", " << n[15] << "] " ); + } +} + +void pqSpaceMouseImpl::render() +{ + pqRenderView* view = qobject_cast(pqActiveObjects::instance().activeView()); + if (view) + { + view->render(); + } +} + +// Following methods were copied from +// 3DxWare_SDK_v4-0-2_r17624/samples/navlib_viewer/src/mainfrm.cpp and follow the recommendations of +// 3DxWare_SDK_v4-0-2_r17624/doc/quick_guide.pdf + +///////////////////////////////////////////////////////////////////////////// +// navlib + +/// Shutdown the connection to the navlib +void pqSpaceMouseImpl::Disable3DNavigation() +{ + nav3d::Enable = false; +} + +/// Open the connection to the navlib and expose the property interface +/// functions +bool pqSpaceMouseImpl::Enable3DNavigation() +{ + try + { + // Set the hint/title for the '3Dconnexion Properties' Utility. + std::string title = vtkInitializationHelper::GetApplicationName(); + nav3d::Profile = title.empty() ? "ParaView" : title; + + // Enable input from / output to the Navigation3D controller. + nav3d::Enable = true; + +#if APPLICATION_HAS_ANIMATION_LOOP + // Use the application render loop as the timing source for the frames + nav3d::FrameTiming = TimingSource::Application; +#else + // Use the SpaceMouse as the timing source for the frames. + nav3d::FrameTiming = TimingSource::SpaceMouse; +#endif + } + catch (const std::exception&) + { + return false; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////// +// The get property assessors +long pqSpaceMouseImpl::GetModelExtents(navlib::box_t& bbox) const +{ + pqRenderView* view = qobject_cast(pqActiveObjects::instance().activeView()); + if (view) + { + // by moving some default bounds to the center-of-rotation, navlib uses our CoR. + std::vector cor = + vtkSMPropertyHelper(view->getProxy(), "CenterOfRotation").GetDoubleArray(); + bbox.min = { { cor[0] - 1., cor[1] - 1., cor[2] - 1. } }; + bbox.max = { { cor[0] + 1., cor[1] + 1., cor[2] + 1. } }; + return 0; + } + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetIsSelectionEmpty(navlib::bool_t& /*empty*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetSelectionExtents(navlib::box_t& /*bbox*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetViewConstructionPlane(navlib::plane_t& /*plane*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetViewExtents(navlib::box_t& /*extents*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetViewFOV(double& fov) const +{ + if (this->Camera) + { + fov = this->Camera->GetViewAngle() * M_PI / 180.0; + return 0; + } + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetViewFrustum(navlib::frustum_t& /*frustum*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Get whether the view can be rotated +/// true if the view can be rotated +/// 0 on success otherwise an error +long pqSpaceMouseImpl::GetIsViewRotatable(navlib::bool_t& rotatable) const +{ + if (this->Camera) + { + rotatable = true; + return 0; + } + + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::IsUserPivot(navlib::bool_t& userPivot) const +{ + // pivot is always the center-of-rotation supplied by PV + userPivot = true; + return 0; +} + +/// Get the affine of the coordinate system +/// the world to navlib transformation +/// 0 on success otherwise an error +long pqSpaceMouseImpl::GetCoordinateSystem(navlib::matrix_t& affine) const +{ + // Y-Up rhs + navlib::matrix_t cs = { 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1. }; + + affine = cs; + + return 0; +} + +/// Get the affine of the view +/// the camera to world transformation +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::GetCameraMatrix(navlib::matrix_t& affine) const +{ + if (this->Camera) + { + double* m = this->Camera->GetModelViewTransformMatrix()->GetData(); + // vtkWarningWithObjectMacro(nullptr, << "vtkCM [" << m[0] << ", " << m[1] << ", " << m[2] << ", + // " << m[3] << "] [" << m[4] << ", " << m[5] << ", " << m[6] << ", " << m[7] << "] [" << m[8] + // << ", " << m[9] << ", " << m[10] << ", " << m[11] << "] [" << m[12] << ", " << m[13] << ", " + // << m[14] << ", " << m[15] << "] " ); VTK supplies the world-to-camera tranform, so we must + // invert. + vtkMatrix4x4::Invert(m, affine.m); + return 0; + } + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/////////////////////////////////////////////////////////////////////////// +// Handle navlib hit testing requests + +/// Get the position of the point hit +/// the hit point +/// 0 when something is hit, otherwise navlib::navlib_errc::no_data_available +long pqSpaceMouseImpl::GetHitLookAt(navlib::point_t& /*position*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Get the position of the rotation pivot in world coordinates +/// the position of the pivot +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::GetPivotPosition(navlib::point_t& position) const +{ + pqRenderView* view = qobject_cast(pqActiveObjects::instance().activeView()); + if (view) + { + std::vector cor = + vtkSMPropertyHelper(view->getProxy(), "CenterOfRotation").GetDoubleArray(); + position.x = cor[0]; + position.y = cor[1]; + position.z = cor[2]; + return 0; + } + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetPivotVisible(navlib::bool_t& /*visible*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Get the position of the mouse cursor on the projection plane in world +/// coordinates +/// the position of the mouse cursor +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::GetPointerPosition(navlib::point_t& /*position*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Get the whether the view is a perspective projection +/// true when the projection is perspective +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::GetIsViewPerspective(navlib::bool_t& persp) const +{ + if (this->Camera) + { + persp = !this->Camera->GetParallelProjection(); + return 0; + } + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// set property handlers (mutators) +// + +/// Sets the moving property value. +/// true when moving. +/// 0 on success, otherwise an error. +/// The navlib sets this to true at the beginning of navigation. +long pqSpaceMouseImpl::SetMotionFlag(bool /*value*/) +{ + return 0; +} + +/// Sets the transaction property value +/// !0 at the beginning of a frame;0 at the end of a +/// frame 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetTransaction(long /*value*/) +{ + return 0; +} + +/// Sets the affine of the view +/// The camera to world transformation +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetCameraMatrix(const navlib::matrix_t& affine) +{ + if (this->Camera) + { + // VTK wants the world-to-camera transform, so invert to retrieve the + // position in world coords. + double m[16]; + double inv[16]; + vtkMatrix4x4::Invert(affine.m, m); + vtkMatrix4x4::DeepCopy(inv, affine.m); + + double pos[3] = { inv[3], inv[7], inv[11] }; + double lk[3] = { -m[8], -m[9], -m[10] }; + double vu[3] = { m[4], m[5], m[6] }; + // vtkWarningWithObjectMacro(nullptr, << "SM ps " << pos[0] << " " << pos[1] << " " << pos[2] ); + // vtkWarningWithObjectMacro(nullptr, << "SM lk " << lk[0] << " " << lk[1] << " " << lk[2] ); + // vtkWarningWithObjectMacro(nullptr, << "SM vu " << vu[0] << " " << vu[1] << " " << vu[2] ); + double dist = this->Camera->GetDistance(); + // Set the new values on the camera. + double fp[3] = { pos[0] + dist * lk[0], pos[1] + dist * lk[1], pos[2] + dist * lk[2] }; + this->Camera->SetPosition(pos); + this->Camera->SetFocalPoint(fp); + this->Camera->SetViewUp(vu); + this->render(); + return 0; + } + + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::GetSelectionTransform(navlib::matrix_t& /*affine*/) const +{ + return navlib::make_result_code(navlib::navlib_errc::function_not_supported); +} + +long pqSpaceMouseImpl::SetSelectionTransform(const navlib::matrix_t& /*affine*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the extents of the view +/// The view extents +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetViewExtents(const navlib::box_t& /*extents*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the visibility of the pivot +/// true to display the pivot +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetPivotVisible(bool /*show*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the position of the pivot +/// The position of the pivot in world +/// coordinates 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetPivotPosition(const navlib::point_t& /*position*/) +{ + return 0; +} + +/// Sets the vertical field of view +/// The fov in radians +/// 0 on success, otherwise an error. +long pqSpaceMouseImpl::SetViewFOV(double /*fov*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +long pqSpaceMouseImpl::SetViewFrustum(const navlib::frustum_t& /*frustum*/) +{ + return navlib::make_result_code(navlib::navlib_errc::function_not_supported); +} + +/////////////////////////////////////////////////////////////////////////// +// Handle navlib hit testing parameters + +/// Sets the diameter of the aperture in the projection plane to look through. +/// The diameter of the hole/ray in world units. +long pqSpaceMouseImpl::SetHitAperture(double /*diameter*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the direction to look +/// Unit vector in world coordinates +long pqSpaceMouseImpl::SetHitDirection(const navlib::vector_t& /*direction*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the position to look from +/// Position in world coordinates +long pqSpaceMouseImpl::SetHitLookFrom(const navlib::point_t& /*position*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +/// Sets the selection only hit filter +/// If true then filter non-selected objects +long pqSpaceMouseImpl::SetHitSelectionOnly(bool /*value*/) +{ + return navlib::make_result_code(navlib::navlib_errc::invalid_operation); +} + +////////////////////////////////////////////////////////////////////////////////////// + +/// Handle when a command is activated by a mouse button press +long pqSpaceMouseImpl::SetActiveCommand(std::string /*commandId*/) +{ + return 0; +} + +/// Handler for settings_changed event +long pqSpaceMouseImpl::SetSettingsChanged(long /*change*/) +{ + return 0; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.h b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.h new file mode 100644 index 0000000000000000000000000000000000000000..0277057c75f40e3f9beb36b72b6bbb2289b80030 --- /dev/null +++ b/Plugins/SpaceMouseInteractor/pqSpaceMouseImplWin.h @@ -0,0 +1,115 @@ +/*========================================================================= + + Program: ParaView + Module: pqSpaceMouseImpl.h + + Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc. + All rights reserved. + + ParaView is a free software; you can redistribute it and/or modify it + under the terms of the ParaView license version 1.2. + + See License_v1.2.txt for the full ParaView license. + A copy of this license can be obtained by contacting + Kitware Inc. + 28 Corporate Drive + Clifton Park, NY 12065 + USA + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +========================================================================*/ +#ifndef pqSpaceMouseImpl_h +#define pqSpaceMouseImpl_h + +// This header is provided in the 3DxWare SDK, in samples/navlib_viewer/src/SpaceMouse +// If you are not using paraview superbuild, it is simplest to copy the entire +// SpaceMouse directory to the ${3DxWareSDK_INCLUDE_DIR} directory +#include "SpaceMouse/CNavigation3D.hpp" +#include "vtkCamera.h" +#include "vtkWeakPointer.h" + +#include +class pqView; + +/// Communicate with the TDxNavlib SDK provided by 3DConnexion to move the camera with a SpaceMouse +class pqSpaceMouseImpl + : public QObject + , public TDx::SpaceMouse::Navigation3D::CNavigation3D +{ + Q_OBJECT + typedef TDx::SpaceMouse::Navigation3D::CNavigation3D nav3d; + typedef TDx::SpaceMouse::Navigation3D::CNavigation3D Superclass; + +public: + pqSpaceMouseImpl(); + ~pqSpaceMouseImpl() override; + +public Q_SLOTS: + /// which view are we controlling? The active one. + void setActiveView(pqView* view); + /// the active camera changed. + void cameraChanged(); + +public: + void render(); + + // navlib initialization + bool Enable3DNavigation(); + void Disable3DNavigation(); + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // accessors and mutators used by the navlib + // These are the functions supplied to the navlib in the accessors structure so that the navlib + // can query and update our (the clients) values. + long GetCoordinateSystem(navlib::matrix_t& affine) const override; + long GetViewConstructionPlane(navlib::plane_t& plane) const override; + long GetCameraMatrix(navlib::matrix_t& affine) const override; + long GetViewExtents(navlib::box_t& affine) const override; + long GetViewFrustum(navlib::frustum_t& frustum) const override; + long GetViewFOV(double& fov) const override; + long GetIsViewRotatable(navlib::bool_t& rotatble) const override; + long IsUserPivot(navlib::bool_t& userPivot) const override; + long GetPivotVisible(navlib::bool_t& visible) const override; + long GetPivotPosition(navlib::point_t& position) const override; + long GetPointerPosition(navlib::point_t& position) const override; + long GetIsViewPerspective(navlib::bool_t& persp) const override; + long GetModelExtents(navlib::box_t& extents) const override; + long GetIsSelectionEmpty(navlib::bool_t& empty) const override; + long GetSelectionExtents(navlib::box_t& extents) const override; + long GetSelectionTransform(navlib::matrix_t&) const override; + long GetHitLookAt(navlib::point_t& position) const override; + + long SetSettingsChanged(long change) override; + + long SetMotionFlag(bool value) override; + long SetTransaction(long value) override; + long SetCameraMatrix(const navlib::matrix_t& affine) override; + long SetSelectionTransform(const navlib::matrix_t& affine) override; + long SetViewExtents(const navlib::box_t& extents) override; + long SetViewFOV(double fov) override; + long SetViewFrustum(const navlib::frustum_t& frustum) override; + long SetPivotPosition(const navlib::point_t& position) override; + long SetPivotVisible(bool visible) override; + + long SetHitLookFrom(const navlib::point_t& position) override; + long SetHitDirection(const navlib::vector_t& direction) override; + long SetHitAperture(double diameter) override; + long SetHitSelectionOnly(bool value) override; + long SetActiveCommand(std::string commandId) override; + +protected: + vtkWeakPointer Camera; +}; + +#endif