NOTE: This is the documentation for the new version of the Huygens Loadable Modules interface, used in recent versions of Huygens (20.04 and newer). Documentation for the old interface (up to Huygens 15.10) can be found here.
Huygens Loadable Modules
Table of contents
1 Introduction
Huygens Loadable Modules allows you to create modules that extend Huygens Professional. It allows you define new Tcl commands, create user interfaces, and provides low-level access to the Huygens images. Modules are written in C and Tcl. Graphical User Interfaces can be written using the Tk-toolkit.
2 Requirements
To use loadable modules you need a working installation of Huygens Professional and a C compiler.
3 Usage
To make use of loadable modules Huygens should be started with the “-checkLoadMod” option. This option directs Huygens to search for modules in the SVI/PlugIn directory. Multiple loadable modules can be loaded simultaneously with or without configuration files.
4 Developing modules
4.1 Overview
A loadable module consists of at least a Makefile and one or more C source files. Additionally a module can have a ‘gui’ folder with Tcl/Tk files for the GUI and a ‘doc’ folder for module documentation. The files in the GUI folder are automatically sourced on module initialization.
4.2 The module source file
A loadable module can consist of one or more C files, which all should include the HuExtern.h include file. Before including the HuExtern.h file, a unique global variable name should be defined, in this way:
#define HUEXT_API G_moduleName /* Replace G_moduleName with your unique name. */ #include "HuExtern.h"
In one of the source files the following macro should be called:
HUEXT_DEFINE_API;
4.3 The initialization function
Every Huygens Loadable Module should implement the InitHuygensExtension fuction:
HUEXT_EXPORT void InitHuygensExtension(HuExt_API api);
This initialization function is called when a module is loaded by Huygens at start-up. It should contain a call to the following macro, before any other plugin functions are called:
HUEXT_INIT_API(api);
4.4 Commands and image operations
In the initialization function you can create Tcl commands and add image operations. With the following function you can create a Tcl command:
int HuExt_CreateTclCmd(const char *cmdName, HuExt_CmdFuncType *cmdFuncPtr);
After the Tcl command is registered you can type the command ‘comName’ in the Tcl interpreter to call the function where ‘comFuncPtr’ points to.
To add an image operation this function should be called:int HuExt_AddImgOp(const char *opName, HuExt_ImgOpFuncType *opFuncPtr);
This adds an operation with name ‘opName’ that can be applied to an image by calling the function that is passed by ‘imgOpFuncPtr’.
4.5 Error handling
Most functions that are provided by HuExtern.h return an error that can have the value 'HUEXT_OK" or "HUEXT_ERROR". Functions you add with 'HuExt_CreateTclCmd' or 'HuExt_ImgOpFuncType' should also return HUEXT_OK when succesful, or HUEXT_ERROR otherwise.
To report an error message you can set the Tcl result to an error message using:
void HuExt_TclSetError(const char *cmdName, const char *format, ...);
4.6 GUI communication
Communication with a Tcl/Tk GUI is handled with a String token. A String token can be created and destroyed using the following functions:
HuExt_ErrorTokenType HuExt_CreateString(HuExt_StringTokenType *token); HuExt_ErrorTokenType HuExt_DestroyString(HuExt_StringTokenType token);
Text can be added to the string token using the following command:
HuExt_ErrorTokenType HuExt_AppendToString(HuExt_StringTokenType token, const char *fmt, ...);
To set the result of a Tcl command that you added you can call the following function:
void HuExt_TclSetResult(HuExt_StringTokenType token);
You can also print to the Huygens report window using:
HuExt_ErrorTokenType HuExt_Print(const char *format, ...);
4.7 Accessing Huygens images
A number of functions are availabe for low-level access to Huygens images:
/* Adopt the physical parameters of another image: */ HuExt_ErrorTokenType AdoptPhysicalParams(HuExt_ImageTokenType src, HuExt_ImageTokenType dest); /* Get an image token by image name: */ HuExt_ErrorTokenType HuExt_ImName2Token(HuExt_ImageTokenType *token, const char *name); /* Get an image name by image token: */ HuExt_ErrorTokenType HuExt_ImToken2Name(HuExt_ImageTokenType token, char *name); /* Get the image data pointer for read-only use: */ HuExt_ErrorTokenType HuExt_InqImRODataPtr(HuExt_ImageTokenType token, HuExt_RODataPtrType *ptr); /* Get the image data pointer for read-write use: */ HuExt_ErrorTokenType HuExt_InqImRWDataPtr(HuExt_ImageTokenType token, HuExt_RWDataPtrType *ptr); /* Get the image data type: */ HuExt_ErrorTokenType HuExt_InqImDataSpec(HuExt_ImageTokenType token, HuExt_DataSpecType *spec); /* Get the image dimensions: */ HuExt_ErrorTokenType HuExt_InqImDimSel(HuExt_ImageTokenType token, HuExt_DimensionSelectorType *dims); /* Inquire the image channel count: */ HuExt_ErrorTokenType HuExt_InqImChanCnt(HuExt_ImageTokenType token, int *cnt); /* Inquire the image channel configuration: */ HuExt_ErrorTokenType HuExt_InqChanConfig(HuExt_ImageTokenType token, HuExt_ChanConfigSpecType *conf); /* Adapt an image to a new size and data type: */ HuExt_ErrorTokenType HuExt_AdaptImage(HuExt_ImageTokenType token, HuExt_SizeType x, HuExt_SizeType y, HuExt_SizeType z, HuExt_SizeType t, int cnt, HuExt_DataSpecType spec, HuExt_ChanConfigSpecType conf); /* Publish an image, updating its display: */ HuExt_ErrorTokenType HuExt_PublishImage(HuExt_ImageTokenType token);
The definitions of the various C types needed to use these functions can be found in HuExtern.h.
5 Examples
Here is a simple example of a minimal Huygens Module which implements a Tcl command that just prints its arguments to the Huygens report window and an image command which just returns the image dimensions in the Tcl result string of the command:
#include <stdlib.h> #include <stdio.h> #include <string.h> /* Before including HuExtern.h define a macro with the name of the variable that will hold the pointer to the API structure. */ #define HUEXT_API G_testPlugin #include "HuExtern.h" /* declare a global variable to hold the API. */ HUEXT_DEFINE_API; /* A callback for a new Tcl command that prints its arguments. */ int printArgumentsCmd(int argc, const char *argv[]) { int j; char msg[1024]; msg[0] = 0; for (j = 1; j < argc - 1; j++) sprintf(msg + strlen(msg), "%s ", argv[j]); if (argc > 1) sprintf(msg + strlen(msg), "%s", argv[argc - 1]); HuExt_Print("arguments: %s", msg); return HUEXT_OK; } /* A callback for a new image operation that returns the X, Y and Z dimensions. */ int getImageDimensionsCmd(HuExt_ImageTokenType token, int argc, const char *argv[]) { HuExt_ErrorTokenType error = HUEXT_OK; HuExt_StringTokenType result; HuExt_DimensionSelectorType dims; if (argc > 2) { HuExt_TclSetError("getImageDimensions", "something happened"); return HUEXT_ERROR; } error = HuExt_InqImDimSel(token, &dims); if (error != HUEXT_OK) return error; error = HuExt_CreateString(&result); if (error != HUEXT_OK) return error; error = HuExt_AppendToString(result, "%d %d %d", dims[0], dims[1], dims[2]); if (error != HUEXT_OK) return error; HuExt_TclSetResult(result); return HUEXT_OK; } /* The initialization function of the module. */ HUEXT_EXPORT void InitHuygensExtension(HuExt_API api) { /* Initialize the API from the input parameter. */ HUEXT_INIT_API(api); /* Create a command. */ HuExt_CreateTclCmd("printArguments", printArgumentsCmd); /* Create a image operation. */ HuExt_AddImgOp("getImageDimensions", getImageDimensionsCmd); }
Download the FRAP simulator to see what a more complex Huygens Module looks like.
6 Building and executing the module
In the FRAP simulator one can see which files are necessary to build a module. Besides the C implementation of a particular function one needs to provide a Makefile that compiles the C code and copies the object files to the HOME/SVI/PlugIn directory.
After a successful build the module can be loaded into Huygens by using the checkLoadMod argument. The module can then be used as an extension command to the regular Huygens library. The command can perform any operation on the images and a GUI can be build around it.
For example, the FRAP simulator is equipped with a GUI which is launched by typing::FrapSimulator::create
7 Licensing
Huygens Loadable Modules is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty ; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.