diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ad103c955e..e48dcd454b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,20 +11,19 @@ jobs: include: - os: windows-latest triplet: x64-windows - vcpkgGitCommitId: '6282cab61d175974b1af06473db584b9b80dcd48' - vcpkgPackages: 'grpc' - os: ubuntu-latest triplet: x64-linux - vcpkgGitCommitId: '6282cab61d175974b1af06473db584b9b80dcd48' - vcpkgPackages: 'grpc' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v1 + with: + submodules: true - name: Install Qt - uses: ouuan/install-qt-action@v2.3.1 + uses: jurplel/install-qt-action@v2.5.0 with: version: 5.9 modules: qtscript + mirror: 'http://mirrors.ocf.berkeley.edu/qt/' - name: Install Python dependencies run: | python -m pip install --upgrade pip @@ -36,36 +35,39 @@ jobs: - name: Cache vcpkg artifacts uses: actions/cache@v1 env: - cache-name: cache-vcpkg-modules + vcpkgResponseFile: '${{ github.workspace }}/vcpkg_${{ matrix.triplet }}.txt' with: path: ${{ github.workspace }}/vcpkg/ - key: ${{ env.cache-name }}-${{ runner.os }} + # Ensure the cache is invalidated any time vcpkg version changes, or a different set of packages is being used. + key: ${{ hashFiles( env.vcpkgResponseFile ) }}-${{ hashFiles('.git/modules/vcpkg/HEAD') }}-${{ runner.os }} - name: Run vcpkg - uses: lukka/run-vcpkg@v0.10 + uses: lukka/run-vcpkg@v0 id: runvcpkg + env: + vcpkgResponseFile: '${{ github.workspace }}/vcpkg_${{ matrix.triplet }}.txt' with: - vcpkgArguments: '${{ matrix.vcpkgPackages }}' - vcpkgTriplet: '${{ matrix.triplet }}' - vcpkgGitCommitId: '${{ matrix.vcpkgGitCommitId }}' + vcpkgArguments: '@${{ env.vcpkgResponseFile }}' + vcpkgDirectory: '${{ github.workspace }}/vcpkg' - name: Prints outputs of run-vcpkg task run: echo "'${{ steps.runvcpkg.outputs.RUNVCPKG_VCPKG_ROOT_OUT }}' '${{ steps.runvcpkg.outputs.RUNVCPKG_VCPKG_TRIPLET_OUT }}' " - - name: Build ResInsight-x64 Windows - if: "contains( matrix.os, 'windows')" + - name: Build ResInsight-x64 + uses: lukka/run-cmake@v0 + with: + cmakeListsOrSettingsJson: CMakeListsTxtAdvanced + cmakeAppendedArgs: -DRESINSIGHT_ENABLE_GRPC=true -DRESINSIGHT_GRPC_PYTHON_EXECUTABLE=python -DRESINSIGHT_ENABLE_PRECOMPILED_HEADERS=true -DRESINSIGHT_ENABLE_UNITY_BUILD=true + buildDirectory: ${{ github.workspace }}/cmakebuild + buildWithCMakeArgs: '--config Release --target package' + useVcpkgToolchainFile: true + - name: Remove packages/_CPack_Packages + shell: bash run: | - mkdir cmakebuild - cd cmakebuild - cmake .. -DRESINSIGHT_ENABLE_GRPC=true -DRESINSIGHT_GRPC_PYTHON_EXECUTABLE=python -DRESINSIGHT_ENABLE_PRECOMPILED_HEADERS=true -DRESINSIGHT_ENABLE_UNITY_BUILD=true -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake -A x64 - cmake --build . --config Release --target PACKAGE - rd packages/_CPack_Packages -Recurse - - name: Build ResInsight-x64 Linux - if: "contains( matrix.os, 'ubuntu')" - run: | - mkdir cmakebuild - cd cmakebuild - cmake .. -DRESINSIGHT_ENABLE_GRPC=true -DRESINSIGHT_GRPC_PYTHON_EXECUTABLE=python -DRESINSIGHT_ENABLE_PRECOMPILED_HEADERS=true -DRESINSIGHT_ENABLE_UNITY_BUILD=true -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake - cmake --build . --config Release - make package rm -rf packages/_CPack_Packages + - name: dir + run: find ${{ runner.workspace }} + if: "!contains( matrix.os, 'windows')" + - name: dir + run: gci -recurse ${{ runner.workspace }} + if: contains( matrix.os, 'windows') - name: Test with pytest if: "contains( matrix.os, 'windows')" # To be used when RESINSIGHT_GRPC_PYTHON_EXECUTABLE can be 'python' without extention in PATH env: diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..fe07c999af --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 0cad8eceea..dcf4675d3b 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -36,7 +36,6 @@ #include "RicImportGeneralDataFeature.h" #include "RicfCommandFileExecutor.h" #include "RicfFieldHandle.h" -#include "RicfMessages.h" #include "RicfObjectCapability.h" #include "Rim2dIntersectionViewCollection.h" @@ -97,7 +96,10 @@ #include "RiuViewer.h" #include "RiuViewerCommands.h" +#include "cafPdmCodeGenerator.h" +#include "cafPdmDataValueField.h" #include "cafPdmDefaultObjectFactory.h" +#include "cafPdmScriptIOMessages.h" #include "cafPdmSettings.h" #include "cafPdmUiModelChangeDetector.h" #include "cafProgressInfo.h" @@ -1260,8 +1262,8 @@ QVariant RiaApplication::cacheDataObject( const QString& key ) const //-------------------------------------------------------------------------------------------------- void RiaApplication::executeCommandFile( const QString& commandFile ) { - QFile file( commandFile ); - RicfMessages messages; + QFile file( commandFile ); + caf::PdmScriptIOMessages messages; if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) { // TODO : Error logging? @@ -1717,180 +1719,26 @@ void RiaApplication::resetProject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiaApplication::generatePythonClasses( const QString& fileName ) +bool RiaApplication::generateCode( const QString& fileName, QString* errMsg ) { - auto factory = caf::PdmDefaultObjectFactory::instance(); + CAF_ASSERT( errMsg ); - QFile pythonFile( fileName ); - if ( !pythonFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) + QFile outputFile( fileName ); + if ( !outputFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) { - return; + *errMsg = QString( "Could not open file %1 for writing" ).arg( fileName ); + return false; } - QTextStream out( &pythonFile ); - std::vector classKeywords = factory->classKeywords(); + QTextStream out( &outputFile ); - std::vector> dummyObjects; - for ( QString classKeyword : classKeywords ) + std::string fileExt = QFileInfo( fileName ).suffix().toStdString(); + + std::unique_ptr generator( caf::PdmCodeGeneratorFactory::instance()->create( fileExt ) ); + if ( !generator ) { - auto objectHandle = factory->create( classKeyword ); - const caf::PdmObject* object = dynamic_cast( objectHandle ); - CAF_ASSERT( object ); - - std::shared_ptr sharedObject( object ); - if ( RicfObjectCapability::isScriptable( sharedObject.get() ) ) - { - dummyObjects.push_back( sharedObject ); - } + *errMsg = QString( "No code generator matches the provided file extension" ); + return false; } - - // Sort to make sure super classes get created before sub classes - std::sort( dummyObjects.begin(), - dummyObjects.end(), - []( std::shared_ptr lhs, std::shared_ptr rhs ) { - if ( lhs->inheritsClassWithKeyword( rhs->classKeyword() ) ) - { - return false; - } - return lhs->classKeyword() < rhs->classKeyword(); - } ); - - std::map>> classesGenerated; - std::map classCommentsGenerated; - - // First generate all attributes and comments to go into each object - for ( std::shared_ptr object : dummyObjects ) - { - const std::list& classInheritanceStack = object->classInheritanceStack(); - - for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it ) - { - const QString& classKeyword = *it; - QString scriptClassComment = RicfObjectCapability::scriptClassComment( classKeyword ); - - std::map attributesGenerated; - - if ( !scriptClassComment.isEmpty() ) classCommentsGenerated[classKeyword] = scriptClassComment; - - if ( classKeyword == object->classKeyword() ) - { - std::vector fields; - object->fields( fields ); - for ( auto field : fields ) - { - auto pdmValueField = dynamic_cast( field ); - if ( pdmValueField ) - { - QString keyword = pdmValueField->keyword(); - auto ricfHandle = field->template capability(); - if ( ricfHandle != nullptr ) - { - QString snake_field_name = RiaTextStringTools::camelToSnakeCase( ricfHandle->fieldName() ); - if ( classesGenerated[field->ownerClass()].count( snake_field_name ) ) continue; - - QString fieldPythonCode = QString( " self.%1 = None\n" ).arg( snake_field_name ); - - QString comment; - { - QStringList commentComponents; - commentComponents << pdmValueField->capability()->uiName(); - commentComponents << pdmValueField->capability()->uiWhatsThis(); - commentComponents.removeAll( QString( "" ) ); - comment = commentComponents.join( ". " ); - } - - QVariant valueVariant = pdmValueField->toQVariant(); - QString dataTypeString = valueVariant.typeName(); - - classesGenerated[field->ownerClass()][snake_field_name].first = fieldPythonCode; - classesGenerated[field->ownerClass()][snake_field_name].second = - QString( "%1 (%2): %3\n" ).arg( snake_field_name ).arg( dataTypeString ).arg( comment ); - } - } - } - } - } - } - - // Write out classes - std::set classesWritten; - for ( std::shared_ptr object : dummyObjects ) - { - const std::list& classInheritanceStack = object->classInheritanceStack(); - std::list scriptSuperClassNames; - - for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it ) - { - const QString& classKeyword = *it; - QString scriptClassName = RicfObjectCapability::scriptClassNameFromClassKeyword( classKeyword ); - if ( scriptClassName.isEmpty() ) scriptClassName = classKeyword; - - if ( !classesWritten.count( scriptClassName ) ) - { - QString classCode; - if ( scriptSuperClassNames.empty() ) - { - classCode = QString( "class %1:\n" ).arg( scriptClassName ); - } - else - { - classCode = QString( "class %1(%2):\n" ).arg( scriptClassName ).arg( scriptSuperClassNames.back() ); - } - - if ( !classCommentsGenerated[classKeyword].isEmpty() || !classesGenerated[classKeyword].empty() ) - { - classCode += " \"\"\"\n"; - if ( !classCommentsGenerated[classKeyword].isEmpty() ) - { - classCode += QString( " %1\n\n" ).arg( classCommentsGenerated[classKeyword] ); - } - - classCode += " Attributes\n"; - classCode += " class_keyword (string): the class keyword that uniquely defines a class\n"; - for ( auto keyWordValuePair : classesGenerated[classKeyword] ) - { - classCode += " " + keyWordValuePair.second.second; - } - classCode += " \"\"\"\n"; - } - classCode += - QString( " __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n" ); - - classCode += QString( " def __init__(self, pb2_object=None, channel=None):\n" ); - classCode += QString( " self.class_keyword = \"%1\"\n" ).arg( scriptClassName ); - if ( !scriptSuperClassNames.empty() ) - { - // Own attributes. This initializes a lot of attributes to None. - // This means it has to be done before we set any values. - for ( auto keyWordValuePair : classesGenerated[classKeyword] ) - { - classCode += keyWordValuePair.second.first; - } - // Parent constructor - classCode += - QString( " %1.__init__(self, pb2_object, channel)\n" ).arg( scriptSuperClassNames.back() ); - } - - classCode += QString( " if %1.__custom_init__ is not None:\n" ).arg( scriptClassName ); - classCode += QString( " %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n" ) - .arg( scriptClassName ); - - out << classCode << "\n"; - classesWritten.insert( scriptClassName ); - } - scriptSuperClassNames.push_back( scriptClassName ); - } - } - out << "def class_dict():\n"; - out << " classes = {}\n"; - for ( QString classKeyword : classesWritten ) - { - out << QString( " classes['%1'] = %1\n" ).arg( classKeyword ); - } - out << " return classes\n\n"; - - out << "def class_from_keyword(class_keyword):\n"; - out << " all_classes = class_dict()\n"; - out << " if class_keyword in all_classes.keys():\n"; - out << " return all_classes[class_keyword]\n"; - out << " return None\n"; + out << generator->generate( caf::PdmDefaultObjectFactory::instance() ); + return true; } diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index bc603033e4..c6393279ed 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -226,7 +226,7 @@ protected: friend class RiaRegressionTestRunner; void resetProject(); - void generatePythonClasses( const QString& outputPath ); + bool generateCode( const QString& outputPath, QString* errMsg ); protected: cvf::ref m_defaultSceneFont; diff --git a/ApplicationCode/Application/RiaConsoleApplication.cpp b/ApplicationCode/Application/RiaConsoleApplication.cpp index 80332d6b52..67ca0f4fe0 100644 --- a/ApplicationCode/Application/RiaConsoleApplication.cpp +++ b/ApplicationCode/Application/RiaConsoleApplication.cpp @@ -137,7 +137,12 @@ RiaApplication::ApplicationStatus RiaConsoleApplication::handleArguments( cvf::P CVF_ASSERT( o.valueCount() == 1 ); QString outputFile = cvfqt::Utils::toQString( o.value( 0 ) ); - RiaApplication::generatePythonClasses( outputFile ); + QString errMsg; + if ( !RiaApplication::generateCode( outputFile, &errMsg ) ) + { + RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) ); + return RiaApplication::EXIT_WITH_ERROR; + } return RiaApplication::EXIT_COMPLETED; } diff --git a/ApplicationCode/Application/RiaGuiApplication.cpp b/ApplicationCode/Application/RiaGuiApplication.cpp index 16a6f34d1e..1449eb509e 100644 --- a/ApplicationCode/Application/RiaGuiApplication.cpp +++ b/ApplicationCode/Application/RiaGuiApplication.cpp @@ -457,7 +457,12 @@ RiaApplication::ApplicationStatus RiaGuiApplication::handleArguments( cvf::Progr CVF_ASSERT( o.valueCount() == 1 ); QString outputFile = cvfqt::Utils::toQString( o.value( 0 ) ); - RiaApplication::generatePythonClasses( outputFile ); + QString errMsg; + if ( !RiaApplication::generateCode( outputFile, &errMsg ) ) + { + RiaLogging::error( QString( "Error: %1" ).arg( errMsg ) ); + return RiaApplication::EXIT_WITH_ERROR; + } return RiaApplication::EXIT_COMPLETED; } diff --git a/ApplicationCode/Application/Tools/RiaArgumentParser.cpp b/ApplicationCode/Application/Tools/RiaArgumentParser.cpp index 3883eff3fe..ab3f17e936 100644 --- a/ApplicationCode/Application/Tools/RiaArgumentParser.cpp +++ b/ApplicationCode/Application/Tools/RiaArgumentParser.cpp @@ -31,13 +31,13 @@ #include "RiuPlotMainWindow.h" #include "RicfCommandFileExecutor.h" -#include "RicfMessages.h" #include "ExportCommands/RicSnapshotAllPlotsToFileFeature.h" #include "ExportCommands/RicSnapshotAllViewsToFileFeature.h" #include "ExportCommands/RicSnapshotViewToFileFeature.h" #include "RicImportSummaryCasesFeature.h" +#include "cafPdmScriptIOMessages.h" #include "cvfProgramOptions.h" #include "cvfqtUtils.h" diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp index 72cde20999..261a997519 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp @@ -55,17 +55,3 @@ QString RiaTextStringTools::trimAndRemoveDoubleSpaces( const QString& s ) return trimmed; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RiaTextStringTools::camelToSnakeCase( const QString& camelString ) -{ - static QRegularExpression re1( "(.)([A-Z][a-z]+)" ); - static QRegularExpression re2( "([a-z0-9])([A-Z])" ); - - QString snake_case = camelString; - snake_case.replace( re1, "\\1_\\2" ); - snake_case.replace( re2, "\\1_\\2" ); - return snake_case.toLower(); -} diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.h b/ApplicationCode/Application/Tools/RiaTextStringTools.h index bb2a1bbd65..ec85197ed2 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.h +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.h @@ -27,5 +27,4 @@ namespace RiaTextStringTools { bool compare( const QString& expected, const QString& actual ); QString trimAndRemoveDoubleSpaces( const QString& s ); -QString camelToSnakeCase( const QString& camelString ); } // namespace RiaTextStringTools diff --git a/ApplicationCode/CommandFileInterface/Core/CMakeLists_files.cmake b/ApplicationCode/CommandFileInterface/Core/CMakeLists_files.cmake index cbb3dbe6cb..67d97ac1d3 100644 --- a/ApplicationCode/CommandFileInterface/Core/CMakeLists_files.cmake +++ b/ApplicationCode/CommandFileInterface/Core/CMakeLists_files.cmake @@ -6,7 +6,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfFieldCapability.h ${CMAKE_CURRENT_LIST_DIR}/RicfFieldHandle.h ${CMAKE_CURRENT_LIST_DIR}/RicfObjectCapability.h ${CMAKE_CURRENT_LIST_DIR}/RifcCommandFileReader.h -${CMAKE_CURRENT_LIST_DIR}/RicfMessages.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -16,7 +15,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfFieldCapability.cpp ${CMAKE_CURRENT_LIST_DIR}/RicfFieldHandle.cpp ${CMAKE_CURRENT_LIST_DIR}/RicfObjectCapability.cpp ${CMAKE_CURRENT_LIST_DIR}/RifcCommandFileReader.cpp -${CMAKE_CURRENT_LIST_DIR}/RicfMessages.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.cpp b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.cpp index b1bbfa6bf0..4bcf181958 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.cpp @@ -18,7 +18,7 @@ #include "RicfCommandObject.h" -#include "RiaTextStringTools.h" +#include "cafPdmPythonGenerator.h" //-------------------------------------------------------------------------------------------------- /// @@ -34,16 +34,3 @@ RicfCommandObject::RicfCommandObject() RicfCommandObject::~RicfCommandObject() { } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicfCommandObject::pythonHelpString( const QString& existingTooltip, const QString& keyword ) -{ - QString snake_case = RiaTextStringTools::camelToSnakeCase( keyword ); - - QString helpString = QString( "Available through python/rips as the attribute '%1'" ).arg( snake_case ); - - if ( !existingTooltip.isEmpty() ) return existingTooltip + "\n\n" + helpString; - return helpString; -} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h index 575d6793d5..b670dc5343 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h @@ -20,8 +20,11 @@ #include "RicfCommandResponse.h" #include "RicfFieldCapability.h" #include "RicfObjectCapability.h" + #include "cafCmdFeature.h" #include "cafPdmObject.h" +#include "cafPdmObjectScriptabilityRegister.h" +#include "cafPdmPythonGenerator.h" //================================================================================================== // @@ -35,8 +38,6 @@ public: ~RicfCommandObject() override; virtual RicfCommandResponse execute() = 0; - - static QString pythonHelpString( const QString& existingTooltip, const QString& keyword ); }; #define RICF_InitField( field, keyword, default, uiName, iconResourceName, toolTip, whatsThis ) \ @@ -45,7 +46,7 @@ public: default, \ uiName, \ iconResourceName, \ - RicfCommandObject::pythonHelpString( toolTip, keyword ), \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \ whatsThis ); \ AddRicfCapabilityToField( field, keyword ) @@ -54,7 +55,7 @@ public: keyword, \ uiName, \ iconResourceName, \ - RicfCommandObject::pythonHelpString( toolTip, keyword ), \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \ whatsThis ); \ AddRicfCapabilityToField( field, keyword ) @@ -64,7 +65,7 @@ public: default, \ uiName, \ iconResourceName, \ - RicfCommandObject::pythonHelpString( toolTip, scriptKeyword ), \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \ whatsThis ); \ AddRicfCapabilityToField( field, scriptKeyword ) @@ -73,18 +74,10 @@ public: keyword, \ uiName, \ iconResourceName, \ - RicfCommandObject::pythonHelpString( toolTip, scriptKeyword ), \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \ whatsThis ); \ AddRicfCapabilityToField( field, scriptKeyword ) -#define RICF_InitObject( uiName, iconResourceName, toolTip, whatsThis ) \ - CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \ - RicfObjectCapability::addCapabilityToObject( this, classKeyword(), whatsThis ); - -#define RICF_InitObjectWithScriptNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \ - CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \ - RicfObjectCapability::addCapabilityToObject( this, scriptClassName, scriptComment ); - #define RICF_HEADER_INIT \ CAF_CMD_HEADER_INIT; \ CAF_PDM_HEADER_INIT diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp index d78cf8928a..991796333b 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RicfFieldCapability.h" -#include "RicfMessages.h" #include "RiaColorTools.h" @@ -26,10 +25,10 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldReader::readFieldData( QString& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted ) +void RicfFieldIOHandler::writeToField( QString& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted ) { fieldValue = ""; @@ -99,7 +98,10 @@ void RicfFieldReader::readFieldData( QString& fieldValue, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldWriter::writeFieldData( const QString& fieldValue, QTextStream& outputStream, bool quoteStrings ) +void RicfFieldIOHandler::readFromField( const QString& fieldValue, + QTextStream& outputStream, + bool quoteStrings, + bool quoteNonBuiltin ) { outputStream << "\""; for ( int i = 0; i < fieldValue.size(); ++i ) @@ -116,10 +118,10 @@ void RicfFieldWriter::writeFieldData( const QString& fieldValue, QTextS //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldReader::readFieldData( bool& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted ) +void RicfFieldIOHandler::writeToField( bool& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted ) { errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream ); QString accumulatedFieldValue; @@ -155,7 +157,10 @@ void RicfFieldReader::readFieldData( bool& fieldValue, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldWriter::writeFieldData( const bool& fieldValue, QTextStream& outputStream, bool quoteStrings ) +void RicfFieldIOHandler::readFromField( const bool& fieldValue, + QTextStream& outputStream, + bool quoteStrings, + bool quoteNonBuiltin ) { // Lower-case true/false is used in the documentation. outputStream << ( fieldValue ? "true" : "false" ); @@ -164,13 +169,13 @@ void RicfFieldWriter::writeFieldData( const bool& fieldValue, QTextStream& //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldReader::readFieldData( cvf::Color3f& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted ) +void RicfFieldIOHandler::writeToField( cvf::Color3f& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted ) { QString fieldStringValue; - RicfFieldReader::readFieldData( fieldStringValue, inputStream, errorMessageContainer, stringsAreQuoted ); + RicfFieldIOHandler::writeToField( fieldStringValue, inputStream, errorMessageContainer, stringsAreQuoted ); QColor qColor( fieldStringValue ); if ( qColor.isValid() ) @@ -182,9 +187,12 @@ void RicfFieldReader::readFieldData( cvf::Color3f& fieldValue, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfFieldWriter::writeFieldData( const cvf::Color3f& fieldValue, QTextStream& outputStream, bool quoteStrings ) +void RicfFieldIOHandler::readFromField( const cvf::Color3f& fieldValue, + QTextStream& outputStream, + bool quoteStrings, + bool quoteNonBuiltin ) { QColor qColor = RiaColorTools::toQColor( fieldValue ); QString fieldStringValue = qColor.name(); - RicfFieldWriter::writeFieldData( fieldStringValue, outputStream, quoteStrings ); -} \ No newline at end of file + RicfFieldIOHandler::readFromField( fieldStringValue, outputStream, quoteStrings ); +} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h index 6a88d97caf..c684466cc3 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h @@ -19,9 +19,9 @@ #pragma once #include "RicfFieldHandle.h" -#include "RicfMessages.h" #include "cafAppEnum.h" +#include "cafPdmScriptIOMessages.h" #include "cvfColor3.h" @@ -29,12 +29,12 @@ #include template -struct RicfFieldReader +struct RicfFieldIOHandler { - static void readFieldData( DataType& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ) + static void writeToField( DataType& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ) { inputStream >> fieldValue; if ( inputStream.status() == QTextStream::ReadCorruptData ) @@ -46,69 +46,62 @@ struct RicfFieldReader inputStream.setStatus( QTextStream::Ok ); } } -}; -template -struct RicfFieldWriter -{ - static void writeFieldData( const DataType& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) + static void readFromField( const DataType& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ) { outputStream << fieldValue; } }; template <> -struct RicfFieldReader +struct RicfFieldIOHandler { - static void readFieldData( QString& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ); + static void writeToField( QString& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ); + static void readFromField( const QString& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ); }; template <> -struct RicfFieldWriter +struct RicfFieldIOHandler { - static void writeFieldData( const QString& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); + static void writeToField( bool& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ); + static void readFromField( const bool& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ); }; template <> -struct RicfFieldReader +struct RicfFieldIOHandler { - static void readFieldData( bool& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ); -}; - -template <> -struct RicfFieldWriter -{ - static void writeFieldData( const bool& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); -}; - -template <> -struct RicfFieldReader -{ - static void readFieldData( cvf::Color3f& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ); -}; - -template <> -struct RicfFieldWriter -{ - static void writeFieldData( const cvf::Color3f& fieldValue, QTextStream& outputStream, bool quoteStrings = true ); + static void writeToField( cvf::Color3f& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ); + static void readFromField( const cvf::Color3f& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ); }; template -struct RicfFieldReader> +struct RicfFieldIOHandler> { - static void readFieldData( caf::AppEnum& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ) + static void writeToField( caf::AppEnum& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ) { errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream ); QString accumulatedFieldValue; @@ -136,24 +129,30 @@ struct RicfFieldReader> errorMessageContainer->currentCommand + "\"" ); } } -}; -template -struct RicfFieldWriter> -{ - static void writeFieldData( const caf::AppEnum& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) + static void readFromField( const caf::AppEnum& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ) { - outputStream << fieldValue; + if ( quoteNonBuiltins ) + { + outputStream << "\"" << fieldValue << "\""; + } + else + { + outputStream << fieldValue; + } } }; template -struct RicfFieldReader> +struct RicfFieldIOHandler> { - static void readFieldData( std::vector& fieldValue, - QTextStream& inputStream, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ) + static void writeToField( std::vector& fieldValue, + QTextStream& inputStream, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ) { errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream ); QChar chr = errorMessageContainer->readCharWithLineNumberCount( inputStream ); @@ -175,7 +174,7 @@ struct RicfFieldReader> } T value; - RicfFieldReader::readFieldData( value, inputStream, errorMessageContainer, true ); + RicfFieldIOHandler::writeToField( value, inputStream, errorMessageContainer, true ); fieldValue.push_back( value ); } } @@ -186,17 +185,16 @@ struct RicfFieldReader> errorMessageContainer->currentCommand + "\"" ); } } -}; -template -struct RicfFieldWriter> -{ - static void writeFieldData( const std::vector& fieldValue, QTextStream& outputStream, bool quoteStrings = true ) + static void readFromField( const std::vector& fieldValue, + QTextStream& outputStream, + bool quoteStrings = true, + bool quoteNonBuiltins = false ) { outputStream << "["; for ( size_t i = 0; i < fieldValue.size(); ++i ) { - RicfFieldWriter::writeFieldData( fieldValue[i], outputStream ); + RicfFieldIOHandler::readFromField( fieldValue[i], outputStream, quoteNonBuiltins ); if ( i < fieldValue.size() - 1 ) { outputStream << ", "; @@ -223,16 +221,16 @@ public: // Xml Serializing public: - void readFieldData( QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ) override + void writeToField( QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true ) override { typename FieldType::FieldDataType value; - RicfFieldReader::readFieldData( value, - inputStream, - errorMessageContainer, - stringsAreQuoted ); + RicfFieldIOHandler::writeToField( value, + inputStream, + errorMessageContainer, + stringsAreQuoted ); if ( this->isIOWriteable() ) { @@ -240,9 +238,12 @@ public: } } - void writeFieldData( QTextStream& outputStream, bool quoteStrings = true ) const override + void readFromField( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const override { - RicfFieldWriter::writeFieldData( m_field->value(), outputStream, quoteStrings ); + RicfFieldIOHandler::readFromField( m_field->value(), + outputStream, + quoteStrings, + quoteNonBuiltins ); } private: diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.cpp b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.cpp index f82dcb8b08..08ed08849a 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.cpp @@ -22,12 +22,9 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fieldName, bool giveOwnership ) +RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership ) + : caf::PdmFieldScriptability( owner, scriptFieldName, giveOwnership ) { - m_IOWriteable = true; - m_owner = owner; - m_fieldName = fieldName; - owner->addCapability( this, giveOwnership ); } //-------------------------------------------------------------------------------------------------- @@ -36,11 +33,3 @@ RicfFieldHandle::RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fie RicfFieldHandle::~RicfFieldHandle() { } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const QString& RicfFieldHandle::fieldName() const -{ - return m_fieldName; -} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h index ff5bb625ea..deecc13e1d 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h @@ -17,7 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "cafPdmFieldCapability.h" +#include "cafPdmFieldScriptability.h" #include @@ -25,10 +25,9 @@ namespace caf { class PdmObjectFactory; class PdmFieldHandle; +class PdmScriptIOMessages; } // namespace caf -class RicfMessages; - class QTextStream; //================================================================================================== @@ -36,24 +35,12 @@ class QTextStream; // // //================================================================================================== -class RicfFieldHandle : public caf::PdmFieldCapability +class RicfFieldHandle : public caf::PdmFieldScriptability { public: - RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& fieldName, bool giveOwnership ); + RicfFieldHandle( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership ); ~RicfFieldHandle() override; - const QString& fieldName() const; - - bool isIOWriteable() const { return m_IOWriteable; } - - void setIOWriteable( bool writeable ) { m_IOWriteable = writeable; } - - virtual void readFieldData( QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory, - RicfMessages* errorMessageContainer, - bool stringsAreQuoted = true ) = 0; - virtual void writeFieldData( QTextStream& outputStream, bool quoteStrings = true ) const = 0; - private: caf::PdmFieldHandle* m_owner; QString m_fieldName; diff --git a/ApplicationCode/CommandFileInterface/Core/RicfMessages.cpp b/ApplicationCode/CommandFileInterface/Core/RicfMessages.cpp deleted file mode 100644 index 6afdffe56a..0000000000 --- a/ApplicationCode/CommandFileInterface/Core/RicfMessages.cpp +++ /dev/null @@ -1,90 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017 Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// -#include "RicfMessages.h" -#include - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfMessages::addWarning( const QString& message ) -{ - m_messages.push_back( - std::make_pair( MESSAGE_WARNING, "Line " + QString::number( m_currentLineNumber ) + ": " + message ) ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfMessages::addError( const QString& message ) -{ - m_messages.push_back( - std::make_pair( MESSAGE_ERROR, "Line " + QString::number( m_currentLineNumber ) + ": " + message ) ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfMessages::skipWhiteSpaceWithLineNumberCount( QTextStream& inputStream ) -{ - while ( !inputStream.atEnd() ) - { - QChar ch = readCharWithLineNumberCount( inputStream ); - if ( !ch.isSpace() ) - { - inputStream.seek( inputStream.pos() - 1 ); - break; - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QChar RicfMessages::readCharWithLineNumberCount( QTextStream& inputStream ) -{ - QChar ch; - inputStream >> ch; - if ( ch == QChar( '\n' ) ) - { - m_currentLineNumber++; - } - return ch; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QChar RicfMessages::peekNextChar( QTextStream& inputStream ) -{ - QChar ch; - if ( !inputStream.atEnd() ) - { - inputStream >> ch; - inputStream.seek( inputStream.pos() - 1 ); - } - return ch; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfMessages::skipLineWithLineNumberCount( QTextStream& inputStream ) -{ - inputStream.readLine(); - m_currentLineNumber++; -} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfMessages.h b/ApplicationCode/CommandFileInterface/Core/RicfMessages.h deleted file mode 100644 index d8cec21173..0000000000 --- a/ApplicationCode/CommandFileInterface/Core/RicfMessages.h +++ /dev/null @@ -1,54 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017 Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// -#pragma once - -#include -#include - -class QTextStream; - -class RicfMessages -{ -public: - RicfMessages() - : m_currentLineNumber( 1 ) - { - } - - enum MessageType - { - MESSAGE_WARNING, - MESSAGE_ERROR - }; - - void addWarning( const QString& message ); - void addError( const QString& message ); - - void skipWhiteSpaceWithLineNumberCount( QTextStream& inputStream ); - void skipLineWithLineNumberCount( QTextStream& inputStream ); - - QChar readCharWithLineNumberCount( QTextStream& inputStream ); - QChar peekNextChar( QTextStream& inputStream ); - - QString currentCommand; - QString currentArgument; - std::vector> m_messages; - -private: - int m_currentLineNumber; -}; diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp index 3d1a7a9e2d..205fae53c5 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp @@ -18,18 +18,14 @@ #include "RicfObjectCapability.h" #include "RicfFieldHandle.h" -#include "RicfMessages.h" #include "cafPdmObject.h" #include "cafPdmObjectHandle.h" +#include "cafPdmScriptIOMessages.h" #include "cafPdmXmlFieldHandle.h" #include -std::map RicfObjectCapability::s_classKeywordToScriptClassName; -std::map RicfObjectCapability::s_scriptClassNameToClassKeyword; -std::map RicfObjectCapability::s_scriptClassComments; - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -49,9 +45,9 @@ RicfObjectCapability::~RicfObjectCapability() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicfObjectCapability::readFields( QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory, - RicfMessages* errorMessageContainer ) +void RicfObjectCapability::readFields( QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer ) { std::set readFields; bool isLastArgumentRead = false; @@ -140,7 +136,7 @@ void RicfObjectCapability::readFields( QTextStream& inputStream, if ( xmlFieldHandle->isIOReadable() ) { errorMessageContainer->currentArgument = keyword; - rcfField->readFieldData( inputStream, objectFactory, errorMessageContainer ); + rcfField->writeToField( inputStream, objectFactory, errorMessageContainer ); errorMessageContainer->currentArgument = keyword; } } @@ -217,82 +213,9 @@ void RicfObjectCapability::writeFields( QTextStream& outputStream ) const } outputStream << keyword << " = "; - rcfField->writeFieldData( outputStream ); + rcfField->readFromField( outputStream ); writtenFieldCount++; } } } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfObjectCapability::registerScriptClassNameAndComment( const QString& classKeyword, - const QString& scriptClassName, - const QString& scriptClassComment ) -{ - s_classKeywordToScriptClassName[classKeyword] = scriptClassName; - s_scriptClassNameToClassKeyword[scriptClassName] = classKeyword; - s_scriptClassComments[classKeyword] = scriptClassComment; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicfObjectCapability::scriptClassNameFromClassKeyword( const QString& classKeyword ) -{ - auto it = s_classKeywordToScriptClassName.find( classKeyword ); - if ( it != s_classKeywordToScriptClassName.end() ) - { - return it->second; - } - return classKeyword; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicfObjectCapability::classKeywordFromScriptClassName( const QString& scriptClassName ) -{ - auto it = s_scriptClassNameToClassKeyword.find( scriptClassName ); - if ( it != s_scriptClassNameToClassKeyword.end() ) - { - return it->second; - } - return scriptClassName; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicfObjectCapability::scriptClassComment( const QString& classKeyword ) -{ - auto it = s_scriptClassComments.find( classKeyword ); - if ( it != s_scriptClassComments.end() ) - { - return it->second; - } - return ""; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RicfObjectCapability::isScriptable( const caf::PdmObject* object ) -{ - return s_classKeywordToScriptClassName.find( object->classKeyword() ) != s_classKeywordToScriptClassName.end(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicfObjectCapability::addCapabilityToObject( caf::PdmObject* object, - const QString& scriptClassName, - const QString& scriptClassComment ) -{ - if ( !object->capability() ) - { - new RicfObjectCapability( object, true ); - } - RicfObjectCapability::registerScriptClassNameAndComment( object->classKeyword(), scriptClassName, scriptClassComment ); -} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h index 271a9159a5..4f6cd5f83d 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h @@ -28,10 +28,10 @@ namespace caf class PdmObject; class PdmObjectHandle; class PdmObjectFactory; +class PdmScriptIOMessages; } // namespace caf class QTextStream; -class RicfMessages; //================================================================================================== // @@ -45,24 +45,11 @@ public: ~RicfObjectCapability() override; - void readFields( QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer ); + void readFields( QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer ); void writeFields( QTextStream& outputStream ) const; - static void registerScriptClassNameAndComment( const QString& classKeyword, - const QString& scriptClassName, - const QString& scriptClassComment ); - static QString scriptClassNameFromClassKeyword( const QString& classKeyword ); - static QString classKeywordFromScriptClassName( const QString& scriptClassName ); - static QString scriptClassComment( const QString& classKeyword ); - - static bool isScriptable( const caf::PdmObject* object ); - static void - addCapabilityToObject( caf::PdmObject* object, const QString& scriptClassName, const QString& scriptClassComment ); - private: caf::PdmObjectHandle* m_owner; - - static std::map s_classKeywordToScriptClassName; - static std::map s_scriptClassNameToClassKeyword; - static std::map s_scriptClassComments; }; diff --git a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp index 543c6296b4..6bda135a7b 100644 --- a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp @@ -19,19 +19,19 @@ #include "RifcCommandFileReader.h" #include "RicfCommandObject.h" -#include "RicfMessages.h" #include "RicfObjectCapability.h" #include "cafPdmObjectFactory.h" +#include "cafPdmScriptIOMessages.h" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RicfCommandFileReader::readCommands( QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory, - RicfMessages* errorMessageContainer ) +std::vector RicfCommandFileReader::readCommands( QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer ) { std::vector readCommands; diff --git a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h index a6fafbc9e0..1025fe4591 100644 --- a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h +++ b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.h @@ -26,9 +26,8 @@ class QTextStream; namespace caf { class PdmObjectFactory; -} - -class RicfMessages; +class PdmScriptIOMessages; +} // namespace caf //================================================================================================== // @@ -38,9 +37,9 @@ class RicfMessages; class RicfCommandFileReader { public: - static std::vector readCommands( QTextStream& inputStream, - caf::PdmObjectFactory* objectFactory, - RicfMessages* errorMessageContainer ); + static std::vector readCommands( QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer ); static void writeCommands( QTextStream& outputStream, const std::vector& commandsToWrite ); }; diff --git a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp index b13b53cbaf..75e76fd987 100644 --- a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp +++ b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp @@ -61,7 +61,7 @@ RicfCommandFileExecutor::~RicfCommandFileExecutor() //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::executeCommands( QTextStream& stream ) { - RicfMessages messages; + caf::PdmScriptIOMessages messages; std::vector executableCommands; { clearCachedData(); @@ -70,7 +70,7 @@ void RicfCommandFileExecutor::executeCommands( QTextStream& stream ) RicfCommandFileReader::readCommands( stream, caf::PdmDefaultObjectFactory::instance(), &messages ); for ( auto message : messages.m_messages ) { - if ( message.first == RicfMessages::MESSAGE_WARNING ) + if ( message.first == caf::PdmScriptIOMessages::MESSAGE_WARNING ) { RiaLogging::warning( QString( "Command file parsing warning: %1" ).arg( message.second ) ); } diff --git a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h index 17a5cbc3bd..f99e5c71cf 100644 --- a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h +++ b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h @@ -18,9 +18,8 @@ #pragma once -#include "RicfMessages.h" - #include "cafAppEnum.h" +#include "cafPdmScriptIOMessages.h" #include #include diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteSubPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicDeleteSubPlotFeature.cpp index 8b0218433b..c14cf0f71a 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeleteSubPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteSubPlotFeature.cpp @@ -27,6 +27,7 @@ #include "RimMultiPlot.h" #include "RimPlotWindow.h" +#include "RimWellLogPlot.h" #include "RimWellLogTrack.h" #include "cafSelectionManager.h" @@ -50,9 +51,11 @@ bool RicDeleteSubPlotFeature::isCommandEnabled() size_t plotsSelected = 0; for ( caf::PdmObject* object : selection ) { - RimMultiPlot* multiPlot = nullptr; + RimMultiPlot* multiPlot = nullptr; + RimWellLogPlot* wellLogPlot = nullptr; object->firstAncestorOrThisOfType( multiPlot ); - if ( dynamic_cast( object ) && multiPlot ) + object->firstAncestorOrThisOfType( wellLogPlot ); + if ( dynamic_cast( object ) && ( multiPlot || wellLogPlot ) ) { plotsSelected++; } @@ -72,26 +75,34 @@ void RicDeleteSubPlotFeature::onActionTriggered( bool isChecked ) std::vector selection; caf::SelectionManager::instance()->objectsByType( &selection ); - std::set alteredPlotWindows; + std::set alteredPlotWindows; for ( RimPlot* plot : selection ) { - RimMultiPlot* plotWindow = nullptr; - plot->firstAncestorOrThisOfType( plotWindow ); - if ( plot && plotWindow ) + if ( !plot ) continue; + + RimMultiPlot* multiPlot = nullptr; + RimWellLogPlot* wellLogPlot = nullptr; + plot->firstAncestorOrThisOfType( multiPlot ); + plot->firstAncestorOrThisOfType( wellLogPlot ); + if ( multiPlot ) { - alteredPlotWindows.insert( plotWindow ); - plotWindow->removePlot( plot ); + alteredPlotWindows.insert( multiPlot ); + multiPlot->removePlot( plot ); caf::SelectionManager::instance()->removeObjectFromAllSelections( plot ); - plotWindow->updateConnectedEditors(); + multiPlot->updateConnectedEditors(); delete plot; } - } + else if ( wellLogPlot ) + { + alteredPlotWindows.insert( wellLogPlot ); + wellLogPlot->removePlot( plot ); + caf::SelectionManager::instance()->removeObjectFromAllSelections( plot ); - for ( RimMultiPlot* plotWindow : alteredPlotWindows ) - { - plotWindow->uiCapability()->updateConnectedEditors(); + wellLogPlot->updateConnectedEditors(); + delete plot; + } } } diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp index 7c613988d5..e0a53abf2d 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp @@ -78,6 +78,7 @@ RimWellBoreStabilityPlot* RimWellBoreStabilityPlot* plot = RicNewWellLogPlotFeatureImpl::createWellBoreStabilityPlot( false, "Well Bore Stability", parameters ); + plot->setCaseWellPathAndTimeStep( geoMechCase, wellPath, timeStep ); { auto task = progInfo.task( "Creating formation track", 2 ); diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 41450a5658..9b06a825e0 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -385,8 +385,8 @@ bool RifEclipseInputFileTools::exportGrid( const QString& fileName, } // Do not perform the transformation (applyMapaxes == false): - // The coordinates have been transformed to the mapaxes coordinate system already. - // However, send the mapaxes data in to libecl so that the coordinate system description is saved. + // The coordinates have been transformed to the map axes coordinate system already. + // However, send the map axes data in to libecl so that the coordinate system description is saved. bool applyMapaxes = false; ecl_grid_type* mainEclGrid = ecl_grid_alloc_GRID_data( (int)ecl_coords.size(), ecl_nx, @@ -473,6 +473,12 @@ bool RifEclipseInputFileTools::exportKeywords( const QString& resul CVF_ASSERT( !resultValues.empty() ); if ( resultValues.empty() ) continue; + double defaultExportValue = 0.0; + if ( keyword.endsWith( "NUM" ) ) + { + defaultExportValue = 1.0; + } + std::vector filteredResults; filteredResults.reserve( resultValues.size() ); @@ -493,6 +499,10 @@ bool RifEclipseInputFileTools::exportKeywords( const QString& resul { filteredResults.push_back( resultValues[resIndex] ); } + else + { + filteredResults.push_back( defaultExportValue ); + } } } } diff --git a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp index dbc73fdf1c..7637b0d8f6 100644 --- a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp +++ b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp @@ -83,6 +83,7 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress( SummaryVarCategory case SUMMARY_WELL_SEGMENT: m_wellName = identifiers[INPUT_WELL_NAME]; m_wellSegmentNumber = RiaStdStringTools::toInt( identifiers[INPUT_SEGMENT_NUMBER] ); + break; case SUMMARY_BLOCK: ijkTuple = ijkTupleFromUiText( identifiers[INPUT_CELL_IJK] ); m_cellI = std::get<0>( ijkTuple ); diff --git a/ApplicationCode/GrpcInterface/CMakeLists.cmake b/ApplicationCode/GrpcInterface/CMakeLists.cmake index 0e4e01eb08..1102b554e8 100644 --- a/ApplicationCode/GrpcInterface/CMakeLists.cmake +++ b/ApplicationCode/GrpcInterface/CMakeLists.cmake @@ -182,15 +182,13 @@ if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE) "rips/contour_map.py" "rips/grid.py" "rips/gridcasegroup.py" - "rips/project.py" "rips/instance.py" "rips/pdmobject.py" "rips/plot.py" + "rips/project.py" "rips/simulation_well.py" "rips/view.py" - "rips/wellpath.py" "rips/well_log_plot.py" - "rips/well_bore_stability_plot.py" "rips/PythonExamples/instance_example.py" "rips/PythonExamples/command_example.py" "rips/PythonExamples/case_grid_group.py" diff --git a/ApplicationCode/GrpcInterface/GrpcProtos/PdmObject.proto b/ApplicationCode/GrpcInterface/GrpcProtos/PdmObject.proto index 601a2fc45b..e5ecf1976d 100644 --- a/ApplicationCode/GrpcInterface/GrpcProtos/PdmObject.proto +++ b/ApplicationCode/GrpcInterface/GrpcProtos/PdmObject.proto @@ -11,6 +11,8 @@ service PdmObjectService rpc GetAncestorPdmObject(PdmParentObjectRequest) returns (PdmObject) {} rpc CreateChildPdmObject(CreatePdmChildObjectRequest) returns (PdmObject) {} rpc UpdateExistingPdmObject(PdmObject) returns (Empty) {} + rpc CallPdmObjectGetMethod(PdmObjectMethodRequest) returns (stream PdmObjectGetMethodReply) {} + rpc CallPdmObjectSetMethod(stream PdmObjectSetMethodChunk) returns (ClientToServerStreamReply) {} } message PdmDescendantObjectRequest @@ -48,4 +50,53 @@ message PdmObject message PdmObjectArray { repeated PdmObject objects = 1; +} + +message PdmObjectMethodRequest +{ + PdmObject object = 1; + string method = 2; +} + +message PdmObjectSetMethodRequest +{ + PdmObjectMethodRequest request = 1; + int32 data_count = 2; +} + +message PdmObjectSetMethodChunk +{ + oneof data + { + PdmObjectSetMethodRequest set_request = 1; + DoubleArray doubles = 2; + IntArray ints = 3; + StringArray strings = 4; + } +} + + +message DoubleArray +{ + repeated double data = 1; +} + +message IntArray +{ + repeated int32 data = 1; +} + +message StringArray +{ + repeated string data = 1; +} + +message PdmObjectGetMethodReply +{ + oneof data + { + DoubleArray doubles = 1; + IntArray ints = 2; + StringArray strings = 3; + } } \ No newline at end of file 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 new file mode 100644 index 0000000000..e65c5adad4 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/alter_wbs_plot.py @@ -0,0 +1,28 @@ +# Load ResInsight Processing Server Client Library +import rips + +# Connect to ResInsight instance +resinsight = rips.Instance.find() + +# Get the project +project = resinsight.project + +# Find all the well bore stability plots in the project +wbsplots = project.descendants(rips.WellBoreStabilityPlot) + +# Chose a sensible output folder +dirname = "C:/temp" + +# Loop through all Well Bore Stability plots +for wbsplot in wbsplots: + # Set depth type a parameter and export snapshot + wbsplot.depth_type = "TRUE_VERTICAL_DEPTH_RKB" + + # Example of setting parameters for existing plots + params = wbsplot.parameters() + params.user_poisson_ratio = 0.12345 + params.update() + wbsplot.update() + wbsplot.export_snapshot(export_folder=dirname) + + diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/cell_result_data.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/cell_result_data.py new file mode 100644 index 0000000000..b420f6f915 --- /dev/null +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/cell_result_data.py @@ -0,0 +1,17 @@ +###################################################################### +# This script retrieves cell result data and alters it +###################################################################### +import rips + +resinsight = rips.Instance.find() + +view = resinsight.project.views()[0] +results = view.cell_result_data() +print ("Number of result values: ", len(results)) + +newresults = [] +for i in range(0, len(results)): + newresults.append(results[i] * -1.0) +view.set_cell_result_data(newresults) + + \ No newline at end of file diff --git a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/create_wbs_plot.py b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/create_wbs_plot.py index a430292de4..f69bb992a4 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/create_wbs_plot.py +++ b/ApplicationCode/GrpcInterface/Python/rips/PythonExamples/create_wbs_plot.py @@ -6,60 +6,38 @@ import rips # Connect to ResInsight instance resInsight = rips.Instance.find() -cases = resInsight.project.cases() - -well_paths = resInsight.project.import_well_paths(well_path_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_WellPaths') -well_log_files = resInsight.project.import_well_log_files(well_log_folder='D:/Projects/ResInsight-regression-test/ModelData/Norne_PLT_LAS') +# Get all GeoMech cases +cases = resInsight.project.descendants(rips.GeoMechCase) +# Get all well paths well_paths = resInsight.project.well_paths() +# Ensure there's at least one well path if len(well_paths) < 1: print("No well paths in project") exit(1) -well_paths = well_paths[0:4] - -print(well_paths) - -# Example of creating parameters for new plots -wbs_parameters = rips.WbsParameters() -wbs_parameters.user_poisson_ratio = 0.412347 -wbs_parameters.pore_pressure_outside_reservoir_source = "USER_DEFINED" -wbs_parameters.user_pp_outside_reservoir = 1.1 -wbs_parameters.fg_shale_source = "PROPORTIONAL_TO_SH" -wbs_parameters.user_fg_shale = 1.13 +# Create a set of WbsParameters +params = rips.WbsParameters() +params.user_poisson_ratio = 0.23456 +params.user_ucs = 123 +# Loop through all cases for case in cases: - if case.type == "GeoMechCase": - min_res_depth, max_res_depth = case.reservoir_depth_range() - - print (case.id) - case_path = case.file_path - folder_name = os.path.dirname(case_path) - case.import_formation_names(formation_files=['D:/Projects/ResInsight-regression-test/ModelData/norne/Norne_ATW2013.lyr']) + assert(isinstance(case, rips.GeoMechCase)) + min_res_depth, max_res_depth = case.reservoir_depth_range() - # create a folder to hold the snapshots - dirname = os.path.join(folder_name, 'snapshots') - print("Exporting to: " + dirname) + # Find a good output path + case_path = case.file_path + folder_name = os.path.dirname(case_path) - for well_path in well_paths: - try: - # Create plot with parameters - wbsplot = case.create_well_bore_stability_plot(well_path=well_path.name, time_step=0, wbs_parameters=wbs_parameters) - # Example of setting parameters for existing plots - replace_params = wbsplot.parameters() - replace_params.user_poisson_ratio = 0.654321 - replace_params.user_fg_shale = 1.0321 - wbsplot.set_parameters(replace_params) - # Demonstrate altering general well log plot settings - min_depth = max(wbsplot.minimum_depth, min_res_depth) - max_depth = min(wbsplot.maximum_depth, max_res_depth) - wbsplot.minimum_depth = min_depth - wbsplot.maximum_depth = max_depth - wbsplot.update() - #wbsplot.depth_type = "TRUE_VERTICAL_DEPTH_RKB" - - wbsplot.export_snapshot(export_folder=dirname) + # Import formation names + case.import_formation_names(formation_files=['D:/Projects/ResInsight-regression-test/ModelData/norne/Norne_ATW2013.lyr']) - except grpc.RpcError as e: - print("Error: ", e.details()) + # create a folder to hold the snapshots + dirname = os.path.join(folder_name, 'snapshots') + print("Exporting to: " + dirname) + + for well_path in well_paths[0:4]: # Loop through the first five well paths + # Create plot with parameters + wbsplot = case.create_well_bore_stability_plot(well_path=well_path.name, time_step=0, parameters=params) \ No newline at end of file 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/__init__.py b/ApplicationCode/GrpcInterface/Python/rips/__init__.py index 1dd1075892..a861e636e1 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/__init__.py +++ b/ApplicationCode/GrpcInterface/Python/rips/__init__.py @@ -13,6 +13,6 @@ from rips.project import Project from rips.plot import Plot, PlotWindow from rips.contour_map import EclipseContourMap, GeoMechContourMap from rips.well_log_plot import WellLogPlot -from rips.well_bore_stability_plot import WellBoreStabilityPlot, WbsParameters from rips.simulation_well import SimulationWell -from rips.wellpath import WellPathBase \ No newline at end of file + +from rips.generated.pdm_objects import * diff --git a/ApplicationCode/GrpcInterface/Python/rips/case.py b/ApplicationCode/GrpcInterface/Python/rips/case.py index 69e1ca6f98..669ebe0e98 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/case.py +++ b/ApplicationCode/GrpcInterface/Python/rips/case.py @@ -26,7 +26,7 @@ import rips.project from rips.grid import Grid from rips.pdmobject import add_method, PdmObject from rips.view import View -from rips.well_bore_stability_plot import WellBoreStabilityPlot, WbsParameters +from rips.generated.pdm_objects import WellBoreStabilityPlot, WbsParameters from rips.simulation_well import SimulationWell """ResInsight case class @@ -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 @@ -826,7 +821,7 @@ def export_property( )) @add_method(Case) -def create_well_bore_stability_plot(self, well_path, time_step, wbs_parameters=None): +def create_well_bore_stability_plot(self, well_path, time_step, parameters=None): """ Create a new well bore stability plot Arguments: @@ -837,9 +832,9 @@ def create_well_bore_stability_plot(self, well_path, time_step, wbs_parameters=N A new plot object """ pb2_parameters = None - if wbs_parameters is not None: - assert(isinstance(wbs_parameters, WbsParameters)) - pb2_parameters = wbs_parameters.pb2_object() + if parameters is not None: + assert(isinstance(parameters, WbsParameters)) + pb2_parameters = parameters.pb2_object() plot_result = self._execute_command(createWellBoreStabilityPlot=Cmd.CreateWbsPlotRequest(caseId=self.id, wellPath=well_path, @@ -847,8 +842,7 @@ def create_well_bore_stability_plot(self, well_path, time_step, wbs_parameters=N wbsParameters=pb2_parameters)) project = self.ancestor(rips.project.Project) plot = project.plot(view_id=plot_result.createWbsPlotResult.viewId) - assert(plot) - return plot.cast(WellBoreStabilityPlot) + return plot @add_method(Case) def import_formation_names(self, formation_files=None): diff --git a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py index 803e52b6d0..f89eb31fc7 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py +++ b/ApplicationCode/GrpcInterface/Python/rips/pdmobject.py @@ -21,6 +21,9 @@ def camel_to_snake(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() +def snake_to_camel(name): + return ''.join(word.title() for word in name.split('_')) + def add_method(cls): def decorator(func): setattr(cls, func.__name__, func) @@ -51,24 +54,26 @@ def _execute_command(self, **command_params): @add_method(PdmObject) def __custom_init__(self, pb2_object, channel): self.__warnings = [] - self.__keyword_translation = {} + self.__chunk_size = 8160 + + self._channel = channel + + # Create stubs + if self._channel: + self._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self._channel) + self._commands = CmdRpc.CommandsStub(self._channel) if pb2_object is not None: - self._pb2_object = pb2_object - else: - self._pb2_object = PdmObject_pb2.PdmObject(class_keyword=self.__class__.__name__) - self.class_keyword = self._pb2_object.class_keyword - self._channel = channel - - if self.pb2_object() is not None and self.channel() is not None: - if self.channel() is not None: - self._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel()) - self._commands = CmdRpc.CommandsStub(self.channel()) - + # Copy parameters from ResInsight + assert(not isinstance(pb2_object, PdmObject)) + self._pb2_object = pb2_object for camel_keyword in self._pb2_object.parameters: snake_keyword = camel_to_snake(camel_keyword) setattr(self, snake_keyword, self.__get_grpc_value(camel_keyword)) - self.__keyword_translation[snake_keyword] = camel_keyword + else: + # Copy parameters from PdmObject defaults + self._pb2_object = PdmObject_pb2.PdmObject(class_keyword=self.__class__.__name__) + self.__copy_to_pb2() @add_method(PdmObject) def copy_from(self, object): @@ -82,16 +87,27 @@ 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): return self.__warnings -@add_method(PdmObject) - +@add_method(PdmObject) def has_warnings(self): return len(self.__warnings) > 0 +@add_method(PdmObject) +def __copy_to_pb2(self): + if self._pb2_object is not None: + for snake_kw in dir(self): + if not snake_kw.startswith('_'): + value = getattr(self, snake_kw) + # This is crucial to avoid overwriting methods + if not callable(value): + camel_kw = snake_to_camel(snake_kw) + self.__set_grpc_value(camel_kw, value) + @add_method(PdmObject) def pb2_object(self): """ Private method""" @@ -125,15 +141,17 @@ def visible(self): @add_method(PdmObject) def print_object_info(self): """Print the structure and data content of the PdmObject""" - print("=========== " + self.class_keyword + " =================") + print("=========== " + self.__class__.__name__ + " =================") print("Object Attributes: ") - for snake_kw, camel_kw in self.__keyword_translation.items(): - print(" " + snake_kw + " [" + type(getattr(self, snake_kw)).__name__ + - "]: " + str(getattr(self, snake_kw))) + for snake_kw in dir(self): + if not snake_kw.startswith("_") and not callable(getattr(self, snake_kw)): + camel_kw = snake_to_camel(snake_kw) + print(" " + snake_kw + " [" + type(getattr(self, snake_kw)).__name__ + + "]: " + str(getattr(self, snake_kw))) print("Object Methods:") - for method in dir(self): - if not method.startswith("_") and callable(getattr(self, method)): - print (" " + method) + for snake_kw in dir(self): + if not snake_kw.startswith("_") and callable(getattr(self, snake_kw)): + print (" " + snake_kw) @add_method(PdmObject) def __convert_from_grpc_value(self, value): @@ -246,7 +264,7 @@ def children(self, child_field, class_definition=PdmObject): A list of PdmObjects inside the child_field """ request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object, - child_field=child_field) + child_field=child_field) try: object_list = self._pdm_object_stub.GetChildPdmObjects(request).objects return self.__from_pb2_to_pdm_objects(object_list, class_definition) @@ -281,13 +299,66 @@ def ancestor(self, class_definition): return None raise e +@add_method(PdmObject) +def _call_get_method_async(self, method_name): + request = PdmObject_pb2.PdmObjectMethodRequest(object=self._pb2_object, method=method_name) + for chunk in self._pdm_object_stub.CallPdmObjectGetMethod(request): + yield chunk + +@add_method(PdmObject) +def _call_get_method(self, method_name): + all_values = [] + generator = self._call_get_method_async(method_name) + for chunk in generator: + data = getattr(chunk, chunk.WhichOneof('data')) + for value in data.data: + all_values.append(value) + return all_values + +@add_method(PdmObject) +def __generate_set_method_chunks(self, array, method_request): + index = -1 + + while index < len(array): + chunk = PdmObject_pb2.PdmObjectSetMethodChunk() + if index is -1: + chunk.set_request.CopyFrom(PdmObject_pb2.PdmObjectSetMethodRequest(request=method_request, data_count=len(array))) + index += 1 + else: + actual_chunk_size = min(len(array) - index + 1, self.__chunk_size) + if isinstance(array[0], float): + chunk.CopyFrom( + PdmObject_pb2.PdmObjectSetMethodChunk(doubles=PdmObject_pb2.DoubleArray(data=array[index:index + + actual_chunk_size]))) + elif isinstance(array[0], int): + chunk.CopyFrom( + PdmObject_pb2.PdmObjectSetMethodChunk(ints=PdmObject_pb2.IntArray(data=array[index:index + + actual_chunk_size]))) + elif isinstance(array[0], str): + chunk.CopyFrom( + PdmObject_pb2.PdmObjectSetMethodChunk(strings=PdmObject_pb2.StringArray(data=array[index:index + + actual_chunk_size]))) + else: + raise Exception("Wrong data type for set method") + index += actual_chunk_size + yield chunk + # Final empty message to signal completion + chunk = PdmObject_pb2.PdmObjectSetMethodChunk() + yield chunk + +@add_method(PdmObject) +def _call_set_method(self, method_name, values): + method_request = PdmObject_pb2.PdmObjectMethodRequest(object=self._pb2_object, method=method_name) + request_iterator = self.__generate_set_method_chunks(values, method_request) + reply = self._pdm_object_stub.CallPdmObjectSetMethod(request_iterator) + if reply.accepted_value_count < len(values): + raise IndexError + @add_method(PdmObject) def update(self): """Sync all fields from the Python Object to ResInsight""" - if self._pdm_object_stub is not None and self._pb2_object is not None: - for snake_kw, camel_kw in self.__keyword_translation.items(): - self.__set_grpc_value(camel_kw, getattr(self, snake_kw)) - + self.__copy_to_pb2() + if self._pdm_object_stub is not None: self._pdm_object_stub.UpdateExistingPdmObject(self._pb2_object) else: raise Exception("Object is not connected to GRPC service so cannot update ResInsight") diff --git a/ApplicationCode/GrpcInterface/Python/rips/project.py b/ApplicationCode/GrpcInterface/Python/rips/project.py index 583a92d3cd..305d87f0ca 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/project.py +++ b/ApplicationCode/GrpcInterface/Python/rips/project.py @@ -11,14 +11,13 @@ from rips.gridcasegroup import GridCaseGroup from rips.pdmobject import PdmObject, add_method, add_static_method from rips.plot import Plot from rips.view import View -from rips.wellpath import WellPathBase import rips.generated.Commands_pb2 as Cmd from rips.generated.Definitions_pb2 import Empty import rips.generated.Project_pb2_grpc as Project_pb2_grpc import rips.generated.Project_pb2 as Project_pb2 import rips.generated.PdmObject_pb2 as PdmObject_pb2 -from rips.generated.pdm_objects import Project, PlotWindow +from rips.generated.pdm_objects import Project, PlotWindow, WellPath @add_method(Project) @@ -277,7 +276,7 @@ def import_well_paths(self, well_path_files=None, well_path_folder=''): well_path_folder(str): A folder path containing files to import Returns: - A list of WellPathBase objects + A list of WellPath objects """ if well_path_files is None: well_path_files = [] @@ -294,16 +293,16 @@ def well_paths(self): """Get a list of all well paths in the project Returns: - A list of rips WellPathBase objects + A list of rips WellPath objects """ - return self.descendants(WellPathBase) + return self.descendants(WellPath) @add_method(Project) def well_path_by_name(self, well_path_name): """Get a specific well path by name from the project Returns: - A WellPathBase object + A WellPath object """ all_well_paths = self.well_paths() for well_path in all_well_paths: diff --git a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py index 27fc32d366..79b2572257 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py +++ b/ApplicationCode/GrpcInterface/Python/rips/tests/test_cases.py @@ -122,7 +122,7 @@ def test_PdmObject(rips_instance, initialize_test): case = rips_instance.project.load_case(path=case_path) assert(case.id == 0) assert(case.address() is not 0) - assert(case.class_keyword == "EclipseCase") + assert(case.__class__.__name__ == "EclipseCase") @pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux") def test_brugge_0010(rips_instance, initialize_test): diff --git a/ApplicationCode/GrpcInterface/Python/rips/view.py b/ApplicationCode/GrpcInterface/Python/rips/view.py index 4e1669402c..fd5418e8c3 100644 --- a/ApplicationCode/GrpcInterface/Python/rips/view.py +++ b/ApplicationCode/GrpcInterface/Python/rips/view.py @@ -9,19 +9,6 @@ import rips.case # Circular import of Case, which already imports View. Use ful from rips.pdmobject import add_method from rips.generated.pdm_objects import View, ViewWindow, EclipseView, GeoMechView -@add_method(View) -def is_eclipse_view(self): - return isinstance(self, EclipseView) - -@add_method(View) -def is_geomech_view(self): - return isinstance(self, GeoMechView) - -@add_method(View) -def cell_result(self): - """Retrieve the current cell results""" - return self.children("GridCellResult")[0] - @add_method(View) def apply_cell_result(self, result_type, result_variable): """Apply a regular cell result diff --git a/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py b/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py deleted file mode 100644 index 62651dffbc..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/well_bore_stability_plot.py +++ /dev/null @@ -1,45 +0,0 @@ -""" -ResInsight Well Bore Stability Plot module -""" - -from rips.pdmobject import PdmObject, add_method -from rips.well_log_plot import WellLogPlot -from rips.generated.pdm_objects import WellBoreStabilityPlot, WbsParameters - -@add_method(WbsParameters) -def __custom_init__(self, pb2_object=None, channel=None): - self.pore_pressure_reservoir_source = "UNDEFINED" - self.pore_pressure_non_reservoir_source = "UNDEFINED" - - self.poisson_ratio_source = "UNDEFINED" - self.ucs_source = "UNDEFINED" - self.obg0_source = "UNDEFINED" - self.df_source = "UNDEFINED" - self.k0sh_source = "UNDEFINED" - self.fg_shale_source = "UNDEFINED" - self.k0fg_source = "UNDEFINED" - - self.user_pp_non_reservoir = 1.05 - self.user_poission_ratio = 0.35 - self.user_ucs = 100 - self.user_df = 0.7 - self.user_k0sh = 0.65 - self.fg_multiplier = 1.05 - 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) diff --git a/ApplicationCode/GrpcInterface/Python/rips/wellpath.py b/ApplicationCode/GrpcInterface/Python/rips/wellpath.py deleted file mode 100644 index 2c2c9c97ed..0000000000 --- a/ApplicationCode/GrpcInterface/Python/rips/wellpath.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -ResInsight Well -""" -import rips.generated.Commands_pb2 as Cmd -from rips.generated.pdm_objects import WellPathBase - diff --git a/ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl b/ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl index a803752725..b0a708ed0d 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl +++ b/ApplicationCode/GrpcInterface/RiaGrpcCallbacks.inl @@ -348,8 +348,8 @@ void RiaGrpcClientToServerStreamCallbackstreamedValueCount() <= m_stateHandler->cellCount() ); - if ( m_stateHandler->streamedValueCount() == m_stateHandler->cellCount() ) + CAF_ASSERT( m_stateHandler->streamedValueCount() <= m_stateHandler->totalValueCount() ); + if ( m_stateHandler->streamedValueCount() == m_stateHandler->totalValueCount() ) { this->setNextCallState( RiaGrpcCallbackInterface::FINISH_REQUEST ); m_reader.Finish( this->m_reply, grpc::Status::OK, this ); diff --git a/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.cpp b/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.cpp index 3cf17e6b37..6ec22178b4 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.cpp +++ b/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.cpp @@ -337,7 +337,6 @@ grpc::Status RiaNNCInputValuesStateHandler::init( const NNCValuesInputRequest* r { auto caseData = m_eclipseCase->eclipseCaseData(); auto m_porosityModel = static_cast( request->porosity_model() ); - auto resultData = caseData->results( m_porosityModel ); m_timeStep = request->time_step(); m_propertyName = QString::fromStdString( request->property_name() ); @@ -423,7 +422,7 @@ grpc::Status RiaNNCInputValuesStateHandler::receiveStreamRequest( const NNCValue //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RiaNNCInputValuesStateHandler::cellCount() const +size_t RiaNNCInputValuesStateHandler::totalValueCount() const { return m_cellCount; } diff --git a/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.h b/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.h index ebdab76e00..fb76bc601d 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.h +++ b/ApplicationCode/GrpcInterface/RiaGrpcNNCPropertiesService.h @@ -84,7 +84,7 @@ public: grpc::Status init( const rips::NNCValuesInputRequest* request ); grpc::Status receiveStreamRequest( const rips::NNCValuesChunk* request, rips::ClientToServerStreamReply* reply ); - size_t cellCount() const; + size_t totalValueCount() const; size_t streamedValueCount() const; void finish(); diff --git a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp index 941d13e0d0..b103f74679 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp +++ b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.cpp @@ -24,10 +24,311 @@ #include "RimEclipseResultDefinition.h" #include "RimProject.h" +#include "cafPdmFieldScriptability.h" #include "cafPdmObject.h" +#include "cafPdmObjectScriptabilityRegister.h" using namespace rips; +template +struct DataHolder : public AbstractDataHolder +{ + DataHolder( const DataType& data ) + : data( data ) + { + } + + size_t dataCount() const override { return data.size(); } + size_t dataSizeOf() const override { return sizeof( typename DataType::value_type ); } + + void reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const; + void addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const; + size_t getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ); + void applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ); + + DataType data; +}; + +template <> +void DataHolder>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_ints()->mutable_data()->Reserve( data.size() ); +} +template <> +void DataHolder>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_ints()->add_data( data[valueIndex] ); +} +template <> +size_t DataHolder>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ) +{ + size_t chunkSize = chunk->ints().data_size(); + size_t currentIndex = startIndex; + size_t chunkIndex = 0u; + for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex ) + { + data[currentIndex] = chunk->ints().data()[chunkIndex]; + } + return chunkSize; +} +template <> +void DataHolder>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ) +{ + auto proxyValueField = dynamic_cast>*>( proxyField ); + CAF_ASSERT( proxyValueField ); + if ( proxyValueField ) + { + proxyValueField->setValue( data ); + } +} + +template <> +void DataHolder>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_doubles()->mutable_data()->Reserve( data.size() ); +} +template <> +void DataHolder>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_doubles()->add_data( data[valueIndex] ); +} +template <> +size_t DataHolder>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ) +{ + size_t chunkSize = chunk->doubles().data_size(); + size_t currentIndex = startIndex; + size_t chunkIndex = 0u; + for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex ) + { + data[currentIndex] = chunk->doubles().data()[chunkIndex]; + } + return chunkSize; +} +template <> +void DataHolder>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ) +{ + auto proxyValueField = dynamic_cast>*>( proxyField ); + CAF_ASSERT( proxyValueField ); + if ( proxyValueField ) + { + proxyValueField->setValue( data ); + } +} + +template <> +void DataHolder>::reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_strings()->mutable_data()->Reserve( data.size() ); +} +template <> +void DataHolder>::addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const +{ + reply->mutable_strings()->add_data( data[valueIndex].toStdString() ); +} +template <> +size_t DataHolder>::getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ) +{ + size_t chunkSize = chunk->strings().data_size(); + size_t currentIndex = startIndex; + size_t chunkIndex = 0u; + for ( ; chunkIndex < chunkSize && currentIndex < data.size(); ++currentIndex, ++chunkIndex ) + { + data[currentIndex] = QString::fromStdString( chunk->strings().data()[chunkIndex] ); + } + return chunkSize; +} +template <> +void DataHolder>::applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ) +{ + auto proxyValueField = dynamic_cast>*>( proxyField ); + CAF_ASSERT( proxyValueField ); + if ( proxyValueField ) + { + proxyValueField->setValue( data ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaPdmObjectMethodStateHandler::RiaPdmObjectMethodStateHandler( bool clientToServerStreamer ) + : m_fieldOwner( nullptr ) + , m_proxyField( nullptr ) + , m_currentDataIndex( 0u ) + , m_clientToServerStreamer( clientToServerStreamer ) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectMethodRequest* request ) +{ + CAF_ASSERT( !m_clientToServerStreamer ); + m_fieldOwner = RiaGrpcPdmObjectService::findCafObjectFromRipsObject( request->object() ); + QString fieldName = QString::fromStdString( request->method() ); + + std::vector fields; + m_fieldOwner->fields( fields ); + for ( auto field : fields ) + { + auto scriptability = field->capability(); + if ( scriptability && scriptability->scriptFieldName() == fieldName ) + { + caf::PdmProxyFieldHandle* proxyField = dynamic_cast( field ); + if ( proxyField ) + { + m_proxyField = proxyField; + + if ( dynamic_cast>*>( field ) ) + { + auto dataField = dynamic_cast>*>( field ); + m_dataHolder.reset( new DataHolder>( dataField->value() ) ); + return grpc::Status::OK; + } + else if ( dynamic_cast>*>( field ) ) + { + auto dataField = dynamic_cast>*>( field ); + m_dataHolder.reset( new DataHolder>( dataField->value() ) ); + return grpc::Status::OK; + } + else if ( dynamic_cast>*>( field ) ) + { + auto dataField = dynamic_cast>*>( field ); + m_dataHolder.reset( new DataHolder>( dataField->value() ) ); + return grpc::Status::OK; + } + else + { + CAF_ASSERT( false && "The proxy field data type is not yet supported for streaming fields" ); + } + } + } + } + + return grpc::Status( grpc::NOT_FOUND, "Proxy field not found" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Status RiaPdmObjectMethodStateHandler::init( const rips::PdmObjectSetMethodChunk* chunk ) +{ + CAF_ASSERT( m_clientToServerStreamer ); + CAF_ASSERT( chunk->has_set_request() ); + auto setRequest = chunk->set_request(); + auto methodRequest = setRequest.request(); + m_fieldOwner = RiaGrpcPdmObjectService::findCafObjectFromRipsObject( methodRequest.object() ); + QString fieldName = QString::fromStdString( methodRequest.method() ); + int valueCount = setRequest.data_count(); + + std::vector fields; + m_fieldOwner->fields( fields ); + for ( auto field : fields ) + { + auto scriptability = field->capability(); + if ( scriptability && scriptability->scriptFieldName() == fieldName ) + { + caf::PdmProxyFieldHandle* proxyField = dynamic_cast( field ); + if ( proxyField ) + { + m_proxyField = proxyField; + + if ( dynamic_cast>*>( field ) ) + { + m_dataHolder.reset( new DataHolder>( std::vector( valueCount ) ) ); + return grpc::Status::OK; + } + else if ( dynamic_cast>*>( field ) ) + { + m_dataHolder.reset( new DataHolder>( std::vector( valueCount ) ) ); + return grpc::Status::OK; + } + else if ( dynamic_cast>*>( field ) ) + { + m_dataHolder.reset( new DataHolder>( std::vector( valueCount ) ) ); + return grpc::Status::OK; + } + else + { + CAF_ASSERT( false && "The proxy field data type is not yet supported for streaming fields" ); + } + } + } + } + return grpc::Status( grpc::NOT_FOUND, "Proxy field not found" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Status RiaPdmObjectMethodStateHandler::assignReply( rips::PdmObjectGetMethodReply* reply ) +{ + CAF_ASSERT( m_dataHolder ); + const size_t packageSize = RiaGrpcServiceInterface::numberOfDataUnitsInPackage( m_dataHolder->dataSizeOf() ); + size_t indexInPackage = 0u; + m_dataHolder->reserveReplyStorage( reply ); + + for ( ; indexInPackage < packageSize && m_currentDataIndex < m_dataHolder->dataCount(); ++indexInPackage ) + { + m_dataHolder->addValueToReply( m_currentDataIndex, reply ); + m_currentDataIndex++; + } + if ( indexInPackage > 0u ) + { + return grpc::Status::OK; + } + return grpc::Status( grpc::OUT_OF_RANGE, + "We've reached the end. This is not an error but means transmission is finished" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Status RiaPdmObjectMethodStateHandler::receiveRequest( const rips::PdmObjectSetMethodChunk* chunk, + rips::ClientToServerStreamReply* reply ) +{ + size_t valuesWritten = m_dataHolder->getValuesFromChunk( m_currentDataIndex, chunk ); + m_currentDataIndex += valuesWritten; + + if ( m_currentDataIndex > totalValueCount() ) + { + return grpc::Status( grpc::OUT_OF_RANGE, "Attempting to write out of bounds" ); + } + reply->set_accepted_value_count( static_cast( m_currentDataIndex ) ); + return grpc::Status::OK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RiaPdmObjectMethodStateHandler::streamedValueCount() const +{ + return m_currentDataIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RiaPdmObjectMethodStateHandler::totalValueCount() const +{ + return m_dataHolder->dataCount(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaPdmObjectMethodStateHandler::finish() +{ + if ( m_proxyField ) + { + QVariant before = m_proxyField->toQVariant(); + m_dataHolder->applyValuesToProxyField( m_proxyField ); + QVariant after = m_proxyField->toQVariant(); + m_fieldOwner->fieldChangedByUi( m_proxyField, before, after ); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -39,7 +340,7 @@ grpc::Status RiaGrpcPdmObjectService::GetAncestorPdmObject( grpc::ServerContext* std::vector objectsOfCurrentClass; QString scriptClassName = QString::fromStdString( request->object().class_keyword() ); - QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName ); + QString classKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( scriptClassName ); project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); @@ -56,7 +357,8 @@ grpc::Status RiaGrpcPdmObjectService::GetAncestorPdmObject( grpc::ServerContext* { caf::PdmObject* parentObject = nullptr; QString ancestorScriptName = QString::fromStdString( request->parent_keyword() ); - QString ancestorClassKeyword = RicfObjectCapability::classKeywordFromScriptClassName( ancestorScriptName ); + QString ancestorClassKeyword = + caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( ancestorScriptName ); matchingObject->firstAncestorOrThisFromClassKeyword( ancestorClassKeyword, parentObject ); if ( parentObject ) { @@ -74,28 +376,13 @@ grpc::Status RiaGrpcPdmObjectService::GetDescendantPdmObjects( grpc::ServerConte const rips::PdmDescendantObjectRequest* request, rips::PdmObjectArray* reply ) { - RimProject* project = RiaApplication::instance()->project(); - std::vector objectsOfCurrentClass; - - QString scriptClassName = QString::fromStdString( request->object().class_keyword() ); - QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName ); - - project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); - - caf::PdmObject* matchingObject = nullptr; - for ( caf::PdmObject* testObject : objectsOfCurrentClass ) - { - if ( reinterpret_cast( testObject ) == request->object().address() ) - { - matchingObject = testObject; - } - } + auto matchingObject = findCafObjectFromRipsObject( request->object() ); if ( matchingObject ) { std::vector childObjects; - QString childClassKeyword = - RicfObjectCapability::classKeywordFromScriptClassName( QString::fromStdString( request->child_keyword() ) ); + QString childClassKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( + QString::fromStdString( request->child_keyword() ) ); matchingObject->descendantsIncludingThisFromClassKeyword( childClassKeyword, childObjects ); for ( auto pdmChild : childObjects ) { @@ -114,23 +401,7 @@ grpc::Status RiaGrpcPdmObjectService::GetChildPdmObjects( grpc::ServerContext* const rips::PdmChildObjectRequest* request, rips::PdmObjectArray* reply ) { - RimProject* project = RiaApplication::instance()->project(); - std::vector objectsOfCurrentClass; - - QString scriptClassName = QString::fromStdString( request->object().class_keyword() ); - QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName ); - - project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); - - caf::PdmObject* matchingObject = nullptr; - for ( caf::PdmObject* testObject : objectsOfCurrentClass ) - { - if ( reinterpret_cast( testObject ) == request->object().address() ) - { - matchingObject = testObject; - } - } - + auto matchingObject = findCafObjectFromRipsObject( request->object() ); if ( matchingObject ) { QString fieldName = QString::fromStdString( request->child_field() ); @@ -138,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 ); @@ -162,22 +434,7 @@ grpc::Status RiaGrpcPdmObjectService::UpdateExistingPdmObject( grpc::ServerConte const rips::PdmObject* request, rips::Empty* response ) { - RimProject* project = RiaApplication::instance()->project(); - std::vector objectsOfCurrentClass; - - QString scriptClassName = QString::fromStdString( request->class_keyword() ); - QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName ); - - project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); - - caf::PdmObject* matchingObject = nullptr; - for ( caf::PdmObject* pdmObject : objectsOfCurrentClass ) - { - if ( reinterpret_cast( pdmObject ) == request->address() ) - { - matchingObject = pdmObject; - } - } + auto matchingObject = findCafObjectFromRipsObject( *request ); if ( matchingObject ) { @@ -191,7 +448,8 @@ grpc::Status RiaGrpcPdmObjectService::UpdateExistingPdmObject( grpc::ServerConte } matchingObject->updateAllRequiredEditors(); - project->scheduleCreateDisplayModelAndRedrawAllViews(); + RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews(); + Rim3dView* view = dynamic_cast( matchingObject ); if ( view ) { @@ -209,22 +467,7 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext* const rips::CreatePdmChildObjectRequest* request, rips::PdmObject* reply ) { - RimProject* project = RiaApplication::instance()->project(); - std::vector objectsOfCurrentClass; - - QString scriptClassName = QString::fromStdString( request->object().class_keyword() ); - QString classKeyword = RicfObjectCapability::classKeywordFromScriptClassName( scriptClassName ); - - project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); - - caf::PdmObject* matchingObject = nullptr; - for ( caf::PdmObject* testObject : objectsOfCurrentClass ) - { - if ( reinterpret_cast( testObject ) == request->object().address() ) - { - matchingObject = testObject; - } - } + auto matchingObject = findCafObjectFromRipsObject( request->object() ); if ( matchingObject ) { @@ -242,6 +485,28 @@ grpc::Status RiaGrpcPdmObjectService::CreateChildPdmObject( grpc::ServerContext* return grpc::Status( grpc::NOT_FOUND, "Could not find PdmObject" ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcPdmObjectService::CallPdmObjectGetMethod( grpc::ServerContext* context, + const rips::PdmObjectMethodRequest* request, + rips::PdmObjectGetMethodReply* reply, + RiaPdmObjectMethodStateHandler* stateHandler ) +{ + return stateHandler->assignReply( reply ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcPdmObjectService::CallPdmObjectSetMethod( grpc::ServerContext* context, + const rips::PdmObjectSetMethodChunk* chunk, + rips::ClientToServerStreamReply* reply, + RiaPdmObjectMethodStateHandler* stateHandler ) +{ + return stateHandler->receiveRequest( chunk, reply ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -262,7 +527,47 @@ std::vector RiaGrpcPdmObjectService::createCallbacks( &Self::RequestUpdateExistingPdmObject ), new RiaGrpcUnaryCallback( this, &Self::CreateChildPdmObject, - &Self::RequestCreateChildPdmObject )}; + &Self::RequestCreateChildPdmObject ), + new RiaGrpcServerToClientStreamCallback( this, + &Self::CallPdmObjectGetMethod, + &Self::RequestCallPdmObjectGetMethod, + new RiaPdmObjectMethodStateHandler ), + + new RiaGrpcClientToServerStreamCallback( this, + &Self::CallPdmObjectSetMethod, + &Self::RequestCallPdmObjectSetMethod, + new RiaPdmObjectMethodStateHandler( + true ) )}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmObject* RiaGrpcPdmObjectService::findCafObjectFromRipsObject( const rips::PdmObject& ripsObject ) +{ + RimProject* project = RiaApplication::instance()->project(); + std::vector objectsOfCurrentClass; + + QString scriptClassName = QString::fromStdString( ripsObject.class_keyword() ); + QString classKeyword = caf::PdmObjectScriptabilityRegister::classKeywordFromScriptClassName( scriptClassName ); + + project->descendantsIncludingThisFromClassKeyword( classKeyword, objectsOfCurrentClass ); + + caf::PdmObject* matchingObject = nullptr; + for ( caf::PdmObject* testObject : objectsOfCurrentClass ) + { + if ( reinterpret_cast( testObject ) == ripsObject.address() ) + { + matchingObject = testObject; + } + } + return matchingObject; } static bool RiaGrpcPdmObjectService_init = RiaGrpcServiceFactory::instance()->registerCreator( diff --git a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.h b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.h index 4bb6de3bbd..1e18670331 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.h +++ b/ApplicationCode/GrpcInterface/RiaGrpcPdmObjectService.h @@ -23,6 +23,50 @@ #include #include +namespace caf +{ +class PdmProxyFieldHandle; +} + +struct AbstractDataHolder +{ + virtual size_t dataCount() const = 0; + virtual size_t dataSizeOf() const = 0; + virtual void reserveReplyStorage( rips::PdmObjectGetMethodReply* reply ) const = 0; + virtual void addValueToReply( size_t valueIndex, rips::PdmObjectGetMethodReply* reply ) const = 0; + + virtual size_t getValuesFromChunk( size_t startIndex, const rips::PdmObjectSetMethodChunk* chunk ) = 0; + virtual void applyValuesToProxyField( caf::PdmProxyFieldHandle* proxyField ) = 0; +}; + +//================================================================================================== +// +// State handler for streaming of active cell info +// +//================================================================================================== +class RiaPdmObjectMethodStateHandler +{ + typedef grpc::Status Status; + +public: + RiaPdmObjectMethodStateHandler( bool clientToServerStreamer = false ); + + Status init( const rips::PdmObjectMethodRequest* request ); + Status init( const rips::PdmObjectSetMethodChunk* chunk ); + Status assignReply( rips::PdmObjectGetMethodReply* reply ); + Status receiveRequest( const rips::PdmObjectSetMethodChunk* chunk, rips::ClientToServerStreamReply* reply ); + size_t streamedValueCount() const; + size_t totalValueCount() const; + void finish(); + +protected: + caf::PdmObject* m_fieldOwner; + caf::PdmProxyFieldHandle* m_proxyField; + std::unique_ptr m_dataHolder; + size_t m_currentDataIndex; + bool m_clientToServerStreamer; +}; + //================================================================================================== // // gRPC-service answering request searching for PdmObjects in property tree @@ -49,5 +93,16 @@ public: const rips::PdmObject* request, rips::Empty* response ) override; + grpc::Status CallPdmObjectGetMethod( grpc::ServerContext* context, + const rips::PdmObjectMethodRequest* request, + rips::PdmObjectGetMethodReply* reply, + RiaPdmObjectMethodStateHandler* stateHandler ); + grpc::Status CallPdmObjectSetMethod( grpc::ServerContext* context, + const rips::PdmObjectSetMethodChunk* chunk, + rips::ClientToServerStreamReply* reply, + RiaPdmObjectMethodStateHandler* stateHandler ); + std::vector createCallbacks() override; + + static caf::PdmObject* findCafObjectFromRipsObject( const rips::PdmObject& ripsObject ); }; diff --git a/ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp b/ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp index 158471b284..dcda32f210 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp +++ b/ApplicationCode/GrpcInterface/RiaGrpcPropertiesService.cpp @@ -70,7 +70,7 @@ public: //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - size_t cellCount() const { return m_cellCount; } + size_t totalValueCount() const { return m_cellCount; } //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp b/ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp index 4dfdda60e8..d2b2f7f4e9 100644 --- a/ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp +++ b/ApplicationCode/GrpcInterface/RiaGrpcServiceInterface.cpp @@ -22,13 +22,15 @@ #include "RimProject.h" #include "RicfFieldHandle.h" -#include "RicfMessages.h" #include "RicfObjectCapability.h" #include "cafPdmChildArrayField.h" #include "cafPdmChildField.h" #include "cafPdmDataValueField.h" #include "cafPdmObject.h" +#include "cafPdmObjectScriptabilityRegister.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmScriptIOMessages.h" #include "cafPdmXmlFieldHandle.h" #include @@ -71,7 +73,7 @@ void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHa CAF_ASSERT( source && destination && source->xmlCapability() ); QString classKeyword = source->xmlCapability()->classKeyword(); - QString scriptName = RicfObjectCapability::scriptClassNameFromClassKeyword( classKeyword ); + QString scriptName = caf::PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword( classKeyword ); destination->set_class_keyword( scriptName.toStdString() ); destination->set_address( reinterpret_cast( source ) ); @@ -100,10 +102,14 @@ void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips( const caf::PdmObjectHa auto ricfHandle = field->template capability(); if ( ricfHandle != nullptr ) { - QString text; - QTextStream outStream( &text ); - ricfHandle->writeFieldData( outStream, false ); - ( *parametersMap )[ricfHandle->fieldName().toStdString()] = text.toStdString(); + auto pdmProxyField = dynamic_cast( field ); + if ( !( pdmProxyField && pdmProxyField->isStreamingField() ) ) + { + QString text; + QTextStream outStream( &text ); + ricfHandle->readFromField( outStream, false ); + ( *parametersMap )[ricfHandle->scriptFieldName().toStdString()] = text.toStdString(); + } } } } @@ -141,7 +147,7 @@ void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf( const rips::PdmObject* auto ricfHandle = pdmValueField->template capability(); if ( ricfHandle ) { - QString keyword = ricfHandle->fieldName(); + QString keyword = ricfHandle->scriptFieldName(); QString value = QString::fromStdString( parametersMap[keyword.toStdString()] ); QVariant oldValue, newValue; @@ -167,10 +173,10 @@ bool RiaGrpcServiceInterface::assignFieldValue( const QString& stringValue, auto ricfHandle = field->template capability(); if ( field && ricfHandle != nullptr ) { - QTextStream stream( stringValue.toLatin1() ); - RicfMessages messages; + QTextStream stream( stringValue.toLatin1() ); + caf::PdmScriptIOMessages messages; *oldValue = field->toQVariant(); - ricfHandle->readFieldData( stream, nullptr, &messages, false ); + ricfHandle->writeToField( stream, nullptr, &messages, false ); *newValue = field->toQVariant(); return true; } @@ -206,7 +212,7 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmObject //-------------------------------------------------------------------------------------------------- caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildFieldHandle* childField ) { - QString childClassKeyword = childField->xmlCapability()->childClassKeyword(); + QString childClassKeyword = childField->xmlCapability()->dataTypeName(); auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); CAF_ASSERT( pdmObjectHandle ); @@ -219,7 +225,7 @@ caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildField( caf::PdmChildF //-------------------------------------------------------------------------------------------------- caf::PdmObjectHandle* RiaGrpcServiceInterface::emplaceChildArrayField( caf::PdmChildArrayFieldHandle* childArrayField ) { - QString childClassKeyword = childArrayField->xmlCapability()->childClassKeyword(); + QString childClassKeyword = childArrayField->xmlCapability()->dataTypeName(); auto pdmObjectHandle = caf::PdmDefaultObjectFactory::instance()->create( childClassKeyword ); CAF_ASSERT( pdmObjectHandle ); diff --git a/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp index 03ec55f743..aac0f7458b 100644 --- a/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Surfaces/RivSurfacePartMgr.cpp @@ -456,7 +456,7 @@ void RivSurfacePartMgr::calculateVertexTextureCoordinates( cvf::Vec2fArray* cvf::Vec2f* rawPtr = textureCoords->ptr(); #pragma omp parallel for - for ( int vxIdx = 0; vxIdx < numVertices; vxIdx++ ) + for ( int vxIdx = 0; vxIdx < static_cast( numVertices ); vxIdx++ ) { double cellScalarValue = resultAccessor->cellScalarGlobIdx( vertexToCellIdxMap[vxIdx] ); cvf::Vec2f texCoord = mapper->mapToTextureCoord( cellScalarValue ); diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index f43589ebb3..9e54235dd9 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -43,7 +43,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimCase, "Case", "RimCase" ); RimCase::RimCase() : m_isInActiveDestruction( false ) { - RICF_InitObjectWithScriptNameAndComment( "Case", ":/Case48x48.png", "", "", "Case", "The ResInsight base class for Cases" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Case", ":/Case48x48.png", "", "", "Case", "The ResInsight base class for Cases" ); RICF_InitField( &caseUserDescription, "Name", QString(), "Case Name", "", "", "" ); caseUserDescription.registerKeywordAlias( "CaseUserDescription" ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index 8dd56d3084..fda868f356 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -78,14 +78,20 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimEclipseCase, "RimReservoir" ); //-------------------------------------------------------------------------------------------------- RimEclipseCase::RimEclipseCase() { - RICF_InitObjectWithScriptNameAndComment( "EclipseCase", - ":/Case48x48.png", - "", - "", - "Reservoir", - "Abtract base class for Eclipse Cases" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "EclipseCase", + ":/Case48x48.png", + "", + "", + "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/RimEclipseCellColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp index 609d0c1c87..7bc3083a9e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp @@ -21,6 +21,7 @@ #include "RimEclipseCellColors.h" #include "RiaColorTables.h" +#include "RicfCommandObject.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFlowDiagResults.h" @@ -50,7 +51,12 @@ CAF_PDM_SOURCE_INIT( RimEclipseCellColors, "ResultSlot" ); //-------------------------------------------------------------------------------------------------- RimEclipseCellColors::RimEclipseCellColors() { - CAF_PDM_InitObject( "Cell Result", ":/CellResult.png", "", "" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Cell Result", + ":/CellResult.png", + "", + "", + "CellColors", + "Eclipse Cell Colors class" ); CAF_PDM_InitFieldNoDefault( &obsoleteField_legendConfig, "LegendDefinition", "Color Legend", "", "", "" ); this->obsoleteField_legendConfig.xmlCapability()->setIOWritable( false ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseContourMapView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseContourMapView.cpp index 98b3d0d72d..2dba5ee15c 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseContourMapView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseContourMapView.cpp @@ -53,12 +53,12 @@ const cvf::Mat4d RimEclipseContourMapView::sm_defaultViewMatrix = RimEclipseContourMapView::RimEclipseContourMapView() : m_cameraPositionLastUpdate( cvf::Vec3d::UNDEFINED ) { - RICF_InitObjectWithScriptNameAndComment( "Contour Map View", - ":/2DMap16x16.png", - "", - "", - "EclipseContourMap", - "A contour map for Eclipse cases" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Contour Map View", + ":/2DMap16x16.png", + "", + "", + "EclipseContourMap", + "A contour map for Eclipse cases" ); CAF_PDM_InitFieldNoDefault( &m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", "" ); m_contourMapProjection = new RimEclipseContourMapProjection(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp index ff5f63c416..b79bf15b96 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -70,7 +70,7 @@ CAF_PDM_SOURCE_INIT( RimEclipseResultCase, "EclipseCase" ); RimEclipseResultCase::RimEclipseResultCase() : RimEclipseCase() { - RICF_InitObject( "Eclipse Case", ":/Case48x48.png", "", "The Regular Eclipse Results Case" ); + CAF_PDM_InitScriptableObject( "Eclipse Case", ":/Case48x48.png", "", "The Regular Eclipse Results Case" ); CAF_PDM_InitFieldNoDefault( &m_unitSystem, "UnitSystem", "Unit System", "", "", "" ); m_unitSystem.registerGetMethod( RiaApplication::instance()->project(), &RimProject::commonUnitSystemForAllCases ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 25b263866a..3bc68e2f7d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -95,7 +95,7 @@ RimEclipseResultDefinition::RimEclipseResultDefinition( caf::PdmUiItemInfo::Labe , m_labelPosition( labelPosition ) , m_ternaryEnabled( true ) { - CAF_PDM_InitObject( "Result Definition", "", "", "" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Result Definition", "", "", "", "EclipseResult", "An eclipse result definition" ); RICF_InitFieldNoDefault( &m_resultType, "ResultType", "Type", "", "", "" ); m_resultType.uiCapability()->setUiHidden( true ); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index a8713cec14..b5e8a87046 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -121,14 +121,20 @@ RimEclipseView::RimEclipseView() RiaPreferences* preferences = app->preferences(); CVF_ASSERT( preferences ); - RICF_InitObjectWithScriptNameAndComment( "Reservoir View", - ":/3DView16x16.png", - "", - "The Eclipse 3d Reservoir View", - "EclipseView", - "The Eclipse 3d Reservoir View" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Reservoir View", + ":/3DView16x16.png", + "", + "The Eclipse 3d Reservoir View", + "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 ); @@ -172,8 +178,12 @@ RimEclipseView::RimEclipseView() CAF_PDM_InitField( &m_showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells", "", "", "" ); CAF_PDM_InitField( &m_showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", "" ); - this->cellResult()->setReservoirView( this ); + CAF_PDM_InitScriptableFieldNoDefault( &m_cellResultData, "CellResultData", "", "", "", "Current Eclipse Cell Result" ); + m_cellResultData.xmlCapability()->disableIO(); + m_cellResultData.registerGetMethod( this, &RimEclipseView::currentCellResultData ); + m_cellResultData.registerSetMethod( this, &RimEclipseView::setCurrentCellResultData ); + this->cellResult()->setReservoirView( this ); this->cellEdgeResult()->setReservoirView( this ); this->cellEdgeResult()->legendConfig()->setColorRange( RimRegularLegendConfig::PINK_WHITE ); @@ -351,6 +361,12 @@ void RimEclipseView::fieldChangedByUi( const caf::PdmFieldHandle* changedField, scheduleCreateDisplayModelAndRedraw(); } + else if ( changedField == &m_cellResultData ) + { + currentGridCellResults()->recalculateStatistics( m_cellResult->eclipseResultAddress() ); + setCurrentTimeStepAndUpdate( currentTimeStep() ); + createDisplayModelAndRedraw(); + } } //-------------------------------------------------------------------------------------------------- @@ -1120,7 +1136,7 @@ void RimEclipseView::onUpdateDisplayModelVisibility() //-------------------------------------------------------------------------------------------------- /// Convenience for quick access to results //-------------------------------------------------------------------------------------------------- -RigCaseCellResultsData* RimEclipseView::currentGridCellResults() +RigCaseCellResultsData* RimEclipseView::currentGridCellResults() const { if ( m_eclipseCase ) { @@ -1894,6 +1910,45 @@ RimEclipseCellColors* RimEclipseView::currentFaultResultColors() return faultResultColors; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEclipseView::currentCellResultData() const +{ + std::vector resultData; + if ( currentGridCellResults() && cellResult() ) + { + int timeStep = 0; + if ( cellResult()->hasDynamicResult() ) + { + timeStep = this->currentTimeStep(); + } + resultData = currentGridCellResults()->cellScalarResults( cellResult()->eclipseResultAddress() )[timeStep]; + } + return resultData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::setCurrentCellResultData( const std::vector& values ) +{ + if ( currentGridCellResults() && cellResult() ) + { + int timeStep = 0; + if ( cellResult()->hasDynamicResult() ) + { + timeStep = this->currentTimeStep(); + } + std::vector* modResult = + currentGridCellResults()->modifiableCellScalarResult( cellResult()->eclipseResultAddress(), timeStep ); + if ( modResult->size() == values.size() ) + { + *modResult = values; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.h b/ApplicationCode/ProjectDataModel/RimEclipseView.h index 9835a2d3f6..fca233d51e 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.h @@ -24,6 +24,7 @@ #include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" #include "cvfArray.h" @@ -101,10 +102,13 @@ public: const RimEclipsePropertyFilterCollection* eclipsePropertyFilterCollection() const; void setOverridePropertyFilterCollection( RimEclipsePropertyFilterCollection* pfc ); - RigCaseCellResultsData* currentGridCellResults(); + RigCaseCellResultsData* currentGridCellResults() const; const RigActiveCellInfo* currentActiveCellInfo() const; RimEclipseCellColors* currentFaultResultColors(); + std::vector currentCellResultData() const; + void setCurrentCellResultData( const std::vector& values ); + void setEclipseCase( RimEclipseCase* reservoir ); RimEclipseCase* eclipseCase() const; RimCase* ownerCase() const override; @@ -206,6 +210,8 @@ private: caf::PdmChildField m_fractureColors; caf::PdmChildField m_virtualPerforationResult; + caf::PdmProxyValueField> m_cellResultData; + caf::PdmChildField m_wellCollection; caf::PdmChildField m_faultCollection; diff --git a/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp b/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp index a0a408715c..b00a03e971 100644 --- a/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp @@ -15,7 +15,12 @@ CAF_PDM_SOURCE_INIT( RimFileWellPath, "WellPath" ); //-------------------------------------------------------------------------------------------------- RimFileWellPath::RimFileWellPath() { - RICF_InitObjectWithScriptNameAndComment( "File Well Path", ":/Well.png", "", "", "FileWellPath", "Well Paths Loaded From File" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "File Well Path", + ":/Well.png", + "", + "", + "FileWellPath", + "Well Paths Loaded From File" ); CAF_PDM_InitFieldNoDefault( &id, "WellPathId", "Id", "", "", "" ); id.uiCapability()->setUiReadOnly( true ); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index ed309550c3..e788d5dbf8 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -69,14 +69,20 @@ CAF_PDM_SOURCE_INIT( RimGeoMechCase, "ResInsightGeoMechCase" ); RimGeoMechCase::RimGeoMechCase( void ) : m_applyTimeFilter( false ) { - RICF_InitObjectWithScriptNameAndComment( "GeoMechanical Case", - ":/GeoMechCase48x48.png", - "", - "The GeoMechanical Results Case", - "GeoMechCase", - "The Abaqus Based GeoMech Case" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMechanical Case", + ":/GeoMechCase48x48.png", + "", + "The GeoMechanical Results Case", + "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/RimGeoMechContourMapView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapView.cpp index 7eb48c3fb6..bc41a7bc3b 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechContourMapView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechContourMapView.cpp @@ -51,12 +51,12 @@ const cvf::Mat4d RimGeoMechContourMapView::sm_defaultViewMatrix = RimGeoMechContourMapView::RimGeoMechContourMapView() : m_cameraPositionLastUpdate( cvf::Vec3d::UNDEFINED ) { - RICF_InitObjectWithScriptNameAndComment( "GeoMech Contour Map View", - ":/2DMap16x16.png", - "", - "", - "GeoMechContourMap", - "A contour map for GeoMech cases" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "GeoMech Contour Map View", + ":/2DMap16x16.png", + "", + "", + "GeoMechContourMap", + "A contour map for GeoMech cases" ); CAF_PDM_InitFieldNoDefault( &m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", "" ); m_contourMapProjection = new RimGeoMechContourMapProjection(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp index 371d65ad4f..5ffa1661b3 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp @@ -85,7 +85,7 @@ CAF_PDM_SOURCE_INIT( RimGeoMechView, "GeoMechView" ); //-------------------------------------------------------------------------------------------------- RimGeoMechView::RimGeoMechView( void ) { - RICF_InitObject( "Geomechanical View", ":/3DViewGeoMech16x16.png", "", "The Geomechanical 3d View" ); + CAF_PDM_InitScriptableObject( "Geomechanical View", ":/3DViewGeoMech16x16.png", "", "The Geomechanical 3d View" ); CAF_PDM_InitFieldNoDefault( &cellResult, "GridCellResult", "Color Result", ":/CellResult.png", "", "" ); cellResult = new RimGeoMechCellColors(); diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp index 0fc8adfe11..ebfb230149 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -55,12 +55,12 @@ CAF_PDM_SOURCE_INIT( RimIdenticalGridCaseGroup, "RimIdenticalGridCaseGroup" ); //-------------------------------------------------------------------------------------------------- RimIdenticalGridCaseGroup::RimIdenticalGridCaseGroup() { - RICF_InitObjectWithScriptNameAndComment( "Grid Case Group", - ":/GridCaseGroup16x16.png", - "", - "", - "GridCaseGroup", - "A statistics case group" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Grid Case Group", + ":/GridCaseGroup16x16.png", + "", + "", + "GridCaseGroup", + "A statistics case group" ); RICF_InitField( &name, "UserDescription", QString( "Grid Case Group" ), "Name", "", "", "" ); diff --git a/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp index e5c7993d35..059ccdccac 100644 --- a/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp @@ -40,7 +40,10 @@ CAF_PDM_SOURCE_INIT( RimModeledWellPath, "ModeledWellPath" ); //-------------------------------------------------------------------------------------------------- RimModeledWellPath::RimModeledWellPath() { - RICF_InitObject( "Modeled WellPath", ":/EditableWell.png", "", "A Well Path created interactively in ResInsight" ); + CAF_PDM_InitScriptableObject( "Modeled WellPath", + ":/EditableWell.png", + "", + "A Well Path created interactively in ResInsight" ); CAF_PDM_InitFieldNoDefault( &m_geometryDefinition, "WellPathGeometryDef", "Trajectory", "", "", "" ); m_geometryDefinition = new RimWellPathGeometryDef; diff --git a/ApplicationCode/ProjectDataModel/RimPlot.cpp b/ApplicationCode/ProjectDataModel/RimPlot.cpp index 621a1fad2d..14302b1286 100644 --- a/ApplicationCode/ProjectDataModel/RimPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimPlot.cpp @@ -33,7 +33,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlot, "RimPlot" ); // Do not use. Abstract //-------------------------------------------------------------------------------------------------- RimPlot::RimPlot() { - RICF_InitObjectWithScriptNameAndComment( "Plot", "", "", "", "Plot", "The Abstract Base Class for all Plot Objects" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Plot", "", "", "", "Plot", "The Abstract Base Class for all Plot Objects" ); CAF_PDM_InitFieldNoDefault( &m_rowSpan, "RowSpan", "Row Span", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_colSpan, "ColSpan", "Col Span", "", "", "" ); diff --git a/ApplicationCode/ProjectDataModel/RimPlotWindow.cpp b/ApplicationCode/ProjectDataModel/RimPlotWindow.cpp index 7ff6703c97..07bd22d4d6 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotWindow.cpp +++ b/ApplicationCode/ProjectDataModel/RimPlotWindow.cpp @@ -37,12 +37,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimPlotWindow, "RimPlotWindow" ); // Do not us //-------------------------------------------------------------------------------------------------- RimPlotWindow::RimPlotWindow() { - RICF_InitObjectWithScriptNameAndComment( "PlotWindow", - "", - "", - "", - "PlotWindow", - "The Abstract base class for all MDI Windows in the Plot Window" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "PlotWindow", + "", + "", + "", + "PlotWindow", + "The Abstract base class for all MDI Windows in the Plot Window" ); RICF_InitField( &m_id, "Id", -1, "View ID", "", "", "" ); m_id.registerKeywordAlias( "ViewId" ); diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index b89f6d9e1c..bdd33f34fe 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -114,7 +114,7 @@ RimProject::RimProject( void ) , m_nextValidPlotId( 1 ) , m_nextValidCalculationId( 1 ) { - RICF_InitObjectWithScriptNameAndComment( "Project", "", "", "", "Project", "The ResInsight Project" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Project", "", "", "", "Project", "The ResInsight Project" ); CAF_PDM_InitField( &m_projectFileVersionString, "ProjectFileVersionString", QString( STRPRODUCTVER ), "", "", "", "" ); m_projectFileVersionString.uiCapability()->setUiHidden( true ); diff --git a/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp b/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp index 2ce7f7a18f..480cc47d53 100644 --- a/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp +++ b/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp @@ -62,7 +62,12 @@ CAF_PDM_SOURCE_INIT( RimSimWellInView, "Well" ); //-------------------------------------------------------------------------------------------------- RimSimWellInView::RimSimWellInView() { - RICF_InitObjectWithScriptNameAndComment( "Simulation Well", ":/Well.png", "", "", "SimulationWell", "An Eclipse Simulation Well" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "Simulation Well", + ":/Well.png", + "", + "", + "SimulationWell", + "An Eclipse Simulation Well" ); RICF_InitFieldNoDefault( &name, "Name", "Name", "", "", "" ); name.registerKeywordAlias( "WellName" ); diff --git a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp index 8fe989bf0f..2c7b5319d3 100644 --- a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp @@ -43,12 +43,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimViewWindow, "ViewWindow" ); // Do not use. //-------------------------------------------------------------------------------------------------- RimViewWindow::RimViewWindow( void ) { - RICF_InitObjectWithScriptNameAndComment( "View window", - "", - "", - "", - "ViewWindow", - "The Base Class for all Views and Plots in ResInsight" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "View window", + "", + "", + "", + "ViewWindow", + "The Base Class for all Views and Plots in ResInsight" ); CAF_PDM_InitFieldNoDefault( &m_windowController, "WindowController", "", "", "", "" ); m_windowController.uiCapability()->setUiHidden( true ); diff --git a/ApplicationCode/ProjectDataModel/RimWbsParameters.cpp b/ApplicationCode/ProjectDataModel/RimWbsParameters.cpp index fbbdf85850..f9b0e888f7 100644 --- a/ApplicationCode/ProjectDataModel/RimWbsParameters.cpp +++ b/ApplicationCode/ProjectDataModel/RimWbsParameters.cpp @@ -33,7 +33,7 @@ CAF_PDM_SOURCE_INIT( RimWbsParameters, "WbsParameters" ); //-------------------------------------------------------------------------------------------------- RimWbsParameters::RimWbsParameters() { - RICF_InitObject( "Well Bore Stability Parameters", ":/WellLogPlot16x16.png", "", "" ); + CAF_PDM_InitScriptableObject( "Well Bore Stability Parameters", ":/WellLogPlot16x16.png", "", "" ); RICF_InitFieldNoDefault( &m_porePressureSource, "PorePressureReservoirSource", @@ -427,13 +427,18 @@ std::vector RimWbsParameters::supportedSource { std::vector sources; + std::set sourcesAlreadyAdded; + for ( auto source : parameter.sources() ) { + if ( sourcesAlreadyAdded.count( source ) ) continue; + if ( source == RigWbsParameter::LAS_FILE ) { if ( hasLasFileWithChannel( parameter.addressString( RigWbsParameter::LAS_FILE ) ) ) { sources.push_back( source ); + sourcesAlreadyAdded.insert( source ); } } else if ( source == RigWbsParameter::ELEMENT_PROPERTY_TABLE ) @@ -442,11 +447,13 @@ std::vector RimWbsParameters::supportedSource if ( hasElementPropertyEntry( resAddr ) ) { sources.push_back( source ); + sourcesAlreadyAdded.insert( source ); } } else { sources.push_back( source ); + sourcesAlreadyAdded.insert( source ); } } return sources; diff --git a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp index ceb31bfc81..b02093ce8a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp @@ -42,9 +42,18 @@ CAF_PDM_SOURCE_INIT( RimWellBoreStabilityPlot, "WellBoreStabilityPlot" ); //-------------------------------------------------------------------------------------------------- RimWellBoreStabilityPlot::RimWellBoreStabilityPlot() { - RICF_InitObject( "Well Bore Stability Plot", ":/WellBoreStability16x16.png", "", "A GeoMechanical Well Bore Stabilit Plot" ); + CAF_PDM_InitScriptableObject( "Well Bore Stability Plot", + ":/WellBoreStability16x16.png", + "", + "A GeoMechanical Well Bore Stabilit Plot" ); - CAF_PDM_InitFieldNoDefault( &m_wbsParameters, "WbsParameters", "Well Bore Stability Parameters", "", "", "" ); + CAF_PDM_InitScriptableFieldWithKeywordNoDefault( &m_wbsParameters, + "WbsParameters", + "Parameters", + "Well Bore Stability Parameters", + "", + "", + "" ); m_wbsParameters = new RimWbsParameters; m_wbsParameters.uiCapability()->setUiTreeHidden( true ); m_wbsParameters.uiCapability()->setUiTreeChildrenHidden( true ); @@ -82,6 +91,16 @@ void RimWellBoreStabilityPlot::copyWbsParameters( const RimWbsParameters* wbsPar } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellBoreStabilityPlot::setCaseWellPathAndTimeStep( RimGeoMechCase* geoMechCase, RimWellPath* wellPath, int timeStep ) +{ + m_wbsParameters->setGeoMechCase( geoMechCase ); + m_wbsParameters->setWellPath( wellPath ); + m_wbsParameters->setTimeStep( timeStep ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h index e17f53929a..4d396b7f87 100644 --- a/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h +++ b/ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h @@ -39,6 +39,7 @@ public: void applyWbsParametersToExtractor( RigGeoMechWellLogExtractor* extractor ); double userDefinedValue( const RigWbsParameter& parameter ) const; void copyWbsParameters( const RimWbsParameters* wbsParameters ); + void setCaseWellPathAndTimeStep( RimGeoMechCase* geoMechCase, RimWellPath* wellPath, int timeStep ); protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp index 9cb61147f8..8e736cd38e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp @@ -108,6 +108,19 @@ void RimWellLogFileCurve::onLoadDataAndUpdate( bool updateParentPlot ) } } } + if ( tvdRkbValues.size() != values.size() ) + { + RigWellPath* rigWellPath = m_wellPath->wellPathGeometry(); + if ( rigWellPath ) + { + tvdRkbValues.clear(); + for ( double measuredDepthValue : measuredDepthValues ) + { + tvdRkbValues.push_back( -rigWellPath->interpolatedPointAlongWellPath( measuredDepthValue ).z() + + m_wellPath->wellPathGeometry()->rkbDiff() ); + } + } + } std::map> validDepths; if ( values.size() == measuredDepthValues.size() ) diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp index 7769b55541..e2880cc58d 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp @@ -71,10 +71,10 @@ CAF_PDM_SOURCE_INIT( RimWellLogPlot, "WellLogPlot" ); //-------------------------------------------------------------------------------------------------- RimWellLogPlot::RimWellLogPlot() { - RICF_InitObject( "Well Log Plot", - ":/WellLogPlot16x16.png", - "", - "A Well Log Plot With a shared Depth Axis and Multiple Tracks" ); + CAF_PDM_InitScriptableObject( "Well Log Plot", + ":/WellLogPlot16x16.png", + "", + "A Well Log Plot With a shared Depth Axis and Multiple Tracks" ); CAF_PDM_InitFieldNoDefault( &m_commonDataSource, "CommonDataSource", diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 4340e86fbb..2e60eb1c8e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -73,7 +73,7 @@ const char RimWellPath::SIM_WELL_NONE_UI_TEXT[] = "None"; //-------------------------------------------------------------------------------------------------- RimWellPath::RimWellPath() { - RICF_InitObject( "WellPath", ":/Well.png", "", "The Base class for Well Paths" ); + CAF_PDM_InitScriptableObjectWithNameAndComment( "WellPath", ":/Well.png", "", "", "WellPath", "The Base class for Well Paths" ); RICF_InitFieldNoDefault( &m_name, "Name", "Name", "", "", "" ); m_name.registerKeywordAlias( "WellPathName" ); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp index f998b4ae80..df953ff50b 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp @@ -42,7 +42,7 @@ CAF_PDM_SOURCE_INIT( RimFileSummaryCase, "FileSummaryCase" ); //-------------------------------------------------------------------------------------------------- RimFileSummaryCase::RimFileSummaryCase() { - RICF_InitObject( "File Summary Case ", "", "", "A Summary Case based on SMSPEC files" ); + CAF_PDM_InitScriptableObject( "File Summary Case ", "", "", "A Summary Case based on SMSPEC files" ); CAF_PDM_InitField( &m_includeRestartFiles, "IncludeRestartFiles", false, "Include Restart Files", "", "", "" ); m_includeRestartFiles.uiCapability()->setUiHidden( true ); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp index 51497f8f25..e5c0cb42c7 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp @@ -40,7 +40,7 @@ CAF_PDM_SOURCE_INIT( RimGridSummaryCase, "GridSummaryCase" ); //-------------------------------------------------------------------------------------------------- RimGridSummaryCase::RimGridSummaryCase() { - RICF_InitObject( "Grid Summary Case ", "", "", "A Summary Case based on extracting grid data." ); + CAF_PDM_InitScriptableObject( "Grid Summary Case ", "", "", "A Summary Case based on extracting grid data." ); CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "Associated3DCase", "Eclipse Case", "", "", "" ); m_eclipseCase.uiCapability()->setUiHidden( true ); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp index 15c6514a46..3fdacd76e4 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp @@ -44,7 +44,7 @@ const QString RimSummaryCase::DEFAULT_DISPLAY_NAME = "Display Name"; //-------------------------------------------------------------------------------------------------- RimSummaryCase::RimSummaryCase() { - RICF_InitObject( "Summary Case", ":/SummaryCase16x16.png", "", "The Base Class for all Summary Cases" ); + CAF_PDM_InitScriptableObject( "Summary Case", ":/SummaryCase16x16.png", "", "The Base Class for all Summary Cases" ); RICF_InitField( &m_shortName, "ShortName", QString( "Display Name" ), DEFAULT_DISPLAY_NAME, "", "", "" ); RICF_InitField( &m_useAutoShortName, "AutoShortyName", false, "Use Auto Display Name", "", "", "" ); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 3ba91c04c8..a7f6bf2600 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -143,7 +143,7 @@ CurvesData concatCurvesData( const std::vector& curvesData ); RimSummaryPlot::RimSummaryPlot() : RimPlot() { - RICF_InitObject( "Summary Plot", ":/SummaryPlotLight16x16.png", "", "A Summary Plot" ); + CAF_PDM_InitScriptableObject( "Summary Plot", ":/SummaryPlotLight16x16.png", "", "A Summary Plot" ); RICF_InitField( &m_showPlotTitle, "ShowPlotTitle", true, "Plot Title", "", "", "" ); m_showPlotTitle.xmlCapability()->setIOWritable( false ); diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp index 4542c1d587..c9efee09e4 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -183,6 +183,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd } } } + return RiaWellLogUnitTools::sg_emwUnitString(); } else if ( resAddr.isValid() ) { @@ -210,7 +211,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd } } } - return RiaWellLogUnitTools::sg_emwUnitString(); + return RiaWellLogUnitTools::barUnitString(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigWbsParameter.cpp b/ApplicationCode/ReservoirDataModel/RigWbsParameter.cpp index 9949b52f4e..655d959d1e 100644 --- a/ApplicationCode/ReservoirDataModel/RigWbsParameter.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWbsParameter.cpp @@ -255,8 +255,8 @@ RigWbsParameter RigWbsParameter::PP_NonReservoir() true, {{LAS_FILE, SourceAddress( "PP_NONRES_INP", "", RiaWellLogUnitTools::sg_emwUnitString() )}, {LAS_FILE, SourceAddress( "POR_NONRES_INP", "", RiaWellLogUnitTools::gPerCm3UnitString() )}, - {HYDROSTATIC, SourceAddress( "Hydrostatic", "", RiaWellLogUnitTools::barUnitString() )}, - {USER_DEFINED, SourceAddress( "", "", RiaWellLogUnitTools::barUnitString() )}} ); + {USER_DEFINED, SourceAddress( "", "", RiaWellLogUnitTools::barUnitString() )}, + {HYDROSTATIC, SourceAddress( "Hydrostatic", "", RiaWellLogUnitTools::barUnitString() )}} ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp index 49730cbf3c..ad1164365b 100644 --- a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp +++ b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp @@ -2,10 +2,10 @@ #include "RicfCommandFileExecutor.h" #include "RicfCommandObject.h" -#include "RicfMessages.h" #include "RifcCommandFileReader.h" #include "cafPdmField.h" +#include "cafPdmScriptIOMessages.h" class TestCommand1 : public RicfCommandObject { @@ -80,8 +80,8 @@ TEST( RicfCommands, Test1 ) // std::cout << commandString.toStdString() << std::endl; - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); EXPECT_EQ( (size_t)5, objects.size() ); @@ -138,8 +138,8 @@ TEST( RicfCommands, ErrorMessages ) std::cout << commandString.toStdString() << std::endl; - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); @@ -155,7 +155,7 @@ TEST( RicfCommands, ErrorMessages ) for ( const auto& msg : errors.m_messages ) { QString label; - if ( msg.first == RicfMessages::MESSAGE_ERROR ) + if ( msg.first == caf::PdmScriptIOMessages::MESSAGE_ERROR ) { label = "Error : "; } @@ -180,8 +180,8 @@ TEST( RicfCommands, EmptyArgumentList ) // Ensure no error messages when command with no arguments is read QString commandString( "TestCommand1()" ); - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); @@ -215,8 +215,8 @@ TEST( RicfCommands, TransformFileCommandObjectsToExecutableCommandObjects ) )"; - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); EXPECT_TRUE( errors.m_messages.empty() ); @@ -252,8 +252,8 @@ TEST( RicfCommands, IgnoreCommentLines ) )"; - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); EXPECT_TRUE( errors.m_messages.empty() ); @@ -283,8 +283,8 @@ TEST( RicfCommands, IgnoreCommentLinesShowErrorLine ) )"; - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); EXPECT_EQ( (size_t)1, errors.m_messages.size() ); @@ -315,8 +315,8 @@ TEST( RicfCommands, WriteCommand ) } { - QTextStream inputStream( &commandString ); - RicfMessages errors; + QTextStream inputStream( &commandString ); + caf::PdmScriptIOMessages errors; auto objects = RicfCommandFileReader::readCommands( inputStream, caf::PdmDefaultObjectFactory::instance(), &errors ); diff --git a/ApplicationCode/UserInterface/RiuMultiPlotBook.cpp b/ApplicationCode/UserInterface/RiuMultiPlotBook.cpp index 6b0fcbb0a8..517cf0378d 100644 --- a/ApplicationCode/UserInterface/RiuMultiPlotBook.cpp +++ b/ApplicationCode/UserInterface/RiuMultiPlotBook.cpp @@ -483,9 +483,18 @@ void RiuMultiPlotBook::createPages() page->addPlot( plotWidgets[visibleIndex] ); page->performUpdate(); } + + // Set page numbers in title when there's more than one page + if ( m_pages.size() > 1 ) + { + for ( int i = 0; i < m_pages.size(); ++i ) + { + int pageNumber = i + 1; + m_pages[i]->setPlotTitle( QString( "%1 %2/%3" ).arg( m_plotTitle ).arg( pageNumber ).arg( m_pages.size() ) ); + } + } m_book->adjustSize(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -502,8 +511,7 @@ RiuMultiPlotPage* RiuMultiPlotBook::createPage() RiuMultiPlotPage* page = new RiuMultiPlotPage( m_plotDefinition, this ); // Reapply plot settings - size_t pageNumber = m_pages.size() + 1; - page->setPlotTitle( QString( "%1 %2/%3" ).arg( m_plotTitle ).arg( pageNumber ).arg( pageNumber ) ); + page->setPlotTitle( m_plotTitle ); page->setFontSize( RiaApplication::instance()->preferences()->defaultPlotFontSize() ); page->setTitleVisible( m_titleVisible ); page->setSubTitlesVisible( m_subTitlesVisible ); diff --git a/CMakeLists.txt b/CMakeLists.txt index cb483e65d0..1a39bdda34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -382,10 +382,13 @@ add_subdirectory(Fwk/AppFwk/cafUserInterface) add_subdirectory(Fwk/AppFwk/cafPdmCvf) add_subdirectory(Fwk/AppFwk/CommonCode) add_subdirectory(Fwk/AppFwk/cafVizExtensions) +add_subdirectory(Fwk/AppFwk/cafPdmScripting) +set_property(TARGET cafPdmScripting PROPERTY FOLDER "AppFwk") add_subdirectory(Fwk/AppFwk/cafCommandFeatures) set_property(TARGET cafCommandFeatures PROPERTY FOLDER "AppFwk") + #add_subdirectory(Fwk/AppFwk/cafTests/cafTestCvfApplication) add_subdirectory(Fwk/AppFwk/cafTensor) @@ -403,9 +406,10 @@ list(APPEND APP_FWK_LIBRARIES cafCommand cafPdmCvf - cafTensor + cafTensor CommonCode cafVizExtensions + cafPdmScripting ) set_property(TARGET diff --git a/Fwk/AppFwk/CMakeLists.txt b/Fwk/AppFwk/CMakeLists.txt index b201672db1..e351cf8f19 100644 --- a/Fwk/AppFwk/CMakeLists.txt +++ b/Fwk/AppFwk/CMakeLists.txt @@ -47,6 +47,7 @@ add_subdirectory(cafProjectDataModel) add_subdirectory(cafCommand) add_subdirectory(cafCommandFeatures) add_subdirectory(cafUserInterface) +add_subdirectory(cafPdmScripting) #executables add_subdirectory(cafTests/cafTestApplication) @@ -59,6 +60,7 @@ add_subdirectory (cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests) add_subdirectory (cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests) add_subdirectory (cafProjectDataModel/cafProjectDataModel_UnitTests) add_subdirectory (cafUserInterface/cafUserInterface_UnitTests) +#add_subdirectory(cafPdmScripting/cafPdmScripting_UnitTests) # Organize sub-projects into folders on Visual Studio # Turn on using solution folders diff --git a/Fwk/AppFwk/cafCommandFeatures/AddAndDelete/cafCmdAddItemExec.cpp b/Fwk/AppFwk/cafCommandFeatures/AddAndDelete/cafCmdAddItemExec.cpp index a121bf17be..7731678643 100644 --- a/Fwk/AppFwk/cafCommandFeatures/AddAndDelete/cafCmdAddItemExec.cpp +++ b/Fwk/AppFwk/cafCommandFeatures/AddAndDelete/cafCmdAddItemExec.cpp @@ -63,7 +63,7 @@ QString CmdAddItemExec::name() if (listField) { PdmXmlFieldHandle* xfh = listField->xmlCapability(); - containedObjectType = xfh->childClassKeyword(); + containedObjectType = xfh->dataTypeName(); } return QString("Create new '%1'").arg(containedObjectType); @@ -79,7 +79,7 @@ void CmdAddItemExec::redo() PdmChildArrayFieldHandle* listField = dynamic_cast(field); if (listField && field->xmlCapability()) { - QString classKeyword = field->xmlCapability()->childClassKeyword(); + QString classKeyword = field->xmlCapability()->dataTypeName(); if (classKeyword.isEmpty()) return; diff --git a/Fwk/AppFwk/cafPdmScripting/CMakeLists.txt b/Fwk/AppFwk/cafPdmScripting/CMakeLists.txt new file mode 100644 index 0000000000..5112fa85c2 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required (VERSION 2.8.12) + +project (cafPdmScripting) + +set( PROJECT_FILES + cafPdmCodeGenerator.h + cafPdmFieldScriptability.h + cafPdmFieldScriptability.cpp + cafPdmObjectScriptabilityRegister.h + cafPdmObjectScriptabilityRegister.cpp + cafPdmPythonGenerator.h + cafPdmPythonGenerator.cpp + cafPdmScriptIOMessages.h + cafPdmScriptIOMessages.cpp +) + + +add_library( ${PROJECT_NAME} + ${PROJECT_FILES} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries( ${PROJECT_NAME} cafProjectDataModel ${QT_LIBRARIES} ) + +source_group("" FILES ${PROJECT_FILES}) + +# cotire +if (COMMAND caf_apply_cotire) + caf_apply_cotire("${PROJECT_NAME}") +endif() \ No newline at end of file diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h new file mode 100644 index 0000000000..ac4ba58759 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmCodeGenerator.h @@ -0,0 +1,67 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include "cafFactory.h" + +#include + +#define CAF_PDM_CODE_GENERATOR_HEADER_INIT \ + public: \ + static const std::string& fileExtension(); + +#define CAF_PDM_CODE_GENERATOR_SOURCE_INIT(ClassName, FileExtension)\ + const std::string& ClassName::fileExtension() { static std::string ext = FileExtension; return ext;} \ + CAF_FACTORY_REGISTER(caf::PdmCodeGenerator, ClassName, std::string, ClassName::fileExtension()) + + +namespace caf { + +class PdmObjectFactory; + +//================================================================================================== +/// Abstract skeleton code generator for the Project Data Model +//================================================================================================== +class PdmCodeGenerator +{ +public: + virtual QString generate(PdmObjectFactory* factory) const = 0; +}; + + +typedef Factory PdmCodeGeneratorFactory; + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.cpp new file mode 100644 index 0000000000..23b705acaa --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.cpp @@ -0,0 +1,111 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#include "cafPdmFieldScriptability.h" + +#include "cafPdmFieldHandle.h" + +using namespace caf; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldScriptability::PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership) +{ + m_IOWriteable = true; + m_owner = owner; + m_scriptFieldName = scriptFieldName; + owner->addCapability(this, giveOwnership); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmFieldScriptability::~PdmFieldScriptability() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString PdmFieldScriptability::scriptFieldName() const +{ + return m_scriptFieldName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmFieldScriptability::isIOWriteable() const +{ + return m_IOWriteable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmFieldScriptability::setIOWriteable(bool writeable) +{ + m_IOWriteable = writeable; +} + +//-------------------------------------------------------------------------------------------------- +/// Empty default implementation that doesn't offer any script IO for the field +//-------------------------------------------------------------------------------------------------- +void PdmFieldScriptability::readFromField(QTextStream& outputStream, bool quoteStrings /*= true*/, bool quoteNonBuiltins /*= false*/) const +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// Empty default implementation that doesn't offer any script IO for the field +//-------------------------------------------------------------------------------------------------- +void PdmFieldScriptability::writeToField(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, caf::PdmScriptIOMessages* errorMessageContainer, bool stringsAreQuoted /*= true*/) +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmFieldScriptability::addToField(caf::PdmFieldHandle* field, const QString& fieldName) +{ + if (field->template capability() == nullptr) + { + new PdmFieldScriptability(field, fieldName, true); + } +} diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.h b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.h new file mode 100644 index 0000000000..4d9a9daf0b --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmFieldScriptability.h @@ -0,0 +1,113 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include +#include "cafPdmFieldCapability.h" + +class QTextStream; + +namespace caf { + +class PdmFieldHandle; +class PdmObjectFactory; +class PdmScriptIOMessages; + +#define CAF_PDM_InitScriptableField( field, keyword, default, uiName, iconResourceName, toolTip, whatsThis ) \ + CAF_PDM_InitField( field, \ + keyword, \ + default, \ + uiName, \ + iconResourceName, \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \ + whatsThis ); \ + caf::PdmFieldScriptability::addToField( field, keyword ) + +#define CAF_PDM_InitScriptableFieldNoDefault( field, keyword, uiName, iconResourceName, toolTip, whatsThis ) \ + CAF_PDM_InitFieldNoDefault( field, \ + keyword, \ + uiName, \ + iconResourceName, \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \ + whatsThis ); \ + caf::PdmFieldScriptability::addToField( field, keyword ) + +#define CAF_PDM_InitScriptableFieldWithKeyword( field, keyword, scriptKeyword, default, uiName, iconResourceName, toolTip, whatsThis ) \ + CAF_PDM_InitField( field, \ + keyword, \ + default, \ + uiName, \ + iconResourceName, \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \ + whatsThis ); \ + caf::PdmFieldScriptability::addToField( field, scriptKeyword ) + +#define CAF_PDM_InitScriptableFieldWithKeywordNoDefault( field, keyword, scriptKeyword, uiName, iconResourceName, toolTip, whatsThis ) \ + CAF_PDM_InitFieldNoDefault( field, \ + keyword, \ + uiName, \ + iconResourceName, \ + caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \ + whatsThis ); \ + caf::PdmFieldScriptability::addToField( field, scriptKeyword ) + +class PdmFieldScriptability : public PdmFieldCapability +{ +public: + PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership); + virtual ~PdmFieldScriptability(); + + const QString scriptFieldName() const; + + bool isIOWriteable() const; + void setIOWriteable(bool writeable); + + virtual void readFromField(QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false) const; + virtual void writeToField(QTextStream& inputStream, + caf::PdmObjectFactory* objectFactory, + caf::PdmScriptIOMessages* errorMessageContainer, + bool stringsAreQuoted = true); + + static void addToField(caf::PdmFieldHandle* field, const QString& fieldName); +private: + caf::PdmFieldHandle* m_owner; + QString m_scriptFieldName; + bool m_IOWriteable; +}; + + +} + diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.cpp new file mode 100644 index 0000000000..06e867f71f --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.cpp @@ -0,0 +1,103 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#include "cafPdmObjectScriptabilityRegister.h" + +#include "cafPdmObject.h" + +using namespace caf; + +std::map PdmObjectScriptabilityRegister::s_classKeywordToScriptClassName; +std::map PdmObjectScriptabilityRegister::s_scriptClassNameToClassKeyword; +std::map PdmObjectScriptabilityRegister::s_scriptClassComments; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmObjectScriptabilityRegister::registerScriptClassNameAndComment(const QString& classKeyword, + const QString& scriptClassName, + const QString& scriptClassComment) +{ + s_classKeywordToScriptClassName[classKeyword] = scriptClassName; + s_scriptClassNameToClassKeyword[scriptClassName] = classKeyword; + s_scriptClassComments[classKeyword] = scriptClassComment; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(const QString& classKeyword) +{ + auto it = s_classKeywordToScriptClassName.find(classKeyword); + if (it != s_classKeywordToScriptClassName.end()) + { + return it->second; + } + return classKeyword; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmObjectScriptabilityRegister::classKeywordFromScriptClassName(const QString& scriptClassName) +{ + auto it = s_scriptClassNameToClassKeyword.find(scriptClassName); + if (it != s_scriptClassNameToClassKeyword.end()) + { + return it->second; + } + return scriptClassName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmObjectScriptabilityRegister::scriptClassComment(const QString& classKeyword) +{ + auto it = s_scriptClassComments.find(classKeyword); + if (it != s_scriptClassComments.end()) + { + return it->second; + } + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmObjectScriptabilityRegister::isScriptable(const caf::PdmObject* object) +{ + return s_classKeywordToScriptClassName.find(object->classKeyword()) != s_classKeywordToScriptClassName.end(); +} diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.h b/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.h new file mode 100644 index 0000000000..3d2ae96e20 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmObjectScriptabilityRegister.h @@ -0,0 +1,75 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include + +#include + + +#define CAF_PDM_InitScriptableObject( uiName, iconResourceName, toolTip, whatsThis ) \ + CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \ + caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), classKeyword(), whatsThis ); + +#define CAF_PDM_InitScriptableObjectWithNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \ + CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \ + caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), scriptClassName, scriptComment ); + +namespace caf { +class PdmObject; + +//================================================================================================== +/// Static register for object scriptability. +//================================================================================================== +class PdmObjectScriptabilityRegister +{ +public: + static void registerScriptClassNameAndComment(const QString& classKeyword, + const QString& scriptClassName, + const QString& scriptClassComment); + static QString scriptClassNameFromClassKeyword(const QString& classKeyword); + static QString classKeywordFromScriptClassName(const QString& scriptClassName); + static QString scriptClassComment(const QString& classKeyword); + + static bool isScriptable(const caf::PdmObject* object); + +private: + static std::map s_classKeywordToScriptClassName; + static std::map s_scriptClassNameToClassKeyword; + static std::map s_scriptClassComments; +}; + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp new file mode 100644 index 0000000000..5b4e7e6253 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.cpp @@ -0,0 +1,406 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#include "cafPdmPythonGenerator.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" +#include "cafPdmFieldScriptability.h" +#include "cafPdmObject.h" +#include "cafPdmObjectFactory.h" +#include "cafPdmObjectScriptabilityRegister.h" +#include "cafPdmProxyValueField.h" +#include "cafPdmXmlFieldHandle.h" + +#include +#include + +#include +#include +#include + +using namespace caf; + +CAF_PDM_CODE_GENERATOR_SOURCE_INIT(PdmPythonGenerator, "py"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const +{ + QString generatedCode; + QTextStream out(&generatedCode); + + std::vector classKeywords = factory->classKeywords(); + + std::vector> dummyObjects; + for (QString classKeyword : classKeywords) + { + auto objectHandle = factory->create(classKeyword); + const PdmObject* object = dynamic_cast(objectHandle); + CAF_ASSERT(object); + + std::shared_ptr sharedObject(object); + if (PdmObjectScriptabilityRegister::isScriptable(sharedObject.get())) + { + dummyObjects.push_back(sharedObject); + } + } + + // Sort to make sure super classes get created before sub classes + std::sort(dummyObjects.begin(), + dummyObjects.end(), + [](std::shared_ptr lhs, std::shared_ptr rhs) { + if (lhs->inheritsClassWithKeyword(rhs->classKeyword())) + { + return false; + } + return lhs->classKeyword() < rhs->classKeyword(); + }); + + std::map>> classAttributesGenerated; + std::map> classMethodsGenerated; + std::map classCommentsGenerated; + + // First generate all attributes and comments to go into each object + for (std::shared_ptr object : dummyObjects) + { + const std::list& classInheritanceStack = object->classInheritanceStack(); + + for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it) + { + const QString& classKeyword = *it; + QString scriptClassComment = PdmObjectScriptabilityRegister::scriptClassComment(classKeyword); + + std::map attributesGenerated; + + if (!scriptClassComment.isEmpty()) classCommentsGenerated[classKeyword] = scriptClassComment; + + if (classKeyword == object->classKeyword()) + { + std::vector fields; + object->fields(fields); + for (auto field : fields) + { + 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; + + if (classAttributesGenerated[field->ownerClass()].count(snake_field_name)) continue; + if (classMethodsGenerated[field->ownerClass()].count(snake_field_name)) continue; + + QVariant valueVariant = pdmValueField->toQVariant(); + + if (shouldBeMethod) + { + if (proxyField->hasGetter()) + { + QString fullComment = + QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"") + .arg(comment) + .arg(dataType); + + QString fieldCode = QString(" def %1(self):\n%2\n return " + "self._call_get_method(\"%3\")\n") + .arg(snake_field_name) + .arg(fullComment) + .arg(scriptability->scriptFieldName()); + classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode; + } + if (proxyField->hasSetter()) + { + QString fullComment = QString(" \"\"\"Set %1\n Arguments:\n" + " values (%2): data\n \"\"\"") + .arg(comment) + .arg(dataType); + + QString fieldCode = QString(" def set_%1(self, values):\n%2\n " + "self._call_set_method(\"%3\", values)\n") + .arg(snake_field_name) + .arg(fullComment) + .arg(scriptability->scriptFieldName()); + classMethodsGenerated[field->ownerClass()][QString("set_%1").arg(snake_field_name)] = + fieldCode; + } + } + else + { + QString valueString; + QTextStream valueStream(&valueString); + scriptability->readFromField(valueStream, true, true); + if (valueString.isEmpty()) + valueString = QString("\"\""); + valueString = pythonifyDataValue(valueString); + + QString fieldCode = QString(" self.%1 = %2\n").arg(snake_field_name).arg(valueString); + + QString fullComment = + QString("%1 (%2): %3\n").arg(snake_field_name).arg(dataType).arg(comment); + + classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode; + 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 fullComment = + QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"") + .arg(comment) + .arg(commentDataType); + + if (pdmChildField) + { + QString fieldCode = QString(" def %1(self):\n%2\n children = " + "self.children(\"%3\", %4)\n return children[0] if len(children) > 0 else None\n") + .arg(snake_field_name) + .arg(fullComment) + .arg(scriptability->scriptFieldName()) + .arg(scriptDataType); + classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode; + } + else + { + QString fieldCode = QString(" def %1(self):\n%2\n return " + "self.children(\"%3\", %4)\n") + .arg(snake_field_name) + .arg(fullComment) + .arg(scriptability->scriptFieldName()) + .arg(scriptDataType); + classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode; + } + } + } + } + } + } + } + + // Write out classes + std::set classesWritten; + for (std::shared_ptr object : dummyObjects) + { + const std::list& classInheritanceStack = object->classInheritanceStack(); + std::list scriptSuperClassNames; + + for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it) + { + const QString& classKeyword = *it; + QString scriptClassName = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(classKeyword); + if (scriptClassName.isEmpty()) scriptClassName = classKeyword; + + if (!classesWritten.count(scriptClassName)) + { + QString classCode; + if (scriptSuperClassNames.empty()) + { + classCode = QString("class %1:\n").arg(scriptClassName); + } + else + { + classCode = QString("class %1(%2):\n").arg(scriptClassName).arg(scriptSuperClassNames.back()); + } + if (!classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty()) + { + classCode += " \"\"\"\n"; + if (!classCommentsGenerated[classKeyword].isEmpty()) + { + if (!classCommentsGenerated[classKeyword].isEmpty()) + { + classCode += QString(" %1\n\n").arg(classCommentsGenerated[classKeyword]); + } + } + if (!classAttributesGenerated[classKeyword].empty()) + { + classCode += " Attributes\n"; + for (auto keyWordValuePair : classAttributesGenerated[classKeyword]) + { + classCode += " " + keyWordValuePair.second.second; + } + } + classCode += " \"\"\"\n"; + } + classCode += + QString(" __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n"); + + classCode += QString(" def __init__(self, pb2_object=None, channel=None):\n"); + if (!scriptSuperClassNames.empty()) + { + // Own attributes. This initializes a lot of attributes to None. + // This means it has to be done before we set any values. + for (auto keyWordValuePair : classAttributesGenerated[classKeyword]) + { + classCode += keyWordValuePair.second.first; + } + // Parent constructor + classCode += + QString(" %1.__init__(self, pb2_object, channel)\n").arg(scriptSuperClassNames.back()); + } + + classCode += QString(" if %1.__custom_init__ is not None:\n").arg(scriptClassName); + classCode += QString(" %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n") + .arg(scriptClassName); + + for (auto keyWordValuePair : classMethodsGenerated[classKeyword]) + { + classCode += "\n"; + classCode += keyWordValuePair.second; + classCode += "\n"; + } + + out << classCode << "\n"; + classesWritten.insert(scriptClassName); + } + scriptSuperClassNames.push_back(scriptClassName); + } + } + out << "def class_dict():\n"; + out << " classes = {}\n"; + for (QString classKeyword : classesWritten) + { + out << QString(" classes['%1'] = %1\n").arg(classKeyword); + } + out << " return classes\n\n"; + + out << "def class_from_keyword(class_keyword):\n"; + out << " all_classes = class_dict()\n"; + out << " if class_keyword in all_classes.keys():\n"; + out << " return all_classes[class_keyword]\n"; + out << " return None\n"; + + return generatedCode; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmPythonGenerator::camelToSnakeCase(const QString& camelString) +{ + static QRegularExpression re1("(.)([A-Z][a-z]+)"); + static QRegularExpression re2("([a-z0-9])([A-Z])"); + + QString snake_case = camelString; + snake_case.replace(re1, "\\1_\\2"); + snake_case.replace(re2, "\\1_\\2"); + return snake_case.toLower(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes) +{ + auto xmlObj = field->capability(); + + QString dataType = xmlObj->dataTypeName(); + + std::map builtins = + { {QString::fromStdString(typeid(double).name()), "float"}, + {QString::fromStdString(typeid(float).name()), "float"}, + {QString::fromStdString(typeid(int).name()), "int"}, + {QString::fromStdString(typeid(QString).name()), "str"} + }; + + bool foundBuiltin = false; + for (auto builtin : builtins) + { + if (dataType == builtin.first) + { + dataType.replace(builtin.first, builtin.second); + foundBuiltin = true; + } + } + + if (!foundBuiltin && useStrForUnknownDataTypes) + { + dataType = "str"; + } + + return dataType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmPythonGenerator::pythonifyDataValue(const QString& dataValue) +{ + QString outValue = dataValue; + outValue.replace("false", "False"); + outValue.replace("true", "True"); + return outValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmPythonGenerator::pythonHelpString(const QString& existingTooltip, const QString& keyword) +{ + QString snake_case = caf::PdmPythonGenerator::camelToSnakeCase(keyword); + + QString helpString = QString("Available through python/rips as the attribute '%1'").arg(snake_case); + + if (!existingTooltip.isEmpty()) return existingTooltip + "\n\n" + helpString; + return helpString; +} diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h new file mode 100644 index 0000000000..1c4f47eb00 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmPythonGenerator.h @@ -0,0 +1,60 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include "cafPdmCodeGenerator.h" + +namespace caf { + +class PdmFieldHandle; + +//================================================================================================== +/// Python skeleton generator from Project Data Model +//================================================================================================== +class PdmPythonGenerator : public PdmCodeGenerator +{ + CAF_PDM_CODE_GENERATOR_HEADER_INIT; +public: + QString generate(PdmObjectFactory* factory) const override; + static QString camelToSnakeCase(const QString& camelString); + static QString dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes); + + static QString pythonifyDataValue(const QString& dataValue); + static QString pythonHelpString(const QString& existingTooltip, const QString& keyword); + +}; + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.cpp b/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.cpp new file mode 100644 index 0000000000..003d4f41e7 --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.cpp @@ -0,0 +1,110 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#include "cafPdmScriptIOMessages.h" +#include + +using namespace caf; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmScriptIOMessages::addWarning( const QString& message ) +{ + m_messages.push_back( + std::make_pair( MESSAGE_WARNING, "Line " + QString::number( m_currentLineNumber ) + ": " + message ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmScriptIOMessages::addError( const QString& message ) +{ + m_messages.push_back( + std::make_pair( MESSAGE_ERROR, "Line " + QString::number( m_currentLineNumber ) + ": " + message ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmScriptIOMessages::skipWhiteSpaceWithLineNumberCount( QTextStream& inputStream ) +{ + while ( !inputStream.atEnd() ) + { + QChar ch = readCharWithLineNumberCount( inputStream ); + if ( !ch.isSpace() ) + { + inputStream.seek( inputStream.pos() - 1 ); + break; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QChar PdmScriptIOMessages::readCharWithLineNumberCount( QTextStream& inputStream ) +{ + QChar ch; + inputStream >> ch; + if ( ch == QChar( '\n' ) ) + { + m_currentLineNumber++; + } + return ch; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QChar PdmScriptIOMessages::peekNextChar( QTextStream& inputStream ) +{ + QChar ch; + if ( !inputStream.atEnd() ) + { + inputStream >> ch; + inputStream.seek( inputStream.pos() - 1 ); + } + return ch; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmScriptIOMessages::skipLineWithLineNumberCount( QTextStream& inputStream ) +{ + inputStream.readLine(); + m_currentLineNumber++; +} diff --git a/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.h b/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.h new file mode 100644 index 0000000000..6e2be995ad --- /dev/null +++ b/Fwk/AppFwk/cafPdmScripting/cafPdmScriptIOMessages.h @@ -0,0 +1,76 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include +#include + +class QTextStream; + +namespace caf { + +class PdmScriptIOMessages +{ +public: + PdmScriptIOMessages() + : m_currentLineNumber( 1 ) + { + } + + enum MessageType + { + MESSAGE_WARNING, + MESSAGE_ERROR + }; + + void addWarning( const QString& message ); + void addError( const QString& message ); + + void skipWhiteSpaceWithLineNumberCount( QTextStream& inputStream ); + void skipLineWithLineNumberCount( QTextStream& inputStream ); + + QChar readCharWithLineNumberCount( QTextStream& inputStream ); + QChar peekNextChar( QTextStream& inputStream ); + + QString currentCommand; + QString currentArgument; + std::vector> m_messages; + +private: + int m_currentLineNumber; +}; + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h index 26300dc3a4..06b1653979 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildField.h @@ -19,6 +19,7 @@ template< typename T> class PdmFieldXmlCap; class PdmChildFieldHandle : public PdmFieldHandle { public: + virtual void childObjects(std::vector* objects) = 0; virtual void setChildObject(PdmObjectHandle* object) = 0; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h index a3283fdfed..fc87743483 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h @@ -45,6 +45,7 @@ #include +#include #include @@ -62,6 +63,10 @@ template class PdmDataValueField : public PdmValueField { public: + // Type traits magic to check if a template argument is a vector + template struct is_vector : public std::false_type {}; + template struct is_vector> : public std::true_type {}; + typedef DataType FieldDataType; PdmDataValueField() {} PdmDataValueField(const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; } @@ -95,6 +100,7 @@ public: bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; } bool operator!= (const DataType& fieldValue) const { return m_fieldValue != fieldValue; } + protected: DataType m_fieldValue; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h index 1e2b1f9a63..1a801d3cb9 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmProxyValueField.h @@ -8,21 +8,40 @@ #include +#include +#include + namespace caf { +//================================================================================================== +/// Abstract non-templated base class for PdmProxyValueField +/// Exists only to be able to determine that a field is a proxy field +//================================================================================================== + +class PdmProxyFieldHandle : public PdmValueField +{ +public: + virtual bool isStreamingField() const = 0; + virtual bool hasGetter() const = 0; + virtual bool hasSetter() const = 0; +}; + //================================================================================================== /// Field class encapsulating data access through object setter/getter with input and output of this /// data to/from a QXmlStream /// read/write-FieldData is supposed to be specialized for types needing specialization //================================================================================================== - template -class PdmProxyValueField : public PdmValueField +class PdmProxyValueField : public PdmProxyFieldHandle { public: + // Type traits magic to check if a template argument is a vector + template struct is_vector : public std::false_type {}; + template struct is_vector> : public std::true_type {}; + typedef DataType FieldDataType; - PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; } + PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; } ~PdmProxyValueField() override { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; } // Assignment @@ -34,6 +53,10 @@ public: void setValue(const DataType& fieldValue) { CAF_ASSERT(isInitializedByInitFieldMacro()); if (m_valueSetter) m_valueSetter->setValue(fieldValue); } DataType value() const { CAF_ASSERT(m_valueGetter); return m_valueGetter->getValue(); } + bool isStreamingField() const override { return is_vector(); } + bool hasGetter() const override { return m_valueGetter != nullptr; } + bool hasSetter() const override { return m_valueSetter != nullptr; } + // Implementation of PdmValueField interface QVariant toQVariant() const override { DataType val = value(); return PdmValueFieldSpecialization::convert(val); } @@ -130,6 +153,7 @@ private: SetValueInterface* m_valueSetter; GetValueInterface* m_valueGetter; + }; } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h index 166caf349c..570f9221d9 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h @@ -3,6 +3,8 @@ #include "cafInternalPdmXmlFieldReaderWriter.h" #include "cafPdmXmlFieldHandle.h" +#include + namespace caf { @@ -10,7 +12,15 @@ template < typename FieldType> class PdmFieldXmlCap : public PdmXmlFieldHandle { public: - PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; } + // Type traits magic to check if a template argument is a vector + template struct is_vector : public std::false_type {}; + template struct is_vector> : public std::true_type {}; + + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) + { + m_field = field; + m_dataTypeName = QString("%1").arg(typeid(FieldType).name()); + } // Xml Serializing public: @@ -18,11 +28,12 @@ public: void writeFieldData(QXmlStreamWriter& xmlStream) const override; bool resolveReferences() override; + bool isVectorField() const; + private: FieldType* m_field; }; - template class PdmPtrField; template < typename DataType> @@ -33,7 +44,7 @@ public: PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; - m_childClassKeyword = DataType::classKeywordStatic(); + m_dataTypeName = DataType::classKeywordStatic(); m_isResolved = false; m_referenceString = ""; } @@ -63,7 +74,7 @@ public: PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; - m_childClassKeyword = DataType::classKeywordStatic(); + m_dataTypeName = DataType::classKeywordStatic(); m_isResolved = false; m_referenceString = ""; } @@ -73,7 +84,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; @@ -90,7 +101,7 @@ class PdmFieldXmlCap< PdmChildField > : public PdmXmlFieldHandle { typedef PdmChildField FieldType; public: - PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic(); } + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_dataTypeName = DataType::classKeywordStatic(); } // Xml Serializing public: @@ -110,13 +121,14 @@ class PdmFieldXmlCap< PdmChildArrayField > : public PdmXmlFieldHandle { typedef PdmChildArrayField FieldType; public: - PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic();} + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_dataTypeName = DataType::classKeywordStatic();} // Xml Serializing 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 137b8e3525..a00b7da813 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl @@ -15,6 +15,16 @@ namespace caf /// //================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template < typename FieldType> +bool caf::PdmFieldXmlCap::isVectorField() const +{ + return is_vector(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -208,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<> @@ -422,4 +440,13 @@ bool caf::PdmFieldXmlCap>::resolveReferences return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template < typename DataType> +bool caf::PdmFieldXmlCap< caf::PdmChildArrayField >::isVectorField() const +{ + return true; +} + } // End namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h index 2c20223293..77ef8b01fb 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h @@ -87,7 +87,7 @@ public: return true; } - std::vector classKeywords() const; + std::vector classKeywords() const override; private: PdmDefaultObjectFactory() {} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h index d758c4bbcb..9c2ae69de5 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmObjectFactory.h @@ -37,6 +37,8 @@ #pragma once +#include + class QString; namespace caf @@ -56,7 +58,7 @@ class PdmObjectFactory public: virtual PdmObjectHandle* create(const QString& classNameKeyword) = 0; - + virtual std::vector classKeywords() const = 0; protected: PdmObjectFactory() {} virtual ~PdmObjectFactory() {} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp index e876afcaff..693520d726 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.cpp @@ -53,12 +53,14 @@ void PdmXmlFieldHandle::disableIO() //-------------------------------------------------------------------------------------------------- /// Returns the classKeyword of the child class type, if this field is supposed to contain pointers -/// to PdmObjectHandle derived onbjects. -/// Returns empty string if the field is not containig some PdmObjectHandle type +/// to PdmObjectHandle derived objects. +/// Returns typeid(DataType).name() if the field is not containing some PdmObjectHandle type. +/// Warning: typeid(DataType).name() is compiler implementation specific and thus you should not +/// Compare this with a predefined literal, like "double" or "float". Instead compare with typeid(double).name(). //-------------------------------------------------------------------------------------------------- -QString PdmXmlFieldHandle::childClassKeyword() +QString PdmXmlFieldHandle::dataTypeName() const { - return m_childClassKeyword; + return m_dataTypeName; } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h index f81b83755b..06a31dd32e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h @@ -33,12 +33,14 @@ public: bool isIOWritable() const { return m_isIOWritable; } bool isCopyable() const { return m_isCopyable;} + virtual bool isVectorField() const { return false; } + void disableIO(); void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } void setCopyable(bool isCopyable) { m_isCopyable = isCopyable; } - QString childClassKeyword(); + QString dataTypeName() const; virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0; virtual void writeFieldData(QXmlStreamWriter& xmlStream) const = 0; @@ -49,7 +51,7 @@ public: protected: bool assertValid() const; - QString m_childClassKeyword; ///< Must be set in constructor of derived XmlFieldHandle + QString m_dataTypeName; ///< Must be set in constructor of derived XmlFieldHandle private: bool m_isIOReadable; diff --git a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h index e1e57bc5fb..6c931e5600 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h +++ b/Fwk/AppFwk/cafVizExtensions/cafCategoryLegend.h @@ -46,9 +46,10 @@ protected: charHeight = 0.0f; lineSpacing = 0.0f; margins = cvf::Vec2f::ZERO; - tickEndX = 0.0f; tickStartX = 0.0f; tickMidX = 0.0f; + tickEndX = 0.0f; + tickTextLeadSpace = 0.0f; overallLegendSize = setSize; } diff --git a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h index 60d7553b6f..695f2cf7e3 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h +++ b/Fwk/AppFwk/cafVizExtensions/cafOverlayScalarMapperLegend.h @@ -97,6 +97,14 @@ protected: { OverlayColorLegendLayoutInfo(const Vec2ui& setSize) { + charHeight = 0.0f; + lineSpacing = 0.0f; + margins = cvf::Vec2f::ZERO; + tickStartX = 0.0f; + tickMidX = 0.0f; + tickEndX = 0.0f; + tickTextLeadSpace = 0.0f; + overallLegendSize = setSize; } diff --git a/Fwk/AppFwk/cafVizExtensions/cafOverlayScaleLegend.h b/Fwk/AppFwk/cafVizExtensions/cafOverlayScaleLegend.h index 6f3ec84077..30d6b545a4 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafOverlayScaleLegend.h +++ b/Fwk/AppFwk/cafVizExtensions/cafOverlayScaleLegend.h @@ -112,6 +112,17 @@ protected: LayoutInfo(const Vec2ui& setSize) { + charWidth = 0.0f; + charHeight = 0.0f; + lineSpacing = 0.0f; + margins = cvf::Vec2f::ZERO; + tickTextLeadSpace = 0.0f; + + axisStartPt = cvf::Vec2f::ZERO; + axisLength = 0.0f; + majorTickSize = 0.0f; + minorTickSize = 0.0f; + overallLegendSize = setSize; } diff --git a/Fwk/CMakeLists.txt b/Fwk/CMakeLists.txt index 4b00e6a77e..5538062f68 100644 --- a/Fwk/CMakeLists.txt +++ b/Fwk/CMakeLists.txt @@ -19,6 +19,7 @@ add_subdirectory(AppFwk/cafProjectDataModel/cafPdmXml) add_subdirectory(AppFwk/cafProjectDataModel) add_subdirectory(AppFwk/cafCommand) add_subdirectory(AppFwk/cafUserInterface) +add_subdirectory(AppFwk/cafPdmScripting) # Unit Tests add_subdirectory(AppFwk/cafProjectDataModel/cafProjectDataModel_UnitTests) diff --git a/vcpkg b/vcpkg new file mode 160000 index 0000000000..6282cab61d --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 6282cab61d175974b1af06473db584b9b80dcd48 diff --git a/vcpkg_x64-linux.txt b/vcpkg_x64-linux.txt new file mode 100644 index 0000000000..bc27b0025a --- /dev/null +++ b/vcpkg_x64-linux.txt @@ -0,0 +1,3 @@ +grpc +--triplet +x64-linux diff --git a/vcpkg_x64-windows.txt b/vcpkg_x64-windows.txt new file mode 100644 index 0000000000..0bac3fa88b --- /dev/null +++ b/vcpkg_x64-windows.txt @@ -0,0 +1,3 @@ +grpc +--triplet +x64-windows