diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp index cc086a0364..983c8f7634 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp @@ -57,18 +57,50 @@ bool RicNewWellPathListTargetFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicNewWellPathListTargetFeature::onActionTriggered(bool isChecked) { - std::vector targets; - caf::SelectionManager::instance()->objectsByType(&targets, caf::SelectionManager::FIRST_LEVEL); - if (targets.size() > 0) + std::vector selectedTargets; + caf::SelectionManager::instance()->objectsByType(&selectedTargets, caf::SelectionManager::FIRST_LEVEL); + if (selectedTargets.size() > 0) { - auto firstTarget = targets.front(); + auto firstTarget = selectedTargets.front(); RimWellPathGeometryDef* wellGeomDef = nullptr; firstTarget->firstAncestorOrThisOfTypeAsserted(wellGeomDef); - RimWellPathTarget* duplicate = dynamic_cast(firstTarget->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); - wellGeomDef->insertTarget(firstTarget, duplicate); + auto afterBeforePair = wellGeomDef->findActiveTargetsAroundInsertionPoint(firstTarget); + + cvf::Vec3d newPos = cvf::Vec3d::ZERO; + + if (!afterBeforePair.first && afterBeforePair.second) + { + newPos = afterBeforePair.second->targetPointXYZ(); + newPos.z() = -wellGeomDef->referencePointXyz().z(); + } + else if (afterBeforePair.first && afterBeforePair.second) + { + newPos = 0.5*(afterBeforePair.first->targetPointXYZ() + afterBeforePair.second->targetPointXYZ()); + } + else if (afterBeforePair.first && !afterBeforePair.second) + { + std::vector activeTargets = wellGeomDef->activeWellTargets(); + size_t targetCount = activeTargets.size(); + if (targetCount > 1) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ(); + cvf::Vec3d nextLastToLast = newPos - activeTargets[targetCount-2]->targetPointXYZ(); + newPos += 0.5*nextLastToLast; + } + else + { + newPos = afterBeforePair.first->targetPointXYZ() + cvf::Vec3d(0, 0, 200); + } + } + + RimWellPathTarget* newTarget = new RimWellPathTarget; + newTarget->setAsPointTargetXYD({ newPos[0], newPos[1], -newPos[2] }); + + wellGeomDef->insertTarget(firstTarget, newTarget); wellGeomDef->updateConnectedEditors(); wellGeomDef->updateWellPathVisualization(); + return; } @@ -77,8 +109,34 @@ void RicNewWellPathListTargetFeature::onActionTriggered(bool isChecked) if (geomDefs.size() > 0) { RimWellPathGeometryDef* wellGeomDef = geomDefs[0]; + std::vector activeTargets = wellGeomDef->activeWellTargets(); + + size_t targetCount = activeTargets.size(); + + if ( targetCount == 0 ) + { + wellGeomDef->appendTarget(); + } + else + { + cvf::Vec3d newPos = cvf::Vec3d::ZERO; + + if ( targetCount > 1 ) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ(); + cvf::Vec3d nextLastToLast = newPos - activeTargets[targetCount-2]->targetPointXYZ(); + newPos += 0.5*nextLastToLast; + } + else if ( targetCount > 0 ) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ() + cvf::Vec3d(0, 0, 200); + } + + RimWellPathTarget* newTarget = new RimWellPathTarget; + newTarget->setAsPointTargetXYD({ newPos[0], newPos[1], -newPos[2] }); + wellGeomDef->insertTarget(nullptr, newTarget); + } - wellGeomDef->appendTarget(); wellGeomDef->updateConnectedEditors(); wellGeomDef->updateWellPathVisualization(); } diff --git a/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp index 30d916ec43..0a4f1196ea 100644 --- a/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp @@ -40,7 +40,7 @@ CAF_PDM_SOURCE_INIT(RimModeledWellPath, "ModeledWellPath"); //-------------------------------------------------------------------------------------------------- RimModeledWellPath::RimModeledWellPath() { - CAF_PDM_InitObject("Modeled WellPath", ":/Well.png", "", ""); + CAF_PDM_InitObject("Modeled WellPath", ":/EditableWell.png", "", ""); CAF_PDM_InitFieldNoDefault(&m_geometryDefinition, "WellPathGeometryDef", "Trajectory", "", "", ""); m_geometryDefinition = new RimWellPathGeometryDef; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp index 4005d41d2d..473f0bca81 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp @@ -58,7 +58,7 @@ CAF_PDM_SOURCE_INIT(RimWellPathGeometryDef, "WellPathGeometryDef"); RimWellPathGeometryDef::RimWellPathGeometryDef() : m_pickTargetsEventHandler(new RicCreateWellTargetsPickEventHandler(this)) { - CAF_PDM_InitObject("Well Targets", ":/Well.png", "", ""); + CAF_PDM_InitObject("Well Targets", ":/WellTargets.png", "", ""); CAF_PDM_InitField(&m_referencePointUtmXyd, "ReferencePosUtmXyd", cvf::Vec3d(0,0,0), "UTM Reference Point", "", "", ""); @@ -164,6 +164,31 @@ void RimWellPathGeometryDef::updateWellPathVisualization() modWellPath->updateWellPathVisualization(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair +RimWellPathGeometryDef::findActiveTargetsAroundInsertionPoint(const RimWellPathTarget* targetToInsertBefore) +{ + RimWellPathTarget* before = nullptr; + RimWellPathTarget* after = nullptr; + + bool foundTarget = false; + for (const auto& wt : m_wellTargets) + { + if ( wt == targetToInsertBefore ) + { + foundTarget = true; + } + + if ( wt->isEnabled() && !after && foundTarget ) after = wt; + + if ( wt->isEnabled() && !foundTarget ) before = wt; + } + + return { before, after}; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h index 599b853bcf..2fec0e909a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h @@ -51,6 +51,7 @@ public: cvf::ref createWellPathGeometry(); void updateWellPathVisualization(); + std::pair findActiveTargetsAroundInsertionPoint(const RimWellPathTarget* targetToInsertBefore); void insertTarget(const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert); diff --git a/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp b/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp index 9025b8e714..bad39e827c 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp @@ -3,6 +3,7 @@ #include #include "RimWellPathGeometryDef.h" +#include "cafPdmUiCheckBoxEditor.h" CAF_PDM_SOURCE_INIT(RimWellPathTarget, "WellPathTarget"); @@ -28,13 +29,16 @@ RimWellPathTarget::RimWellPathTarget() { CAF_PDM_InitField(&m_isEnabled, "IsEnabled", true, "", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_targetType, "TargetType", "Type", "", "", ""); //m_targetType.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&m_dogleg1, "Dogleg1", 3.0, "DLS 1", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_targetPoint, "TargetPoint", "Point", "", "", ""); + CAF_PDM_InitField(&m_dogleg1, "Dogleg1", 3.0, "DLh", "", "", ""); + CAF_PDM_InitField(&m_dogleg2, "Dogleg2", 3.0, "DLl", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_targetType, "TargetType", "Type", "", "", ""); + m_targetType.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir", "", "", ""); + m_hasTangentConstraintUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", ""); CAF_PDM_InitField(&m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", ""); - CAF_PDM_InitField(&m_dogleg2, "Dogleg2", 3.0, "DLS 2", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -252,8 +256,8 @@ QList RimWellPathTarget::calculateValueOptions(const caf QList options; if (fieldNeedingOptions == & m_targetType) { - options.push_back(caf::PdmOptionItemInfo("o->",RimWellPathTarget::POINT_AND_TANGENT, false, QIcon(":/WellTargetPointTangent16x16.png") )); - options.push_back(caf::PdmOptionItemInfo("o", RimWellPathTarget::POINT, false, QIcon(":/WellTargetPoint16x16.png"))); + options.push_back(caf::PdmOptionItemInfo("o->",RimWellPathTarget::POINT_AND_TANGENT));//, false, QIcon(":/WellTargetPointTangent16x16.png") )); + options.push_back(caf::PdmOptionItemInfo("o", RimWellPathTarget::POINT));//, false, QIcon(":/WellTargetPoint16x16.png"))); } return options; } @@ -263,6 +267,12 @@ QList RimWellPathTarget::calculateValueOptions(const caf //-------------------------------------------------------------------------------------------------- void RimWellPathTarget::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { + if (changedField == &m_hasTangentConstraintUiField) + { + if (m_hasTangentConstraintUiField) m_targetType = POINT_AND_TANGENT; + else m_targetType = POINT; + } + RimModeledWellPath* wellPath; firstAncestorOrThisOfTypeAsserted(wellPath); wellPath->updateWellPathVisualization(); @@ -270,6 +280,7 @@ void RimWellPathTarget::fieldChangedByUi(const caf::PdmFieldHandle* changedField { wellPath->scheduleUpdateOfDependentVisualization(); } + } //-------------------------------------------------------------------------------------------------- @@ -277,9 +288,11 @@ void RimWellPathTarget::fieldChangedByUi(const caf::PdmFieldHandle* changedField //-------------------------------------------------------------------------------------------------- void RimWellPathTarget::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { + m_hasTangentConstraintUiField = (m_targetType == POINT_AND_TANGENT); + if (m_isEnabled()) { - + m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly(false); m_targetType.uiCapability()->setUiReadOnly(false); m_targetPoint.uiCapability()->setUiReadOnly(false); m_dogleg2.uiCapability()->setUiReadOnly(false); @@ -318,5 +331,6 @@ void RimWellPathTarget::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderin m_azimuth.uiCapability()->setUiReadOnly(true); m_inclination.uiCapability()->setUiReadOnly(true); m_dogleg2.uiCapability()->setUiReadOnly(true); + m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly(true); } } diff --git a/ApplicationCode/ProjectDataModel/RimWellPathTarget.h b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h index 1150a8cb1c..60c82da0eb 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathTarget.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h @@ -68,6 +68,7 @@ private: caf::PdmField m_inclination; caf::PdmField m_dogleg1; caf::PdmField m_dogleg2; + caf::PdmField m_hasTangentConstraintUiField; }; diff --git a/ApplicationCode/Resources/EditableWell.png b/ApplicationCode/Resources/EditableWell.png new file mode 100644 index 0000000000..55cefe214a Binary files /dev/null and b/ApplicationCode/Resources/EditableWell.png differ diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index eaac2525f0..54cac6e571 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -18,6 +18,8 @@ Minus.png Save.png Well.png + EditableWell.png + WellTargets.png WellCollection.png octave.png OctaveScriptFile16x16.png diff --git a/ApplicationCode/Resources/WellTargets.png b/ApplicationCode/Resources/WellTargets.png new file mode 100644 index 0000000000..df0379467b Binary files /dev/null and b/ApplicationCode/Resources/WellTargets.png differ