Click here to show toolbars of the Web Online Help System: show toolbars |
//*************************************************************************************** // // File name: ExampleManager.cpp // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This file contains the implementation of the CExampleMngr class that // manages the different inspection tasks defined from a specific example. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved #include <mil.h> #include <math.h> #include "ExampleManager.h" #include "../InspectionTaskBase/InspectionTask.h" //***************************************************************************** // Constants. //***************************************************************************** static const MIL_INT MAX_DISPLAY_SIZE_Y = 1080; static const MIL_INT SAMPLES_BORDER_Y = 10; static const MIL_INT VIEW_BORDER_X = 40; static const MIL_INT NB_ARROW_POINT = 7; static const MIL_DOUBLE ARROW_X[NB_ARROW_POINT] = { 5, 25, 25, 35, 25, 25, 5 }; static const MIL_DOUBLE ARROW_Y[NB_ARROW_POINT] = { -5, -5, -10, 0, 10, 5, 5 }; // Change this to have more samples per display. static const MIL_INT MAX_SAMPLES_PER_GROUP = 1; // The point size of the scale 1:1 display. static const MIL_DOUBLE DEFAULT_TITLE_POINT_SIZE = 20; static const MIL_DOUBLE DEFAULT_TEXT_POINT_SIZE = 14; // The font to used for the title. static MIL_CONST_TEXT_PTR TITLE_FONT = M_FONT_DEFAULT_TTF; static MIL_CONST_TEXT_PTR TEXT_FONT = M_FONT_DEFAULT_TTF; //***************************************************************************** // Mouse Callbacks //***************************************************************************** MIL_INT MFTYPE MouseMoveFunc(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr) { CExampleMngr *pExampleMngr = (CExampleMngr*) UserDataPtr; // Get the mouse position. MIL_DOUBLE PosX, PosY; MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_X, &PosX); MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_Y, &PosY); // Select the image as the hovered. pExampleMngr->SetHoverImageAt(PosX, PosY); return 0; } MIL_INT MFTYPE MouseLeftClickFunc(MIL_INT HookType, MIL_ID EventID, void* UserDataPtr) { CExampleMngr *pExampleMngr = (CExampleMngr*) UserDataPtr; // Get the mouse position. MIL_DOUBLE PosX, PosY; MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_X, &PosX); MdispGetHookInfo(EventID, M_MOUSE_POSITION_BUFFER_Y, &PosY); // Select the the image as the currently selected. pExampleMngr->SetSelectedImageAt(PosX, PosY); return 0; } //***************************************************************************** // Constructor. //***************************************************************************** CExampleMngr::CExampleMngr(MIL_ID MilSystem) : m_MilSystem (MilSystem), m_MilDisplay (M_NULL), m_MilGraList (M_NULL), m_MilGraGraphicContext (M_NULL), m_MilGraTextContext (M_NULL), m_MilGraSingleContext (M_NULL), m_MilGraSingleTextContext (M_NULL), m_MilGraTitleContext (M_NULL), m_MilViewChildArray (NULL), m_MilDisplayImage (M_NULL), m_MilSingleDisplay (M_NULL), m_MilSingleDisplayChild (M_NULL), m_NbSamplesToInspect (0), m_CurProductInfo (NULL), m_HoverLabel (0), m_SelectedLabel (0), m_CurrentGroupIdx (0) { // Allocate the display. MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &m_MilDisplay); MdispControl(m_MilDisplay, M_SCALE_DISPLAY, M_ENABLE); // Allocate a single display. MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &m_MilSingleDisplay); // Allocate a graphics list to be associated on the display. MgraAllocList(MilSystem, M_DEFAULT, &m_MilGraList); MgraAllocList(MilSystem, M_DEFAULT, &m_MilSingleGraList); MdispControl(m_MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, m_MilGraList); MdispControl(m_MilSingleDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, m_MilSingleGraList); // Allocate a graphic context for the graphic results annotations. MgraAlloc(MilSystem, &m_MilGraGraphicContext); MgraAlloc(MilSystem, &m_MilGraSingleContext); // Allocate a graphic context for the text annotation. MgraAlloc(MilSystem, &m_MilGraTextContext); MgraAlloc(MilSystem, &m_MilGraSingleTextContext); MgraAlloc(MilSystem, &m_MilGraTitleContext); // Set the text graphic context. MgraFont(m_MilGraTextContext, MIL_FONT_NAME(TEXT_FONT)); MgraFont(m_MilGraSingleTextContext, MIL_FONT_NAME(TEXT_FONT)); MgraControl(m_MilGraSingleTextContext, M_FONT_SIZE, DEFAULT_TEXT_POINT_SIZE); MgraColor(m_MilGraTitleContext, M_COLOR_DARK_GREEN); MgraFont(m_MilGraTitleContext, MIL_FONT_NAME(TEXT_FONT)); MgraControl(m_MilGraTitleContext, M_TEXT_ALIGN_HORIZONTAL, M_CENTER); MgraControl(m_MilGraTitleContext, M_DRAW_OFFSET_Y, -SAMPLES_BORDER_Y); } //***************************************************************************** // Destructor. //***************************************************************************** CExampleMngr::~CExampleMngr() { // Reset the tasks. ResetTasks(); // Reset the images. ResetImages(); // Free the graphic contexts. MgraFree(m_MilGraGraphicContext); MgraFree(m_MilGraSingleContext); MgraFree(m_MilGraTextContext); MgraFree(m_MilGraSingleTextContext); MgraFree(m_MilGraTitleContext); // Free the graphics lists. MgraFree(m_MilGraList); MgraFree(m_MilSingleGraList); // Free the displays. MdispFree(m_MilDisplay); MdispFree(m_MilSingleDisplay); } //***************************************************************************** // Main run function. //***************************************************************************** void CExampleMngr::Run(SProductInfo* ProductsInfoList, MIL_INT NbProduct) { // For each types of product. for(MIL_INT ProductIdx = 0; ProductIdx < NbProduct; ProductIdx++) { // Reset the inspection for the new product. ResetInspection(ProductsInfoList[ProductIdx]); for(MIL_INT GroupIdx = 0, SampleIdx =0; GroupIdx < GetNbGroups(); GroupIdx++) { // Load the groups images. LoadGroupImages(GroupIdx); for(MIL_INT DispSampleIdx = 0; DispSampleIdx < GetNbSamples(GroupIdx); DispSampleIdx++, SampleIdx++) { // Disable display updates. MdispControl(m_MilDisplay, M_UPDATE, M_DISABLE); // Print message. MosPrintf(MIL_TEXT("Inspecting sample %i.\n\n"), (int) SampleIdx); // Inspect the products. InspectProducts(DispSampleIdx); // Draw the results. DrawResults(DispSampleIdx); // Print message. MosPrintf(MIL_TEXT("The results of sample %i are displayed.\n\n"), (int) SampleIdx); // Enable the display updates. MdispControl(m_MilDisplay, M_UPDATE, M_ENABLE); } // Enable the display hooks. EnableDisplayHooks(); // Wait for the user input. MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); // Disable the display hooks. DisableDisplayHooks(); } } } //***************************************************************************** // Function that resets the images. //***************************************************************************** void CExampleMngr::ResetImages() { if(m_MilDisplayImage) { for(MIL_INT SampleIdx = 0; SampleIdx < m_NbSamplesPerGroup; SampleIdx++) { // Free all the childs. for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { MbufFree(m_MilViewChildArray[SampleIdx][ViewIdx].MilChild); MgraFree(m_MilViewChildArray[SampleIdx][ViewIdx].MilGraList); MgraFree(m_MilViewChildArray[SampleIdx][ViewIdx].MilGraTextList); } // Delete the child array. delete [] m_MilViewChildArray[SampleIdx]; } // Delete the pointers to the arrays. delete [] m_MilViewChildArray; // Free the displays images. MbufFree(m_MilDisplayImage); m_MilDisplayImage = M_NULL; MbufFree(m_MilSingleDisplayChild); MbufFree(m_MilSingleDisplayImage); } } //***************************************************************************** // Function that resets the tasks. //***************************************************************************** void CExampleMngr::ResetTasks() { if(m_CurProductInfo) { for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the current view task list. SImageTaskList &rViewTaskList = m_CurProductInfo->ImageTasksListArray[ViewIdx]; // Deallocates the tasks. Do it in reverse order to free the child before the parents. for(MIL_INT TaskIdx = rViewTaskList.NbTasks-1; TaskIdx >=0 ; TaskIdx--) { rViewTaskList.TaskList[TaskIdx]->Free(); } } } } //***************************************************************************** // Function that initializes the tasks. //***************************************************************************** void CExampleMngr::InitializeTasks() { // Initialize the tasks. for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the current view task list. SImageTaskList &rViewTaskList = m_CurProductInfo->ImageTasksListArray[ViewIdx]; // Initialize the task. for(MIL_INT TaskIdx = 0; TaskIdx < rViewTaskList.NbTasks; TaskIdx++) { rViewTaskList.TaskList[TaskIdx]->Init(m_MilSystem, m_MilViewChildArray[0][ViewIdx].SizeX, m_MilViewChildArray[0][ViewIdx].SizeY); } } } //***************************************************************************** // Function that initialize the display images. //***************************************************************************** void CExampleMngr::InitializeDisplayImages() { // Get the number of products to inspect. m_NbSamplesToInspect = MbufDiskInquire(m_CurProductInfo->ViewAviFilePathArray[0], M_NUMBER_OF_IMAGES, M_NULL); // Reset the size of the display grid. m_DisplaySizeX = VIEW_BORDER_X; m_DisplayGridSizeY = 0; m_DisplayGridTextSizeY = 0; m_DisplayGridImageSizeY = 0; // Calculate the parameters of the display. for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Calculate the size of the text for the view. MIL_INT TextSizeY = m_CurProductInfo->ImageTasksListArray[ViewIdx].NbTasks * RESULT_TEXT_LINE_SPACING_Y; // Get the current size of the view. MIL_INT CurSizeX = MbufDiskInquire(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_SIZE_X, M_NULL); MIL_INT CurSizeY = MbufDiskInquire(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_SIZE_Y, M_NULL); // Update the display size info. m_DisplayGridTextSizeY = (TextSizeY > m_DisplayGridTextSizeY) ? TextSizeY : m_DisplayGridTextSizeY ; m_DisplayGridImageSizeY = (CurSizeY > m_DisplayGridImageSizeY) ? CurSizeY : m_DisplayGridImageSizeY; m_DisplaySizeX += CurSizeX + VIEW_BORDER_X; } // Set the size of the grid in Y. m_DisplayGridSizeY = m_DisplayGridTextSizeY + m_DisplayGridImageSizeY + 2 * SAMPLES_BORDER_Y; // Calculate the nb of samples per group processed. m_NbSamplesPerGroup = (MIL_INT)((MIL_DOUBLE)(MAX_DISPLAY_SIZE_Y-SAMPLES_BORDER_Y) / (m_DisplayGridSizeY)); m_NbSamplesPerGroup = m_NbSamplesPerGroup > m_NbSamplesToInspect ? m_NbSamplesToInspect : m_NbSamplesPerGroup; m_NbSamplesPerGroup = m_NbSamplesPerGroup > MAX_SAMPLES_PER_GROUP ? MAX_SAMPLES_PER_GROUP : m_NbSamplesPerGroup; if(m_NbSamplesPerGroup == 0) { m_NbSamplesPerGroup = 1; } // Allocate the number samples. m_MilViewChildArray = new SViewChildInfo*[m_NbSamplesPerGroup]; // Set the display size Y. m_DisplaySizeY = (m_DisplayGridSizeY * m_NbSamplesPerGroup) + 2 * SAMPLES_BORDER_Y + TITLE_LINE_SPACING_Y; // Allocate the display image. MbufAllocColor(m_MilSystem, 3, m_DisplaySizeX, m_DisplaySizeY, 8+M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &m_MilDisplayImage); MbufClear(m_MilDisplayImage, M_COLOR_BLACK); MbufAllocColor(m_MilSystem, 3, m_DisplaySizeX, m_DisplaySizeY, 8+M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &m_MilSingleDisplayImage); MbufClear(m_MilSingleDisplayImage, M_COLOR_BLACK); MbufChild2d(m_MilSingleDisplayImage, 0, 0, 1, 1, &m_MilSingleDisplayChild); // For all the childs set the offset and allocate the child. for(MIL_INT SampleIdx = 0, CurrentOffsetY = 2 * SAMPLES_BORDER_Y + TITLE_LINE_SPACING_Y; SampleIdx < m_NbSamplesPerGroup; SampleIdx++, CurrentOffsetY += m_DisplayGridSizeY) { // Allocate the child info structures. m_MilViewChildArray[SampleIdx] = new SViewChildInfo[m_CurProductInfo->NbViews]; for(MIL_INT ViewIdx = 0, CurrentOffsetX = VIEW_BORDER_X; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get the current size of the view. MIL_INT CurSizeX = MbufDiskInquire(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_SIZE_X, M_NULL); MIL_INT CurSizeY = MbufDiskInquire(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_SIZE_Y, M_NULL); // Get a reference to the structure. SViewChildInfo &rChildInfo = m_MilViewChildArray[SampleIdx][ViewIdx]; // Set the child information and allocate it. rChildInfo.SizeX = CurSizeX; rChildInfo.SizeY = CurSizeY; rChildInfo.OffsetX = CurrentOffsetX; rChildInfo.OffsetY = CurrentOffsetY; rChildInfo.RealOffsetY = CurrentOffsetY + (m_DisplayGridImageSizeY - CurSizeY)/2; CurrentOffsetX += CurSizeX + VIEW_BORDER_X; MbufChild2d(m_MilDisplayImage, rChildInfo.OffsetX, rChildInfo.RealOffsetY, rChildInfo.SizeX, rChildInfo.SizeY, &rChildInfo.MilChild); MgraAllocList(m_MilSystem, M_DEFAULT, &rChildInfo.MilGraList); MgraAllocList(m_MilSystem, M_DEFAULT, &rChildInfo.MilGraTextList); } } } //***************************************************************************** // Function that sets the rectangle of the views. //***************************************************************************** void CExampleMngr::SetImageRect() { for(MIL_INT SampleIdx = 0; SampleIdx < GetNbSamples(m_CurrentGroupIdx); SampleIdx++) { for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the structure. SViewChildInfo &rChildInfo = m_MilViewChildArray[SampleIdx][ViewIdx]; // Draw the rectangle in the graphics list. MgraColor(M_DEFAULT, M_COLOR_WHITE); MgraControl(M_DEFAULT, M_DRAW_OFFSET_X, 0.0); MgraControl(M_DEFAULT, M_DRAW_OFFSET_Y, 0.0); MgraRect(M_DEFAULT, m_MilGraList, rChildInfo.OffsetX, rChildInfo.RealOffsetY, rChildInfo.OffsetX + rChildInfo.SizeX, rChildInfo.RealOffsetY + rChildInfo.SizeY); MgraInquireList(m_MilGraList, M_LIST, M_DEFAULT, M_LAST_LABEL + M_TYPE_MIL_INT, &rChildInfo.GraRectLabel); } } } //***************************************************************************** // Function that loads the group images. //***************************************************************************** void CExampleMngr::LoadGroupImages(MIL_INT GroupIdx) { // Enable the display updates. MdispControl(m_MilDisplay, M_UPDATE, M_DISABLE); // Clear the display. MbufClear(m_MilDisplayImage, 0); MbufClear(m_MilSingleDisplayImage, 0); MgraClear(M_DEFAULT, m_MilGraList); // Draw the views titles. DrawViewsTitles(); // Reset the hover and selected labels. m_HoverLabel = -1; m_SelectedLabel = -1; // Clear the single graphics list. for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { for(MIL_INT DispSampleIdx = 0; DispSampleIdx < m_NbSamplesPerGroup ; DispSampleIdx++) { MgraClear(M_DEFAULT, m_MilViewChildArray[DispSampleIdx][ViewIdx].MilGraList); MgraClear(M_DEFAULT, m_MilViewChildArray[DispSampleIdx][ViewIdx].MilGraTextList); } } // Set the current group index. m_CurrentGroupIdx = GroupIdx; // Set the images rectangles. SetImageRect(); for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Open the sequence. MbufImportSequence(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_DEFAULT, M_NULL, M_NULL, M_NULL, M_NULL, M_NULL, M_OPEN); for(MIL_INT DispSampleIdx = 0, SampleIdx = m_NbSamplesPerGroup * GroupIdx; DispSampleIdx < m_NbSamplesPerGroup && SampleIdx < m_NbSamplesToInspect; DispSampleIdx++, SampleIdx++) { // Get the image from the sequence. MbufImportSequence(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_DEFAULT, M_LOAD, M_NULL, &m_MilViewChildArray[DispSampleIdx][ViewIdx].MilChild, SampleIdx, 1, M_READ); } // Close the sequence. MbufImportSequence(m_CurProductInfo->ViewAviFilePathArray[ViewIdx], M_DEFAULT, M_NULL, M_NULL, M_NULL, M_NULL, M_NULL, M_CLOSE); } // Enable the display updates. MdispControl(m_MilDisplay, M_UPDATE, M_DISABLE); } //***************************************************************************** // Function that resets the inspection using a new product information. //***************************************************************************** void CExampleMngr::ResetInspection(SProductInfo &ProductInfo) { // Print message. MosPrintf(MIL_TEXT("Setting up the inspection of the product...\n\n")); // Reset the previously used tasks. ResetTasks(); // Reset the images. ResetImages(); // Get a pointer to the new product info. m_CurProductInfo = &ProductInfo; // Initialize the display. InitializeDisplayImages(); // Select the display image on the display. MdispSelect(m_MilDisplay, m_MilDisplayImage); // Calculate the display scale factor. CalculateDisplayScaleFactor(); // Initialize the tasks. InitializeTasks(); } //***************************************************************************** // Function that resets the inspection using a new product information. //***************************************************************************** void CExampleMngr::EnableDisplayHooks() { // Put the callbacks on the display. MdispHookFunction(m_MilDisplay, M_MOUSE_MOVE, MouseMoveFunc, (void*)this); MdispHookFunction(m_MilDisplay, M_MOUSE_LEFT_BUTTON_UP, MouseLeftClickFunc, (void*)this); } //***************************************************************************** // Function that resets the inspection using a new product information. //***************************************************************************** void CExampleMngr::DisableDisplayHooks() { // Remove the callbacks on the display. MdispHookFunction(m_MilDisplay, M_MOUSE_MOVE + M_UNHOOK, MouseMoveFunc, (void*)this); MdispHookFunction(m_MilDisplay, M_MOUSE_LEFT_BUTTON_UP + M_UNHOOK, MouseLeftClickFunc, (void*)this); // Deselect the single display. if(MdispInquire(m_MilSingleDisplay, M_SELECTED, M_NULL)) { MdispSelect(m_MilSingleDisplay, M_NULL); } } //***************************************************************************** // Function that inspects the products. //***************************************************************************** void CExampleMngr::InspectProducts(MIL_INT SampleIdx) { for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the task list. SImageTaskList &rTaskList = m_CurProductInfo->ImageTasksListArray[ViewIdx]; // Perform all the task for the given product. for(MIL_INT TaskIdx = 0; TaskIdx < rTaskList.NbTasks; TaskIdx++) rTaskList.TaskList[TaskIdx]->InspectImage(m_MilViewChildArray[SampleIdx][ViewIdx].MilChild); } } //***************************************************************************** // Function that draws the results. //***************************************************************************** void CExampleMngr::DrawResults(MIL_INT SampleIdx) { for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the task list. SImageTaskList &rTaskList = m_CurProductInfo->ImageTasksListArray[ViewIdx]; // Get a reference to the child info structure. SViewChildInfo &rChildInfo = m_MilViewChildArray[SampleIdx][ViewIdx]; // Set the text offset and the point size according to the size of the display. MgraControl(m_MilGraTextContext, M_FONT_SIZE, DEFAULT_TEXT_POINT_SIZE * m_DisplayScaleFactor); MgraControl(m_MilGraTextContext, M_DRAW_OFFSET_X, (MIL_DOUBLE)-(rChildInfo.OffsetX + 5)); MgraControl(m_MilGraTextContext, M_DRAW_OFFSET_Y, (MIL_DOUBLE)-(rChildInfo.RealOffsetY + rChildInfo.SizeY + SAMPLES_BORDER_Y)); // Set the text offset. MgraControl(m_MilGraSingleTextContext, M_DRAW_OFFSET_X, -5.0); MgraControl(m_MilGraSingleTextContext, M_DRAW_OFFSET_Y, (MIL_DOUBLE)-(rChildInfo.SizeY + SAMPLES_BORDER_Y)); // Set the drawing offset of the graphic context. MgraControl(m_MilGraGraphicContext, M_DRAW_OFFSET_X, (MIL_DOUBLE)(-rChildInfo.OffsetX)); MgraControl(m_MilGraGraphicContext, M_DRAW_OFFSET_Y, (MIL_DOUBLE)(-rChildInfo.RealOffsetY)); // Set the drawing offset of the graphic context. MgraControl(m_MilGraSingleContext, M_DRAW_OFFSET_X, 0.0); MgraControl(m_MilGraSingleContext, M_DRAW_OFFSET_Y, 0.0); // Draw the graphical results of all the tasks. for(MIL_INT TaskIdx = 0; TaskIdx < rTaskList.NbTasks; TaskIdx++) { // Draw the graphical result. rTaskList.TaskList[TaskIdx]->DrawInspectionGraphicalResult(m_MilGraGraphicContext, m_MilGraList); rTaskList.TaskList[TaskIdx]->DrawInspectionGraphicalResult(m_MilGraSingleContext, rChildInfo.MilGraList); // Draw the text result in the graphics list. rTaskList.TaskList[TaskIdx]->DrawTextResult(m_MilGraTextContext, m_MilGraList); rTaskList.TaskList[TaskIdx]->DrawTextResult(m_MilGraSingleTextContext, rChildInfo.MilGraTextList); } // Draw the arrow if necessary. if(m_CurProductInfo->ViewsType == enSequential && ViewIdx < m_CurProductInfo->NbViews-1) { MgraControl(M_DEFAULT, M_DRAW_OFFSET_X, (MIL_DOUBLE)-(rChildInfo.OffsetX + rChildInfo.SizeX)); MgraControl(M_DEFAULT, M_DRAW_OFFSET_Y, (MIL_DOUBLE)-(rChildInfo.RealOffsetY + rChildInfo.SizeY / 2)); DrawArrow(); } } } //***************************************************************************** // Function that draws the arrow between the views. //***************************************************************************** void CExampleMngr::DrawArrow() { MgraColor(M_DEFAULT, M_COLOR_DARK_GREEN); MgraLines(M_DEFAULT, m_MilGraList, NB_ARROW_POINT, ARROW_X, ARROW_Y, M_NULL, M_NULL, M_POLYGON + M_FILLED); } //***************************************************************************** // Function that draws the title of each view. //***************************************************************************** void CExampleMngr::DrawViewsTitles() { // Set the graphic context to draw the title text. MgraControl(m_MilGraTitleContext, M_FONT_SIZE, (MIL_DOUBLE)DEFAULT_TITLE_POINT_SIZE * m_DisplayScaleFactor); for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { // Get a reference to the structure. SViewChildInfo &rChildInfo = m_MilViewChildArray[0][ViewIdx]; // Draw the title of the inspection. MgraText(m_MilGraTitleContext, m_MilGraList, rChildInfo.OffsetX + rChildInfo.SizeX/2, 0, m_CurProductInfo->ImageTasksListArray[ViewIdx].TaskTitle); } } //***************************************************************************** // Function that calculates the display scale factor. //***************************************************************************** void CExampleMngr::CalculateDisplayScaleFactor() { MIL_INT DisplayAreaSizeX = MdispInquire(m_MilDisplay, M_SIZE_X, M_NULL); MIL_INT DisplayAreaSizeY = MdispInquire(m_MilDisplay, M_SIZE_Y, M_NULL); if(DisplayAreaSizeX == m_DisplaySizeX) m_DisplayScaleFactor = (MIL_DOUBLE)DisplayAreaSizeY / m_DisplaySizeY; else m_DisplayScaleFactor = (MIL_DOUBLE)DisplayAreaSizeX / m_DisplaySizeX; } //***************************************************************************** // Function that gets the number of groups of a given product. //***************************************************************************** MIL_INT CExampleMngr::GetNbGroups() const { // Gets the number of groups of a given product. return (MIL_INT)ceil((MIL_DOUBLE)m_NbSamplesToInspect / m_NbSamplesPerGroup); } //***************************************************************************** // Function that gets the number of samples of a given group. //***************************************************************************** MIL_INT CExampleMngr::GetNbSamples(MIL_INT GroupIdx) const { MIL_INT NbSamplesLeft = m_NbSamplesToInspect - GroupIdx * m_NbSamplesPerGroup; // Gets the number of samples for a given group. return NbSamplesLeft < m_NbSamplesPerGroup ? NbSamplesLeft : m_NbSamplesPerGroup; } //***************************************************************************** // Mouse interaction functions. //***************************************************************************** void CExampleMngr::SetHoverImageAt(MIL_DOUBLE PosX, MIL_DOUBLE PosY) { const SViewChildInfo *pViewChild = GetViewOfPos(PosX, PosY); if(pViewChild) { // Uncomment to display selected in green. /*if(pViewChild->GraRectLabel == m_SelectedLabel) ResetSpecialLabel(&m_HoverLabel, -1, M_COLOR_YELLOW); else */ ResetSpecialLabel(&m_HoverLabel, pViewChild->GraRectLabel, M_COLOR_YELLOW); } else ResetSpecialLabel(&m_HoverLabel, -1, M_COLOR_YELLOW); } void CExampleMngr::SetSelectedImageAt(MIL_DOUBLE PosX, MIL_DOUBLE PosY) { MIL_INT ViewIdx; const SViewChildInfo *pViewChild = GetViewOfPos(PosX, PosY, &ViewIdx); if(pViewChild) { // Update the display. UpdateSingleDisplay(pViewChild, ViewIdx); ResetSpecialLabel(&m_SelectedLabel, pViewChild->GraRectLabel, M_COLOR_WHITE); if(m_SelectedLabel == m_HoverLabel) m_HoverLabel = -1; } } void CExampleMngr::ResetSpecialLabel(MIL_INT* pCurrentLabel, MIL_INT NewLabel, MIL_INT Color) { // If the label status has changed. if(*pCurrentLabel != NewLabel) { // If the current label exist, reset it to white. if(*pCurrentLabel != -1) MgraControlList(m_MilGraList, M_GRAPHIC_LABEL(*pCurrentLabel), M_DEFAULT, M_COLOR, M_COLOR_WHITE); // If the new label exists, put it to the new color. if(NewLabel != -1) MgraControlList(m_MilGraList, M_GRAPHIC_LABEL(NewLabel), M_DEFAULT, M_COLOR, Color); *pCurrentLabel = NewLabel; } } const SViewChildInfo* CExampleMngr::GetViewOfPos(MIL_DOUBLE PosX, MIL_DOUBLE PosY, MIL_INT *pViewIdx /* = NULL */) { for(MIL_INT SampleIdx = 0; SampleIdx < GetNbSamples(m_CurrentGroupIdx); SampleIdx ++) { for(MIL_INT ViewIdx = 0; ViewIdx < m_CurProductInfo->NbViews; ViewIdx++) { SViewChildInfo &rChildInfo = m_MilViewChildArray[SampleIdx][ViewIdx]; if(PosX >= rChildInfo.OffsetX && PosX <= (rChildInfo.OffsetX + rChildInfo.SizeX - 1) && PosY >= rChildInfo.RealOffsetY && PosY <= (rChildInfo.RealOffsetY + rChildInfo.SizeY - 1)) { if(pViewIdx) { *pViewIdx = ViewIdx; } return &rChildInfo; } } } return NULL; } //***************************************************************************** // Function that updates the single display. //***************************************************************************** void CExampleMngr::UpdateSingleDisplay(const SViewChildInfo *pViewChild, MIL_INT ViewIdx) { // Disable the display updates. MdispControl(m_MilSingleDisplay, M_UPDATE, M_DISABLE); // Deselect the image. if(MdispInquire(m_MilSingleDisplay, M_SELECTED, M_NULL)) MdispSelect(m_MilSingleDisplay, M_NULL); // Move the child. MbufChildMove(m_MilSingleDisplayChild, pViewChild->OffsetX, pViewChild->RealOffsetY, pViewChild->SizeX, pViewChild->SizeY + m_DisplayGridTextSizeY + SAMPLES_BORDER_Y, M_DEFAULT); // Copy the child. MbufCopy(pViewChild->MilChild, m_MilSingleDisplayChild); // Set the graphics list. MdispControl(m_MilSingleDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, pViewChild->MilGraList); // Draw the text in the child. MgraDraw(pViewChild->MilGraTextList, m_MilSingleDisplayChild, M_DEFAULT); // Select the child. MdispSelect(m_MilSingleDisplay, m_MilSingleDisplayChild); // Enable the display updates. MdispControl(m_MilSingleDisplay, M_UPDATE, M_ENABLE); }