Options
All
  • Public
Menu

Class CustomFunctions

Websdk Plugins

Websdk Plugins

The F.A.S.T. Cloud SDK provides features to allow the client to call custom function plugins that will be run on the server. These plugins can be used to load custom data types or to implement custom data analysis and manipulation algorithms. The plugins are written in C++ and they will be dynamically loaded (.dll's in Windows, and runtime loaded .so's in Linux) into the address space of the server at program start. You will have access to all the relevant data structures in memory so you can perform almost any processing you wish. We recomend that processing which requires high compute resources and/or acces to the original DICOM images be done through custom functions implemented in plugins. There are four types of functions that can be implemented in a plugin file. These are 3D custom functions, 3D data loaders, 2D custom functions, and 2D data loaders.

Creating a Plugin File

The websdk distribution includes a basic sample plugin in the directory websdk/examples/plugins/plugin_sample that can be used as a reference. The source code for a number of other plugins packaged with the websdk distribution are also included in websdk/examples/plugins/.

A websdk plugin file is a Windows .dll or Linux .so file that exports a one or more functions designed to be called from the websdk server. The exported functions can have any name, but to be compatable with websdk, the exported functions must have the following prototypes.

3D Custom Function Prototype:
string customFunction3D(std::list<IVolumeData> &volumes, std::list<IVolumeOctree> &octrees, std::list<IRenderEngine> &renderEngines, std::list<IVolumeSegmentation> &segmentations, const nlohmann::json pJSONObjectInput, nlohmann::json pJSONObjectOutput);

3D Custom Loader Protoype:
string customLoad3D(const nlohmann::json pJSONObjectInput, IVolumeData** ppi, nlohmann::json pJSONObjectOutput);

2D Custom Function Prototype:
string customFunction2D(std::list<ISeriesDataContext> &series, std::list<ISegmentation2DContext> &segmentations, const nlohmann::json pJSONObjectInput, nlohmann::json pJSONObjectOutput);

2D Custom Loader Prototype:
string customLoad2D(const nlohmann::json pJSONObjectInput, IDicomStudyData** ppi, nlohmann::json pScanDirResultsJson, nlohmann::json pJSONObjectOutput);

A websdk plugin must include the file websdk_plugin_defines.h. This file is included in the websdk distribution in the websdk/examples/customfunctions/Headers directory. The websdk_plugin_defines.h contains a number of predefined values that facilitate plugin development. The plugin must also include the appropriate header files with definitions for the websdk data types used by the function protoypes. The developer may also wish to include the header files for HDVR In-Process SDK, which allows direct access to low level native data structures.

#include "websdk_plugin_defines.h"

#include "hdrc/hdrc.h"
#include "sysapi/sysdef.h"

#include "FoviaCustomInterfaces.h"
#include "foviaJSONtoCPPConverter.h"

A websdk plugin must export an enumeration function called EnumerateFunctions(), as shown below. This function returns to the websdk plugin loader a std::string that contains the names and types of functions included in the plugin so they may be bound to the websdk server. Any combination or number of 2D/3D custom functions and custom loaders may be packaged in a plugin file. The only restrictions are that the exported functions must comform the the required prototypes listed above, and that function names must be gloabally unique across all plugin files within the four function types. For example, amonsts all 3D custom data loader functions, a function name must be unique, but the same function name could be used in a 2D custom data loader, if desired. The EnumerateFunctions() function must also return in output paramaters the plugin version identifier. The plugin version numbers are provided in websdk_plugin_defines.h and should be returned as shown below.

string EnumerateFunctions(int
pMajorVersion, int pMinorVersion) {

    string functionBuf;

    // Create list of function names and types.  
    functionBuf += "customFunction3D" + PLUGIN_TYPE_FUNC3D;
    functionBuf += "customFunction2D" + PLUGIN_TYPE_FUNC2D;
    functionBuf += "customLoad3D" + PLUGIN_TYPE_LOAD3D;
    functionBuf += "customLoad2D" + PLUGIN_TYPE_LOAD2D;

    // Return plugin version number.
    if (pMajorVersion)
pMajorVersion = PLUGIN_MAJOR_VERSION;
    if (pMinorVersion) *pMinorVersion = PLUGIN_MINOR_VERSION;

    return functionBuf;
}



The compiled plugin binary file should be placed in the websdk/foviaserver/nodeaddon/plugins directory.

Calling Custom Functions and Loaders from the Client

Invoke a server-side 3D custom function with a call to Fovia.ServerContext.callCustomFunction passing in an array of Volumes, an array of Octrees, an array of Render Engines, an array of Segmentation objects and a JSON object of parameters that you build up as required. The arrays can be either null (if that data structure is not needed by your custom functions on the other side) or an array of one or more objects. For most cases only one object is needed but the array implementation allows for multiple objects to be passed in case comparaisons or multi-object processing is necessary. Invoke a server-side 2D custom function with a call to Fovia.ServerContext.callCustomFunction2D passing in an array of SeriesDataContext and SeriesSegmentationContext objects. The input JSON object is decoded within the custom function so the input paramaters can be processed. A JSON object is returned from the custom function containing custom output values generated by the server-side implementation.

Invoke a server-side 3D custom data loader with a call to Fovia.ServerContext.loadCustomData , passing in a JSON object of parameters that you build up as required. This function also takes a boolean flag indicating if an octree structure should be built for the dataset. Invoke a server-side 2D custom data loader with a call to Fovia.ServerContext.load2DCustomData, which also takes an input JSON object of paramaters. The input JSON object is decoded within the custom function so the input paramaters can be processed. A JSON object is returned from the custom function containing custom output values generated by the server-side implementation.

The call returns a promise that is fulfilled when the custom function completes on the server side. Another JSON object is returned which is built on the server side in the plugin implementation so it can be decoded and read on the client.

Concurrent Processing.

Crashes or data corruption could happen if custom functions are running and changing data while the server is trying to render. For this reason you want to avoid the possiblity of calling custom functions to change data while rendering or segmenting data on server side. You can do this inside your app, or you can use the two client-side functions below.

pauseServerOperations() with the same parameters as the callCustomFunctions(). It will pause and return a promise that is fulfilled only when all operations on those data structures are completed and flag is set indicating that no more can start.

resumeServerOperations() either again with all the objects that would like to resume or resumeAllServerOperations() which will enable all operations on all objects.

Hierarchy

  • CustomFunctions