Python adjustments (#7809)

* #7797 Well Targets: Add scripting capability
* #7794 Python : Do not update childField or childFieldArray
* #7797: Python - Add scripting to well path collection
- Extend the pdmobject.py with method add_object()
- allow objects to be created from Python in well path collections
- add well targets to modelled well path

* #7795 Python : Make sure referenced generated classes are defined
* #7810 StimPlanModel: clean-up python generation
* Python : Always use empty string as default value for ptrFieldValue
It can happen that a ptrField is assigned to a pointer on object construction. (FaciesProperties) Make sure that constructor always assigns an empty string.

Co-authored-by: magnesj <magnesj@users.noreply.github.com>
Co-authored-by: Kristian Bendiksen <kristian.bendiksen@gmail.com>
This commit is contained in:
Magne Sjaastad 2021-06-25 14:18:36 +02:00
parent 27b1d6ebfb
commit 273e416b40
28 changed files with 294 additions and 73 deletions

View File

@ -1555,7 +1555,9 @@ bool RiaApplication::generateCode( const QString& fileName, gsl::not_null<QStrin
"objects automatically created based on the data model in ResInsight."; "objects automatically created based on the data model in ResInsight.";
} }
out << generator->generate( caf::PdmDefaultObjectFactory::instance() ); std::vector<QString> logMessages;
out << generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages );
} }
{ {
@ -1613,7 +1615,22 @@ bool RiaApplication::generateCode( const QString& fileName, gsl::not_null<QStrin
} }
QTextStream out( &outputFile ); QTextStream out( &outputFile );
out << generator->generate( caf::PdmDefaultObjectFactory::instance() ); std::vector<QString> logMessages;
out << generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages );
QString errorText;
for ( const auto& msg : logMessages )
{
errorText += msg;
errorText += "\n";
}
if ( !errorText.isEmpty() )
{
*errMsg = errorText;
return false;
}
} }
return true; return true;

View File

@ -453,7 +453,7 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( gsl::not_n
if ( !RiaApplication::generateCode( outputFile, &errMsg ) ) if ( !RiaApplication::generateCode( outputFile, &errMsg ) )
{ {
RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) ); RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) );
return RiaApplication::ApplicationStatus::EXIT_WITH_ERROR; return RiaApplication::ApplicationStatus::KEEP_GOING;
} }
return RiaApplication::ApplicationStatus::EXIT_COMPLETED; return RiaApplication::ApplicationStatus::EXIT_COMPLETED;

View File

@ -89,7 +89,9 @@ RimFormationNames* RicImportFormationNamesFeature::importFormationFiles( const Q
} }
} }
return formationNames.back(); if ( !formationNames.empty() ) return formationNames.back();
return nullptr;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -44,7 +44,7 @@ RimCellFilterCollection::RimCellFilterCollection()
CAF_PDM_InitScriptableField( &m_isActive, "Active", true, "Active", "", "", "" ); CAF_PDM_InitScriptableField( &m_isActive, "Active", true, "Active", "", "", "" );
m_isActive.uiCapability()->setUiHidden( true ); m_isActive.uiCapability()->setUiHidden( true );
CAF_PDM_InitScriptableFieldNoDefault( &m_cellFilters, "CellFilters", "Filters", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_cellFilters, "CellFilters", "Filters", "", "", "" );
m_cellFilters.uiCapability()->setUiTreeHidden( true ); m_cellFilters.uiCapability()->setUiTreeHidden( true );
caf::PdmFieldReorderCapability::addToField( &m_cellFilters ); caf::PdmFieldReorderCapability::addToField( &m_cellFilters );

View File

@ -30,9 +30,9 @@ CAF_PDM_SOURCE_INIT( RimEnsembleFractureStatisticsPlotCollection, "EnsembleFract
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimEnsembleFractureStatisticsPlotCollection::RimEnsembleFractureStatisticsPlotCollection() RimEnsembleFractureStatisticsPlotCollection::RimEnsembleFractureStatisticsPlotCollection()
{ {
CAF_PDM_InitScriptableObject( "Ensemble Fracture Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); CAF_PDM_InitObject( "Ensemble Fracture Statistics Plots", ":/WellLogPlots16x16.png", "", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_ensembleFractureStatisticsPlots, "EnsembleFractureStatisticsPlots", "", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_ensembleFractureStatisticsPlots, "EnsembleFractureStatisticsPlots", "", "", "", "" );
m_ensembleFractureStatisticsPlots.uiCapability()->setUiHidden( true ); m_ensembleFractureStatisticsPlots.uiCapability()->setUiHidden( true );
} }

View File

@ -30,9 +30,9 @@ CAF_PDM_SOURCE_INIT( RimGridStatisticsPlotCollection, "GridStatisticsPlotCollect
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimGridStatisticsPlotCollection::RimGridStatisticsPlotCollection() RimGridStatisticsPlotCollection::RimGridStatisticsPlotCollection()
{ {
CAF_PDM_InitScriptableObject( "Grid Statistics Plots", ":/WellLogPlots16x16.png", "", "" ); CAF_PDM_InitObject( "Grid Statistics Plots", ":/WellLogPlots16x16.png", "", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_gridStatisticsPlots, "GridStatisticsPlots", "", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_gridStatisticsPlots, "GridStatisticsPlots", "", "", "", "" );
m_gridStatisticsPlots.uiCapability()->setUiHidden( true ); m_gridStatisticsPlots.uiCapability()->setUiHidden( true );
} }

View File

@ -54,6 +54,8 @@
#include "Riu3DMainWindowTools.h" #include "Riu3DMainWindowTools.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiEditorHandle.h" #include "cafPdmUiEditorHandle.h"
#include "cafPdmUiTreeOrdering.h" #include "cafPdmUiTreeOrdering.h"
#include "cafProgressInfo.h" #include "cafProgressInfo.h"
@ -83,7 +85,12 @@ CAF_PDM_SOURCE_INIT( RimWellPathCollection, "WellPaths" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimWellPathCollection::RimWellPathCollection() RimWellPathCollection::RimWellPathCollection()
{ {
CAF_PDM_InitObject( "Wells", ":/WellCollection.png", "", "" ); CAF_PDM_InitScriptableObjectWithNameAndComment( "Wells",
":/WellCollection.png",
"",
"",
"WellPathCollection",
"Collection of Well Paths" );
CAF_PDM_InitField( &isActive, "Active", true, "Active", "", "", "" ); CAF_PDM_InitField( &isActive, "Active", true, "Active", "", "", "" );
isActive.uiCapability()->setUiHidden( true ); isActive.uiCapability()->setUiHidden( true );
@ -109,7 +116,7 @@ RimWellPathCollection::RimWellPathCollection()
CAF_PDM_InitField( &wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", "" ); CAF_PDM_InitField( &wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", "" );
CAF_PDM_InitField( &wellPathClipZDistance, "WellPathClipZDistance", 100, "Well Path Clipping Depth Distance", "", "", "" ); CAF_PDM_InitField( &wellPathClipZDistance, "WellPathClipZDistance", 100, "Well Path Clipping Depth Distance", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_wellPaths, "WellPaths", "Well Paths", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_wellPaths, "WellPaths", "Well Paths", "", "", "" );
m_wellPaths.uiCapability()->setUiHidden( true ); m_wellPaths.uiCapability()->setUiHidden( true );
m_wellPaths.uiCapability()->setUiTreeHidden( true ); m_wellPaths.uiCapability()->setUiTreeHidden( true );
m_wellPaths.uiCapability()->setUiTreeChildrenHidden( true ); m_wellPaths.uiCapability()->setUiTreeChildrenHidden( true );
@ -977,3 +984,14 @@ void RimWellPathCollection::onChildDeleted( caf::PdmChildArrayFieldHandle*
scheduleRedrawAffectedViews(); scheduleRedrawAffectedViews();
uiCapability()->updateConnectedEditors(); uiCapability()->updateConnectedEditors();
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPathCollection::onChildAdded( caf::PdmFieldHandle* containerForNewObject )
{
rebuildWellPathNodes();
scheduleRedrawAffectedViews();
uiCapability()->updateConnectedEditors();
}

View File

@ -127,6 +127,8 @@ public:
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects ) override; std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
void onChildAdded( caf::PdmFieldHandle* containerForNewObject ) override;
protected: protected:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;

View File

@ -25,8 +25,7 @@
#include "RimWellPathCompletions.h" #include "RimWellPathCompletions.h"
#include "RimWellPathValve.h" #include "RimWellPathValve.h"
#include "cafPdmFieldScriptingCapability.h" #include "cafPdmObject.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiTreeOrdering.h" #include "cafPdmUiTreeOrdering.h"
#include <QStringList> #include <QStringList>
@ -38,23 +37,18 @@ CAF_PDM_SOURCE_INIT( RimWellPathGroup, "WellPathGroup" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimWellPathGroup::RimWellPathGroup() RimWellPathGroup::RimWellPathGroup()
{ {
CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Path Group", CAF_PDM_InitObject( "Well Path Group", ":/WellPathGroup.svg", "", "" );
":/WellPathGroup.svg", CAF_PDM_InitFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" );
"", CAF_PDM_InitFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" );
"",
"WellPathGroup",
"A Group of Well Paths" );
CAF_PDM_InitScriptableFieldNoDefault( &m_childWellPaths, "ChildWellPaths", "Child Well Paths", "", "", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_groupName, "GroupName", "Group Name", "", "", "" );
CAF_PDM_InitScriptableField( &m_addValveAtConnection, CAF_PDM_InitField( &m_addValveAtConnection,
"AddValveAtConnection", "AddValveAtConnection",
false, false,
"Add Outlet Valve for Branches", "Add Outlet Valve for Branches",
"", "",
"Should an outlet valve be added to branches for MSW export?", "Should an outlet valve be added to branches for MSW export?",
"" ); "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_valve, "Valve", "Branch Outlet Valve", "", "", "" );
m_valve = new RimWellPathValve; m_valve = new RimWellPathValve;
m_groupName.registerGetMethod( this, &RimWellPathGroup::createGroupName ); m_groupName.registerGetMethod( this, &RimWellPathGroup::createGroupName );

View File

@ -26,6 +26,9 @@
#include "RimWellPath.h" #include "RimWellPath.h"
#include "RimWellPathGeometryDef.h" #include "RimWellPathGeometryDef.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmFieldScriptingCapabilityCvfVec3d.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiLineEditor.h" #include "cafPdmUiLineEditor.h"
@ -54,19 +57,26 @@ RimWellPathTarget::RimWellPathTarget()
, m_inclination( 0.0 ) , m_inclination( 0.0 )
, m_isFullUpdateEnabled( true ) , m_isFullUpdateEnabled( true )
{ {
CAF_PDM_InitScriptableObjectWithNameAndComment( "Well Target",
"",
"",
"",
"WellPathTarget",
"Class containing the Well Target definition" );
CAF_PDM_InitField( &m_isEnabled, "IsEnabled", true, "", "", "", "" ); CAF_PDM_InitField( &m_isEnabled, "IsEnabled", true, "", "", "", "" );
CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "", "", "", "" ); CAF_PDM_InitField( &m_isLocked, "IsLocked", false, "", "", "", "" );
m_isLocked.uiCapability()->setUiHidden( true ); m_isLocked.uiCapability()->setUiHidden( true );
// m_targetType.uiCapability()->setUiHidden(true); // m_targetType.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault( &m_targetPoint, "TargetPoint", "Point", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_targetPoint, "TargetPoint", "Point", "", "", "" );
CAF_PDM_InitField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" ); CAF_PDM_InitScriptableField( &m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", "" );
CAF_PDM_InitField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" ); CAF_PDM_InitScriptableField( &m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", "" );
CAF_PDM_InitFieldNoDefault( &m_targetType, "TargetType", "Type", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_targetType, "TargetType", "Type", "", "", "" );
m_targetType.uiCapability()->setUiHidden( true ); m_targetType.uiCapability()->setUiHidden( true );
CAF_PDM_InitField( &m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir", "", "", "" ); CAF_PDM_InitField( &m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir", "", "", "" );
m_hasTangentConstraintUiField.xmlCapability()->disableIO(); m_hasTangentConstraintUiField.xmlCapability()->disableIO();
CAF_PDM_InitField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" ); CAF_PDM_InitScriptableField( &m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", "" );
CAF_PDM_InitField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" ); CAF_PDM_InitScriptableField( &m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_parentWellPath, "ParentWellPath", "Parent Well Path", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_parentWellPath, "ParentWellPath", "Parent Well Path", "", "", "" );

View File

@ -18,6 +18,8 @@
#include "RimFaciesInitialPressureConfig.h" #include "RimFaciesInitialPressureConfig.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiLineEditor.h" #include "cafPdmUiLineEditor.h"
@ -29,12 +31,14 @@ CAF_PDM_SOURCE_INIT( RimFaciesInitialPressureConfig, "FaciesInitialPressureConfi
RimFaciesInitialPressureConfig::RimFaciesInitialPressureConfig() RimFaciesInitialPressureConfig::RimFaciesInitialPressureConfig()
: changed( this ) : changed( this )
{ {
CAF_PDM_InitScriptableObject( "Facies Initial Pressure Config", "", "", "" );
m_isChecked.uiCapability()->setUiHidden( false ); m_isChecked.uiCapability()->setUiHidden( false );
CAF_PDM_InitFieldNoDefault( &m_faciesName, "FaciesName", "Facies", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_faciesName, "FaciesName", "Facies", "", "", "" );
m_faciesName.uiCapability()->setUiReadOnly( true ); m_faciesName.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitFieldNoDefault( &m_faciesValue, "FaciesValue", "Value", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_faciesValue, "FaciesValue", "Value", "", "", "" );
m_faciesValue.uiCapability()->setUiHidden( true ); m_faciesValue.uiCapability()->setUiHidden( true );
// Use unicode for delta letter // Use unicode for delta letter
@ -44,7 +48,7 @@ RimFaciesInitialPressureConfig::RimFaciesInitialPressureConfig()
QString deltaPressureFractionString = QString::fromUtf8( "\u0394 Pressure Fraction" ); QString deltaPressureFractionString = QString::fromUtf8( "\u0394 Pressure Fraction" );
#endif #endif
CAF_PDM_InitField( &m_fraction, "Fraction", 0.0, deltaPressureFractionString, "", "", "" ); CAF_PDM_InitScriptableField( &m_fraction, "Fraction", 0.0, deltaPressureFractionString, "", "", "" );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -21,6 +21,8 @@
#include "RimPressureTableItem.h" #include "RimPressureTableItem.h"
#include "cafCmdFeatureMenuBuilder.h" #include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiTableViewEditor.h" #include "cafPdmUiTableViewEditor.h"
#include "cafPdmUiTreeOrdering.h" #include "cafPdmUiTreeOrdering.h"
@ -32,14 +34,14 @@ CAF_PDM_SOURCE_INIT( RimPressureTable, "PressureTable" );
RimPressureTable::RimPressureTable() RimPressureTable::RimPressureTable()
: changed( this ) : changed( this )
{ {
CAF_PDM_InitObject( "Pressure Table", "", "", "" ); CAF_PDM_InitScriptableObject( "Pressure Table", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_pressureTableItems, "Items", "Pressure Table Items", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_pressureTableItems, "Items", "Pressure Table Items", "", "", "" );
m_pressureTableItems.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() ); m_pressureTableItems.uiCapability()->setUiEditorTypeName( caf::PdmUiTableViewEditor::uiEditorTypeName() );
m_pressureTableItems.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); m_pressureTableItems.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
m_pressureTableItems.uiCapability()->setCustomContextMenuEnabled( true ); m_pressureTableItems.uiCapability()->setCustomContextMenuEnabled( true );
CAF_PDM_InitFieldNoDefault( &m_pressureDate, "PressureDate", "Pressure Date", "", "", "" ); CAF_PDM_InitScriptableFieldNoDefault( &m_pressureDate, "PressureDate", "Pressure Date", "", "", "" );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -18,6 +18,8 @@
#include "RimPressureTableItem.h" #include "RimPressureTableItem.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiLineEditor.h" #include "cafPdmUiLineEditor.h"
@ -29,9 +31,11 @@ CAF_PDM_SOURCE_INIT( RimPressureTableItem, "PressureTableItem" );
RimPressureTableItem::RimPressureTableItem() RimPressureTableItem::RimPressureTableItem()
: changed( this ) : changed( this )
{ {
CAF_PDM_InitField( &m_depth, "Depth", 0.0, "Depth TVDMSL [m]", "", "", "" ); CAF_PDM_InitScriptableObject( "Pressure Table Item", "", "", "" );
CAF_PDM_InitField( &m_initialPressure, "InitialPressure", 0.0, "Initial Pressure [Bar]", "", "", "" );
CAF_PDM_InitField( &m_pressure, "Pressure", 0.0, "Pressure [Bar]", "", "", "" ); CAF_PDM_InitScriptableField( &m_depth, "Depth", 0.0, "Depth TVDMSL [m]", "", "", "" );
CAF_PDM_InitScriptableField( &m_initialPressure, "InitialPressure", 0.0, "Initial Pressure [Bar]", "", "", "" );
CAF_PDM_InitScriptableField( &m_pressure, "Pressure", 0.0, "Pressure [Bar]", "", "", "" );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -61,9 +61,9 @@ class PdmObjectFactory;
class PdmCodeGenerator class PdmCodeGenerator
{ {
public: public:
virtual QString generate( PdmObjectFactory* factory ) const = 0; virtual QString generate( PdmObjectFactory* factory, std::vector<QString>& errorMessages ) const = 0;
}; };
typedef Factory<PdmCodeGenerator, std::string> PdmCodeGeneratorFactory; typedef Factory<PdmCodeGenerator, std::string> PdmCodeGeneratorFactory;
} // namespace caf } // namespace caf

View File

@ -46,7 +46,7 @@ CAF_PDM_CODE_GENERATOR_SOURCE_INIT( PdmMarkdownGenerator, "md" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString caf::PdmMarkdownGenerator::generate( PdmObjectFactory* factory ) const QString caf::PdmMarkdownGenerator::generate( PdmObjectFactory* factory, std::vector<QString>& errorMessages ) const
{ {
QString generatedCode; QString generatedCode;
QTextStream out( &generatedCode ); QTextStream out( &generatedCode );

View File

@ -58,7 +58,7 @@ class PdmMarkdownGenerator : public PdmCodeGenerator
}; };
public: public:
QString generate( PdmObjectFactory* factory ) const override; QString generate( PdmObjectFactory* factory, std::vector<QString>& errorMessages ) const override;
}; };
} // namespace caf } // namespace caf

View File

@ -59,7 +59,7 @@ CAF_PDM_CODE_GENERATOR_SOURCE_INIT( PdmPythonGenerator, "py" );
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const QString caf::PdmPythonGenerator::generate( PdmObjectFactory* factory, std::vector<QString>& errorMessages ) const
{ {
QString generatedCode; QString generatedCode;
QTextStream out( &generatedCode ); QTextStream out( &generatedCode );
@ -92,6 +92,7 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated; std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated;
std::map<QString, std::map<QString, QString>> classMethodsGenerated; std::map<QString, std::map<QString, QString>> classMethodsGenerated;
std::map<QString, QString> classCommentsGenerated; std::map<QString, QString> classCommentsGenerated;
std::set<QString> dataTypesInChildFields;
// First generate all attributes and comments to go into each object // First generate all attributes and comments to go into each object
for ( std::shared_ptr<PdmObject> object : dummyObjects ) for ( std::shared_ptr<PdmObject> object : dummyObjects )
@ -181,9 +182,14 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
} }
else else
{ {
QString valueString; QString valueString;
QTextStream valueStream( &valueString );
scriptability->readFromField( valueStream, true, true ); // Always make sure the default value for a ptrField is empty string
if ( !field->hasPtrReferencedObjects() )
{
QTextStream valueStream( &valueString );
scriptability->readFromField( valueStream, true, true );
}
if ( valueString.isEmpty() ) valueString = QString( "\"\"" ); if ( valueString.isEmpty() ) valueString = QString( "\"\"" );
valueString = pythonifyDataValue( valueString ); valueString = pythonifyDataValue( valueString );
@ -203,6 +209,8 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
QString scriptDataType = QString scriptDataType =
PdmObjectScriptingCapabilityRegister::scriptClassNameFromClassKeyword( dataType ); PdmObjectScriptingCapabilityRegister::scriptClassNameFromClassKeyword( dataType );
dataTypesInChildFields.insert( scriptDataType );
QString commentDataType = field->xmlCapability()->isVectorField() QString commentDataType = field->xmlCapability()->isVectorField()
? QString( "List of %1" ).arg( scriptDataType ) ? QString( "List of %1" ).arg( scriptDataType )
: scriptDataType; : scriptDataType;
@ -385,6 +393,16 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
out << " return all_classes[class_keyword]\n"; out << " return all_classes[class_keyword]\n";
out << " return None\n"; out << " return None\n";
// Check if all referenced data types are exported as classes
for ( const auto& scriptDataType : dataTypesInChildFields )
{
if ( classesWritten.count( scriptDataType ) == 0 )
{
QString errorText = "No export for data type " + scriptDataType;
errorMessages.push_back( errorText );
}
}
return generatedCode; return generatedCode;
} }

View File

@ -49,11 +49,11 @@ class PdmPythonGenerator : public PdmCodeGenerator
CAF_PDM_CODE_GENERATOR_HEADER_INIT; CAF_PDM_CODE_GENERATOR_HEADER_INIT;
public: public:
QString generate( PdmObjectFactory* factory ) const override; QString generate( PdmObjectFactory* factory, std::vector<QString>& errorMessages ) const override;
static QString camelToSnakeCase( const QString& camelString ); static QString camelToSnakeCase( const QString& camelString );
static QString dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes ); static QString dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes );
static QString pythonifyDataValue( const QString& dataValue ); static QString pythonifyDataValue( const QString& dataValue );
}; };
} // namespace caf } // namespace caf

View File

@ -250,7 +250,8 @@ TEST( PdmScriptingTest, BasicUse )
std::string fileExt = "py"; std::string fileExt = "py";
std::unique_ptr<caf::PdmCodeGenerator> generator( caf::PdmCodeGeneratorFactory::instance()->create( fileExt ) ); std::unique_ptr<caf::PdmCodeGenerator> generator( caf::PdmCodeGeneratorFactory::instance()->create( fileExt ) );
auto generatedText = generator->generate( caf::PdmDefaultObjectFactory::instance() ); std::vector<QString> logMessages;
auto generatedText = generator->generate( caf::PdmDefaultObjectFactory::instance(), logMessages );
auto string = generatedText.toStdString(); auto string = generatedText.toStdString();
} }

View File

@ -104,6 +104,8 @@ public:
virtual void onChildDeleted( PdmChildArrayFieldHandle* childArray, virtual void onChildDeleted( PdmChildArrayFieldHandle* childArray,
std::vector<caf::PdmObjectHandle*>& referringObjects ); std::vector<caf::PdmObjectHandle*>& referringObjects );
virtual void onChildAdded( caf::PdmFieldHandle* containerForNewObject ){};
protected: protected:
void addField( PdmFieldHandle* field, const QString& keyword ); void addField( PdmFieldHandle* field, const QString& keyword );

View File

@ -32,6 +32,7 @@ message CreatePdmChildObjectRequest
{ {
PdmObject object = 1; PdmObject object = 1;
string child_field = 2; string child_field = 2;
string class_keyword = 3;
} }
message PdmParentObjectRequest message PdmParentObjectRequest

View File

@ -284,6 +284,41 @@ class PdmObjectBase:
return [] return []
raise e raise e
def add_new_object(self, class_definition, child_field=""):
"""Create and add an object to the specified child field
Arguments:
class_definition[class]: Class definition of the object to create
child_field[str]: The keyword for the field to create a new object in. If empty, the first child array field is used.
Returns:
The created PdmObject inside the child_field
"""
from .generated.generated_classes import class_from_keyword
assert inspect.isclass(class_definition)
class_keyword = class_definition.__name__
request = PdmObject_pb2.CreatePdmChildObjectRequest(
object=self._pb2_object,
child_field=child_field,
class_keyword=class_keyword,
)
try:
pb2_object = self._pdm_object_stub.CreateChildPdmObject(request)
child_class_definition = class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
child_class_definition = class_keyword
pdm_object = child_class_definition(
pb2_object=pb2_object, channel=self.channel()
)
return pdm_object
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return None
raise e
def ancestor(self, class_definition): def ancestor(self, class_definition):
"""Find the first ancestor that matches the provided class_keyword """Find the first ancestor that matches the provided class_keyword
Arguments: Arguments:

View File

@ -0,0 +1,35 @@
from rips.generated.generated_classes import (
ModeledWellPath,
StimPlanModel,
WellPathGeometry,
WellPathTarget,
)
import sys
import os
sys.path.insert(1, os.path.join(sys.path[0], "../../"))
import rips
def test_well_path_target(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()
geometry = my_well_path.well_path_geometry()
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
geometry.add_new_object(rips.WellPathTarget)
assert len(geometry.well_path_targets()) == 3
assert len(well_path_coll.well_paths()) == 1
my_well_path_duplicate = well_path_coll.well_paths()[0]
assert my_well_path_duplicate.name == "test"
geometry_duplicate = my_well_path_duplicate.well_path_geometry()
assert len(geometry_duplicate.well_path_targets()) == 3
# Not allowed to add object of unrelated type
invalid_object = geometry.add_new_object(rips.WellPath)
assert invalid_object is None

View File

@ -19,5 +19,5 @@ setup(
license=license, license=license,
packages=['rips'], packages=['rips'],
package_data={'rips': ['*.py', 'generated/*.py', 'PythonExamples/*.py', 'tests/*.py']}, package_data={'rips': ['*.py', 'generated/*.py', 'PythonExamples/*.py', 'tests/*.py']},
install_requires=['grpcio>=1.20.0', protobuf, wheel] install_requires=['grpcio>=1.20.0', 'protobuf', 'wheel']
) )

View File

@ -269,7 +269,7 @@ void RiaGrpcCommandService::assignPdmObjectValues( caf::PdmObjectHandle*
} }
else if ( childObjects.empty() ) else if ( childObjects.empty() )
{ {
childObject = emplaceChildField( pdmChildFieldHandle ); childObject = emplaceChildField( pdmChildFieldHandle, "" );
} }
CAF_ASSERT( childObject ); CAF_ASSERT( childObject );
if ( childObject ) if ( childObject )

View File

@ -473,11 +473,15 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext*
{ {
CAF_ASSERT( request ); CAF_ASSERT( request );
caf::PdmObjectHandle* pdmObject = QString keywordClassToCreate = QString::fromStdString( request->class_keyword() );
emplaceChildField( matchingObject, QString::fromStdString( request->child_field() ) ); QString fieldKeyword = QString::fromStdString( request->child_field() );
if ( pdmObject )
caf::PdmObjectHandle* pdmObjectHandle = emplaceChildField( matchingObject, fieldKeyword, keywordClassToCreate );
if ( pdmObjectHandle )
{ {
copyPdmObjectFromCafToRips( pdmObject, reply ); copyPdmObjectFromCafToRips( pdmObjectHandle, reply );
matchingObject->uiCapability()->updateConnectedEditors();
return grpc::Status::OK; return grpc::Status::OK;
} }
return grpc::Status( grpc::NOT_FOUND, "Could not create PdmObject" ); return grpc::Status( grpc::NOT_FOUND, "Could not create PdmObject" );

View File

@ -142,6 +142,12 @@ void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject*
auto scriptability = field->template capability<caf::PdmAbstractFieldScriptingCapability>(); auto scriptability = field->template capability<caf::PdmAbstractFieldScriptingCapability>();
if ( scriptability ) if ( scriptability )
{ {
if ( !dynamic_cast<caf::PdmValueField*>( field ) )
{
// Recursive object update is not supported
// https://github.com/OPM/ResInsight/issues/7794
continue;
}
QString keyword = scriptability->scriptFieldName(); QString keyword = scriptability->scriptFieldName();
QString value = QString::fromStdString( parametersMap[keyword.toStdString()] ); QString value = QString::fromStdString( parametersMap[keyword.toStdString()] );
@ -181,7 +187,9 @@ bool RiaGrpcServiceInterface::assignFieldValue( const QString& stringValue
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject* parent, const QString& fieldLabel ) caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject* parent,
const QString& fieldKeyword,
const QString& keywordForClassToCreate )
{ {
std::vector<caf::PdmFieldHandle*> fields; std::vector<caf::PdmFieldHandle*> fields;
parent->fields( fields ); parent->fields( fields );
@ -190,13 +198,32 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject
{ {
auto pdmChildArrayField = dynamic_cast<caf::PdmChildArrayFieldHandle*>( field ); auto pdmChildArrayField = dynamic_cast<caf::PdmChildArrayFieldHandle*>( field );
auto pdmChildField = dynamic_cast<caf::PdmChildFieldHandle*>( field ); auto pdmChildField = dynamic_cast<caf::PdmChildFieldHandle*>( field );
if ( pdmChildArrayField && pdmChildArrayField->keyword() == fieldLabel ) if ( pdmChildArrayField )
{ {
return emplaceChildArrayField( pdmChildArrayField ); bool isMatching = false;
if ( fieldKeyword.isEmpty() )
{
// Use first child array field if no fieldKeyword is specified
isMatching = true;
}
else
{
isMatching = ( pdmChildArrayField->keyword() == fieldKeyword );
}
if ( isMatching )
{
auto objectCreated = emplaceChildArrayField( pdmChildArrayField, keywordForClassToCreate );
// Notify parent object that a new object has been created
if ( objectCreated ) parent->onChildAdded( pdmChildArrayField );
return objectCreated;
}
} }
else if ( pdmChildField && pdmChildField->keyword() == fieldLabel ) else if ( pdmChildField && pdmChildField->keyword() == fieldKeyword )
{ {
return emplaceChildField( pdmChildField ); return emplaceChildField( pdmChildField, keywordForClassToCreate );
} }
} }
return nullptr; return nullptr;
@ -205,12 +232,33 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField ) caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField,
const QString& keywordForClassToCreate )
{ {
QString childClassKeyword = childField->xmlCapability()->dataTypeName(); QString childClassKeyword;
if ( keywordForClassToCreate.isEmpty() )
{
childClassKeyword = childField->xmlCapability()->dataTypeName();
}
else
{
childClassKeyword = keywordForClassToCreate;
}
auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword );
CAF_ASSERT( pdmObjectHandle ); CAF_ASSERT( pdmObjectHandle );
{
auto childDataTypeName = childField->xmlCapability()->dataTypeName();
auto isInheritanceValid = pdmObjectHandle->xmlCapability()->inheritsClassWithKeyword( childDataTypeName );
if ( !isInheritanceValid )
{
delete pdmObjectHandle;
return nullptr;
}
}
childField->setChildObject( pdmObjectHandle ); childField->setChildObject( pdmObjectHandle );
return pdmObjectHandle; return pdmObjectHandle;
} }
@ -218,13 +266,34 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildF
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField ) caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField,
const QString& keywordForClassToCreate )
{ {
QString childClassKeyword = childArrayField->xmlCapability()->dataTypeName(); QString childClassKeyword;
if ( keywordForClassToCreate.isEmpty() )
{
childClassKeyword = childArrayField->xmlCapability()->dataTypeName();
}
else
{
childClassKeyword = keywordForClassToCreate;
}
auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword );
CAF_ASSERT( pdmObjectHandle ); if ( !pdmObjectHandle ) return nullptr;
{
auto childDataTypeName = childArrayField->xmlCapability()->dataTypeName();
auto isInheritanceValid = pdmObjectHandle->xmlCapability()->inheritsClassWithKeyword( childDataTypeName );
if ( !isInheritanceValid )
{
delete pdmObjectHandle;
return nullptr;
}
}
childArrayField->insertAt( -1, pdmObjectHandle ); childArrayField->insertAt( -1, pdmObjectHandle );
return pdmObjectHandle; return pdmObjectHandle;
} }

View File

@ -60,10 +60,13 @@ public:
static bool static bool
assignFieldValue( const QString& stringValue, caf::PdmFieldHandle* field, QVariant* oldValue, QVariant* newValue ); assignFieldValue( const QString& stringValue, caf::PdmFieldHandle* field, QVariant* oldValue, QVariant* newValue );
static caf::PdmObjectHandle* emplaceChildField( caf::PdmObject* parent, const QString& fieldLabel ); static caf::PdmObjectHandle*
emplaceChildField( caf::PdmObject* parent, const QString& fieldKeyword, const QString& keywordForClassToCreate );
static caf::PdmObjectHandle* emplaceChildField( caf::PdmChildFieldHandle* childField ); static caf::PdmObjectHandle* emplaceChildField( caf::PdmChildFieldHandle* childField,
static caf::PdmObjectHandle* emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField ); const QString& keywordForClassToCreate );
static caf::PdmObjectHandle* emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField,
const QString& keywordForClassToCreate );
}; };
#include "cafFactory.h" #include "cafFactory.h"