Add support for duplicating editable well paths from python

This commit is contained in:
jonjenssen authored and JJ committed 2025-08-04 15:25:05 +02:00
1 parent 84cdfe796c
commit 09f180ee53
6 files changed
+117 -18

No files matched your search

@@ -51,24 +51,7 @@ bool RicDuplicateWellPathFeature::isCommandEnabled() const
void RicDuplicateWellPathFeature::onActionTriggered( bool isChecked )
{
auto sourceWellPath = caf::firstAncestorOfTypeFromSelectedObject<RimModeledWellPath>();
if ( !sourceWellPath ) return;
RimProject* project = RimProject::current();
RimWellPathCollection* wellPathCollection = RimTools::wellPathCollection();
if ( project && wellPathCollection )
{
auto newModeledWellPath = sourceWellPath->copyObject<RimModeledWellPath>();
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<RimModeledWellPath>();
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;
}
@@ -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;
@@ -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<caf::PdmObjectHandle*, QString> RimcModeledWellPath_duplicate::execute()
{
auto wellPath = self<RimWellPath>();
return RicDuplicateWellPathFeature::duplicateWellPath( wellPath );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimcModeledWellPath_duplicate::classKeywordReturnedType() const
{
return RimModeledWellPath::classKeywordStatic();
}
@@ -43,3 +43,17 @@ private:
caf::PdmField<double> m_tieInDepth;
caf::PdmField<QString> m_lateralName;
};
//==================================================================================================
///
//==================================================================================================
class RimcModeledWellPath_duplicate : public caf::PdmObjectMethod
{
CAF_PDM_HEADER_INIT;
public:
RimcModeledWellPath_duplicate( caf::PdmObjectHandle* self );
std::expected<caf::PdmObjectHandle*, QString> execute() override;
QString classKeywordReturnedType() const override;
};
@@ -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)
@@ -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