I’m trying to write a Python plugin with a line, defined by two points, as one of its inputs. If possible, I would like to use ParaView’s InteractiveLine widget to select the points so the user can interactively pick the points and see the line drawn on the screen.
One way I thought to do this was as follows:
import numpy as np
import vtk
from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk
from vtk.util.vtkAlgorithm import VTKPythonAlgorithmBase
from paraview.util.vtkAlgorithm import smproxy, smproperty, smdomain
@smproxy.filter()
@smproperty.input(name='LineLoads', port_index=0)
class LineLoads(VTKPythonAlgorithmBase):
def __init__(self):
VTKPythonAlgorithmBase.__init__(self, nInputPorts=1, nOutputPorts=1, outputType='vtkPolyData')
self.AxisBegin = [0.0] * 3
self.AxisEnd = [0.0] * 3
@smproperty.xml("""
<DoubleVectorProperty name="AxisBegin"
number_of_elements="3"
default_values="0 0 0"
command="SetAxisBegin" />
<PropertyGroup panel_widget="InteractiveLine">
<Property function="Point1WorldPosition" name="AxisBegin" />
<Property function="Point2WorldPosition" name="AxisEnd" />
</PropertyGroup>""")
def SetAxisBegin(self, *val):
if val != self.AxisBegin:
self.AxisBegin = np.array(val[:3])
self.Modified()
def SetAxisEnd(self, *val):
if val != self.AxisEnd:
self.AxisEnd = np.array(val[:3])
self.Modified()
def RequestData(self, request, inVec, outVec):
return 1
If I do that, I get a warning saying:
vtkSMPropertyGroup.cxx:194 WARN| vtkSMPropertyGroup (0x107d9b00): Failed to locate property 'AxisEnd' for PropertyGroup. Skipping.
critical: In unknown, line 0
critical: Missing required property for function 'Point2WorldPosition'.
So then I added the smproperty.xml decorator separately to the SetAxisBegin and SetAxisEnd functions:
@smproperty.xml("""
<DoubleVectorProperty name="AxisBegin"
number_of_elements="3"
default_values="0 0 0"
command="SetAxisBegin" />
<PropertyGroup panel_widget="InteractiveLine">
<Property function="Point1WorldPosition" name="AxisBegin" />
</PropertyGroup>""")
def SetAxisBegin(self, *val):
if val != self.AxisBegin:
self.AxisBegin = np.array(val[:3])
self.Modified()
@smproperty.xml("""
<DoubleVectorProperty name="AxisEnd"
number_of_elements="3"
default_values="0 0 0"
command="SetAxisEnd" />
<PropertyGroup panel_widget="InteractiveLine">
<Property function="Point2WorldPosition" name="AxisEnd" />
</PropertyGroup>""")
def SetAxisEnd(self, *val):
if val != self.AxisEnd:
self.AxisEnd = np.array(val[:3])
self.Modified()
This gives me a message that looks like:
critical: In unknown, line 0
critical: Missing required property for function 'Point2WorldPosition'.
critical: In unknown, line 0
critical: Missing required property for function 'Point1WorldPosition'.
Unsurprisingly, I also get two InteractiveLine widgets in the GUI. What’s the magic recipe here so that I get one line widget with Point1WorldPosition connected to my plugin’s AxisBegin and Point2WorldPosition connected to AxisEnd?