Programmatically generating a selection based on cell IDs - any comments?

Migrating a custom application from PV 5.10 to 5.12.0-RC3, I am running into a problem with my code that generates an ID’s based selection from within a property panel. This is what my code is doing and what was working just fine so far:

        // generate a new IDs selection source proxy object
        vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
        vtkSMSourceProxy* selSource = vtkSMSourceProxy::SafeDownCast(pxm->NewProxy("sources", "IDSelectionSource"));
        pqSMAdaptor::setElementProperty(selSource->GetProperty("FieldType"), vtkSelectionNode::CELL);

        // add an IDs property
        vtkSMVectorProperty* vp = vtkSMVectorProperty::SafeDownCast(selSource->GetProperty("IDs"));
        pqSMAdaptor::setMultipleElementProperty(vp, idsPadded);
        selSource->UpdateVTKObjects();

        // set the selection on our port - and delete the reference within this function scope
        outPort->setSelectionInput(selSource, 0);
        selSource->Delete();

This code worked so far just fine, but there is one thing to say that I am working with selections in a somewhat “illegal” way: Normally a selection is referring to the input port data object/proxy and then a filter is using it for some operation, but in my case I am simulating some kind of “interactive” workflow by having the selection on the output port data object. Meaning: once the filter is invoked, it starts with a “silent apply” that ensures that there is an output object from the beginning, and the “current selection” is restored from some properties. After that, the user can select/unselect, check the result etc. without always switching back and forth. On top of that, he can also do other things in the pipeline and come back later on, doing more adaptations in the selection. This just as an explaining side remark about what I am trying to achieve - or rather already achieved in the past.

However, now there is a new function in PV 5.12 pqFindDataCurrentSelectionFrame::showSelectedData() (which did not exist yet in PV 5.10) that “crashes” at line 258 because selectionSource is nullptr: at line 243 it was not able to find a property named "Input" in appendSelections. On the other hand, the latter is in fact the same object as the newly generated selSource in the above code, it does indeed not have a property "Input".

At this point I start swimming…

My reasoning: Maybe I do not go for that Input object, but rather use appendSelections directly because it already represents the object to which my selection applies!??

With this reasoning I changed the code in pqFindDataCurrentSelectionFrame.cxx:236 as follows:

        // Checking only one of the inputs of the appendSelections is sufficient
        // BCO 2024-03-08: We need to take care of the possibility that we do not have
        //   an Input property in the somewhat "special" selection usages in AthosGEO
        vtkSMProxy* selectionSource = (nullptr != appendSelections->GetProperty("Input")) ?
          vtkSMPropertyHelper(appendSelections, "Input").GetAsProxy(0) :
          vtkSMProxy::SafeDownCast(appendSelections);

And indeed: the code is working now as before - no crash any more, but the functionality I used to see!

Still another similar adaptation in pqRenderViewSelectionReaction.cxx avoids also another warning message that still appears.

So far so good, but still I am not sure whether there is not a better way to programmatically generate a selection on the output port object than what I did in the past, avoiding these patches in the PV code??

This looks like a bug and an oversight when selection where improved for 5.11. Open an issue ?

Sure??

Because: You need some crazy guy first who uses selections in such an “illegal” way before the problem is surfacing!

And maybe the problem could be solved if I find a way to add some “Input” property to my newly generated selection!?

It needs more investigation but what your are trying to do seems correct to me and an artificial limitation on the naming of the input doesnt seem right.

Interesting finding: It looks indeed that “a selection” is now not any more what it used to be!

I have some code that is supposed to find the “type” of a selection, and this is what was working so far:

vtkSMSourceProxy* activeSelection = vtkSMSourceProxy::SafeDownCast(outPort->getSelectionInput());
int ft = -1;
vtkSMIntVectorProperty* ftp = vtkSMIntVectorProperty::SafeDownCast(activeSelection->GetProperty("FieldType"));
if(ftp)
{
  ft = ftp->GetElement(0);
}
else
{
  // with PV 5.10, we cannot assume any more that we always have a <FieldType> property: It is
  // not any more the case if the selection is done with the FindData docking panel (which used
  // to be a common dialog before). Now we have to derive the field type by asking for the
  // <ElementType> property and converting it to a field type
  ftp = vtkSMIntVectorProperty::SafeDownCast(activeSelection->GetProperty("ElementType"));
  if(nullptr != ftp)
    ft = vtkSelectionNode::ConvertAttributeTypeToSelectionField(ftp->GetElement(0));
}
std::cout << "- active selection is of type ";
switch(ft)
{
  case vtkSelectionNode::CELL:
    std::cout << "CELL"; break;
  case vtkSelectionNode::POINT:
    std::cout << "POINT"; break;
  case vtkSelectionNode::FIELD:
    std::cout << "FIELD"; break;
  case vtkSelectionNode::VERTEX:
    std::cout << "VERTEX"; break;
  case vtkSelectionNode::EDGE:
    std::cout << "EDGE"; break;
  case vtkSelectionNode::ROW:
    std::cout << "ROW"; break;
  default:
    std::cout << ft << " <\?\?\?>";
}
std::cout << std::endl;

This is not working any more. Now what the getSelectionInput() call is returning is not any more the “real selection proxy”, but something that looks more like a collection of one or potentially also more “real selections” that have to be extracted from the "Input" property as follows:

vtkSMSourceProxy* appendSelections = vtkSMSourceProxy::SafeDownCast(outPort->getSelectionInput());
unsigned int numSel = vtkSMPropertyHelper(appendSelections, "Input").GetNumberOfElements();
for(unsigned int n = 0; n < numSel; ++n)
{
  vtkSMSourceProxy* activeSelection = vtkSMSourceProxy::SafeDownCast(vtkSMPropertyHelper(appendSelections, "Input").GetAsProxy(n));
  // do something...
}

With this I am fine.

However, if now I want to programmatically generate “a selection”, I would also need to generate such a “selection collection” with one element instead of just generating the selection! And this is where I am right now not getting further because I have not found the example code yet inside of ParaView where this is happening.

In other words: Where currently I simply have my outPort->setSelectionInput(selSource, 0) I would first have to “wrap” that selSource into some kind of “appendSelections” thing which then only is given to the outPort.

So to me it looks like there is some conceptual change in the handling of selections!

Looks like I solved the problem: There is a static function within vtkSMSelectionHelper.h now that looks as if it does exactly what I need:

/**
 * Create an append selection proxy from a selection source.
 */
static vtkSMProxy* NewAppendSelectionsFromSelectionSource(vtkSMSourceProxy* selectionSource);

So let’s try if it does the “magic” that I am missing so far…!!

1 Like