diff --git a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake index d1fb57747d..b3bea11701 100644 --- a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake @@ -13,6 +13,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathViewerEventHandler.h ${CMAKE_CURRENT_LIST_DIR}/RicIntersectionViewerEventHandler.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFormationsImportFileFeature.h +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -29,6 +30,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathViewerEventHandler.cpp ${CMAKE_CURRENT_LIST_DIR}/RicIntersectionViewerEventHandler.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFormationsImportFileFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.cpp ) list(APPEND CODE_HEADER_FILES @@ -39,4 +41,8 @@ list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES} ) +list(APPEND QT_MOC_HEADERS +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.h +) + source_group( "CommandFeature\\WellPath" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp new file mode 100644 index 0000000000..e6aa6235d3 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp @@ -0,0 +1,719 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2013- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPointTangentManipulator.h" + +#include "cafViewer.h" + +#include "cvfCamera.h" +#include "cvfDrawableGeo.h" +#include "cvfHitItemCollection.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfRay.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulator::RicPointTangentManipulator(caf::Viewer* viewer) + : m_viewer(viewer) +{ + m_partManager = new RicPointTangentManipulatorPartMgr; + + m_viewer->installEventFilter(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulator::~RicPointTangentManipulator() +{ + if (m_viewer) m_viewer->removeEventFilter(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::setOrigin(const cvf::Vec3d& origin) +{ + m_partManager->setOrigin(origin); + + emit notifyRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::setTangent(const cvf::Vec3d& tangent) +{ + m_partManager->setTangent(tangent); + + emit notifyRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::appendPartsToModel(cvf::ModelBasicList* model) +{ + m_partManager->appendPartsToModel(model); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPointTangentManipulator::eventFilter(QObject *obj, QEvent* inputEvent) +{ + if (inputEvent->type() == QEvent::MouseButtonPress) + { + QMouseEvent* mouseEvent = static_cast(inputEvent); + + if (mouseEvent->button() == Qt::LeftButton) + { + cvf::HitItemCollection hitItems; + if (m_viewer->rayPick(mouseEvent->x(), mouseEvent->y(), &hitItems)) + { + m_partManager->tryToActivateManipulator(hitItems.firstItem()); + + if(m_partManager->isManipulatorActive()) + { + emit notifyRedraw(); + + return true; + } + } + } + } + else if (inputEvent->type() == QEvent::MouseMove) + { + if (m_partManager->isManipulatorActive()) + { + QMouseEvent* mouseEvent = static_cast(inputEvent); + + //qDebug() << "Inside mouse move"; + //qDebug() << mouseEvent->pos(); + + int translatedMousePosX = mouseEvent->pos().x(); + int translatedMousePosY = m_viewer->height() - mouseEvent->pos().y(); + + cvf::ref ray = m_viewer->mainCamera()->rayFromWindowCoordinates(translatedMousePosX, translatedMousePosY); + { + m_partManager->updateManipulatorFromRay(ray.p()); + + cvf::Vec3d origin; + cvf::Vec3d tangent; + m_partManager->originAndTangent(&origin, &tangent); + + emit notifyUpdate(origin, tangent); + + emit notifyRedraw(); + + return true; + } + } + } + else if (inputEvent->type() == QEvent::MouseButtonRelease) + { + if (m_partManager->isManipulatorActive()) + { + m_partManager->endManipulator(); + + cvf::Vec3d origin; + cvf::Vec3d tangent; + m_partManager->originAndTangent(&origin, &tangent); + + emit notifyUpdate(origin, tangent); + + return true; + } + } + + return false; +} + + + +//================================================================================================== +/// +/// +//================================================================================================== + + + +#include "RicPointTangentManipulator.h" + +#include "cafBoxManipulatorGeometryGenerator.h" +#include "cafEffectGenerator.h" +#include "cafLine.h" + +#include "cvfBoxGenerator.h" +#include "cvfDrawableGeo.h" +#include "cvfGeometryBuilderFaceList.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfPrimitiveSetIndexedUInt.h" +#include "cvfPrimitiveSetIndexedUShort.h" +#include "cvfRay.h" +#include "cvfPrimitiveSetDirect.h" +#include "cvfHitItem.h" +#include + + +// + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulatorPartMgr::RicPointTangentManipulatorPartMgr() + : m_tangentOnStartManipulation(cvf::Vec3d::UNDEFINED), + m_originOnStartManipulation(cvf::Vec3d::UNDEFINED), + m_currentHandleIndex(cvf::UNDEFINED_SIZE_T) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulatorPartMgr::~RicPointTangentManipulatorPartMgr() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::setOrigin(const cvf::Vec3d& origin) +{ + if (isManipulatorActive()) return; + + m_origin = origin; + if (m_originOnStartManipulation.isUndefined()) m_originOnStartManipulation = origin; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::setTangent(const cvf::Vec3d& tangent) +{ + if(isManipulatorActive()) return; + + m_tangent = tangent; + if (m_tangentOnStartManipulation.isUndefined()) m_tangentOnStartManipulation = m_tangent; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::originAndTangent(cvf::Vec3d* origin, cvf::Vec3d* tangent) +{ + *origin = m_origin; + *tangent = m_tangent; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPointTangentManipulatorPartMgr::isManipulatorActive() const +{ + return m_currentHandleIndex != cvf::UNDEFINED_SIZE_T; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::appendPartsToModel(cvf::ModelBasicList* model) +{ + if (!m_handleParts.size()) + { + recreateAllGeometryAndParts(); + } + + for (size_t i = 0; i < m_handleParts.size(); i++) + { + model->addPart(m_handleParts.at(i)); + } + + for (auto activeModePart: m_activeDragModeParts) + { + model->addPart(activeModePart.p()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::tryToActivateManipulator(const cvf::HitItem* hitItem) +{ + endManipulator(); + + if (!hitItem) return; + + const cvf::Part* pickedPart = hitItem->part(); + const cvf::Vec3d intersectionPoint = hitItem->intersectionPoint(); + + if (!pickedPart) return; + + for (size_t i = 0; i < m_handleParts.size(); i++) + { + if (pickedPart == m_handleParts.at(i)) + { + m_initialPickPoint = intersectionPoint; + m_tangentOnStartManipulation = m_tangent; + m_originOnStartManipulation = m_origin; + m_currentHandleIndex = i; + } + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// Calculate new origin and tangent based on the new ray position +/// Clear geometry to trigger regeneration +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay(const cvf::Ray* ray) +{ + if (!isManipulatorActive()) return; + //if (m_boxPart.isNull()) return; + // + // + //BoxFace face = m_handleIds[m_currentHandleIndex].first; + //cvf::Vec3d faceDir = normalFromFace(face); + // + //caf::Line rayLine(ray->origin(), ray->origin() + ray->direction()); + //caf::Line pickLine(m_initialPickPoint, m_initialPickPoint + faceDir); + // + //caf::Line mouseHandleLine = rayLine.findLineBetweenNearestPoints(pickLine); + //cvf::Vec3d closestPointOnMouseRay = mouseHandleLine.start(); + //cvf::Vec3d closestPointOnHandleRay = mouseHandleLine.end(); + // + //cvf::Vec3d newOrigin = m_origin; + //cvf::Vec3d newTangent = m_tangent; + // + //int axis = face/2; + //cvf::Vec3d axisDir; + //axisDir[axis] = 1.0; + // + //cvf::Vec3d motion3d = closestPointOnHandleRay - m_initialPickPoint; + // + //if (face == BCF_X_POS || face == BCF_Y_POS || face == BCF_Z_POS) + //{ + // newTangent = m_tangentOnStartManipulation + motion3d; + // + // for (int i = 0; i < 3; ++i) if (newTangent[i] < 0.0) { newOrigin[i] = m_originOnStartManipulation[i] + newTangent[i]; newTangent[i] = 0.0; } + //} + //else + //{ + // newOrigin = m_originOnStartManipulation + motion3d; + // newTangent = m_tangentOnStartManipulation - motion3d; + // + // for (int i = 0; i < 3; ++i) if (newTangent[i] < 0.0) { newTangent[i] = 0.0; } + //} + + //m_origin = newOrigin; + //m_tangent = newTangent; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::endManipulator() +{ + m_currentHandleIndex = cvf::UNDEFINED_SIZE_T; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::clearAllGeometryAndParts() +{ + m_handleIds.clear(); + m_handleParts.clear(); + m_activeDragModeParts.clear(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::recreateAllGeometryAndParts() +{ + createAllHandleParts(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::createAllHandleParts() +{ + createHorizontalPlaneHandle(); +} + +void RicPointTangentManipulatorPartMgr::createHorizontalPlaneHandle() +{ + using namespace cvf; + cvf::ref vertexArray = new cvf::Vec3fArray(6); + float handleSize = 1.0; + vertexArray->set(0, {-1, -1, 0} ); + vertexArray->set(1, { 1, -1, 0}); + vertexArray->set(2, { 1, 1, 0}); + vertexArray->set(3, {-1, -1, 0}); + vertexArray->set(4, { 1, 1, 0}); + vertexArray->set(5, {-1, 1, 0}); + + Vec3f origin(m_origin); + for (cvf::Vec3f& vx: *vertexArray) + { + vx *= handleSize; + vx += origin; + } + + ref geo = createTriangelDrawableGeo(vertexArray.p()); + + HandleType handleId = HORIZONTAL_PLANE; + cvf::Color4f color = cvf::Color4f(cvf::Color3::MAGENTA); + cvf::String partName("PointTangentManipulator Horizontal Plane Handle"); + + addHandlePart(geo.p(), color, handleId, partName); +} + + +cvf::ref RicPointTangentManipulatorPartMgr::createTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray) +{ + using namespace cvf; + ref geo = new DrawableGeo; + + geo->setVertexArray(triangleVertexArray); + ref primSet = new cvf::PrimitiveSetDirect(cvf::PT_TRIANGLES); + primSet->setIndexCount(triangleVertexArray->size()); + + geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); + + return geo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::addHandlePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName) +{ + cvf::ref handlePart = createPart(geo, color, partName); + + m_handleParts.push_back(handlePart.p()); + m_handleIds.push_back(handleId); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::addActiveModePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName) +{ + cvf::ref handlePart = createPart(geo, color, partName); + + m_activeDragModeParts.push_back(handlePart.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RicPointTangentManipulatorPartMgr::createPart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + const cvf::String& partName) +{ + cvf::ref part = new cvf::Part; + part->setName(partName); + part->setDrawable(geo); + part->updateBoundingBox(); + + caf::SurfaceEffectGenerator surfaceGen(color, caf::PO_1); + cvf::ref eff = surfaceGen.generateCachedEffect(); + part->setEffect(eff.p()); + + return part; +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiObject3dEditorHandle::PdmUiObject3dEditorHandle() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiObject3dEditorHandle::~PdmUiObject3dEditorHandle() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiObject3dEditorHandle::setViewer(caf::Viewer* ownerViewer) +{ + // Not allowed to change viewer. Should be constructor argument, but makes factory stuff difficult. + CAF_ASSERT(m_ownerViewer.isNull()); + m_ownerViewer = ownerViewer; +} +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +#include "cafSelectionManager.h" +#include "RimWellPathGeometryDef.h" + +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiSelectionVisualizer3d::PdmUiSelectionVisualizer3d(caf::Viewer* ownerViewer) + : m_ownerViewer(ownerViewer) +{ + this->setParent(ownerViewer); // Makes this owned by the viewer. +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiSelectionVisualizer3d::~PdmUiSelectionVisualizer3d() +{ + for (auto editor: m_active3DEditors) + { + delete editor; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiSelectionVisualizer3d::onSelectionManagerSelectionChanged() +{ + for (auto editor: m_active3DEditors) + { + delete editor; + } + + m_active3DEditors.clear(); + + if (!m_ownerViewer) return; + + std::vector wellPathGeomDefs; + caf::SelectionManager::instance()->objectsByType(&wellPathGeomDefs); + + for (auto geomDef: wellPathGeomDefs) + { + auto editor = new RicWellPathGeometry3dEditor(); + editor->setViewer(m_ownerViewer); + editor->setPdmObject(geomDef); + m_active3DEditors.push_back(editor); + editor->updateUi(); + } + m_ownerViewer->update(); +} + +} // caf + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +#include "RimWellPathTarget.h" + +CAF_PDM_UI_OBJECT_3D_EDITOR_SOURCE_INIT(RicWellPathGeometry3dEditor); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellPathGeometry3dEditor::RicWellPathGeometry3dEditor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellPathGeometry3dEditor::~RicWellPathGeometry3dEditor() +{ + for (auto targetEditor: m_targetEditors) + { + delete targetEditor; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathGeometry3dEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + RimWellPathGeometryDef* geomDef = dynamic_cast(this->pdmObject()); + + for (auto targetEditor: m_targetEditors) + { + delete targetEditor; + } + m_targetEditors.clear(); + + if (!geomDef) return; + + + std::vector targets = geomDef->activeWellTargets(); + + for (auto target: targets) + { + auto targetEditor = new RicWellTarget3dEditor; + targetEditor->setViewer(m_ownerViewer); + targetEditor->setPdmObject(target); + m_targetEditors.push_back(targetEditor); + targetEditor->updateUi(); + } +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +#include "RimWellPathTarget.h" +#include "RiuViewer.h" +#include "cafDisplayCoordTransform.h" + +CAF_PDM_UI_OBJECT_3D_EDITOR_SOURCE_INIT(RicWellTarget3dEditor); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellTarget3dEditor::RicWellTarget3dEditor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellTarget3dEditor::~RicWellTarget3dEditor() +{ + if (m_cvfModel.notNull()) + { + // Could result in some circularities .... + m_ownerViewer->removeStaticModel(m_cvfModel.p()); + } + + RimWellPathTarget* oldTarget = dynamic_cast(this->pdmObject()); + if (oldTarget) + { + oldTarget->m_targetType.uiCapability()->removeFieldEditor(this); + oldTarget->m_targetPoint.uiCapability()->removeFieldEditor(this); + oldTarget->m_azimuth.uiCapability()->removeFieldEditor(this); + oldTarget->m_inclination.uiCapability()->removeFieldEditor(this); + } + + delete m_manipulator; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + RimWellPathTarget* target = dynamic_cast(this->pdmObject()); + + if ( !target) + { + m_cvfModel->removeAllParts(); + return; + } + + RimWellPathGeometryDef* geomDef; + target->firstAncestorOrThisOfTypeAsserted(geomDef); + + target->m_targetType.uiCapability()->addFieldEditor(this); + target->m_targetPoint.uiCapability()->addFieldEditor(this); + target->m_azimuth.uiCapability()->addFieldEditor(this); + target->m_inclination.uiCapability()->addFieldEditor(this); + + if (m_manipulator.isNull()) + { + m_manipulator = new RicPointTangentManipulator(m_ownerViewer); + m_cvfModel = new cvf::ModelBasicList; + m_ownerViewer->addStaticModelOnce(m_cvfModel.p()); + } + + RiuViewer* viewer = dynamic_cast(m_ownerViewer.data()); + cvf::ref dispXf = viewer->ownerReservoirView()->displayCoordTransform(); + + m_manipulator->setOrigin(dispXf->transformToDisplayCoord( target->targetPointXYZ() + geomDef->referencePoint())); + m_manipulator->setTangent(target->tangent()); + m_cvfModel->removeAllParts(); + m_manipulator->appendPartsToModel(m_cvfModel.p()); + + m_cvfModel->updateBoundingBoxesRecursive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::cleanupBeforeSettingPdmObject() +{ + RimWellPathTarget* oldTarget = dynamic_cast(this->pdmObject()); + if (oldTarget) + { + oldTarget->m_targetType.uiCapability()->removeFieldEditor(this); + oldTarget->m_targetPoint.uiCapability()->removeFieldEditor(this); + oldTarget->m_azimuth.uiCapability()->removeFieldEditor(this); + oldTarget->m_inclination.uiCapability()->removeFieldEditor(this); + } +} diff --git a/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h new file mode 100644 index 0000000000..1dcaa8678f --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h @@ -0,0 +1,284 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMatrix4.h" +#include "cvfVector3.h" + +#include +#include + +namespace cvf { + class Model; + class ModelBasicList; +}; + + +namespace caf { + class Viewer; +}; + +class QMouseEvent; + +class RicPointTangentManipulatorPartMgr; + +//================================================================================================== +// +// +//================================================================================================== +class RicPointTangentManipulator : public QObject +{ + Q_OBJECT + +public: + explicit RicPointTangentManipulator(caf::Viewer* viewer); + ~RicPointTangentManipulator(); + + void setOrigin(const cvf::Vec3d& origin); + void setTangent(const cvf::Vec3d& tangent); + + void appendPartsToModel(cvf::ModelBasicList* model); + +signals: + void notifyRedraw(); + void notifyUpdate(const cvf::Vec3d& origin, const cvf::Vec3d& tangent); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + QPointer m_viewer; + + cvf::ref m_partManager; +}; + + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include "cvfVector3.h" +#include "cvfCollection.h" +#include "cvfMatrix4.h" +#include "cvfString.h" +#include "cvfColor4.h" + +namespace cvf +{ +class ModelBasicList; +class Part; +class DrawableGeo; +class Ray; +class HitItem; + +template class Array; +typedef Array Vec3fArray; +} + +class RicPointTangentManipulatorPartMgr : public cvf::Object +{ +public: + enum HandleType + { + HORIZONTAL_PLANE, + VERTICAL_AXIS, + AZIMUTH, + INCLINATION + }; + +public: + RicPointTangentManipulatorPartMgr(); + ~RicPointTangentManipulatorPartMgr(); + + void setOrigin(const cvf::Vec3d& origin); + void setTangent(const cvf::Vec3d& tangent); + void originAndTangent(cvf::Vec3d* origin, cvf::Vec3d* tangent); + + bool isManipulatorActive() const; + void tryToActivateManipulator(const cvf::HitItem* hitItem); + void updateManipulatorFromRay(const cvf::Ray* ray); + void endManipulator(); + + void appendPartsToModel(cvf::ModelBasicList* model); + +private: + void createAllHandleParts(); + void clearAllGeometryAndParts(); + void recreateAllGeometryAndParts(); + + void createHorizontalPlaneHandle(); + + void addHandlePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName); + + void addActiveModePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName); + + static cvf::ref createTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray); + static cvf::ref createPart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + const cvf::String& partName); +private: + std::vector< HandleType > m_handleIds; // These arrays have the same length + cvf::Collection m_handleParts; // These arrays have the same length + cvf::Collection m_activeDragModeParts; + + + cvf::Vec3d m_origin; + cvf::Vec3d m_tangent; + + cvf::Vec3d m_initialPickPoint; + cvf::Vec3d m_tangentOnStartManipulation; + cvf::Vec3d m_originOnStartManipulation; + + size_t m_currentHandleIndex; +}; + + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +#include "cafSelectionChangedReceiver.h" +#include "cafPdmUiObjectEditorHandle.h" +#include "cafFactory.h" + +namespace caf +{ + +//================================================================================================== +/// Macros helping in development of PDM UI 3d editors +//================================================================================================== + +/// CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT assists the factory used when creating editors +/// Place this in the header file inside the class definition of your PdmUiEditor + +#define CAF_PDM_UI_OBJECT_3D_EDITOR_HEADER_INIT \ +public: \ + static QString uiEditorTypeName() + +/// CAF_PDM_UI_OBJECT_3D_EDITOR_SOURCE_INIT implements editorTypeName() and registers the field editor in the field editor factory +/// Place this in the cpp file, preferably above the constructor + +#define CAF_PDM_UI_OBJECT_3D_EDITOR_SOURCE_INIT(EditorClassName) \ + QString EditorClassName::uiEditorTypeName() { return #EditorClassName; } \ + CAF_FACTORY_REGISTER(caf::PdmUiObject3dEditorHandle, EditorClassName, QString, EditorClassName::uiEditorTypeName()) + + +class PdmUiObject3dEditorHandle : public caf::PdmUiObjectEditorHandle +{ +public: + PdmUiObject3dEditorHandle(); + ~PdmUiObject3dEditorHandle() override; + + void setViewer(caf::Viewer* ownerViewer); + +protected: + // To be removed when splitting the PdmUiObjectEditorHandle + virtual QWidget* createWidget(QWidget* parent) override { return nullptr;} + + QPointer m_ownerViewer; +}; + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +// Selected object 3D editor visualizer +class PdmUiSelectionVisualizer3d : public QObject, caf::SelectionChangedReceiver +{ + Q_OBJECT +public: + PdmUiSelectionVisualizer3d(caf::Viewer* ownerViewer); + ~PdmUiSelectionVisualizer3d(); +protected: + virtual void onSelectionManagerSelectionChanged() override; + + std::vector< QPointer > m_active3DEditors; + + QPointer m_ownerViewer; +}; + + +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +class RicWellTarget3dEditor; + +class RicWellPathGeometry3dEditor : public caf::PdmUiObject3dEditorHandle +{ + CAF_PDM_UI_OBJECT_3D_EDITOR_HEADER_INIT; + Q_OBJECT +public: + RicWellPathGeometry3dEditor(); + ~RicWellPathGeometry3dEditor() override; + +protected: + virtual void configureAndUpdateUi(const QString& uiConfigName) override; + +private: + + std::vector m_targetEditors; +}; + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +class RicWellTarget3dEditor : public caf::PdmUiObject3dEditorHandle +{ + CAF_PDM_UI_OBJECT_3D_EDITOR_HEADER_INIT; + Q_OBJECT +public: + RicWellTarget3dEditor(); + ~RicWellTarget3dEditor() override; + +protected: + virtual void configureAndUpdateUi(const QString& uiConfigName) override; + virtual void cleanupBeforeSettingPdmObject() override; + +private: + QPointer m_manipulator; + cvf::ref m_cvfModel; +}; + +class RiuViewer; + +// 3D editor manager diff --git a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h index 4ba0870ccf..3c85c67250 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h @@ -41,6 +41,7 @@ public: enum WellStartType { START_AT_FIRST_TARGET, START_AT_SURFACE, START_FROM_OTHER_WELL, START_AT_AUTO_SURFACE }; + cvf::Vec3d referencePoint() { return m_referencePoint;} cvf::ref createWellPathGeometry(); void updateWellPathVisualization(); @@ -54,6 +55,7 @@ public: virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + std::vector activeWellTargets() const; protected: virtual void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, @@ -64,7 +66,6 @@ private: virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - std::vector activeWellTargets() const; std::vector lineArcEndpoints() const; cvf::Vec3d startTangent() const; @@ -77,6 +78,3 @@ private: caf::PdmChildArrayField m_wellTargets; }; - - - diff --git a/ApplicationCode/ProjectDataModel/RimWellPathTarget.h b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h index dd7e09a2d8..4a48772277 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathTarget.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h @@ -53,6 +53,7 @@ private: virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: + friend class RicWellTarget3dEditor; caf::PdmField m_isEnabled; caf::PdmField > m_targetType; caf::PdmField m_targetPoint; diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index 3e7ff17476..d4cad38af6 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -65,6 +65,8 @@ #include "WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h" #include +#include "WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h" + using cvf::ManipulatorTrackball; @@ -184,6 +186,7 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) m_windowEdgeAxisOverlay = new RivWindowEdgeAxesOverlayItem(standardFont); m_showWindowEdgeAxes = false; + new caf::PdmUiSelectionVisualizer3d(this); } //--------------------------------------------------------------------------------------------------