tkeskita / BVtkNodes

Create and execute VTK pipelines in Blender Node Editor
GNU General Public License v3.0
111 stars 19 forks source link

vtkAssignAttribute Filter #54

Open NickGeneva opened 3 years ago

NickGeneva commented 3 years ago

A new custom filter for handling setting of active attributes of VTK datasets. VTK filters use the current active attribute to tell it what array to process (e.g. vtk stream tracer will use active vector to produce stream lines). In VTK with python this is done through vtkobj.setActiveVector('field name') but isn't easily done in BVTK and in blender. vtkPassArrays does not always work since this only passes the arrays but does not make ones active. This new node allows for such commands through the blender interface.

Key features:

This is a fair bit amount of code for a single node. Largely the use of a custom vtk algo required some integration. But I believe this is the right way to implement this and perhaps other bvtk nodes as well. Also if something goes wrong this allows the VTK pipeline to throw its errors, not in our add on.

IMO I also like prefacing special nodes (not in vtk module) with bvtk(FilterName) since this makes it easy to distinguish what is unique to BVTK but maintains formatting.

Let me know your thoughts and if you see any bugs (some quality of life ones exist but are not possible to fix with the blender API).

See the following example creating streamlines (new node colored green): SetAttribFilter

Additional functions (data set only has point scalar and vector arrays): SetAttribFilter1

tkeskita commented 3 years ago

Thanks Nick! I'll start to test and go through the code, but few initial questions:

  1. vtkAssignAttribute can be used to set the active attribute also. I presume bvtkSetActiveAttribute does the same but with nice user interface, right?
  2. Does it support JSON export/import of node tree?
  3. Do you know is this VTKPythonAlgorithmBase a stable feature in VTK, or something brand new?

BR, Tuomo

tkeskita commented 3 years ago

Got following error with the examples_data/cubeflow OpenFOAM reader case when running update on Info node:

Traceback (most recent call last):
  File "/home/tkeskita/.config/blender/2.83/scripts/addons/BVtkNodes/update.py", line 164, in modal
    queue.next_function()
  File "/home/tkeskita/.config/blender/2.83/scripts/addons/BVtkNodes/update.py", line 131, in next_function
    f[0](*f[1])
  File "/home/tkeskita/.config/blender/2.83/scripts/addons/BVtkNodes/update.py", line 25, in UpdateObj
    node.apply_inputs(vtkobj)
  File "/home/tkeskita/.config/blender/2.83/scripts/addons/BVtkNodes/core.py", line 263, in apply_inputs
    vtkobj.SetInputData(i, input_obj)
AttributeError: 'bvtkSetActiveAttribute' object has no attribute 'SetInputData'

image

tkeskita commented 3 years ago

About Data Attribute: I wonder what would be best for usability here. Now it requires two steps from user: first to make a type selection, after which selecting field is possible (if there are any fields matching the type.. maybe empty type lists should be disabled?). Alternative would be to list all available options in one (possibly long) list from which user selects one.

Some filters require activation of one scalar field and one vector field like vtkGlyph3D, see end of #18. I wonder if it would be better for user to select one entry (or None) for each of scalars, vectors and tensors..?

NickGeneva commented 3 years ago
  • vtkAssignAttribute can be used to set the active attribute also. I presume bvtkSetActiveAttribute does the same but with nice user interface, right?

You know, I was worried there was a filter like this that already existed lol. Wasn't aware of this filter existed, but yes. However this means I can make this a custom node instead of a special node and just piggy back off vtkAssignAttribute. Let me see what I can do.

  • Does it support JSON export/import of node tree?

Believe so since it uses the core class, will recheck after I looking into updating it.

  • Do you know is this VTKPythonAlgorithmBase a stable feature in VTK, or something brand new?

Stable I believe, I found it in this VTK blog from 2014. Apparently its this super class specifically made to help with Python algorithms.

About Data Attribute: I wonder what would be best for usability here. Now it requires two steps from user: first to make a type selection, after which selecting field is possible (if there are any fields matching the type.. maybe empty type lists should be disabled?). Alternative would be to list all available options in one (possibly long) list from which user selects one.

Some filters require activation of one scalar field and one vector field like vtkGlyph3D, see end of #18. I wonder if it would be better for user to select one entry (or None) for each of scalars, vectors and tensors..?

I agree, I used that interface because I found the PropertyGroup seems to be the one way to have dynamic lists of properties that dont give you those blender warnings like the enum operator. However, now that you mention it I think setting it up for multiple attributes can be possible in a dynamic way using these prop groups. I'll just bite the bullet and use dynamic enum lists since they are more compact.

The tricky part with this node is when the user changes the input connection, how do you get stuff to update ideally with out some modal operator.

I'll restructure things, retest and then rebase this PR. Will update again then.

tkeskita commented 3 years ago
  • Do you know is this VTKPythonAlgorithmBase a stable feature in VTK, or something brand new?

Stable I believe, I found it in this VTK blog from 2014. Apparently its this super class specifically made to help with Python algorithms.

It looks really interesting, since it allows to do so much in a node with Python. That may become very useful. Good to know it's stable, so it should be pretty safe and will likely stick around. @thomgrand has some work that uses pyvista, I don't know if there is some overlap.

About Data Attribute

I agree, I used that interface because I found the PropertyGroup seems to be the one way to have dynamic lists of properties that dont give you those blender warnings like the enum operator.

That's a cool solution. This enum definition issue is everywhere, and it has another level: Predefinition is impossible ahead of time (before data exists). Generally speaking: Would it be good to use string variable to store the value (user has the option of writing it themself even before list exists), but then add besides it a button which would generate the dynamic list and let the user pick one, then transfer that value to the string variable? Some kind of general solution for this is needed at some point...

The tricky part with this node is when the user changes the input connection, how do you get stuff to update ideally with out some modal operator.

The update logic and error handling will change in #45. I'm not quite there yet though..

Thanks!

thomgrand commented 3 years ago

I also saw the blog entry about VTKPythonAlgorithm, but I implemented some parts that are more numpy orientated. Inspired by Paraview, the idea was to easily access points and arrays of one or multiple VTK objects and perform computations for easy postprocessing or modifications. The more or less stable node that I've done so far is the PyvistaCalculator node that performs a simple lambda statement and puts its resulting array into the original vtk object with the specified name. I planned a node with the same logic for multiple lines and maybe a bit expanded possibilities. grafik

NickGeneva commented 3 years ago

That's a cool solution. This enum definition issue is everywhere, and it has another level: Predefinition is impossible ahead of time (before data exists).

Going to continue to try to tinker with this, will likely default back to some enum props but finding that general solution for dynamic drop downs would be great. Maybe a combo would work... not sure.

The update logic and error handling will change in #45. I'm not quite there yet though..

No worries, I'll modify when the merge comes.

I also saw the blog entry about VTKPythonAlgorithm, but I implemented some parts that are more numpy orientated. Inspired by Paraview

Yes, the VTKPythonAlgorithm/VTKPythonAlgorithmBase seems like a really cool part of the Python package of VTK, but outside that 2014 blog post theres really not a whole lot on it that I could find. As Thomas mentioned this almost seems to be something added to VTK with paraview in mind... not sure

This got me thinking if all of the special nodes could potentially be routed through custom VTK algos such as the BVTK_Node_MultiBlockLeaf or Time_Selector. The functionality would be the same but it would be more integrated into the standard VTK pipeline than manually editing the vtkobjs attributes. Ideas for the future~

NickGeneva commented 3 years ago

Migrating to making a custom implementation of the vtkAssignAttribute instead of a completely new node. Also switched to the drop downs. Originally I was hoping to have the option to allow the user to set multiple attributes in a single node, but it seems with vtkAssignAttribute you can only edit one attribute per instance (bummer). But you can always just stack the nodes.

As always with these enumitems there's a few bugs going on that I need to see if I can figure out a way around them. Also clean up and rebasing is still needed from all the old stuff as well.

SetAttribFilter2