PluginAPI.wiki - Vaa3D/Vaa3D_Wiki GitHub Wiki

Content

What are exactly in the Vaa3D plugin interface?

Vaa3D API provides methods to access all critical functions of this system, as well as ways to access various plugins directly. It also exports the data structures and other implemented functions (e.g. plugins modules) to external programs (e.g. shell programs or Matlab).

Versions of plugin interfaces

There are two major Vaa3D plugin interfaces:

  • V3DPluginInterface2_1: the major plugin interface; used to access all opened images and surface objects.
  • V3DSingleImageInterface2_1: an obsolete plugin interface; used for access one single opened image in Vaa3D.

In this documentation site, without special note, we always mean V3DPluginInterface2_1.

API source files

After you check out Vaa3D source code, the plugins' API interfaces are defined in the file

<vaa3d_source_code_folder>/v3d_main/basic_c_fun/v3d_interface.h

Other critical data structures you may need to access Vaa3D internal data objects (images and surface objects) are defined in the following header files, which you may need to include in your source code when writing a plugin.

<vaa3d_source_code_folder>/v3d_main/basic_c_fun/basic_4dimage.h
<vaa3d_source_code_folder>/v3d_main/basic_c_fun/basic_surf_objs.h

Critical API functions in interface 2.1

The major accessing points of Vaa3D plugin interface are the domenu and dofunc functions, which use items defined in the menulist() and funclist() functions. Indeed, a Vaa3D plugin normally should inherit from the plugin interface class as follows.

class V3DPluginInterface2_1
{
public:
	virtual ~V3DPluginInterface2_1() {}
        virtual float getPluginVersion() const = 0;

	virtual QStringList menulist() const = 0;
	virtual void domenu(const QString & menu_name, V3DPluginCallback2 & v3d, QWidget * parent) = 0;

	virtual QStringList funclist() const = 0;
	virtual bool dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & v3d, QWidget * parent) = 0;
};

For instance, for the Vaa3D plugin for "gray-scale image distance transform" under the folder

<vaa3d_tools_source_code_folder>/released_plugins/v3d_plugins/gsdt/

you can find the header "gsdt_plugin.h" and c++ files "gsdt_plugin.cpp", for which the major plugin class "GrayScaleDistanceTransformationPlugin" is defined as

#include <QtGui>
#include <v3d_interface.h>

class GrayScaleDistanceTransformationPlugin : public QObject, public V3DPluginInterface2_1
{
	Q_OBJECT
	Q_INTERFACES(V3DPluginInterface2_1);

public:
	float getPluginVersion() const {return 1.1f;}

	QStringList menulist() const;
	void domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent);

	QStringList funclist() const ;
	bool dofunc(const QString &func_name, const V3DPluginArgList &input, V3DPluginArgList &output, V3DPluginCallback2 &callback, QWidget *parent);
};

Accordingly, in the c++ file "gsdt_plugin.cpp" the menus and functions of this plugin module are defined as

QStringList GrayScaleDistanceTransformationPlugin::menulist() const
{
	return QStringList()
		<<tr("Grayscale Distance Transformation")
		<<tr("about");
}

QStringList GrayScaleDistanceTransformationPlugin::funclist() const
{
	return QStringList()
		<<tr("gsdt")
		<<tr("help");
}

The actual entry points to invoke customary code via the domenu interface is

void GrayScaleDistanceTransformationPlugin::domenu(const QString &menu_name, V3DPluginCallback2 &callback, QWidget *parent)
{
	if (menu_name == tr("Grayscale Distance Transformation"))
	{
		gsdt(callback,parent);
	}
	else
	{
		v3d_msg(tr("Perform distance transformation on grayscale image."
			"Developed by Hang Xiao, 2012-03-02"));
	}
}

The actual entry points to invoke customary code via the dofunc interface is

bool GrayScaleDistanceTransformationPlugin::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback,  QWidget * parent)
{
	if (func_name == tr("gsdt"))
	{
		return gsdt(input, output);
	}
	else if(func_name == tr("help"))
	{
		cout<<"Usage : v3d -x gsdt -f gsdt -i <inimg_file> -o <outimg_file> -p <bkg_thresh_value> <cnn_type> <channel>"<<endl;
		cout<<endl;
		cout<<"bkg_thresh_value         the background threshold value, default 0 and maximum 255"<<endl;
		cout<<"cnn_type                 connection type, 1 : 6 neighbors, 2 : 18 neighbors, 3 : 26 neighbors"<<endl;
		cout<<"channel                  the input channel value. 0 for red channel, 1 for green channel, 2 for blue channel"<<endl;
		cout<<endl;
		cout<<"e.g. v3d -x gsdt -f gsdt -i input.raw -o output.raw -p 0 1 0"<<endl;
		cout<<endl;
		return true;
	}
}

Apparently, you can replace the code using your own code for whatever computation you like.

Access Vaa3D internal data & functions based on V3DPluginCallback2

Vaa3D plugin interface provides the callback function class, V3DPluginCallback2, to access all internal data and completely control the behavior of Vaa3D via plugin. This class is also defined in the file "v3d_interface.h" as discussed above.

Based on the callback class, you can access any images (and their associated surface objects, e.g. a neuron reconstruction) that have been opened in Vaa3D main window. You can also control how these data should be displayed in tri-view and 3D viewers (both global 3D viewer and local 3D viewer). You can even control the mouse and keyboard events, take snapshot of the 3D viewer, etc.

V3DPluginCallback class is defined as follows, with which it is easy to get a handle to an opened image, or to a list of all opened images, and thus perform whatever operations on these images and display the result.

typedef QList<v3dhandle>       v3dhandleList;

// this is the export interface of V3D functions to plugin
class V3DPluginCallback
{
public:
	virtual ~V3DPluginCallback() {}

////invoke a Vaa3D plugin function
	virtual bool callPluginFunc(const QString & plugin_name, const QString & func_name,
			const V3DPluginArgList & input, V3DPluginArgList & output) = 0;

////get opened images 

	//obtain a list of all currently opened images
	virtual v3dhandleList getImageWindowList() const = 0;

	//obtain the *current* selected image window, defined as the tri-view window currently selected in Vaa3D main window
	virtual v3dhandle currentImageWindow() = 0;

	//obtain the *current* selected image window, defined as the currently being operated 3D viewer
	//curHiddenSelectedWindow may not be the *currentImageWindow* if the selection is done from a 3d viewer
	virtual v3dhandle curHiddenSelectedWindow() = 0; 

////set computed image content/result 

	//create a new image window for returning some computed image content
	virtual v3dhandle newImageWindow(QString name="new_image") = 0;

	//directly output computed image content to an existing image window. The size of the window will be changed automatically.
	virtual void updateImageWindow(v3dhandle image_window) = 0;

////manipulate image names

	virtual QString getImageName(v3dhandle image_window) const = 0;
	virtual void setImageName(v3dhandle image_window, QString name) = 0;

////access the actual 4D image data structure

	virtual Image4DSimple * getImage(v3dhandle image_window) = 0;
	virtual bool setImage(v3dhandle image_window, Image4DSimple * image) = 0;

////access the 3D landmark list defined for an image

	virtual LandmarkList  getLandmark(v3dhandle image_window) = 0;
	virtual bool setLandmark(v3dhandle image_window, LandmarkList & landmark_list) = 0;

////access the 3D region of interest (ROI) defined for an image

	virtual ROIList getROI(v3dhandle image_window) = 0;
	virtual bool setROI(v3dhandle image_window, ROIList & roi_list) = 0;

////access the 3D curve, 3D curve set, and 3D reconstructed neuron structure for an image

	virtual NeuronTree getSWC(v3dhandle image_window) = 0;
	virtual bool setSWC(v3dhandle image_window, NeuronTree & nt) = 0;

////access the global-setting (e.g. display preferences) data structure of Vaa3D

	virtual V3D_GlobalSetting getGlobalSetting() = 0;
	virtual bool setGlobalSetting( V3D_GlobalSetting & gs ) = 0;

////operating (open/close) the rendering windows

	//open and close a global 3D viewer
	virtual void open3DWindow(v3dhandle image_window) = 0;
	virtual void close3DWindow(v3dhandle image_window) = 0;

	//open and close a local 3D viewer
	virtual void openROI3DWindow(v3dhandle image_window) = 0;
	virtual void closeROI3DWindow(v3dhandle image_window) = 0;

////Data pushing functions

	//update the surface objects currently being displayed in a 3D viewer
	virtual void pushObjectIn3DWindow(v3dhandle image_window) = 0;

	//update the content in a 3D viewer directly
	virtual void pushImageIn3DWindow(v3dhandle image_window) = 0;

	//update the time point of a 3D viewer if it is displaying 5D (temporal) data
	virtual int pushTimepointIn3DWindow(v3dhandle image_window, int timepoint) = 0;

////take snapshots of the 3D viewers

	//snap of a global 3D viewer
	virtual bool screenShot3DWindow(v3dhandle image_window, QString BMPfilename) = 0;

	//snap of a local 3D viewer
	virtual bool screenShotROI3DWindow(v3dhandle image_window, QString BMPfilename) = 0;
};

////direct pointers to Vaa3D internal data structure

	virtual View3DControl * getView3DControl(v3dhandle image_window) = 0;
	virtual View3DControl * getLocalView3DControl(v3dhandle image_window) = 0;
	virtual TriviewControl * getTriviewControl(v3dhandle image_window) = 0;

In details, with this callback function, it is possible to do the following.

get opened images

Obtain a list of all currently opened images

        virtual v3dhandleList getImageWindowList() const = 0;

Obtain the current selected image window, defined as the tri-view window currently selected in Vaa3D main window

        virtual v3dhandle currentImageWindow() = 0;

Obtain the current selected image window, defined as the currently being operated 3D viewer

        virtual v3dhandle curHiddenSelectedWindow() = 0; 

open/close 3D viewers

Open and close global 3D viewers can be done by

        virtual void open3DWindow(v3dhandle image_window) = 0;
        virtual void close3DWindow(v3dhandle image_window) = 0;

Open and close local 3D viewers can be done by

        virtual void openROI3DWindow(v3dhandle image_window) = 0;
        virtual void closeROI3DWindow(v3dhandle image_window) = 0;

set computed image content/result

Create a new image window for returning some computed image content

        virtual v3dhandle newImageWindow(QString name="new_image") = 0;

Directly output computed image content to an existing image window. The size of the window will be changed automatically.

        virtual void updateImageWindow(v3dhandle image_window) = 0;

manipulate image names

Get and set the image name (string)

        virtual QString getImageName(v3dhandle image_window) const = 0;
        virtual void setImageName(v3dhandle image_window, QString name) = 0;

access the actual 4D image data structure

Get and set the pixel information of Vaa3D images

        virtual Image4DSimple * getImage(v3dhandle image_window) = 0;
        virtual bool setImage(v3dhandle image_window, Image4DSimple * image) = 0;

access the 3D landmark list defined for an image

Landmarks are 3D locations of interest that a user can define for measuring some image statistics, or attach regional image annotations, or introduce prior information for image analysis. They can be accessed via

        virtual LandmarkList  getLandmark(v3dhandle image_window) = 0;
        virtual bool setLandmark(v3dhandle image_window, LandmarkList & landmark_list) = 0;

access the 3D region of interest (ROI) defined for an image

Regions of interest, defined a three polygons for XY, YZ, and ZX planes, can be access via

        virtual ROIList getROI(v3dhandle image_window) = 0;
        virtual bool setROI(v3dhandle image_window, ROIList & roi_list) = 0;

access the 3D curve, 3D curve set, and 3D reconstructed neuron structure for an image

3D curves or a 3D network structure or 3D reconstructed neurons can all be described as graphs. These graphs are coded using the SWC format, which typically is used to describe 3D neuron structures. These data can be accessed via

        virtual NeuronTree getSWC(v3dhandle image_window) = 0;
        virtual bool setSWC(v3dhandle image_window, NeuronTree & nt) = 0;

access the global-setting (e.g. display preferences) data structure of Vaa3D

Directly call

        virtual V3D_GlobalSetting getGlobalSetting() = 0;
        virtual bool setGlobalSetting( V3D_GlobalSetting & gs ) = 0;

surface and volume data pushing functions

Many times one may want to do some computation, and then update the 3D windows that display the computation results, but without closing these windows. This means the computed results should be "pushed" continuously to the 3D viewers. This can be done in the following ways.

For surface objects (e.g. neuron, point cloud, landmarks)

        virtual void pushObjectIn3DWindow(v3dhandle image_window) = 0;

For image pixel data

        virtual void pushImageIn3DWindow(v3dhandle image_window) = 0;

For 5D (temporal data), update the time point of a 3D viewer if it is displaying 5D (temporal) data

        virtual int pushTimepointIn3DWindow(v3dhandle image_window, int timepoint) = 0;

take snapshots of the 3D viewers

Use the function to to snapshot a global 3D viewer

        virtual bool screenShot3DWindow(v3dhandle image_window, QString BMPfilename) = 0;

or for a local 3D viewer window

	virtual bool screenShotROI3DWindow(v3dhandle image_window, QString BMPfilename) = 0;

invoke a Vaa3D plugin function using Callback

Call

        virtual bool callPluginFunc(const QString & plugin_name, const QString & func_name,
                        const V3DPluginArgList & input, V3DPluginArgList & output) = 0;

direct access to all surface objects in one or more 3D viewers

Call

	virtual QList <NeuronTree> * getHandleNeuronTrees_Any3DViewer(V3dR_MainWindow *w) = 0;
	virtual QList <CellAPO>    * getHandleAPOCellList_Any3DViewer(V3dR_MainWindow *w) = 0;        
	virtual QList <LabelSurf> getListLabelSurf_Any3DViewer(V3dR_MainWindow *w) = 0;
	virtual bool setListLabelSurf_Any3DViewer(V3dR_MainWindow *w, QList <LabelSurf> listLabelSurfinput) = 0;    

Since when a surface object is opened in a 3D viewer, this 3D viewer may not associate with a tri-view window of an image, an image handle may not be available. In this case, one can get the window handles of 3D viewers directly from calling

	virtual MainWindow * getVaa3DMainWindow() = 0; 
	virtual QList <V3dR_MainWindow *> getListAll3DViewers() = 0; 
	virtual V3dR_MainWindow * find3DViewerByName(QString fileName) = 0;

On the other hand, when a tri-view window handle is available, these surface objects in 3D viewers can be obtained by calling

	virtual QList <NeuronTree> * getHandleNeuronTrees_3DGlobalViewer(v3dhandle image_window) = 0;
	virtual QList <CellAPO>    * getHandleAPOCellList_3DGlobalViewer(v3dhandle image_window) = 0;        
	virtual QList <LabelSurf> getListLabelSurf_3DGlobalViewer(v3dhandle image_window) = 0;
	virtual bool setListLabelSurf_3DGlobalViewer(v3dhandle image_window, QList <LabelSurf> listLabelSurfinput) = 0;

direct access to all other data & functions of Vaa3D

Vaa3D's critical data structures are the tri-view windows, global 3D viewers and local 3D viewers. To access all other functions/data not provided in other parts of the plugin interfaces, you can call the following functions in the Callback class:

	virtual View3DControl * getView3DControl(v3dhandle image_window) = 0;  //return a pointer to a global 3D window
	virtual View3DControl * getLocalView3DControl(v3dhandle image_window) = 0;  //return a pointer to a local 3D viewer window
	virtual TriviewControl * getTriviewControl(v3dhandle image_window) = 0;  //return a pointer to the tri-view window

With these pointers, you can the do many more things, e.g. control how to generate a sub-volume visualization of images by combining volume-cut and surface-cut controls (scroll-bars) in a global/local 3D viewer.

Of course, to use these advanced functions, you will need to check the respective source code to understand the classes "View3DControl" and "TriviewControl". Yet, we provide these three functions so that an plugin program can take the ENTIRE control (and power) of Vaa3D, without the need to revise directly on the Vaa3D source code, thus to maximize the modularity of the code.

load and save image files who formats are supported by Vaa3D

While in principle anyone can use any existing or additional modules to load and save image files, when it is needed in a plugin this can often means including a number of header and source files and linking to some libraries (e.g. libtiff) that are already used in the Vaa3D main program. Therefore, it is beneficial to use the callback functions, instead of using the respective source codes directly, to load and save image files. The Vaa3D plugin interface provides two functions to load and save image files whose formats are supported by Vaa3D by default (including tif/tiff, lsm, v3draw, v3dpbd, mrc, ...):

	virtual Image4DSimple * loadImage(char *filename) = 0;  //return a pointer to the Image4DSimple data structure which is a container of the 4D/5D image data
	virtual bool saveImage(Image4DSimple * img, char *filename) = 0; //save the image to file

Understand the Vaa3D data structures for images and surface objects

Vaa3D plugin interfaces let one access the Vaa3D internal data structures for both multi-dimensional images and various surface objects. The actual data objects are defined in the following files

<vaa3d_source_code_folder>/v3d_main/basic_c_fun/basic_4dimage.h   # 4D/5D images
<vaa3d_source_code_folder>/v3d_main/basic_c_fun/basic_surf_objs.h # various surface objects
<vaa3d_source_code_folder>/v3d_main/basic_c_fun/basic_landmark.h  # 3D landmarks

For more details, either read them files directly (quite easy to understand!), or check other pages of this website for Vaa3D data structures.

How to capture the mouse and keyboard events in 3D viewer windows or tri-view windows?

Once you get the pointers to the tri-view or 3D viewers, you can at the source code level add a Qt event filter, to capture these events.

Multi-thread plugins

Vaa3D plugin interface is compatible with multi-threads programming. However, it is the plugin-developer's responsibility to ensure the threads should be created safely and meaningfully.

Interested developers can check some of the Vaa3D plugins, e.g. the "multithreaded_imgloading" plugin under the "review" folder after vaa3d_tools source code has been checked out. This plugin uses a separate thread to load image data while the main thread of Vaa3D is responsible for rendering the data.

⚠️ **GitHub.com Fallback** ⚠️