mrDarker
2025-08-14 4fb0f6c9b7b0fdfc6cc52c9bf1153d87f92651ca
1. 修复RIP新增配方闪退的问题
2. 完善RIP结果绘画在视图窗口
已修改9个文件
236 ■■■■ 文件已修改
EdgeInspector_App/BICommon.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Define/Global_Define.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Process/InspectCamera.cpp 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Recipe/GlassRecipe.h 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Side_Data.cpp 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/Side_Data.h 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/View/EdgeImageViewer.cpp 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/View/EdgeImageViewer.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/ViewMain_Recipe.cpp 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
EdgeInspector_App/BICommon.h
@@ -8,10 +8,10 @@
#include <string>
#include <time.h>
#define OFFLINE_KEY           0   //OFFLINE_KEY:1是离线模式;0是在线模式
#define OFFLINE_KEY           1   //OFFLINE_KEY:1是离线模式;0是在线模式
#define MINI_LED              0   //Mini车间
#define MINI_NOTCH              0   //Mini车间, 是否使用刻槽功能
#define HALCON_VISION_KEY     1   //是否启用HALCON
#define HALCON_VISION_KEY     0   //是否启用HALCON
#define USE_WEBSOCKET         0   //是否启用websocket(AI)
#define USE_AI_DETECT         0   //是否启用AI检测
EdgeInspector_App/Define/Global_Define.h
@@ -54,6 +54,9 @@
#define MAX_SIDE_NOTCH_MEASURE_COUNT            10
#define MAX_SIDE_NOTCH_CIRCLE_COUNT                4
#define MAX_RIP_SAMPLE_COUNT                    36
#define RIP_POINT_COUNT                            2
/*
#define MAX_PROFILE_SETTING_COUNT        79
#define PROFILE_INSPECT_SIZE_A_C        13
EdgeInspector_App/Process/InspectCamera.cpp
@@ -556,6 +556,40 @@
            double dDiff = SpecDiff(right_dist_Gass_array[i], rip.m_nRightRipSizeMin_um, rip.m_nRightRipSizeMax_um);
            m_pDefectControl->ExtractDefect_RipThickness(eDim, m_iCamera, stFrame.nScanIdx, defect, right_dist_Gass_array[i], dDiff);
        }
        if (i < MAX_RIP_SAMPLE_COUNT) {
            pSideData->m_ptSideRip_Glass_pxl[i][0] = CPoint((int)xMinEdge_array_px[i], (int)yMinEdge_array_px[i]); // start
            pSideData->m_ptSideRip_Glass_pxl[i][1] = CPoint((int)xMaxEdge_array_px[i], (int)yMaxEdge_array_px[i]); // end
            pSideData->m_ptSideRip_Left_pxl[i][0] = CPoint((int)xMinEdge_array_px[i], (int)yMinEdge_array_px[i]);  // start
            pSideData->m_ptSideRip_Left_pxl[i][1] = CPoint((int)xMinGas_array_px[i], (int)yMinGas_array_px[i]);    // end
            pSideData->m_ptSideRip_Right_pxl[i][0] = CPoint((int)xMaxGas_array_px[i], (int)yMaxGas_array_px[i]);   // start
            pSideData->m_ptSideRip_Right_pxl[i][1] = CPoint((int)xMaxEdge_array_px[i], (int)yMaxEdge_array_px[i]); // end
            pSideData->m_dSideRip_Glass_um[i] = dist_array[i];
            pSideData->m_dSideRip_Left_um[i] = left_dist_Gass_array[i];
            pSideData->m_dSideRip_Right_um[i] = right_dist_Gass_array[i];
            if (dist_array[i] > 0) {
                pSideData->m_nSideRip_Glass_Status[i] = ngGlass ? 2 : 1;
            }
            else {
                pSideData->m_nSideRip_Glass_Status[i] = 0;
            }
            if (left_dist_Gass_array[i] > 0) {
                pSideData->m_nSideRip_Left_Status[i] = ngLeft ? 2 : 1;
            }
            else {
                pSideData->m_nSideRip_Left_Status[i] = 0;
            }
            if (right_dist_Gass_array[i] > 0) {
                pSideData->m_nSideRip_Right_Status[i] = ngRight ? 2 : 1;
            }
            else {
                pSideData->m_nSideRip_Right_Status[i] = 0;
            }
        }
    }
    return TRUE;
EdgeInspector_App/Recipe/GlassRecipe.h
@@ -332,12 +332,13 @@
    int  m_nTopOffset = 0;            // Inspect Top Offset
    int  m_nRectRight = 0;            // Inspect Rect R
    int  m_nBottomOffset = 0;       // Inspect Bottom Offset
    // RIP chip detection
    BOOL    m_bRipUseInspect = FALSE;
    int        m_nRipInspect_Range_um=0;
    int        m_nRipInspect_SideLine_Offset_um=0;
    int        m_nRipMin_Threshold = 0;
    int        m_nRipMax_Threshold = 0;
    BOOL m_bRipUseInspect = FALSE;
    int     m_nRipInspect_Range_um=0;
    int     m_nRipInspect_SideLine_Offset_um=0;
    int     m_nRipMin_Threshold = 0;
    int     m_nRipMax_Threshold = 0;
    
    
    // Judgement
EdgeInspector_App/Side_Data.cpp
@@ -164,6 +164,21 @@
    m_nTotalDefectCount = 0;
    m_nNgDefectCount = 0;
    ZeroMemory(m_nSideRip_Glass_Status, sizeof(m_nSideRip_Glass_Status));
    ZeroMemory(m_nSideRip_Left_Status, sizeof(m_nSideRip_Left_Status));
    ZeroMemory(m_nSideRip_Right_Status, sizeof(m_nSideRip_Right_Status));
    ZeroMemory(m_dSideRip_Glass_um, sizeof(m_dSideRip_Glass_um));
    ZeroMemory(m_dSideRip_Left_um, sizeof(m_dSideRip_Left_um));
    ZeroMemory(m_dSideRip_Right_um, sizeof(m_dSideRip_Right_um));
    for (int i = 0; i < MAX_RIP_SAMPLE_COUNT; i++) {
        for (int j = 0; j < RIP_POINT_COUNT; j++) {
            m_ptSideRip_Glass_pxl[i][j] = CPoint(-1, -1);
            m_ptSideRip_Left_pxl[i][j] = CPoint(-1, -1);
            m_ptSideRip_Right_pxl[i][j] = CPoint(-1, -1);
        }
    }
}
void CSide_Data::SetFrameProc(int nFrameIdx)
EdgeInspector_App/Side_Data.h
@@ -181,7 +181,6 @@
    int                    m_nUserDefectAreaCount;
    CRect                m_rtUserDefectArea_pxl[MAX_SIDE_USER_DEFECT_AREA_COUNT];
    // Defect
    int                    m_nTotalDefectCount;
    int                    m_nNgDefectCount;
@@ -190,5 +189,16 @@
    BOOL                m_nFrameThreadProc[MAX_IMAGE_FRAME];            // Thread啊 瘤唱埃 Frame阑 眉农窍磊..
    CCriticalSection    m_csFrameThread;
};
    // RIP Thickness
    int m_nSideRip_Glass_Status[MAX_RIP_SAMPLE_COUNT];
    int m_nSideRip_Left_Status[MAX_RIP_SAMPLE_COUNT];
    int m_nSideRip_Right_Status[MAX_RIP_SAMPLE_COUNT];
    double  m_dSideRip_Glass_um[MAX_RIP_SAMPLE_COUNT];
    double  m_dSideRip_Left_um[MAX_RIP_SAMPLE_COUNT];
    double  m_dSideRip_Right_um[MAX_RIP_SAMPLE_COUNT];
    CPoint  m_ptSideRip_Glass_pxl[MAX_RIP_SAMPLE_COUNT][RIP_POINT_COUNT];
    CPoint  m_ptSideRip_Left_pxl[MAX_RIP_SAMPLE_COUNT][RIP_POINT_COUNT];
    CPoint  m_ptSideRip_Right_pxl[MAX_RIP_SAMPLE_COUNT][RIP_POINT_COUNT];
};
EdgeInspector_App/View/EdgeImageViewer.cpp
@@ -667,6 +667,8 @@
    memDC.SetStretchBltMode(COLORONCOLOR);
    pOldBitmap = (CBitmap*)memDC.SelectObject(&Bitmap);
    DimensionDir eDim = (DimensionDir)m_nSideIdx;
    bool bIsRipSide = (DIMENSION_A_RIP == m_nSideIdx) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim);
    // 1. Draw Buffer Image
    UpdateView_Image(&memDC);
@@ -688,7 +690,7 @@
    // 7. Draw Exception : MODE_VIEW_EXCEPTION_AREA
    UpdateView_ExceptionArea(&memDC);
    // 8. Draw Inspect : MODE_VIEW_INSPECT_AREA
    UpdateView_InspectArea(&memDC);
@@ -722,6 +724,8 @@
    UpdateView_VisionResult(&memDC);
#endif // HALCON_VISION_KEY
    // 18. Side Rip Thickness : MODE_VIEW_MEASURE
    UpdateView_SideRipThickness(&memDC);
    pDC->BitBlt(0,0,m_rtWnd.Width(),m_rtWnd.Height(),&memDC,0,0,SRCCOPY);
    memDC.SelectObject(pOldBitmap);
@@ -2160,6 +2164,99 @@
    memDC->SelectObject(pOldPen);
}
void CEdgeImageViewer::UpdateView_SideRipThickness(CDC* memDC)
{
    if (m_pBuffer == NULL || memDC == NULL || m_pGlassData == NULL || m_pRecipe == NULL) {
        return;
    }
    DimensionDir eDim = (DimensionDir)m_nSideIdx;
    bool bIsRipSide = (DIMENSION_A_RIP == m_nSideIdx) || (DIMENSION_B_RIP == eDim) || (DIMENSION_C_RIP == eDim) || (DIMENSION_D_RIP == eDim);
    if (!bIsRipSide) {
        return;
    }
    CRIP_THICKNESS_PARM& rip = m_pRecipe->m_SideParam[eDim].m_RipThk;
    if (rip.m_bUseInspect != TRUE) {
        return;
    }
    CSide_Data* pSideData = m_pGlassData->GetSideData(eDim);
    if (pSideData == NULL) {
        return;
    }
    if (m_MenuStatus[MODE_VIEW_MEASURE] == FALSE) {
        return;
    }
    CPen penOK(PS_SOLID, 1, RGB(0, 255, 0));
    CPen penNG(PS_SOLID, 1, RGB(255, 0, 0));
    CPen penNone(PS_DOT, 1, RGB(180, 180, 180));
    CBrush brNull; brNull.CreateStockObject(NULL_BRUSH);
    CPen* pOldPen = memDC->SelectObject(&penOK);
    CBrush* pOldBrush = memDC->SelectObject(&brNull);
    auto DrawOne = [&](const CPoint(&pts)[RIP_POINT_COUNT], int nStatus, LPCTSTR label, double value_um, int index, int nAnchorX, int dy) {
        if (nStatus == 0) {
            return;
        }
        if (nStatus == 1) {
            memDC->SelectObject(&penOK);
            memDC->SetTextColor(RGB(0, 255, 0));
        }
        else {
            memDC->SelectObject(&penNG);
            memDC->SetTextColor(RGB(255, 0, 0));
        }
        CPoint p0 = GetWndPos(pts[0]);
        CPoint p1 = GetWndPos(pts[1]);
        memDC->MoveTo(p0); memDC->LineTo(p1);
        auto Cross = [&](const CPoint& p) {
            memDC->MoveTo(p.x - 3, p.y - 3); memDC->LineTo(p.x + 3, p.y + 3);
            memDC->MoveTo(p.x + 3, p.y - 3); memDC->LineTo(p.x - 3, p.y + 3);
        };
        Cross(p0); Cross(p1);
        CPoint mid{ (p0.x + p1.x) / 2, (p0.y + p1.y) / 2 };
        CString s; s.Format(_T("%s[%02d]: %.1f um"), label, index + 1, value_um);
        memDC->TextOut(nAnchorX, mid.y + dy, s);
    };
    const int DY = 16;
    for (int i = 0; i < MAX_RIP_SAMPLE_COUNT; ++i) {
        CPoint L0 = GetWndPos(pSideData->m_ptSideRip_Left_pxl[i][0]);
        CPoint L1 = GetWndPos(pSideData->m_ptSideRip_Left_pxl[i][1]);
        CPoint R0 = GetWndPos(pSideData->m_ptSideRip_Right_pxl[i][0]);
        CPoint R1 = GetWndPos(pSideData->m_ptSideRip_Right_pxl[i][1]);
        CPoint G0 = GetWndPos(pSideData->m_ptSideRip_Glass_pxl[i][0]);
        CPoint G1 = GetWndPos(pSideData->m_ptSideRip_Glass_pxl[i][1]);
        int nAnchorX = max(max(max(L0.x, L1.x), max(R0.x, R1.x)), max(G0.x, G1.x)) + 6;
        if (nAnchorX > DISPLAY_FRAME_WIDTH / 2) {
            nAnchorX = DISPLAY_FRAME_WIDTH / 2 - 100;
        }
        // Left
        DrawOne(pSideData->m_ptSideRip_Left_pxl[i], pSideData->m_nSideRip_Left_Status[i], _T("Rip-Left"), pSideData->m_dSideRip_Left_um[i], i, nAnchorX , -DY);
        // Glass
        DrawOne(pSideData->m_ptSideRip_Glass_pxl[i], pSideData->m_nSideRip_Glass_Status[i], _T("Rip-Glass"), pSideData->m_dSideRip_Glass_um[i], i, nAnchorX, 0);
        // Right
        DrawOne(pSideData->m_ptSideRip_Right_pxl[i], pSideData->m_nSideRip_Right_Status[i], _T("Rip-Right"), pSideData->m_dSideRip_Right_um[i], i, nAnchorX, +DY);
    }
    memDC->SelectObject(pOldPen);
    memDC->SelectObject(pOldBrush);
    brNull.DeleteObject();
}
CRect CEdgeImageViewer::GetManualMeasureRect()
{
    bool bManualMeasure = m_MenuStatus[MODE_USER_SELECT];
EdgeInspector_App/View/EdgeImageViewer.h
@@ -130,6 +130,7 @@
    void UpdateView_MeasureSideDimensionResult(CDC* memDC);
    void UpdateView_Frame(CDC* memDC);
    void UpdateView_MousePoint(CDC* memDC);
    void UpdateView_SideRipThickness(CDC* memDC);
public:
    CRect    GetManualMeasureRect();
EdgeInspector_App/ViewMain_Recipe.cpp
@@ -1657,7 +1657,7 @@
        nRows = 14;
        break;
    case eRcp_InsType_RipThickness:
        nRows = 10;
        nRows = 15;
        break;
    default:
        break;
@@ -1855,6 +1855,16 @@
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. B Offset"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. Use (0:OFF/1:ON)"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. Range (um)"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. SideLine Offset (um)"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. Min Thres"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Ins. Max Thres"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        CLanguageControl* pLanguageControl = g_pStatus->m_pLanguageControl;
@@ -1911,7 +1921,7 @@
        nRows = 11;
        break;
    case eRcp_InsType_RipThickness:
        nRows = 7;
        nRows = 10;
        break;
    default:
        break;
@@ -2069,17 +2079,23 @@
    }
    else if (eRcp_InsType_RipThickness == m_eSelectInsType) {
        std::vector<CString> vecParams;
        strTemp.Format(_T("Glass Size Min um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Glass %s Size Min um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("Glass Size Max um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Glass %s Size Max um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("Left Rip Size Min um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Left %s Rip Size Min um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("Left Rip Size Max um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Left %s Rip Size Max um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("Right Rip Size Min um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Right %s Rip Size Min um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("Right Rip Size Max um"), g_strInsType[m_eSelectInsType]);
        strTemp.Format(_T("Right %s Rip Size Max um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Rip Judge Size Min X um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Rip Judge Size Min Y um"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        strTemp.Format(_T("%s Rip Judge Mode (0:NoUse/1:OR/2:AND)"), g_strInsType[m_eSelectInsType]);
        vecParams.push_back(strTemp);
        CLanguageControl* pLanguageControl = g_pStatus->m_pLanguageControl;
@@ -2608,27 +2624,28 @@
                strTemp.Format(_T("%d"), rip.m_nBottomOffset);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
                // 10.  RIP Inspect Use
                m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor);
                // 10. RIP Inspect Use
                if (rip.m_bRipUseInspect)  m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(RGB(50, 255, 50));
                else                       m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(RGB(255, 50, 50));
                strTemp.Format(_T("%d"), rip.m_bRipUseInspect);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
                // 11.  RIP Inspect Range
                // 11. RIP Inspect Range
                m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor);
                strTemp.Format(_T("%d"), rip.m_nRipInspect_Range_um);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
                // 12.  RIP Inspect SideLine Offset
                // 12. RIP Inspect SideLine Offset
                m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor);
                strTemp.Format(_T("%d"), rip.m_nRipInspect_SideLine_Offset_um);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
                // 13.  RIP Min Threshold
                // 13. RIP Min Threshold
                m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor);
                strTemp.Format(_T("%d"), rip.m_nRipMin_Threshold);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
                // 14.  RIP Min Threshold
                // 14. RIP Min Threshold
                m_SideInspectInfo.GetCell(nRowIdx, nColIdx)->SetBackClr(uCellColor);
                strTemp.Format(_T("%d"), rip.m_nRipMax_Threshold);
                m_SideInspectInfo.SetItemText(nRowIdx++, nColIdx, strTemp);
@@ -2841,23 +2858,23 @@
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_nBottomOffset = _wtoi(strTemp);
                // 10.  RIP Inspect Use
                // 10. RIP Inspect Use
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_bRipUseInspect = _wtoi(strTemp);
                // 11.  RIP Inspect Range
                // 11. RIP Inspect Range
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_nRipInspect_Range_um = _wtoi(strTemp);
                // 12.  RIP Inspect SideLine Offset
                // 12. RIP Inspect SideLine Offset
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_nRipInspect_SideLine_Offset_um = _wtoi(strTemp);
                // 13.  RIP Min Threshold
                // 13. RIP Min Threshold
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_nRipMin_Threshold = _wtoi(strTemp);
                // 14.  RIP Min Threshold
                // 14. RIP Min Threshold
                strTemp = m_SideInspectInfo.GetItemText(nRowIdx++, nColIdx);
                rip.m_nRipMax_Threshold = _wtoi(strTemp);
            }