#include <mil.h>
#include <math.h>
#define GRID_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("CalGrid.mim")
#define DISTORTED_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("CalibratedRuler/Distorted.mim")
#define GRID_OFFSET_X 0
#define GRID_OFFSET_Y 0
#define GRID_OFFSET_Z 0
#define GRID_ROW_SPACING 1
#define GRID_COLUMN_SPACING 1
#define GRID_ROW_NUMBER 18
#define GRID_COLUMN_NUMBER 25
#define RULER_COLOR M_COLOR_RED
#define MEAS_BOX_WIDTH 15
#define MEAS_BOX_HEIGHT 15
#define MEAS_COLOR M_COLOR_GREEN
#define STRING_SIZE 128
#define M_Round(x) ((MIL_INT)((x) + ((x) >= 0 ? 0.5 : -0.5)))
typedef struct
{
MIL_ID MilDisplay;
MIL_ID MilImage;
MIL_ID MilCalibration;
MIL_ID MilGraphics;
MIL_ID MilRulerGraphicList;
MIL_ID MilMeasGraphicList;
MIL_ID MilMeasBoxGraphicList;
MIL_ID MilDisplayGraphicList;
MIL_INT ImageSizeX;
MIL_INT ImageSizeY;
MIL_DOUBLE PrevDispZoomX;
MIL_DOUBLE PrevDispZoomY;
MIL_DOUBLE PrevDispPanOffsetX;
MIL_DOUBLE PrevDispPanOffsetY;
MIL_INT NumCalibrationPoints;
MIL_INT RowNumber;
MIL_INT ColumnNumber;
MIL_DOUBLE ColumnWorldSpacing;
MIL_DOUBLE RowWorldSpacing;
MIL_DOUBLE* WorldCalibrationPointsX;
MIL_DOUBLE* WorldCalibrationPointsY;
MIL_DOUBLE* PixelCalibrationPointsX;
MIL_DOUBLE* PixelCalibrationPointsY;
} DispHookRulerDataStruct;
typedef struct
{
MIL_DOUBLE Measure;
bool DrawMajorMeasure;
bool DrawMediumMeasure;
bool DrawMinorMeasure;
} RulerDataStruct;
enum RulerType
{
eXAxis,
eYAxis
};
typedef struct
{
MIL_ID MilDisplay;
MIL_ID MilImage;
MIL_ID MilCalibration;
MIL_ID MilGraphics;
MIL_ID MilRulerGraphicList;
MIL_ID MilMeasGraphicList;
MIL_ID MilMeasBoxGraphicList;
MIL_ID MilDisplayGraphicList;
MIL_ID MilMeasMarker1;
MIL_ID MilMeasMarker2;
MIL_ID MilMeasCalculateRes;
MIL_INT NumDefinedMarkers;
} DispHookMeasureDataStruct;
MIL_INT MFTYPE DrawRuler(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr);
void FillRulerMeasures(const DispHookRulerDataStruct& HookData, MIL_INT RulerArraySize,
RulerType Type, RulerDataStruct* RulerArray);
void FillSubRulerMeasures(MIL_ID MilCalibratedImage, MIL_DOUBLE WorldStartCoord,
MIL_DOUBLE WorldEndCoord, MIL_DOUBLE ZoomX, MIL_DOUBLE ZoomY,
MIL_DOUBLE OffsetX, MIL_DOUBLE OffsetY, RulerType Type,
MIL_INT RulerArraySize, RulerDataStruct* RulerArray,
MIL_INT SubRulerSize);
void DisplayToPixel(MIL_DOUBLE* DisplayX, MIL_DOUBLE* DisplayY, MIL_DOUBLE* PixelX,
MIL_DOUBLE* PixelY, MIL_INT NumCoordinates, MIL_DOUBLE ZoomX,
MIL_DOUBLE ZoomY, MIL_DOUBLE OffsetX, MIL_DOUBLE OffsetY);
void PixelToDisplay(MIL_DOUBLE* PixelX, MIL_DOUBLE* PixelY, MIL_DOUBLE* DisplayX,
MIL_DOUBLE* DisplayY, MIL_INT NumCoordinates, MIL_DOUBLE ZoomX,
MIL_DOUBLE ZoomY, MIL_DOUBLE OffsetX, MIL_DOUBLE OffsetY);
MIL_INT MFTYPE MeasMouseRightClick(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr);
MIL_INT MFTYPE MeasMouseMove(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr);
MIL_INT MFTYPE MeasureDistance(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr,
bool RightClick);
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n"));
MosPrintf(MIL_TEXT("CalibratedRuler\n\n"));
MosPrintf(MIL_TEXT("[SYNOPSIS]\n"));
MosPrintf(MIL_TEXT("This example allows to interactively measure the distance, in\n")
MIL_TEXT("world units, between two points in a corrected image. It also\n")
MIL_TEXT("displays rulers with world unit measures.\n\n"));
MosPrintf(MIL_TEXT("[MODULES USED]\n"));
MosPrintf(MIL_TEXT("Modules used: application, system, display, buffer, graphic,\n")
MIL_TEXT("calibration, measurement.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
}
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem;
DispHookRulerDataStruct DisplayHookRulerData;
DispHookMeasureDataStruct DisplayHookMeasureData;
MIL_INT CalibrationStatus;
DisplayHookRulerData.WorldCalibrationPointsX = M_NULL;
DisplayHookRulerData.WorldCalibrationPointsY = M_NULL;
DisplayHookRulerData.PixelCalibrationPointsX = M_NULL;
DisplayHookRulerData.PixelCalibrationPointsY = M_NULL;
MappAlloc(M_NULL, M_DEFAULT, &MilApplication);
MsysAlloc(M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED,
&DisplayHookRulerData.MilDisplay);
MdispControl(DisplayHookRulerData.MilDisplay, M_CENTER_DISPLAY, M_DISABLE);
PrintHeader();
MbufRestore(GRID_IMAGE_FILE, MilSystem, &DisplayHookRulerData.MilImage);
MdispSelect(DisplayHookRulerData.MilDisplay, DisplayHookRulerData.MilImage);
MgraAlloc(MilSystem, &DisplayHookRulerData.MilGraphics);
MgraAllocList(MilSystem, M_DEFAULT, &DisplayHookRulerData.MilDisplayGraphicList);
MgraAllocList(MilSystem, M_DEFAULT, &DisplayHookRulerData.MilRulerGraphicList);
MgraAllocList(MilSystem, M_DEFAULT, &DisplayHookMeasureData.MilMeasGraphicList);
MgraAllocList(MilSystem, M_DEFAULT, &DisplayHookMeasureData.MilMeasBoxGraphicList);
MgraControl(DisplayHookRulerData.MilGraphics, M_BACKGROUND_MODE, M_TRANSPARENT);
MdispControl(DisplayHookRulerData.MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID,
DisplayHookRulerData.MilDisplayGraphicList);
MosPrintf(MIL_TEXT("The displayed grid has been grabbed with high lens distortion\n"));
MosPrintf(MIL_TEXT("and will be used to calibrate the camera.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
McalAlloc(MilSystem, M_DEFAULT, M_DEFAULT, &DisplayHookRulerData.MilCalibration);
McalGrid(DisplayHookRulerData.MilCalibration, DisplayHookRulerData.MilImage,
GRID_OFFSET_X, GRID_OFFSET_Y, GRID_OFFSET_Z,
GRID_ROW_NUMBER, GRID_COLUMN_NUMBER,
GRID_ROW_SPACING, GRID_COLUMN_SPACING,
M_DEFAULT, M_DEFAULT);
MmeasAllocMarker(MilSystem, M_EDGE, M_DEFAULT, &DisplayHookMeasureData.MilMeasMarker1);
MmeasAllocMarker(MilSystem, M_EDGE, M_DEFAULT, &DisplayHookMeasureData.MilMeasMarker2);
MmeasAllocResult(MilSystem, M_DEFAULT, &DisplayHookMeasureData.MilMeasCalculateRes);
MmeasSetMarker(DisplayHookMeasureData.MilMeasMarker1, M_BOX_ANGLE_MODE, M_ENABLE,
M_NULL);
MmeasSetMarker(DisplayHookMeasureData.MilMeasMarker1, M_BOX_ANGLE, M_ANY, M_NULL);
MmeasSetMarker(DisplayHookMeasureData.MilMeasMarker2, M_BOX_ANGLE_MODE, M_ENABLE,
M_NULL);
MmeasSetMarker(DisplayHookMeasureData.MilMeasMarker2, M_BOX_ANGLE, M_ANY, M_NULL);
DisplayHookMeasureData.MilDisplay =
DisplayHookRulerData.MilDisplay;
DisplayHookMeasureData.MilImage =
DisplayHookRulerData.MilImage;
DisplayHookMeasureData.MilCalibration =
DisplayHookRulerData.MilCalibration;
DisplayHookMeasureData.MilDisplayGraphicList =
DisplayHookRulerData.MilDisplayGraphicList;
DisplayHookMeasureData.MilRulerGraphicList =
DisplayHookRulerData.MilRulerGraphicList;
DisplayHookMeasureData.MilGraphics =
DisplayHookRulerData.MilGraphics;
DisplayHookRulerData.MilMeasGraphicList =
DisplayHookMeasureData.MilMeasGraphicList;
DisplayHookRulerData.MilMeasBoxGraphicList =
DisplayHookMeasureData.MilMeasBoxGraphicList;
McalInquire(DisplayHookRulerData.MilCalibration, M_CALIBRATION_STATUS + M_TYPE_MIL_INT,
&CalibrationStatus);
if( CalibrationStatus == M_CALIBRATED )
{
MbufLoad(DISTORTED_IMAGE_FILE, DisplayHookRulerData.MilImage);
McalAssociate(DisplayHookRulerData.MilCalibration, DisplayHookRulerData.MilImage,
M_DEFAULT);
DisplayHookRulerData.ImageSizeX = MbufInquire(DisplayHookRulerData.MilImage,
M_SIZE_X, M_NULL);
DisplayHookRulerData.ImageSizeY = MbufInquire(DisplayHookRulerData.MilImage,
M_SIZE_Y, M_NULL);
MosPrintf(MIL_TEXT("A distorted image grabbed with the same camera was loaded.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
McalTransformImage(DisplayHookRulerData.MilImage, DisplayHookRulerData.MilImage,
DisplayHookRulerData.MilCalibration, M_BILINEAR+M_OVERSCAN_CLEAR,
M_DEFAULT, M_DEFAULT);
DisplayHookRulerData.PrevDispPanOffsetX = -1;
DisplayHookRulerData.PrevDispPanOffsetY = -1;
DisplayHookRulerData.PrevDispZoomX = -1;
DisplayHookRulerData.PrevDispZoomY = -1;
McalInquire(DisplayHookRulerData.MilCalibration,
M_NUMBER_OF_CALIBRATION_POINTS+M_TYPE_MIL_INT,
&DisplayHookRulerData.NumCalibrationPoints);
DisplayHookRulerData.WorldCalibrationPointsX =
new MIL_DOUBLE [DisplayHookRulerData.NumCalibrationPoints];
DisplayHookRulerData.WorldCalibrationPointsY =
new MIL_DOUBLE [DisplayHookRulerData.NumCalibrationPoints];
DisplayHookRulerData.PixelCalibrationPointsX =
new MIL_DOUBLE [DisplayHookRulerData.NumCalibrationPoints];
DisplayHookRulerData.PixelCalibrationPointsY =
new MIL_DOUBLE [DisplayHookRulerData.NumCalibrationPoints];
McalInquire(DisplayHookRulerData.MilCalibration, M_CALIBRATION_WORLD_POINTS_X,
DisplayHookRulerData.WorldCalibrationPointsX);
McalInquire(DisplayHookRulerData.MilCalibration, M_CALIBRATION_WORLD_POINTS_Y,
DisplayHookRulerData.WorldCalibrationPointsY);
McalTransformCoordinateList(DisplayHookRulerData.MilImage, M_WORLD_TO_PIXEL,
DisplayHookRulerData.NumCalibrationPoints,
DisplayHookRulerData.WorldCalibrationPointsX,
DisplayHookRulerData.WorldCalibrationPointsY,
DisplayHookRulerData.PixelCalibrationPointsX,
DisplayHookRulerData.PixelCalibrationPointsY);
McalInquire(DisplayHookRulerData.MilCalibration, M_ROW_NUMBER+M_TYPE_MIL_INT,
&DisplayHookRulerData.RowNumber);
McalInquire(DisplayHookRulerData.MilCalibration, M_COLUMN_NUMBER+M_TYPE_MIL_INT,
&DisplayHookRulerData.ColumnNumber);
McalInquire(DisplayHookRulerData.MilCalibration, M_ROW_SPACING,
&DisplayHookRulerData.RowWorldSpacing);
McalInquire(DisplayHookRulerData.MilCalibration, M_COLUMN_SPACING,
&DisplayHookRulerData.ColumnWorldSpacing);
DrawRuler(0, 0, (void*)&DisplayHookRulerData);
DisplayHookMeasureData.NumDefinedMarkers = 0;
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_KEY_CHAR, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_KEY_UP, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_LEFT_BUTTON_UP, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_MIDDLE_BUTTON_UP,
DrawRuler, (void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_LEFT_DOUBLE_CLICK,
DrawRuler, (void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_MOVE, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_WHEEL, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookMeasureData.MilDisplay, M_MOUSE_MOVE, MeasMouseMove,
(void*)&DisplayHookMeasureData);
MdispHookFunction(DisplayHookMeasureData.MilDisplay, M_MOUSE_RIGHT_BUTTON_UP,
MeasMouseRightClick, (void*)&DisplayHookMeasureData);
MosPrintf(MIL_TEXT("The image was corrected to remove its distortions and a "));
MosPrintf(MIL_TEXT("ruler was added.\nThe ruler is marked with measurements in "));
MosPrintf(MIL_TEXT("world coordinates.\nYou can:\n"));
MosPrintf(MIL_TEXT("- Zoom and pan the image to view measurements at various "));
MosPrintf(MIL_TEXT("locations.\n- Right-click on areas with edges to add ")
MIL_TEXT("two points, measure and view\n the distance between them.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_KEY_CHAR+M_UNHOOK, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_KEY_UP+M_UNHOOK, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay,
M_MOUSE_LEFT_BUTTON_UP+M_UNHOOK, DrawRuler, (void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay,
M_MOUSE_MIDDLE_BUTTON_UP+M_UNHOOK, DrawRuler, (void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay,
M_MOUSE_LEFT_DOUBLE_CLICK+M_UNHOOK, DrawRuler, (void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_MOVE+M_UNHOOK, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookRulerData.MilDisplay, M_MOUSE_WHEEL+M_UNHOOK, DrawRuler,
(void*)&DisplayHookRulerData);
MdispHookFunction(DisplayHookMeasureData.MilDisplay, M_MOUSE_MOVE +M_UNHOOK,
MeasMouseMove, (void*)&DisplayHookMeasureData);
MdispHookFunction(DisplayHookMeasureData.MilDisplay,
M_MOUSE_RIGHT_BUTTON_UP +M_UNHOOK, MeasMouseRightClick,
(void*)&DisplayHookMeasureData);
delete [] DisplayHookRulerData.WorldCalibrationPointsX;
delete [] DisplayHookRulerData.WorldCalibrationPointsY;
delete [] DisplayHookRulerData.PixelCalibrationPointsX;
delete [] DisplayHookRulerData.PixelCalibrationPointsY;
}
else
{
MosPrintf(MIL_TEXT("Calibration did not succeed with this grid image.\n"));
MosPrintf(MIL_TEXT("See User Guide to resolve the situation.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
}
MgraFree(DisplayHookRulerData.MilGraphics);
MgraFree(DisplayHookRulerData.MilDisplayGraphicList);
MgraFree(DisplayHookRulerData.MilRulerGraphicList);
MgraFree(DisplayHookMeasureData.MilMeasGraphicList);
MgraFree(DisplayHookMeasureData.MilMeasBoxGraphicList);
McalFree(DisplayHookRulerData.MilCalibration);
MmeasFree(DisplayHookMeasureData.MilMeasMarker1);
MmeasFree(DisplayHookMeasureData.MilMeasMarker2);
MmeasFree(DisplayHookMeasureData.MilMeasCalculateRes);
MbufFree(DisplayHookRulerData.MilImage);
MdispFree(DisplayHookRulerData.MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
#define MAJOR_MEASURE_DISTANCE 40
#define MEDIUM_MEASURE_DISTANCE 20
#define MINOR_MEASURE_DISTANCE 10
MIL_INT MFTYPE DrawRuler(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr)
{
const MIL_INT RulerWidth = 1;
const MIL_INT MeasureLineLength = 2;
const MIL_INT MajorMeasureLineHeight = 8;
const MIL_INT MediumMeasureLineHeight = 4;
const MIL_INT MinorMeasureLineHeight = 2;
DispHookRulerDataStruct* pRulerData = (DispHookRulerDataStruct*)UserDataPtr;
MIL_ID MilDisplay = pRulerData->MilDisplay;
MIL_ID MilCalibration = pRulerData->MilCalibration;
MIL_ID MilCalibratedImage = pRulerData->MilImage;
MIL_ID MilDisplayGraphicList = pRulerData->MilDisplayGraphicList;
MIL_ID MilRulerGraphicList = pRulerData->MilRulerGraphicList;
MIL_ID MilMeasGraphicList = pRulerData->MilMeasGraphicList;
MIL_ID MilMeasBoxGraphicList = pRulerData->MilMeasBoxGraphicList;
MIL_ID MilGraphics = pRulerData->MilGraphics;
MIL_INT SizeX = pRulerData->ImageSizeX;
MIL_INT SizeY = pRulerData->ImageSizeY;
MIL_DOUBLE PanOffsetX, ZoomFactorX;
MIL_DOUBLE PanOffsetY, ZoomFactorY;
MgraColor(MilGraphics, RULER_COLOR);
MgraControl(MilGraphics, M_INPUT_UNITS, M_DISPLAY);
MdispInquire(MilDisplay, M_PAN_OFFSET_X, &PanOffsetX);
MdispInquire(MilDisplay, M_PAN_OFFSET_Y, &PanOffsetY);
MdispInquire(MilDisplay, M_ZOOM_FACTOR_X, &ZoomFactorX);
MdispInquire(MilDisplay, M_ZOOM_FACTOR_Y, &ZoomFactorY);
if ( PanOffsetX == pRulerData->PrevDispPanOffsetX &&
PanOffsetY == pRulerData->PrevDispPanOffsetY &&
ZoomFactorX == pRulerData->PrevDispZoomX &&
ZoomFactorY == pRulerData->PrevDispZoomY )
{ return 0; }
pRulerData->PrevDispPanOffsetX = PanOffsetX;
pRulerData->PrevDispPanOffsetY = PanOffsetY;
pRulerData->PrevDispZoomX = ZoomFactorX;
pRulerData->PrevDispZoomY = ZoomFactorY;
MdispControl(MilDisplay, M_UPDATE_GRAPHIC_LIST, M_DISABLE);
MgraClear(M_DEFAULT, MilDisplayGraphicList);
MgraClear(M_DEFAULT, MilRulerGraphicList);
MIL_INT RulerSize =
(MIL_INT)(ceil( (SizeX*ZoomFactorX-1) - PanOffsetX*ZoomFactorX) + 1);
MgraRectFill(MilGraphics, MilRulerGraphicList, 0, 0, RulerSize-1, RulerWidth);
RulerDataStruct* RulerArray = new RulerDataStruct[RulerSize];
FillRulerMeasures(*pRulerData, RulerSize, eXAxis, RulerArray);
MIL_TEXT_CHAR MeasureString[STRING_SIZE];
for (MIL_INT i=0; i < RulerSize; i++)
{
if (i > MINOR_MEASURE_DISTANCE)
{
if (RulerArray[i].DrawMajorMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, i, 0, i+MeasureLineLength,
MajorMeasureLineHeight);
if (i > MEDIUM_MEASURE_DISTANCE)
{
MosSprintf(MeasureString, STRING_SIZE, MIL_TEXT("%.2f"),
RulerArray[i].Measure);
MgraText(MilGraphics, MilRulerGraphicList, i-6, MajorMeasureLineHeight+1,
MeasureString);
}
}
else if (RulerArray[i].DrawMediumMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, i, 0, i+MeasureLineLength,
MediumMeasureLineHeight);
}
else if (RulerArray[i].DrawMinorMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, i, 0, i+MeasureLineLength,
MinorMeasureLineHeight);
}
}
}
delete [] RulerArray;
RulerSize = (MIL_INT)(ceil((SizeY*ZoomFactorY-1)-PanOffsetY*ZoomFactorY) + 1);
MgraRectFill(MilGraphics, MilRulerGraphicList, 0, 0, RulerWidth, RulerSize-1);
RulerArray = new RulerDataStruct[RulerSize];
FillRulerMeasures(*pRulerData, RulerSize, eYAxis, RulerArray);
for (MIL_INT i=0; i < RulerSize; i++)
{
if (i > MINOR_MEASURE_DISTANCE)
{
if (RulerArray[i].DrawMajorMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, 0, i, MajorMeasureLineHeight,
i+MeasureLineLength);
if (i > MEDIUM_MEASURE_DISTANCE)
{
MosSprintf(MeasureString, STRING_SIZE, MIL_TEXT("%.2f"),
RulerArray[i].Measure);
MgraText(MilGraphics, MilRulerGraphicList, MajorMeasureLineHeight+3, i-4,
MeasureString);
}
}
else if (RulerArray[i].DrawMediumMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, 0, i, MediumMeasureLineHeight,
i+MeasureLineLength);
}
else if (RulerArray[i].DrawMinorMeasure)
{
MgraRectFill(MilGraphics, MilRulerGraphicList, 0, i, MinorMeasureLineHeight,
i+MeasureLineLength);
}
}
}
delete [] RulerArray;
MgraCopy(MilRulerGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MgraCopy(MilMeasGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MgraCopy(MilMeasBoxGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MdispControl(MilDisplay, M_UPDATE_GRAPHIC_LIST, M_ENABLE);
return 0;
}
void FillRulerMeasures(const DispHookRulerDataStruct& HookData, MIL_INT RulerArraySize,
RulerType Type, RulerDataStruct* RulerArray)
{
MIL_INT NumCalibrationPoints = HookData.NumCalibrationPoints;
MIL_INT RowNumber = HookData.RowNumber;
MIL_INT ColumnNumber = HookData.ColumnNumber;
MIL_DOUBLE ColumnWorldSpacing = HookData.ColumnWorldSpacing;
MIL_DOUBLE RowWorldSpacing = HookData.RowWorldSpacing;
MIL_DOUBLE* WorldCalibrationPointsX = HookData.WorldCalibrationPointsX;
MIL_DOUBLE* WorldCalibrationPointsY = HookData.WorldCalibrationPointsY;
MIL_DOUBLE* PixelCalibrationPointsX = HookData.PixelCalibrationPointsX;
MIL_DOUBLE* PixelCalibrationPointsY = HookData.PixelCalibrationPointsY;
MIL_DOUBLE* DisplayCalibrationPointsX = M_NULL;
MIL_DOUBLE* DisplayCalibrationPointsY = M_NULL;
MIL_ID MilCalibration = HookData.MilCalibration;
MIL_ID MilCalibratedImage = HookData.MilImage;
MIL_DOUBLE ZoomFactorX = HookData.PrevDispZoomX;
MIL_DOUBLE ZoomFactorY = HookData.PrevDispZoomY;
MIL_DOUBLE PanOffsetX = HookData.PrevDispPanOffsetX;
MIL_DOUBLE PanOffsetY = HookData.PrevDispPanOffsetY;
MIL_INT ImageSizeX = HookData.ImageSizeX;
MIL_INT ImageSizeY = HookData.ImageSizeY;
for (MIL_INT i=0; i < RulerArraySize; i++)
{
RulerArray[i].DrawMajorMeasure = false;
RulerArray[i].DrawMediumMeasure = false;
RulerArray[i].DrawMinorMeasure = false;
}
DisplayCalibrationPointsX = new MIL_DOUBLE [NumCalibrationPoints];
DisplayCalibrationPointsY = new MIL_DOUBLE [NumCalibrationPoints];
PixelToDisplay(PixelCalibrationPointsX, PixelCalibrationPointsY,
DisplayCalibrationPointsX, DisplayCalibrationPointsY,
NumCalibrationPoints, ZoomFactorX, ZoomFactorY, PanOffsetX,
PanOffsetY);
MIL_INT PreviousRulerCoord = 0;
MIL_INT CurrentRulerCoord = 0;
MIL_DOUBLE PreviousPixelCoordX = (MIL_DOUBLE)PreviousRulerCoord;
MIL_DOUBLE PreviousPixelCoordY = (MIL_DOUBLE)PreviousRulerCoord;
MIL_DOUBLE PreviousWorldCoordX = 0;
MIL_DOUBLE PreviousWorldCoordY = 0;
MIL_DOUBLE CurrentWorldCoord = 0;
DisplayToPixel(&PreviousPixelCoordX, &PreviousPixelCoordY, &PreviousPixelCoordX,
&PreviousPixelCoordY, 1, ZoomFactorX, ZoomFactorY, PanOffsetX, PanOffsetY);
McalTransformCoordinate(MilCalibratedImage, M_PIXEL_TO_WORLD, PreviousPixelCoordX,
PreviousPixelCoordY, &PreviousWorldCoordX, &PreviousWorldCoordY);
if (Type == eXAxis)
{
MIL_INT SpacingFactor = (MIL_INT)
ceil(MAJOR_MEASURE_DISTANCE/(DisplayCalibrationPointsX[1]-
DisplayCalibrationPointsX[0]));
for (MIL_INT i=0; i < ColumnNumber; i++)
{
if ( DisplayCalibrationPointsX[i] > MAJOR_MEASURE_DISTANCE)
{
CurrentWorldCoord = WorldCalibrationPointsX[i];
while (CurrentWorldCoord - PreviousWorldCoordX > 0)
{
CurrentWorldCoord = CurrentWorldCoord - SpacingFactor*ColumnWorldSpacing;
}
PreviousWorldCoordX = CurrentWorldCoord;
break;
}
}
for (MIL_INT i=0; i < ColumnNumber; i++)
{
CurrentRulerCoord = M_Round(DisplayCalibrationPointsX[i]);
CurrentWorldCoord = WorldCalibrationPointsX[i];
if ( (CurrentRulerCoord - PreviousRulerCoord) > MAJOR_MEASURE_DISTANCE)
{
RulerArray[CurrentRulerCoord].DrawMajorMeasure = true;
RulerArray[CurrentRulerCoord].Measure = WorldCalibrationPointsX[i];
FillSubRulerMeasures(MilCalibratedImage, PreviousWorldCoordX,
CurrentWorldCoord, ZoomFactorX, ZoomFactorY, PanOffsetX, PanOffsetY, Type,
RulerArraySize, RulerArray, (CurrentRulerCoord - PreviousRulerCoord)-1);
PreviousRulerCoord = CurrentRulerCoord;
PreviousWorldCoordX = CurrentWorldCoord;
}
}
MIL_DOUBLE EndWorldCoordX = 0;
MIL_DOUBLE EndWorldCoordY = 0;
McalTransformCoordinate(MilCalibratedImage, M_PIXEL_TO_WORLD,
(MIL_DOUBLE)ImageSizeX-1, 0, &EndWorldCoordX, &EndWorldCoordY);
MIL_DOUBLE PreviousWorldCoordX2 = PreviousWorldCoordX;
while (EndWorldCoordX - PreviousWorldCoordX2 > 0)
{
PreviousWorldCoordX2 = PreviousWorldCoordX2 + SpacingFactor*ColumnWorldSpacing;
}
EndWorldCoordX = PreviousWorldCoordX2;
FillSubRulerMeasures(MilCalibratedImage, PreviousWorldCoordX, EndWorldCoordX,
ZoomFactorX, ZoomFactorY, PanOffsetX, PanOffsetY, Type, RulerArraySize,
RulerArray, (RulerArraySize-PreviousRulerCoord)-1);
}
else if (Type == eYAxis)
{
MIL_INT SpacingFactor = (MIL_INT)
ceil(MAJOR_MEASURE_DISTANCE/
(DisplayCalibrationPointsY[ColumnNumber]-DisplayCalibrationPointsY[0]));
for (MIL_INT i=0; i < NumCalibrationPoints; i+=ColumnNumber)
{
if ( DisplayCalibrationPointsY[i] > MAJOR_MEASURE_DISTANCE)
{
CurrentWorldCoord = WorldCalibrationPointsY[i];
while (CurrentWorldCoord - PreviousWorldCoordY > 0)
{
CurrentWorldCoord = CurrentWorldCoord - SpacingFactor*RowWorldSpacing;
}
PreviousWorldCoordY = CurrentWorldCoord;
break;
}
}
for (MIL_INT i=0; i < NumCalibrationPoints; i+=ColumnNumber)
{
CurrentRulerCoord = M_Round(DisplayCalibrationPointsY[i]);
CurrentWorldCoord = WorldCalibrationPointsY[i];
if ( (CurrentRulerCoord - PreviousRulerCoord) > MAJOR_MEASURE_DISTANCE)
{
RulerArray[CurrentRulerCoord].DrawMajorMeasure = true;
RulerArray[CurrentRulerCoord].Measure = WorldCalibrationPointsY[i];
FillSubRulerMeasures(MilCalibratedImage, PreviousWorldCoordY,
CurrentWorldCoord, ZoomFactorX, ZoomFactorY, PanOffsetX, PanOffsetY,
Type, RulerArraySize, RulerArray,
(CurrentRulerCoord - PreviousRulerCoord)-1);
PreviousRulerCoord = CurrentRulerCoord;
PreviousWorldCoordY = CurrentWorldCoord;
}
}
MIL_DOUBLE EndWorldCoordX = 0;
MIL_DOUBLE EndWorldCoordY = 0;
McalTransformCoordinate(MilCalibratedImage, M_PIXEL_TO_WORLD, 0,
(MIL_DOUBLE)ImageSizeY-1, &EndWorldCoordX, &EndWorldCoordY);
MIL_DOUBLE PreviousWorldCoordY2 = PreviousWorldCoordY;
while (EndWorldCoordY - PreviousWorldCoordY2 > 0)
{
PreviousWorldCoordY2 = PreviousWorldCoordY2 + SpacingFactor*RowWorldSpacing;
}
EndWorldCoordY = PreviousWorldCoordY2;
FillSubRulerMeasures(MilCalibratedImage, PreviousWorldCoordY, EndWorldCoordY,
ZoomFactorX, ZoomFactorY, PanOffsetX, PanOffsetY, Type, RulerArraySize,
RulerArray, (RulerArraySize-PreviousRulerCoord)-1);
}
delete[] DisplayCalibrationPointsX;
delete[] DisplayCalibrationPointsY;
}
void FillSubRulerMeasures(MIL_ID MilCalibratedImage, MIL_DOUBLE WorldStartCoord,
MIL_DOUBLE WorldEndCoord, MIL_DOUBLE ZoomX, MIL_DOUBLE ZoomY, MIL_DOUBLE OffsetX,
MIL_DOUBLE OffsetY, RulerType Type, MIL_INT RulerArraySize, RulerDataStruct* RulerArray,
MIL_INT SubRulerSize)
{
typedef struct
{
MIL_DOUBLE StartCoord;
MIL_DOUBLE EndCoord;
} CoordStruct;
enum CoordType
{
eStart,
eEnd
};
const MIL_INT NumCoordType = 2;
if (SubRulerSize < 1)
return;
MIL_INT NumStackElements = 0;
CoordStruct* MidPointStack = new CoordStruct[SubRulerSize];
MidPointStack[0].StartCoord = WorldStartCoord;
MidPointStack[0].EndCoord = WorldEndCoord;
NumStackElements = 1;
MIL_DOUBLE WorldCoordX [NumCoordType];
MIL_DOUBLE WorldCoordY [NumCoordType];
MIL_DOUBLE PixelCoordX [NumCoordType];
MIL_DOUBLE PixelCoordY [NumCoordType];
MIL_DOUBLE DisplayCoordX[NumCoordType];
MIL_DOUBLE DisplayCoordY[NumCoordType];
MIL_DOUBLE WorldMidPointCoord;
MIL_DOUBLE PrevWorldStartCoord, PrevWorldEndCoord;
while (NumStackElements > 0 && NumStackElements < SubRulerSize)
{
PrevWorldStartCoord = MidPointStack[NumStackElements-1].StartCoord;
PrevWorldEndCoord = MidPointStack[NumStackElements-1].EndCoord;
NumStackElements--;
WorldMidPointCoord = PrevWorldStartCoord +
(PrevWorldEndCoord - PrevWorldStartCoord)/2;
if (Type == eXAxis)
{
WorldCoordX[eStart] = PrevWorldStartCoord;
WorldCoordY[eStart] = 0;
WorldCoordX[eEnd] = WorldMidPointCoord;
WorldCoordY[eEnd] = 0;
McalTransformCoordinateList(MilCalibratedImage, M_WORLD_TO_PIXEL,
NumCoordType, WorldCoordX, WorldCoordY, PixelCoordX, PixelCoordY);
PixelToDisplay(PixelCoordX, PixelCoordY, DisplayCoordX, DisplayCoordY,
NumCoordType, ZoomX, ZoomY, OffsetX, OffsetY);
MIL_DOUBLE SubRulerDistance = DisplayCoordX[eEnd]-DisplayCoordX[eStart];
if (SubRulerDistance > MINOR_MEASURE_DISTANCE)
{
MIL_INT RoundedDisplayEndCoordX = M_Round(DisplayCoordX[eEnd]);
if ( DisplayCoordX[eEnd]>=0 && RoundedDisplayEndCoordX < RulerArraySize)
{
if (SubRulerDistance > MAJOR_MEASURE_DISTANCE)
{
RulerArray[RoundedDisplayEndCoordX].DrawMajorMeasure = true;
RulerArray[RoundedDisplayEndCoordX].Measure = WorldMidPointCoord;
}
else if (SubRulerDistance > MEDIUM_MEASURE_DISTANCE)
{
RulerArray[RoundedDisplayEndCoordX].DrawMediumMeasure = true;
RulerArray[RoundedDisplayEndCoordX].Measure = WorldMidPointCoord;
}
else
{
RulerArray[RoundedDisplayEndCoordX].DrawMinorMeasure = true;
RulerArray[RoundedDisplayEndCoordX].Measure = WorldMidPointCoord;
}
}
MidPointStack[NumStackElements].StartCoord = WorldCoordX[eStart];
MidPointStack[NumStackElements].EndCoord = WorldCoordX[eEnd];
NumStackElements++;
MidPointStack[NumStackElements].StartCoord = WorldMidPointCoord;
MidPointStack[NumStackElements].EndCoord = PrevWorldEndCoord;
NumStackElements++;
}
}
else
{
WorldCoordX[eStart] = 0;
WorldCoordY[eStart] = PrevWorldStartCoord;
WorldCoordX[eEnd] = 0;
WorldCoordY[eEnd] = WorldMidPointCoord;
McalTransformCoordinateList(MilCalibratedImage, M_WORLD_TO_PIXEL, NumCoordType,
WorldCoordX, WorldCoordY, PixelCoordX, PixelCoordY);
PixelToDisplay(PixelCoordX, PixelCoordY, DisplayCoordX, DisplayCoordY,
NumCoordType, ZoomX, ZoomY, OffsetX, OffsetY);
MIL_DOUBLE SubRulerDistance = DisplayCoordY[eEnd] - DisplayCoordY[eStart];
if (SubRulerDistance > MINOR_MEASURE_DISTANCE)
{
MIL_INT RoundedDisplayEndCoordY = M_Round(DisplayCoordY[eEnd]);
if (DisplayCoordY[eEnd]>=0 && RoundedDisplayEndCoordY < RulerArraySize)
{
if (SubRulerDistance > MAJOR_MEASURE_DISTANCE)
{
RulerArray[RoundedDisplayEndCoordY].DrawMajorMeasure = true;
RulerArray[RoundedDisplayEndCoordY].Measure = WorldMidPointCoord;
}
else if (SubRulerDistance > MEDIUM_MEASURE_DISTANCE)
{
RulerArray[RoundedDisplayEndCoordY].DrawMediumMeasure = true;
RulerArray[RoundedDisplayEndCoordY].Measure = WorldMidPointCoord;
}
else
{
RulerArray[RoundedDisplayEndCoordY].DrawMinorMeasure = true;
RulerArray[RoundedDisplayEndCoordY].Measure = WorldMidPointCoord;
}
}
MidPointStack[NumStackElements].StartCoord = WorldCoordY[eStart];
MidPointStack[NumStackElements].EndCoord = WorldCoordY[eEnd];
NumStackElements++;
MidPointStack[NumStackElements].StartCoord = WorldMidPointCoord;
MidPointStack[NumStackElements].EndCoord = PrevWorldEndCoord;
NumStackElements++;
}
}
}
delete [] MidPointStack;
}
MIL_INT MFTYPE MeasureDistance(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr,
bool RightClick)
{
DispHookMeasureDataStruct* pMeasData = (DispHookMeasureDataStruct*)UserDataPtr;
MIL_ID MilDisplay = pMeasData->MilDisplay;
MIL_ID MilCalibration = pMeasData->MilCalibration;
MIL_ID MilCalibratedImage = pMeasData->MilImage;
MIL_ID MilDisplayGraphicList = pMeasData->MilDisplayGraphicList;
MIL_ID MilRulerGraphicList = pMeasData->MilRulerGraphicList;
MIL_ID MilMeasGraphicList = pMeasData->MilMeasGraphicList;
MIL_ID MilMeasBoxGraphicList = pMeasData->MilMeasBoxGraphicList;
MIL_ID MilGraphics = pMeasData->MilGraphics;
MIL_ID MilMeasMarker1 = pMeasData->MilMeasMarker1;
MIL_ID MilMeasMarker2 = pMeasData->MilMeasMarker2;
MIL_ID MilMeasCalculateRes = pMeasData->MilMeasCalculateRes;
MIL_INT* NumDefinedMarkers = &(pMeasData->NumDefinedMarkers);
MIL_DOUBLE MousePositionX, MousePositionY;
MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_X, &MousePositionX);
MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_Y, &MousePositionY);
MgraColor(MilGraphics, MEAS_COLOR);
MgraControl(MilGraphics, M_INPUT_UNITS, M_PIXEL);
MdispControl(MilDisplay, M_UPDATE_GRAPHIC_LIST, M_DISABLE);
MgraClear(M_DEFAULT, MilDisplayGraphicList);
MgraClear(M_DEFAULT, MilMeasBoxGraphicList);
if ( RightClick || ((*NumDefinedMarkers) == 1) )
{ MgraClear(M_DEFAULT, MilMeasGraphicList); }
if ( ((*NumDefinedMarkers) == 2) && RightClick)
{ (*NumDefinedMarkers) = 0; }
if (!RightClick && (*NumDefinedMarkers) != 1)
{
MIL_DOUBLE BoxOriginX, BoxOriginY;
MIL_DOUBLE BoxEndX, BoxEndY;
BoxOriginX = MousePositionX - MEAS_BOX_WIDTH/2;
BoxOriginY = MousePositionY - MEAS_BOX_HEIGHT/2;
BoxEndX = BoxOriginX + MEAS_BOX_WIDTH - 1;
BoxEndY = BoxOriginY + MEAS_BOX_HEIGHT - 1;
MmeasSetMarker(MilMeasMarker2, M_BOX_ORIGIN, BoxOriginX, BoxOriginY);
MmeasSetMarker(MilMeasMarker2, M_BOX_SIZE, BoxEndX-BoxOriginX+1,
BoxEndY-BoxOriginY+1);
MmeasFindMarker(M_DEFAULT, MilCalibratedImage, MilMeasMarker2, M_POSITION);
MIL_DOUBLE NumMarkers = 0;
MmeasGetResult(MilMeasMarker2, M_NUMBER, &NumMarkers, M_NULL);
if (NumMarkers > 0)
{
MmeasDraw(MilGraphics, MilMeasMarker2, MilMeasBoxGraphicList,
M_DRAW_SEARCH_REGION, M_DEFAULT, M_DEFAULT);
}
else
{
MgraColor(MilGraphics, M_COLOR_RED);
MgraRect(MilGraphics, MilMeasBoxGraphicList, BoxOriginX-0.5,
BoxOriginY-0.5, BoxEndX+0.5, BoxEndY+0.5);
MgraColor(MilGraphics, MEAS_COLOR);
}
}
else if ((*NumDefinedMarkers) == 0)
{
MIL_DOUBLE BoxOriginX, BoxOriginY;
MIL_DOUBLE BoxEndX, BoxEndY;
BoxOriginX = MousePositionX - MEAS_BOX_WIDTH/2;
BoxOriginY = MousePositionY - MEAS_BOX_HEIGHT/2;
BoxEndX = BoxOriginX + MEAS_BOX_WIDTH - 1;
BoxEndY = BoxOriginY + MEAS_BOX_HEIGHT - 1;
MmeasSetMarker(MilMeasMarker1, M_BOX_ORIGIN, BoxOriginX, BoxOriginY);
MmeasSetMarker(MilMeasMarker1, M_BOX_SIZE, BoxEndX-BoxOriginX+1,
BoxEndY-BoxOriginY+1);
MmeasFindMarker(M_DEFAULT, MilCalibratedImage, MilMeasMarker1, M_POSITION);
MIL_DOUBLE NumMarkers = 0;
MmeasGetResult(MilMeasMarker1, M_NUMBER, &NumMarkers, M_NULL);
if (NumMarkers > 0)
{
MmeasDraw(MilGraphics, MilMeasMarker1, MilMeasGraphicList, M_DRAW_SEARCH_REGION,
M_DEFAULT, M_DEFAULT);
(*NumDefinedMarkers)++;
}
else
{
MgraColor(MilGraphics, M_COLOR_RED);
MgraRect(MilGraphics, MilMeasBoxGraphicList, BoxOriginX-0.5, BoxOriginY-0.5,
BoxEndX+0.5, BoxEndY+0.5);
MgraColor(MilGraphics, MEAS_COLOR);
}
}
else if ((*NumDefinedMarkers) == 1)
{
MIL_DOUBLE BoxOriginX, BoxOriginY;
MIL_DOUBLE BoxEndX, BoxEndY;
BoxOriginX = MousePositionX - MEAS_BOX_WIDTH/2;
BoxOriginY = MousePositionY - MEAS_BOX_HEIGHT/2;
BoxEndX = BoxOriginX + MEAS_BOX_WIDTH - 1;
BoxEndY = BoxOriginY + MEAS_BOX_HEIGHT - 1;
MmeasDraw(MilGraphics, MilMeasMarker1, MilMeasGraphicList, M_DRAW_SEARCH_REGION,
M_DEFAULT, M_DEFAULT);
MmeasSetMarker(MilMeasMarker2, M_BOX_ORIGIN, BoxOriginX, BoxOriginY);
MmeasSetMarker(MilMeasMarker2, M_BOX_SIZE, BoxEndX-BoxOriginX+1,
BoxEndY-BoxOriginY+1);
MmeasFindMarker(M_DEFAULT, MilCalibratedImage, MilMeasMarker2, M_POSITION);
MIL_DOUBLE NumMarkers=0;
MmeasGetResult(MilMeasMarker2, M_NUMBER, &NumMarkers, M_NULL);
if (NumMarkers > 0)
{
MmeasDraw(MilGraphics, MilMeasMarker2, MilMeasGraphicList, M_DRAW_SEARCH_REGION,
M_DEFAULT, M_DEFAULT);
MmeasCalculate(M_DEFAULT, MilMeasMarker1, MilMeasMarker2, MilMeasCalculateRes,
M_DISTANCE);
MmeasDraw(MilGraphics, MilMeasCalculateRes, MilMeasGraphicList, M_DRAW_LINE,
M_DEFAULT, M_DEFAULT);
MIL_DOUBLE PixelPositionX1, PixelPositionY1;
MIL_DOUBLE PixelPositionX2, PixelPositionY2;
MmeasSetMarker(MilMeasMarker1, M_RESULT_OUTPUT_UNITS, M_PIXEL, M_NULL);
MmeasSetMarker(MilMeasMarker2, M_RESULT_OUTPUT_UNITS, M_PIXEL, M_NULL);
MmeasGetResult(MilMeasMarker1, M_POSITION, &PixelPositionX1, &PixelPositionY1);
MmeasGetResult(MilMeasMarker2, M_POSITION, &PixelPositionX2, &PixelPositionY2);
MIL_DOUBLE WorldDistance;
MmeasControl(MilMeasCalculateRes, M_RESULT_OUTPUT_UNITS, M_WORLD);
MmeasGetResult(MilMeasCalculateRes, M_DISTANCE+M_TYPE_DOUBLE, &WorldDistance,
M_NULL);
MIL_TEXT_CHAR WorldDistanceString[STRING_SIZE];
MosSprintf(WorldDistanceString, STRING_SIZE, MIL_TEXT("%.2f"), WorldDistance);
MgraFont(MilGraphics, M_FONT_DEFAULT_MEDIUM);
MgraText(MilGraphics, MilMeasGraphicList,
PixelPositionX1+(PixelPositionX2-PixelPositionX1)/2+4,
PixelPositionY1+(PixelPositionY2-PixelPositionY1)/2+4, WorldDistanceString);
MgraFont(MilGraphics, M_FONT_DEFAULT);
if (RightClick)
(*NumDefinedMarkers)++;
}
else
{
MgraColor(MilGraphics, M_COLOR_RED);
MgraRect(MilGraphics, MilMeasBoxGraphicList, BoxOriginX-0.5, BoxOriginY-0.5,
BoxEndX+0.5, BoxEndY+0.5);
MgraColor(MilGraphics, MEAS_COLOR);
}
}
MgraCopy(MilRulerGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MgraCopy(MilMeasGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MgraCopy(MilMeasBoxGraphicList, MilDisplayGraphicList, M_DEFAULT, M_DEFAULT, M_ALL,
M_NULL, M_NULL, M_DEFAULT);
MdispControl(MilDisplay, M_UPDATE_GRAPHIC_LIST, M_ENABLE);
return 0;
}
MIL_INT MFTYPE MeasMouseRightClick(MIL_INT HookType, MIL_ID EventID,
void* UserDataPtr)
{
MeasureDistance(HookType, EventID, UserDataPtr, true);
return 0;
}
MIL_INT MFTYPE MeasMouseMove(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr)
{
MeasureDistance(HookType, EventID, UserDataPtr, false);
return 0;
}
void DisplayToPixel(MIL_DOUBLE* DisplayX, MIL_DOUBLE* DisplayY, MIL_DOUBLE* PixelX,
MIL_DOUBLE* PixelY, MIL_INT NumCoordinates, MIL_DOUBLE ZoomX, MIL_DOUBLE ZoomY,
MIL_DOUBLE OffsetX, MIL_DOUBLE OffsetY)
{
for (MIL_INT i=0; i < NumCoordinates; i++)
{
PixelX[i] = (DisplayX[i] + 0.5)/ZoomX + OffsetX - 0.5;
PixelY[i] = (DisplayY[i] + 0.5)/ZoomY + OffsetY - 0.5;
}
}
void PixelToDisplay(MIL_DOUBLE* PixelX, MIL_DOUBLE* PixelY, MIL_DOUBLE* DisplayX,
MIL_DOUBLE* DisplayY, MIL_INT NumCoordinates, MIL_DOUBLE ZoomX, MIL_DOUBLE ZoomY,
MIL_DOUBLE OffsetX, MIL_DOUBLE OffsetY)
{
for (MIL_INT i=0; i < NumCoordinates; i++)
{
DisplayX[i] = (PixelX[i] + 0.5 - OffsetX) * ZoomX - 0.5;
DisplayY[i] = (PixelY[i] + 0.5 - OffsetY) * ZoomY - 0.5;
}
}