In a ParaView custom application, I have a “textured representation” class which is derived from vtkGeometryRepresentationWithFaces. The purpose is to allow draping a texture over a triangulated surface that “understands” reading georeferencing information from ESRI world files or GeoTIFF files.
The real action is within a “geometry filter” that is derived from vtkPVGeometryFilter. Within that filter, within the RequestData function, a vtkTextureMapToPlane object is initialized with the origin, point1 and point2 from the georeferencing information.
The last steps are finally:
// the current output will be the input for the original function call
inInfo->Set(vtkDataObject::DATA_OBJECT(), textureMap->GetOutput());
// do the job of the parent class as if the textured topo was the input
Superclass::RequestData(request, inputVector, outputVector);
// clean up: set the input back to original
inInfo->Set(vtkDataObject::DATA_OBJECT(), topo);
the topo variable was previously read from the info data object. This setup I somehow empirically developed by analyzing existing code, and somehow it worked until ParaView version 5.8.0.
Now I converted all to ParaView version 5.9.1, with not much trouble. But now I see that the above functionality does not work any more: I am tracking the function calls in my custom code, all the calculations and calls are done like before and without problems, but at the end I simply do not see a texture on the triangulated topo surface (polydata object)!
Question: Any hint regarding what could have changed regarding the texturing of geometric objects between version 5.8.0 and 5.9.1?
My guess (or my hope…) is that I only need one more function call or “switch” and the entire functionality would come back. Only I do not know which “magic function call” might be the right one!
Looks like this is not such an easy question, and maybe also it is hard to really understand what goes wrong for those who understand the details of texture display in VTK/ParaView. And also during a couple of days of code reading and investigation did not bring myself to the point where I could fix the functioning of my original code.
Now I started implementing the entire thing in a different way, starting with the existing vtkTextureMapToPlane class and plugin. This looks like a quite straightforward operation: Instead of asking the user for origin/point1/point2, ask him for a georeferenced image file, extract the relevant geoinformation and provide the origin/point1/point2 information programmatically.
This should work, but for the user it brings a number of inconveniences that I was avoiding with the first approach of writing a “representation” plugin:
The user will have to select the texture file twice: once in the “Properties” panel in order to extract the georeferencing information, and then once more on the “Display” panel in order to read the texture itself. In order to avoid this, the image file name should somehow be automatically “transferred” from the “Properties” panel to the “Display” panel, but these two represent properties in quite different parts of the ParaView code, and so far I do not understand how they can communicate.
For a georeferenced image, like an aerial photo, it never makes sense to “repeat texture”, but this is the default on the “Display” panel. The contrary is true: repeating the texture can lead to extremely confusing effects in this situation. Here the solution would be to programmatically turn this option off - again making it necessary to communicate from the georeferenced texture mapper filter to some other item of type vtkGeometryRepresentation. How would this be accessible programmatically?
The alternative to “repeat texture” is to infinitely repeat the edge pixel in all directions, but also this is not really the method of choice - except the user would prepare the texture file in such a way that the texture is surrounded by a one-pixel wide “frame” of white. Also this was provided programmatically in my original code, but it requires access not only to the texture file name, but to the texture object in memory. Again I do not see how I can achieve this from the texture mapper plugin code.
Any hints how these latter things could be achieved?
Finally got it running. I have now new a custom filter that asks for a file name for the texture and tries to read georeferencing info from if (using GDAL functionality).
If that info was found, TCoords are generated by using the “map to plane…” filter.
Furthermore, the texture file name and path is written into a “field data” item of the same poly data that is the input of the filter.
Now the already existing and not any more working “georeferenced texture representation” comes into action. In the “RequestData” function it looks for that texture file information, generates a vtkTexture and “remembers” it in it’s class variables.
Finally, on calling the visualization function, that texture is set - and for some strange reason it is now working!
So basically I have no idea what went wrong with the switch from PV 5.8 to 5.9, but I am happy that I am having again a working program.