From fdd9edc45ff7e3cb06adf2ccfc2c6f214786aa98 Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Thu, 26 Nov 2020 16:42:32 +0100 Subject: [PATCH] Better timestamp management to synchronize the timestamp of the view and the field id - when displaying a field from gui, its id at the current timestamp is used - when displaying a field from tui with its id, the field timestamp is set in the view (and time toolbar) --- idl/MEDDataManager.idl | 4 +- src/MEDCalc/cmp/MEDDataManager_i.cxx | 78 ++++++++++++++++--- src/MEDCalc/cmp/MEDDataManager_i.hxx | 5 +- src/MEDCalc/cmp/MEDPresentation.cxx | 15 ++-- src/MEDCalc/cmp/MEDPresentation.hxx | 2 +- src/MEDCalc/cmp/MEDPresentationContour.cxx | 1 + .../cmp/MEDPresentationDeflectionShape.cxx | 1 + .../cmp/MEDPresentationPointSprite.cxx | 1 + src/MEDCalc/cmp/MEDPresentationScalarMap.cxx | 2 +- src/MEDCalc/cmp/MEDPresentationSlices.cxx | 1 + .../cmp/MEDPresentationVectorField.cxx | 1 + src/MEDCalc/gui/MEDModule.cxx | 8 ++ src/MEDCalc/gui/MEDModule.hxx | 2 + src/MEDCalc/gui/PresentationController.cxx | 11 +-- src/MEDCalc/test/tui/vector_field.py | 5 +- 15 files changed, 107 insertions(+), 30 deletions(-) diff --git a/idl/MEDDataManager.idl b/idl/MEDDataManager.idl index 715c4d9e7..8fa024d34 100644 --- a/idl/MEDDataManager.idl +++ b/idl/MEDDataManager.idl @@ -133,6 +133,8 @@ module MEDCALC FieldseriesHandlerList getFieldseriesListOnMesh(in long meshId); FieldHandlerList getFieldListInFieldseries(in long fieldseriesId); + long getFieldIdAtTimestamp(in long fieldseriesId, in double timestamp); + FieldHandler getFieldHandler(in long fieldHandlerId); FieldHandlerList getFieldHandlerList(); // __GBO__ Maybe it could be useful to define a getFieldHandlerList with a datasourceId in argument @@ -154,7 +156,7 @@ module MEDCALC //void saveFields(in FieldHandlerList fieldHandlerList, in string filepath); - double getFieldTimeStep(in long fieldHandlerId); + double getFieldTimestamp(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 75e082399..1df1e28fd 100644 --- a/src/MEDCalc/cmp/MEDDataManager_i.cxx +++ b/src/MEDCalc/cmp/MEDDataManager_i.cxx @@ -90,6 +90,17 @@ std::string MEDDataManager_i::source_to_file(const char * source) return filepath; } +/*! + * Check if a source (from its uri name) is in a file or in memory + */ +bool MEDDataManager_i::isSourceInFile(const char * sourceName) +{ + std::string sourceString(sourceName); + return (sourceString.substr(0, 7) == std::string("file://")); +} + + + /*! * This function loads the meta-data from the specified med file and * returns the associated datasource handler. The data source handler @@ -323,7 +334,6 @@ MEDCALC::FieldseriesHandlerList * MEDDataManager_i::getFieldseriesListOnMesh(COR * the different time iterations defined for the specified field id. */ MEDCALC::FieldHandlerList * MEDDataManager_i::getFieldListInFieldseries(CORBA::Long fieldseriesId) { - // We initiate a list with the maximum length MEDCALC::FieldHandlerList_var fieldHandlerList = new MEDCALC::FieldHandlerList(); fieldHandlerList->length(_fieldHandlerMap.size()); @@ -343,6 +353,32 @@ MEDCALC::FieldHandlerList * MEDDataManager_i::getFieldListInFieldseries(CORBA::L return fieldHandlerList._retn(); } +/*! + * Get the field id of a field series at a given timestep + */ +CORBA::Long MEDDataManager_i::getFieldIdAtTimestamp(CORBA::Long fieldseriesId, double timestampOfPvAnimation) { + // Scan the map looking for field defined on the specified mesh at given timestep + int itemIdx = 0; + CORBA::Long fieldId = 0; + double timestampOfField; + FieldHandlerMapIterator it; + for ( it=_fieldHandlerMap.begin(); it != _fieldHandlerMap.end(); it++) { + if ( it->second->fieldseriesId == fieldseriesId ) { + if (itemIdx == 0) { + // set the fieldId to the first one in case it is not found + fieldId = it->second->id; + } + timestampOfField = getFieldTimestamp(it->second->id); + if (timestampOfField == timestampOfPvAnimation) { + fieldId = it->second->id; + break; + } + itemIdx++; + } + } + return fieldId; +} + /*! * This returns the whole set of fields handlers for all datasource * that have been loaded using loadDatasource. @@ -589,19 +625,39 @@ long MEDDataManager_i::getUMeshId(const MEDCouplingMesh * mesh) { } /** - * Get the timestep associated to a field + * Get the timestamp associated to a field */ -double MEDDataManager_i::getFieldTimeStep(CORBA::Long fieldHandlerId) +double MEDDataManager_i::getFieldTimestamp(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. + LOG("getFieldTimestamp(" << fieldHandlerId << ")"); + double timestamp(0); MEDCALC::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId); - MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); - double timestamp = fieldDouble->getTime(iteration, order); + + // if the field is in a file, get the timestamp by MEDLoader tiny information + long meshHandlerId = fieldHandler->meshid; + long sourceid = _meshHandlerMap[meshHandlerId]->sourceid; + if (isSourceInFile(fieldHandler->source)) + { + const char * meshSourceUri = (_datasourceHandlerMap[sourceid])->uri; + std::string fileName(source_to_file(meshSourceUri)); + const char * fieldName = fieldHandler->fieldname; + const char * meshName = _meshHandlerMap[meshHandlerId]->name; + timestamp = GetTimeAttachedOnFieldIteration(fileName.c_str(), fieldName, fieldHandler->iteration, fieldHandler->order); + LOG("timestamp in med file is " << timestamp); + } + else + { + // else get the timestamp with MEDCouplingField + 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. + MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler); + timestamp = fieldDouble->getTime(iteration, order); + LOG("timestamp in MEDCouplingFieldDouble is " << timestamp); + } return timestamp; } diff --git a/src/MEDCalc/cmp/MEDDataManager_i.hxx b/src/MEDCalc/cmp/MEDDataManager_i.hxx index 4b0a55c81..8a6ea9571 100644 --- a/src/MEDCalc/cmp/MEDDataManager_i.hxx +++ b/src/MEDCalc/cmp/MEDDataManager_i.hxx @@ -82,6 +82,8 @@ public: MEDCALC_EXPORT MEDCALC::FieldseriesHandlerList * getFieldseriesListOnMesh(CORBA::Long meshId); MEDCALC_EXPORT MEDCALC::FieldHandlerList * getFieldListInFieldseries(CORBA::Long fieldseriesId); + MEDCALC_EXPORT CORBA::Long getFieldIdAtTimestamp(CORBA::Long fieldseriesId, double timestamp); + MEDCALC_EXPORT MEDCALC::FieldHandler * getFieldHandler(CORBA::Long fieldHandlerId); MEDCALC_EXPORT char * getFieldRepresentation(CORBA::Long fieldHandlerId); MEDCALC_EXPORT MEDCALC::FieldHandlerList * getFieldHandlerList(); @@ -156,12 +158,13 @@ private: std::string file_to_source(const char * filepath); std::string source_to_file(const char * source); + bool isSourceInFile(const char * sourceName); long getDatasourceId(const char *filepath); MEDCouplingUMesh * getUMesh(long meshHandlerId); long getUMeshId(const MEDCouplingMesh * mesh); - double getFieldTimeStep(CORBA::Long fieldHandlerId); + double getFieldTimestamp(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 e4b1c01f1..ad2167020 100644 --- a/src/MEDCalc/cmp/MEDPresentation.cxx +++ b/src/MEDCalc/cmp/MEDPresentation.cxx @@ -356,21 +356,24 @@ MEDPresentation::createSource() } /* - * Set the timestep of the animation to the timestep of the field. + * Set the timestamp of the animation to the timestamp 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() +MEDPresentation::setTimestamp() { - // get the timestep of the field - double timestep = MEDFactoryClient::getDataManager()->getFieldTimeStep(_handlerId); + // get the timestamp of the field + double timestamp = MEDFactoryClient::getDataManager()->getFieldTimestamp(_handlerId); + STDLOG("Displaying timestamp : " << timestamp); std::ostringstream oss; - // go to the right timestep in animation (view and VCR toolbar) + // go to the right timestamp in animation (view and VCR toolbar) pushAndExecPyLine("pvs.GetAnimationScene().UpdateAnimationUsingDataTimeSteps()"); - oss << "pvs.GetAnimationScene().AnimationTime = " << timestep << ";"; + oss << "pvs.GetAnimationScene().AnimationTime = " << timestamp << ";"; + pushAndExecPyLine(oss.str()); oss.str(""); + oss << "pvs.GetTimeKeeper().Time = " << timestamp << ";"; pushAndExecPyLine(oss.str()); oss.str(""); } diff --git a/src/MEDCalc/cmp/MEDPresentation.hxx b/src/MEDCalc/cmp/MEDPresentation.hxx index 3a0870626..e6c28cc9b 100644 --- a/src/MEDCalc/cmp/MEDPresentation.hxx +++ b/src/MEDCalc/cmp/MEDPresentation.hxx @@ -84,7 +84,7 @@ protected: // The most common elements of the ParaView pipeline: void setOrCreateRenderView(); void createSource(); - void setTimestep(); + void setTimestamp(); void selectFieldComponent(); void showObject(); void colorBy(); diff --git a/src/MEDCalc/cmp/MEDPresentationContour.cxx b/src/MEDCalc/cmp/MEDPresentationContour.cxx index c7dd7019b..9b4c00d9d 100644 --- a/src/MEDCalc/cmp/MEDPresentationContour.cxx +++ b/src/MEDCalc/cmp/MEDPresentationContour.cxx @@ -64,6 +64,7 @@ MEDPresentationContour::internalGeneratePipeline() MEDPyLockWrapper lock; createSource(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/cmp/MEDPresentationDeflectionShape.cxx b/src/MEDCalc/cmp/MEDPresentationDeflectionShape.cxx index 5bfd0b887..b3a81b05c 100644 --- a/src/MEDCalc/cmp/MEDPresentationDeflectionShape.cxx +++ b/src/MEDCalc/cmp/MEDPresentationDeflectionShape.cxx @@ -62,6 +62,7 @@ MEDPresentationDeflectionShape::internalGeneratePipeline() MEDPyLockWrapper lock; createSource(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/cmp/MEDPresentationPointSprite.cxx b/src/MEDCalc/cmp/MEDPresentationPointSprite.cxx index 5cc2ce0a1..fdc838c41 100644 --- a/src/MEDCalc/cmp/MEDPresentationPointSprite.cxx +++ b/src/MEDCalc/cmp/MEDPresentationPointSprite.cxx @@ -77,6 +77,7 @@ MEDPresentationPointSprite::internalGeneratePipeline() setOrCreateRenderView(); // instantiate __viewXXX createSource(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx b/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx index 654a5cdd5..641d0c96f 100644 --- a/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx +++ b/src/MEDCalc/cmp/MEDPresentationScalarMap.cxx @@ -45,7 +45,7 @@ MEDPresentationScalarMap::internalGeneratePipeline() setOrCreateRenderView(); // instantiate __viewXXX createSource(); - setTimestep(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/cmp/MEDPresentationSlices.cxx b/src/MEDCalc/cmp/MEDPresentationSlices.cxx index bdffc0e8b..87df324b4 100644 --- a/src/MEDCalc/cmp/MEDPresentationSlices.cxx +++ b/src/MEDCalc/cmp/MEDPresentationSlices.cxx @@ -141,6 +141,7 @@ MEDPresentationSlices::internalGeneratePipeline() std::ostringstream oss; createSource(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/cmp/MEDPresentationVectorField.cxx b/src/MEDCalc/cmp/MEDPresentationVectorField.cxx index d2de18b84..5dbd98a38 100644 --- a/src/MEDCalc/cmp/MEDPresentationVectorField.cxx +++ b/src/MEDCalc/cmp/MEDPresentationVectorField.cxx @@ -62,6 +62,7 @@ MEDPresentationVectorField::internalGeneratePipeline() MEDPyLockWrapper lock; createSource(); + setTimestamp(); // Populate internal array of available components: fillAvailableFieldComponents(); diff --git a/src/MEDCalc/gui/MEDModule.cxx b/src/MEDCalc/gui/MEDModule.cxx index 53d274a7e..0401d929e 100644 --- a/src/MEDCalc/gui/MEDModule.cxx +++ b/src/MEDCalc/gui/MEDModule.cxx @@ -53,6 +53,7 @@ #include #include +#include //! The only instance of the reference to engine MED_ORB::MED_Gen_var MEDModule::_MED_engine; @@ -315,6 +316,13 @@ MEDModule::initToolbars() #endif } +double +MEDModule::getCurrentAnimationTimestamp() +{ + double timestamp = pqPVApplicationCore::instance()->animationManager()->getActiveScene()->getAnimationTime(); + return timestamp; +} + void MEDModule::createModuleActions() { _datasourceController->createActions(); diff --git a/src/MEDCalc/gui/MEDModule.hxx b/src/MEDCalc/gui/MEDModule.hxx index d0a9c3ce0..6d5c6dc57 100644 --- a/src/MEDCalc/gui/MEDModule.hxx +++ b/src/MEDCalc/gui/MEDModule.hxx @@ -92,6 +92,8 @@ public: int getIntParamFromStudyEditor(SALOMEDS::SObject_var obj, const char* name); + double getCurrentAnimationTimestamp(); + signals: void presentationSelected(int presId, const QString& presType, const QString& presName); diff --git a/src/MEDCalc/gui/PresentationController.cxx b/src/MEDCalc/gui/PresentationController.cxx index 7ea2bc26d..42b297eed 100644 --- a/src/MEDCalc/gui/PresentationController.cxx +++ b/src/MEDCalc/gui/PresentationController.cxx @@ -294,7 +294,6 @@ PresentationController::visualize(PresentationEvent::EventType eventType) std::string name(_studyEditor->getName(soObj)); if (soObj->_is_nil() || name == "MEDCalc") return; - int fieldId = _salomeModule->getIntParamFromStudyEditor(soObj, FIELD_ID); int meshId = _salomeModule->getIntParamFromStudyEditor(soObj, MESH_ID); MEDCALC::FieldHandler* fieldHandler = 0; @@ -317,12 +316,10 @@ PresentationController::visualize(PresentationEvent::EventType eventType) if ( fieldSeriesId < 0) continue; - MEDCALC::FieldHandlerList* fieldHandlerList = MEDFactoryClient::getDataManager()->getFieldListInFieldseries(fieldSeriesId); - if (fieldHandlerList->length() < 0) - continue; - // For a field series, get the first real field entry: - MEDCALC::FieldHandler fieldHandler = (*fieldHandlerList)[0]; - fieldId = fieldHandler.id; + // get the current timestamp + double timestamp = _salomeModule->getCurrentAnimationTimestamp(); + // get the field id a the current timestamp + fieldId = MEDFactoryClient::getDataManager()->getFieldIdAtTimestamp(fieldSeriesId, timestamp); } fieldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId); } diff --git a/src/MEDCalc/test/tui/vector_field.py b/src/MEDCalc/test/tui/vector_field.py index 9b83a20fc..8e8a626c7 100644 --- a/src/MEDCalc/test/tui/vector_field.py +++ b/src/MEDCalc/test/tui/vector_field.py @@ -30,8 +30,9 @@ from medcalc_testutils import GetMEDFileDirTUI datafile = os.path.join(GetMEDFileDirTUI(), "agitateur.med") source_id = medcalc.LoadDataSource(datafile) -# Field 55 = VITESSE_ELEM_DOM (ON_CELLS) -presentation_id = medcalc.MakeVectorField(accessField(55), viewMode=MEDCALC.VIEW_MODE_REPLACE, +# Field 55 = VITESSE_ELEM_DOM (ON_CELLS) at timestamp 0 +# Field 65 = VITESSE_ELEM_DOM (ON_CELLS) at timestamp 10 +presentation_id = medcalc.MakeVectorField(accessField(65), viewMode=MEDCALC.VIEW_MODE_REPLACE, colorMap=MEDCALC.COLOR_MAP_BLUE_TO_RED_RAINBOW, scalarBarRange=MEDCALC.SCALAR_BAR_CURRENT_TIMESTEP ) -- 2.39.2