Skip to content

Fix: behavior of apply when first pass on reader generates no output

Pain point

This fix concerns readers which read composite objects and tend to generate vtkDataObjects during a REQUEST_DATA call (vtkIOSSReader for example). When using these types of readers and unchecking all blocks of data in the properties panel on the first "Apply", subsequent "Apply" button pushes do not provoke REQUEST_DATA calls on the server side. This puts the application in a state where the user can not visualize his data without destroying the reader first.

Related issue: #21293 (closed)

Ideally, if the user checks some of his data in the properties panel and clicks "Apply", then he should visualize the data as if the reader had been called with those properties the first time.

Gif of problematic behavior: unexpected_behavior

Fix 1

The proposed fix is contained in this MR and modifies pqApplyBehavior::applied. It operates by checking whether the given vtkSMSourceProxy has a representation in the current active view. If it doesn't, it performs a pqApplyBehavior::ShowData to generate the representation and render the data if possible.

Gif of Fix 1 behavior: fix_no_warning_gray_apply

Fix 2

The second fix that was investigated is the following:

diff --git a/Qt/ApplicationComponents/pqApplyBehavior.cxx b/Qt/ApplicationComponents/pqApplyBehavior.cxx
index 8ad08d5359..d6b157621b 100644
--- a/Qt/ApplicationComponents/pqApplyBehavior.cxx
+++ b/Qt/ApplicationComponents/pqApplyBehavior.cxx
@@ -181,12 +181,30 @@ void pqApplyBehavior::onResetDone()
 void pqApplyBehavior::applied(pqPropertiesPanel*, pqProxy* pqproxy)
 {
   this->Internals->AutoApplyTimer.stop();
+  bool setUnmodified = true;
   if (pqproxy->modifiedState() == pqProxy::UNINITIALIZED)
   {
     if (auto pqsource = qobject_cast<pqPipelineSource*>(pqproxy))
     {
       // if this is first apply after creation, show the data in the view.
       this->showData(pqsource, pqActiveObjects::instance().activeView());
+
+      // if the source has no valid representations then keep it uninitialized
+      setUnmodified = false;
+      vtkSMViewProxy * activeViewProxy = pqActiveObjects::instance().activeView()->getViewProxy();
+      if(activeViewProxy)
+      {
+        for(int outputPort = 0; outputPort < pqsource->getNumberOfOutputPorts(); outputPort++)
+        {
+          vtkSMRepresentationProxy* reprProxy =
+            pqActiveObjects::instance().activeView()->getViewProxy()->FindRepresentation(pqsource->getSourceProxy(), outputPort);
+          setUnmodified |= (reprProxy != nullptr);
+          if(setUnmodified)
+          {
+            break;
+          }
+        }
+      }
     }

     // add undo-element to ensure this state change happens when
@@ -197,7 +215,14 @@ void pqApplyBehavior::applied(pqPropertiesPanel*, pqProxy* pqproxy)
     ADD_UNDO_ELEM(undoElement);
     undoElement->Delete();
   }
-  pqproxy->setModifiedState(pqProxy::UNMODIFIED);
+  if(setUnmodified)
+  {
+    pqproxy->setModifiedState(pqProxy::UNMODIFIED);
+  }
+  else
+  {
+    vtkGenericWarningMacro("No representation created for this data, please make sure source will not be empty on applying.");
+  }

   // Make sure filters menu enable state is updated
   Q_EMIT pqApplicationCore::instance()->forceFilterMenuRefresh();

It works by enforcing that the vtkSMSourceProxy remains in an UNINITIALIZED state when this happens and generates a warning.

Gif of Fix 2 behavior: fix_with_warning

Edited by Julien Fausty

Merge request reports