Merge pull request #6336 from OPM/bug-python-38

#6322 Fix Python 3.8 problems
This commit is contained in:
Kristian Bendiksen
2020-08-24 10:06:21 +02:00
committed by GitHub
15 changed files with 435 additions and 486 deletions

View File

@@ -584,12 +584,12 @@ endforeach()
if (RESINSIGHT_ENABLE_GRPC)
set(RESINSIGHT_GRPC_PYTHON_EXECUTABLE "" CACHE FILEPATH "gRPC : Path to Python 3 executable, required to build the Python client library")
if (RESINSIGHT_GRPC_PYTHON_EXECUTABLE)
add_custom_command(OUTPUT ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/pdm_objects.py
COMMAND ResInsight ARGS --console --generate ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/pdm_objects.py
add_custom_command(OUTPUT ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/resinsight_classes.py
COMMAND ResInsight ARGS --console --generate ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/resinsight_classes.py
DEPENDS ResInsight
COMMENT "Generating ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/pdm_objects.py"
COMMENT "Generating ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/resinsight_classes.py"
)
list(APPEND GRPC_GENERATED_PYTHON_SOURCES ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/pdm_objects.py)
list(APPEND GRPC_GENERATED_PYTHON_SOURCES ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/resinsight_classes.py)
add_custom_target(GeneratedPythonSources ALL DEPENDS ${GRPC_GENERATED_PYTHON_SOURCES})
add_dependencies(GeneratedPythonSources ResInsight)
else()
@@ -781,7 +781,7 @@ if (RESINSIGHT_PRIVATE_INSTALL)
)
endif()
install(DIRECTORY ${GRPC_PYTHON_SOURCE_PATH}/ DESTINATION ${RESINSIGHT_INSTALL_FOLDER}/Python)
install(FILES ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/pdm_objects.py DESTINATION ${RESINSIGHT_INSTALL_FOLDER}/Python/rips/generated)
install(FILES ${GRPC_PYTHON_SOURCE_PATH}/rips/generated/resinsight_classes.py DESTINATION ${RESINSIGHT_INSTALL_FOLDER}/Python/rips/generated)
endif()
endif()

View File

@@ -4,15 +4,15 @@ import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'generated'))
from rips.case import Case, EclipseCase, GeoMechCase
from rips.grid import Grid
from rips.instance import Instance
from rips.pdmobject import PdmObject
from rips.view import View
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.simulation_well import SimulationWell
from resinsight_classes import *
from rips.generated.pdm_objects import *
from .case import Case, EclipseCase, GeoMechCase
from .grid import Grid
from .instance import Instance
from .pdmobject import PdmObjectBase
from .view import View
from .project import Project
from .plot import Plot, PlotWindow
from .contour_map import EclipseContourMap, GeoMechContourMap
from .well_log_plot import WellLogPlot
from .simulation_well import SimulationWell

View File

@@ -49,24 +49,23 @@ Attributes:
import builtins
import grpc
import rips.generated.Case_pb2 as Case_pb2
import rips.generated.Case_pb2_grpc as Case_pb2_grpc
import rips.generated.Commands_pb2 as Cmd
import rips.generated.PdmObject_pb2 as PdmObject_pb2
import Case_pb2
import Case_pb2_grpc
import Commands_pb2 as Cmd
import PdmObject_pb2 as PdmObject_pb2
import rips.generated.Properties_pb2 as Properties_pb2
import rips.generated.Properties_pb2_grpc as Properties_pb2_grpc
import rips.generated.NNCProperties_pb2 as NNCProperties_pb2
import rips.generated.NNCProperties_pb2_grpc as NNCProperties_pb2_grpc
from rips.generated.pdm_objects import Case, EclipseCase, GeoMechCase
import Properties_pb2
import Properties_pb2_grpc
import NNCProperties_pb2
import NNCProperties_pb2_grpc
from resinsight_classes import Case, EclipseCase, GeoMechCase, WellBoreStabilityPlot, WbsParameters
import rips.project
from .grid import Grid
from .pdmobject import add_method
from .view import View
from .simulation_well import SimulationWell
import rips.project # full name import due to circular dependency
from rips.grid import Grid
from rips.pdmobject import add_method, PdmObject
from rips.view import View
from rips.generated.pdm_objects import WellBoreStabilityPlot, WbsParameters
from rips.simulation_well import SimulationWell
@add_method(Case)
def __custom_init__(self, pb2_object, channel):
@@ -322,7 +321,7 @@ def view(self, view_id):
view_id(int): view id
Returns:
:class:`rips.generated.pdm_objects.View`
:class:`rips.generated.resinsight_classes.View`
"""
views = self.views()
for view_object in views:
@@ -336,7 +335,7 @@ def create_view(self):
"""Create a new view in the current case
Returns:
:class:`rips.generated.pdm_objects.View`
:class:`rips.generated.resinsight_classes.View`
"""
return self.view(
self._execute_command(createView=Cmd.CreateViewRequest(
@@ -925,7 +924,7 @@ def create_well_bore_stability_plot(self, well_path, time_step, parameters=None)
time_step(int): time step
Returns:
:class:`rips.generated.pdm_objects.WellBoreStabilityPlot`
:class:`rips.generated.resinsight_classes.WellBoreStabilityPlot`
"""
pb2_parameters = None
if parameters is not None:
@@ -963,7 +962,7 @@ def simulation_wells(self):
"""Get a list of all simulation wells for a case
Returns:
:class:`rips.generated.pdm_objects.SimulationWell`
:class:`rips.generated.resinsight_classes.SimulationWell`
"""
wells = self.descendants(SimulationWell)

View File

@@ -1,11 +1,11 @@
"""
ResInsight 3d contour map module
"""
import rips.generated.Commands_pb2 as Cmd
import Commands_pb2
from rips.pdmobject import PdmObject, add_method
from rips.view import View
from rips.generated.pdm_objects import EclipseContourMap, GeoMechContourMap
from .pdmobject import add_method
from .view import View
from resinsight_classes import EclipseContourMap, GeoMechContourMap
@add_method(EclipseContourMap)
@@ -19,7 +19,7 @@ def export_to_text(self, export_file_name='', export_local_coordinates=False, un
exclude_undefined_values(bool): Skip undefined values.
"""
return self._execute_command(
exportContourMapToText=Cmd.ExportContourMapToTextRequest(
exportContourMapToText=Commands_pb2.ExportContourMapToTextRequest(
exportFileName=export_file_name,
exportLocalCoordinates=export_local_coordinates,
undefinedValueLabel=undefined_value_label,
@@ -38,7 +38,7 @@ def export_to_text(self, export_file_name='', export_local_coordinates=False, un
exclude_undefined_values(bool): Skip undefined values.
"""
return self._execute_command(
exportContourMapToText=Cmd.ExportContourMapToTextRequest(
exportContourMapToText=Commands_pb2.ExportContourMapToTextRequest(
exportFileName=export_file_name,
exportLocalCoordinates=export_local_coordinates,
undefinedValueLabel=undefined_value_label,

View File

@@ -5,9 +5,9 @@ Module containing the Grid class, containing information
about Case grids.
"""
import rips.generated.Case_pb2 as Case_pb2
import rips.generated.Grid_pb2 as Grid_pb2
import rips.generated.Grid_pb2_grpc as Grid_pb2_grpc
import Case_pb2
import Grid_pb2
import Grid_pb2_grpc
class Grid:

View File

@@ -2,12 +2,12 @@
Grid Case Group statistics module
"""
from rips.pdmobject import PdmObject, add_method
from rips.view import View
from rips.case import Case
from .pdmobject import add_method
from .view import View
from .case import Case
import rips.generated.Commands_pb2 as Cmd
from rips.generated.pdm_objects import GridCaseGroup
import Commands_pb2
from resinsight_classes import GridCaseGroup
@add_method(GridCaseGroup)
@@ -15,10 +15,10 @@ def create_statistics_case(self):
"""Create a Statistics case in the Grid Case Group
Returns:
:class:`rips.generated.pdm_objects.EclipseCase`
:class:`rips.generated.resinsight_classes.EclipseCase`
"""
command_reply = self._execute_command(
createStatisticsCase=Cmd.CreateStatisticsCaseRequest(
createStatisticsCase=Commands_pb2.CreateStatisticsCaseRequest(
caseGroupId=self.group_id))
return Case(self.channel,
command_reply.createStatisticsCaseResult.caseId)
@@ -29,7 +29,7 @@ def statistics_cases(self):
"""Get a list of all statistics cases in the Grid Case Group
Returns:
List of :class:`rips.generated.pdm_objects.EclipseCase`
List of :class:`rips.generated.resinsight_classes.EclipseCase`
"""
stat_case_collection = self.children("StatisticsCaseCollection")[0]
@@ -41,12 +41,12 @@ def views(self):
"""Get a list of views belonging to a grid case group
Returns:
List of :class:`rips.generated.pdm_objects.EclipseView`
List of :class:`rips.generated.resinsight_classes.EclipseView`
"""
pdm_objects = self.descendants(EclipseView)
resinsight_classes = self.descendants(EclipseView)
view_list = []
for pdm_object in pdm_objects:
for pdm_object in resinsight_classes:
view_list.append(pdm_object)
return view_list
@@ -58,7 +58,7 @@ def view(self, view_id):
id(int): view id
Returns:
List of :class:`rips.generated.pdm_objects.EclipseView`
List of :class:`rips.generated.resinsight_classes.EclipseView`
"""
views = self.views()
@@ -79,5 +79,5 @@ def compute_statistics(self, case_ids=None):
if case_ids is None:
case_ids = []
return self._execute_command(
computeCaseGroupStatistics=Cmd.ComputeCaseGroupStatRequest(
computeCaseGroupStatistics=Commands_pb2.ComputeCaseGroupStatRequest(
caseIds=case_ids, caseGroupId=self.group_id))

View File

@@ -12,15 +12,15 @@ import time
import grpc
import rips.generated.App_pb2 as App_pb2
import rips.generated.App_pb2_grpc as App_pb2_grpc
import rips.generated.Commands_pb2 as Cmd
import rips.generated.Commands_pb2_grpc as CmdRpc
from rips.generated.Definitions_pb2 import Empty
import App_pb2
import App_pb2_grpc
import Commands_pb2
import Commands_pb2_grpc
from Definitions_pb2 import Empty
import rips.generated.RiaVersionInfo as RiaVersionInfo
import RiaVersionInfo
from rips.project import Project
from .project import Project
class Instance:
@@ -148,7 +148,7 @@ class Instance:
return None
def __execute_command(self, **command_params):
return self.commands.Execute(Cmd.CommandParams(**command_params))
return self.commands.Execute(Commands_pb2.CommandParams(**command_params))
def __check_version(self):
try:
@@ -175,7 +175,7 @@ class Instance:
False)
])
self.launched = launched
self.commands = CmdRpc.CommandsStub(self.channel)
self.commands = Commands_pb2_grpc.CommandsStub(self.channel)
# Main version check package
self.app = App_pb2_grpc.AppStub(self.channel)
@@ -219,7 +219,7 @@ class Instance:
path (str): path to directory
"""
return self.__execute_command(setStartDir=Cmd.FilePathRequest(path=path))
return self.__execute_command(setStartDir=Commands_pb2.FilePathRequest(path=path))
def set_export_folder(self, export_type, path, create_folder=False):
"""
@@ -243,7 +243,7 @@ class Instance:
"STATISTICS" |
"""
return self.__execute_command(setExportFolder=Cmd.SetExportFolderRequest(
return self.__execute_command(setExportFolder=Commands_pb2.SetExportFolderRequest(
type=export_type, path=path, createFolder=create_folder))
def set_main_window_size(self, width, height):
@@ -258,7 +258,7 @@ class Instance:
height | Height in pixels | Integer
"""
return self.__execute_command(setMainWindowSize=Cmd.SetWindowSizeParams(
return self.__execute_command(setMainWindowSize=Commands_pb2.SetWindowSizeParams(
width=width, height=height))
def set_plot_window_size(self, width, height):
@@ -272,7 +272,7 @@ class Instance:
width | Width in pixels | Integer
height | Height in pixels | Integer
"""
return self.__execute_command(setPlotWindowSize=Cmd.SetWindowSizeParams(
return self.__execute_command(setPlotWindowSize=Commands_pb2.SetWindowSizeParams(
width=width, height=height))
def major_version(self):

View File

@@ -11,11 +11,11 @@ import importlib
import inspect
import sys
import rips.generated.PdmObject_pb2 as PdmObject_pb2
import rips.generated.PdmObject_pb2_grpc as PdmObject_pb2_grpc
import rips.generated.Commands_pb2 as Cmd
import rips.generated.Commands_pb2_grpc as CmdRpc
from rips.generated.pdm_objects import PdmObject, class_from_keyword
import PdmObject_pb2
import PdmObject_pb2_grpc
import Commands_pb2
import Commands_pb2_grpc
import resinsight_classes as ClassList
def camel_to_snake(name):
@@ -45,374 +45,323 @@ def add_static_method(cls):
return decorator
@add_method(PdmObject)
def _execute_command(self, **command_params):
self.__warnings = []
response, call = self._commands.Execute.with_call(Cmd.CommandParams(**command_params))
for key, value in call.trailing_metadata():
value = value.replace(';;', '\n')
if key == 'warning':
self.__warnings.append(value)
return response
@add_method(PdmObject)
def __custom_init__(self, pb2_object, channel):
self.__warnings = []
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:
# 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))
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):
"""Copy attribute values from object to self
class PdmObjectBase:
"""
The ResInsight base class for the Project Data Model
"""
for attribute in dir(object):
if not attribute.startswith('__'):
value = getattr(object, attribute)
# This is crucial to avoid overwriting methods
if not callable(value):
setattr(self, attribute, value)
if self.__custom_init__ is not None:
self.__custom_init__(self._pb2_object, self._channel)
self.update()
def _execute_command(self, **command_params):
self.__warnings = []
response, call = self._commands.Execute.with_call(
Commands_pb2.CommandParams(**command_params))
for key, value in call.trailing_metadata():
value = value.replace(';;', '\n')
if key == 'warning':
self.__warnings.append(value)
@add_method(PdmObject)
def warnings(self):
return self.__warnings
return response
def __init__(self, pb2_object, channel):
self.__warnings = []
self.__chunk_size = 8160
@add_method(PdmObject)
def has_warnings(self):
return len(self.__warnings) > 0
self._channel = channel
# Create stubs
if self._channel:
self._pdm_object_stub = PdmObject_pb2_grpc.PdmObjectServiceStub(self._channel)
self._commands = Commands_pb2_grpc.CommandsStub(self._channel)
@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)
if pb2_object is not None:
# Copy parameters from ResInsight
assert(isinstance(pb2_object, PdmObject_pb2.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))
else:
# Copy parameters from PdmObject defaults
self._pb2_object = PdmObject_pb2.PdmObject(class_keyword=self.__class__.__name__)
self.__copy_to_pb2()
def copy_from(self, object):
"""Copy attribute values from object to self
"""
for attribute in dir(object):
if not attribute.startswith('__'):
value = getattr(object, attribute)
# 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)
setattr(self, attribute, value)
if self.__custom_init__ is not None:
self.__custom_init__(self._pb2_object, self._channel)
self.update()
def warnings(self):
return self.__warnings
@add_method(PdmObject)
def pb2_object(self):
""" Private method"""
return self._pb2_object
def has_warnings(self):
return len(self.__warnings) > 0
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 channel(self):
""" Private method"""
return self._channel
def pb2_object(self):
""" Private method"""
return self._pb2_object
def channel(self):
""" Private method"""
return self._channel
@add_method(PdmObject)
def address(self):
"""Get the unique address of the PdmObject
def address(self):
"""Get the unique address of the PdmObject
Returns:
A 64-bit unsigned integer address
"""
Returns:
A 64-bit unsigned integer address
"""
return self._pb2_object.address
return self._pb2_object.address
def set_visible(self, visible):
"""Set the visibility of the object in the ResInsight project tree"""
self._pb2_object.visible = visible
@add_method(PdmObject)
def set_visible(self, visible):
"""Set the visibility of the object in the ResInsight project tree"""
self._pb2_object.visible = visible
def visible(self):
"""Get the visibility of the object in the ResInsight project tree"""
return self._pb2_object.visible
def print_object_info(self):
"""Print the structure and data content of the PdmObject"""
print("=========== " + self.__class__.__name__ + " =================")
print("Object Attributes: ")
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 snake_kw in dir(self):
if not snake_kw.startswith("_") and callable(getattr(self, snake_kw)):
print(" " + snake_kw)
@add_method(PdmObject)
def visible(self):
"""Get the visibility of the object in the ResInsight project tree"""
return self._pb2_object.visible
@add_method(PdmObject)
def print_object_info(self):
"""Print the structure and data content of the PdmObject"""
print("=========== " + self.__class__.__name__ + " =================")
print("Object Attributes: ")
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 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):
if value.lower() == 'false':
return False
if value.lower() == 'true':
return True
try:
int_val = int(value)
return int_val
except ValueError:
def __convert_from_grpc_value(self, value):
if value.lower() == 'false':
return False
if value.lower() == 'true':
return True
try:
float_val = float(value)
return float_val
int_val = int(value)
return int_val
except ValueError:
# We may have a string. Strip internal start and end quotes
value = value.strip('\"')
if self.__islist(value):
return self.__makelist(value)
return value
try:
float_val = float(value)
return float_val
except ValueError:
# We may have a string. Strip internal start and end quotes
value = value.strip('\"')
if self.__islist(value):
return self.__makelist(value)
return value
def __convert_to_grpc_value(self, value):
if isinstance(value, bool):
if value:
return "true"
return "false"
if isinstance(value, PdmObjectBase):
return value.__class__.__name__ + ":" + str(value.address())
if isinstance(value, list):
list_of_strings = []
for val in value:
list_of_strings.append('\"' + self.__convert_to_grpc_value(val) + '\"')
return "[" + ", ".join(list_of_strings) + "]"
return str(value)
@add_method(PdmObject)
def __convert_to_grpc_value(self, value):
if isinstance(value, bool):
if value:
return "true"
return "false"
if isinstance(value, PdmObject):
return value.__class__.__name__ + ":" + str(value.address())
if isinstance(value, list):
list_of_strings = []
for val in value:
list_of_strings.append('\"' + self.__convert_to_grpc_value(val) + '\"')
return "[" + ", ".join(list_of_strings) + "]"
return str(value)
def __get_grpc_value(self, camel_keyword):
return self.__convert_from_grpc_value(self._pb2_object.parameters[camel_keyword])
def __set_grpc_value(self, camel_keyword, value):
self._pb2_object.parameters[camel_keyword] = self.__convert_to_grpc_value(value)
@add_method(PdmObject)
def __get_grpc_value(self, camel_keyword):
return self.__convert_from_grpc_value(self._pb2_object.parameters[camel_keyword])
def set_value(self, snake_keyword, value):
"""Set the value associated with the provided keyword and updates ResInsight
Arguments:
keyword(str): A string containing the parameter keyword
value(varying): A value matching the type of the parameter.
See keyword documentation and/or print_object_info() to find
the correct data type.
"""
setattr(self, snake_keyword, value)
self.update()
def __islist(self, value):
return value.startswith("[") and value.endswith("]")
@add_method(PdmObject)
def __set_grpc_value(self, camel_keyword, value):
self._pb2_object.parameters[camel_keyword] = self.__convert_to_grpc_value(value)
def __makelist(self, list_string):
list_string = list_string.lstrip("[")
list_string = list_string.rstrip("]")
strings = list_string.split(", ")
values = []
for string in strings:
values.append(self.__convert_from_grpc_value(string))
return values
def __from_pb2_to_resinsight_classes(self, pb2_object_list, super_class_definition):
pdm_object_list = []
for pb2_object in pb2_object_list:
child_class_definition = ClassList.class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
child_class_definition = super_class_definition
@add_method(PdmObject)
def set_value(self, snake_keyword, value):
"""Set the value associated with the provided keyword and updates ResInsight
Arguments:
keyword(str): A string containing the parameter keyword
value(varying): A value matching the type of the parameter.
See keyword documentation and/or print_object_info() to find
the correct data type.
"""
setattr(self, snake_keyword, value)
self.update()
pdm_object = child_class_definition(pb2_object=pb2_object, channel=self.channel())
pdm_object_list.append(pdm_object)
return pdm_object_list
def descendants(self, class_definition):
"""Get a list of all project tree descendants matching the class keyword
Arguments:
class_definition[class]: A class definition matching the type of class wanted
@add_method(PdmObject)
def __islist(self, value):
return value.startswith("[") and value.endswith("]")
Returns:
A list of PdmObjects matching the class_definition
"""
assert(inspect.isclass(class_definition))
class_keyword = class_definition.__name__
try:
request = PdmObject_pb2.PdmDescendantObjectRequest(
object=self._pb2_object, child_keyword=class_keyword)
object_list = self._pdm_object_stub.GetDescendantPdmObjects(
request).objects
return self.__from_pb2_to_resinsight_classes(object_list, class_definition)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return [] # Valid empty result
raise e
@add_method(PdmObject)
def __makelist(self, list_string):
list_string = list_string.lstrip("[")
list_string = list_string.rstrip("]")
strings = list_string.split(", ")
values = []
for string in strings:
values.append(self.__convert_from_grpc_value(string))
return values
def children(self, child_field, class_definition):
"""Get a list of all direct project tree children inside the provided child_field
Arguments:
child_field[str]: A field name
Returns:
A list of PdmObjects inside the child_field
"""
request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object,
child_field=child_field)
try:
object_list = self._pdm_object_stub.GetChildPdmObjects(request).objects
return self.__from_pb2_to_resinsight_classes(object_list, class_definition)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return []
raise e
def ancestor(self, class_definition):
"""Find the first ancestor that matches the provided class_keyword
Arguments:
class_definition[class]: A class definition matching the type of class wanted
"""
assert(inspect.isclass(class_definition))
@add_method(PdmObject)
def __from_pb2_to_pdm_objects(self, pb2_object_list, super_class_definition):
pdm_object_list = []
for pb2_object in pb2_object_list:
child_class_definition = class_from_keyword(pb2_object.class_keyword)
class_keyword = class_definition.__name__
request = PdmObject_pb2.PdmParentObjectRequest(
object=self._pb2_object, parent_keyword=class_keyword)
try:
pb2_object = self._pdm_object_stub.GetAncestorPdmObject(request)
child_class_definition = ClassList.class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
child_class_definition = class_definition
pdm_object = child_class_definition(pb2_object=pb2_object, channel=self.channel())
return pdm_object
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return None
raise e
def _call_get_method_async(self, method_name):
request = PdmObject_pb2.PdmObjectGetterRequest(object=self._pb2_object, method=method_name)
for chunk in self._pdm_object_stub.CallPdmObjectGetter(request):
yield chunk
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
def __generate_set_method_chunks(self, array, method_request):
index = -1
while index < len(array):
chunk = PdmObject_pb2.PdmObjectSetterChunk()
if index == -1:
chunk.set_request.CopyFrom(PdmObject_pb2.PdmObjectSetterRequest(
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.PdmObjectSetterChunk(doubles=PdmObject_pb2.DoubleArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], int):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetterChunk(ints=PdmObject_pb2.IntArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], str):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetterChunk(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.PdmObjectSetterChunk()
yield chunk
def _call_set_method(self, method_name, values):
method_request = PdmObject_pb2.PdmObjectGetterRequest(
object=self._pb2_object, method=method_name)
request_iterator = self.__generate_set_method_chunks(values, method_request)
reply = self._pdm_object_stub.CallPdmObjectSetter(request_iterator)
if reply.accepted_value_count < len(values):
raise IndexError
def _call_pdm_method(self, method_name, **kwargs):
pb2_params = PdmObject_pb2.PdmObject(class_keyword=method_name)
for key, value in kwargs.items():
pb2_params.parameters[snake_to_camel(key)] = self.__convert_to_grpc_value(value)
request = PdmObject_pb2.PdmObjectMethodRequest(
object=self._pb2_object, method=method_name, params=pb2_params)
pb2_object = self._pdm_object_stub.CallPdmObjectMethod(request)
child_class_definition = ClassList.class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
child_class_definition = super_class_definition
pdm_object = child_class_definition(pb2_object=pb2_object, channel=self.channel())
pdm_object_list.append(pdm_object)
return pdm_object_list
@add_method(PdmObject)
def descendants(self, class_definition):
"""Get a list of all project tree descendants matching the class keyword
Arguments:
class_definition[class]: A class definition matching the type of class wanted
Returns:
A list of PdmObjects matching the class_definition
"""
assert(inspect.isclass(class_definition))
class_keyword = class_definition.__name__
try:
request = PdmObject_pb2.PdmDescendantObjectRequest(
object=self._pb2_object, child_keyword=class_keyword)
object_list = self._pdm_object_stub.GetDescendantPdmObjects(
request).objects
return self.__from_pb2_to_pdm_objects(object_list, class_definition)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return [] # Valid empty result
raise e
@add_method(PdmObject)
def children(self, child_field, class_definition=PdmObject):
"""Get a list of all direct project tree children inside the provided child_field
Arguments:
child_field[str]: A field name
Returns:
A list of PdmObjects inside the child_field
"""
request = PdmObject_pb2.PdmChildObjectRequest(object=self._pb2_object,
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)
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return []
raise e
@add_method(PdmObject)
def ancestor(self, class_definition):
"""Find the first ancestor that matches the provided class_keyword
Arguments:
class_definition[class]: A class definition matching the type of class wanted
"""
assert(inspect.isclass(class_definition))
class_keyword = class_definition.__name__
request = PdmObject_pb2.PdmParentObjectRequest(
object=self._pb2_object, parent_keyword=class_keyword)
try:
pb2_object = self._pdm_object_stub.GetAncestorPdmObject(request)
child_class_definition = class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
child_class_definition = class_definition
return None
pdm_object = child_class_definition(pb2_object=pb2_object, channel=self.channel())
return pdm_object
except grpc.RpcError as e:
if e.code() == grpc.StatusCode.NOT_FOUND:
return None
raise e
@add_method(PdmObject)
def _call_get_method_async(self, method_name):
request = PdmObject_pb2.PdmObjectGetterRequest(object=self._pb2_object, method=method_name)
for chunk in self._pdm_object_stub.CallPdmObjectGetter(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.PdmObjectSetterChunk()
if index is -1:
chunk.set_request.CopyFrom(PdmObject_pb2.PdmObjectSetterRequest(
request=method_request, data_count=len(array)))
index += 1
def update(self):
"""Sync all fields from the Python Object to ResInsight"""
self.__copy_to_pb2()
if self._pdm_object_stub is not None:
self._pdm_object_stub.UpdateExistingPdmObject(self._pb2_object)
else:
actual_chunk_size = min(len(array) - index + 1, self.__chunk_size)
if isinstance(array[0], float):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetterChunk(doubles=PdmObject_pb2.DoubleArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], int):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetterChunk(ints=PdmObject_pb2.IntArray(data=array[index:index +
actual_chunk_size])))
elif isinstance(array[0], str):
chunk.CopyFrom(
PdmObject_pb2.PdmObjectSetterChunk(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.PdmObjectSetterChunk()
yield chunk
@add_method(PdmObject)
def _call_set_method(self, method_name, values):
method_request = PdmObject_pb2.PdmObjectGetterRequest(
object=self._pb2_object, method=method_name)
request_iterator = self.__generate_set_method_chunks(values, method_request)
reply = self._pdm_object_stub.CallPdmObjectSetter(request_iterator)
if reply.accepted_value_count < len(values):
raise IndexError
@add_method(PdmObject)
def _call_pdm_method(self, method_name, **kwargs):
pb2_params = PdmObject_pb2.PdmObject(class_keyword=method_name)
for key, value in kwargs.items():
pb2_params.parameters[snake_to_camel(key)] = self.__convert_to_grpc_value(value)
request = PdmObject_pb2.PdmObjectMethodRequest(
object=self._pb2_object, method=method_name, params=pb2_params)
pb2_object = self._pdm_object_stub.CallPdmObjectMethod(request)
child_class_definition = class_from_keyword(pb2_object.class_keyword)
if child_class_definition is None:
return None
pdm_object = child_class_definition(pb2_object=pb2_object, channel=self.channel())
return pdm_object
@add_method(PdmObject)
def update(self):
"""Sync all fields from the Python Object to ResInsight"""
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")
raise Exception("Object is not connected to GRPC service so cannot update ResInsight")

View File

@@ -1,11 +1,10 @@
"""
ResInsight 2d plot module
"""
import rips.generated.Commands_pb2 as Cmd
import Commands_pb2
from rips.pdmobject import PdmObject
from rips.generated.pdm_objects import PlotWindow, Plot
from rips.pdmobject import add_method
from .pdmobject import PdmObjectBase, add_method
from resinsight_classes import PlotWindow, Plot
@add_method(PlotWindow)
@@ -19,8 +18,8 @@ def export_snapshot(self, export_folder='', file_prefix='', output_format='PNG')
"""
return self._execute_command(
exportSnapshots=Cmd.ExportSnapshotsRequest(type='PLOTS',
prefix=file_prefix,
viewId=self.id,
exportFolder=export_folder,
plotOutputFormat=output_format))
exportSnapshots=Commands_pb2.ExportSnapshotsRequest(type='PLOTS',
prefix=file_prefix,
viewId=self.id,
exportFolder=export_folder,
plotOutputFormat=output_format))

View File

@@ -6,18 +6,18 @@ The ResInsight project module
import builtins
import grpc
from rips.case import Case
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 .case import Case
from .gridcasegroup import GridCaseGroup
from .pdmobject import PdmObjectBase, add_method, add_static_method
from .plot import Plot
from .view import View
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, WellPath
import Commands_pb2
from Definitions_pb2 import Empty
import Project_pb2_grpc
import Project_pb2
import PdmObject_pb2
from resinsight_classes import Project, PlotWindow, WellPath
@add_method(Project)
@@ -40,7 +40,7 @@ def open(self, path):
path(str): path to project file
"""
self._execute_command(openProject=Cmd.FilePathRequest(path=path))
self._execute_command(openProject=Commands_pb2.FilePathRequest(path=path))
return self
@@ -51,7 +51,7 @@ def save(self, path=""):
Arguments:
path(str): File path to the file to save the project to. If empty, saves to the active project file
"""
self._execute_command(saveProject=Cmd.SaveProjectRequest(filePath=path))
self._execute_command(saveProject=Commands_pb2.SaveProjectRequest(filePath=path))
return self
@@ -68,9 +68,9 @@ def load_case(self, path):
Arguments:
path(str): file path to case
Returns:
:class:`rips.generated.pdm_objects.Case`
:class:`rips.generated.resinsight_classes.Case`
"""
command_reply = self._execute_command(loadCase=Cmd.FilePathRequest(
command_reply = self._execute_command(loadCase=Commands_pb2.FilePathRequest(
path=path))
return self.case(command_reply.loadCaseResult.id)
@@ -80,7 +80,7 @@ def selected_cases(self):
"""Get a list of all cases selected in the project tree
Returns:
A list of :class:`rips.generated.pdm_objects.Case`
A list of :class:`rips.generated.resinsight_classes.Case`
"""
case_infos = self._project_stub.GetSelectedCases(Empty())
cases = []
@@ -94,7 +94,7 @@ def cases(self):
"""Get a list of all cases in the project
Returns:
A list of :class:`rips.generated.pdm_objects.Case`
A list of :class:`rips.generated.resinsight_classes.Case`
"""
return self.descendants(Case)
@@ -106,7 +106,7 @@ def case(self, case_id):
Arguments:
id(int): case id
Returns:
:class:`rips.generated.pdm_objects.Case`
:class:`rips.generated.resinsight_classes.Case`
"""
allCases = self.cases()
for case in allCases:
@@ -124,7 +124,7 @@ def replace_source_cases(self, grid_list_file, case_group_id=0):
case_group_id (int): id of the case group to replace
"""
return self._execute_command(
replaceSourceCases=Cmd.ReplaceSourceCasesRequest(
replaceSourceCases=Commands_pb2.ReplaceSourceCasesRequest(
gridListFile=grid_list_file, caseGroupId=case_group_id))
@@ -135,10 +135,10 @@ def create_grid_case_group(self, case_paths):
Arguments:
case_paths (list): list of file path strings
Returns:
:class:`rips.generated.pdm_objects.GridCaseGroup`
:class:`rips.generated.resinsight_classes.GridCaseGroup`
"""
command_reply = self._execute_command(
createGridCaseGroup=Cmd.CreateGridCaseGroupRequest(
createGridCaseGroup=Commands_pb2.CreateGridCaseGroupRequest(
casePaths=case_paths))
return self.grid_case_group(
command_reply.createGridCaseGroupResult.groupId)
@@ -157,7 +157,7 @@ def view(self, view_id):
Arguments:
view_id(int): view id
Returns:
:class:`rips.generated.pdm_objects.View`
:class:`rips.generated.resinsight_classes.View`
"""
views = self.views()
for view_object in views:
@@ -171,11 +171,11 @@ def plots(self):
"""Get a list of all plots belonging to a project
Returns:
List of :class:`rips.generated.pdm_objects.Plot`
List of :class:`rips.generated.resinsight_classes.Plot`
"""
pdm_objects = self.descendants(PlotWindow)
resinsight_classes = self.descendants(PlotWindow)
plot_list = []
for pdm_object in pdm_objects:
for pdm_object in resinsight_classes:
if pdm_object.id != -1:
plot_list.append(pdm_object)
return plot_list
@@ -189,7 +189,7 @@ def plot(self, view_id):
view_id(int): view id
Returns:
:class:`rips.generated.pdm_objects.Plot`
:class:`rips.generated.resinsight_classes.Plot`
"""
plots = self.plots()
for plot_object in plots:
@@ -203,7 +203,7 @@ def grid_case_groups(self):
"""Get a list of all grid case groups in the project
Returns:
List of :class:`rips.generated.pdm_objects.GridCaseGroup`
List of :class:`rips.generated.resinsight_classes.GridCaseGroup`
"""
case_groups = self.descendants(GridCaseGroup)
@@ -218,7 +218,7 @@ def grid_case_group(self, group_id):
groupId(int): group id
Returns:
:class:`rips.generated.pdm_objects.GridCaseGroup`
:class:`rips.generated.resinsight_classes.GridCaseGroup`
"""
case_groups = self.grid_case_groups()
for case_group in case_groups:
@@ -235,7 +235,7 @@ def export_multi_case_snapshots(self, grid_list_file):
grid_list_file (str): Path to a file containing a list of grids to export snapshot for
"""
return self._execute_command(
exportMultiCaseSnapshot=Cmd.ExportMultiCaseRequest(
exportMultiCaseSnapshot=Commands_pb2.ExportMultiCaseRequest(
gridListFile=grid_list_file))
@@ -249,7 +249,7 @@ def export_snapshots(self, snapshot_type='ALL', prefix='', plot_format='PNG'):
plot_format(str): Enum string, 'PNG' or 'PDF'
"""
return self._execute_command(
exportSnapshots=Cmd.ExportSnapshotsRequest(
exportSnapshots=Commands_pb2.ExportSnapshotsRequest(
type=snapshot_type, prefix=prefix, caseId=-1, viewId=-1, plotOutputFormat=plot_format))
@@ -265,7 +265,7 @@ def export_well_paths(self, well_paths=None, md_step_size=5.0):
well_paths = []
elif isinstance(well_paths, str):
well_paths = [well_paths]
return self._execute_command(exportWellPaths=Cmd.ExportWellPathRequest(
return self._execute_command(exportWellPaths=Commands_pb2.ExportWellPathRequest(
wellPathNames=well_paths, mdStepSize=md_step_size))
@@ -282,7 +282,7 @@ def scale_fracture_template(self, template_id, half_length, height,
conductivity (double): Conductivity scale factor
"""
return self._execute_command(
scaleFractureTemplate=Cmd.ScaleFractureTemplateRequest(
scaleFractureTemplate=Commands_pb2.ScaleFractureTemplateRequest(
id=template_id,
halfLength=half_length,
height=height,
@@ -300,7 +300,7 @@ def set_fracture_containment(self, template_id, top_layer, base_layer):
base_layer (int): Base layer containment
"""
return self._execute_command(
setFractureContainment=Cmd.SetFracContainmentRequest(
setFractureContainment=Commands_pb2.SetFracContainmentRequest(
id=template_id, topLayer=top_layer, baseLayer=base_layer))
@@ -313,13 +313,13 @@ def import_well_paths(self, well_path_files=None, well_path_folder=''):
well_path_folder(str): A folder path containing files to import
Returns:
List of :class:`rips.generated.pdm_objects.WellPath`
List of :class:`rips.generated.resinsight_classes.WellPath`
"""
if well_path_files is None:
well_path_files = []
res = self._execute_command(importWellPaths=Cmd.ImportWellPathsRequest(wellPathFolder=well_path_folder,
wellPathFiles=well_path_files))
res = self._execute_command(importWellPaths=Commands_pb2.ImportWellPathsRequest(wellPathFolder=well_path_folder,
wellPathFiles=well_path_files))
well_paths = []
for well_path_name in res.importWellPathsResult.wellPathNames:
well_paths.append(self.well_path_by_name(well_path_name))
@@ -331,7 +331,7 @@ def well_paths(self):
"""Get a list of all well paths in the project
Returns:
List of :class:`rips.generated.pdm_objects.WellPath`
List of :class:`rips.generated.resinsight_classes.WellPath`
"""
return self.descendants(WellPath)
@@ -341,7 +341,7 @@ def well_path_by_name(self, well_path_name):
"""Get a specific well path by name from the project
Returns:
:class:`rips.generated.pdm_objects.WellPath`
:class:`rips.generated.resinsight_classes.WellPath`
"""
all_well_paths = self.well_paths()
for well_path in all_well_paths:
@@ -364,8 +364,8 @@ def import_well_log_files(self, well_log_files=None, well_log_folder=''):
if well_log_files is None:
well_log_files = []
res = self._execute_command(importWellLogFiles=Cmd.ImportWellLogFilesRequest(wellLogFolder=well_log_folder,
wellLogFiles=well_log_files))
res = self._execute_command(importWellLogFiles=Commands_pb2.ImportWellLogFilesRequest(wellLogFolder=well_log_folder,
wellLogFiles=well_log_files))
return res.importWellLogFilesResult.wellPathNames
@@ -382,6 +382,5 @@ def import_formation_names(self, formation_files=None):
elif isinstance(formation_files, str):
formation_files = [formation_files]
self._execute_command(importFormationNames=Cmd.ImportFormationNamesRequest(formationFiles=formation_files,
applyToCaseId=-1))
self._execute_command(importFormationNames=Commands_pb2.ImportFormationNamesRequest(formationFiles=formation_files,
applyToCaseId=-1))

View File

@@ -3,16 +3,16 @@ ResInsight SimulationWell
"""
import grpc
import rips.generated.SimulationWell_pb2 as SimulationWell_pb2
import rips.generated.SimulationWell_pb2_grpc as SimulationWell_pb2_grpc
import SimulationWell_pb2
import SimulationWell_pb2_grpc
import rips.generated.Properties_pb2 as Properties_pb2
import rips.generated.Properties_pb2_grpc as Properties_pb2_grpc
import Properties_pb2
import Properties_pb2_grpc
import rips.generated.Commands_pb2 as Cmd
from rips.generated.pdm_objects import SimulationWell
from resinsight_classes import SimulationWell
from .pdmobject import PdmObjectBase, add_method
from rips.pdmobject import PdmObject, add_method
import rips.case

View File

@@ -3,11 +3,11 @@ ResInsight 3d view module
"""
import builtins
import rips.generated.Commands_pb2 as Cmd
import Commands_pb2 as Cmd
import rips.case # Circular import of Case, which already imports View. Use full name.
from rips.pdmobject import add_method
from rips.generated.pdm_objects import View, ViewWindow, EclipseView, GeoMechView
from .pdmobject import add_method
from resinsight_classes import View, ViewWindow, EclipseView, GeoMechView
@add_method(View)

View File

@@ -2,12 +2,11 @@
ResInsight Well Log Plot plot module
"""
import rips.generated.Commands_pb2 as Cmd
import Commands_pb2
from rips.plot import Plot
from rips.pdmobject import PdmObject
from rips.generated.pdm_objects import WellLogPlot
from rips.pdmobject import add_method
from .plot import Plot
from .pdmobject import PdmObjectBase, add_method
from resinsight_classes import WellLogPlot
@add_method(WellLogPlot)
@@ -24,14 +23,14 @@ def export_data_as_las(self, export_folder, file_prefix='', export_tvdrkb=False,
Returns:
A list of files exported
"""
res = self._execute_command(exportWellLogPlotData=Cmd.ExportWellLogPlotDataRequest(exportFormat='LAS',
viewId=self.id,
exportFolder=export_folder,
filePrefix=file_prefix,
exportTvdRkb=export_tvdrkb,
capitalizeFileNames=capitalize_file_names,
resampleInterval=resample_interval,
convertCurveUnits=convert_to_standard_units))
res = self._execute_command(exportWellLogPlotData=Commands_pb2.ExportWellLogPlotDataRequest(exportFormat='LAS',
viewId=self.id,
exportFolder=export_folder,
filePrefix=file_prefix,
exportTvdRkb=export_tvdrkb,
capitalizeFileNames=capitalize_file_names,
resampleInterval=resample_interval,
convertCurveUnits=convert_to_standard_units))
return res.exportWellLogPlotDataResult.exportedFiles
@@ -47,11 +46,11 @@ def export_data_as_ascii(self, export_folder, file_prefix='', capitalize_file_na
Returns:
A list of files exported
"""
res = self._execute_command(exportWellLogPlotData=Cmd.ExportWellLogPlotDataRequest(exportFormat='ASCII',
viewId=self.id,
exportFolder=export_folder,
filePrefix=file_prefix,
exportTvdRkb=False,
capitalizeFileNames=capitalize_file_names,
resampleInterval=0.0))
res = self._execute_command(exportWellLogPlotData=Commands_pb2.ExportWellLogPlotDataRequest(exportFormat='ASCII',
viewId=self.id,
exportFolder=export_folder,
filePrefix=file_prefix,
exportTvdRkb=False,
capitalizeFileNames=capitalize_file_names,
resampleInterval=0.0))
return res.exportWellLogPlotDataResult.exportedFiles

View File

@@ -291,6 +291,10 @@ QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
// Write out classes
std::set<QString> classesWritten;
classesWritten.insert( "PdmObjectBase" );
out << "from rips.pdmobject import PdmObjectBase\n";
for ( std::shared_ptr<PdmObject> object : dummyObjects )
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();

View File

@@ -2,7 +2,7 @@
using namespace caf;
CAF_PDM_ABSTRACT_SOURCE_INIT( PdmObject, "PdmObject" );
CAF_PDM_ABSTRACT_SOURCE_INIT( PdmObject, "PdmObjectBase" );
//--------------------------------------------------------------------------------------------------
///