Salome HOME
Better timestamp management to synchronize the timestamp of the view and the field id
authorChristophe Bourcier <christophe.bourcier@cea.fr>
Thu, 26 Nov 2020 15:42:32 +0000 (16:42 +0100)
committerChristophe Bourcier <christophe.bourcier@cea.fr>
Thu, 26 Nov 2020 15:42:32 +0000 (16:42 +0100)
- 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)

15 files changed:
idl/MEDDataManager.idl
src/MEDCalc/cmp/MEDDataManager_i.cxx
src/MEDCalc/cmp/MEDDataManager_i.hxx
src/MEDCalc/cmp/MEDPresentation.cxx
src/MEDCalc/cmp/MEDPresentation.hxx
src/MEDCalc/cmp/MEDPresentationContour.cxx
src/MEDCalc/cmp/MEDPresentationDeflectionShape.cxx
src/MEDCalc/cmp/MEDPresentationPointSprite.cxx
src/MEDCalc/cmp/MEDPresentationScalarMap.cxx
src/MEDCalc/cmp/MEDPresentationSlices.cxx
src/MEDCalc/cmp/MEDPresentationVectorField.cxx
src/MEDCalc/gui/MEDModule.cxx
src/MEDCalc/gui/MEDModule.hxx
src/MEDCalc/gui/PresentationController.cxx
src/MEDCalc/test/tui/vector_field.py

index 715c4d9e770b217c1dc1c0abd23761b6e245b1f7..8fa024d3436b86845b82408493ca3bcd7b1c13a6 100644 (file)
@@ -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);
index 75e082399553b3a53a9abf3196187ab8f29c9506..1df1e28fd8c0e5be8cf474aaaddbdaa11da8e3d9 100644 (file)
@@ -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;
 }
 
index 4b0a55c819db417be00c807677ef9be14bcbc646..8a6ea95712e5910a6d16565cf253e154b195fb76 100644 (file)
@@ -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);
index e4b1c01f13d48435fb544923e347205ee1582ac2..ad2167020ce48f31ef9d9923a17f147ea96c1609 100644 (file)
@@ -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("");
 }
 
index 3a0870626ada806748d8c057785633b8d0e7a13f..e6c28cc9b816dd583531dbf896a5445998c550db 100644 (file)
@@ -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();
index c7dd7019bc4cba49d9e14ab56a6eaa7c62ec6773..9b4c00d9d79c341d7d62454caa4dde1743836e72 100644 (file)
@@ -64,6 +64,7 @@ MEDPresentationContour::internalGeneratePipeline()
   MEDPyLockWrapper lock;
 
   createSource();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index 5bfd0b88774b722642d3a294acb6ade07a2bd3c8..b3a81b05c7bab2363944703deb7950749e526b48 100644 (file)
@@ -62,6 +62,7 @@ MEDPresentationDeflectionShape::internalGeneratePipeline()
   MEDPyLockWrapper lock;
 
   createSource();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index 5cc2ce0a120511e06819416d69846cb3532a210a..fdc838c41389933446f0ae3f1d0d4348b02c2383 100644 (file)
@@ -77,6 +77,7 @@ MEDPresentationPointSprite::internalGeneratePipeline()
 
   setOrCreateRenderView(); // instantiate __viewXXX
   createSource();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index 654a5cdd519455ee81a027a7ece929aedd215bc0..641d0c96f384c7fdf0828bb5624e121caa400d74 100644 (file)
@@ -45,7 +45,7 @@ MEDPresentationScalarMap::internalGeneratePipeline()
 
   setOrCreateRenderView(); // instantiate __viewXXX
   createSource();
-  setTimestep();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index bdffc0e8b7cd2b64cca39b1a86fa79bb9f0d139a..87df324b468c232d61afb3d87413dec7bba7cd0f 100644 (file)
@@ -141,6 +141,7 @@ MEDPresentationSlices::internalGeneratePipeline()
   std::ostringstream oss;
 
   createSource();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index d2de18b84e09b503795adf58948f72165b5d85b5..5dbd98a3827f9d5d3f0f4e2d8832cca2d6ee48b8 100644 (file)
@@ -62,6 +62,7 @@ MEDPresentationVectorField::internalGeneratePipeline()
   MEDPyLockWrapper lock;
 
   createSource();
+  setTimestamp();
 
   // Populate internal array of available components:
   fillAvailableFieldComponents();
index 53d274a7ea6d5701b0a36a1a790464305c0958ba..0401d929eb874afb68facc1b9870f0f0c4aed6a3 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <pqAnimationManager.h>
 #include <pqPVApplicationCore.h>
+#include <pqAnimationScene.h>
 
 //! 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();
index d0a9c3ce0bf2bc1a6f02d0040335531566c5d7ce..6d5c6dc57ea07850cf8f2f9ad7784862dd55b813 100644 (file)
@@ -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);
 
index 7ea2bc26de31002bc0ea2e060e6e25bb8182c70a..42b297eedd75711e7bd0eb918d5a37f9ecd90dcb 100644 (file)
@@ -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);
         }
index 9b83a20fca8d5f223c1a9170c5aa3622cc3f60f9..8e8a626c7d33bc500624922679780ff0dbc92901 100644 (file)
@@ -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
                                           )