#include <mil.h>
#include <math.h>
#include <stdlib.h>
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n"));
MosPrintf(MIL_TEXT("3dModelHeightDefect\n\n"));
MosPrintf(MIL_TEXT("[SYNOPSIS]\n"));
MosPrintf(MIL_TEXT("This example demonstrates how to use the 3D surface alignment \n"));
MosPrintf(MIL_TEXT("operation to align the acquired point cloud of a 3D object with \n"));
MosPrintf(MIL_TEXT("its 3D reference model in order to detect defects. \n"));
MosPrintf(MIL_TEXT("\n"));
MosPrintf(MIL_TEXT("[MODULES USED]\n"));
MosPrintf(MIL_TEXT("Modules used: 3dMap, Buffer, Calibration, Display,\n")
MIL_TEXT("Graphics, Image Processing.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
}
void AddLutColorForInvalidDepth(MIL_ID MilLut, MIL_UINT8 InvalidDepthGray);
MIL_ID CreateLutLegend(MIL_ID MilSystem);
void DrawLutLegend(MIL_ID DstImage, MIL_ID MilLutLegend);
void GetBoxPoints(MIL_ID MilDepthMap,
MIL_DOUBLE BoxPtsInAbsX[],
MIL_DOUBLE BoxPtsInAbsY[],
MIL_DOUBLE BoxPtsInAbsZ[]);
void Draw3dBoxes(MIL_ID MilSystem,
MIL_ID MilAlignmentResult,
MIL_ID MilDepthMap[],
MIL_ID MilDisplay[],
MIL_ID MilPointCloud[]);
void DrawBoxInOneDepthMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_ID MilDepthMap,
MIL_DOUBLE BoxPtsInAbsX[],
MIL_DOUBLE BoxPtsInAbsY[],
MIL_DOUBLE BoxPtsInAbsZ[]);
enum { eModel = 0, eObject = 1, eDefects = 2 };
static const MIL_TEXT_CHAR* const FILE_3DCONTEXT[] =
{M_IMAGE_PATH MIL_TEXT("3dModelHeightDefect/LaserContext_L.m3d" ),
M_IMAGE_PATH MIL_TEXT("3dModelHeightDefect/LaserContext_R.m3d")};
static const MIL_TEXT_CHAR* const FILE_OBJECT_UNCORRECTED_DEPTHMAP[] =
{M_IMAGE_PATH MIL_TEXT("3dModelHeightDefect/LaserScanUncorrectedDepthmap_L.mim"),
M_IMAGE_PATH MIL_TEXT("3dModelHeightDefect/LaserScanUncorrectedDepthmap_R.mim")};
static const MIL_TEXT_CHAR* const FILE_MODEL_POINT_CLOUD =
M_IMAGE_PATH MIL_TEXT("3dModelHeightDefect/3dModel.ply");
static const MIL_INT NUM_DEPTHMAP_VALUES = 65536;
static const MIL_INT DEPTHMAP_INVALID_VALUE = NUM_DEPTHMAP_VALUES-1;
static const MIL_UINT8 DEPTHMAP_INVALID_COLOR = 128;
static const MIL_INT DEPTH_MAP_SIZE_X = 380;
static const MIL_INT DEPTH_MAP_SIZE_Y = 400;
static const MIL_DOUBLE EXTRACTION_BOX_MIN_X = -3.0;
static const MIL_DOUBLE EXTRACTION_BOX_MIN_Y = -10.0;
static const MIL_DOUBLE EXTRACTION_BOX_MIN_Z = 13.0;
static const MIL_DOUBLE EXTRACTION_BOX_MAX_X = 190.0;
static const MIL_DOUBLE EXTRACTION_BOX_MAX_Y = 190.0;
static const MIL_DOUBLE EXTRACTION_BOX_MAX_Z = -53.0;
static const MIL_INT DECIMATION_STEP_MODEL = 8;
static const MIL_INT DECIMATION_STEP_OBJECT = 8;
static const MIL_DOUBLE MODEL_OVERLAP = 95.0;
static const MIL_INT MAX_ITERATIONS = 20;
static const MIL_DOUBLE ALIGN_RMS_ERROR_RELATIVE_THRESHOLD = 0.5;
static const MIL_INT NUM_BOX_POINTS = 24;
static const MIL_DOUBLE DRAW_BOX_MIN_X = EXTRACTION_BOX_MIN_X + 30.0;
static const MIL_DOUBLE DRAW_BOX_MIN_Y = EXTRACTION_BOX_MIN_Y + 40.0;
static const MIL_DOUBLE DRAW_BOX_MIN_Z = EXTRACTION_BOX_MIN_Z - 60.0;
static const MIL_DOUBLE DRAW_BOX_MAX_X = DRAW_BOX_MIN_X + 98.0;
static const MIL_DOUBLE DRAW_BOX_MAX_Y = DRAW_BOX_MIN_Y + 136.0;
static const MIL_DOUBLE DRAW_BOX_MAX_Z = DRAW_BOX_MIN_Z + 100.0;
static const MIL_DOUBLE DEFECT_SCALE_Z_RATIO = 0.12;
int MosMain(void)
{
PrintHeader();
MIL_ID MilApplication;
MIL_ID MilSystem;
MIL_ID MilObjectUncorrDepth[2];
MIL_ID Mil3dContext[2];
MIL_ID MilPointCloud[2];
MIL_ID MilAlignmentContext;
MIL_ID MilAlignmentResult;
MIL_ID MilDepthMap[3];
MIL_ID MilLut;
MIL_ID MilLutLegend;
MIL_ID MilDisplay[3];
MappAlloc(M_NULL, M_DEFAULT, &MilApplication);
MsysAlloc(M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilSystem);
M3dmapAllocResult(MilSystem, M_POINT_CLOUD_CONTAINER, M_DEFAULT, &MilPointCloud[eModel]);
MosPrintf(MIL_TEXT("The model's 3D point cloud is imported from a PLY file.\n\n"));
M3dmapImport(FILE_MODEL_POINT_CLOUD, M_PLY, MilPointCloud[eModel], M_POINT_CLOUD_LABEL(1), M_NULL, M_DEFAULT);
M3dmapAllocResult(MilSystem, M_POINT_CLOUD_CONTAINER, M_DEFAULT, &MilPointCloud[eObject]);
MosPrintf(MIL_TEXT("The object's raw depth maps acquired using a 3D camera-laser scanner are restored.\n\n"));
const MIL_INT NumCameras = 2;
for (MIL_INT i = 0; i < NumCameras; i++)
{
MbufRestore(FILE_OBJECT_UNCORRECTED_DEPTHMAP[i], MilSystem, &MilObjectUncorrDepth[i]);
M3dmapRestore(FILE_3DCONTEXT[i], MilSystem, M_DEFAULT, &Mil3dContext[i]);
M3dmapControl(MilPointCloud[eObject], M_GENERAL, M_MAX_FRAMES, 2048);
M3dmapAddScan(Mil3dContext[i], MilPointCloud[eObject], MilObjectUncorrDepth[i], M_NULL, M_NULL, M_POINT_CLOUD_LABEL(i+1), M_LINE_ALREADY_EXTRACTED);
M3dmapFree(Mil3dContext[i]);
MbufFree(MilObjectUncorrDepth[i]);
}
MbufAllocColor(MilSystem, 3, NUM_DEPTHMAP_VALUES, 1, 8 + M_UNSIGNED, M_LUT, &MilLut);
AddLutColorForInvalidDepth(MilLut, DEPTHMAP_INVALID_COLOR);
MilLutLegend = CreateLutLegend(MilSystem);
const MIL_INT NumDisplays = 3;
for (MIL_INT i = 0; i < NumDisplays; i++)
{
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay[i]);
MdispLut(MilDisplay[i], MilLut);
MdispControl(MilDisplay[i], M_OVERLAY, M_ENABLE);
MdispControl(MilDisplay[i], M_WINDOW_INITIAL_POSITION_X, (MIL_INT)(i*1.04 * DEPTH_MAP_SIZE_X));
MdispControl(MilDisplay[i], M_UPDATE, M_DISABLE);
switch (i)
{
case eModel:
MdispControl(MilDisplay[eModel] , M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Model Depth Map"))); break;
case eObject:
MdispControl(MilDisplay[eObject] , M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Object Depth Map"))); break;
case eDefects:
MdispControl(MilDisplay[eDefects], M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Defect Height Map"))); break;
}
}
const MIL_INT NumPtCloudContainers = 2;
MIL_INT NumPoints[NumPtCloudContainers];
for (MIL_INT i = 0; i < NumPtCloudContainers; i++)
{
M3dmapGetResult(MilPointCloud[i], M_DEFAULT,
M_NUMBER_OF_3D_POINTS + M_NO_INVALID_POINT + M_TYPE_MIL_INT,
&NumPoints[i]);
MbufAlloc2d(MilSystem, DEPTH_MAP_SIZE_X, DEPTH_MAP_SIZE_Y, 16 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilDepthMap[i]);
M3dmapControl(MilPointCloud[i], M_DEFAULT, M_EXTRACTION_OVERLAP , M_MAX );
M3dmapControl(MilPointCloud[i], M_DEFAULT, M_EXTRACTION_SATURATION, M_DISABLE );
M3dmapControl(MilPointCloud[i], M_DEFAULT, M_FILL_MODE , M_DISABLE );
M3dmapSetBox(MilPointCloud[i], M_EXTRACTION_BOX, M_BOTH_CORNERS,
EXTRACTION_BOX_MIN_X, EXTRACTION_BOX_MIN_Y, EXTRACTION_BOX_MIN_Z,
EXTRACTION_BOX_MAX_X, EXTRACTION_BOX_MAX_Y, EXTRACTION_BOX_MAX_Z);
M3dmapExtract(MilPointCloud[i], MilDepthMap[i], M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);
MdispSelect(MilDisplay[i], MilDepthMap[i]);
DrawLutLegend(MilDepthMap[i], MilLutLegend);
MdispControl(MilDisplay[i], M_UPDATE, M_NOW);
}
MosPrintf(MIL_TEXT("The model's and object's corrected depth maps are displayed using pseudo colors.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
M3dmapAlloc(MilSystem, M_PAIRWISE_ALIGNMENT_CONTEXT, M_DEFAULT, &MilAlignmentContext);
M3dmapAllocResult(MilSystem, M_ALIGNMENT_RESULT, M_DEFAULT, &MilAlignmentResult);
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_DECIMATION_STEP_MODEL , DECIMATION_STEP_MODEL );
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_DECIMATION_STEP_SCENE , DECIMATION_STEP_OBJECT );
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_PREALIGNMENT_MODE , M_CENTROID );
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_MODEL_OVERLAP , MODEL_OVERLAP );
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_MAX_ITERATIONS , MAX_ITERATIONS );
M3dmapControl(MilAlignmentContext, M_DEFAULT, M_ALIGN_RMS_ERROR_RELATIVE_THRESHOLD, ALIGN_RMS_ERROR_RELATIVE_THRESHOLD);
MIL_INT64 AlignStatus = M_NULL;
MIL_DOUBLE AlignComputationTime = 0.0;
MappTimer(M_TIMER_RESET, M_NULL);
M3dmapAlign(MilAlignmentContext ,
MilPointCloud[eModel] ,
M_ALL ,
MilPointCloud[eObject] ,
M_ALL ,
M_NULL ,
MilAlignmentResult ,
M_DEFAULT ,
&AlignStatus );
MappTimer(M_TIMER_READ, &AlignComputationTime);
MosPrintf(MIL_TEXT("The 3D alignment between the model and the object has been performed.\n\n"));
switch (AlignStatus)
{
case M_NOT_INITIALIZED:
MosPrintf(MIL_TEXT("Alignment failed: the alignment result is not initialized.\n\n"));
break;
case M_NOT_ENOUGH_POINT_PAIRS:
MosPrintf(MIL_TEXT("Alignment failed: point clouds are not overlaping.\n\n"));
break;
case M_MAX_ITERATIONS_REACHED:
MosPrintf(MIL_TEXT("Alignment reached the maximum number of iterations allowed (%d)\n")
MIL_TEXT("in %.2f ms. Resulting fixture may or may not be valid.\n\n"),
MAX_ITERATIONS, AlignComputationTime*1000);
break;
case M_ALIGN_RMS_ERROR_THRESHOLD_REACHED:
case M_ALIGN_RMS_ERROR_RELATIVE_THRESHOLD_REACHED:
MIL_DOUBLE AlignRmsError;
M3dmapGetResult(MilAlignmentResult, M_DEFAULT, M_ALIGN_RMS_ERROR + M_TYPE_MIL_DOUBLE, &AlignRmsError);
MosPrintf(MIL_TEXT("The alignment of %d model points with %d object points\n")
MIL_TEXT("succeeded in %.2f ms with a final RMS error of %f mm.\n\n"),
NumPoints[eModel], NumPoints[eObject], AlignComputationTime*1000, AlignRmsError);
break;
default:
MosPrintf(MIL_TEXT("Unknown alignment status.\n\n"));
}
Draw3dBoxes(MilSystem, MilAlignmentResult, MilDepthMap, MilDisplay, MilPointCloud);
MosPrintf(MIL_TEXT("3D boxes are drawn to highlight the 3D pose estimation of the object relative to the model.\n\n"));
DrawLutLegend(MilDepthMap[eObject], MilLutLegend);
MdispControl(MilDisplay[eObject], M_UPDATE, M_NOW);
McalFixture(MilPointCloud[eObject], M_NULL, M_MOVE_RELATIVE, M_RESULT_ALIGNMENT_3DMAP, MilAlignmentResult, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dmapExtract(MilPointCloud[eObject], MilDepthMap[eObject], M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);
MbufAlloc2d(MilSystem, DEPTH_MAP_SIZE_X, DEPTH_MAP_SIZE_Y, 16 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilDepthMap[eDefects]);
MIL_DOUBLE ScaleZ;
McalAssociate(MilDepthMap[eModel], MilDepthMap[eDefects], M_DEFAULT);
McalControl(MilDepthMap[eDefects], M_WORLD_POS_Z, 0.0);
McalInquire(MilDepthMap[eDefects], M_GRAY_LEVEL_SIZE_Z, &ScaleZ);
McalControl(MilDepthMap[eDefects], M_GRAY_LEVEL_SIZE_Z, fabs(ScaleZ) * DEFECT_SCALE_Z_RATIO);
MosPrintf(MIL_TEXT("The object's depth map is corrected according to the found 3D pose relative to the model\n")
MIL_TEXT("and is subtracted from the model reference to determine differences in heights.\n\n"));
M3dmapArith(MilDepthMap[eModel], MilDepthMap[eObject], MilDepthMap[eDefects], M_NULL, M_SUB_ABS, M_USE_DESTINATION_SCALES);
DrawLutLegend(MilDepthMap[eDefects], MilLutLegend);
MdispSelect(MilDisplay[eDefects], MilDepthMap[eDefects]);
MosPrintf(MIL_TEXT("The resulting depth map of differences is displayed using pseudo colors.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
for (MIL_INT i = 0; i < NumPtCloudContainers; i++)
{
M3dmapFree(MilPointCloud[i]);
MbufFree(MilDepthMap[i]);
MdispControl(MilDisplay[i], M_ASSOCIATED_GRAPHIC_LIST_ID, M_NULL);
MdispFree(MilDisplay[i]);
}
M3dmapFree(MilAlignmentContext);
M3dmapFree(MilAlignmentResult);
MbufFree(MilLutLegend);
MbufFree(MilDepthMap[eDefects]);
MdispFree(MilDisplay[eDefects]);
MbufFree(MilLut);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
void AddLutColorForInvalidDepth(MIL_ID MilLut, MIL_UINT8 InvalidDepthGray)
{
MgenLutFunction(MilLut, M_COLORMAP_JET, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MIL_UINT8 LutJetArray[3][NUM_DEPTHMAP_VALUES];
MbufGetColor(MilLut, M_PLANAR, M_ALL_BANDS, LutJetArray);
MIL_UINT8 InvalidDepthColor[3] = {InvalidDepthGray, InvalidDepthGray, InvalidDepthGray};
LutJetArray[0][DEPTHMAP_INVALID_VALUE] = InvalidDepthColor[0];
LutJetArray[1][DEPTHMAP_INVALID_VALUE] = InvalidDepthColor[1];
LutJetArray[2][DEPTHMAP_INVALID_VALUE] = InvalidDepthColor[2];
MbufPutColor(MilLut, M_PLANAR, M_ALL_BANDS, LutJetArray);
}
void Draw3dBoxes(MIL_ID MilSystem,
MIL_ID MilAlignmentResult,
MIL_ID MilDepthMap[],
MIL_ID MilDisplay[],
MIL_ID MilPointCloud[])
{
MIL_DOUBLE ModelBoxPtsInAbsX[NUM_BOX_POINTS];
MIL_DOUBLE ModelBoxPtsInAbsY[NUM_BOX_POINTS];
MIL_DOUBLE ModelBoxPtsInAbsZ[NUM_BOX_POINTS];
GetBoxPoints(MilDepthMap[eModel], ModelBoxPtsInAbsX, ModelBoxPtsInAbsY, ModelBoxPtsInAbsZ);
DrawBoxInOneDepthMap(MilSystem,
MilDisplay[eModel],
MilDepthMap[eModel],
ModelBoxPtsInAbsX,
ModelBoxPtsInAbsY,
ModelBoxPtsInAbsZ);
MdispControl(MilDisplay[eModel], M_UPDATE, M_NOW);
McalFixture(MilPointCloud[eObject], M_NULL, M_MOVE_RELATIVE, M_RESULT_ALIGNMENT_3DMAP, MilAlignmentResult, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dmapExtract(MilPointCloud[eObject], MilDepthMap[eObject], M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);
MIL_DOUBLE ObjectBoxPtsInAbsX[NUM_BOX_POINTS];
MIL_DOUBLE ObjectBoxPtsInAbsY[NUM_BOX_POINTS];
MIL_DOUBLE ObjectBoxPtsInAbsZ[NUM_BOX_POINTS];
GetBoxPoints(MilDepthMap[eObject], ObjectBoxPtsInAbsX, ObjectBoxPtsInAbsY, ObjectBoxPtsInAbsZ);
McalFixture(MilPointCloud[eObject], M_NULL, M_MOVE_RELATIVE, M_RESULT_ALIGNMENT_3DMAP, MilAlignmentResult, 0, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dmapExtract(MilPointCloud[eObject], MilDepthMap[eObject], M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);
DrawBoxInOneDepthMap(MilSystem,
MilDisplay[eObject],
MilDepthMap[eObject],
ObjectBoxPtsInAbsX,
ObjectBoxPtsInAbsY,
ObjectBoxPtsInAbsZ);
MdispControl(MilDisplay[eObject], M_UPDATE, M_NOW);
}
void GetBoxPoints(MIL_ID MilDepthMap, MIL_DOUBLE BoxPtsInAbsX[], MIL_DOUBLE BoxPtsInAbsY[], MIL_DOUBLE BoxPtsInAbsZ[])
{
MIL_DOUBLE BoxPtsInRelX[NUM_BOX_POINTS] = {DRAW_BOX_MIN_X, DRAW_BOX_MAX_X, DRAW_BOX_MAX_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MAX_X, DRAW_BOX_MAX_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MAX_X, DRAW_BOX_MAX_X,
DRAW_BOX_MAX_X, DRAW_BOX_MAX_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MAX_X, DRAW_BOX_MAX_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MIN_X, DRAW_BOX_MAX_X, DRAW_BOX_MAX_X};
MIL_DOUBLE BoxPtsInRelY[NUM_BOX_POINTS] = {DRAW_BOX_MIN_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y,
DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y, DRAW_BOX_MIN_Y, DRAW_BOX_MAX_Y};
MIL_DOUBLE BoxPtsInRelZ[NUM_BOX_POINTS] = {DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z,
DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MIN_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z, DRAW_BOX_MAX_Z};
McalTransformCoordinate3dList(MilDepthMap,
M_RELATIVE_COORDINATE_SYSTEM, M_ABSOLUTE_COORDINATE_SYSTEM,
NUM_BOX_POINTS,
BoxPtsInRelX, BoxPtsInRelY, BoxPtsInRelZ,
BoxPtsInAbsX, BoxPtsInAbsY, BoxPtsInAbsZ,
M_DEFAULT);
}
void DrawBoxInOneDepthMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_ID MilDepthMap,
MIL_DOUBLE BoxPtsInAbsX[],
MIL_DOUBLE BoxPtsInAbsY[],
MIL_DOUBLE BoxPtsInAbsZ[])
{
MIL_INT NumLines = NUM_BOX_POINTS/2;
MIL_DOUBLE BoxPixelsInFixtureX[NUM_BOX_POINTS];
MIL_DOUBLE BoxPixelsInFixtureY[NUM_BOX_POINTS];
MIL_DOUBLE* BoxPixelStartX = BoxPixelsInFixtureX;
MIL_DOUBLE* BoxPixelStartY = BoxPixelsInFixtureY;
MIL_DOUBLE* BoxPixelEndX = BoxPixelsInFixtureX + NumLines;
MIL_DOUBLE* BoxPixelEndY = BoxPixelsInFixtureY + NumLines;
McalTransformCoordinate3dList(MilDepthMap,
M_ABSOLUTE_COORDINATE_SYSTEM, M_PIXEL_COORDINATE_SYSTEM,
NUM_BOX_POINTS,
BoxPtsInAbsX , BoxPtsInAbsY , BoxPtsInAbsZ,
BoxPixelsInFixtureX, BoxPixelsInFixtureY, M_NULL ,
M_DEPTH_MAP);
MIL_ID BoxOverlay;
MbufAlloc2d(MilSystem, DEPTH_MAP_SIZE_X, DEPTH_MAP_SIZE_Y, 1+M_UNSIGNED, M_IMAGE+M_PROC, &BoxOverlay);
MbufClear(BoxOverlay, 0.0);
MgraColor(M_DEFAULT, 1.0);
MgraLines(M_DEFAULT, BoxOverlay, 4, BoxPixelStartX, BoxPixelStartY, BoxPixelEndX, BoxPixelEndY, M_DEFAULT);
MbufClearCond(BoxOverlay, 0.0, M_NULL, M_NULL, MilDepthMap, M_NOT_EQUAL, (MIL_DOUBLE)DEPTHMAP_INVALID_VALUE);
MgraLines(M_DEFAULT, BoxOverlay, NumLines-4, &BoxPixelStartX[4], &BoxPixelStartY[4], &BoxPixelEndX[4], &BoxPixelEndY[4], M_DEFAULT);
MIL_ID MilOverlay;
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MdispInquire(MilDisplay, M_OVERLAY_ID, &MilOverlay);
MbufCopyCond(BoxOverlay, MilOverlay, BoxOverlay, M_EQUAL, 1.0);
MbufFree(BoxOverlay);
}
MIL_ID CreateLutLegend(MIL_ID MilSystem)
{
MIL_ID MilLutLegend;
MbufAlloc2d(MilSystem, 1, NUM_DEPTHMAP_VALUES, 16 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilLutLegend);
MIL_UINT16* pLUTLegend = new MIL_UINT16[NUM_DEPTHMAP_VALUES];
for (MIL_INT i = 0; i < NUM_DEPTHMAP_VALUES; i++)
pLUTLegend[i] = static_cast<MIL_UINT16>(NUM_DEPTHMAP_VALUES - i);
MbufPut(MilLutLegend, pLUTLegend);
delete[] pLUTLegend;
return MilLutLegend;
}
void DrawLutLegend(MIL_ID DstImage, MIL_ID MilLutLegend)
{
MIL_INT LegendSizeX = (DEPTH_MAP_SIZE_X) / 8;
MIL_INT LegendSizeY = (DEPTH_MAP_SIZE_Y * 3) / 4;
MIL_INT LegendOffX = DEPTH_MAP_SIZE_X - LegendSizeX - 10;
MIL_INT LegendOffY = (DEPTH_MAP_SIZE_Y - LegendSizeY) / 2;
MIL_ID ChildForLegend = MbufChild2d(DstImage, LegendOffX, LegendOffY, LegendSizeX, LegendSizeY, M_NULL);
MimResize(MilLutLegend, ChildForLegend, M_FILL_DESTINATION, M_FILL_DESTINATION, M_BILINEAR);
MIL_DOUBLE GrayLevelSizeZ;
McalInquire(DstImage, M_GRAY_LEVEL_SIZE_Z, &GrayLevelSizeZ);
MIL_DOUBLE GrayScaleWorldBoxHeight = fabs(GrayLevelSizeZ) * (NUM_DEPTHMAP_VALUES-1);
MIL_DOUBLE LegendLowZ = 0.0;
MIL_DOUBLE LegendMidZ = LegendLowZ + (GrayScaleWorldBoxHeight * 0.5);
MIL_DOUBLE LegendHiZ = LegendLowZ + GrayScaleWorldBoxHeight;
MIL_TEXT_CHAR mmTxt[256];
MgraControl(M_DEFAULT, M_TEXT_ALIGN_HORIZONTAL, M_CENTER);
MgraColor(M_DEFAULT, 32767);
MosSprintf(mmTxt, 256, MIL_TEXT("%.0f mm"), LegendHiZ);
MgraText(M_DEFAULT, ChildForLegend, LegendSizeX / 2, 5, mmTxt);
MosSprintf(mmTxt, 256, MIL_TEXT("%.0f mm"), LegendMidZ);
MgraText(M_DEFAULT, ChildForLegend, LegendSizeX / 2, LegendSizeY / 2, mmTxt);
MosSprintf(mmTxt, 256, MIL_TEXT("%.0f mm"), LegendLowZ);
MgraText(M_DEFAULT, ChildForLegend, LegendSizeX / 2, LegendSizeY - 20, mmTxt);
MbufFree(ChildForLegend);
}