Salome HOME
#28928 [CEA] FIELDS : developer documentation for the simplified visualisation
[modules/med.git] / src / MEDCalc / gui / PresentationController.cxx
index ffd9bab25867669160df4cd6d93aeaed4afd0bda..93c5eef0c191c752a5adb6654b1f59368f789503 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016  CEA/DEN, EDF R&D
+// Copyright (C) 2016-2021  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include "MEDPresentationScalarMap.hxx"
 #include "MEDPresentationContour.hxx"
 #include "MEDPresentationSlices.hxx"
+#include "MEDPresentationPointSprite.hxx"
+#include "MEDPresentationVectorField.hxx"
+#include "MEDPresentationPlot3D.hxx"
+#include "MEDPresentationStreamLines.hxx"
+#include "MEDPresentationCutSegment.hxx"
+#include "MEDPresentationDeflectionShape.hxx"
 
 #include "MEDWidgetHelperMeshView.hxx"
 #include "MEDWidgetHelperScalarMap.hxx"
 #include "MEDWidgetHelperContour.hxx"
 #include "MEDWidgetHelperSlices.hxx"
+#include "MEDWidgetHelperPointSprite.hxx"
+#include "MEDWidgetHelperPlot3D.hxx"
+#include "MEDWidgetHelperStreamLines.hxx"
+#include "MEDWidgetHelperCutSegment.hxx"
+#include "MEDWidgetHelperVectorField.hxx"
+#include "MEDWidgetHelperDeflectionShape.hxx"
 
 #include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
 #include <SalomeApp_DataObject.h>
 
+#include <SALOME_ListIO.hxx>
+#include <LightApp_SelectionMgr.h>
+
 #include <SALOMEDS_SObject.hxx>
 #include <SALOMEDS_Study.hxx>
 
@@ -49,6 +64,7 @@
 #include <SUIT_ResourceMgr.h>
 #include <QMessageBox>
 #include <sstream>
+#include <regex>
 
 #include "MEDFactoryClient.hxx"
 
@@ -101,21 +117,6 @@ PresentationController::~PresentationController()
     delete((*it).second);
 }
 
-/**
- * [ABN] Created this probably because I don't know the right way to deal with non existent
- * attributes in an object from the study ...
- */
-int
-PresentationController::getIntParamFromStudyEditor(SALOMEDS::SObject_var obj, const char * name)
-{
-  int theInt = -1;
-  try {
-      theInt = _studyEditor->getParameterInt(obj,name);
-  }
-  catch(...)  {  }
-  return theInt;
-}
-
 std::string
 PresentationController::_getIconName(const std::string& name)
 {
@@ -172,7 +173,7 @@ PresentationController::createActions()
 
   // Presentations
   int presentationToolbarId = _salomeModule->createTool("Presentations", "PresentationToolbar");
-  int presentationMenuId = _salomeModule->createMenu(tr("MENU_PRESENTATIONS"), -1, 1);
+  int presentationMenuId = _salomeModule->createMenu(tr("MENU_PRESENTATIONS"), -1, -1, 10);
 
   label   = tr("LAB_PRESENTATION_MESH_VIEW");
   tooltip = tr("TIP_PRESENTATION_MESH_VIEW");
@@ -186,7 +187,8 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_SCALAR_MAP");
   tooltip = tr("TIP_PRESENTATION_SCALAR_MAP");
   icon = tr(_getIconName("ICO_PRESENTATION_SCALAR_MAP").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeScalarMap()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeScalarMap()),
+                                                 icon, tooltip, FIELDSOp::OpScalarMap);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
@@ -194,7 +196,8 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_CONTOUR");
   tooltip = tr("TIP_PRESENTATION_CONTOUR");
   icon    = tr(_getIconName("ICO_PRESENTATION_CONTOUR").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeContour()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeContour()),
+                                                 icon, tooltip, FIELDSOp::OpContour);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
@@ -202,7 +205,8 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_VECTOR_FIELD");
   tooltip = tr("TIP_PRESENTATION_VECTOR_FIELD");
   icon    = tr(_getIconName("ICO_PRESENTATION_VECTOR_FIELD").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeVectorField()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeVectorField()),
+                                                 icon, tooltip, FIELDSOp::OpVectorFields);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
@@ -210,7 +214,8 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_SLICES");
   tooltip = tr("TIP_PRESENTATION_SLICES");
   icon    = tr(_getIconName("ICO_PRESENTATION_SLICES").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeSlices()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeSlices()),
+                                                 icon, tooltip, FIELDSOp::OpSlices);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
@@ -218,7 +223,8 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_DEFLECTION_SHAPE");
   tooltip = tr("TIP_PRESENTATION_DEFLECTION_SHAPE");
   icon    = tr(_getIconName("ICO_PRESENTATION_DEFLECTION_SHAPE").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeDeflectionShape()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeDeflectionShape()),
+                                                 icon, tooltip, FIELDSOp::OpDeflectionShape);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
@@ -226,31 +232,62 @@ PresentationController::createActions()
   label   = tr("LAB_PRESENTATION_POINT_SPRITE");
   tooltip = tr("TIP_PRESENTATION_POINT_SPRITE");
   icon    = tr(_getIconName("ICO_PRESENTATION_POINT_SPRITE").c_str());
-  actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizePointSprite()),icon,tooltip);
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizePointSprite()),
+                                                 icon, tooltip, FIELDSOp::OpPointSprite);
+  _salomeModule->createTool(actionId, presentationToolbarId);
+  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
+  _salomeModule->createMenu(actionId, presentationMenuId);
+
+  // sphinx doc: begin of plot3d gui items
+  label   = tr("LAB_PRESENTATION_PLOT3D");
+  tooltip = tr("TIP_PRESENTATION_PLOT3D");
+  icon    = tr(_getIconName("ICO_PRESENTATION_PLOT3D").c_str());
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizePlot3D()),
+                                                 icon, tooltip, FIELDSOp::OpPlot3D);
+  _salomeModule->createTool(actionId, presentationToolbarId);
+  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
+  _salomeModule->createMenu(actionId, presentationMenuId);
+  // sphinx doc: end of plot3d gui items
+
+  label   = tr("LAB_PRESENTATION_STREAM_LINES");
+  tooltip = tr("TIP_PRESENTATION_STREAM_LINES");
+  icon    = tr(_getIconName("ICO_PRESENTATION_STREAM_LINES").c_str());
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeStreamLines()),
+                                                 icon, tooltip, FIELDSOp::OpStreamLines);
+  _salomeModule->createTool(actionId, presentationToolbarId);
+  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
+  _salomeModule->createMenu(actionId, presentationMenuId);
+
+  label   = tr("LAB_PRESENTATION_CUT_SEGMENT");
+  tooltip = tr("TIP_PRESENTATION_CUT_SEGMENT");
+  icon    = tr(_getIconName("ICO_PRESENTATION_CUT_SEGMENT").c_str());
+  actionId = _salomeModule->createStandardAction(label, this, SLOT(onVisualizeCutSegment()),
+                                                 icon, tooltip, FIELDSOp::OpCutSegment);
   _salomeModule->createTool(actionId, presentationToolbarId);
   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
 
+
   // Separator
   _salomeModule->createMenu(_salomeModule->separator(), presentationMenuId);
 
   label   = tr("LAB_DELETE_PRESENTATION");
   tooltip = tr("TIP_DELETE_PRESENTATION");
-  icon    = tr(_getIconName("ICO_DELETE_PRESENTATION").c_str());
+  icon    = tr("ICO_DELETE_PRESENTATION");
   actionId = _salomeModule->createStandardAction(label,this, SLOT(onDeletePresentation()),icon,tooltip);
   //  _salomeModule->createTool(actionId, presentationToolbarId);
   //  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
   _salomeModule->createMenu(actionId, presentationMenuId);
 
-  //
-  // Actions for popup menu only
-  //
   // Low level PARAVIS dump
   label = tr("LAB_PARAVIS_DUMP");
-  //icon  = tr("ICO_DATASOURCE_EXPAND_FIELD");
+  tooltip = tr("TIP_PARAVIS_DUMP");
   actionId = _salomeModule->createStandardAction(label,this,SLOT(onParavisDump()),"");
-  _salomeModule->addActionInPopupMenu(actionId);
+  _salomeModule->createMenu(actionId, presentationMenuId);
 
+  //
+  // Actions for popup menu only
+  //
 
 }
 
@@ -289,44 +326,58 @@ PresentationController::getSelectedScalarBarRange() const
 void
 PresentationController::visualize(PresentationEvent::EventType eventType)
 {
-  // We need a _studyEditor updated on the active study
-  _studyEditor->updateActiveStudy();
-
   // Get the selected objects in the study (SObject)
   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
 
   // For each object, emit a signal to the workspace to request a
   // visualisation using the tui command (so that the user can see how
   // to make a view of an object from the tui console).
-  for (int i=0; i<listOfSObject->size(); i++) {
-      SALOMEDS::SObject_var soField = listOfSObject->at(i);
-      int fieldId = getIntParamFromStudyEditor(soField, FIELD_ID);
-      if (fieldId < 0)  // is it a field serie ?
+  for (int i=0; i<(int)listOfSObject->size(); i++) {
+      SALOMEDS::SObject_var soObj = listOfSObject->at(i);
+      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;
+      MEDCALC::MeshHandler* meshHandler = 0;
+
+      // is it a mesh?
+      if (meshId >= 0)
         {
-          int fieldSeriesId = getIntParamFromStudyEditor(soField, FIELD_SERIES_ID);
-          // If fieldId and fieldSeriesId equals -1, then it means that it is not a field
-          // managed by the MED module, and we stop this function process.
-          if ( fieldSeriesId < 0)
+          if (eventType != PresentationEvent::EVENT_VIEW_OBJECT_MESH_VIEW)
             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;
+          meshHandler = MEDFactoryClient::getDataManager()->getMeshHandler(meshId);
+        }
+      else
+        {
+          if (fieldId < 0)  // is it a field series?
+            {
+              int fieldSeriesId = _salomeModule->getIntParamFromStudyEditor(soObj, FIELD_SERIES_ID);
+              // If fieldId and fieldSeriesId equals -1, then it means that it is not a field
+              // managed by the MED module, and we stop this function process.
+              if ( fieldSeriesId < 0)
+                  continue;
+
+              // 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);
         }
 
-      MEDCALC::FieldHandler* fieldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
-      if (! fieldHandler) {
+      if ((!fieldHandler) && (!meshHandler)) {
           QMessageBox::warning(_salomeModule->getApp()->desktop(),
                                tr("Operation not allowed"),
-                               tr("No field is defined"));
+                               tr("No field (or mesh) is defined"));
           return;
       }
 
       PresentationEvent* event = new PresentationEvent();
       event->eventtype = eventType;
       event->fieldHandler = fieldHandler;
+      event->meshHandler = meshHandler;
       emit presentationSignal(event); // --> processPresentationEvent()
   }
 }
@@ -373,19 +424,44 @@ PresentationController::onVisualizePointSprite()
   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE);
 }
 
+// sphinx doc: begin of onVisualizePlot3D
 void
-PresentationController::onDeletePresentation()
+PresentationController::onVisualizePlot3D()
+{
+  this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_PLOT3D);
+}
+// sphinx doc: end of onVisualizePlot3D
+
+void
+PresentationController::onVisualizeStreamLines()
 {
-  // We need a _studyEditor updated on the active study
-  _studyEditor->updateActiveStudy();
+  this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_STREAM_LINES);
+}
+
+void
+PresentationController::onVisualizeCutSegment()
+{
+  // Cut segment presentation "creates" new view, so switch off visibility state update 
+  // because pqActiveObjects::viewChanged is emmited 
+  _salomeModule->visibilityStateUpdateOff();
+  this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_CUT_SEGMENT);
+  _salomeModule->visibilityStateUpdateOn();
+  _salomeModule->updateVisibilityState();
+}
 
+void
+PresentationController::onDeletePresentation()
+{
   // Get the selected objects in the study (SObject)
   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
 
   // For each object, emit a signal to the workspace to request pres deletion
-  for (int i=0; i<listOfSObject->size(); i++) {
+  for (int i=0; i<(int)listOfSObject->size(); i++) {
       SALOMEDS::SObject_var soPres = listOfSObject->at(i);
-      int presId = getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
+      std::string name(_studyEditor->getName(soPres));
+      if (soPres->_is_nil() || name == "MEDCalc")
+        return;
+      int presId = _salomeModule->getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
       // If fieldId equals -1, then it means that it is not a field
       // managed by the MED module, and we stop this function process.
       if ( presId < 0 )
@@ -425,10 +501,11 @@ PresentationController::getColorMapPython() const
 QString
 PresentationController::getScalarBarRangePython() const
 {
-  MEDCALC::ScalarBarRangeType colorMap = getSelectedScalarBarRange();
-  switch(colorMap) {
+  MEDCALC::ScalarBarRangeType scalarBarRange = getSelectedScalarBarRange();
+  switch(scalarBarRange) {
     case MEDCALC::SCALAR_BAR_ALL_TIMESTEPS: return "MEDCALC.SCALAR_BAR_ALL_TIMESTEPS";
     case MEDCALC::SCALAR_BAR_CURRENT_TIMESTEP: return "MEDCALC.SCALAR_BAR_CURRENT_TIMESTEP";
+    case MEDCALC::SCALAR_BAR_CUSTOM_RANGE: return "MEDCALC.SCALAR_BAR_CUSTOM_RANGE";
   }
   return QString();
 }
@@ -461,6 +538,19 @@ PresentationController::getSliceOrientationPython(const int orientation) const
   return QString();
 }
 
+QString
+PresentationController::getIntegrDirTypePython(const int intDir) const
+{
+  MEDCALC::IntegrationDirType type = static_cast<MEDCALC::IntegrationDirType>(intDir);
+  switch(type) {
+    case MEDCALC::INTEGRATION_DIR_BOTH:     return "MEDCALC.INTEGRATION_DIR_BOTH";
+    case MEDCALC::INTEGRATION_DIR_FORWARD:  return "MEDCALC.INTEGRATION_DIR_FORWARD";
+    case MEDCALC::INTEGRATION_DIR_BACKWARD: return "MEDCALC.INTEGRATION_DIR_BACKWARD";
+  }
+  return QString();
+}
+
+
 std::string
 PresentationController::getPresTypeFromWidgetHelper(int presId) const
 {
@@ -470,6 +560,12 @@ PresentationController::getPresTypeFromWidgetHelper(int presId) const
   return "UNKNOWN";
 }
 
+void
+PresentationController::emitPresentationSignal(const PresentationEvent* event) 
+{
+  emit presentationSignal(event);
+}
+
 void
 PresentationController::processPresentationEvent(const PresentationEvent* event) {
   // --> Send commands to SALOME Python console
@@ -478,9 +574,15 @@ PresentationController::processPresentationEvent(const PresentationEvent* event)
   QString scalarBarRange = getScalarBarRangePython();
   MEDCALC::FieldHandler* fieldHandler = event->fieldHandler;
   QStringList commands;
+
+  // [ABN] using event mechanism for all this is awkward? TODO: direct implementation in each
+  // dedicated widget helper class?
+
   if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_MESH_VIEW ) {
-        commands += QString("presentation_id = medcalc.MakeMeshView(accessField(%1), viewMode=%2)").arg(fieldHandler->id).arg(viewMode);
-        commands += QString("presentation_id");
+      // Do we request mesh view from a field or from a mesh only?
+      int meshId = event->meshHandler ? event->meshHandler->id : event->fieldHandler->meshid;
+      commands += QString("presentation_id = medcalc.MakeMeshView(%1, viewMode=%2)").arg(meshId).arg(viewMode);
+      commands += QString("presentation_id");
     }
   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SCALAR_MAP ) {
       commands += QString("presentation_id = medcalc.MakeScalarMap(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
@@ -489,29 +591,48 @@ PresentationController::processPresentationEvent(const PresentationEvent* event)
   }
   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_CONTOUR ) {
       commands += QString("presentation_id = medcalc.MakeContour(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
-        .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+            .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
       commands += QString("presentation_id");
   }
-  //  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD ) {
-  //    commands += QString("presentation_id = medcalc.MakeVectorField(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
-  //    commands += QString("presentation_id");
-  //  }
-    else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SLICES ) {
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SLICES ) {
       commands += QString("presentation_id = medcalc.MakeSlices(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
-        .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+            .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
       commands += QString("presentation_id");
-    }
-  //  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE ) {
-  //    commands += QString("presentation_id = medcalc.MakeDeflectionShape(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
-  //    commands += QString("presentation_id");
-  //  }
-  //  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE ) {
-  //    commands += QString("presentation_id = medcalc.MakePointSprite(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
-  //    commands += QString("presentation_id");
-  //  }
-
-  // [ABN] using event mechanism for this is awkward? TODO: direct implementation in each
-  // dedicated widget helper class?
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD ) {
+      commands += QString("presentation_id = medcalc.MakeVectorField(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+          .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE ) {
+      commands += QString("presentation_id = medcalc.MakePointSprite(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+              .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+  // sphinx doc: begin of plot3d prs creation
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_PLOT3D ) {
+      commands += QString("presentation_id = medcalc.MakePlot3D(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+              .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+  // sphinx doc: end of plot3d prs creation
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_STREAM_LINES ) {
+      commands += QString("presentation_id = medcalc.MakeStreamLines(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+              .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_CUT_SEGMENT ) {
+      commands += QString("presentation_id = medcalc.MakeCutSegment(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+              .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE ) {
+      commands += QString("presentation_id = medcalc.MakeDeflectionShape(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
+          .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
+      commands += QString("presentation_id");
+  }
+
+
   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_COMPONENT ) {
       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
       commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
@@ -525,9 +646,20 @@ PresentationController::processPresentationEvent(const PresentationEvent* event)
       commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
   }
   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_TIME_RANGE ) {
+      bool customRangeFlag =
+        (bool)_presManager->getPresentationIntProperty(event->presentationId, MEDPresentation::PROP_HIDE_DATA_OUTSIDE_CUSTOM_RANGE.c_str());
       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
       commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
       commands += QString("params.scalarBarRange = %1").arg(getScalarBarRangePython());
+      if (getSelectedScalarBarRange() == MEDCALC::SCALAR_BAR_CUSTOM_RANGE) {
+        commands += QString("params.scalarBarRangeArray = [%1, %2]").arg(event->aDouble1).arg(event->aDouble2);
+      }
+      else {
+        if (customRangeFlag) // switch off hideDataOutsideCustomRange
+        {
+          commands += QString("params.hideDataOutsideCustomRange = False");
+        }
+      }
       commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
   }
   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_NB_CONTOUR ) {
@@ -554,9 +686,100 @@ PresentationController::processPresentationEvent(const PresentationEvent* event)
       commands += QString("params.orientation = %1").arg(getSliceOrientationPython(event->anInteger));
       commands += QString("medcalc.UpdateSlices(%1, params)").arg(event->presentationId);
   }
+  // sphinx doc: begin of plot3d prs update
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_PLANE_POS ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetPlot3DParameters(%2)").arg(event->presentationId);
+      commands += QString("params.planePos = %1").arg(event->aDouble3);
+      commands += QString("medcalc.UpdatePlot3D(%1, params)").arg(event->presentationId);
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_NORMAL ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetPlot3DParameters(%2)").arg(event->presentationId);
+      commands += QString("params.planeNormal = [%1, %2, %3]").arg(event->aDoubleN[0]).arg(event->aDoubleN[1]).arg(event->aDoubleN[2]);
+      commands += QString("medcalc.UpdatePlot3D(%1, params)").arg(event->presentationId);
+  }
+  // sphinx doc: end of plot3d prs update
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_CUT_POINT1 ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetCutSegmentParameters(%2)").arg(event->presentationId);
+      commands += QString("params.point1 = [%1, %2, %3]").arg(event->aDoubleP1[0]).arg(event->aDoubleP1[1]).arg(event->aDoubleP1[2]);
+      commands += QString("medcalc.UpdateCutSegment(%1, params)").arg(event->presentationId);
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_CUT_POINT2 ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetCutSegmentParameters(%2)").arg(event->presentationId);
+      commands += QString("params.point2 = [%1, %2, %3]").arg(event->aDoubleP2[0]).arg(event->aDoubleP2[1]).arg(event->aDoubleP2[2]);
+      commands += QString("medcalc.UpdateCutSegment(%1, params)").arg(event->presentationId);
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_INTEGR_DIR ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetStreamLinesParameters(%2)").arg(event->presentationId);
+      commands += QString("params.integrDir = %1").arg(getIntegrDirTypePython(event->anInteger));
+      commands += QString("medcalc.UpdateStreamLines(%1, params)").arg(event->presentationId);
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_CONTOUR_COMPONENT) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetContourParameters(%2)").arg(event->presentationId);
+      commands += QString("params.contourComponent = '%1'").arg(event->aString.c_str());
+      commands += QString("medcalc.UpdateContour(%1, params)").arg(event->presentationId);
+  }
+  else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_SCALE_FACTOR ) {
+      std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+      commands += QString("params = medcalc.GetVectorFieldParameters(%2)").arg(event->presentationId);
+      commands += QString("params.scaleFactor = %1").arg(event->aDouble3);
+      commands += QString("medcalc.UpdateVectorField(%1, params)").arg(event->presentationId);
+  }
+
+  else if (event->eventtype == PresentationEvent::EVENT_CHANGE_CUSTOM_SCALE_FACTOR) {
+  std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+  commands += QString("params = medcalc.GetVectorFieldParameters(%2)").arg(event->presentationId);
+  commands += QString("params.customScaleFactor = %1").arg(event->anInteger);
+  if(event->anInteger) {
+    commands += QString("params.scaleFactor = %1").arg(event->aDouble3);
+  }
+  commands += QString("medcalc.UpdateVectorField(%1, params)").arg(event->presentationId);
+  }
 
   else if ( event->eventtype == PresentationEvent::EVENT_DELETE_PRESENTATION ) {
       commands += QString("medcalc.RemovePresentation(%1)").arg(event->presentationId);
+
+  }
+  else if (event->eventtype == PresentationEvent::EVENT_DISPLAY_PRESENTATION ||
+           event->eventtype == PresentationEvent::EVENT_ERASE_PRESENTATION) {
+    commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(getPresTypeFromWidgetHelper(event->presentationId)))
+      .arg(event->presentationId);
+    QString visility = event->eventtype == PresentationEvent::EVENT_DISPLAY_PRESENTATION ? QString("True") : QString("False");
+    commands += QString("params.visibility = %1").arg(visility);
+    commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(getPresTypeFromWidgetHelper(event->presentationId)))
+      .arg(event->presentationId);
+  }
+  else if (event->eventtype == PresentationEvent::EVENT_SCALAR_BAR_VISIBILITY_CHANGED ||
+           event->eventtype == PresentationEvent::EVENT_HIDE_DATA_OUTSIDE_CUSTOM_RANGE_CHANGED) {
+    std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+    QString param;
+    switch (event->eventtype) {
+    case PresentationEvent::EVENT_SCALAR_BAR_VISIBILITY_CHANGED: 
+      param = QString("scalarBarVisibility"); 
+      break;
+    case PresentationEvent::EVENT_HIDE_DATA_OUTSIDE_CUSTOM_RANGE_CHANGED:
+      param = QString("hideDataOutsideCustomRange"); 
+      break;
+    default: break;
+    }
+    commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
+    commands += QString("params.%1 = %2").arg(param).arg( event->anInteger ? QString("True") : QString("False"));
+    if (event->eventtype == PresentationEvent::EVENT_HIDE_DATA_OUTSIDE_CUSTOM_RANGE_CHANGED && event->anInteger) {
+      commands += QString("params.scalarBarRangeArray = [%1, %2]").arg(event->aDouble1).arg(event->aDouble2);
+    }
+    commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
+  }
+  else if (event->eventtype == PresentationEvent::EVENT_CUSTOM_RANGE_CHANGED)
+  {
+  std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
+    commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
+    commands += QString("params.scalarBarRangeArray = [%1, %2]").arg(event->aDouble1).arg(event->aDouble2);
+    commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
   }
   else {
       STDLOG("The event "<<event->eventtype<<" is not implemented yet");
@@ -565,13 +788,13 @@ PresentationController::processPresentationEvent(const PresentationEvent* event)
 }
 
 MEDWidgetHelper *
-PresentationController::findOrCreateWidgetHelper(MEDCALC::MEDPresentationManager_ptr presManager,
+PresentationController::findOrCreateWidgetHelper(MEDCALC::MEDPresentationManager_ptr /*presManager*/,                  // todo: unused
                                                  int presId, const std::string& type, const std::string& name )
 {
   std::map<int, MEDWidgetHelper *>::const_iterator it =_presHelperMap.find(presId);
   if (it != _presHelperMap.end())
     return (*it).second;
-  MEDWidgetHelper * wh;
+  MEDWidgetHelper * wh = 0;
   if (type == MEDPresentationMeshView::TYPE_NAME)
     wh = new MEDWidgetHelperMeshView(this, _presManager, presId, name, _widgetPresentationParameters);
   else if (type == MEDPresentationScalarMap::TYPE_NAME)
@@ -579,10 +802,23 @@ PresentationController::findOrCreateWidgetHelper(MEDCALC::MEDPresentationManager
   else if (type == MEDPresentationContour::TYPE_NAME)
     wh = new MEDWidgetHelperContour(this, _presManager, presId, name, _widgetPresentationParameters);
   else if (type == MEDPresentationSlices::TYPE_NAME)
-      wh = new MEDWidgetHelperSlices(this, _presManager, presId, name, _widgetPresentationParameters);
+    wh = new MEDWidgetHelperSlices(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationVectorField::TYPE_NAME)
+    wh = new MEDWidgetHelperVectorField(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationPointSprite::TYPE_NAME)
+    wh = new MEDWidgetHelperPointSprite(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationPlot3D::TYPE_NAME)
+    wh = new MEDWidgetHelperPlot3D(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationStreamLines::TYPE_NAME)
+    wh = new MEDWidgetHelperStreamLines(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationCutSegment::TYPE_NAME)
+    wh = new MEDWidgetHelperCutSegment(this, _presManager, presId, name, _widgetPresentationParameters);
+  else if (type == MEDPresentationDeflectionShape::TYPE_NAME)
+    wh = new MEDWidgetHelperDeflectionShape(this, _presManager, presId, name, _widgetPresentationParameters);
   else
     {
       STDLOG("findOrCreateWidgetHelper(): NOT IMPLEMENTED !!!");
+      return wh;
     }
   _presHelperMap[presId] = wh;
   return wh;
@@ -602,43 +838,45 @@ PresentationController::onPresentationSelected(int presId, const QString& presTy
     }
   else
     {
+      if(_currentWidgetHelper)
+        _currentWidgetHelper->releaseWidget();
       // Activate corresponding ParaView render view
       _presManager->activateView(presId);
       // Update widgets parameters
       _currentWidgetHelper = findOrCreateWidgetHelper(_presManager, presId, presType.toStdString(), presName.toStdString());
-      _currentWidgetHelper->udpateWidget();
+      _currentWidgetHelper->updateWidget(true);
     }
 }
 
 void
 PresentationController::onParavisDump()
 {
-  // We need a _studyEditor updated on the active study
-  _studyEditor->updateActiveStudy();
-
   // Get the selected objects in the study (SObject)
   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
 
   // For the first object only, request the dump
-  for (int i=0; i<listOfSObject->size(); i++) {
+  for (int i=0; i<(int)listOfSObject->size(); i++) {
       SALOMEDS::SObject_var soPres = listOfSObject->at(i);
-      int presId = getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
+      std::string name(_studyEditor->getName(soPres));
+      if (soPres->_is_nil() || name == "MEDCalc")
+        return;
+      int presId = _salomeModule->getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
       // If fieldId equals -1, then it means that it is not a field
       // managed by the MED module, and we stop this function process.
       if ( presId < 0 )
         continue;
 
       std::string dump(_presManager->getParavisDump(presId));
-      std::cerr << "#====== ParaVis dump =============== " << std::endl;
+      std::cerr << "#====== ParaVis dump (presentation "  << presId << ") =====" << std::endl;
       std::cerr << dump;
-      std::cerr << "#====== End of ParaVis dump ======== " << std::endl;
+      std::cerr << "#====== End of ParaVis dump =============== " << std::endl;
 
       break; // stop at the first one
   }
 }
 
 void
-PresentationController::updateTreeViewWithNewPresentation(long fieldId, long presentationId)
+PresentationController::updateTreeViewWithNewPresentation(long dataId, long presentationId)
 {
   if (presentationId < 0) {
       std::cerr << "Unknown presentation\n";
@@ -656,40 +894,35 @@ PresentationController::updateTreeViewWithNewPresentation(long fieldId, long pre
   name = tr(name.c_str()).toStdString();
   oss << name << " (" << presentationId << ")";
 
-  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
-  _PTR(Study) studyDS = study->studyDS();
-
-  _salomeModule->engine()->registerPresentation(_CAST(Study, studyDS)->GetStudy(), fieldId,
-      oss.str().c_str(), type.c_str(),ico.c_str(), presentationId);
-
-
-  //  MEDCALC::ViewModeType viewMode = MEDFactoryClient::getPresentationManager()->getPresentationViewMode(presentationId);
-  //
-  //  // Remove sibling presentations if view mode is set to REPLACE
-  //  if (viewMode == MEDCALC::VIEW_MODE_REPLACE) {
-  //    MED_ORB::PresentationsList* presList = _salomeModule->engine()->getSiblingPresentations(_CAST(Study, studyDS)->GetStudy(), presentationId);
-  //    CORBA::ULong size = presList->length();
-  //
-  //    std::stringstream sstm;
-  //    sstm << "Removing sibling presentation(s): ";
-  //    for (int i = 0; i < size; ++i)
-  //      sstm << (*presList)[i] << "  ";
-  //    STDLOG(sstm.str());
-  //
-  //    for (int i = 0; i < size; ++i) {
-  //      PresentationEvent* event = new PresentationEvent();
-  //      event->eventtype = PresentationEvent::EVENT_DELETE_PRESENTATION;
-  //      XmedDataObject* dataObject = new XmedDataObject();
-  //      dataObject->setPresentationId((*presList)[i]);
-  //      event->objectdata = dataObject;
-  //      emit presentationSignal(event); // --> WorkspaceController::processPresentationEvent
-  //    }
-  //
-  //    delete presList;
-  //  }
+  // Mesh views are always registered at the mesh level:
+  if (type == MEDPresentationMeshView::TYPE_NAME)
+    {
+      _salomeModule->engine()->registerPresentationMesh(dataId, oss.str().c_str(), type.c_str(),ico.c_str(), presentationId);
+    }
+  else
+    _salomeModule->engine()->registerPresentationField(dataId, oss.str().c_str(), type.c_str(),ico.c_str(), presentationId);
 
   // update Object browser
   _salomeModule->getApp()->updateObjectBrowser(true);
+
+  // auto-select new presentation
+  std::string entry = _salomeModule->engine()->getStudyPresentationEntry(presentationId);
+  SALOME_ListIO selectedObjects;
+  LightApp_Study* lightStudy = dynamic_cast<LightApp_Study*>( _salomeModule->application()->activeStudy() );
+  QString component = lightStudy->componentDataType( entry.c_str() );
+  selectedObjects.Append( new SALOME_InteractiveObject( (const char*)entry.c_str(),
+                                                        (const char*)component.toLatin1(),
+                                                        ""/*refobj->Name().c_str()*/ ) );
+  //QStringList selectedObjects;
+  //selectedObjects << QString(entry.c_str());
+  LightApp_SelectionMgr* aSelectionMgr = _salomeModule->getApp()->selectionMgr();
+  aSelectionMgr->setSelectedObjects(selectedObjects, false);
+
+  // emit onPresentationSelected
+  int presId = -1;
+  _salomeModule->itemClickGeneric(name, type, presId);
+  onPresentationSelected(presId, QString::fromStdString(type), QString::fromStdString(name));
+  updateVisibilityState(presId);
 }
 
 void
@@ -700,41 +933,63 @@ PresentationController::updateTreeViewForPresentationRemoval(long presentationId
       return;
   }
 
-  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
-  _PTR(Study) studyDS = study->studyDS();
-
-  _salomeModule->engine()->unregisterPresentation(_CAST(Study, studyDS)->GetStudy(), presentationId);
+  _salomeModule->engine()->unregisterPresentation(presentationId);
 
   // update Object browser
   _salomeModule->getApp()->updateObjectBrowser(true);
 }
 
+void
+PresentationController::_dealWithReplaceMode()
+{
+  // Deal with replace mode: presentations with invalid IDs have to be removed:
+
+  MEDCALC::PresentationsList * lstManager = _presManager->getAllPresentations();
+  MED_ORB::PresentationsList * lstModule = _salomeModule->engine()->getStudyPresentations();
+  // The IDs not in the intersection needs deletion:
+  CORBA::Long * last = lstManager->get_buffer() + lstManager->length();
+  for (unsigned i = 0; i < lstModule->length(); i++) {
+    CORBA::Long * ptr = std::find(lstManager->get_buffer(), last, (*lstModule)[i]);
+    if (ptr == last) {
+      STDLOG("Removing pres " << (*lstModule)[i] << " from OB.");
+      // Presentation in module but not in manager anymore: to be deleted from OB:
+      updateTreeViewForPresentationRemoval((*lstModule)[i]);
+    }
+  }
+}
+
 void
 PresentationController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
 {
   if ( event->type == MEDCALC::EVENT_ADD_PRESENTATION ) {
-    updateTreeViewWithNewPresentation(event->dataId, event->presentationId);
-    // Deal with replace mode: presentations with invalid IDs have to be removed:
-    SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
-    _PTR(Study) studyDS = study->studyDS();
-
-    MEDCALC::PresentationsList * lstManager = _presManager->getAllPresentations();
-    MED_ORB::PresentationsList * lstModule = _salomeModule->engine()->getStudyPresentations(_CAST(Study, studyDS)->GetStudy());
-    // The IDs not in the intersection needs deletion:
-    CORBA::Long * last = lstManager->get_buffer() + lstManager->length();
-    for (unsigned i = 0; i < lstModule->length(); i++)
-      {
-        CORBA::Long * ptr = std::find(lstManager->get_buffer(), last, (*lstModule)[i]);
-        if (ptr == last)
-          {
-            STDLOG("Removing pres " << (*lstModule)[i] << " from OB.");
-          // Presentation in module but not in manager anymore: to be deleted from OB:
-          updateTreeViewForPresentationRemoval((*lstModule)[i]);
-          }
-      }
+    if (event->dataId == -1) {
+      // A file has been loaded, and we want to create a default presentation (MeshView) for it
+      QString viewMode = getViewModePython();
+      QStringList commands;
+      commands += QString("presentation_id = medcalc.MakeMeshView(medcalc.GetFirstMeshFromDataSource(source_id), viewMode=%1)").arg(viewMode);
+      commands += QString("presentation_id");
+      _consoleDriver->exec(commands);
+    }
+    else {
+      updateTreeViewWithNewPresentation(event->dataId, event->presentationId);
+      _dealWithReplaceMode();
+      // Update parameter widget if shown: some parameters should be updated after presentation has been added
+      if (_currentWidgetHelper)
+        _currentWidgetHelper->updateWidget(false);
+    }
   }
   else if ( event->type == MEDCALC::EVENT_REMOVE_PRESENTATION ) {
       updateTreeViewForPresentationRemoval(event->presentationId);
+      // Hide parameter widget if necessary:
+      onPresentationSelected(-1, "", "");
+  }
+  else if ( event->type == MEDCALC::EVENT_MODIFY_PRESENTATION ) {
+      // Update parameter widget if shown:
+      if(_currentWidgetHelper)
+        _currentWidgetHelper->updateWidget(false);
+  }
+  else if (event->type == MEDCALC::EVENT_VISIBILITY_CHANGED) {
+    updateVisibilityState(event->presentationId);
   }
 }
 
@@ -744,3 +999,16 @@ PresentationController::showDockWidgets(bool isVisible)
   _dockWidget->setVisible(isVisible);
 }
 
+void PresentationController::updateVisibilityState(long presId) 
+{
+  char* str = _salomeModule->engine()->getStudyPresentationEntry(presId);
+  if (str) {
+    QStringList entries;
+    entries.append(str);
+    _salomeModule->updateVisibilityState(false, entries);
+  }
+}
+
+std::string PresentationController::presentationName2Type(const std::string& name) {
+  return std::regex_replace(name, std::regex("MEDPresentation"), std::string(""));
+}
\ No newline at end of file