Bug when creating multiple render windows with VTK and WSLink

I believe there is a bug regarding the the way the IDs for render windows are SET and then being GET.

When I set a new VIEW (Render Window) using:
self.getApplication().GetObjectIdMap().SetActiveObject( "1", my_render_window)

I am using the function on the C++ side:
vtkTypeUInt32 vtkObjectIdMap::SetActiveObject(const char* objectType, vtkObject* obj)

which like the signature says it allows for a const char* type, meaning that it does not have to be a integer. And this is the way the example is showed using “VIEW” as the id.

But then if one wants to create more than 1 render window using for example something like uuid to generate ids for the views it stops working because the GET is wrong in multiple places (imo).

First place that it’s broken:

def getView(self, vid):
        """
        Returns the view for a given view ID, if vid is None then return the
        current active view.
        :param vid: The view ID
        :type vid: str
        """
        v = self.mapIdToObject(vid)

        if not v:
            # Use active view is none provided.
            v = self.getApplication().GetObjectIdMap().GetActiveObject("VIEW")
        if not v:
            raise Exception("no view provided: %s" % vid)

        return v

as one can see the v is mapped by using mapIdToObject which then casts the id to an int to pass it to ...getVTKObject(id) which is not the same way it’s being saved in the first place:
SetActiveObject should imply a GetActiveObject and not GetVTKObject .

def mapIdToObject(self, id):
        """
        Maps global-id for a vtkObject to the vtkObject instance. May return None if the
        id is not valid.
        """
        id = int(id)
        if id <= 0:
            return None
        return self.getApplication().GetObjectIdMap().GetVTKObject(id)

This is the first place that it’s not right because it allows the creation of multiple windows with a string id but then on the get side casts the ids to integers and uses a different function to get the views.

But then if one for example changes mapIdObject to GetActiveObject instead another problem follows when asking for view updates.

In many places of the vtkWebPublishImageDelivery protocol there is a call to request the VTK Global Id like so:

@exportRpc("viewport.image.push")
def imagePush(self, options):
    sView = self.getView(options["view"])
    realViewId = str(self.getGlobalId(sView))
    # Make sure an image is pushed
    self.getApplication().InvalidateCache(sView)
    self.pushRender(realViewId)

This asks the pushRender function to push the realViewId and then “ignores” the id that was set earlier creating a mismatch if the ids are not integers and created sequentially.

I am hoping I am not seeing this correctly and that there is a nicer way to create multiple render windows but this is as far as my investigation as reached.

Any answers to this?

From a quick browse of what you are saying, you may have found a bug. Would you mind submitting a PR that fix it ?

fyi @Sebastien_Jourdain

It is not a bug, just a bad usage from your side.

Active objects can only be “VIEW”, “SOURCE”, “REPRESENTATION” and what ever else category you see fit. The concept of active is that you can only have one object at a time in a given category.

So by default we use ID=“-1” for a view which perform the lookup of the actual ID of the registered active view. (That way you don’t need to know the id before hand).

If you don’t want to be limited with the number of view, you just need to provide all the view ids correctly and obviously not relying on any “Active” part of the API.

HTH