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.