From 36c0676ec479a2d4cda940eb59236b1c71a942ec Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Wed, 18 Nov 2020 10:46:10 +0100 Subject: [PATCH] Implement view python function to be able to view a field's iteration from the python console like in the documentation examples --- idl/MEDDataManager.idl | 2 ++ src/MEDCalc/cmp/MEDDataManager_i.cxx | 17 +++++++++ src/MEDCalc/cmp/MEDDataManager_i.hxx | 2 ++ src/MEDCalc/cmp/MEDPresentation.cxx | 38 +++++++++++++++++--- src/MEDCalc/cmp/MEDPresentation.hxx | 1 + src/MEDCalc/cmp/MEDPresentationScalarMap.cxx | 1 + src/MEDCalc/gui/XmedConsoleDriver.cxx | 2 +- src/MEDCalc/tui/medconsole.py | 8 +++++ 8 files changed, 66 insertions(+), 5 deletions(-) diff --git a/idl/MEDDataManager.idl b/idl/MEDDataManager.idl index 6f46be875..715c4d9e7 100644 --- a/idl/MEDDataManager.idl +++ b/idl/MEDDataManager.idl @@ -154,6 +154,8 @@ module MEDCALC //void saveFields(in FieldHandlerList fieldHandlerList, in string filepath); + double getFieldTimeStep(in long fieldHandlerId); + void changeUnderlyingMesh(in long fieldHandlerId, in long meshHandlerId) raises (SALOME::SALOME_Exception); diff --git a/src/MEDCalc/cmp/MEDDataManager_i.cxx b/src/MEDCalc/cmp/MEDDataManager_i.cxx index 12910999e..75e082399 100644 --- a/src/MEDCalc/cmp/MEDDataManager_i.cxx +++ b/src/MEDCalc/cmp/MEDDataManager_i.cxx @@ -588,6 +588,23 @@ long MEDDataManager_i::getUMeshId(const MEDCouplingMesh * mesh) { return LONG_UNDEFINED; } +/** + * Get the timestep associated to a field + */ +double MEDDataManager_i::getFieldTimeStep(CORBA::Long fieldHandlerId) +{ + int iteration, order; + // WARN: note that the variables "iteration" and "order" are passed + // by reference to the function getTime (see documentation of + // MEDCouplingField). As a consequence, the values of these + // variables are updated by this function call. This is the means to + // retrieve the iteration and order of the field. + MEDCALC::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId); + MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); + double timestamp = fieldDouble->getTime(iteration, order); + return timestamp; +} + /*! * This method returns the physical data of the specified field, * i.e. the MEDCoupling field associated to the specified field diff --git a/src/MEDCalc/cmp/MEDDataManager_i.hxx b/src/MEDCalc/cmp/MEDDataManager_i.hxx index b68fc714d..4b0a55c81 100644 --- a/src/MEDCalc/cmp/MEDDataManager_i.hxx +++ b/src/MEDCalc/cmp/MEDDataManager_i.hxx @@ -161,6 +161,8 @@ private: MEDCouplingUMesh * getUMesh(long meshHandlerId); long getUMeshId(const MEDCouplingMesh * mesh); + double getFieldTimeStep(CORBA::Long fieldHandlerId); + INTERP_KERNEL::IntersectionType _getIntersectionType(const char* intersType); MEDCoupling::NatureOfField _getNatureOfField(const char* fieldNature); diff --git a/src/MEDCalc/cmp/MEDPresentation.cxx b/src/MEDCalc/cmp/MEDPresentation.cxx index 5284d0387..e4b1c01f1 100644 --- a/src/MEDCalc/cmp/MEDPresentation.cxx +++ b/src/MEDCalc/cmp/MEDPresentation.cxx @@ -95,7 +95,8 @@ MEDPresentation::initFieldMeshInfos() MEDCALC::MeshHandler* meshHandler = dataManager->getMeshHandler(fieldHandler->meshid); MEDCALC::DatasourceHandler* dataSHandler = dataManager->getDatasourceHandlerFromID(meshHandler->sourceid); - extractFileName(std::string(dataSHandler->uri)); + // get the file name of the field (or its memory information) + extractFileName(std::string(fieldHandler->source)); _fieldName = fieldHandler->fieldname; _mcFieldType = (MEDCoupling::TypeOfField) fieldHandler->type; @@ -107,13 +108,23 @@ MEDPresentation::initFieldMeshInfos() void MEDPresentation::extractFileName(const std::string& name) { + STDLOG("MEDPresentation::extractFileName('" << name << "')"); _fileName = name; if (_fileName.substr(0, 7) != std::string("file://")) { - const char* msg = "MEDPresentation(): Data source is not a file! Can not proceed."; + const char* msg = "MEDPresentation(): Data source is in memory! Saving it in tmp file."; STDLOG(msg); - throw MEDPresentationException(msg); + // export a med file with this field + // we could instead use CORBA to transfer the field to PARAVIS like in MEDCalculatorDBFieldReal::display() + _fileName = std::tmpnam(NULL); + MEDCALC::FieldIdList fieldIdList; + fieldIdList.length(1); + fieldIdList[0] = _handlerId; + MEDFactoryClient::getDataManager()->saveFields(_fileName.c_str(), fieldIdList); } - _fileName = _fileName.substr(7, _fileName.size()); + else + // removing "file://" + _fileName = _fileName.substr(7, _fileName.size()); + STDLOG("MEDPresentation::extractFileName _fileName=" << _fileName); } MEDPresentation::~MEDPresentation() @@ -344,6 +355,25 @@ MEDPresentation::createSource() } } +/* + * Set the timestep of the animation to the timestep of the field. + * Especially useful when working on a field's iteration: + * in the workspace, in the python console, or using changeUnderlyingMesh. + */ +void +MEDPresentation::setTimestep() +{ + // get the timestep of the field + double timestep = MEDFactoryClient::getDataManager()->getFieldTimeStep(_handlerId); + + std::ostringstream oss; + + // go to the right timestep in animation (view and VCR toolbar) + pushAndExecPyLine("pvs.GetAnimationScene().UpdateAnimationUsingDataTimeSteps()"); + oss << "pvs.GetAnimationScene().AnimationTime = " << timestep << ";"; + pushAndExecPyLine(oss.str()); oss.str(""); +} + void MEDPresentation::setOrCreateRenderView() { diff --git a/src/MEDCalc/cmp/MEDPresentation.hxx b/src/MEDCalc/cmp/MEDPresentation.hxx index 5fa62c55e..3a0870626 100644 --- a/src/MEDCalc/cmp/MEDPresentation.hxx +++ b/src/MEDCalc/cmp/MEDPresentation.hxx @@ -84,6 +84,7 @@ protected: // The most common elements of the ParaView pipeline: void setOrCreateRenderView(); void createSource(); + void setTimestep(); void selectFieldComponent(); void showObject(); void colorBy(); diff --git a/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx b/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx index 0ebb60f82..654a5cdd5 100644 --- a/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx +++ b/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx @@ -45,6 +45,7 @@ MEDPresentationScalarMap::internalGeneratePipeline() setOrCreateRenderView(); // instantiate __viewXXX createSource(); + setTimestep(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/gui/XmedConsoleDriver.cxx b/src/MEDCalc/gui/XmedConsoleDriver.cxx index fd7a609e7..6bc23849e 100644 --- a/src/MEDCalc/gui/XmedConsoleDriver.cxx +++ b/src/MEDCalc/gui/XmedConsoleDriver.cxx @@ -61,7 +61,7 @@ void XmedConsoleDriver::setup() { commands += ""; commands += "from medcalc.medconsole import saveWorkspace, cleanWorkspace"; commands += "from medcalc.medconsole import putInWorkspace, removeFromWorkspace"; - commands += "from medcalc.medconsole import accessField"; + commands += "from medcalc.medconsole import accessField, view"; commands += "from medcalc.medconsole import getEnvironment, ls, la"; commands += ""; this->exec(commands); diff --git a/src/MEDCalc/tui/medconsole.py b/src/MEDCalc/tui/medconsole.py index 5f2bfbc4b..7ae45231a 100644 --- a/src/MEDCalc/tui/medconsole.py +++ b/src/MEDCalc/tui/medconsole.py @@ -18,6 +18,7 @@ # import medcalc +import MEDCALC dataManager = medcalc.medcorba.factory.getDataManager() @@ -159,3 +160,10 @@ def accessField(fieldHandlerId): """ return medcalc.newFieldProxy(fieldHandlerId) # + +def view(field): + """ + Display the field at its timestep + """ + medcalc.MakeScalarMap(field, viewMode=MEDCALC.VIEW_MODE_REPLACE, scalarBarRange=MEDCALC.SCALAR_BAR_CURRENT_TIMESTEP) + pass -- 2.39.2