diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.cpp index f7b83b71ea..bb9d13955b 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.cpp +++ b/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.cpp @@ -51,24 +51,7 @@ bool RicDuplicateWellPathFeature::isCommandEnabled() const void RicDuplicateWellPathFeature::onActionTriggered( bool isChecked ) { auto sourceWellPath = caf::firstAncestorOfTypeFromSelectedObject(); - if ( !sourceWellPath ) return; - - RimProject* project = RimProject::current(); - RimWellPathCollection* wellPathCollection = RimTools::wellPathCollection(); - if ( project && wellPathCollection ) - { - auto newModeledWellPath = sourceWellPath->copyObject(); - size_t modelledWellpathCount = wellPathCollection->modelledWellPathCount(); - newModeledWellPath->setName( "Well-" + QString::number( modelledWellpathCount + 1 ) ); - newModeledWellPath->setWellPathColor( RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount ) ); - - wellPathCollection->addWellPaths( { newModeledWellPath } ); - newModeledWellPath->createWellPathGeometry(); - - project->scheduleCreateDisplayModelAndRedrawAllViews(); - - Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() ); - } + duplicateWellPath( sourceWellPath ); } //-------------------------------------------------------------------------------------------------- @@ -79,3 +62,34 @@ void RicDuplicateWellPathFeature::setupActionLook( QAction* actionToSetup ) actionToSetup->setText( "Duplicate Well Path" ); actionToSetup->setIcon( QIcon( ":/caf/duplicate.svg" ) ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RicDuplicateWellPathFeature::duplicateWellPath( RimWellPath* wellPath ) +{ + if ( wellPath == nullptr ) return nullptr; + + RimProject* project = RimProject::current(); + RimWellPathCollection* wellPathCollection = RimTools::wellPathCollection(); + if ( project && wellPathCollection ) + { + auto newModeledWellPath = wellPath->copyObject(); + if ( newModeledWellPath == nullptr ) return nullptr; + + size_t modelledWellpathCount = wellPathCollection->modelledWellPathCount(); + newModeledWellPath->setName( "Well-" + QString::number( modelledWellpathCount + 1 ) ); + newModeledWellPath->setWellPathColor( RiaColorTables::editableWellPathsPaletteColors().cycledColor3f( modelledWellpathCount ) ); + + wellPathCollection->addWellPaths( { newModeledWellPath } ); + newModeledWellPath->createWellPathGeometry(); + + project->scheduleCreateDisplayModelAndRedrawAllViews(); + + Riu3DMainWindowTools::selectAsCurrentItem( newModeledWellPath->geometryDefinition() ); + + return newModeledWellPath; + } + + return nullptr; +} \ No newline at end of file diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.h b/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.h index e07c1ae31f..65a105e901 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.h +++ b/ApplicationLibCode/Commands/WellPathCommands/RicDuplicateWellPathFeature.h @@ -20,6 +20,8 @@ #include "cafCmdFeature.h" +class RimWellPath; + //================================================================================================== /// //================================================================================================== @@ -27,6 +29,9 @@ class RicDuplicateWellPathFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; +public: + static RimWellPath* duplicateWellPath( RimWellPath* wellPath ); + protected: bool isCommandEnabled() const override; void onActionTriggered( bool isChecked ) override; diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.cpp b/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.cpp index 8f910653fe..d4124dc7f5 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.cpp +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.cpp @@ -23,6 +23,7 @@ #include "RimWellPathGeometryDef.h" #include "RimWellPathTarget.h" +#include "WellPathCommands/RicDuplicateWellPathFeature.h" #include "WellPathCommands/RicNewWellPathLateralAtDepthFeature.h" #include "cafPdmAbstractFieldScriptingCapability.h" @@ -66,3 +67,32 @@ QString RimcModeledWellPath_appendLateral::classKeywordReturnedType() const { return RimModeledWellPath::classKeywordStatic(); } + +CAF_PDM_OBJECT_METHOD_SOURCE_INIT( RimModeledWellPath, RimcModeledWellPath_duplicate, "Duplicate" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimcModeledWellPath_duplicate::RimcModeledWellPath_duplicate( caf::PdmObjectHandle* self ) + : PdmObjectMethod( self, PdmObjectMethod::NullPointerType::NULL_IS_VALID, PdmObjectMethod::ResultType::PERSISTENT_TRUE ) +{ + CAF_PDM_InitObject( "Duplicate", "", "", "Duplicate" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::expected RimcModeledWellPath_duplicate::execute() +{ + auto wellPath = self(); + + return RicDuplicateWellPathFeature::duplicateWellPath( wellPath ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimcModeledWellPath_duplicate::classKeywordReturnedType() const +{ + return RimModeledWellPath::classKeywordStatic(); +} diff --git a/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.h b/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.h index b0d01478e8..4aa4ce630f 100644 --- a/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.h +++ b/ApplicationLibCode/ProjectDataModelCommands/RimcModeledWellPath.h @@ -43,3 +43,17 @@ private: caf::PdmField m_tieInDepth; caf::PdmField m_lateralName; }; + +//================================================================================================== +/// +//================================================================================================== +class RimcModeledWellPath_duplicate : public caf::PdmObjectMethod +{ + CAF_PDM_HEADER_INIT; + +public: + RimcModeledWellPath_duplicate( caf::PdmObjectHandle* self ); + + std::expected execute() override; + QString classKeywordReturnedType() const override; +}; diff --git a/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/duplicate_well.py b/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/duplicate_well.py new file mode 100644 index 0000000000..ca87236dc3 --- /dev/null +++ b/GrpcInterface/Python/rips/PythonExamples/wells_and_fractures/duplicate_well.py @@ -0,0 +1,23 @@ +################################################################################### +# This example will connect to ResInsight, retrieve a list of wells, print info and +# make a duplicate of the first well found, if any +# +################################################################################### + +# Import the ResInsight Processing Server Module +import rips + +# Connect to ResInsight +resinsight = rips.Instance.find() +if resinsight is not None: + # Get a list of all wells + wells = resinsight.project.well_paths() + + print("Got " + str(len(wells)) + " wells: ") + for well in wells: + print("Well name: " + well.name) + + # will only work for editable well paths (ModeledWellPath) + new_well = well.duplicate() + print("New Well name: " + new_well.name) + diff --git a/GrpcInterface/Python/rips/tests/test_create_well_path.py b/GrpcInterface/Python/rips/tests/test_create_well_path.py index 6c31e0cd24..7be7edf6a8 100644 --- a/GrpcInterface/Python/rips/tests/test_create_well_path.py +++ b/GrpcInterface/Python/rips/tests/test_create_well_path.py @@ -58,3 +58,16 @@ def test_add_well_path_targets(rips_instance, initialize_test): assert not target.use_fixed_azimuth assert target.azimuth == 0.0 assert target.inclination == 25.6 + + +def test_duplicate_well_path(rips_instance, initialize_test): + well_path_coll = rips_instance.project.descendants(rips.WellPathCollection)[0] + + my_well_path = well_path_coll.add_new_object(rips.ModeledWellPath) + my_well_path.name = "test" + my_well_path.update() + + new_well_path = my_well_path.duplicate() + assert new_well_path is not None + assert new_well_path.name != my_well_path.name +