#4423 First implementation of PdmObject exchange

This commit is contained in:
Gaute Lindkvist
2019-06-10 20:42:20 +02:00
parent b70c88330a
commit 439913b7b1
29 changed files with 730 additions and 228 deletions

View File

@@ -26,6 +26,9 @@
CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis); \
AddRicfCapabilityToField(field)
#define RICF_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \
CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis); \
AddRicfCapabilityToField(field)
//==================================================================================================
//

View File

@@ -19,7 +19,9 @@
#include "RicfFieldCapability.h"
#include "RicfMessages.h"
#include "RiaColorTools.h"
#include <QColor>
//--------------------------------------------------------------------------------------------------
@@ -130,3 +132,28 @@ void RicfFieldWriter<bool>::writeFieldData(const bool& fieldValue, QTextStream&
// Lower-case true/false is used in the documentation.
outputStream << (fieldValue ? "true" : "false");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfFieldReader<cvf::Color3f>::readFieldData(cvf::Color3f& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer)
{
QString fieldStringValue;
RicfFieldReader<QString>::readFieldData(fieldStringValue, inputStream, errorMessageContainer);
if (QColor::isValidColor(fieldStringValue))
{
QColor qColor(fieldStringValue);
fieldValue = RiaColorTools::fromQColorTo3f(qColor);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfFieldWriter<cvf::Color3f>::writeFieldData(const cvf::Color3f& fieldValue, QTextStream& outputStream)
{
QColor qColor = RiaColorTools::toQColor(fieldValue);
QString fieldStringValue = qColor.name();
RicfFieldWriter<QString>::writeFieldData(fieldStringValue, outputStream);
}

View File

@@ -22,6 +22,8 @@
#include "RicfMessages.h"
#include "cafAppEnum.h"
#include "cvfBase.h"
#include "cvfColor3.h"
#include <QTextStream>
#include <QString>
@@ -77,6 +79,17 @@ struct RicfFieldWriter<bool>
static void writeFieldData(const bool& fieldValue, QTextStream& outputStream);
};
template<>
struct RicfFieldReader<cvf::Color3f>
{
static void readFieldData(cvf::Color3f& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer);
};
template<>
struct RicfFieldWriter<cvf::Color3f>
{
static void writeFieldData(const cvf::Color3f& fieldValue, QTextStream& outputStream);
};
template <typename T>
struct RicfFieldReader< caf::AppEnum<T> >

View File

@@ -11,6 +11,7 @@ set ( SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPdmObjectService.h
)
set ( SOURCE_GROUP_SOURCE_FILES
@@ -22,6 +23,7 @@ set ( SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPdmObjectService.cpp
)
add_definitions(-DENABLE_GRPC)
@@ -76,6 +78,7 @@ endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
# Proto files
set(PROTO_FILES
"Empty"
"PdmObject"
"Case"
"Project"
"Commands"
@@ -156,7 +159,7 @@ if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
"rips/Project.py"
"rips/Properties.py"
"rips/Instance.py"
"rips/examples/AppInfo.py"
"rips/PdmObject.py"
"rips/examples/InstanceExample.py"
"rips/examples/CommandExample.py"
"rips/examples/CaseInfoStreamingExample.py"

View File

@@ -1,206 +0,0 @@
cmake_minimum_required (VERSION 2.8.12)
set ( SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCallbacks.inl
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCaseService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcGridService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.h
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.h
)
set ( SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServer.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcServiceInterface.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCaseService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcGridService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcProjectService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcCommandService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcAppService.cpp
${CMAKE_CURRENT_LIST_DIR}/RiaGrpcPropertiesService.cpp
)
add_definitions(-DENABLE_GRPC)
if (MSVC)
add_definitions(-D_WIN32_WINNT=0x600)
# Find Protobuf installation
# Looks for protobuf-config.cmake file installed by Protobuf's cmake installation.
set(protobuf_MODULE_COMPATIBLE ON CACHE DBOOL "")
find_package(Protobuf CONFIG 3.0 QUIET)
if (Protobuf_FOUND)
message(STATUS "Using protobuf ${protobuf_VERSION}")
else()
message(FATAL_ERROR "Protocol Buffers not found. This is required to build with gRPC")
endif()
# Find gRPC installation
# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.
find_package(gRPC CONFIG REQUIRED NO_MODULE)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
set(_GRPC_GRPCPP_UNSECURE gRPC::grpc++_unsecure gRPC::grpc_unsecure gRPC::gpr)
set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
set(GRPC_LIBRARIES ${_GRPC_GRPCPP_UNSECURE} ${_PROTOBUF_LIBPROTOBUF})
set_target_properties(${GRPC_LIBRARIES} PROPERTIES
MAP_IMPORTED_CONFIG_MINSIZEREL RELEASE
MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELEASE
)
else()
if (NOT DEFINED GRPC_INSTALL_PREFIX OR NOT EXISTS ${GRPC_INSTALL_PREFIX})
message(FATAL_ERROR "You need a valid GRPC_INSTALL_PREFIX set to build with gRPC")
endif()
set(ENV{PKG_CONFIG_PATH} "${GRPC_INSTALL_PREFIX}/lib/pkgconfig")
find_package(PkgConfig REQUIRED)
pkg_check_modules(GRPC REQUIRED grpc++_unsecure>=1.20 grpc_unsecure gpr protobuf)
set(_PROTOBUF_PROTOC "${GRPC_INSTALL_PREFIX}/bin/protoc")
set(_GRPC_CPP_PLUGIN_EXECUTABLE "${GRPC_INSTALL_PREFIX}/bin/grpc_cpp_plugin")
include_directories(AFTER ${GRPC_INCLUDE_DIRS})
endif()
# Cannot use the nice new FindPackage modules for python since that is CMake 3.12+
if(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
message(STATUS "Using Python ${PYTHON_EXECUTABLE}")
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
# Proto files
set(PROTO_FILES
"Empty"
"Case"
"Project"
"Commands"
"App"
"Properties"
"Grid"
)
set(GRPC_PYTHON_SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}/Python")
set(GRPC_PYTHON_DEST_PATH "${CMAKE_BINARY_DIR}/Python")
foreach(proto_file ${PROTO_FILES})
get_filename_component(rips_proto "${CMAKE_CURRENT_LIST_DIR}/GrpcProtos/${proto_file}.proto" ABSOLUTE)
get_filename_component(rips_proto_path "${rips_proto}" PATH)
list(APPEND GRPC_PROTO_FILES_FULL_PATH ${rips_proto})
set(rips_proto_srcs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.pb.cc")
set(rips_proto_hdrs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.pb.h")
set(rips_grpc_srcs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.grpc.pb.cc")
set(rips_grpc_hdrs "${CMAKE_BINARY_DIR}/Generated/${proto_file}.grpc.pb.h")
add_custom_command(
OUTPUT "${rips_proto_srcs}" "${rips_proto_hdrs}" "${rips_grpc_srcs}" "${rips_grpc_hdrs}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --grpc_out "${CMAKE_BINARY_DIR}/Generated"
--cpp_out "${CMAKE_BINARY_DIR}/Generated"
-I "${rips_proto_path}"
--plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}"
"${rips_proto}"
DEPENDS "${rips_proto}"
)
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
set(rips_proto_python "generated/${proto_file}_pb2.py")
set(rips_grpc_python "generated/${proto_file}_pb2_grpc.py")
add_custom_command(
OUTPUT "${GRPC_PYTHON_SOURCE_PATH}/${rips_proto_python}" "${GRPC_PYTHON_SOURCE_PATH}/${rips_grpc_python}"
COMMAND ${PYTHON_EXECUTABLE}
ARGS -m grpc_tools.protoc
-I "${rips_proto_path}"
--python_out "${GRPC_PYTHON_SOURCE_PATH}/generated"
--grpc_python_out "${GRPC_PYTHON_SOURCE_PATH}/generated"
"${rips_proto}"
DEPENDS "${rips_proto}"
COMMENT "Generating ${rips_proto_python} and ${rips_grpc_python}"
VERBATIM
)
list (APPEND GRPC_PYTHON_GENERATED_SOURCES
${rips_proto_python}
${rips_grpc_python}
)
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
list( APPEND GRPC_HEADER_FILES
${rips_proto_hdrs}
${rips_grpc_hdrs}
)
list( APPEND GRPC_CPP_SOURCES
${rips_proto_srcs}
${rips_grpc_srcs}
)
endforeach(proto_file)
if (PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
list(APPEND GRPC_PYTHON_SOURCES
${GRPC_PYTHON_GENERATED_SOURCES}
"generated/RiaVersionInfo.py"
"rips/__init__.py"
"rips/App.py"
"rips/Case.py"
"rips/Commands.py"
"rips/Grid.py"
"rips/Project.py"
"rips/Properties.py"
"rips/Instance.py"
"examples/CommandExample.py"
"examples/CaseInfoStreamingExample.py"
"examples/SoilPorvAsync.py"
"examples/SoilPorvSync.py"
"examples/SelectedCases.py"
"examples/AllCases.py"
"examples/SetGridProperties.py"
"examples/GridInformation.py"
"examples/InputPropTestSync.py"
"examples/InputPropTestAsync.py"
"examples/SoilAverage.py"
"examples/SoilAverageNoComm.py"
"tests/test_cases.py"
<<<<<<< Updated upstream
"tests/test_commands.py"
=======
>>>>>>> Stashed changes
"tests/test_grids.py"
"tests/test_properties.py"
"tests/conftest.py"
"tests/dataroot.py"
"requirements.txt"
"setup.py.cmake"
"README.md"
"LICENSE"
)
foreach(PYTHON_SCRIPT ${GRPC_PYTHON_SOURCES})
list(APPEND GRPC_PYTHON_SOURCES_FULL_PATH "${GRPC_PYTHON_SOURCE_PATH}/${PYTHON_SCRIPT}")
endforeach()
if (MSVC)
source_group(TREE ${GRPC_PYTHON_SOURCE_PATH} FILES ${GRPC_PYTHON_SOURCES_FULL_PATH} PREFIX "GrpcInterface\\Python")
endif(MSVC)
endif(PYTHON_EXECUTABLE AND EXISTS ${PYTHON_EXECUTABLE})
list ( APPEND GRPC_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list ( APPEND GRPC_CPP_SOURCES ${SOURCE_GROUP_SOURCE_FILES})
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/ApplicationCode/Adm/RiaVersionInfo.py.cmake
${GRPC_PYTHON_SOURCE_PATH}/generated/RiaVersionInfo.py
)
CONFIGURE_FILE( ${GRPC_PYTHON_SOURCE_PATH}/setup.py.cmake
${GRPC_PYTHON_SOURCE_PATH}/setup.py
)
source_group( "GrpcInterface" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.cmake )
source_group( "GrpcInterface\\GrpcProtos" FILES ${GRPC_PROTO_FILES_FULL_PATH} )

View File

@@ -1,5 +1,7 @@
syntax = "proto3";
import "PdmObject.proto";
package rips;
service Case
@@ -11,6 +13,7 @@ service Case
rpc GetTimeSteps(CaseRequest) returns (TimeStepDates) {}
rpc GetDaysSinceStart(CaseRequest) returns (DaysSinceStart) {}
rpc GetCaseInfo(CaseRequest) returns (CaseInfo) {}
rpc GetPdmObject(CaseRequest) returns (PdmObject) {}
}
message CaseRequest {

View File

@@ -0,0 +1,37 @@
syntax = "proto3";
import "Empty.proto";
package rips;
service PdmObjectService
{
rpc GetDescendantPdmObjects(PdmChildObjectRequest) returns (PdmObjectArray) {}
rpc GetChildPdmObjects(PdmChildObjectRequest) returns (PdmObjectArray) {}
rpc GetAncestorPdmObject(PdmParentObjectRequest) returns (PdmObject) {}
rpc UpdateExistingPdmObject(PdmObject) returns (Empty) {}
}
message PdmChildObjectRequest
{
PdmObject object = 1;
string child_keyword = 2;
}
message PdmParentObjectRequest
{
PdmObject object = 1;
string parent_keyword = 2;
}
message PdmObject
{
string class_keyword = 1;
uint64 address = 2;
map<string, string> parameters = 3;
}
message PdmObjectArray
{
repeated PdmObject objects = 1;
}

View File

@@ -1,7 +1,8 @@
syntax = "proto3";
import "Case.proto";
import "Empty.proto";
import "Case.proto";
import "PdmObject.proto";
package rips;
@@ -11,4 +12,5 @@ service Project {
rpc GetAllCaseGroups(Empty) returns (CaseGroups) {}
rpc GetAllCases(Empty) returns (CaseInfoArray) {}
rpc GetCasesInGroup(CaseGroup) returns (CaseInfoArray) {}
rpc GetPdmObject(Empty) returns (PdmObject) {}
}

View File

@@ -3,13 +3,15 @@ import os
import sys
from .Grid import Grid
from .Properties import Properties
from .PdmObject import PdmObject
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
import Case_pb2
import Case_pb2_grpc
import PdmObject_pb2
class Case:
class Case (PdmObject):
"""ResInsight case class
Operate on a ResInsight case specified by a Case Id integer.
@@ -31,6 +33,7 @@ class Case:
self.type = info.type
self.properties = Properties(self)
self.request = Case_pb2.CaseRequest(id=self.id)
PdmObject.__init__(self, self.stub.GetPdmObject(self.request), self.channel)
def gridCount(self):
"""Get number of grids in the case"""
@@ -104,4 +107,7 @@ class Case:
def daysSinceStart(self):
"""Get a list of decimal values representing days since the start of the simulation"""
return self.stub.GetDaysSinceStart(self.request).day_decimals
def views(self):
return self.children("ReservoirView")

View File

@@ -69,8 +69,7 @@ class Instance:
parameters.append("--console")
pid = os.spawnv(os.P_NOWAIT, resInsightExecutable, parameters)
if pid:
instance = Instance(port=port)
instance.launched = True
instance = Instance(port=port, launched=True)
return instance
return None
@@ -93,7 +92,7 @@ class Instance:
for tryPort in range(startPort, endPort):
if Instance.__is_port_in_use(tryPort):
return Instance(tryPort)
return Instance(port=tryPort)
print('Error: Could not find any ResInsight instances responding between ports ' + str(startPort) + ' and ' + str(endPort))
return None
@@ -106,7 +105,7 @@ class Instance:
except grpc.RpcError as e:
return False, False
def __init__(self, port = 50051):
def __init__(self, port = 50051, launched = False):
""" Attempts to connect to ResInsight at aa specific port on localhost
Args:
@@ -116,7 +115,7 @@ class Instance:
location = "localhost:" + str(port)
self.channel = grpc.insecure_channel(location)
self.launched = False
self.launched = launched
# Main version check package
self.app = App(self.channel)

View File

@@ -0,0 +1,78 @@
import grpc
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
from Empty_pb2 import Empty
import PdmObject_pb2
import PdmObject_pb2_grpc
class PdmObject:
def __init__(self, pb2Object, channel):
self.pb2Object = pb2Object
self.channel = channel
self.stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self.channel)
def address(self):
return self.pb2Object.address
def classKeyword(self):
return self.pb2Object.class_keyword
def keywords(self):
listOfKeywords = []
for keyword in self.pb2Object.parameters:
listOfKeywords.append(keyword)
return listOfKeywords
def getValue(self, keyword):
value = self.pb2Object.parameters[keyword]
if value.lower() == 'false':
return False
elif value.lower() == 'true':
return True
else:
try:
intVal = int(value)
return intVal
except ValueError:
try:
floatVal = float(value)
return floatVal
except ValueError:
return value
def setValue(self, keyword, value):
if isinstance(value, bool):
if value:
self.pb2Object.parameters[keyword] = "true"
else:
self.pb2Object.parameters[keyword] = "false"
elif isinstance(value, str):
self.pb2Object.parameters[keyword] = "\"" + str(value) + "\""
else:
self.pb2Object.parameters[keyword] = str(value)
def descendants(self, classKeyword):
request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2Object, child_keyword=classKeyword)
objectList = self.stub.GetDescendantPdmObjects(request).objects
childList = []
for object in objectList:
childList.append(PdmObject(object, self.channel))
return childList
def children(self, classKeyword):
request = PdmObject_pb2.PdmChildObjectRequest(object=self.pb2Object, child_keyword=classKeyword)
objectList = self.stub.GetChildPdmObjects(request).objects
childList = []
for object in objectList:
childList.append(PdmObject(object, self.channel))
return childList
def ancestor(self, classKeyword):
request = PdmObject_pb2.PdmParentObjectRequest(object=self.pb2Object, parent_keyword=classKeyword)
return PdmObject(self.stub.GetAncestorPdmObject(request), self.channel)
def update(self):
self.stub.UpdateExistingPdmObject(self.pb2Object)

View File

@@ -4,6 +4,7 @@ import sys
from .Case import Case
from .Commands import Commands
from .PdmObject import PdmObject
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
@@ -11,7 +12,7 @@ from Empty_pb2 import Empty
import Project_pb2
import Project_pb2_grpc
class Project:
class Project (PdmObject):
"""ResInsight project. Not intended to be created separately.
Automatically created and assigned to Instance.
@@ -19,6 +20,7 @@ class Project:
def __init__(self, channel):
self.channel = channel
self.project = Project_pb2_grpc.ProjectStub(channel)
PdmObject.__init__(self, self.project.GetPdmObject(Empty()), self.channel)
def open(self, path):
"""Open a new project from the given path

View File

@@ -11,3 +11,33 @@ if resInsight is not None:
print ("Got " + str(len(cases)) + " cases: ")
for case in cases:
print(case.name)
assert(case.address() is not 0)
assert(case.classKeyword() == "EclipseCase")
print("\n#### Case ####")
for keyword in case.keywords():
print (keyword + ": " + case.getValue(keyword))
print ("\n####Project#####")
pdmProject = case.ancestor(classKeyword="ResInsightProject")
assert(pdmProject)
assert(pdmProject.address() is not 0)
assert(pdmProject.address() == resInsight.project.address())
for keyword in resInsight.project.keywords():
print (keyword + ": " + resInsight.project.getValue(keyword))
pdmViews = resInsight.project.descendants(classKeyword="ReservoirView")
for view in pdmViews:
print ("\n####View####")
print(view.classKeyword(), view.address())
for viewKeyword in view.keywords():
print(viewKeyword + "-> " + str(view.getValue(viewKeyword)))
view.setValue("ShowGridBox", not view.getValue("ShowGridBox"))
view.setValue("ViewBackgroundColor", "#3388AA")
view.update()
print ("\n####Cell Result####")
cellResults = view.children(classKeyword="ResultSlot")
for resultKeyword in cellResults[0].keywords():
print(resultKeyword + "->" + str(cellResults[0].getValue(resultKeyword)))
cellResults[0].setValue("ResultVariable", "SOIL")
cellResults[0].setValue("ResultType", "DYNAMIC_NATIVE")
cellResults[0].update()

View File

@@ -50,6 +50,18 @@ def test_10k(rips_instance, initializeTest):
daysSinceStart = case.daysSinceStart()
assert(len(daysSinceStart) == 9)
def test_PdmObject(rips_instance, initializeTest):
casePath = dataroot.PATH + "/TEST10K_FLT_LGR_NNC/TEST10K_FLT_LGR_NNC.EGRID"
case = rips_instance.project.loadCase(path=casePath)
pdmObject = case.pdmObject()
assert(pdmObject.address is not 0)
assert(pdmObject.class_keyword == "EclipseCase")
assert(pdmObject.parameters['CaseFileName'] == casePath)
assert(int(pdmObject.parameters['CaseId']) == 0)
for keyword in pdmObject.parameters:
print (keyword + ": " + pdmObject.parameters[keyword])
@pytest.mark.skipif(sys.platform.startswith('linux'), reason="Brugge is currently exceptionally slow on Linux")
def test_brugge_0010(rips_instance, initializeTest):
casePath = dataroot.PATH + "/Case_with_10_timesteps/Real10/BRUGGE_0010.EGRID"

View File

@@ -334,6 +334,21 @@ grpc::Status
return Status(grpc::NOT_FOUND, "No cases found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status
RiaGrpcCaseService::GetPdmObject(grpc::ServerContext* context, const rips::CaseRequest* request, rips::PdmObject* reply)
{
RimCase* rimCase = findCase(request->id());
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>(rimCase);
if (eclipseCase)
{
copyPdmObjectFromCafToRips(eclipseCase, reply);
}
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -357,6 +372,7 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcCaseService::createCallbacks()
new RiaGrpcUnaryCallback<Self, CaseRequest, TimeStepDates>(this, &Self::GetTimeSteps, &Self::RequestGetTimeSteps),
new RiaGrpcUnaryCallback<Self, CaseRequest, DaysSinceStart>(this, &Self::GetDaysSinceStart, &Self::RequestGetDaysSinceStart),
new RiaGrpcUnaryCallback<Self, CaseRequest, CaseInfo>(this, &Self::GetCaseInfo, &Self::RequestGetCaseInfo),
new RiaGrpcUnaryCallback<Self, CaseRequest, PdmObject>(this, &Self::GetPdmObject, &Self::RequestGetPdmObject),
new RiaGrpcServerStreamCallback<Self, CellInfoRequest, CellInfoArray, RiaActiveCellInfoStateHandler>(
this, &Self::GetCellInfoForActiveCells, &Self::RequestGetCellInfoForActiveCells, new RiaActiveCellInfoStateHandler)};
}

View File

@@ -27,6 +27,7 @@
namespace rips
{
class CaseRequest;
class PdmObject;
}
class RiaGrpcCallbackInterface;
@@ -74,7 +75,7 @@ public:
grpc::Status GetTimeSteps(grpc::ServerContext* context, const rips::CaseRequest* request, rips::TimeStepDates* reply) override;
grpc::Status GetDaysSinceStart(grpc::ServerContext* context, const rips::CaseRequest* request, rips::DaysSinceStart* reply) override;
grpc::Status GetCaseInfo(grpc::ServerContext* context, const rips::CaseRequest* request, rips::CaseInfo* reply) override;
grpc::Status GetPdmObject(grpc::ServerContext* context, const rips::CaseRequest* request, rips::PdmObject* reply) override;
grpc::Status GetCellInfoForActiveCells(grpc::ServerContext* context,
const rips::CellInfoRequest* request,
rips::CellInfoArray* reply,

View File

@@ -0,0 +1,192 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
//////////////////////////////////////////////////////////////////////////////////
#include "RiaGrpcPdmObjectService.h"
#include "RiaApplication.h"
#include "RiaGrpcCallbacks.h"
#include "Rim3dView.h"
#include "RimEclipseResultDefinition.h"
#include "RimProject.h"
#include "cafPdmObject.h"
using namespace rips;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::GetAncestorPdmObject(grpc::ServerContext* context,
const rips::PdmParentObjectRequest* request,
rips::PdmObject* reply)
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
project->descendantsIncludingThisFromClassKeyword(QString::fromStdString(request->object().class_keyword()),
objectsOfCurrentClass);
caf::PdmObject* matchingObject = nullptr;
for (caf::PdmObject* testObject : objectsOfCurrentClass)
{
if (reinterpret_cast<uint64_t>(testObject) == request->object().address())
{
matchingObject = testObject;
}
}
if (matchingObject)
{
caf::PdmObject* parentObject = nullptr;
matchingObject->firstAncestorOrThisFromClassKeyword(QString::fromStdString(request->parent_keyword()), parentObject);
if (parentObject)
{
copyPdmObjectFromCafToRips(parentObject, reply);
return grpc::Status::OK;
}
}
return grpc::Status(grpc::NOT_FOUND, "Parent PdmObject not found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::GetDescendantPdmObjects(grpc::ServerContext* context,
const rips::PdmChildObjectRequest* request,
rips::PdmObjectArray* reply)
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
project->descendantsIncludingThisFromClassKeyword(QString::fromStdString(request->object().class_keyword()),
objectsOfCurrentClass);
caf::PdmObject* matchingObject = nullptr;
for (caf::PdmObject* testObject : objectsOfCurrentClass)
{
if (reinterpret_cast<uint64_t>(testObject) == request->object().address())
{
matchingObject = testObject;
}
}
if (matchingObject)
{
std::vector<caf::PdmObject*> childObjects;
matchingObject->descendantsIncludingThisFromClassKeyword(QString::fromStdString(request->child_keyword()), childObjects);
for (auto pdmChild : childObjects)
{
rips::PdmObject* ripsChild = reply->add_objects();
copyPdmObjectFromCafToRips(pdmChild, ripsChild);
}
return grpc::Status::OK;
}
return grpc::Status(grpc::NOT_FOUND, "Current PdmObject not found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::GetChildPdmObjects(grpc::ServerContext* context,
const rips::PdmChildObjectRequest* request,
rips::PdmObjectArray* reply)
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
project->descendantsIncludingThisFromClassKeyword(QString::fromStdString(request->object().class_keyword()),
objectsOfCurrentClass);
caf::PdmObject* matchingObject = nullptr;
for (caf::PdmObject* testObject : objectsOfCurrentClass)
{
if (reinterpret_cast<uint64_t>(testObject) == request->object().address())
{
matchingObject = testObject;
}
}
if (matchingObject)
{
std::vector<caf::PdmObject*> childObjects;
matchingObject->childrenFromClassKeyword(QString::fromStdString(request->child_keyword()), childObjects);
for (auto pdmChild : childObjects)
{
rips::PdmObject* ripsChild = reply->add_objects();
copyPdmObjectFromCafToRips(pdmChild, ripsChild);
}
return grpc::Status::OK;
}
return grpc::Status(grpc::NOT_FOUND, "Current PdmObject not found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcPdmObjectService::UpdateExistingPdmObject(grpc::ServerContext* context,
const rips::PdmObject* request,
rips::Empty* response)
{
RimProject* project = RiaApplication::instance()->project();
std::vector<caf::PdmObject*> objectsOfCurrentClass;
project->descendantsIncludingThisFromClassKeyword(QString::fromStdString(request->class_keyword()), objectsOfCurrentClass);
caf::PdmObject* matchingObject = nullptr;
for (caf::PdmObject* pdmObject : objectsOfCurrentClass)
{
if (reinterpret_cast<uint64_t>(pdmObject) == request->address())
{
matchingObject = pdmObject;
}
}
if (matchingObject)
{
copyPdmObjectFromRipsToCaf(request, matchingObject);
RimEclipseResultDefinition* resultDefinition = dynamic_cast<RimEclipseResultDefinition*>(matchingObject);
// TODO: Make this more general. Perhaps we need an interface method for updating UI fields
if (resultDefinition)
{
resultDefinition->updateUiFieldsFromActiveResult();
}
matchingObject->updateAllRequiredEditors();
project->scheduleCreateDisplayModelAndRedrawAllViews();
Rim3dView* view = dynamic_cast<Rim3dView*>(matchingObject);
if (view)
{
view->applyBackgroundColorAndFontChanges();
}
return grpc::Status::OK;
}
return grpc::Status(grpc::NOT_FOUND, "PdmObject not found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RiaGrpcCallbackInterface*> RiaGrpcPdmObjectService::createCallbacks()
{
typedef RiaGrpcPdmObjectService Self;
return
{
new RiaGrpcUnaryCallback<Self, PdmParentObjectRequest, PdmObject>(this, &Self::GetAncestorPdmObject, &Self::RequestGetAncestorPdmObject),
new RiaGrpcUnaryCallback<Self, PdmChildObjectRequest, PdmObjectArray>(this, &Self::GetDescendantPdmObjects, &Self::RequestGetDescendantPdmObjects),
new RiaGrpcUnaryCallback<Self, PdmChildObjectRequest, PdmObjectArray>(this, &Self::GetChildPdmObjects, &Self::RequestGetChildPdmObjects),
new RiaGrpcUnaryCallback<Self, PdmObject, Empty>(this, &Self::UpdateExistingPdmObject, &Self::RequestUpdateExistingPdmObject),
};
}
static bool RiaGrpcPdmObjectService_init =
RiaGrpcServiceFactory::instance()->registerCreator<RiaGrpcPdmObjectService>(typeid(RiaGrpcPdmObjectService).hash_code());

View File

@@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
//////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "PdmObject.grpc.pb.h"
#include "RiaGrpcServiceInterface.h"
#include <grpcpp/grpcpp.h>
#include <vector>
//==================================================================================================
//
// gRPC-service answering request searching for PdmObjects in property tree
//
//==================================================================================================
class RiaGrpcPdmObjectService final : public rips::PdmObjectService::AsyncService, public RiaGrpcServiceInterface
{
public:
grpc::Status GetAncestorPdmObject(grpc::ServerContext* context,
const rips::PdmParentObjectRequest* request,
rips::PdmObject* reply) override;
grpc::Status GetDescendantPdmObjects(grpc::ServerContext* context,
const rips::PdmChildObjectRequest* request,
rips::PdmObjectArray* reply);
grpc::Status GetChildPdmObjects(grpc::ServerContext* context,
const rips::PdmChildObjectRequest* request,
rips::PdmObjectArray* reply);
grpc::Status
UpdateExistingPdmObject(grpc::ServerContext* context, const rips::PdmObject* request, rips::Empty* response) override;
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;
};

View File

@@ -179,6 +179,19 @@ grpc::Status
return Status(grpc::NOT_FOUND, "No cases found");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
grpc::Status RiaGrpcProjectService::GetPdmObject(grpc::ServerContext* context, const rips::Empty* request, rips::PdmObject* reply)
{
RimProject* project = RiaApplication::instance()->project();
if (project)
{
copyPdmObjectFromCafToRips(project, reply);
}
return grpc::Status::OK;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -191,7 +204,8 @@ std::vector<RiaGrpcCallbackInterface*> RiaGrpcProjectService::createCallbacks()
new RiaGrpcUnaryCallback<Self, Empty, CaseInfoArray>(this, &Self::GetSelectedCases, &Self::RequestGetSelectedCases),
new RiaGrpcUnaryCallback<Self, Empty, CaseGroups>(this, &Self::GetAllCaseGroups, &Self::RequestGetAllCaseGroups),
new RiaGrpcUnaryCallback<Self, Empty, CaseInfoArray>(this, &Self::GetAllCases, &Self::RequestGetAllCases),
new RiaGrpcUnaryCallback<Self, CaseGroup, CaseInfoArray>(this, &Self::GetCasesInGroup, &Self::RequestGetCasesInGroup)};
new RiaGrpcUnaryCallback<Self, CaseGroup, CaseInfoArray>(this, &Self::GetCasesInGroup, &Self::RequestGetCasesInGroup),
new RiaGrpcUnaryCallback<Self, Empty, PdmObject>(this, &Self::GetPdmObject, &Self::RequestGetPdmObject) };
}
static bool RiaGrpcProjectService_init =

View File

@@ -43,6 +43,7 @@ public:
grpc::Status GetAllCaseGroups(grpc::ServerContext* context, const rips::Empty* request, rips::CaseGroups* reply) override;
grpc::Status GetAllCases(grpc::ServerContext* context, const rips::Empty* request, rips::CaseInfoArray* reply) override;
grpc::Status GetCasesInGroup(grpc::ServerContext* context, const rips::CaseGroup* request, rips::CaseInfoArray* reply) override;
grpc::Status GetPdmObject(grpc::ServerContext* context, const rips::Empty* request, rips::PdmObject* reply) override;
public:
std::vector<RiaGrpcCallbackInterface*> createCallbacks() override;

View File

@@ -21,8 +21,17 @@
#include "RimProject.h"
#include "RimCase.h"
#include "RicfFieldHandle.h"
#include "RicfMessages.h"
#include "cafPdmDataValueField.h"
#include "cafPdmObject.h"
#include "cafPdmXmlFieldHandle.h"
#include <grpcpp/grpcpp.h>
#include <PdmObject.pb.h>
#include <QXmlStreamReader>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -52,3 +61,73 @@ size_t RiaGrpcServiceInterface::numberOfMessagesForByteCount(size_t messageSize,
return messageCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcServiceInterface::copyPdmObjectFromCafToRips(const caf::PdmObject* source, rips::PdmObject* destination)
{
CAF_ASSERT(source && destination);
destination->set_class_keyword(source->classKeyword().toStdString());
destination->set_address(reinterpret_cast<uint64_t>(source));
std::vector<caf::PdmFieldHandle*> fields;
source->fields(fields);
auto parametersMap = destination->mutable_parameters();
for (auto field : fields)
{
auto pdmValueField = dynamic_cast<const caf::PdmValueField*>(field);
if (pdmValueField)
{
QString keyword = pdmValueField->keyword();
auto ricfHandle = field->template capability<RicfFieldHandle>();
if (ricfHandle != nullptr)
{
QString text;
QTextStream outStream(&text);
ricfHandle->writeFieldData(outStream);
(*parametersMap)[keyword.toStdString()] = text.toStdString();
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcServiceInterface::copyPdmObjectFromRipsToCaf(const rips::PdmObject* source, caf::PdmObject* destination)
{
CAF_ASSERT(source && destination);
CAF_ASSERT(source->class_keyword() == destination->classKeyword().toStdString());
CAF_ASSERT(source->address() == reinterpret_cast<uint64_t>(destination));
std::vector<caf::PdmFieldHandle*> fields;
destination->fields(fields);
auto parametersMap = source->parameters();
for (auto field : fields)
{
auto pdmValueField = dynamic_cast<caf::PdmValueField*>(field);
if (pdmValueField)
{
QString keyword = pdmValueField->keyword();
QString value = QString::fromStdString(parametersMap[keyword.toStdString()]);
assignFieldValue(value, pdmValueField);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaGrpcServiceInterface::assignFieldValue(const QString& stringValue, caf::PdmValueField* field)
{
auto ricfHandle = field->template capability<RicfFieldHandle>();
if (field && ricfHandle != nullptr)
{
QTextStream stream(stringValue.toLatin1());
RicfMessages messages;
ricfHandle->readFieldData(stream, nullptr, &messages);
}
}

View File

@@ -24,6 +24,19 @@
class RiaGrpcCallbackInterface;
class RimCase;
namespace caf
{
class PdmObject;
class PdmValueField;
}
namespace rips
{
class PdmObject;
}
class QString;
//==================================================================================================
//
// gRPC-service interface which all gRPC-services has to implement
@@ -36,6 +49,11 @@ public:
virtual ~RiaGrpcServiceInterface() = default;
static RimCase* findCase(int caseId);
static size_t numberOfMessagesForByteCount(size_t messageSize, size_t byteCount = 64 * 1024u);
static void copyPdmObjectFromCafToRips(const caf::PdmObject* source, rips::PdmObject* destination);
static void copyPdmObjectFromRipsToCaf(const rips::PdmObject* source, caf::PdmObject* destination);
static void assignFieldValue(const QString& stringValue, caf::PdmValueField* field);
};
#include "cafFactory.h"

View File

@@ -24,6 +24,8 @@
#include "RiaPreferences.h"
#include "RiaViewRedrawScheduler.h"
#include "RicfCommandObject.h"
#include "Rim3dWellLogCurve.h"
#include "RimAnnotationInViewCollection.h"
#include "RimCase.h"
@@ -101,7 +103,7 @@ Rim3dView::Rim3dView(void)
CAF_PDM_InitField(&scaleZ, "GridZScale", defaultScaleFactor, "Z Scale", "", "Scales the scene in the Z direction", "");
cvf::Color3f defBackgColor = preferences->defaultViewerBackgroundColor();
CAF_PDM_InitField(&m_backgroundColor, "ViewBackgroundColor", defBackgColor, "Background", "", "", "");
RICF_InitField(&m_backgroundColor, "ViewBackgroundColor", defBackgColor, "Background", "", "", "");
CAF_PDM_InitField(&maximumFrameRate, "MaximumFrameRate", 10, "Maximum Frame Rate", "", "", "");
maximumFrameRate.uiCapability()->setUiHidden(true);
@@ -115,12 +117,12 @@ Rim3dView::Rim3dView(void)
CAF_PDM_InitField(&meshMode, "MeshMode", defaultMeshType, "Grid Lines", "", "", "");
CAF_PDM_InitFieldNoDefault(&surfaceMode, "SurfaceMode", "Grid Surface", "", "", "");
CAF_PDM_InitField(&m_showGridBox, "ShowGridBox", true, "Show Grid Box", "", "", "");
RICF_InitField(&m_showGridBox, "ShowGridBox", true, "Show Grid Box", "", "", "");
CAF_PDM_InitField(&m_disableLighting, "DisableLighting", false, "Disable Results Lighting", "", "Disable light model for scalar result colors", "");
CAF_PDM_InitField(&m_showZScaleLabel, "ShowZScale", true, "Show Z Scale Label", "", "", "");
m_crossSectionVizModel = new cvf::ModelBasicList;
m_crossSectionVizModel->setName("CrossSectionModel");
@@ -135,6 +137,9 @@ Rim3dView::Rim3dView(void)
m_measurementPartManager = new RivMeasurementPartMgr(this);
this->setAs3DViewMdiWindow();
RimProject* proj = RiaApplication::instance()->project();
proj->assignViewIdToView(this);
}
//--------------------------------------------------------------------------------------------------
@@ -279,8 +284,7 @@ void Rim3dView::deleteViewWidget()
void Rim3dView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* viewGroup = uiOrdering.addNewGroupWithKeyword("Viewer", "ViewGroup");
//viewGroup->add(m_nameConfig->nameField());
viewGroup->add(&m_backgroundColor);
viewGroup->add(&m_showZScaleLabel);
viewGroup->add(&m_showGridBox);

View File

@@ -20,6 +20,8 @@
#include "RimCase.h"
#include "RiaApplication.h"
#include "RicfCommandObject.h"
#include "RimFormationNames.h"
#include "RimFormationNamesCollection.h"
#include "RimOilField.h"
@@ -42,7 +44,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimCase, "RimCase");
//--------------------------------------------------------------------------------------------------
RimCase::RimCase() : m_isInActiveDestruction(false)
{
CAF_PDM_InitField(&caseUserDescription, "CaseUserDescription", QString(), "Case Name", "", "" ,"");
RICF_InitField(&caseUserDescription, "CaseUserDescription", QString(), "Case Name", "", "" ,"");
CAF_PDM_InitField(&caseId, "CaseId", -1, "Case ID", "", "" ,"");
caseId.uiCapability()->setUiReadOnly(true);

View File

@@ -24,6 +24,8 @@
#include "RiaLogging.h"
#include "RiaQDateTimeTools.h"
#include "RicfCommandObject.h"
#include "RigActiveCellInfo.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
@@ -82,13 +84,13 @@ RimEclipseResultDefinition::RimEclipseResultDefinition(caf::PdmUiItemInfo::Label
{
CAF_PDM_InitObject("Result Definition", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_resultType, "ResultType", "Type", "", "", "");
RICF_InitFieldNoDefault(&m_resultType, "ResultType", "Type", "", "", "");
m_resultType.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_porosityModel, "PorosityModelType", "Porosity", "", "", "");
RICF_InitFieldNoDefault(&m_porosityModel, "PorosityModelType", "Porosity", "", "", "");
m_porosityModel.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_resultVariable, "ResultVariable", RiaDefines::undefinedResultName(), "Variable", "", "", "");
RICF_InitField(&m_resultVariable, "ResultVariable", RiaDefines::undefinedResultName(), "Variable", "", "", "");
m_resultVariable.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_flowSolution, "FlowDiagSolution", "Solution", "", "", "");

View File

@@ -18,6 +18,7 @@ set( PROJECT_FILES
cafPdmDocument.h
cafPdmObjectGroup.cpp
cafPdmObjectGroup.h
cafPdmObject.cpp
cafPdmObject.h
cafPdmField.h
)

View File

@@ -47,7 +47,7 @@ public:
template <typename T>
void descendantsIncludingThisOfType(std::vector<T*>& descendants) const;
// PtrReferences
// PtrReferences
/// The PdmPtrField's containing pointers to this PdmObjecthandle
/// Use ownerObject() on the fieldHandle to get the PdmObjectHandle
void referringPtrFields(std::vector<PdmFieldHandle*>& fieldsReferringToMe) const;

View File

@@ -0,0 +1,98 @@
#include "cafPdmObject.h"
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObject::firstAncestorOrThisFromClassKeyword(
const QString& classKeyword, PdmObject*& ancestor) const
{
ancestor = nullptr;
// Check if this matches the type
if (this->classKeyword() == classKeyword)
{
ancestor = const_cast<PdmObject*>(this);
return;
}
// Search parents for first type match
PdmObject* parent = nullptr;
PdmFieldHandle* parentField = this->parentField();
if (parentField) parent = dynamic_cast<PdmObject*>(parentField->ownerObject());
while (parent != nullptr)
{
if (parent->classKeyword() == classKeyword)
{
ancestor = parent;
return;
}
// Get next level parent
PdmFieldHandle* nextParentField = parent->parentField();
if (nextParentField)
{
parent = dynamic_cast<PdmObject*>(nextParentField->ownerObject());
}
else
{
parent = nullptr;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObject::descendantsIncludingThisFromClassKeyword(
const QString& classKeyword,
std::vector<PdmObject*>& descendants) const
{
if (this->classKeyword() == classKeyword)
{
descendants.push_back(const_cast<PdmObject*>(this));
}
std::vector<PdmFieldHandle*> fields;
this->fields(fields);
for (auto f : fields)
{
std::vector<PdmObjectHandle*> childObjects;
f->childObjects(&childObjects);
for (auto childObject : childObjects)
{
PdmObject* pdmObjectChild = dynamic_cast<PdmObject*>(childObject);
if (pdmObjectChild)
{
pdmObjectChild->descendantsIncludingThisFromClassKeyword(classKeyword, descendants);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObject::childrenFromClassKeyword(
const QString& classKeyword,
std::vector<PdmObject*>& children) const
{
std::vector<PdmFieldHandle*> fields;
this->fields(fields);
for (auto f : fields)
{
std::vector<PdmObjectHandle*> childObjects;
f->childObjects(&childObjects);
for (auto childObject : childObjects)
{
PdmObject* pdmObjectChild = dynamic_cast<PdmObject*>(childObject);
if (pdmObjectChild && pdmObjectChild->classKeyword() == classKeyword)
{
children.push_back(pdmObjectChild);
}
}
}
}

View File

@@ -166,6 +166,22 @@ public:
}
}
/// Returns _this_ if _this_ has requested class keyword
/// Traverses parents recursively and returns first parent of the requested
/// type.
void firstAncestorOrThisFromClassKeyword(const QString& classKeyword,
PdmObject*& ancestor) const;
/// Traverses all children recursively to find objects of the requested
/// class keyword. This object is also
/// included if it has the requested class keyword
void descendantsIncludingThisFromClassKeyword(const QString& classKeyword,
std::vector<PdmObject*>& descendants) const;
/// Gets all children matching class keyword. Not recursive.
void childrenFromClassKeyword(
const QString& classKeyword,
std::vector<PdmObject*>& children) const;
};
} // End of namespace caf