Sounds good to me!
I like the idea of a more python VTK wrapping. Have anybody considered how you will go the other way around. Say that you have a pipeline and after execute would like to serialize it to get the names of the filters and all their parameters to be able to easily construct the pipeline again based on this information.
Thanks in advance.
You intend for vtkAlgorithm
to be iterable (iterating over connections)? There are several interpretations of what iterating an algorithm might mean:
- iterate upstream input connections
- iterate downstream output connections
- iterate output data (points, cells, field data, ā¦)
If you intend to iterate connections (upstream or downstream), then what happens for algorithms with multiple inputs/outputs? Say I had
p = (vtkSphereSource, vtkSphereSource >> vtkTransform) >> vtkAppendPolyData
How would one know to write
(sphereA, (sphereB, transform)), append = p.upstream()
to recover the pipeline without already knowing the structure? Or if you intend merely to return the structure for users to process, a use case for how it would be processed might help motivate the feature. The above is one potential interpretation, but did you also intend to capture non-default parameters? What about multiple ports vs. multiple connections on a single port?
I would just like to return the structure of the pipeline for a user to be able to establish all input connections and perform Update()
and GetOutput()
on an output port.
- Setting up input connections should have been done already (how else could you get upstream filters?).
- You should not need to call
Update()
on anything but the terminal filter(s). - If you want to call
GetOutput()
on upstream filters, how will you know which one in the pipeline you want?
There is already a way to traverse the pipeline, it is just not very pythonic. But without a good use case, there is not a strong motivation to make it easy (it comes with the cost of maintenance and may conflict with unforeseen use cases that arise in the future).
1-2) I know that. 3) I picture a situation where I have a pipeline and an output, i.e. I have just called Update()
and GetOutput()
on a filter (not necessarily a terminal filter). Then, I would like to get the information needed for establishing a pipeline (perhaps only a fraction of the pipeline) to produce the output that I just received.
The state of the output is uniquely determined by the filter in the pipeline and input data. For this situation, it would be awesome if it was possible to query a list of parameters for a given object. I know how this is done in ParaView and this can be achieved by replacing the macros, vtkSetMacro
, vtkSetBooleanMacro
etc.
Iāve just quickly browsed through this thread and my only comment is that Iām not sure if the syntax that uses bitwise shift operator for building and connecting pipelines āpythonicā. Using >>
to connect filters is an interesting, very compact syntax that C++ developers who used streams can relate to, but it may not look familiar at all to Python developers.
If the goal is still what the topic title is - More Pythonic VTK wrapping - then it might worth getting some feedback from Python developers (those who have never seen C++ code) to see if they like the proposed API.
Thank you for your input Andras. But after several rounds of voting, we settled on >> and I put a decent amount of time into making it work. I am afraid that it is too late to change.
Appreciate your feedback!
Yes, that has been the goal since the beginning and the operator choices were open for public votes. I think we can still choose something else if the python developers in our community come up with a better alternative. However, it would take some effort to replace existing code.
Berk, more or less has taken inspiration from fenicsā use of <<
operator in python.
Maybe just try to keep things as open as possible (donāt bet everything on that Python developers will be happy to use >>
) and try to go to places for feedback where the target audience is (ordinary Python developers are not represented well in a discussion in the Development category of the VTK forum).
Sounds good. Btw, we did have some folks from the Python vis community (from pyvista and vedo).
Here is an example that displays Gaussian and Mean curvatures of a surface along with normals colored by elevation.
There is also a text widget and scalar bar widgets. With respect to these, there are a lot of positioning parameters.
Most of the properties of VTK classes are initialized when they are instantiated.
While I was doing this I came across issues where I wanted to use the VTK constants, however they are usually created in the C++ code by #define...
. I considered several approaches e.g dictionaries and named tuples, however the best solution I found was to use the Python data class. This has the big advantage that the defined VTK constants are visible and are constants. Just like in the C++ code.
Have a look at CurvaturesNormalsElevations and How to handle #defines
You will see that, after defining the data classes, we just use them in the relevant VTK class:
glyph_mapper = vtkPolyDataMapper(scalar_range=v['scalar_range_elevation'],
lookup_table=v['lut1'],
scalar_mode=MapperScalarMode().VTK_SCALAR_MODE_USE_POINT_FIELD_DATA,
scalar_visibility=True,
color_mode=MapperColorMode().VTK_COLOR_MODE_MAP_SCALARS)
An update, I have done more work on dataclasses and I now believe I have a āusefulā solution. In my opinion, this makes initializing the VTK classes even better. Being able to now initialize by using variables from dataclasses in the constructor of a VTK class is fantastic!
Please look at How to handle #defines using dataclasses and VTKDataClasses.
So far, around 218 classes in 65 examples have been used with no particular issues. I have mentioned a couple of little things that I have seen here: PythonicAPI hints and here: Python hints
@berk.geveci FYI