From bd8e079e241c3bcb00f8feb3d4344777ac52c03e Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Wed, 4 Mar 2020 14:52:16 +0100 Subject: [PATCH] #5632 Generate PdmChildField and PdmChildArrayField methods --- .../Python/rips/PythonExamples/all_cases.py | 2 +- .../rips/PythonExamples/alter_wbs_plot.py | 2 +- .../rips/PythonExamples/export_plots.py | 7 +- .../launch_with_commandline_options.py | 2 +- .../GrpcInterface/Python/rips/case.py | 5 -- .../GrpcInterface/Python/rips/pdmobject.py | 1 + .../Python/rips/well_bore_stability_plot.py | 18 +--- .../GrpcInterface/RiaGrpcPdmObjectService.cpp | 10 ++- .../ProjectDataModel/RimEclipseCase.cpp | 8 +- .../ProjectDataModel/RimEclipseView.cpp | 8 +- .../ProjectDataModel/RimGeoMechCase.cpp | 8 +- .../RimWellBoreStabilityPlot.cpp | 2 +- .../cafPdmScripting/cafPdmPythonGenerator.cpp | 86 +++++++++++-------- .../cafPdmScripting/cafPdmPythonGenerator.h | 2 +- .../cafInternalPdmXmlFieldCapability.h | 3 +- .../cafInternalPdmXmlFieldCapability.inl | 19 +++- 16 files changed, 112 insertions(+), 71 deletions(-) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/all_cases.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/all_cases.py index a28254d890..28db4aeced 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/all_cases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/all_cases.py @@ -16,7 +16,7 @@ if resinsight is not None: for case in cases: print("Case id: " + str(case.id)) print("Case name: " + case.name) - print("Case type: " + case.class_keyword) + print("Case type: " + case.__class__.__name__) print("Case file name: " + case.file_path) print("Case reservoir bounding box:", case.reservoir_boundingbox()) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/alter_wbs_plot.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/alter_wbs_plot.py index d2f7a0bace..e65c5adad4 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/alter_wbs_plot.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/alter_wbs_plot.py @@ -20,7 +20,7 @@ for wbsplot in wbsplots: # Example of setting parameters for existing plots params = wbsplot.parameters() - params.user_poisson_ratio = 0.654321 + params.user_poisson_ratio = 0.12345 params.update() wbsplot.update() wbsplot.export_snapshot(export_folder=dirname) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/export_plots.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/export_plots.py index 0bab47bf9c..3baeeb4476 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/export_plots.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/export_plots.py @@ -15,7 +15,6 @@ print("Exporting to: " + export_folder) for plot in plots: plot.export_snapshot(export_folder=export_folder) plot.export_snapshot(export_folder=export_folder, output_format='PDF') - well_log_plot = plot.cast(rips.WellLogPlot) - if well_log_plot is not None: - well_log_plot.export_data_as_las(export_folder=export_folder) - well_log_plot.export_data_as_ascii(export_folder=export_folder) + if isinstance(plot, rips.WellLogPlot): + plot.export_data_as_las(export_folder=export_folder) + plot.export_data_as_ascii(export_folder=export_folder) diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/launch_with_commandline_options.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/launch_with_commandline_options.py index f6b85def3c..3f5faaa8a5 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/launch_with_commandline_options.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/launch_with_commandline_options.py @@ -8,4 +8,4 @@ cases = resinsight.project.cases() print ("Got " + str(len(cases)) + " cases: ") for case in cases: print("Case name: " + case.name) - print("Case grid path: " + case.grid_path()) + print("Case grid path: " + case.file_path) diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py index a0f7a3be04..3987d1e66b 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/case.py +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -245,11 +245,6 @@ def days_since_start(self): """Get a list of decimal values representing days since the start of the simulation""" return self.__case_stub.GetDaysSinceStart(self.__request()).day_decimals -@add_method(Case) -def views(self): - """Get a list of views belonging to a case""" - return self.descendants(View) - @add_method(Case) def view(self, view_id): """Get a particular view belonging to a case by providing view id diff --git a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py index d91f346541..f89eb31fc7 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py +++ b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py @@ -87,6 +87,7 @@ def copy_from(self, object): setattr(self, attribute, value) if self.__custom_init__ is not None: self.__custom_init__(self._pb2_object, self._channel) + self.update() @add_method(PdmObject) def warnings(self): diff --git a/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py b/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py index 62651dffbc..b8c3fb775e 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py +++ b/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py @@ -28,18 +28,6 @@ def __custom_init__(self, pb2_object=None, channel=None): self.user_k0fg = 0.75 @add_method(WellBoreStabilityPlot) -def parameters(self): - """Retrieve the parameters of the Plot - """ - children = self.children("WbsParameters", WbsParameters) - if len(children) == 1: - child = children[0] - return child - return None - -@add_method(WellBoreStabilityPlot) -def set_parameters(self, wbs_parameters): - children = self.children("WbsParameters", WbsParameters) - if len(children) == 1: - pdm_params = children[0] - pdm_params.copy_from(wbs_parameters) +def set_parameters(self, new_parameters): + current_params = self.parameters() + current_params.copy_from(new_parameters) diff --git a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp index fb17522500..b103f74679 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp +++ b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp @@ -24,6 +24,7 @@ #include "RimEclipseResultDefinition.h" #include "RimProject.h" +#include "cafPdmFieldScriptability.h" #include "cafPdmObject.h" #include "cafPdmObjectScriptabilityRegister.h" @@ -171,7 +172,8 @@ Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectMethodRequest* m_fieldOwner->fields( fields ); for ( auto field : fields ) { - if ( field->keyword() == fieldName ) + auto scriptability = field->capability(); + if ( scriptability && scriptability->scriptFieldName() == fieldName ) { caf::PdmProxyFieldHandle* proxyField = dynamic_cast( field ); if ( proxyField ) @@ -224,7 +226,8 @@ Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectSetMethodChunk m_fieldOwner->fields( fields ); for ( auto field : fields ) { - if ( field->keyword() == fieldName ) + auto scriptability = field->capability(); + if ( scriptability && scriptability->scriptFieldName() == fieldName ) { caf::PdmProxyFieldHandle* proxyField = dynamic_cast( field ); if ( proxyField ) @@ -406,7 +409,8 @@ grpc::Status RiaGrpcPdmObjectService::GetChildPdmObjects( grpc::ServerContext* matchingObject->fields( fields ); for ( auto field : fields ) { - if ( field->keyword() == fieldName ) + auto scriptability = field->capability(); + if ( scriptability && scriptability->scriptFieldName() == fieldName ) { std::vector childObjects; field->childObjects( &childObjects ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index 5c6a639406..fda868f356 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -85,7 +85,13 @@ RimEclipseCase::RimEclipseCase() "Reservoir", "Abtract base class for Eclipse Cases" ); - CAF_PDM_InitFieldNoDefault( &reservoirViews, "ReservoirViews", "", "", "", "" ); + CAF_PDM_InitScriptableFieldWithKeywordNoDefault( &reservoirViews, + "ReservoirViews", + "Views", + "", + "", + "", + "All Eclipse Views in the case" ); reservoirViews.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_matrixModelResults, "MatrixModelResults", "", "", "", "" ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index dad935b8a4..b5e8a87046 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -128,7 +128,13 @@ RimEclipseView::RimEclipseView() "EclipseView", "The Eclipse 3d Reservoir View" ); - CAF_PDM_InitFieldNoDefault( &m_cellResult, "GridCellResult", "Cell Result", ":/CellResult.png", "", "" ); + CAF_PDM_InitScriptableFieldWithKeywordNoDefault( &m_cellResult, + "GridCellResult", + "CellResult", + "Cell Result", + ":/CellResult.png", + "", + "" ); m_cellResult = new RimEclipseCellColors(); m_cellResult.uiCapability()->setUiHidden( true ); m_cellResult->setDiffResultOptionsEnabled( true ); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index 3f928f9516..e788d5dbf8 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -76,7 +76,13 @@ RimGeoMechCase::RimGeoMechCase( void ) "GeoMechCase", "The Abaqus Based GeoMech Case" ); - CAF_PDM_InitFieldNoDefault( &geoMechViews, "GeoMechViews", "", "", "", "" ); + CAF_PDM_InitScriptableFieldWithKeywordNoDefault( &geoMechViews, + "GeoMechViews", + "Views", + "", + "", + "", + "All GeoMech Views in the Case" ); geoMechViews.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_cohesion, "CaseCohesion", 10.0, "Cohesion", "", "Used to calculate the SE:SFI result", "" ); diff --git a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp index 37b85ad5fa..b02093ce8a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp @@ -49,7 +49,7 @@ RimWellBoreStabilityPlot::RimWellBoreStabilityPlot() CAF_PDM_InitScriptableFieldWithKeywordNoDefault( &m_wbsParameters, "WbsParameters", - "Params", + "Parameters", "Well Bore Stability Parameters", "", "", diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp index 215384bc2f..211c940a64 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp @@ -35,6 +35,8 @@ //################################################################################################## #include "cafPdmPythonGenerator.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmFieldScriptability.h" #include "cafPdmObject.h" #include "cafPdmObjectFactory.h" @@ -112,35 +114,40 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const object->fields(fields); for (auto field : fields) { - auto pdmValueField = dynamic_cast(field); - if (pdmValueField) + auto scriptability = field->template capability(); + if (scriptability != nullptr) { - QString keyword = pdmValueField->keyword(); - auto scriptability = field->template capability(); - if (scriptability != nullptr) + QString snake_field_name = camelToSnakeCase(scriptability->scriptFieldName()); + + QString comment; { + QStringList commentComponents; + commentComponents << field->capability()->uiName(); + commentComponents << field->capability()->uiWhatsThis(); + commentComponents.removeAll(QString("")); + comment = commentComponents.join(". "); + } + + auto pdmValueField = dynamic_cast(field); + auto pdmChildField = dynamic_cast(field); + auto pdmChildArrayField = dynamic_cast(field); + if (pdmValueField) + { + QString dataType = PdmPythonGenerator::dataTypeString(field, true); + if (field->xmlCapability()->isVectorField()) + { + dataType = QString("List of %1").arg(dataType); + } + bool shouldBeMethod = false; auto proxyField = dynamic_cast(field); if (proxyField && proxyField->isStreamingField()) shouldBeMethod = true; - QString snake_field_name = camelToSnakeCase(scriptability->scriptFieldName()); if (classAttributesGenerated[field->ownerClass()].count(snake_field_name)) continue; if (classMethodsGenerated[field->ownerClass()].count(snake_field_name)) continue; - QString comment; - { - QStringList commentComponents; - commentComponents << pdmValueField->capability()->uiName(); - commentComponents << pdmValueField->capability()->uiWhatsThis(); - commentComponents.removeAll(QString("")); - comment = commentComponents.join(". "); - } - QVariant valueVariant = pdmValueField->toQVariant(); - bool isList, isBuiltinType; - QString dataType = PdmPythonGenerator::dataTypeString(pdmValueField, &isList, &isBuiltinType); - if (shouldBeMethod) { if (proxyField->hasGetter()) @@ -174,7 +181,7 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const } } else - { + { QString valueString; QTextStream valueStream(&valueString); scriptability->readFromField(valueStream, true, true); @@ -191,6 +198,29 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment; } } + else if (pdmChildField || pdmChildArrayField) + { + QString dataType = PdmPythonGenerator::dataTypeString(field, false); + QString scriptDataType = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(dataType); + + QString commentDataType = field->xmlCapability()->isVectorField() ? + QString("List of %1").arg(scriptDataType) : scriptDataType; + + QString firstItemTag = pdmChildField ? QString("[0]") : QString(""); + QString fullComment = + QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"") + .arg(comment) + .arg(commentDataType); + + QString fieldCode = QString(" def %1(self):\n%2\n return " + "self.children(\"%3\", %4)%5\n") + .arg(snake_field_name) + .arg(fullComment) + .arg(scriptability->scriptFieldName()) + .arg(scriptDataType) + .arg(firstItemTag); + classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode; + } } } } @@ -309,12 +339,11 @@ QString PdmPythonGenerator::camelToSnakeCase(const QString& camelString) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool* isList, bool* isBuiltinType) +QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes) { auto xmlObj = field->capability(); QString dataType = xmlObj->dataTypeName(); - bool foundList = xmlObj->isVectorField(); std::map builtins = { {QString::fromStdString(typeid(double).name()), "float"}, @@ -333,22 +362,11 @@ QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool* is } } - if (isList) - { - *isList = foundList; - } - if (isBuiltinType) - { - *isBuiltinType = foundBuiltin; - } - - if (!foundBuiltin) + if (!foundBuiltin && useStrForUnknownDataTypes) { dataType = "str"; } - - if (foundList) return QString("List of %1").arg(dataType); - + return dataType; } diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h index a16d1cd4f2..1c4f47eb00 100644 --- a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h @@ -50,7 +50,7 @@ class PdmPythonGenerator : public PdmCodeGenerator public: QString generate(PdmObjectFactory* factory) const override; static QString camelToSnakeCase(const QString& camelString); - static QString dataTypeString(const PdmFieldHandle* field, bool* isList = nullptr, bool* isBuiltinType = nullptr); + static QString dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes); static QString pythonifyDataValue(const QString& dataValue); static QString pythonHelpString(const QString& existingTooltip, const QString& keyword); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h index fd3e6101ac..acb1bce005 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h @@ -80,7 +80,7 @@ public: void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; void writeFieldData(QXmlStreamWriter& xmlStream) const override; bool resolveReferences() override; - + bool isVectorField() const; private: FieldType* m_field; @@ -124,6 +124,7 @@ public: void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; void writeFieldData(QXmlStreamWriter& xmlStream) const override; bool resolveReferences() override; + bool isVectorField() const; private: FieldType* m_field; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl index 614e57b54d..a00b7da813 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl @@ -218,7 +218,15 @@ bool caf::PdmFieldXmlCap::resolveReferences() return foundValidObjectFromString; } - + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + template < typename DataType> + bool caf::PdmFieldXmlCap< caf::PdmPtrArrayField >::isVectorField() const + { + return true; + } //================================================================================================== /// XML Implementation for PdmChildField<> @@ -432,4 +440,13 @@ bool caf::PdmFieldXmlCap>::resolveReferences return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template < typename DataType> +bool caf::PdmFieldXmlCap< caf::PdmChildArrayField >::isVectorField() const +{ + return true; +} + } // End namespace caf