From 44fdb52926fa7bdae49752054eb02c3018bc0081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Skowro=C5=84ski?= Date: Thu, 3 Aug 2023 11:51:21 +0200 Subject: [PATCH] Rework of the active molecule handling. --- avogadro/mainwindow.cpp | 5 +- avogadro/tdxcontroller.cpp | 188 ++++++++++++++++--------------------- avogadro/tdxcontroller.h | 61 ++++++------ 3 files changed, 118 insertions(+), 136 deletions(-) diff --git a/avogadro/mainwindow.cpp b/avogadro/mainwindow.cpp index 9bcfeb49..ce5f6f42 100644 --- a/avogadro/mainwindow.cpp +++ b/avogadro/mainwindow.cpp @@ -321,7 +321,10 @@ MainWindow::MainWindow(const QStringList& fileNames, bool disableSettings) GLWidget* glWidget = qobject_cast(m_multiViewWidget->activeWidget()); - m_TDxController = new TDxController(this, glWidget, &m_molecule); + m_TDxController = new TDxController(this, glWidget); + + connect(this, &MainWindow::moleculeChanged, m_TDxController, &TDxController::updateMolecule); + m_TDxController->enableController(); QMap> actionsMap = m_menuBuilder->getMenuActions(); diff --git a/avogadro/tdxcontroller.cpp b/avogadro/tdxcontroller.cpp index f100e50b..1d7c6f25 100644 --- a/avogadro/tdxcontroller.cpp +++ b/avogadro/tdxcontroller.cpp @@ -8,28 +8,26 @@ #include #include -#include -#include #include #include #include +#include +#include -#include #include -#include > +#include #include +#include > #include Avogadro::TDxController::TDxController( - MainWindow* const mainWindow, - Avogadro::QtOpenGL::GLWidget* const pGLWidget, - QtGui::Molecule** ppMolecule) + MainWindow* const mainWindow, Avogadro::QtOpenGL::GLWidget* const pGLWidget) : CNavigation3D(false, true) , QObject(mainWindow) , m_pRootNode(std::make_shared("User Interface")) , m_pGLWidget(pGLWidget) - , m_ppMolecule(ppMolecule) + , m_pMolecule(mainWindow->molecule()) , m_pGLRenderer(&pGLWidget->renderer()) , m_eyePosition({ 0.0, 0.0, 0.0 }) , m_lookDirection({ 0.0, 0.0, 0.0 }) @@ -49,7 +47,7 @@ Avogadro::TDxController::TDxController( m_rayOrigins[i].x = x; m_rayOrigins[i].y = y; } - + QString pivotImagePath = QCoreApplication::applicationDirPath(); #ifdef WIN32 @@ -82,7 +80,7 @@ void Avogadro::TDxController::enableController() } void Avogadro::TDxController::exportCommands( - const QMap> &actionsMap) + const QMap>& actionsMap) { if (errorCode) return; @@ -97,7 +95,7 @@ void Avogadro::TDxController::exportCommands( for (uint32_t i = 0; i < m_pRootNode->m_children.size(); i++) { pathCode.append(std::to_string(i)); pathCode.append("."); - commandSet.push_back(getCategory(pathCode, m_pRootNode->m_children[i])); + commandSet.push_back(getCategory(pathCode, m_pRootNode->m_children[i])); pathCode.clear(); } @@ -109,6 +107,19 @@ void Avogadro::TDxController::exportCommands( #endif } +void Avogadro::TDxController::updateMolecule(QtGui::Molecule* const pMolecule) +{ + if (pMolecule == nullptr) + return; + + m_pMolecule = pMolecule; + + navlib::box_t modelExtents; + + GetModelExtents(modelExtents); + Write(navlib::model_extents_k, modelExtents); +} + void Avogadro::TDxController::disableController() { EnableNavigation(false, errorCode); @@ -116,14 +127,12 @@ void Avogadro::TDxController::disableController() } void Avogadro::TDxController::addActions( - const std::string &path, - const std::shared_ptr &pNode, - const QList &actions) + const std::string& path, const std::shared_ptr& pNode, + const QList& actions) { if (path.empty()) { - std::copy(actions.begin(), - actions.end(), + std::copy(actions.begin(), actions.end(), std::back_inserter(pNode->m_actions)); return; } @@ -156,9 +165,9 @@ void Avogadro::TDxController::addActions( return; } -QAction *Avogadro::TDxController::decodeAction( - const std::string &pathCode, - const std::shared_ptr &pNode) const +QAction* Avogadro::TDxController::decodeAction( + const std::string& pathCode, + const std::shared_ptr& pNode) const { std::string indexString; std::string remainingPath; @@ -166,8 +175,7 @@ QAction *Avogadro::TDxController::decodeAction( for (auto itr = pathCode.begin(); itr != pathCode.end(); itr++) { if (*itr != '.') { indexString.push_back(*itr); - } - else { + } else { std::copy(itr + 1, pathCode.end(), std::back_inserter(remainingPath)); break; } @@ -193,7 +201,7 @@ QAction *Avogadro::TDxController::decodeAction( // Inherited via CNavigation3D // Getters -long Avogadro::TDxController::GetCameraMatrix(navlib::matrix_t &matrix) const +long Avogadro::TDxController::GetCameraMatrix(navlib::matrix_t& matrix) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -225,7 +233,7 @@ long Avogadro::TDxController::GetCameraMatrix(navlib::matrix_t &matrix) const } long Avogadro::TDxController::GetPointerPosition( - navlib::point_t &position) const + navlib::point_t& position) const { if (m_pGLRenderer == nullptr || m_pGLWidget == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -243,7 +251,7 @@ long Avogadro::TDxController::GetPointerPosition( return 0; } -long Avogadro::TDxController::GetViewExtents(navlib::box_t &extents) const +long Avogadro::TDxController::GetViewExtents(navlib::box_t& extents) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -257,12 +265,12 @@ long Avogadro::TDxController::GetViewExtents(navlib::box_t &extents) const return 0; } -long Avogadro::TDxController::GetViewFOV(double &fov) const +long Avogadro::TDxController::GetViewFOV(double& fov) const { return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -long Avogadro::TDxController::GetViewFrustum(navlib::frustum_t &frustum) const +long Avogadro::TDxController::GetViewFrustum(navlib::frustum_t& frustum) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -275,9 +283,9 @@ long Avogadro::TDxController::GetViewFrustum(navlib::frustum_t &frustum) const frustum.farVal = m_pGLRenderer->m_perspectiveFrustum[5]; return 0; } - + long Avogadro::TDxController::GetIsViewPerspective( - navlib::bool_t &perspective) const + navlib::bool_t& perspective) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -287,10 +295,8 @@ long Avogadro::TDxController::GetIsViewPerspective( return 0; } - TDx::SpaceMouse::CCategory Avogadro::TDxController::getCategory( - const std::string &pathCode, - const std::shared_ptr &pNode) + const std::string& pathCode, const std::shared_ptr& pNode) { TDx::SpaceMouse::CCategory result(pNode->m_nodeName, pNode->m_nodeName); @@ -304,26 +310,26 @@ TDx::SpaceMouse::CCategory Avogadro::TDxController::getCategory( } for (uint32_t i = 0u; i < pNode->m_actions.size(); i++) { - - if (pNode->m_actions[i]->iconText().isEmpty()) + + if (pNode->m_actions[i]->iconText().isEmpty()) continue; - std::string commandId(nextPathCode + std::to_string(i)); + std::string commandId(nextPathCode + std::to_string(i)); result.push_back(TDx::SpaceMouse::CCommand( - commandId, - pNode->m_actions[i]->iconText().toStdString(), - pNode->m_actions[i]->toolTip().toStdString())); - + commandId, pNode->m_actions[i]->iconText().toStdString(), + pNode->m_actions[i]->toolTip().toStdString())); + #ifdef WIN32 - const QIcon iconImg = pNode->m_actions[i]->icon(); + const QIcon iconImg = pNode->m_actions[i]->icon(); const QImage qimage = iconImg.pixmap(QSize(256, 256)).toImage(); QByteArray qbyteArray; QBuffer qbuffer(&qbyteArray); qimage.save(&qbuffer, "PNG"); - TDx::CImage icon = TDx::CImage::FromData(qbyteArray.toStdString(), 0, commandId.c_str()); + TDx::CImage icon = + TDx::CImage::FromData(qbyteArray.toStdString(), 0, commandId.c_str()); m_utilityIcons.push_back(icon); #endif @@ -331,43 +337,25 @@ TDx::SpaceMouse::CCategory Avogadro::TDxController::getCategory( return result; } -long Avogadro::TDxController::GetModelExtents(navlib::box_t &extents) const +long Avogadro::TDxController::GetModelExtents(navlib::box_t& extents) const { - if (m_pGLRenderer == nullptr) + if (m_pMolecule == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); - std::vector flags; + Vector3 boxMin; + Vector3 boxMax; + + m_pMolecule->boundingBox(boxMin, boxMax); - m_pGLRenderer->scene().getBoundingBox(extents.min.x, - extents.min.y, - extents.min.z, - extents.max.x, - extents.max.y, - extents.max.z, - flags); + std::copy_n(boxMin.data(), 3u, &extents.min.x); + std::copy_n(boxMax.data(), 3u, &extents.max.x); return 0; } -long Avogadro::TDxController::GetSelectionExtents(navlib::box_t &extents) const +long Avogadro::TDxController::GetSelectionExtents(navlib::box_t& extents) const { - if (m_pGLRenderer == nullptr || *m_ppMolecule == nullptr) - return navlib::make_result_code(navlib::navlib_errc::no_data_available); - - std::vector flags((*m_ppMolecule)->atomCount()); - - for (uint32_t i = 0u; i < (*m_ppMolecule)->atomCount(); i++) - flags[i] = (*m_ppMolecule)->atomSelected(i); - - m_pGLRenderer->scene().getBoundingBox(extents.min.x, - extents.min.y, - extents.min.z, - extents.max.x, - extents.max.y, - extents.max.z, - flags); - - return 0; + return GetModelExtents(extents); } long Avogadro::TDxController::GetSelectionTransform( @@ -376,27 +364,22 @@ long Avogadro::TDxController::GetSelectionTransform( return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -long Avogadro::TDxController::GetIsSelectionEmpty(navlib::bool_t &empty) const +long Avogadro::TDxController::GetIsSelectionEmpty(navlib::bool_t& empty) const { - if (*m_ppMolecule == nullptr) + if (m_pMolecule == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); - for (uint32_t i = 0u; i < (*m_ppMolecule)->atomCount(); i++) { - if ((*m_ppMolecule)->atomSelected(i)) { - empty = false; - return 0; - } - } - empty = true; + empty = m_pMolecule->isSelectionEmpty(); + return 0; -} +} -long Avogadro::TDxController::GetPivotPosition(navlib::point_t &position) const +long Avogadro::TDxController::GetPivotPosition(navlib::point_t& position) const { return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -long Avogadro::TDxController::GetPivotVisible(navlib::bool_t &visible) const +long Avogadro::TDxController::GetPivotVisible(navlib::bool_t& visible) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -405,7 +388,7 @@ long Avogadro::TDxController::GetPivotVisible(navlib::bool_t &visible) const return 0; } -long Avogadro::TDxController::GetHitLookAt(navlib::point_t &position) const +long Avogadro::TDxController::GetHitLookAt(navlib::point_t& position) const { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -423,15 +406,12 @@ long Avogadro::TDxController::GetHitLookAt(navlib::point_t &position) const origin = transform * Eigen::Vector4f(0., 0., 0., 1.); origin /= origin.w(); - auto rayOrigin = Eigen::Vector3f(origin.x(), origin.y(), origin.z()); - auto rayDirection = Eigen::Vector3f(m_lookDirection.x, - m_lookDirection.y, - m_lookDirection.z); + auto rayOrigin = Eigen::Vector3f(origin.x(), origin.y(), origin.z()); + auto rayDirection = + Eigen::Vector3f(m_lookDirection.x, m_lookDirection.y, m_lookDirection.z); - distance = m_pGLRenderer->hit( - rayOrigin, - rayOrigin + rayLength * rayDirection, - rayDirection); + distance = m_pGLRenderer->hit( + rayOrigin, rayOrigin + rayLength * rayDirection, rayDirection); } else { @@ -445,15 +425,13 @@ long Avogadro::TDxController::GetHitLookAt(navlib::point_t &position) const originBuffer = transform * Eigen::Vector4f(x, y, 0., 1.); originBuffer /= originBuffer.w(); - auto rayOrigin = Eigen::Vector3f(originBuffer.x(), originBuffer.y(), originBuffer.z()); - auto rayDirection = Eigen::Vector3f(m_lookDirection.x, - m_lookDirection.y, + auto rayOrigin = + Eigen::Vector3f(originBuffer.x(), originBuffer.y(), originBuffer.z()); + auto rayDirection = Eigen::Vector3f(m_lookDirection.x, m_lookDirection.y, m_lookDirection.z); float buffer = m_pGLRenderer->hit( - rayOrigin, - rayOrigin + rayLength * rayDirection, - rayDirection); + rayOrigin, rayOrigin + rayLength * rayDirection, rayDirection); if (buffer > 0.0f && buffer < distance) { origin = originBuffer; @@ -471,9 +449,9 @@ long Avogadro::TDxController::GetHitLookAt(navlib::point_t &position) const return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -// Setters +// Setters -long Avogadro::TDxController::SetCameraMatrix(const navlib::matrix_t &matrix) +long Avogadro::TDxController::SetCameraMatrix(const navlib::matrix_t& matrix) { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -488,7 +466,7 @@ long Avogadro::TDxController::SetCameraMatrix(const navlib::matrix_t &matrix) return 0; } -long Avogadro::TDxController::SetViewExtents(const navlib::box_t &extents) +long Avogadro::TDxController::SetViewExtents(const navlib::box_t& extents) { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -508,24 +486,24 @@ long Avogadro::TDxController::SetViewFOV(double fov) return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -long Avogadro::TDxController::SetViewFrustum(const navlib::frustum_t &frustum) +long Avogadro::TDxController::SetViewFrustum(const navlib::frustum_t& frustum) { return navlib::make_result_code(navlib::navlib_errc::no_data_available); } long Avogadro::TDxController::SetSelectionTransform( - const navlib::matrix_t &matrix) + const navlib::matrix_t& matrix) { return navlib::make_result_code(navlib::navlib_errc::no_data_available); } -long Avogadro::TDxController::IsUserPivot(navlib::bool_t &userPivot) const +long Avogadro::TDxController::IsUserPivot(navlib::bool_t& userPivot) const { userPivot = false; return 0; } -long Avogadro::TDxController::SetPivotPosition(const navlib::point_t &position) +long Avogadro::TDxController::SetPivotPosition(const navlib::point_t& position) { if (m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); @@ -538,7 +516,7 @@ long Avogadro::TDxController::SetPivotPosition(const navlib::point_t &position) long Avogadro::TDxController::SetPivotVisible(bool visible) { - if (m_pGLWidget == nullptr || m_pGLRenderer == nullptr) + if (m_pGLWidget == nullptr || m_pGLRenderer == nullptr) return navlib::make_result_code(navlib::navlib_errc::no_data_available); m_pGLRenderer->m_drawIcon = visible; @@ -552,13 +530,13 @@ long Avogadro::TDxController::SetHitAperture(double aperture) return 0; } -long Avogadro::TDxController::SetHitDirection(const navlib::vector_t &direction) +long Avogadro::TDxController::SetHitDirection(const navlib::vector_t& direction) { m_lookDirection = direction; return 0; } -long Avogadro::TDxController::SetHitLookFrom(const navlib::point_t &eye) +long Avogadro::TDxController::SetHitLookFrom(const navlib::point_t& eye) { m_eyePosition = eye; return 0; diff --git a/avogadro/tdxcontroller.h b/avogadro/tdxcontroller.h index 0bfe143d..41cc583f 100644 --- a/avogadro/tdxcontroller.h +++ b/avogadro/tdxcontroller.h @@ -4,18 +4,17 @@ ******************************************************************************/ #ifdef _3DCONNEXION -#ifndef AVOGADRO_TDXCONTROLLER_H +#ifndef AVOGADRO_TDXCONTROLLER_H #define AVOGADRO_TDXCONTROLLER_H #include #include -#include +#include "mainwindow.h" #include #include #include -#include -#include "mainwindow.h" +#include #include constexpr uint32_t rayCount = 50; @@ -38,18 +37,16 @@ class Molecule; class ToolPlugin; } - /** * This class is responsible for handling the TDx navigation in Avogadro2. */ -class TDxController : private TDx::SpaceMouse::Navigation3D::CNavigation3D, private QObject +class TDxController + : private TDx::SpaceMouse::Navigation3D::CNavigation3D + , public QObject { - - public: TDxController(MainWindow* const mainWindow, - Avogadro::QtOpenGL::GLWidget* const pGLWidget, - QtGui::Molecule** ppMolecule); + Avogadro::QtOpenGL::GLWidget* const pGLWidget); /** * Enables the TDx navigation. */ @@ -62,26 +59,30 @@ class TDxController : private TDx::SpaceMouse::Navigation3D::CNavigation3D, priv /** * Exports interface utilities to the TDx wizard. - * @param &actionsMap A map that contains pairs which constists of a string - * and an action list. The string represents a path through UI menus and - * submenus, to reach corresponding actions. Submenus names are expected + * @param &actionsMap A map that contains pairs which constists of a string + * and an action list. The string represents a path through UI menus and + * submenus, to reach corresponding actions. Submenus names are expected * to be separated by '|' char. */ - void exportCommands(const QMap> &actionsMap); - + void exportCommands(const QMap>& actionsMap); + + void updateMolecule(QtGui::Molecule* const pMolecule); + private: struct ActionTreeNode { std::string m_nodeName; std::vector> m_children; std::vector m_actions; - explicit ActionTreeNode(const std::string &nodeName) - : m_nodeName(nodeName) {} + explicit ActionTreeNode(const std::string& nodeName) + : m_nodeName(nodeName) + { + } }; std::shared_ptr m_pRootNode; QtOpenGL::GLWidget* m_pGLWidget; Rendering::GLRenderer* m_pGLRenderer; - QtGui::Molecule** m_ppMolecule; + QtGui::Molecule* m_pMolecule; navlib::point_t m_eyePosition; navlib::vector_t m_lookDirection; QImage m_pivotImage; @@ -99,28 +100,27 @@ class TDxController : private TDx::SpaceMouse::Navigation3D::CNavigation3D, priv * @param &pNode traversal starting point * @param &actions action list to add to the tree node */ - void addActions(const std::string &path, - const std::shared_ptr &pNode, - const QList &actions); + void addActions(const std::string& path, + const std::shared_ptr& pNode, + const QList& actions); /** * Returns CCategory hierarchy which reflects the actions tree. * Created CCommand's ID's are encoded paths to the actions in the tree. * @param &pNode root of the action tree - */ + */ TDx::SpaceMouse::CCategory getCategory( - const std::string &pathCode, - const std::shared_ptr &pNode); + const std::string& pathCode, const std::shared_ptr& pNode); /** * Recursively decodes a path from provided code and returns a QAction pointer - * that has been reached in the actions tree. If the code is invalid, then nullptr - * is returned. + * that has been reached in the actions tree. If the code is invalid, then + * nullptr is returned. * @param &pathCode encoded path to the action in the actions tree * @param &pNode node from which the decoding begins - */ - QAction *decodeAction(const std::string &pathCode, - const std::shared_ptr &pNode) const; + */ + QAction* decodeAction(const std::string& pathCode, + const std::shared_ptr& pNode) const; // Inherited via CNavigation3D // Getters @@ -133,7 +133,8 @@ class TDxController : private TDx::SpaceMouse::Navigation3D::CNavigation3D, priv virtual long GetIsViewPerspective(navlib::bool_t& perspective) const override; virtual long GetModelExtents(navlib::box_t& extents) const override; virtual long GetSelectionExtents(navlib::box_t& extents) const override; - virtual long GetSelectionTransform(navlib::matrix_t& transform) const override; + virtual long GetSelectionTransform( + navlib::matrix_t& transform) const override; virtual long GetIsSelectionEmpty(navlib::bool_t& empty) const override; virtual long GetPivotPosition(navlib::point_t& position) const override; virtual long GetPivotVisible(navlib::bool_t& visible) const override;