VTKPythonAlgorithmBase for custom annotations

python
(Art Danning) #1

Dear devs,

Can one use the VTKPythonAlgorithmBase class to create annotation filters, i.e. show additional descriptive text? I have managed to open a table in a separate window, but never to show a text in the same window.

I have a feeling there should be a connection to the PrintSelf function and the ostream to achieve this, is it so? Any help is deeply appreciated.

Best,
Art

(Mathieu Westphal (Kitware)) #2

You may want to precise what you are trying to achieve.

(Art Danning) #3

As an execrcise, I am trying to write a PV plugin in python, that would create an annotation filter, i.e. show a text at the top of the render view window. The problem is that instead of a string I get a table in the Spread Sheet view. I also compared the python implementation with existing c++ filters, and the only thing that was different is that c++ filters have the PrintSelf function, while python filters do not.

(Utkarsh Ayachit) #4

A filter indicate it’s producing data that should rendered as text by adding a hint. If your filter is producing a table with a single row/column with the string to be rendered as text in the render view, the following hint should do the trick.

@smhint.xml("<OutputPort index='0'  name='Output-0'  type='text' />")
class Foo(VTKPythonAlgorithmBase):
   ...
(Art Danning) #5

Dear Mathieu, dear Utkarsh,

I’m sorry, but I still cannot get it right. I have added the hint as you suggested, yet I still get no text in the render view, but a table in a separate window. Here is my code:

@smproxy.filter(name="CustomAnnotationFilter", 
                label="CustomAnnotationFilter")
@smproperty.input(name="InputDataSet", port_index=0)
@smdomain.datatype(dataTypes=["vtkDataObject"], 
                   composite_data_supported=False)
@smhint.xml("<OutputPort index='0' name='output-0' type='text' />")
class ExampleTwoInputFilter(VTKPythonAlgorithmBase):
	def __init__(self):
		VTKPythonAlgorithmBase.__init__(self, nInputPorts=1, 
                     nOutputPorts=1, outputType="vtkTable")

	def FillInputPortInformation(self, port, info):
		info.Set(self.INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject")
		return 1

	def RequestData(self, request, inInfoVec, outInfoVec):
		output = vtkTable.GetData(outInfoVec, 0)

		data = vtk.vtkStringArray()
		data.SetName("text")
		data.SetNumberOfComponents(1)
		data.InsertNextValue("this is inserted text")

		output.AddColumn(data)
		return 1

Upon loading the plugin, I create a sphere from source and apply this filter.

Once again, any help is deeply appreciated, thank you.
Art

(Mathieu Westphal (Kitware)) #6

Here is a Python text source that work out of the box.

    @smproxy.source(name="PythonText",
           label="PythonText")
    @smhint.xml("<OutputPort index='0'  name='Output-0'  type='text' />")
    class PythonText(VTKPythonAlgorithmBase):
        """This is dummy VTKPythonAlgorithmBase subclass that
        simply puts out a Text"""
        def __init__(self):
            VTKPythonAlgorithmBase.__init__(self,
                    nInputPorts=0,
                    nOutputPorts=1,
                    outputType='vtkTable')
            from paraview.modules.vtkPVVTKExtensionsDefault import vtkPVTextSource
            self._realAlgorithm = vtkPVTextSource()

        def RequestData(self, request, inInfo, outInfo):
            from vtkmodules.vtkCommonDataModel import vtkTable
            self._realAlgorithm.Update()
            output = vtkTable.GetData(outInfo, 0)
            output.ShallowCopy(self._realAlgorithm.GetOutput())
            return 1

        @smproperty.stringvector(name="Text")
        def SetText(self, text):
            self._realAlgorithm.SetText(text)
            self.Modified()