Click here to show toolbars of the Web Online Help System: show toolbars
 

//***************************************************************************************
// 
// File name: 3dProfileMetrology.cpp  
// Location: See Matrox Example Launcher in the MIL Control Center
// 
//
// Synopsis: Demonstrates metrology operations along the 3D profile of a 
//           the scanned 3d mechanical part.
//
// Copyright (C) Matrox Electronic Systems Ltd., 1992-2016.
// All Rights Reserved

#include <mil.h>

//****************************************************************************
// Example description.
//****************************************************************************
void PrintHeader()   
   {
   MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n"));
   MosPrintf(MIL_TEXT("3dProfileMetrology\n\n"));

   MosPrintf(MIL_TEXT("[SYNOPSIS]\n"));
   MosPrintf(MIL_TEXT("This example demonstrates the validation of metrology measurements\n")
             MIL_TEXT("along a 3d profile of the 3d reconstruction of a mechanical part."));
   MosPrintf(MIL_TEXT("\n\n"));

   MosPrintf(MIL_TEXT("[MODULES USED]\n"));
   MosPrintf(MIL_TEXT("Modules used: Application, system, display, buffer, graphic,\n")
             MIL_TEXT("image processing, calibration, 3d reconstruction, model finder,\n")
             MIL_TEXT("and metrology.\n\n"));
   }

static const MIL_INT MAP_SIZE_X = 487;
static const MIL_INT MAP_SIZE_Y = 1319;

// Macro defining the example's filepath.
#define EX_PATH(x) (M_IMAGE_PATH MIL_TEXT("MechanicalPartScan/") MIL_TEXT(x))
#define METAL_PART_CLOUD_CONTAINER EX_PATH("MetalPartCloudContainer.m3d")

struct SMapGeneration
   {
   MIL_DOUBLE BoxCornerX;
   MIL_DOUBLE BoxCornerY;
   MIL_DOUBLE BoxCornerZ;
   MIL_DOUBLE BoxSizeX;
   MIL_DOUBLE BoxSizeY;
   MIL_DOUBLE BoxSizeZ;
   MIL_INT    MapSizeX;
   MIL_INT    MapSizeY;
   MIL_DOUBLE PixelSizeX;
   MIL_DOUBLE PixelSizeY;
   MIL_DOUBLE GrayScaleZ;
   MIL_INT    IntensityMapType;
   bool       SetExtractOverlap;
   MIL_DOUBLE ExtractOverlap;
   MIL_DOUBLE FillXThreshold;
   MIL_DOUBLE FillYThreshold;
   };

struct SProjectionBox
   {
   MIL_DOUBLE OffsetX;
   MIL_DOUBLE OffsetY;
   MIL_DOUBLE OffsetZ;
   MIL_DOUBLE Length;
   MIL_DOUBLE Thickness;
   MIL_DOUBLE Height;
   };

struct SRectRegion
   {
   MIL_DOUBLE OffsetX;
   MIL_DOUBLE OffsetY;
   MIL_DOUBLE Width;
   MIL_DOUBLE Height;
   MIL_DOUBLE Angle;
   };

struct SArcRegion
   {
   MIL_DOUBLE OffsetX;
   MIL_DOUBLE OffsetY;
   MIL_DOUBLE StartRadius;
   MIL_DOUBLE EndRadius;
   MIL_DOUBLE StartAngle;
   MIL_DOUBLE EndAngle;
   };

void Analyze3DProfile(MIL_ID MilSystem,
                      MIL_ID PointCloudContainer);

void GenerateDepthMap(MIL_ID MilSystem, 
                      MIL_ID PointCloudContainer, 
                      const SMapGeneration& GenerationInfo, 
                      MIL_ID& OutDepthmap);

bool FixturePart(MIL_ID MilSystem, 
                 MIL_ID MilDepthMap, 
                 MIL_ID MilFixtureDestination, 
                 MIL_ID MilGraList);

bool CheckForRequiredMILFile(MIL_CONST_TEXT_PTR FileName);

//*****************************************************************************
// Main.
//*****************************************************************************
int MosMain(void)
   {
   PrintHeader();

   // Allocate the MIL application.
   MIL_ID MilApplication = MappAlloc(M_NULL, M_DEFAULT, M_NULL);

   //Check for required example files.
   if (!CheckForRequiredMILFile(METAL_PART_CLOUD_CONTAINER))
      {
      MappFree(MilApplication);
      return -1;
      }

   // Allocate a host system.
   MIL_ID MilSystem = MsysAlloc(M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, M_NULL);

   MosPrintf(MIL_TEXT("Press <Enter> to start.\n\n"));
   MosGetch();

   // Restore a 3d point cloud of the object.
   MIL_ID PointCloudContainer = M_NULL;
   M3dmapRestore(METAL_PART_CLOUD_CONTAINER, MilSystem, M_DEFAULT, &PointCloudContainer);
   
   // Analyze.
   Analyze3DProfile(MilSystem, PointCloudContainer);

   // Free the MIL 3d point cloud.
   M3dmapFree(PointCloudContainer);

   // Free the MIL system and application.
   MsysFree(MilSystem);
   MappFree(MilApplication);

   return 0;
   }

//*******************************************************************************
// 3D profile analysis of the the scanned object.
//*******************************************************************************
void Analyze3DProfile (MIL_ID MilSystem, MIL_ID PointCloudContainer)
   {
   // Allocates the displays and graphic lists
   MIL_ID MilDisplayDepthMap   = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL);
   MIL_ID MilDisplayProjection = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL);

   MIL_ID MilDepthMapGraphicList   = MgraAllocList(MilSystem, M_DEFAULT, M_NULL);
   MIL_ID MilProjectionGraphicList = MgraAllocList(MilSystem, M_DEFAULT, M_NULL);

   MdispControl(MilDisplayDepthMap, M_ASSOCIATED_GRAPHIC_LIST_ID, MilDepthMapGraphicList);
   MdispControl(MilDisplayProjection, M_ASSOCIATED_GRAPHIC_LIST_ID, MilProjectionGraphicList);

   MdispControl(MilDisplayDepthMap, M_VIEW_MODE, M_AUTO_SCALE);
   MdispControl(MilDisplayProjection, M_VIEW_MODE, M_AUTO_SCALE);

   // Set the volume information.
   SMapGeneration MapData;
   MapData.BoxCornerX = 5.00;
   MapData.BoxCornerY = -160.00;
   MapData.BoxCornerZ = -4.00;
   MapData.BoxSizeX   = 120.00;
   MapData.BoxSizeY   = 410.00;
   MapData.BoxSizeZ   = -30.00;
   MapData.MapSizeX   = MAP_SIZE_X;
   MapData.MapSizeY   = MAP_SIZE_Y;
   MapData.PixelSizeX = 0.22;
   MapData.PixelSizeY = 0.22;
   MapData.GrayScaleZ = (MapData.BoxSizeZ / 65534.0);
   MapData.IntensityMapType  = 8 + M_UNSIGNED;
   MapData.SetExtractOverlap = true;
   MapData.ExtractOverlap = M_MIN;
   MapData.FillXThreshold = 1.0;
   MapData.FillYThreshold = 1.0;

   // Set the extraction box definition in world units and relative to the part fixture.
   // The extraction box is defined to retrieve a slice of 3D positions from the scanned object.
   SProjectionBox ProjBox;
   ProjBox.OffsetX   = 41.0;
   ProjBox.OffsetY   = 70.0;
   ProjBox.OffsetZ   = 20.0;
   ProjBox.Length    = 90.0;
   ProjBox.Height    = 80.0;
   ProjBox.Thickness = 0.5;

   // Generate the top view calibrated depth map.
   MIL_ID MilDepthMap = M_NULL;
   GenerateDepthMap(MilSystem, PointCloudContainer, MapData, MilDepthMap);

   // Allocate the necessary buffers for processing and display.
   const MIL_INT DepthMapScanOffsetY = 400;
   MIL_ID MilDepthMapChild = M_NULL;
   MbufChild2d(MilDepthMap, 0, DepthMapScanOffsetY, MAP_SIZE_X, MAP_SIZE_Y - DepthMapScanOffsetY, &MilDepthMapChild);

   // Display the depth map and its calibration.
   MgraClear(M_DEFAULT, MilDepthMapGraphicList);
   MgraColor(M_DEFAULT, M_COLOR_LIGHT_BLUE);
   MgraBackColor(M_DEFAULT, M_COLOR_GRAY);
   McalDraw(M_DEFAULT, MilDepthMapChild, MilDepthMapGraphicList, M_DRAW_RELATIVE_COORDINATE_SYSTEM, M_DEFAULT, M_DEFAULT);
   MdispSelect(MilDisplayDepthMap, MilDepthMapChild);

   MosPrintf(MIL_TEXT("A top view calibrated depth map of the mechanical part was generated.\n")
             MIL_TEXT("Press <Enter> to continue.\n\n"));
   MosGetch();

   // Locate the part and move the relative coordinate system accordingly.
   bool PartFound = FixturePart(MilSystem, MilDepthMapChild, MilDepthMapChild, MilDepthMapGraphicList);

   if (PartFound)
      {
      MosPrintf(MIL_TEXT("The mechanical part was located and fixtured using Model Finder in the depth map.\n")
                MIL_TEXT("Press <Enter> to continue.\n\n"));
      MosGetch();

      // Draw the fixtured coordinate system.
      MgraClear(M_DEFAULT, MilDepthMapGraphicList);
      MgraColor(M_DEFAULT, M_COLOR_LIGHT_BLUE);
      MgraBackColor(M_DEFAULT, M_COLOR_GRAY);
      McalDraw(M_DEFAULT, MilDepthMapChild, MilDepthMapGraphicList, M_DRAW_RELATIVE_COORDINATE_SYSTEM, M_DEFAULT, M_DEFAULT);

      // Move the relative coordinate system along the projection axis and draw the resulting fixture.
      McalFixture(MilDepthMapChild, M_NULL, 
                  M_MOVE_RELATIVE, 
                  M_POINT_AND_DIRECTION_POINT, 
                  M_DEFAULT, 
                  ProjBox.OffsetX, 
                  ProjBox.OffsetY, 
                  ProjBox.OffsetX, 
                  ProjBox.OffsetY + ProjBox.Length);
      MgraColor(M_DEFAULT, M_COLOR_DARK_BLUE);
      McalDraw(M_DEFAULT, MilDepthMapChild, MilDepthMapGraphicList, M_DRAW_RELATIVE_COORDINATE_SYSTEM+M_DRAW_FRAME, M_DEFAULT, M_DEFAULT);

      // Move the relative coordinate system of the point cloud at the new fixtured position.
      McalFixture(PointCloudContainer, M_NULL, M_MOVE_RELATIVE, M_SAME_AS_SOURCE, MilDepthMapChild, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);

      // Set the Z axis in the direction of the desired projection.
      McalSetCoordinateSystem(PointCloudContainer, 
                              M_RELATIVE_COORDINATE_SYSTEM, 
                              M_RELATIVE_COORDINATE_SYSTEM, 
                              M_ROTATION_X, M_NULL, 
                              90, M_DEFAULT, M_DEFAULT, M_DEFAULT);
      
      // Set the extraction box dimensions and position in the relative coordinate system.
      M3dmapSetBox(PointCloudContainer, 
                   M_EXTRACTION_BOX, M_BOTH_CORNERS, 
                   0             , ProjBox.OffsetZ - ProjBox.Height,  ProjBox.Thickness,
                   ProjBox.Length, ProjBox.OffsetZ                 , -ProjBox.Thickness);

      // Draw the projection box in the depth map.
      MgraColor(M_DEFAULT, M_COLOR_RED);
      MgraControl(M_DEFAULT, M_INPUT_UNITS, M_WORLD);
      MgraRect(M_DEFAULT, MilDepthMapGraphicList,
               0.0           ,  ProjBox.Thickness,
               ProjBox.Length, -ProjBox.Thickness);

      MosPrintf(MIL_TEXT("The extraction box was set relative to the fixture.\n")
                MIL_TEXT("Press <Enter> to continue.\n\n"));
      MosGetch();

      // Retrieve the number of points within the extraction box.
      MIL_INT NumberOfExtractedPoints = 0;
      M3dmapGet(PointCloudContainer, M_DEFAULT, M_POSITION, M_INCLUDE_POINTS_INSIDE_BOX_ONLY, 64 + M_FLOAT, 0, M_NULL, M_NULL, M_NULL, &NumberOfExtractedPoints);

      // Retrieve the point within the extraction box.
      MIL_DOUBLE* pX = new MIL_DOUBLE[NumberOfExtractedPoints];
      MIL_DOUBLE* pY = new MIL_DOUBLE[NumberOfExtractedPoints];
      M3dmapGet(PointCloudContainer, M_DEFAULT, M_POSITION, M_INCLUDE_POINTS_INSIDE_BOX_ONLY, 64 + M_FLOAT, NumberOfExtractedPoints, pX, pY, M_NULL, M_NULL);

      // Allocate the Metrology tool to perform measures along the 3D profile.
      MIL_ID MetContext = MmetAlloc(MilSystem, M_DEFAULT, M_NULL);
      MIL_ID MetResult = MmetAllocResult(MilSystem, M_DEFAULT, M_NULL);

      const SRectRegion UpperRect = {40, -25, 8, 15, 0};
      const SRectRegion LowerRect = {55, -15, 20, 10, 0};
      const SArcRegion  UpperArc  = {12, -30, 3, 8, 180, 270};
      
      // Set the Metrology features and tolerances.
      const MIL_INT EdgelLabel[1] = { M_FEATURE_INDEX(1) };
      MmetAddFeature(MetContext, M_CONSTRUCTED, M_EDGEL, M_DEFAULT, M_EXTERNAL_FEATURE, M_NULL, M_NULL, 0, M_DEFAULT);
      MmetPut(MetContext, M_FEATURE_INDEX(1), NumberOfExtractedPoints, M_NULL, pX, pY, M_NULL, M_NULL, M_DEFAULT);

      MmetAddFeature(MetContext, M_CONSTRUCTED, M_SEGMENT, M_DEFAULT, M_FIT, EdgelLabel, M_NULL, 1, M_DEFAULT);
      MmetSetRegion(MetContext, M_FEATURE_INDEX(2), M_DEFAULT, M_RECTANGLE, UpperRect.OffsetX, UpperRect.OffsetY, UpperRect.Width, UpperRect.Height, UpperRect.Angle, M_NULL);

      MmetAddFeature(MetContext, M_CONSTRUCTED, M_SEGMENT, M_DEFAULT, M_FIT, EdgelLabel, M_NULL, 1, M_DEFAULT);
      MmetSetRegion(MetContext, M_FEATURE_INDEX(3), M_DEFAULT, M_RECTANGLE, LowerRect.OffsetX, LowerRect.OffsetY, LowerRect.Width, LowerRect.Height, LowerRect.Angle, M_NULL);

      const MIL_INT SegLabels[2] = { M_FEATURE_INDEX(2), M_FEATURE_INDEX(3) };
      MmetAddTolerance(MetContext, M_PARALLELISM, M_DEFAULT, 0, 2, SegLabels, M_NULL, 2, M_DEFAULT);

      MmetAddFeature(MetContext, M_CONSTRUCTED, M_ARC, M_DEFAULT, M_FIT, EdgelLabel, M_NULL, 1, M_DEFAULT);
      MmetSetRegion(MetContext, M_FEATURE_INDEX(4), M_DEFAULT, M_RING_SECTOR, UpperArc.OffsetX, UpperArc.OffsetY, UpperArc.StartRadius, UpperArc.EndRadius, UpperArc.StartAngle, UpperArc.EndAngle);

      const MIL_INT ArcLabel[1] = { M_FEATURE_INDEX(4)};
      MmetAddTolerance(MetContext, M_RADIUS, M_DEFAULT, 0, 2, ArcLabel, M_NULL, 1, M_DEFAULT);

      // Calculate the features and tolerances.
      MmetCalculate(MetContext, M_NULL, MetResult, M_DEFAULT);

      // Allocate a buffer to display the extracted 3D slice.
      const MIL_DOUBLE ZoomFactor = 2.0;
      MIL_ID MilSliceProjection = MbufAlloc2d(MilSystem,
                                              (MIL_INT)(ZoomFactor * ProjBox.Length / MapData.PixelSizeX),
                                              (MIL_INT)(ZoomFactor * ProjBox.Height / MapData.PixelSizeY),
                                              16 + M_UNSIGNED,
                                              M_IMAGE + M_PROC + M_DISP,
                                              M_NULL);

      MgraClear(M_DEFAULT, MilProjectionGraphicList);
      MbufClear(MilSliceProjection, 0);

      M3dmapExtract(PointCloudContainer, MilSliceProjection, M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);

      // Display the calibration system.
      MgraColor(M_DEFAULT, M_COLOR_LIGHT_BLUE);
      MgraBackColor(M_DEFAULT, M_COLOR_GRAY);
      McalDraw(M_DEFAULT, MilSliceProjection, MilProjectionGraphicList, M_DRAW_RELATIVE_COORDINATE_SYSTEM, M_DEFAULT, M_DEFAULT);
      
      // Display the Metrology results.
      MgraControl(M_DEFAULT, M_INPUT_UNITS, M_WORLD);

      MgraColor(M_DEFAULT, M_COLOR_GREEN);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_REGION, M_DEFAULT, M_DEFAULT);

      MgraColor(M_DEFAULT, M_COLOR_YELLOW);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_FEATURE, M_FEATURE_INDEX(1), M_DEFAULT);

      MgraColor(M_DEFAULT, M_COLOR_BLUE);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_ACTIVE_EDGELS, M_FEATURE_INDEX(2), M_DEFAULT);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_ACTIVE_EDGELS, M_FEATURE_INDEX(3), M_DEFAULT);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_ACTIVE_EDGELS, M_FEATURE_INDEX(4), M_DEFAULT);

      MgraColor(M_DEFAULT, M_COLOR_RED);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_FEATURE, M_FEATURE_INDEX(2), M_DEFAULT);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_FEATURE, M_FEATURE_INDEX(3), M_DEFAULT);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_FEATURE, M_FEATURE_INDEX(4), M_DEFAULT);

      MgraColor(M_DEFAULT, M_COLOR_MAGENTA);
      MmetDraw(M_DEFAULT, MetResult, MilProjectionGraphicList, M_DRAW_TOLERANCE, M_ALL, M_DEFAULT);

      // Select the buffer to the display.
      MdispSelect(MilDisplayProjection, MilSliceProjection);

      MosPrintf(MIL_TEXT("Metrology measurements and tolerances were calculated along the 3D profile.\n")
                MIL_TEXT("   - Profile positions are displayed in yellow.\n")
                MIL_TEXT("   - Regions are displayed in green.\n")
                MIL_TEXT("   - Active edgels are displayed in blue.\n")
                MIL_TEXT("   - Fitted features are displayed in red.\n")
                MIL_TEXT("   - Tolerances are displayed in magenta.\n\n"));

      MosPrintf(MIL_TEXT("The display can be zoomed to observe the subpixel annotations.\n\n")
                MIL_TEXT("Press <Enter> to end.\n\n"));
      MosGetch();

      // Free the allocated resources.
      delete[] pX;
      delete[] pY;
      MbufFree(MilSliceProjection);
      MmetFree(MetContext);
      MmetFree(MetResult);
      }
   else
      {
      MosPrintf(MIL_TEXT("Unable to find the part in the corrected depth map.\n")
                MIL_TEXT("Press <Enter> to end.\n\n"));
      MosGetch();
      }

   // Free the allocated resources.
   MbufFree(MilDepthMapChild);
   MbufFree(MilDepthMap);
   MdispFree(MilDisplayDepthMap);
   MdispFree(MilDisplayProjection);
   MgraFree(MilDepthMapGraphicList);
   MgraFree(MilProjectionGraphicList);
   }

/////////////////////////////////////////////////////////////////////////////////////////
/* Finds the model, fixture a destination and draw the occurrence in the graphic list. */
/////////////////////////////////////////////////////////////////////////////////////////
bool FixturePart(MIL_ID MilSystem, 
                 MIL_ID MilDepthMap, 
                 MIL_ID MilFixtureDestination, 
                 MIL_ID MilGraList)
   {
   // Restore and setup the model used to fixture the part.
   const MIL_TEXT_CHAR* MECHANICAL_PART_MODEL = EX_PATH("ModelFinderContext.mmf");

   MIL_ID ModelCtx = MmodRestore(MECHANICAL_PART_MODEL, MilSystem, M_WITH_CALIBRATION, M_NULL);
   MIL_ID ModelRes = MmodAllocResult(MilSystem, M_DEFAULT, M_NULL);
   
   // Preprocess the model finder context.
   MmodPreprocess(ModelCtx, M_DEFAULT);

   // Create the fixturing offset.
   MIL_ID FixtureOffset = McalAlloc(MilSystem, M_FIXTURING_OFFSET, M_DEFAULT, M_NULL);
   McalFixture(M_NULL, FixtureOffset, M_LEARN_OFFSET, M_MODEL_MOD, ModelCtx, 0, M_DEFAULT, M_DEFAULT, M_DEFAULT);

   // Allocate the target image.
   MIL_INT SizeX, SizeY;
   MbufInquire(MilDepthMap, M_SIZE_X, &SizeX);
   MbufInquire(MilDepthMap, M_SIZE_Y, &SizeY);
   MIL_ID MilSearchImage = MbufAlloc2d(MilSystem, SizeX, SizeY, 8, M_IMAGE + M_PROC, M_NULL);

   // Remap the depth map to the 8 bit target image.
   MimShift(MilDepthMap, MilSearchImage, -8);

   // Find the model.
   MmodFind(ModelCtx, MilSearchImage, ModelRes);

   // Retrieve the information.
   MIL_INT NumOfOccurences = 0;
   MmodGetResult(ModelRes, M_DEFAULT, M_NUMBER + M_TYPE_MIL_INT, &NumOfOccurences);

   if (NumOfOccurences)
      {
      // Fixture the depth map.
      McalFixture(MilFixtureDestination, FixtureOffset, M_MOVE_RELATIVE, M_RESULT_MOD, ModelRes, 0, M_DEFAULT, M_DEFAULT, M_DEFAULT);

      // Draw the found occurrence.
      MgraColor(M_DEFAULT, M_COLOR_RED);
      MmodDraw(M_DEFAULT, ModelRes, MilGraList, M_DRAW_EDGES + M_MODEL, M_DEFAULT, M_DEFAULT);
      MgraColor(M_DEFAULT, M_COLOR_DARK_BLUE);
      McalDraw(M_DEFAULT, MilDepthMap, MilGraList, M_DRAW_RELATIVE_COORDINATE_SYSTEM+M_DRAW_FRAME, M_DEFAULT, M_DEFAULT);
      McalDraw(M_DEFAULT, FixtureOffset, MilGraList, M_DRAW_FIXTURING_OFFSET, M_DEFAULT, M_DEFAULT);
      }

   // Release the allocated resources.
   MmodFree(ModelCtx);
   MmodFree(ModelRes);
   MbufFree(MilSearchImage);
   McalFree(FixtureOffset);

   return (NumOfOccurences > 0);
   }

//////////////////////////////////////////////////////////
/* Depth map extraction from the point cloud container. */
//////////////////////////////////////////////////////////
void GenerateDepthMap(MIL_ID MilSystem, 
                      MIL_ID PointCloudContainer, 
                      const SMapGeneration& GenerationInfo, 
                      MIL_ID& OutDepthmap)
   {
   // Allocate the depth map if required.
   if (OutDepthmap == M_NULL)
      {
      MbufAlloc2d(MilSystem,
                  GenerationInfo.MapSizeX,
                  GenerationInfo.MapSizeY,
                  16 + M_UNSIGNED,
                  M_IMAGE + M_PROC + M_DISP,
                  &OutDepthmap);
      }

   // Set the extraction box.
   M3dmapSetBox(PointCloudContainer,
                M_EXTRACTION_BOX,
                M_CORNER_AND_DIMENSION,
                GenerationInfo.BoxCornerX,
                GenerationInfo.BoxCornerY,
                GenerationInfo.BoxCornerZ,
                GenerationInfo.BoxSizeX,
                GenerationInfo.BoxSizeY,
                GenerationInfo.BoxSizeZ);

   // Set the pixel size.
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_PIXEL_SIZE_X, GenerationInfo.PixelSizeX);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_PIXEL_SIZE_Y, GenerationInfo.PixelSizeY);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_GRAY_LEVEL_SIZE_Z, GenerationInfo.GrayScaleZ);

   // Set extraction properties.
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_EXTRACTION_CUMULATIVE, M_DISABLE);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_FILL_MODE, M_X_THEN_Y);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_FILL_SHARP_ELEVATION, M_DISABLE);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_FILL_THRESHOLD_X, GenerationInfo.FillXThreshold);
   M3dmapControl(PointCloudContainer, M_DEFAULT, M_FILL_THRESHOLD_Y, GenerationInfo.FillYThreshold);

   if (GenerationInfo.SetExtractOverlap)
      M3dmapControl(PointCloudContainer, M_GENERAL, M_EXTRACTION_OVERLAP, GenerationInfo.ExtractOverlap);

   // Generate the depth map.
   M3dmapExtract(PointCloudContainer, OutDepthmap, M_NULL, M_CORRECTED_DEPTH_MAP, M_ALL, M_DEFAULT);
   }

//////////////////////////////////////////////////////////
/* Check for required files for running the example.    */
//////////////////////////////////////////////////////////
bool CheckForRequiredMILFile(MIL_CONST_TEXT_PTR FileName)
   {
   MIL_INT FilePresent;

   MappFileOperation(M_DEFAULT, FileName, M_NULL, M_NULL, M_FILE_EXISTS, M_DEFAULT, &FilePresent);
   if (FilePresent == M_NO)
      {
      MosPrintf(MIL_TEXT("\n")
                MIL_TEXT("The footage needed to run this example is missing. You need \n")
                MIL_TEXT("to obtain and apply a separate specific update to have it.\n\n"));

      MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
      MosGetch();
      }

   return (FilePresent == M_YES);
   }