Making Plugins to 3dmod

When 3dmod starts, it attempts to load dynamic libraries from $IMOD_PLUGIN_DIR (by default, $IMOD_DIR/lib/imodplug), from $IMOD_CALIB_DIR/plugins (by default, /usr/local/ImodCalib/plugins) and from two other less useful locations. It then tries to run defined functions to confirm that they are plugins.

This document gives some basic information about making a plugin to 3dmod and contains the documentation of the functions in 3dmod that are normally accessible from plugins.

Instructions for Making Plugins

Functions Defined in Plugins


const char PLUG_EXPORT *imodPlugInfo(int *type)
void PLUG_EXPORT imodPlugExecute(ImodView *vw)
void PLUG_EXPORT imodPlugExecuteType(ImodView *inView, int inType, int inReason)
int PLUG_EXPORT imodPlugKeys(ImodView *vw, QKeyEvent *event)
int PLUG_EXPORT imodPlugMouse(ImodView *vw, QMouseEvent *event, float imx, float imy, int but1, int but2, int but3)
int PLUG_EXPORT imodPlugEvent(ImodView *vw, QEvent *event, float imx, float imy)
int PLUG_EXPORT imodPlugExecuteMessage(ImodView *vw, QStringList *strings, int *arg)
QString PLUG_EXPORT imodPlugOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter)
QStringList PLUG_EXPORT imodPlugOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter)
QString PLUG_EXPORT imodPlugSaveFileName(QWidget *parent, const QString &caption)

Flag Definitions


Draw flags
Plugin flags
Snapshot flags

Application and Utility Functions


void DLL_EX_IM imodDrawModel(ImodView *inImodView, Imod *inModel, int drawCurrent, float zscale)
int DLL_EX_IM imodDepth(void)
int DLL_EX_IM imodColorValue(int inColor)
void DLL_EX_IM wprint(const char *fmt, ...)
void DLL_EX_IM imodError(FILE *out, const char *format, ...)
void DLL_EX_IM imodPrintStderr(const char *format, ...)
void DLL_EX_IM imodTrace(char key, const char *format, ...)
void DLL_EX_IM imodPuts(const char *message)
void DLL_EX_IM imodPrintInfo(const char *message)
void DLL_EX_IM imodDefaultKeys(QKeyEvent *event, ImodView *vw)
int DLL_EX_IM imodShowHelpPage(const char *page)

Functions Operating on an ImodView


int DLL_EX_IM ivwDraw(ImodView *inImodView, int inFlags)
int DLL_EX_IM ivwRedraw(ImodView *vw)
void DLL_EX_IM ivwGetImageSize(ImodView *inImodView, int *outX, int *outY, int *outZ)
void DLL_EX_IM ivwGetLocation(ImodView *inImodView, int *outX, int *outY, int *outZ)
void DLL_EX_IM ivwGetLocationPoint(ImodView *inImodView, Ipoint *outPoint)
void DLL_EX_IM ivwSetLocation(ImodView *inImodView, int inX, int inY, int inZ)
void DLL_EX_IM ivwSetLocationPoint(ImodView *inImodView, Ipoint *inPoint)
int DLL_EX_IM ivwGetTime(ImodView *inImodView, int *outTime)
void DLL_EX_IM ivwSetTime(ImodView *inImodView, int inTime)
const char DLL_EX_IM *ivwGetTimeLabel(ImodView *inImodView)
const char DLL_EX_IM *ivwGetTimeIndexLabel(ImodView *inImodView, int inIndex)
void DLL_EX_IM ivwSetNewContourTime(ImodView *vi, Iobj *obj, Icont *cont)
int DLL_EX_IM ivwGetImageStoreMode(ImodView *inImodView)
bool DLL_EX_IM ivwDataInTileOrStripCache(ImodView *inImodView)
unsigned char DLL_EX_IM **ivwGetZSection(ImodView *inImodView, int inSection)
unsigned char DLL_EX_IM **ivwGetCurrentZSection(ImodView *inImodView)
unsigned char DLL_EX_IM **ivwGetZSectionTime(ImodView *vi, int section, int time)
unsigned char DLL_EX_IM **ivwGetTileCachedSection(ImodView *inImodView, int section)
void DLL_EX_IM ivwFreeTileCachedSection(ImodView *inImodView)
unsigned char DLL_EX_IM *ivwUShortInRangeToByteMap(ImodView *inImodView)
int DLL_EX_IM ivwCopyImageToByteBuffer(ImodView *inImodView, unsigned char **image, unsigned char *buf)
int DLL_EX_IM ivwGetValue(ImodView *inImodView, int inX, int inY, int inZ)
float DLL_EX_IM ivwGetFileValue(ImodView *inImodView, int inX, int inY, int inZ)
int DLL_EX_IM ivwReadAngleFile(ImodView *vi, const char *fname)
float DLL_EX_IM *ivwGetTiltAngles(ImodView *vi, int &numAngles)
Imod DLL_EX_IM *ivwGetModel(ImodView *inImodView)
int DLL_EX_IM ivwGetFreeExtraObjectNumber(ImodView *vi)
int DLL_EX_IM ivwFreeExtraObject(ImodView *vi, int objNum)
Iobj DLL_EX_IM *ivwGetAnExtraObject(ImodView *inImodView, int objNum)
void DLL_EX_IM ivwClearAnExtraObject(ImodView *inImodView, int objNum)
Iobj DLL_EX_IM *ivwGetExtraObject(ImodView *inImodView)
void DLL_EX_IM ivwClearExtraObject(ImodView *inImodView)
void DLL_EX_IM ivwEnableStipple(ImodView *inImodView, int enable)
void DLL_EX_IM ivwTrackMouseForPlugs(ImodView *inImodView, int enable)
Icont DLL_EX_IM *ivwGetOrMakeContour(ImodView *vw, Iobj *obj, int timeLock)
int DLL_EX_IM ivwGetMovieModelMode(ImodView *vw)
void DLL_EX_IM ivwSetMovieModelMode(ImodView *inImodView, int mode)
int DLL_EX_IM ivwGetContrastReversed(ImodView *inImodView)
int DLL_EX_IM ivwOverlayOK(ImodView *inImodView)
void DLL_EX_IM ivwSetOverlayMode(ImodView *inImodView, int sec, int reverse, int whichGreen)
int DLL_EX_IM ivwGetTopZapZslice(ImodView *inImodView, int *outZ)
int DLL_EX_IM ivwSetTopZapZslice(ImodView *inImodView, int inZ)
int DLL_EX_IM ivwGetTopZapZoom(ImodView *inImodView, float *outZoom)
int DLL_EX_IM ivwSetTopZapZoom(ImodView *inImodView, float inZoom, bool draw)
int DLL_EX_IM ivwGetTopZapMouse(ImodView *inImodView, Ipoint *imagePt)
int DLL_EX_IM ivwGetTopZapCenter(ImodView *inImodView, float &imX, float &imY, int &imZ)
int DLL_EX_IM ivwSetTopZapCenter(ImodView *inImodView, float imX, float imY, int imZ, bool draw)
QString DLL_EX_IM ivwCurrentImageFile(ImodView *inImodView, bool asEntered)
void DLL_EX_IM b3dSetSnapshotCaption(QStringList &captionLines, bool wrapLastLine)
int DLL_EX_IM ivwSnapshotTopZap(QString &name, int format, bool checkGrayConvert, bool fullArea)
int DLL_EX_IM ivwSnapshotTopSlicer(QString &name, int format, bool checkGrayConvert, bool fullArea)
int DLL_EX_IM startAddedArrow(int windowType)
int DLL_EX_IM clearAllArrows(int windowType, bool allWindows)
int DLL_EX_IM getTopSlicerAngles(float angles[3], Ipoint *center, int &time)
int DLL_EX_IM ivwGetTopSlicerZoom(ImodView *inImodView, float *outZoom)
void DLL_EX_IM scaleBarAllLengths(float &zapLen, float &slicerLen, float &xyzLen, float &multiZlen, float &modvLen)
void DLL_EX_IM setScaleBarWithoutDialog(bool enable)
void DLL_EX_IM ivwOpen3dmodDialogs(const char *keys)
QString DLL_EX_IM b3dGetSnapDirectory(void)
void DLL_EX_IM imodSelectionListAdd(ImodView *vi, Iindex newIndex)
int DLL_EX_IM imodSelectionListClear(ImodView *vi)
int DLL_EX_IM imodSelectionListQuery(ImodView *vi, int ob, int co)
void DLL_EX_IM imodSelectionListRemove(ImodView *vi, int ob, int co)
void DLL_EX_IM imodSelectionNewCurPoint(ImodView *vi, Imod *imod, Iindex indSave, int controlDown)
int DLL_EX_IM imodNumSelectedObjects(ImodView *vi, int &minOb, int &maxOb)
void DLL_EX_IM imodUpdateObjectDialogs()
int DLL_EX_IM prefSaveGenericSettings(char *key, int numVals, double *values)
int DLL_EX_IM prefGetGenericSettings(char *key, double *values, int maxVals)
QString DLL_EX_IM utilOpenFileName(QWidget *parent, const char *caption, int numFilters, const char *filters[])
QString DLL_EX_IM imodPlugGetSaveName(QWidget *parent, const QString &caption)

Functions for Registering an Image Drawing Control


int DLL_EX_IM ivwNewControl(ImodView *inImodView, ImodControlProc inDrawFunction, ImodControlProc inQuitFunction, ImodControlKey inKeyFunction, void *data)
int DLL_EX_IM ivwDeleteControl(ImodView *iv, int inCtrlId)
int DLL_EX_IM ivwRemoveControl(ImodView *iv, int inCtrlId)
int DLL_EX_IM ivwControlPriority(ImodView *iv, int inCtrlId)
void DLL_EX_IM ivwControlActive(ImodView *iv, int inCtrlId)
void DLL_EX_IM ivwControlKey(int released, QKeyEvent *e)

Definitions for controls.
Control callbacks

Registering with a Dialog Manager

Definitions and other aspects of a DialogManager.
Dialog Manager

Methods in the DialogManager class.
void DLL_EX_IM adjustGeometryAndShow(QWidget *widget, int dlgClass, bool doSize = true)
void add(QWidget *widget, int dlgClass = IMODV_DIALOG, int dlgType = UNKNOWN_TYPE, int ctrlId = -1)
void remove(QWidget *widget)
QWidget *parent(int dlgClass)

Functions for Undo/Redo


Essay on Undo/Redo
void DLL_EX_IM undoPointChange(ImodView *vi, int type, int object, int contour, int point, int point2)
void DLL_EX_IM undoContourChange(ImodView *vi, int type, int object, int contour, int object2, int contour2)
void DLL_EX_IM undoObjectChange(ImodView *vi, int type, int object, int object2)
void DLL_EX_IM undoModelChange(ImodView *vi, int type, Ipoint *point)
void DLL_EX_IM undoPointShiftCP(ImodView *vi)
void DLL_EX_IM undoPointShift(ImodView *vi, int point)
void DLL_EX_IM undoPointAdditionCC(ImodView *vi, int point)
void DLL_EX_IM undoPointAdditionCC2(ImodView *vi, int point, int point2)
void DLL_EX_IM undoPointAddition(ImodView *vi, int object, int contour, int point)
void DLL_EX_IM undoPointRemovalCP(ImodView *vi)
void DLL_EX_IM undoPointRemoval(ImodView *vi, int point)
void DLL_EX_IM undoPointRemoval2(ImodView *vi, int point, int point2)
void DLL_EX_IM undoContourDataChgCC(ImodView *vi)
void DLL_EX_IM undoContourDataChg(ImodView *vi, int object, int contour)
void DLL_EX_IM undoContourPropChgCC(ImodView *vi)
void DLL_EX_IM undoContourPropChg(ImodView *vi, int object, int contour)
void DLL_EX_IM undoContourRemovalCC(ImodView *vi)
void DLL_EX_IM undoContourRemovalCO(ImodView *vi, int contour)
void DLL_EX_IM undoContourRemoval(ImodView *vi, int object, int contour)
void DLL_EX_IM undoContourAdditionCO(ImodView *vi, int contour)
void DLL_EX_IM undoContourAddition(ImodView *vi, int object, int contour)
void DLL_EX_IM undoContourMove(ImodView *vi, int object, int contour, int object2, int contour2)
void DLL_EX_IM undoObjectPropChgCO(ImodView *vi)
void DLL_EX_IM undoObjectPropChg(ImodView *vi, int object)
void DLL_EX_IM undoObjectRemovalCO(ImodView *vi)
void DLL_EX_IM undoObjectRemoval(ImodView *vi, int object)
void DLL_EX_IM undoObjectAddition(ImodView *vi, int object)
void DLL_EX_IM undoObjectMove(ImodView *vi, int object, int object2)
void DLL_EX_IM undoModelShift(ImodView *vi, Ipoint *point)
void DLL_EX_IM undoFinishUnit(ImodView *vi)
void DLL_EX_IM undoFlushUnit(ImodView *vi)

Instructions for Making Plugins

Here are the preliminary steps:

Beadfixer example. The plugin in IMOD/plugs/beadfix is an old version of the Bead Fixer that was retained to test the ability to build and run plugins, and now serves as an example of a plugin. It is not ideal because it has much more functionality than is needed to illustrate the various features of a plugin. You can concentrate on the implementation of the generic plugin functions in the beginning of the file and ignore most of the class implementation. The functional components do provide examples of how to access and manipulate model structures. There is one major deficiency in this example; it has not been updated to show the proper handling of calls to the undo/redo module. If your plugin modifies the model, you should try to make these calls, as documented below. For examples, you can look in corresponding places in the current beadfix.cpp in the imod directory and in other places in the 3dmod code (grep on "undo").

Public versus Private Structures. The beadfixer example is set up to access the model only by passing pointers to functions that operate on the underlying structures, rather than by accessing structure members directly. This method of defining structures as private was set up by Jim Kremer when he first developed the plugin interface; it has been retained but not extended to cover some new model structures or other structures in the IMOD libraries. It is possible to define a flag to eliminate the private structures and allow access to structure members. The advantages of keeping the structures private are 1) it insulates your plugin against changes in the structure members so that it does not have to be recompiled after such changes; 2) it is a little more object-oriented. The disadvantages are: 1) it is a little clumsier than operating directly on structure members, particularly when looping on contours and objects; and 2) you may find that there is no function to perform a needed operation on a structure member. In the latter case, we can easily add such functions, but then you will be constrained to running with the latest IMOD. It is recommended that you try to keep the structures private when you start work on a plugin, and only switch to accessing structure members if that turns out to be necessary.

Exported Functions and Include Files. In Linux and Mac OS X, all global functions in 3dmod are available to a plugin; whereas in Windows, only functions that are explicitly exported (using DLL_EX_IM) are available. For portability, it is recommended that you use only the exported functions. If you find that you need other functions, we can in most cases easily add the export macro and shift them from private to public header files. If you look at the plugin Makefile, you will see that it copies several headers from the imod directory instead of adding that directory to the include path. These are the headers needed for all the exported functions in 3dmod. All of the headers in IMOD/include are also available to a plugin since that directory is on the include path. All C library functions should be available to a plugin.

ImodView Structure. Many of the functions for interacting with 3dmod pass a pointer to an ImodView structure. This structure has all the information about the data loaded into 3dmod. In principle, there could be more than one such structure, allowing a multi-document type interface; but this capability has never been implemented, so there is just the one ImodView structure in the application. Nevertheless, we keep passing it around.

Dialog Manager and Drawing Control Functions. Every window, either dialog or graphical display, must register with a dialog manager. There is one dialog manager for 3dmod windows and one for model view windows. Plugins would register with imodDialogManager (since plugins to model view are not yet allowed). Follow the example of what beadfixer does to avoid crashes upon closing the window or exiting the program. Image drawing windows have the additional need to register themselves as drawing "controls" so that they get drawn at appropriate times. See the code for image drawing windows for examples of how this is done; locator.cpp would be the simplest.

Sharing You Plugin. If your plugin is generally useful, you may want other people to have access to it. First note the constraints imposed by using Qt. In general, to distribute software using Qt, you must either hold a Qt license or make the source available under an open source license (either GPL or the Q Public License, as far as we could tell). The Qt-related components of IMOD are open source under the GPL. With this in mind, there are at least three ways in which a plugin could be distributed:

  1. You build your plugin on whatever platforms you want to manage, and make it available for users to place in an appropriate directory.
  2. You contribute your code for incorporation into the IMOD source, and we would include the plugin in IMOD distributions for all platforms. The plugin would also be included in our open source releases.
  3. If for some reason you still want to control the distribution, but want the benefit of our building infrastructure, you could contribute the code to the IMOD source but have us leave the plugin out of the install (as the beadfixer example is). We would provide you with copies of the plugin on the various platforms at the time of our major releases. The plugin would still be included in our open source releases.

Functions Defined in Plugins

const char PLUG_EXPORT *imodPlugInfo(int *type)

Function to be defined by all plugins.  
Returns the name of the plugin, which will be inserted in the Special menu and used to send imodsendevent messages by name.  Bit flags made by OR'ing IMOD_PLUG_ values for the type of plugin are returned in type.  
Not all of 3dmod's data structures may be initialized at the time this function is called, so no initialization should be done.  However, an image loading plugin can call iiAddCheckFunction at this time.

void PLUG_EXPORT imodPlugExecute(ImodView *vw)

Menu execution function for plugins with the IMOD_PLUG_MENU bit set.  
vw is the pointer to the view structure, which should be stored and used when calling back into the program. imodPlugExecute will be called if available; if not defined then the following call will be made:
imodPlugExecuteType(inView, IMOD_PLUG_MENU, IMOD_REASON_EXECUTE);

void PLUG_EXPORT imodPlugExecuteType(ImodView *inView, int inType, int inReason)

Function for notification that 3dmod initialization is complete (with inType equal to 0 and inReason equal to IMOD_REASON_STARTUP), and for need to update for a change in model (with inType equal to 0 and inReason equal to IMOD_REASON_MODUPDATE). It is also an alternate function for opening through the menu.

int PLUG_EXPORT imodPlugKeys(ImodView *vw, QKeyEvent *event)

Key input callback function to be defined by plugins with the IMOD_PLUG_KEYS bit set.  
This function can be used to override 3dmod hot key settings; it is called by image windows before they process a key event. A nonzero return value indicates that the plugin handled the input key. and that no other action should be taken by the 3dmod program. A zero return value indicates that 3dmod should process the key as usual.

int PLUG_EXPORT imodPlugMouse(ImodView *vw, QMouseEvent *event, float imx, float imy, int but1, int but2, int but3)

Mouse event callback function to be defined by plugins with the IMOD_PLUG_MOUSE bit set.  
This function can be used to override 3dmod mouse actions in the Zap window.  imx and imy will contain the image position, and but1, but2, and but3 will indicate the state of the 3 buttons as mapped by user preferences.  The return value should be the sum of two values:
  1 if the plugin handled the mouse event, indicating that no other action should be taken with the event itself by the 3dmod program.
  2 if the specific calling window should draw itself, without issuing a general program redraw.  If this is not sufficient, the plugin should call ivwRedraw instead of setting this bit.
  A zero return value indicates that 3dmod should process the event as usual.
This function is called only when a mouse button is down, unless mouse tracking is enabled with ivwTrackMouseForPlugs.

int PLUG_EXPORT imodPlugEvent(ImodView *vw, QEvent *event, float imx, float imy)

General event callback function to be defined by plugins with the IMOD_PLUG_EVENT bit set.  
This function can be used to receive notification of selected events from a Zap window, currently QEvent::Enter, QEvent::Leave, and QEvent::Wheel (which can be cast to QWheelEvent). imx and imy will contain the image position of the mouse at the time of the event.  The return value should be the sum of 1 and 2 as for imodPlugMouse, or 0 if the event should be processed as usual.  It should not be necessary to process Enter and Leave events since the Zap window uses them to manage the removal of a cursor-like extra object created by a plugin.

int PLUG_EXPORT imodPlugExecuteMessage(ImodView *vw, QStringList *strings, int *arg)

Function to execute a message, to be defined by plugins with the IMOD_PLUG_MESSAGE bit set.  
The entire message string is in the strings argument; arg is the index of the current string and should be returned with the index of the last string of the message executed by this plugin. A non-zero return indicates an error.

QString PLUG_EXPORT imodPlugOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter)

Function to get a filename for a file to open.  This and the following file chooser functions are called if defined by plugins with the IMOD_PLUG_CHOOSER bit set.  When 3dmod calls for a file choosing operation, the appropriate call is made to the first file chooser plugin that defines that function.  If none exists, then the corresponding QFileDialog static chooser function is called.  File chooser plugins will be accessed only if the program is started in a way that brings up either the startup window or a file chooser for an image file.
imodPlugOpenFileName should behave like QFileDialog::getOpenFileName when called with these four arguments.

QStringList PLUG_EXPORT imodPlugOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter)

Function to get multiple multiple filenames to open.  It should behave like QFileDialog::getOpenFileName when called with these four arguments.

QString PLUG_EXPORT imodPlugSaveFileName(QWidget *parent, const QString &caption)

Function to get a filename for saving a file.  It should behave like QFileDialog::getSaveFileName when called with these two arguments.

Flag Definitions

Draw flags

Defines for imodDraw() and ivwDraw().  IMOD_DRAW_ACTIVE and IMOD_DRAW_TOP are flags added by the control module when calling the active or top window and would not be included in calls to the draw routines.

/* image data or color map has changed; windows need to clear caches and draw
   all images */
#define IMOD_DRAW_IMAGE       (1) 

/* The current point x, y, z position has been changed.  This causes an update
   of the info window x/y/z, image scale dialog if multifile Z loaded, the 
   image processing window, and the isosurface window.  Model view will be 
   drawn if the image display is on, unless the IMOD_DRAW_SKIPMODV flag is 
   also set. */
#define IMOD_DRAW_XYZ      (1<<1) 

/* Model data or current model object/contour/point has been changed. 
   Prior to XYZ update, this causes update to info window obj/cont/pt, and
   to object edit, cont/surf/pt, contour move and fine grain dialogs and
   update of plugins with IMOD_REASON_MODUPDATE.  Model view will be drawn
   unless the IMOD_DRAW_SKIPMODV flag is also set. */
#define IMOD_DRAW_MOD      (1<<2)

/* A slicer location has changed; Zap and XYZ windows will draw slicer lines */
#define IMOD_DRAW_SLICE    (1<<3) 

/* Skip drawing model view.  Use this to cause a draw of image windows when
 a model view draw is already inevitable */
#define IMOD_DRAW_SKIPMODV (1<<5) 

/* Color index mode color map has changed.  Do not combine with other flags. */
#define IMOD_DRAW_COLORMAP (1<<11)

/* Do not resync image to model point.  This keeps Zap from recentering. */
#define IMOD_DRAW_NOSYNC  (1<<12)

/* Recalculate cursor position: adds the IMOD_DRAW_MOD flag, and if there is
   a current model point defined, sets current point x,y,z to it and adds the 
   IMOD_DRAW_XYZ flag */
#define IMOD_DRAW_RETHINK (1<<13)
#define IMOD_DRAW_ACTIVE  (1<<14) /* current window is active.            */
#define IMOD_DRAW_TOP     (1<<15) /* current window has highest priority. */

#define IMOD_DRAW_ALL (IMOD_DRAW_IMAGE | IMOD_DRAW_XYZ | IMOD_DRAW_MOD)

Plugin flags

The IMOD_PLUG_ flags are ones that a plugin sends back in response to the ImodPlugInfo call.  The IMOD_REASON_ values are sent to the plugin in the imodPlugExecute call
#define IMOD_PLUG_MENU      1  /* Add to special plugin menu. */
#define IMOD_PLUG_TOOL      2  /* Add to toolbar (not implemented)     */
#define IMOD_PLUG_PROC      4  /* Add to image proc window. (not implemented) */
#define IMOD_PLUG_VIEW      8  /* Add to model view window. (not implemented) */
#define IMOD_PLUG_KEYS     16  /* Handle key events. */
#define IMOD_PLUG_FILE     32  /* Allow other image files to be loaded (?). */
#define IMOD_PLUG_MESSAGE  64  /* Execute messages */
#define IMOD_PLUG_MOUSE   128  /* Handle mouse events */
#define IMOD_PLUG_EVENT   256  /* Handle other events (wheel, enter, leave) */
#define IMOD_PLUG_CHOOSER 512  /* Handle file choosing operations */

#define IMOD_REASON_EXECUTE   1 /* Execute plugin after selection from menu  */
#define IMOD_REASON_STARTUP   3 /* 3dmod has started. Initialize plugin. */
#define IMOD_REASON_MODUPDATE 4 /* Update the plugin for model changes */
#define IMOD_REASON_NEWMODEL  5 /* Update the plugin for new model loaded */

Snapshot flags

Codes for snapshot formats.  TIF and RGB are used exclusively within 3dmod, with RGB used for either the user's selected non-TIFF format or the second non-TIFF format.
#define SnapShot_Default 0
#define SnapShot_RGB     1
#define SnapShot_TIF     2
#define SnapShot_PNG     3
#define SnapShot_JPG     4


/**************************** Application Data *******************************/

/* DOC_CODE Color defines */
/* color defines. */
#define COLOR_BACKGROUND 1  /* background color */
#define COLOR_FOREGROUND 2  /* foreground color */
#define COLOR_SELECT     3  /* selection color  */
#define COLOR_SHADOW     4  /* shadowed selection color */
#define COLOR_END        5  /* endpoint color   */
#define COLOR_BEGIN      6  /* begin point color */
#define COLOR_POINT      7  /* point color */
#define COLOR_GHOST      8  /* ghost color, darker version of object. */
#define COLOR_ARROW      9  /* first arrow color */
#define COLOR_ARROW2    10  /* second arrow color */
#define COLOR_ARROW3    11  /* third arrow color */
#define COLOR_ARROW4    12  /* fourth arrow color */
#define COLOR_MIN       13  /* The index of the minimum image value. */
#define COLOR_MAX       14  /* The index of the maximum image value. */

Application and Utility Functions

void DLL_EX_IM imodDrawModel(ImodView *inImodView, Imod *inModel, int drawCurrent, float zscale)

Draw model using a 2D line renderer implemented with OpenGL functions. This is the function used to draw the slicer window.  You will need to set up the view matrix yourself, including Z limits in the projection to avoid getting the whole model drawn on a slice.  Set drawCurrent nonzero to have current image or model point and current contour end symbols drawn too. Provide the z-scaling used to render the image in zscale.

int DLL_EX_IM imodDepth(void)

Gets the color depth; 24 on current systems with no color index mode *

int DLL_EX_IM imodColorValue(int inColor)

Returns the pixel value of the given COLOR_ value in inColor, used to call b3dColorIndex

void DLL_EX_IM wprint(const char *fmt, ...)

Print text to the 3dmod information window. The usage of this function is similar to the usage of the stdio function printf.

void DLL_EX_IM imodError(FILE *out, const char *format, ...)

Prints an error message with printf-type arguments This function will output a message box if out is NULL or under Windows; otherwise it will print to out, which should be stdout or stderr

void DLL_EX_IM imodPrintStderr(const char *format, ...)

Prints a message to standard error with printf-type arguments This function will flush stderr under Windows

void DLL_EX_IM imodTrace(char key, const char *format, ...)

Prints a message using imodPrintStderr if the letter key is entered as a debug key letter with -D

void DLL_EX_IM imodPuts(const char *message)

Puts message to standard error like puts, but flushes under Windows

void DLL_EX_IM imodPrintInfo(const char *message)

Prints message to standard out, or to a message box under Windows

void DLL_EX_IM imodDefaultKeys(QKeyEvent *event, ImodView *vw)

Passes even to the general key handler to execute 3dmod hot keys

int DLL_EX_IM imodShowHelpPage(const char *page)

Shows a help page with filename page in Qt Assistant; provide a full path if the path is not relative to IMOD_DIR/html/3dmodHelp. Returns 1 for error, 0 for success

Functions Operating on an ImodView

int DLL_EX_IM ivwDraw(ImodView *inImodView, int inFlags)

Sends a message to all 3dmod image windows that a redraw is needed. inFlags should contain an OR of the various IMOD_DRAW_ flags.

int DLL_EX_IM ivwRedraw(ImodView *vw)

The general draw update function.  If a current model point is defined, calls for a draw with IMOD_DRAW_ALL; otherwise calls with IMOD_DRAW_MOD.

void DLL_EX_IM ivwGetImageSize(ImodView *inImodView, int *outX, int *outY, int *outZ)

Gets the dimensions of the loaded image into outX, outY, outZ

void DLL_EX_IM ivwGetLocation(ImodView *inImodView, int *outX, int *outY, int *outZ)

Gets the current marker point location into outX, outY, outZ

void DLL_EX_IM ivwGetLocationPoint(ImodView *inImodView, Ipoint *outPoint)

Gets the current marker point location into outPoint

void DLL_EX_IM ivwSetLocation(ImodView *inImodView, int inX, int inY, int inZ)

Sets the current marker point location as inX, inY, inZ

void DLL_EX_IM ivwSetLocationPoint(ImodView *inImodView, Ipoint *inPoint)

Sets the current marker point location from inPoint.  Z and Y are truncated and Z is rounded to integers to be consistent with ivwSetLocation.

int DLL_EX_IM ivwGetTime(ImodView *inImodView, int *outTime)

Returns the maximum time index, the current time is returned in outTime. When there is only a single image file, the maximum index and time index are both 0; when there are multiple times the index is numbered from 1.

void DLL_EX_IM ivwSetTime(ImodView *inImodView, int inTime)

Sets the current time to inTime

const char DLL_EX_IM *ivwGetTimeLabel(ImodView *inImodView)

Gets the label for the current time.

const char DLL_EX_IM *ivwGetTimeIndexLabel(ImodView *inImodView, int inIndex)

Gets the label for time inIndex.

void DLL_EX_IM ivwSetNewContourTime(ImodView *vi, Iobj *obj, Icont *cont)

Sets the time for a new contour cont in object obj to match the current image time.

int DLL_EX_IM ivwGetImageStoreMode(ImodView *inImodView)

Gets the mode of the image data stored in the program.  It will be 0 for bytes, MRC_MODE_USHORT (6) for unsigned shorts, or MRC_MODE_RGB (16) for RGB triplets.

bool DLL_EX_IM ivwDataInTileOrStripCache(ImodView *inImodView)

Returns true if image data are loaded into a tile or strip cache.  If this is the case, then the regular image access functions ivwGetZSection and ivwGetZSectionTime will return NULL, and either ivwGetCurrentZSection or ivwGetTileCachedSection must be used instead.

unsigned char DLL_EX_IM **ivwGetZSection(ImodView *inImodView, int inSection)

Returns line pointers to loaded image data for the given Z section, inSection.  The line pointers are an array of pointers to the data on each line in Y.  The return value must be cast to (b3dUInt16 **) to use to access array values when unsigned shorts are loaded.  Returns NULL if data are loaded as strips or tiles.

unsigned char DLL_EX_IM **ivwGetCurrentZSection(ImodView *inImodView)

Returns line pointers to loaded image data for the current Z section.  If data are loaded as strips or tiles, this will load all tiles in the section if necessary/

unsigned char DLL_EX_IM **ivwGetZSectionTime(ImodView *vi, int section, int time)

Returns line pointers to loaded image data for the Z slice section and time index time.  Returns NULL if data are loaded as strips or tiles.

unsigned char DLL_EX_IM **ivwGetTileCachedSection(ImodView *inImodView, int section)

Returns line pointers to a buffer with the entire Z slice section loaded from the highest resolution image file, when data are cached as tiles or strips.  This call will force all of the data to be loaded synchronously, which can be time-consuming if images are large.  The call will allocate an array for the image which should be freed when operations are done (or when a window closes) by calling ivwFreeTileCachedSection.

void DLL_EX_IM ivwFreeTileCachedSection(ImodView *inImodView)

Frees the arrays allocated when ivwGetTileCachedSection is called, if they have been allocated; otherwise does nothing.

unsigned char DLL_EX_IM *ivwUShortInRangeToByteMap(ImodView *inImodView)

Returns a lookup table for mapping from unsigned short values to bytes based on the current setting of the Low and High range sliders.  It calls get_short_map, which returns an allocated map that must be freed.

int DLL_EX_IM ivwCopyImageToByteBuffer(ImodView *inImodView, unsigned char **image, unsigned char *buf)

Copies one Z plane of a loaded image with line pointers in image as bytes to the buffer buf.  If the loaded image is unsigned shorts, it is scaled based on the current settings of the Low and High range sliders.  Returns 1 for failure to get a lookup table.

int DLL_EX_IM ivwGetValue(ImodView *inImodView, int inX, int inY, int inZ)

Returns grey scale value in memory for given image coordinate inX, inY, inZ.  Works when loaded data are bytes or unsigned shorts, but not RGB.

float DLL_EX_IM ivwGetFileValue(ImodView *inImodView, int inX, int inY, int inZ)

Return value from image file.

int DLL_EX_IM ivwReadAngleFile(ImodView *vi, const char *fname)

Reads tilt angles, or any set of floating point values from the text file fname.  The file should have one value per line.  Returns 1 for error opening the file, or 2 for memory error.

float DLL_EX_IM *ivwGetTiltAngles(ImodView *vi, int &numAngles)

Returns a pointer to angles read from a file, or NULL if there are none, and returns the number of angles in numAngles.  If a subset in Z was read in, this function assumes the tilt angle list was for the complete stack and returns a pointer that starts at the starting Z.

Imod DLL_EX_IM *ivwGetModel(ImodView *inImodView)

Gets the model associated with the view.

int DLL_EX_IM ivwGetFreeExtraObjectNumber(ImodView *vi)

Gets the number of a free extra object; returns a number greater than 1 or -1 for an error.  A plugin could claim an object it opens and free it when it closes.

int DLL_EX_IM ivwFreeExtraObject(ImodView *vi, int objNum)

Clears out and releases the extra object specified by objNum.  Returns 1 for an object number out of bounds.

Iobj DLL_EX_IM *ivwGetAnExtraObject(ImodView *inImodView, int objNum)

Gets pointer to the extra object specified by objNum.  Do not save this in a static structure; always get a new pointer before working with it. Returns NULL for an object number out of bounds.

void DLL_EX_IM ivwClearAnExtraObject(ImodView *inImodView, int objNum)

Deletes all contours, meshes, and general storage data in the extra object specified by objNum.

Iobj DLL_EX_IM *ivwGetExtraObject(ImodView *inImodView)

Gets the original extra object. Do not use this.  Get a free object number and use that instead.

void DLL_EX_IM ivwClearExtraObject(ImodView *inImodView)

Delete all contours in the original extra object

void DLL_EX_IM ivwEnableStipple(ImodView *inImodView, int enable)

Enable or disable drawing of stippled contours

void DLL_EX_IM ivwTrackMouseForPlugs(ImodView *inImodView, int enable)

Enable or disable sending mouse moves with button up to plugins

Icont DLL_EX_IM *ivwGetOrMakeContour(ImodView *vw, Iobj *obj, int timeLock)

Gets the current contour or makes a new one if there is none in object obj, at the current time or the time indicated by timeLock.

int DLL_EX_IM ivwGetMovieModelMode(ImodView *vw)

Returns 1 if in model mode or 0 if in movie mode

void DLL_EX_IM ivwSetMovieModelMode(ImodView *inImodView, int mode)

Sets the program into movie or model mode if mode is IMOD_MMOVIE or IMOD_MMODEL, or toggles the mode if mode is IMOD_MM_TOGGLE.  This will cause a redraw.

int DLL_EX_IM ivwGetContrastReversed(ImodView *inImodView)

Returns non-zero if contrast is reversed, otherwise returns 0

int DLL_EX_IM ivwOverlayOK(ImodView *inImodView)

Return true if it is possible to display images in overlay mode in the Zap window.

void DLL_EX_IM ivwSetOverlayMode(ImodView *inImodView, int sec, int reverse, int whichGreen)

Sets the overlay mode section difference to sec, reverse contrast if reverse is nonzero, and displays current or other section in green if whichGreen is 0 or 1.

int DLL_EX_IM ivwGetTopZapZslice(ImodView *inImodView, int *outZ)

Returns the Z slice of the top Zap window in outZ.  The return value is 1 if there is no Zap window.

int DLL_EX_IM ivwSetTopZapZslice(ImodView *inImodView, int inZ)

Sets the Z slice of the top Zap window to inZ.  This will set the Zap window's section number if it is locked, or the current point location if not, but in either case it will not cause a redraw.  The return value is 1 if there is no Zap window or inZ is out of range.

int DLL_EX_IM ivwGetTopZapZoom(ImodView *inImodView, float *outZoom)

Returns the zoom of the top Zap window in outZoom.  The return value is 1 if there is no Zap window.

int DLL_EX_IM ivwSetTopZapZoom(ImodView *inImodView, float inZoom, bool draw)

Sets the zoom of the top Zap window to inZoom and redraws that Zap window if draw is true.  Returns 1 if there is no Zap window or the zoom value is out of the range 0.005 to 200.

int DLL_EX_IM ivwGetTopZapMouse(ImodView *inImodView, Ipoint *imagePt)

Returns the image coordinates of the mouse in the top Zap window in imagePt.  The X and Y coordinates may be out of range if the mouse is outside the graphics area.  The return value is 1 if there is no Zap window.

int DLL_EX_IM ivwGetTopZapCenter(ImodView *inImodView, float &imX, float &imY, int &imZ)

Returns the image coordinates at the center of the top Zap window in imX and imY, and its current Z coordinate in imZ.  The return value is 1 if there is no top Zap window.

int DLL_EX_IM ivwSetTopZapCenter(ImodView *inImodView, float imX, float imY, int imZ, bool draw)

Sets the image coordinates at the center of the top Zap window to imX and imY, and its current Z coordinate to imZ.  If draw is true, either draws the Zap window (if it is locked) or issues a general draw command; otherwise the caller is responsible for drawing.  The return value is 1 if there is no top Zap window or if coordinates are out of range.

QString DLL_EX_IM ivwCurrentImageFile(ImodView *inImodView, bool asEntered)

Returns the name of the current image file being displayed.  If multiple single-image files are loaded in Z, returns the name of the file at the current Z slice.  If asEntered is false, it returns a correct absolute path; otherwise, it returns the path as the user entered it, which may not be correct if the file is listed in an image descriptor file located in another directory.

void DLL_EX_IM b3dSetSnapshotCaption(QStringList &captionLines, bool wrapLastLine)

Set the captions for the next single-frame snapshot of an image or model view window. captionLines can contain a series of captions. All but the last will be drawn on a single line.  If wrapLastLine is true, the last string will be drawn on multiple lines with text wrapping at word boundaries.

int DLL_EX_IM ivwSnapshotTopZap(QString &name, int format, bool checkGrayConvert, bool fullArea)

Takes a single-frame snapshot of the top Zap window.  If name is not empty, the snapshot will be given that filename; otherwise, the name is automatically generated as usual and returned in name.  The snapshot format is specified by format, which should be SnapShot_TIF, SnapShot_PNG, or SnapShot_JPG, not the ambiguous SnapShot_RGB. For a TIFF snapshot, the user's choice of whether to convert to gray-scale is honored if checkGrayConvert is true and ignored otherwise.  If fullArea is true, the snapshot will be of the whole window even if there is a rubber band.  Returns -1 if there is no top zap window, -2 if the format is not one of the three listed, -3 if the format is not available as the first or second nonTiff format selected by the user, or 1 for any kind of error in the snapshotting process.

int DLL_EX_IM ivwSnapshotTopSlicer(QString &name, int format, bool checkGrayConvert, bool fullArea)

Takes a single-frame snapshot of the top Slicer window; arguments and return values are the same as in ivwSnapshotTopZap.

int DLL_EX_IM startAddedArrow(int windowType)

Starts a new arrow, retaining any existing arrows, in the top window of the type given by windowType, which can be either ZAP_WINDOW_TYPE or SLICER_WINDOW_TYPE.  Returns -4 for an invalid type and -1 if there is no top window.

int DLL_EX_IM clearAllArrows(int windowType, bool allWindows)

Clears all arrows in the top window of the type given by windowType if allWindows is false, or all windows of that type if allWindows is true.  windowType can be either ZAP_WINDOW_TYPE or SLICER_WINDOW_TYPE.  Returns -4 for an invalid type and -1 if there are now windows of the given type.

int DLL_EX_IM getTopSlicerAngles(float angles[3], Ipoint *center, int &time)

Returns the X, Y, and Z angles of the top slicer in angles, the center position in center, and the time of that slicer in time.  The return value is 1 if there is no slicer open.

int DLL_EX_IM ivwGetTopSlicerZoom(ImodView *inImodView, float *outZoom)

Returns the zoom of the top slicer window in outZoom.  The return value is 1 if there is no slicer open.

void DLL_EX_IM scaleBarAllLengths(float &zapLen, float &slicerLen, float &xyzLen, float &multiZlen, float &modvLen)

Returns the lengths of the scale bars in the top windows of each of the different types, Zap, Slicer, XYZ, multiZ, or model view.  A -1 is returned if there are no scale bars being displayed or if the particular window is not open. Call imodUnits with the current model to obtain a units string.

void DLL_EX_IM setScaleBarWithoutDialog(bool enable)

Enables or disables the drawing of scale bars without the Scale Bar dialog open.

void DLL_EX_IM ivwOpen3dmodDialogs(const char *keys)

Opens or raises the 3dmod dialog windows specified by the key letters provided in keys, where the letters are the same as can be given with the -E option.

QString DLL_EX_IM b3dGetSnapDirectory(void)

Returns the current snapshot directory or an empty string if one is not set, in which case snapshots will be to QDir::currentPath().

void DLL_EX_IM imodSelectionListAdd(ImodView *vi, Iindex newIndex)

Adds an item to the selection list defined by the object, contour, and point indices in newIndex.

int DLL_EX_IM imodSelectionListClear(ImodView *vi)

Clears the selection list and returns the number previously on the list.

int DLL_EX_IM imodSelectionListQuery(ImodView *vi, int ob, int co)

If contour co in object ob is on the selection list, returns the point number; otherwise returns -2.  If co < 0, it simply tests whether the object is on the selection list and returns nonzero if so.

void DLL_EX_IM imodSelectionListRemove(ImodView *vi, int ob, int co)

Removes contour co in object ob from the selection list if it is on it.

void DLL_EX_IM imodSelectionNewCurPoint(ImodView *vi, Imod *imod, Iindex indSave, int controlDown)

Manages the selection list when there is a new current point selected, for the model imod.  The current point index is defined in indSave, and controlDown should be nonzero if the control key is down.

int DLL_EX_IM imodNumSelectedObjects(ImodView *vi, int &minOb, int &maxOb)

Returns the number of selected objects, and returns the minimum and maximum selected object number in minOb and maxOb.

void DLL_EX_IM imodUpdateObjectDialogs()

Updates the Object Type dialog, the Model View Edit Object and Object List dialogs, and the color in the Info window.

int DLL_EX_IM prefSaveGenericSettings(char *key, int numVals, double *values)

Saves settings in the user preferences under a key given by key, which should be the name of a  module.  It saves numVals values from the array values.  Returns 1 for memory allocation errors.

int DLL_EX_IM prefGetGenericSettings(char *key, double *values, int maxVals)

Returns settings from the user preferences under the key given by key. Up to maxVals values are returned into the array values.  The return value is the number of values returned.

QString DLL_EX_IM utilOpenFileName(QWidget *parent, const char *caption, int numFilters, const char *filters[])

Gets the name of a single existing file with a file chooser that will show caption in its title bar.  A set of numFilters filters can be given in filters; the first will be the default filter.  Returns an empty string if the user cancels.  Uses the file chooser plugin if one is defined.

QString DLL_EX_IM imodPlugGetSaveName(QWidget *parent, const QString &caption)

Gets the name of a file in which to save with a file chooser that will show caption in its title bar.  Uses the file chooser plugin if one is defined.

Functions for Registering an Image Drawing Control

int DLL_EX_IM ivwNewControl(ImodView *inImodView, ImodControlProc inDrawFunction, ImodControlProc inQuitFunction, ImodControlKey inKeyFunction, void *data)

Creates a new image drawing control for a 3dmod view and returns a nonzero integer that is used as the inCtrlId when calling other control functions.  

  The inDrawFunction is called when the 3dmod draw function is called. The integer in the third argument contains the draw flags.
  The inQuitFunction is called when a user quits 3dmod.
  The inKeyFunction is optional and if it is not NULL it is called with key events that dialogs do not accept.
  data should be a pointer to the window's data structure so that multiple instances can be distinguished

int DLL_EX_IM ivwDeleteControl(ImodView *iv, int inCtrlId)

Deletes the control associated with the ID inCtrlId. This will also call the quit callback function of the control.

int DLL_EX_IM ivwRemoveControl(ImodView *iv, int inCtrlId)

Removes the control associated with the ID inCtrlId. This does not call the quit callback function of the control and is typically  called by the control itself when it is closing.

int DLL_EX_IM ivwControlPriority(ImodView *iv, int inCtrlId)

Moves the control with ID inCtrlId to the top of the control queue if it exists.  Also sets this one as the active control, which means that it alone is drawn with the IMOD_DRAW_ACTIVE flag.  If necessary, pending draws are stopped before the conrol queue is reordered. Returns the ID of the highest priority control.

void DLL_EX_IM ivwControlActive(ImodView *iv, int inCtrlId)

Makes the control with ID inCtrlId the active one, which means that if it is also the top priority control, it is drawn with the IMOD_DRAW_ACTIVE flag.  A zero value for inCtrlId make no control the active one.

void DLL_EX_IM ivwControlKey(int released, QKeyEvent *e)

Passes a key event e on to the first control on the list that has a key callback.

Definitions for controls.

Control callbacks

Function typedefs for the callback functions passed to ivwNewControl. The second argument will have the data value passed to ivwNewControl.
typedef void (*ImodControlProc)(struct ViewInfo *, void *, int);
typedef void (*ImodControlKey)(struct ViewInfo *, void *, int,  QKeyEvent *);

Registering with a Dialog Manager

Definitions and other aspects of a DialogManager

Dialog Manager

// A dialog manager class for hiding, showing, and closing windows in concert
class DialogManager;

/* Global instances */
extern DLL_EX_IM DialogManager imodvDialogManager;
extern DLL_EX_IM DialogManager imodDialogManager;

/* Classes of windows for the dialog manager */
#define IMODV_DIALOG 0
#define IMOD_DIALOG  1
#define IMOD_IMAGE   2

/* Types of windows for finding geometries and finding top windows */
enum {ZAP_WINDOW_TYPE, MULTIZ_WINDOW_TYPE, SLICER_WINDOW_TYPE, XYZ_WINDOW_TYPE,
      GRAPH_WINDOW_TYPE, TUMBLER_WINDOW_TYPE, UNKNOWN_TYPE};

Methods in the DialogManager class.

void DLL_EX_IM adjustGeometryAndShow(QWidget *widget, int dlgClass, bool doSize = true)

Processes events, adjusts size of widget if doSize is true, makes sure it is fully on the desktop, then shows the widget.  On Mac OSX, if dlgClass is non-negative, the widget is retored to the window manager's position then, if necessary, moved so as not to overlay the parent (Info window or model view).

void add(QWidget *widget, int dlgClass = IMODV_DIALOG, int dlgType = UNKNOWN_TYPE, int ctrlId = -1)

Adds widget to the list for this DialogManager.  The class of dialog or window is given in dlgClass and the specific type, if any, in dlgType (default UNKNOWN_TYPE), and a control ID can be supplied in ctrlId.

void remove(QWidget *widget)

Removes widget from the list for this DialogManager.

QWidget *parent(int dlgClass)

On Mac OSX, returns the parent window for the give type of dialog/window, dlgClass.  Elsewhere, returns NULL.

Functions for Undo/Redo

Essay on Undo/Redo

This module records various kinds of changes to the model so that changes can be undone and redone.  An individual change is specified by one call to one of the four change routines.  Changes are organized into groups called units, so each undo or redo operation does all of the changes in one unit.  The units are maintained in an ilist, mUnitList.  Each unit contains an ilist of the changes.  The unit also contains values for the current object/contour/point before and after the change, as well as state information that is required to match before a unit will be undone or redone: the # of objects, the # of contours in the current object, and the number of points in the current contour.
A unit is "opened" automatically when a change call comes in, i.e., it is created and added to the list and the starting state recorded.  Further changes are added to the same unit until an explicit call is made to finishUnit to close the unit.  If an error occurs while recording a change, the entire undo stack is flushed and further changes are ignore until the the next finishUnit call.
This protocol dictates that a change call be made before any actual changes to the model (except current contour and point changes).  Also, the finishUnit call must be made after all changes to the model, preferably after the current contour and point are set.  If an error occurs after starting a unit, flushUnit can be used to clear the changes within that unit but leave the previous undo stack intact.
Most changes involve recording some data such as a contour structure or complete contour including points.  These data are copied into backup pool items maintained on the list mItemPool.  Each pool item has a unique identifier that is also recorded in the change structure.  Data are freed from these items when no longer needed and the pool list is periodically repacked to remove empty items.  The number of backup units is limited by mMaxUnits and can be quite large; in practice it will be limited by the maximum number of bytes of data allowed in the pool, mMaxBytes.
The variety of changes allow for relatively efficient recording of most changes.  Points may be added or deleted singly or in groups, or the current point may be moved, without registering a contour change.  Contour changes may be of properties only, in which case points, labels, and general storage are not stored, or of data, in which case the whole contour is duplicated. Object changes will duplicate labels but not contours and meshes, unless an object is being deleted.  Model changes are excessive in copying all of the views every time.  Object rearrangements invoke a model change.  A change of model view invokes an object change for each view, since that is the only way to preserve the current state of the objects and of the object views separately.
The presence of data in a contour or object general storage structure will sometimes modify the behavior.  A call to register addition or removal of points will be converted to a contour data change call when the contour store has data.  A call to register a contour removal, addition, or move will cause an object property change to be registered first if the affected object store has data.

void DLL_EX_IM undoPointChange(ImodView *vi, int type, int object, int contour, int point, int point2)

Register change of given type for contour in object, between point and point2.  The default for object, contour and point are the current object, contour, or point if any is < -1; the default for point2 is point if point2 < 0.

void DLL_EX_IM undoContourChange(ImodView *vi, int type, int object, int contour, int object2, int contour2)

Register change of given type for contour in object, potentially involving contour2 in object2.  The default for object or contour are the current object or contour if one is < -1.

void DLL_EX_IM undoObjectChange(ImodView *vi, int type, int object, int object2)

Register change of given type for [object, potentially involving object2.  The default for object is the current object if it is < -1.

void DLL_EX_IM undoModelChange(ImodView *vi, int type, Ipoint *point)

Register change in the model of given type.  point specifies the shift for a PointShift

void DLL_EX_IM undoPointShiftCP(ImodView *vi)

Register shift of current point

void DLL_EX_IM undoPointShift(ImodView *vi, int point)

Register shift of point with index point in current contour

void DLL_EX_IM undoPointAdditionCC(ImodView *vi, int point)

Register addition of point with index point in current contour

void DLL_EX_IM undoPointAdditionCC2(ImodView *vi, int point, int point2)

Register addition of points from index point to index point2 in current contour

void DLL_EX_IM undoPointAddition(ImodView *vi, int object, int contour, int point)

Register addition of a point at index point in contour of object

void DLL_EX_IM undoPointRemovalCP(ImodView *vi)

Register deletion of the current point

void DLL_EX_IM undoPointRemoval(ImodView *vi, int point)

Register deletion of the point at index point in the current contour

void DLL_EX_IM undoPointRemoval2(ImodView *vi, int point, int point2)

Register deletion of points from index point to point2 in the current contour.

void DLL_EX_IM undoContourDataChgCC(ImodView *vi)

Register change in the data (points) of the current contour

void DLL_EX_IM undoContourDataChg(ImodView *vi, int object, int contour)

Register change in the data  of contour in object

void DLL_EX_IM undoContourPropChgCC(ImodView *vi)

Register change in properties only of the current contour

void DLL_EX_IM undoContourPropChg(ImodView *vi, int object, int contour)

Register change in properties only of contour in object

void DLL_EX_IM undoContourRemovalCC(ImodView *vi)

Register deletion of current contour

void DLL_EX_IM undoContourRemovalCO(ImodView *vi, int contour)

Register deletion of contour with index contour in current object

void DLL_EX_IM undoContourRemoval(ImodView *vi, int object, int contour)

Register deletion of contour in object

void DLL_EX_IM undoContourAdditionCO(ImodView *vi, int contour)

Register addition of contour at index contour in current object

void DLL_EX_IM undoContourAddition(ImodView *vi, int object, int contour)

Register addition of contour at index contour in object

void DLL_EX_IM undoContourMove(ImodView *vi, int object, int contour, int object2, int contour2)

Register move of a contour from object, contour to object2, contour2.

void DLL_EX_IM undoObjectPropChgCO(ImodView *vi)

Register a change in properties of the current object

void DLL_EX_IM undoObjectPropChg(ImodView *vi, int object)

Register a change in properties of object at index object

void DLL_EX_IM undoObjectRemovalCO(ImodView *vi)

Register deletion of the current object

void DLL_EX_IM undoObjectRemoval(ImodView *vi, int object)

Register deletion of an object at index object

void DLL_EX_IM undoObjectAddition(ImodView *vi, int object)

Register addition of an object at index object

void DLL_EX_IM undoObjectMove(ImodView *vi, int object, int object2)

Register moving an object from index object to object2

void DLL_EX_IM undoModelShift(ImodView *vi, Ipoint *point)

Register a shift of the model by amounts in point

void DLL_EX_IM undoFinishUnit(ImodView *vi)

Finish (close) a unit of changes to the model.  Either this function or the flush function must always be called eventually after registering changes.

void DLL_EX_IM undoFlushUnit(ImodView *vi)

Flush all the changes that were registered since this unit of changes was started.  Call this function if an operation is aborted due to an error after changes were registered.