1. 优化SIdeDimensionSetting表格的读取
2. 优化侧面检的功能,从固定的36个检测点变更为自己设置
已修改9个文件
851 ■■■■ 文件已修改
EdgeInspector_App/DlgSideDimensionSetting.cpp 372 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/DlgSideDimensionSetting.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Process/InspectCamera.cpp 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Process/InspectCamera.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/View/EdgeImageViewer.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/ViewMain_Recipe.cpp 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SDK/VisionMeasure/include/VisionMeasureClass.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
VisionMeasure/VisionMeasureClass.cpp 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
VisionMeasure/VisionMeasureClass.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/DlgSideDimensionSetting.cpp
@@ -53,52 +53,98 @@
void CDlgSideDimensionSetting::SetDlgRecipe(CGlassRecipe* pDlgRecipe)
{
    m_pDlgRecipe = pDlgRecipe;
    UpdateRecipe(FALSE);
}
void CDlgSideDimensionSetting::UpdateRecipe(BOOL bGetData)
{
    // Title
    if(m_pSelectSideIdx != NULL)
    if(bGetData == FALSE) {
        Fill_SideDimensionSetting(bGetData);
        Fill_TopCornerDimensionSetting(bGetData);
        Fill_BotCornerDimensionSetting(bGetData);
    }
    else {
        Fill_SideDimensionSetting(bGetData);
        Fill_TopCornerDimensionSetting(bGetData);
        Fill_BotCornerDimensionSetting(bGetData);
    }
}
void CDlgSideDimensionSetting::RefreshSideUI(BOOL bReinitGrid /*=TRUE*/)
    {
    if (!m_pSelectSideIdx) {
        return;
    }
    const int nSideIdx = *m_pSelectSideIdx;
    const DimensionDir eDim = (DimensionDir)nSideIdx;
    m_bIsRipSide = (DIMENSION_A_RIP == eDim) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim);
        CString strTemp;
        strTemp.Format(_T("[%s] Dim. Setting"), g_SideName[(int) *(m_pSelectSideIdx)]);
    strTemp.Format(_T("[%s] Dim. Setting"), g_SideName[nSideIdx]);
        SetDlgItemText(IDC_STATIC_TITLE, strTemp);
        strTemp.Format(_T("Top Corner [%s] Dim. Setting"), g_SideName[(int) *(m_pSelectSideIdx)]);
    strTemp.Format(_T("Top Corner [%s] Dim. Setting"), g_SideName[nSideIdx]);
        SetDlgItemText(IDC_STATIC_TITLE_TOP_CORNER, strTemp);
        strTemp.Format(_T("Bot Corner [%s] Dim. Setting"), g_SideName[(int) *(m_pSelectSideIdx)]);
    strTemp.Format(_T("Bot Corner [%s] Dim. Setting"), g_SideName[nSideIdx]);
        SetDlgItemText(IDC_STATIC_TITLE_BOT_CORNER, strTemp);
    if (CWnd* p = GetDlgItem(IDC_BUTTON_CAL)) {
        p->EnableWindow(!m_bIsRipSide);
    }
    if(bGetData == FALSE)
    {
        Fill_SideDimensionSetting(bGetData);
        Fill_TopCornerDimensionSetting(bGetData);
        Fill_BotCornerDimensionSetting(bGetData);
    if (CWnd* p = GetDlgItem(IDC_BUTTON_GET_SIDE_RESULT)) {
        p->EnableWindow(!m_bIsRipSide);
    }
    else
    {
        Fill_SideDimensionSetting(bGetData);
        Fill_TopCornerDimensionSetting(bGetData);
        Fill_BotCornerDimensionSetting(bGetData);
    if (bReinitGrid) {
        Init_SideDimensionSetting();
    }
}
void CDlgSideDimensionSetting::Init_SideDimensionSetting()
{
    if (m_SideDimensionSetting.GetSafeHwnd() == NULL)
    if (m_SideDimensionSetting.GetSafeHwnd() == NULL) {
        return;
    }
    int nRows = 1;
    int nCols = 9 + 3;
    if (m_pSelectSideIdx == nullptr) {
        return;
    }
    int nFixRows = 1;
    int nFixCols = 0;
    int nRowIdx = 0;
    int nColIdx = 0;
    auto ScaleX = [&](int px)->int {
        HDC hdc = ::GetDC(m_hWnd);
        const int dpi = GetDeviceCaps(hdc, LOGPIXELSX);
        ::ReleaseDC(m_hWnd, hdc);
        return MulDiv(px, dpi, 96);
    };
    struct ColDef { int w; LPCTSTR name; };
    static const ColDef kColsRip[] = {
        { 90, _T("No.") },
        { 100, _T("Start Line To Y(um)") },
        { 100, _T("Use Dim.") },
    };
    static const ColDef kColsNormal[] = {
        { 90, _T("No.") },
        { 70, _T("Top Mark To Y(um)") },
        { 70, _T("Use Dim.") },
        { 70, _T("Thres") },
        { 70, _T("Std(mm)") },
        { 70, _T("Min(mm)") },
        { 70, _T("Max(mm)") },
        { 70, _T("Off(mm)") },
        { 70, _T("Use Chamfer") },
        { 70, _T("Std(mm)") },
        { 70, _T("Min(mm)") },
        { 70, _T("Max(mm)") },
    };
    const ColDef* cols = m_bIsRipSide ? kColsRip : kColsNormal;
    const int nCols = m_bIsRipSide ? (int)_countof(kColsRip) : (int)_countof(kColsNormal);
    const int nRows = 1;
    const int nFixRows = 1;
    const int nFixCols = 0;
    m_SideDimensionSetting.DeleteAllItems();
    m_SideDimensionSetting.SetVirtualMode(FALSE);
@@ -112,15 +158,12 @@
    m_SideDimensionSetting.SetFixedRowCount(nFixRows);
    m_SideDimensionSetting.SetFixedColumnCount(nFixCols);
    CFont *pFont = m_SideDimensionSetting.GetFont();
    if (pFont)
    {
        LOGFONT lf;
        pFont->GetLogFont(&lf);
    if (CFont* pFont = m_SideDimensionSetting.GetFont()) {
        LOGFONT lf{}; pFont->GetLogFont(&lf);
        lf.lfItalic = 0;
        lf.lfHeight = 14;
        lf.lfWeight = FW_BOLD;
        _tcscpy_s(lf.lfFaceName, _T("Arial"));
        lf.lfHeight = 14;
        m_SideDimensionSetting.GetDefaultCell(FALSE, TRUE)->SetFont(&lf);
        m_SideDimensionSetting.GetDefaultCell(TRUE, FALSE)->SetFont(&lf);
@@ -128,31 +171,10 @@
        m_SideDimensionSetting.GetDefaultCell(TRUE, TRUE)->SetFont(&lf);
    }
    // Col
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 90);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("No."));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 100);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Top Mark To Y(um)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Use Dim."));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Thres"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Std(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Min(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Max(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Off(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Use Chamfer"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Std(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Min(mm)"));
    m_SideDimensionSetting.SetColumnWidth(nColIdx, 70);
    m_SideDimensionSetting.SetItemText(nRowIdx, nColIdx++, _T("Max(mm)"));
    for (int c = 0; c < nCols; ++c) {
        m_SideDimensionSetting.SetColumnWidth(c, ScaleX(cols[c].w));
        m_SideDimensionSetting.SetItemText(0, c, cols[c].name);
    }
    m_SideDimensionSetting.SetFixedRowSelection(FALSE);
    m_SideDimensionSetting.SetFixedColumnSelection(FALSE);
@@ -165,145 +187,147 @@
void CDlgSideDimensionSetting::Fill_SideDimensionSetting(BOOL bGetData)
{
    if(m_SideDimensionSetting.GetSafeHwnd() == NULL)
    if (m_SideDimensionSetting.GetSafeHwnd() == NULL) {
        return;
    }
    if(m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL)
    if (m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL) {
        return;
    }
    int nSideIdx = *(m_pSelectSideIdx);
    if(nSideIdx < 0 || eRcp_SideRD_End <=  nSideIdx)
    if (nSideIdx < 0 || nSideIdx >= eRcp_SideRD_End) {
        return;
    }
    int c = 0;
    const int COL_NO = c++;
    const int COL_TOPMARK_Y = c++;
    const int COL_USE_DIM = c++;
    int COL_THRES = -1, COL_STD = -1, COL_MIN = -1, COL_MAX = -1, COL_OFF = -1;
    int COL_CHAMFER_USE = -1, COL_CH_STD = -1, COL_CH_MIN = -1, COL_CH_MAX = -1;
    if (!m_bIsRipSide) {
        COL_THRES = c++;
        COL_STD = c++;
        COL_MIN = c++;
        COL_MAX = c++;
        COL_OFF = c++;
        COL_CHAMFER_USE = c++;
        COL_CH_STD = c++;
        COL_CH_MIN = c++;
        COL_CH_MAX = c++;
    }
    // 单元格读写封装
    auto SetCell = [&](int r, int col, LPCTSTR s) { m_SideDimensionSetting.SetItemText(r, col, s); };
    auto SetCellInt = [&](int r, int col, int v) { CString t; t.Format(_T("%d"), v); SetCell(r, col, t); };
    auto SetCellDouble = [&](int r, int col, double v, int prec = 3) { CString t; t.Format(_T("%.*f"), prec, v); SetCell(r, col, t); };
    auto SetCellBool = [&](int r, int col, BOOL b) { CString t; t.Format(_T("%d"), b ? 1 : 0); SetCell(r, col, t); };
    auto GetCellStr = [&](int r, int col)->CString { CString s = m_SideDimensionSetting.GetItemText(r, col); s.Trim(); return s; };
    auto GetCellInt = [&](int r, int col, int def = 0)->int { CString s = GetCellStr(r, col); return s.IsEmpty() ? def : _wtoi(s); };
    auto GetCellDouble = [&](int r, int col, double def = 0.0)->double { CString s = GetCellStr(r, col); return s.IsEmpty() ? def : _wtof(s); };
    auto GetCellBool = [&](int r, int col)->BOOL { return GetCellInt(r, col, 0) ? TRUE : FALSE; };
    m_SideDimensionSetting.SetRedraw(FALSE);
    CSIDE_PARM* pParam = &m_pDlgRecipe->m_SideParam[nSideIdx];
    CString strTemp;
    int nRow = 0;
    int nCol = 0;
    if(bGetData == FALSE)
    {
        int nDimensionCount = pParam->m_nSideDimensionCount;
    if (!bGetData) {
        const int nDimensionCount = max(0, min(pParam->m_nSideDimensionCount, MAX_SIDE_DIMENSION_MEASURE_COUNT));
        m_SideDimensionSetting.SetRowCount(nDimensionCount + 1);
        for(int i=0; i<nDimensionCount; i++)
        {
            nRow = i + 1;
            nCol = 0;
        for (int i = 0; i < nDimensionCount; ++i) {
            const int r = i + 1;
            // 1. No.
            strTemp.Format(_T("S_D/C_%d"), i + 1);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 1) No.
            CString no; no.Format(_T("S_D/C_%d"), i + 1);
            SetCell(r, COL_NO, no);
            // 2. Top Mark To Distance Y (um)
            strTemp.Format(_T("%d"), pParam->m_nSideDimensionPos_TopMarkToDistance_um[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 2) Top Mark To Distance Y (um)
            SetCellInt(r, COL_TOPMARK_Y, pParam->m_nSideDimensionPos_TopMarkToDistance_um[i]);
            // 3. Use Dimension
            strTemp.Format(_T("%d"), (int) pParam->m_bSideDimension_Use[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 3) Use Dimension (0/1)
            SetCellBool(r, COL_USE_DIM, pParam->m_bSideDimension_Use[i]);
            // 4. Thres
            strTemp.Format(_T("%.d"), pParam->m_nSideDimensionSpec_Thres[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            if (!m_bIsRipSide) {
                // 4) Thres
                SetCellInt(r, COL_THRES, pParam->m_nSideDimensionSpec_Thres[i]);
            // 5. Std
            strTemp.Format(_T("%.3f"), pParam->m_dSideDimensionSpec_mm_Std[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
                // 5-7) Std/Min/Max
                SetCellDouble(r, COL_STD, pParam->m_dSideDimensionSpec_mm_Std[i]);
                SetCellDouble(r, COL_MIN, pParam->m_dSideDimensionSpec_mm_Min[i]);
                SetCellDouble(r, COL_MAX, pParam->m_dSideDimensionSpec_mm_Max[i]);
            // 6. Min
            strTemp.Format(_T("%.3f"), pParam->m_dSideDimensionSpec_mm_Min[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
                // 8) Offset
                SetCellDouble(r, COL_OFF, pParam->m_dSideDimensionSpec_mm_Off[i]);
            // 7. Max
            strTemp.Format(_T("%.3f"), pParam->m_dSideDimensionSpec_mm_Max[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
                // 9) Chamfer Use
                SetCellBool(r, COL_CHAMFER_USE, pParam->m_bSideChamfer_Use[i]);
            // 8. Offset
            strTemp.Format(_T("%.3f"), pParam->m_dSideDimensionSpec_mm_Off[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 9. Chamfer
            strTemp.Format(_T("%d"), (int) pParam->m_bSideChamfer_Use[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 10. Std
            strTemp.Format(_T("%.3f"), pParam->m_dSideChamfer_Spec_mm_Std[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 11. Min
            strTemp.Format(_T("%.3f"), pParam->m_dSideChamfer_Spec_mm_Min[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
            // 12. Max
            strTemp.Format(_T("%.3f"), pParam->m_dSideChamfer_Spec_mm_Max[i]);
            m_SideDimensionSetting.SetItemText(nRow, nCol++, strTemp);
                // 10-12) Chamfer Std/Min/Max
                SetCellDouble(r, COL_CH_STD, pParam->m_dSideChamfer_Spec_mm_Std[i]);
                SetCellDouble(r, COL_CH_MIN, pParam->m_dSideChamfer_Spec_mm_Min[i]);
                SetCellDouble(r, COL_CH_MAX, pParam->m_dSideChamfer_Spec_mm_Max[i]);
        }
        m_SideDimensionSetting.Invalidate();
    }
    else
    {
        int nDimensionCount = m_SideDimensionSetting.GetRowCount() - 1;
    }
    else {
        int nDimensionCount = max(0, m_SideDimensionSetting.GetRowCount() - 1);
        nDimensionCount = min(nDimensionCount, MAX_SIDE_DIMENSION_MEASURE_COUNT);
        pParam->m_nSideDimensionCount = nDimensionCount;
        for(int i=0; i<nDimensionCount; i++)
        {
            nRow = i + 1;
            nCol = 1;
        for (int i = 0; i < nDimensionCount; ++i) {
            const int r = i + 1;
            int col = COL_TOPMARK_Y;
            // 1. No.
            // 2) Top Mark To Distance Y (um)
            pParam->m_nSideDimensionPos_TopMarkToDistance_um[i] = GetCellInt(r, col++, pParam->m_nSideDimensionPos_TopMarkToDistance_um[i]);
            // 2. Top Mark To Distance Y (um)
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_nSideDimensionPos_TopMarkToDistance_um[i] = _wtoi(strTemp);
            // 3) Use Dimension
            pParam->m_bSideDimension_Use[i] = GetCellBool(r, col++);
            // 3. Use Dimension
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_bSideDimension_Use[i] = (_wtoi(strTemp) == 0) ? FALSE : TRUE;
            if (!m_bIsRipSide) {
                // 4) Thres
                pParam->m_nSideDimensionSpec_Thres[i] = GetCellInt(r, col++, pParam->m_nSideDimensionSpec_Thres[i]);
            // 4. Thres
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_nSideDimensionSpec_Thres[i] = _wtoi(strTemp);
                // 5-7) Std/Min/Max
                pParam->m_dSideDimensionSpec_mm_Std[i] = GetCellDouble(r, col++, pParam->m_dSideDimensionSpec_mm_Std[i]);
                pParam->m_dSideDimensionSpec_mm_Min[i] = GetCellDouble(r, col++, pParam->m_dSideDimensionSpec_mm_Min[i]);
                pParam->m_dSideDimensionSpec_mm_Max[i] = GetCellDouble(r, col++, pParam->m_dSideDimensionSpec_mm_Max[i]);
            // 5. Std
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideDimensionSpec_mm_Std[i] = _wtof(strTemp);
                // 8) Offset
                pParam->m_dSideDimensionSpec_mm_Off[i] = GetCellDouble(r, col++, pParam->m_dSideDimensionSpec_mm_Off[i]);
            // 6. Min
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideDimensionSpec_mm_Min[i] = _wtof(strTemp);
                // 9) Chamfer Use
                pParam->m_bSideChamfer_Use[i] = GetCellBool(r, col++);
            // 7. Max
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideDimensionSpec_mm_Max[i] = _wtof(strTemp);
            // 8. Offset
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideDimensionSpec_mm_Off[i] = _wtof(strTemp);
            // 9. Chamfer
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_bSideChamfer_Use[i] = (_wtoi(strTemp) == 0) ? FALSE : TRUE;
            // 10. Std
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideChamfer_Spec_mm_Std[i] = _wtof(strTemp);
            // 11. Min
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideChamfer_Spec_mm_Min[i] = _wtof(strTemp);
            // 12. Max
            strTemp = m_SideDimensionSetting.GetItemText(nRow, nCol++);
            pParam->m_dSideChamfer_Spec_mm_Max[i] = _wtof(strTemp);
                // 10-12) Chamfer Std/Min/Max
                pParam->m_dSideChamfer_Spec_mm_Std[i] = GetCellDouble(r, col++, pParam->m_dSideChamfer_Spec_mm_Std[i]);
                pParam->m_dSideChamfer_Spec_mm_Min[i] = GetCellDouble(r, col++, pParam->m_dSideChamfer_Spec_mm_Min[i]);
                pParam->m_dSideChamfer_Spec_mm_Max[i] = GetCellDouble(r, col++, pParam->m_dSideChamfer_Spec_mm_Max[i]);
        }
    }
        for (int k = nDimensionCount; k < MAX_SIDE_DIMENSION_MEASURE_COUNT; ++k) {
            pParam->m_nSideDimensionPos_TopMarkToDistance_um[k] = 0;
            pParam->m_bSideDimension_Use[k] = FALSE;
            pParam->m_nSideDimensionSpec_Thres[k] = 0;
            pParam->m_dSideDimensionSpec_mm_Std[k] = 0.0;
            pParam->m_dSideDimensionSpec_mm_Min[k] = 0.0;
            pParam->m_dSideDimensionSpec_mm_Max[k] = 0.0;
            pParam->m_dSideDimensionSpec_mm_Off[k] = 0.0;
            pParam->m_bSideChamfer_Use[k] = FALSE;
            pParam->m_dSideChamfer_Spec_mm_Std[k] = 0.0;
            pParam->m_dSideChamfer_Spec_mm_Min[k] = 0.0;
            pParam->m_dSideChamfer_Spec_mm_Max[k] = 0.0;
        }
}
    m_SideDimensionSetting.SetRedraw(TRUE);
    m_SideDimensionSetting.Invalidate(FALSE);
}
void CDlgSideDimensionSetting::Fill_SideDimensionSetting_CurrentResult()
{
@@ -904,25 +928,28 @@
void CDlgSideDimensionSetting::ClickButtonAdd()
{
    if(m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL)
    if (m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL) {
        return;
    }
    int nSideIdx = *(m_pSelectSideIdx);
    if(nSideIdx < 0 || eRcp_SideRD_End <=  nSideIdx)
    if (nSideIdx < 0 || eRcp_SideRD_End <= nSideIdx) {
        return;
    }
    CSIDE_PARM* pParam = &m_pDlgRecipe->m_SideParam[nSideIdx];
    int nAddIdx = pParam->m_nSideDimensionCount;
    if(nAddIdx < 0 || MAX_SIDE_DIMENSION_MEASURE_COUNT <= nAddIdx)
    {
    if(nAddIdx < 0 || MAX_SIDE_DIMENSION_MEASURE_COUNT <= nAddIdx) {
        CString strMsg;
        strMsg.Format(_T("Max Dimension Measure Count : %d ea"), MAX_SIDE_DIMENSION_MEASURE_COUNT);
        AfxMessageBox(strMsg);
        return;
    }
    UpdateRecipe(TRUE);
    pParam->m_nSideDimensionPos_TopMarkToDistance_um[nAddIdx] = 0;
    pParam->m_dSideDimensionSpec_mm_Min[nAddIdx] = 0;
@@ -936,13 +963,15 @@
void CDlgSideDimensionSetting::ClickButtonDel()
{
    if(m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL)
    if (m_pDlgRecipe == NULL || m_pSelectSideIdx == NULL) {
        return;
    }
    int nSideIdx = *(m_pSelectSideIdx);
    if(nSideIdx < 0 || eRcp_SideRD_End <=  nSideIdx)
    if (nSideIdx < 0 || eRcp_SideRD_End <= nSideIdx) {
        return;
    }
    CSIDE_PARM* pParam = &m_pDlgRecipe->m_SideParam[nSideIdx];
@@ -951,17 +980,18 @@
    CCellID FocusedID = m_SideDimensionSetting.GetFocusCell();
    int nDelIdx = FocusedID.row - 1;
    if(nDelIdx < 0 || nSideDimensionCount <= nDelIdx)
    {
    if(nDelIdx < 0 || nSideDimensionCount <= nDelIdx) {
        AfxMessageBox(_T("Select Error"));
        return;
    }
    UpdateRecipe(TRUE);
    int nPosIdx = 0;
    for(int i=0; i<MAX_DIMENSION_COUNT; i++)
    {
        if(i == nDelIdx)
    for(int i=0; i<MAX_DIMENSION_COUNT; i++) {
        if (i == nDelIdx) {
            continue;
        }
        pParam->m_nSideDimensionPos_TopMarkToDistance_um[nPosIdx] = pParam->m_nSideDimensionPos_TopMarkToDistance_um[i];
        pParam->m_dSideDimensionSpec_mm_Min[nPosIdx] = pParam->m_dSideDimensionSpec_mm_Min[i];
EdgeInspector_App/DlgSideDimensionSetting.h
@@ -28,7 +28,7 @@
    void        SetDlgRecipe(CGlassRecipe* pDlgRecipe);
    void        SetGlassData(CGlass_Data* pGlassData)            {m_pGlassData = pGlassData;}
    void        UpdateRecipe(BOOL bGetData);
    void        RefreshSideUI(BOOL bReinitGrid = TRUE);
    void        Init_SideDimensionSetting();
    void        Fill_SideDimensionSetting(BOOL bGetData);
@@ -49,6 +49,7 @@
    CGridCtrl        m_SideDimensionSetting;
    CGridCtrl        m_TopCornerDimensionSetting;
    CGridCtrl        m_BotCornerDimensionSetting;
    BOOL            m_bIsRipSide;
public:
    
    DECLARE_EVENTSINK_MAP()
EdgeInspector_App/Process/InspectCamera.cpp
@@ -430,12 +430,11 @@
    g_pLog->DisplayMessage(_T("[APP]Measure Side Edge Start, StartEdge = %d, EndEdge = %d, Width = %d"), nTopEdge, nBottomEdge, imgWidth);
    
    stFrameIndex stFrame = m_pGrabber->GetGrabFrame();
    CRIP_THICKNESS_PARM& rip = m_pRecipe->m_SideParam[eDim].m_RipThk;
    CSIDE_PARM parm = m_pRecipe->m_SideParam[eDim];
    CRIP_THICKNESS_PARM& rip = parm.m_RipThk;
    if (rip.m_bUseInspect != TRUE) {
        return TRUE;
    }
    int inspectNum = 36;
    //输入参数
    int topOffset = rip.m_nTopOffset;        //T Offset
@@ -446,6 +445,148 @@
    int rightThres = rip.m_nRightThres;     //Right Thres
    int gassThres = rip.m_nGlassThres;      //Gas Thres
    int inspectNum = 36;
    int startY = nTopEdge + topOffset;
    int endY = nBottomEdge - botOffset;
    int step = (int)((endY - startY) / inspectNum);
    g_pLog->DisplayMessage(_T("[APP]Measure Side Edge, (startY, endY, step) = (%d, %d, %d)"), startY, endY, step);
    int nStep = max(1, (endY - startY) / inspectNum); // 防 0
    auto SpecDiff = [](double v, double vMin, double vMax)->double {
        if (v <= 0) return 0.0;            // 无效值
        if (v < vMin) return v - vMin;     // 负:低于下限
        if (v > vMax) return v - vMax;     // 正:高于上限
        return 0.0;                        // 在规格内
    };
    auto judge = [](double v_um, double vMin, double vMax)->int {
        if (v_um <= 0) return 0;
        return (v_um < vMin || v_um > vMax) ? 2 : 1;
    };
    auto MakeBaseInfo = [&](CPoint pt, CRect rt, DefectLocation loc)->CDefect_Info {
        CDefect_Info info;
        info.m_iFrameIdx = stFrame.nFrameIdx;
        info.m_nCamID = m_iCamera;
        info.m_nScanIdx = stFrame.nScanIdx;
        info.m_nGlassStartLine = pSideData->m_nGlassStartLine;
        info.m_nSideIdx = (int)eDim;
        info.m_ptDefectPos_pxl = pt;
        info.m_rtDefectPos_pxl = rt;
        info.m_DefectLoc = loc;
        return info;
    };
#if 1
    int nMeasureCount = parm.m_nSideDimensionCount;
    for (int nMeasurePointIdx = 0; nMeasurePointIdx < nMeasureCount; nMeasurePointIdx++) {
        if (nMeasurePointIdx == MAX_SIDE_DIMENSION_MEASURE_COUNT) {
            break;
        }
        if (parm.m_bSideDimension_Use[nMeasurePointIdx] != TRUE) {
            continue;
        }
        //这里做一个测试
        int inputY = (int)(parm.m_nSideDimensionPos_TopMarkToDistance_um[nMeasurePointIdx] * m_dPixelSizeY);   //这个是输入参数,距离StartLine的距离, um
        int targetY = (int)(inputY / m_dPixelSizeY);
        int x1 = leftEdge;
        int y1 = nTopEdge + targetY - 50;
        int x2 = rightEdge;
        int y2 = nTopEdge + targetY + 50;
        double dist_ret = 0.0f;                 //输出结果
        double left_dist_Gass = 0.0f;           //输出结果
        double right_dist_Gass;                 //输出结果
        double xMinEdge_px = 0.0f;              //输出结果
        double yMinEdge_px = 0.0f;              //输出结果
        double xMaxEdge_px = 0.0f;              //输出结果
        double yMaxEdge_px = 0.0f;              //输出结果
        double xMinGas_px = 0.0f;               //输出结果
        double yMinGas_px = 0.0f;               //输出结果
        double xMaxGas_px = 0.0f;               //输出结果
        double yMaxGas_px = 0.0f;               //输出结果
        MeasureSideEdge_POS_1(eDim, x1, y1, x2, y2, leftThres, rightThres, gassThres,
            xMinEdge_px, yMinEdge_px, xMaxEdge_px, yMaxEdge_px,
            xMinGas_px, yMinGas_px, xMaxGas_px, yMaxGas_px,
            dist_ret, left_dist_Gass, right_dist_Gass);
        g_pLog->DisplayMessage(_T("[APP]Measure Result: LeftEdge = (%.1f, %.1f), LeftGas = (%.1f, %.1f), rightGas = (%.1f, %.1f), RightEdge = (%.1f, %.1f), (Dist, LeftGass, RightGass) = (%.1f, %.1f, %.1f)"),
            xMinEdge_px, yMinEdge_px,
            xMinGas_px, yMinGas_px,
            xMaxGas_px, yMaxGas_px,
            xMaxEdge_px, yMaxEdge_px,
            dist_ret, left_dist_Gass, right_dist_Gass);
        dist_ret *= m_dPixelSizeX;
        left_dist_Gass *= m_dPixelSizeX;
        right_dist_Gass *= m_dPixelSizeX;
        const int nGlassState = judge(dist_ret, rip.m_nGlassSizeMin_um, rip.m_nGlassSizeMax_um);
        const int nLeftState = judge(left_dist_Gass, rip.m_nLeftRipSizeMin_um, rip.m_nLeftRipSizeMax_um);
        const int nRightState = judge(right_dist_Gass, rip.m_nRightRipSizeMin_um, rip.m_nRightRipSizeMax_um);
        if (nMeasurePointIdx < MAX_RIP_SAMPLE_COUNT) {
            // Glass 线段
            pSideData->m_ptSideRip_Glass_pxl[nMeasurePointIdx][0] = CPoint((int)xMinEdge_px, (int)yMinEdge_px);
            pSideData->m_ptSideRip_Glass_pxl[nMeasurePointIdx][1] = CPoint((int)xMaxEdge_px, (int)yMaxEdge_px);
            pSideData->m_dSideRip_Glass_um[nMeasurePointIdx] = dist_ret;
            pSideData->m_nSideRip_Glass_Status[nMeasurePointIdx] = nGlassState;
            // Left 线段
            pSideData->m_ptSideRip_Left_pxl[nMeasurePointIdx][0] = CPoint((int)xMinEdge_px, (int)yMinEdge_px);
            pSideData->m_ptSideRip_Left_pxl[nMeasurePointIdx][1] = CPoint((int)xMinGas_px, (int)yMinGas_px);
            pSideData->m_dSideRip_Left_um[nMeasurePointIdx] = left_dist_Gass;
            pSideData->m_nSideRip_Left_Status[nMeasurePointIdx] = nLeftState;
            // Right 线段
            pSideData->m_ptSideRip_Right_pxl[nMeasurePointIdx][0] = CPoint((int)xMaxGas_px, (int)yMaxGas_px);
            pSideData->m_ptSideRip_Right_pxl[nMeasurePointIdx][1] = CPoint((int)xMaxEdge_px, (int)yMaxEdge_px);
            pSideData->m_dSideRip_Right_um[nMeasurePointIdx] = right_dist_Gass;
            pSideData->m_nSideRip_Right_Status[nMeasurePointIdx] = nRightState;
        }
        // Glass NG
        if (nGlassState == 2) {
            CRect rt(
                (int)min(min(xMinEdge_px, xMinGas_px), min(xMaxEdge_px, xMaxGas_px)),
                (int)min(min(yMinEdge_px, yMinGas_px), min(yMaxEdge_px, yMaxGas_px)),
                (int)max(max(xMinEdge_px, xMinGas_px), max(xMaxEdge_px, xMaxGas_px)),
                (int)max(max(yMinEdge_px, yMinGas_px), max(yMaxEdge_px, yMaxGas_px))
            );
            CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2);
            CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Glass);
            double dDiff = SpecDiff(dist_ret, rip.m_nGlassSizeMin_um, rip.m_nGlassSizeMax_um);
            m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, dist_ret, dDiff);
        }
        // Left NG
        if (nLeftState == 2) {
            CRect rt(
                (int)min(xMinEdge_px, xMinGas_px),
                (int)min(yMinEdge_px, yMinGas_px),
                (int)max(xMinEdge_px, xMinGas_px),
                (int)max(yMinEdge_px, yMinGas_px)
            );
            CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2);
            CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Left);
            double dDiff = SpecDiff(left_dist_Gass, rip.m_nLeftRipSizeMin_um, rip.m_nLeftRipSizeMax_um);
            m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, left_dist_Gass, dDiff);
        }
        // Right NG
        if (nRightState == 2) {
            CRect rt(
                (int)min(xMaxEdge_px, xMaxGas_px),
                (int)min(yMaxEdge_px, yMaxGas_px),
                (int)max(xMaxEdge_px, xMaxGas_px),
                (int)max(yMaxEdge_px, yMaxGas_px)
            );
            CPoint pt((rt.left + rt.right) / 2, (rt.top + rt.bottom) / 2);
            CDefect_Info defect = MakeBaseInfo(pt, rt, DefectLoc_Rip_Thickness_Right);
            double dDiff = SpecDiff(right_dist_Gass, rip.m_nRightRipSizeMin_um, rip.m_nRightRipSizeMax_um);
            m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, right_dist_Gass, dDiff);
        }
    }
#else
    double dist_array[36];                     //输出结果
    double left_dist_Gass_array[36];           //输出结果
    double right_dist_Gass_array[36];          //输出结果
@@ -457,11 +598,6 @@
    double yMinGas_array_px[36];               //输出结果
    double xMaxGas_array_px[36];               //输出结果
    double yMaxGas_array_px[36];               //输出结果
    int startY = nTopEdge + topOffset;
    int endY = nBottomEdge - botOffset;
    int step = (int)((endY - startY) / inspectNum);
    g_pLog->DisplayMessage(_T("[APP]Measure Side Edge, (startY, endY, step) = (%d, %d, %d)"), startY, endY, step);
    for (int i = 0; i < inspectNum; i++) {
        int x1 = leftEdge;
@@ -591,10 +727,172 @@
            }
        }
    }
#endif
    return TRUE;
}
void CInspectCamera::MeasureSideEdge_POS_1(DimensionDir eDim,
    int x1, int y1, int x2, int y2,
    int leftThres, int rightThres, int gassThres,
    double& minEdgeX, double& minEdgeY, double& maxEdgeX, double& maxEdgeY,
    double& minGasX, double& minGasY, double& maxGasX, double& maxGasY,
    double& szDist, double& leftGassDist, double& rightGassDist) {
    /* code */
    szDist = 0.0f;
    leftGassDist = 0.0f;
    rightGassDist = 0.0f;
    int width = x2 - x1 + 1;
    int height = y2 - y1 + 1;
    uchar* imgData = new uchar[width * height];
    try {
        CutImageROI(imgData, eDim, x1, y1, x2, y2);
        MeasurePoint dotResult1[100];
        MeasurePoint dotResult2[100];
        MeasurePoint dotResult3[100];
        int dotNum1 = 0;
        int dotNum2 = 0;
        int dotNum3 = 0;
        CVisionMeasureClass doExec;
        double sigma = 2.5f;   //输入参数, 增加参数
        doExec.doMeasurePosB(imgData, width, height, sigma,
            dotResult1, dotNum1,
            dotResult2, dotNum2,
            dotResult3, dotNum3);
        for (int i = 0; i < dotNum1; i++) {
            dotResult1[i].x += x1;
            dotResult1[i].y += y1;
        }
        for (int i = 0; i < dotNum2; i++) {
            dotResult2[i].x += x1;
            dotResult2[i].y += y1;
        }
        for (int i = 0; i < dotNum3; i++) {
            dotResult3[i].x += x1;
            dotResult3[i].y += y1;
        }
        int fzDist = 4.5;                 //输入参数, 增加参数
        double xMinResult[3] = { -1 };
        double yMinResult[3] = { -1 };
        double xMaxResult[3] = { -1 };
        double yMaxResult[3] = { -1 };
        double xMinGassResult[3] = { -1 };
        double yMinGassResult[3] = { -1 };
        double xMaxGassResult[3] = { -1 };
        double yMaxGassResult[3] = { -1 };
        MeasureResultProc(dotResult1, dotNum1, leftThres, rightThres, gassThres, fzDist,
            xMinResult[0], yMinResult[0], xMaxResult[0], yMaxResult[0],
            xMinGassResult[0], yMinGassResult[0], xMaxGassResult[0], yMaxGassResult[0]);
        MeasureResultProc(dotResult2, dotNum2, leftThres, rightThres, gassThres, fzDist,
            xMinResult[1], yMinResult[1], xMaxResult[1], yMaxResult[1],
            xMinGassResult[1], yMinGassResult[1], xMaxGassResult[1], yMaxGassResult[1]);
        MeasureResultProc(dotResult3, dotNum3, leftThres, rightThres, gassThres, fzDist,
            xMinResult[2], yMinResult[2], xMaxResult[2], yMaxResult[2],
            xMinGassResult[2], yMinGassResult[2], xMaxGassResult[2], yMaxGassResult[2]);
        std::vector<double> vDist, vLeftGass, vRightGass;
        for (int i = 0; i < 3; i++) {
            if (xMinResult[i] > 0 && xMaxResult[i] > 0) {
                double dx = xMaxResult[i] - xMinResult[i];
                double dy = yMaxResult[i] - yMinResult[i];
                double dist = sqrt(dx * dx + dy * dy);
                vDist.push_back(dist);
            }
            if (xMinResult[i] > 0 && xMinGassResult[i] > 0) {
                double dx = xMinGassResult[i] - xMinResult[i];
                double dy = yMinGassResult[i] - yMinResult[i];
                double dist = sqrt(dx * dx + dy * dy);
                vLeftGass.push_back(dist);
            }
            if (xMaxResult[i] > 0 && xMaxGassResult[i] > 0) {
                double dx = xMaxResult[i] - xMaxGassResult[i];
                double dy = yMaxResult[i] - yMaxGassResult[i];
                double dist = sqrt(dx * dx + dy * dy);
                vRightGass.push_back(dist);
            }
        }
        double avgDist = 0.0f;
        int sz = (int)(vDist.size());
        if (sz > 2) {
            for (int i = 0; i < sz - 1; i++) {
                for (int j = i + 1; j < sz; j++) {
                    if (vDist[i] > vDist[j]) {
                        double tmp = vDist[i];
                        vDist[i] = vDist[j];
                        vDist[j] = tmp;
                    }
                }
            }
            double avg = 0.0f;
            for (int i = 1; i < sz - 1; i++) {
                avg += vDist[i];
            }
            avgDist = avg / (sz - 2);
        }
        double avgLeftGass = 0.0f;
        sz = (int)(vLeftGass.size());
        if (sz > 2) {
            for (int i = 0; i < sz - 1; i++) {
                for (int j = i + 1; j < sz; j++) {
                    if (vLeftGass[i] > vLeftGass[j]) {
                        double tmp = vLeftGass[i];
                        vLeftGass[i] = vLeftGass[j];
                        vLeftGass[j] = tmp;
                    }
                }
            }
            double avg = 0.0f;
            for (int i = 1; i < sz - 1; i++) {
                avg += vLeftGass[i];
            }
            avgLeftGass = avg / (sz - 2);
        }
        double avgRightGass = 0.0f;
        sz = (int)(vRightGass.size());
        if (sz > 2) {
            for (int i = 0; i < sz - 1; i++) {
                for (int j = i + 1; j < sz; j++) {
                    if (vRightGass[i] > vRightGass[j]) {
                        double tmp = vRightGass[i];
                        vRightGass[i] = vRightGass[j];
                        vRightGass[j] = tmp;
                    }
                }
            }
            double avg = 0.0f;
            for (int i = 1; i < sz - 1; i++) {
                avg += vRightGass[i];
            }
            avgRightGass = avg / (sz - 2);
        }
        szDist = avgDist;
        leftGassDist = avgLeftGass;
        rightGassDist = avgRightGass;
        minEdgeX = xMinResult[1];
        minEdgeY = yMinResult[1];
        maxEdgeX = xMaxResult[1];
        maxEdgeY = yMaxResult[1];
        minGasX = minEdgeX + leftGassDist - 1;
        minGasY = minEdgeY;
        maxGasX = maxEdgeX - rightGassDist + 1;
        maxGasY = maxEdgeY;
        delete[] imgData;
        imgData = nullptr;
    }
    catch (...) {
        delete[] imgData;
        imgData = nullptr;
    }
}
void CInspectCamera::MeasureSideEdge_POS(DimensionDir eDim, 
    int x1, int y1, int x2, int y2,
    int leftThres, int rightThres, int gassThres,
EdgeInspector_App/Process/InspectCamera.h
@@ -143,6 +143,14 @@
    //14. 截图图像
    int CutImageROI(uchar* img, DimensionDir eDim, int x1, int y1, int x2, int y2);
    BOOL MeasureSideEdge_EI(DimensionDir eDim);
    void MeasureSideEdge_POS_1(DimensionDir eDim,
        int x1, int y1, int x2, int y2,
        int leftThres, int rightThres, int gassThres,
        double& minEdgeX, double& minEdgeY, double& maxEdgeX, double& maxEdgeY,
        double& minGasX, double& minGasY, double& maxGasX, double& maxGasY,
        double& szDist, double& leftGassDist, double& rightGassDist);
    void MeasureSideEdge_POS(DimensionDir eDim, 
        int x1, int y1, int x2, int y2,
        int leftThres, int rightThres, int gassThres,
EdgeInspector_App/View/EdgeImageViewer.cpp
@@ -2171,7 +2171,7 @@
    }
    DimensionDir eDim = (DimensionDir)m_nSideIdx;
    bool bIsRipSide = (DIMENSION_A_RIP == m_nSideIdx) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim);
    bool bIsRipSide = (DIMENSION_A_RIP == eDim) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim);
    if (!bIsRipSide) {
        return;
    }
EdgeInspector_App/ViewMain_Recipe.cpp
@@ -1224,58 +1224,44 @@
void CViewMain_Recipe::UpdateRecipe(BOOL bGetData, int type)
{
    if(bGetData == FALSE)
    {
        // UpdateData(FALSE);    // Parameter
        Fill_PanelInfo(bGetData);
        Fill_SideInsInfo(bGetData);
        Fill_JudgementInfo(bGetData);
        UpdateSideImage();        // Image
        UpdateMarkImage();        // Mark Image
        m_dScanTimeOut = m_pDlgRecipe->m_RecieParm.m_dOneScanTime_sec;
        if(m_pViewSideDimensionSetting != NULL)
            m_pViewSideDimensionSetting->UpdateRecipe(bGetData);
        if(m_pViewSideNotchSetting != NULL)
            m_pViewSideNotchSetting->UpdateRecipe(bGetData);
        if(m_pViewSideExceptionSetting != NULL)
            m_pViewSideExceptionSetting->UpdateRecipe(bGetData);
        if(m_pViewSideUserDefectSetting != NULL)
            m_pViewSideUserDefectSetting->UpdateRecipe(bGetData);
        UpdateData(FALSE);
    }
    else
    {
        UpdateData(TRUE);    // Parameter
        Fill_PanelInfo(bGetData);
        Fill_SideInsInfo(bGetData);
        Fill_JudgementInfo(bGetData);
    if (bGetData) {
        UpdateData(TRUE);
        m_pDlgRecipe->m_RecieParm.m_dOneScanTime_sec = m_dScanTimeOut;
    }
    else {
        m_dScanTimeOut = m_pDlgRecipe->m_RecieParm.m_dOneScanTime_sec;
    }
        if (type == 1)
        {
            if (m_pViewSideDimensionSetting != NULL)
    Fill_PanelInfo(bGetData);
    Fill_SideInsInfo(bGetData);
    Fill_JudgementInfo(bGetData);
    if (!bGetData) {
        UpdateSideImage();
        UpdateMarkImage();
    }
    auto UpdateChild = [&](auto* pView) {
        if (pView) {
            pView->UpdateRecipe(bGetData);
        }
    };
    const bool bNeedUpdateSideDim = (!bGetData) || (type == 1);
    const bool bNeedRefreshSideUI = (!bGetData);
    if (m_pViewSideDimensionSetting && bNeedUpdateSideDim) {
        if (bNeedRefreshSideUI) {
            m_pViewSideDimensionSetting->RefreshSideUI(TRUE);
        }
                m_pViewSideDimensionSetting->UpdateRecipe(bGetData);
        }
        if(m_pViewSideNotchSetting != NULL)
            m_pViewSideNotchSetting->UpdateRecipe(bGetData);
    UpdateChild(m_pViewSideNotchSetting);
    UpdateChild(m_pViewSideExceptionSetting);
    UpdateChild(m_pViewSideUserDefectSetting);
        if(m_pViewSideExceptionSetting != NULL)
            m_pViewSideExceptionSetting->UpdateRecipe(bGetData);
        if(m_pViewSideUserDefectSetting != NULL)
            m_pViewSideUserDefectSetting->UpdateRecipe(bGetData);
    if (!bGetData) {
        UpdateData(FALSE);
    }
}
@@ -3513,8 +3499,9 @@
void CViewMain_Recipe::ClickButtonOpenDimensionSettingView()
{
    if(m_pViewSideDimensionSetting == NULL)
    if (m_pViewSideDimensionSetting == NULL) {
        return;
    }
    m_pViewSideDimensionSetting->SetGlassData(m_pGlassData);
    m_pViewSideDimensionSetting->ShowWindow(SW_SHOW);
SDK/VisionMeasure/include/VisionMeasureClass.h
@@ -40,6 +40,12 @@
        MeasurePoint* measureResult6, int& outResult6,
        MeasurePoint* measureResult7, int& outResult7);
    //4. 测量点
    int doMeasurePosB(unsigned char* img, int width, int height, double sigma,
        MeasurePoint* measureResult1, int& outResult1,
        MeasurePoint* measureResult2, int& outResult2,
        MeasurePoint* measureResult3, int& outResult3);
    //1. 获取程序运行路径
    std::string GetAppPathA(void);
};
VisionMeasure/VisionMeasureClass.cpp
@@ -53,7 +53,6 @@
    HalconCpp::ZoomImageSize(hImage, &hZoomImage, width, szHeight, "constant");
    HalconCpp::MeanImage(hZoomImage, &hMeanImage, 1, 5);
    double xOutResult[MEASURE_MAX_NUM] = { 0 };
    double yOutResult[MEASURE_MAX_NUM] = { 0 };
    double cyOutResult[MEASURE_MAX_NUM] = { 0 };
@@ -131,6 +130,64 @@
    return 1;
}
int CVisionMeasureClass::doMeasurePosB(unsigned char* img, int width, int height, double sigma,
    MeasurePoint* measureResult1, int& outResult1,
    MeasurePoint* measureResult2, int& outResult2,
    MeasurePoint* measureResult3, int& outResult3) {
    /* code */
    if (nullptr == img) return -1;
    HalconCpp::HObject hImage, hZoomImage, hMeanImage;
    HalconCpp::GenImage1(&hImage, "byte", width, height, (Hlong)img);
    int szHeight = (int)(0.5 * height);
    HalconCpp::ZoomImageSize(hImage, &hZoomImage, width, szHeight, "constant");
    HalconCpp::MeanImage(hZoomImage, &hMeanImage, 1, 5);
    double xOutResult[MEASURE_MAX_NUM] = { 0 };
    double yOutResult[MEASURE_MAX_NUM] = { 0 };
    double cyOutResult[MEASURE_MAX_NUM] = { 0 };
    double distOutResult[MEASURE_MAX_NUM] = { 0 };
    int outNum = 0;
    int topEdge = 15;
    int botEdge = szHeight - 16;
    int step = (int)((botEdge - topEdge) / 2);
    int x1 = 5;
    int x2 = width - 6;
    for (int i = 0; i < 3; i++) {
        int y1 = topEdge + i * step;
        int y2 = y1;
        int threshold = 10;
        doMeasurePosApi(hMeanImage, x1, y1, x2, y2, 10, threshold, sigma, xOutResult, yOutResult, cyOutResult, distOutResult, outNum);
        if (0 == i) {
            outResult1 = outNum;
            for (int i = 0; i < outNum; i++) {
                measureResult1[i].x = xOutResult[i];
                measureResult1[i].y = 2 * yOutResult[i];
                measureResult1[i].cy = cyOutResult[i];
            }
        }
        else if (1 == i) {
            outResult2 = outNum;
            for (int i = 0; i < outNum; i++) {
                measureResult2[i].x = xOutResult[i];
                measureResult2[i].y = 2 * yOutResult[i];
                measureResult2[i].cy = cyOutResult[i];
            }
        }
        else if (2 == i) {
            outResult3 = outNum;
            for (int i = 0; i < outNum; i++) {
                measureResult3[i].x = xOutResult[i];
                measureResult3[i].y = 2 * yOutResult[i];
                measureResult3[i].cy = cyOutResult[i];
            }
        }
    }
    return 1;
}
std::string CVisionMeasureClass::GetAppPathA(void) {
    /* code */
    char szFilePath[MAX_PATH] = { 0 }, szDrive[MAX_PATH] = { 0 }, szDir[MAX_PATH] = { 0 }, szFileName[MAX_PATH] = { 0 }, szExt[MAX_PATH] = { 0 };
VisionMeasure/VisionMeasureClass.h
@@ -40,6 +40,12 @@
        MeasurePoint* measureResult6, int& outResult6,
        MeasurePoint* measureResult7, int& outResult7);
    //4. 测量点
    int doMeasurePosB(unsigned char* img, int width, int height, double sigma,
        MeasurePoint* measureResult1, int& outResult1,
        MeasurePoint* measureResult2, int& outResult2,
        MeasurePoint* measureResult3, int& outResult3);
    //1. 获取程序运行路径
    std::string GetAppPathA(void);
};