Plugin Tutorial: Subclassing PythonProgrammableFilter

From KitwarePublic
Jump to navigationJump to search

In this tutorial we show step-by-step how to create a simple subclass of PythonProgrammableFilter. This plugin that shows how to subclass it and pass custom parameters from the GUI to a Python script.

Step 1: Create a CMakeLists.txt

Create a file CMakeLists.txt with the following contents:

cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)

if (NOT ParaView_BINARY_DIR)
  find_package(ParaView REQUIRED)
  include(${PARAVIEW_USE_FILE})
endif()

include(ParaViewPlugins)

# create a paraview plugin containing server manager xml and the server
# manager classes to build
# this plugin can be loaded on the server side

ADD_PARAVIEW_PLUGIN(CPPFilter "1.0"
  SERVER_MANAGER_XML vtkCPPFilter.xml
  SERVER_MANAGER_SOURCES vtkCPPFilter.cxx)

Step 2: Create the XML file describing the plugin and its GUI

In the Step 1 we are referencing the file "vtkCPPFilter.xml", so you need to create it with the following contents:

<ServerManagerConfiguration>
	<ProxyGroup name="filters">
		<SourceProxy name="CPPFilter" class="vtkCPPFilter" label="CPPFilter">
		<InputProperty name="Input" command="SetInputConnection">
			<ProxyGroupDomain name="groups">
			<Group name="sources"/>
			<Group name="filters"/>
			</ProxyGroupDomain>
			<DataTypeDomain name="input_type">
			<DataType value="vtkDataSet"/>
			</DataTypeDomain>
		</InputProperty>
	  
		<IntVectorProperty name="OutputDataSetType" command="SetOutputDataSetType" 
							number_of_elements="1" default_values="0"> 
        </IntVectorProperty>

		<StringVectorProperty name="Script" command="SetScript" number_of_elements="1"
							default_values="print 'Sizz value is: %s' % (sizz)">
			<Hints> <Widget type="multi_line"/> </Hints>
		</StringVectorProperty>

		<!-- Sizz is the name of the variable that we will set in our plugin
		     using the value of the GUI. This name here can be anything, but
			 the "SetSizz" method should exist in the C++ class -->
		<DoubleVectorProperty name="Sizz" command="SetSizz" number_of_elements="1"
							default_values="245">
		</DoubleVectorProperty>
   </SourceProxy>
 </ProxyGroup>
</ServerManagerConfiguration>

Step 3: Create the C++ file with the code for the plugin

Here we will create the C++ file referenced in the Step 1: "vtkCPPFilter.cxx"

#include "vtkCPPFilter.h"
#include "vtkObjectFactory.h"
#include <QMessageBox>

vtkStandardNewMacro(vtkCPPFilter);

vtkCPPFilter::vtkCPPFilter() {}

vtkCPPFilter::~vtkCPPFilter() {}

void vtkCPPFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

// Method that creates a variable for Python using SetParameter
void vtkCPPFilter::SetSizz(double value)
{
	/*
	char s[255];
	sprintf(s, "SetSizz was invoked %f\n", value);
	QMessageBox::information(NULL, "MyAction", s);
	*/

	// Create a new variable for Python called 'sizz'
	SetParameter("sizz", value);
}

Step 4: Create the H file with the header of the plugin

Here we will create the H file referenced in the Step 3: "vtkCPPFilter.h"

#ifndef __vtkMyElevationFilter_h
#define __vtkMyElevationFilter_h

#include "vtkPythonProgrammableFilter.h"

class VTK_EXPORT vtkCPPFilter : public vtkPythonProgrammableFilter
{
	public:
		static vtkCPPFilter* New();
		vtkTypeMacro(vtkCPPFilter, vtkPythonProgrammableFilter);
		void PrintSelf(ostream& os, vtkIndent indent);
  
		// Method that creates a variable for Python using SetParameter
		void SetSizz(double);

	protected:
		vtkCPPFilter();
		~vtkCPPFilter();

	private:
		vtkCPPFilter(const vtkCPPFilter&);  // Not implemented.
		void operator=(const vtkCPPFilter&);  // Not implemented.
};

#endif

Step 5: Generate the rest of the plugin code

Now, you should have 4 files in your working directory:

CMakeLists.txt
vtkCPPFilter.xml
vtkCPPFilter.cxx
vtkCPPFilter.h

The next step is to open CMake and point it to our working folder and specify the build directory. For this example the build directory will be C:/vtkCPPFilter/build.

After you have clicked in "Configure" and then on "Generate" you will have a new file called: C:/vtkCPPFilter/build/Project.sln. You can open this file with Visual Studio 2010 (if you are using other compiler this file may vary).

Step 6: Compile the plugin

In VisualStudio build the solution. After this process finishes the following file will be created:

C:/vtkCPPFilter/build/Debug/CPPFilter.dll

or if you set the default configuration to "Release"then the file will be located in:

C:/vtkCPPFilter/build/Release/CPPFilter.dll

Note this configuration should match the one used when you compiled your version of Paraview.

Step 7: Load the plugin from inside Paraview

In Paraview go to "Tools" -> "Manage plugins..." adn add the DLL file created in the Step 6. Now add a "Sphere" source and go to "Filters" -> "Alphabetical" and find your filter called "CPPFilter" (note that Paraview orders first upper-cases and then lower-cases so your filter will be before the filter "Calculator".

As you load your filter you will get this message printed out to the console:

Sizz value is: 245

If you change in the GUI the value of "Sizz"and click the "Apply" button you will see the message of the console changing as well:

Sizz value is: 24

Note that the script of this filter has been pre-filled with this value (we did it in the XML file):

print 'Sizz value is: %s' % (sizz)

So that is the reason of that message being printed to the output console, but you can use the value of "sizz" in any way you want.

Step 8: Extra debugging

You may have noticed that we had the following lines commented in vtkCPPFilter.cxx:

char s[255];
sprintf(s, "SetSizz was invoked %f\n", value);
QMessageBox::information(NULL, "MyAction", s);

If you uncomment them you will be able to see a popup message each time the value of the variable is updated. This is not recommended besides debugging as a message of this time can be disruptive for the user of your plugin.


That's all for this tutorial !