// Glass.cpp: implementation of the CGlass class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Glass_Data.h" #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CGlass_Data::CGlass_Data(void) { m_pGlassRecipe = NULL; m_pHardwareSetting = NULL; m_nStageNo = 0; m_bSimulation = FALSE; ResetGlass(); } CGlass_Data::~CGlass_Data() { ResetDefect(); } void CGlass_Data::ResetDefect() { HANDLE hThread = GetCurrentThread(); CSingleLock localLock(&m_csGlassDefect); localLock.Lock(); SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); m_nCurDefectIdx_NG = 0; m_nCurDefectIdx_OK = 0; m_nJudgeDefectCount = 0; m_nCurDefectIdx_Total = 0; CDefect* pData; for (MapDefectIt it = m_MapDefect_NG.begin(); it != m_MapDefect_NG.end(); it++) { pData = static_cast (it->second); delete pData; pData = NULL; } m_MapDefect_NG.clear(); for (MapDefectIt it = m_MapDefect_OK.begin(); it != m_MapDefect_OK.end(); it++) { pData = static_cast (it->second); delete pData; pData = NULL; } m_MapDefect_OK.clear(); SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); localLock.Unlock(); } void CGlass_Data::ResetGlass() { ResetDefect(); m_strLoadingTime = _T(""); m_strUnloadingTime = _T(""); m_strScanStartTime = _T(""); m_strScanEndTime = _T(""); m_bPostProcessing = FALSE; for(int i=0; i 0) { pDefect = static_cast(it->second); if (pDefect != NULL && pDefect->m_nIdx == nDefecIdx) { return pDefect; } } } return NULL; } CDefect* CGlass_Data::GetDefect_OK(int nDefecIdx) { CDefect *pDefect = NULL; for(MapDefectIt it=m_MapDefect_OK.begin();it!=m_MapDefect_OK.end();it++) { if (m_nCurDefectIdx_OK > 0) { pDefect = static_cast(it->second); if (pDefect != NULL && pDefect->m_nIdx == nDefecIdx) { return pDefect; } } } return NULL; } BOOL CGlass_Data::TrimString(const CString& strDataInput, std::vector &arrString, const CString& strSign/*=_T(",")*/) { /* code */ arrString.clear(); CString strData = strDataInput; strData.Trim(); //??3y??óD????μ??é?? if (strData.IsEmpty()) { return TRUE; } if (-1 == strData.Find(strSign)) { //2?°üo?·???·? arrString.push_back(strData); return TRUE; } while (0 == strData.Find(strSign)) { //?-?·é?3yê×??é?μ?·???·? strData.Delete(0, strSign.GetLength()); } strData += strSign; CString str = _T(""); long lIndex = strData.Find(strSign); while (-1 < lIndex) { str.Empty(); str = strData.Left(lIndex).Trim(); if (!str.IsEmpty()) { arrString.push_back(str); } strData.Delete(0, lIndex + strSign.GetLength()); lIndex = strData.Find(strSign); } return TRUE; } int CGlass_Data::DecodePose(CString strDirection) { /* code */ USES_CONVERSION; std::string strCode(W2A(strDirection)); if (0 == strCode.compare("C1-L")) { return 0; } else if (0 == strCode.compare("C1-S")) { return 1; } else if (0 == strCode.compare("C1-C2")) { return 2; } else if (0 == strCode.compare("C1-C4")) { return 3; } else if (0 == strCode.compare("C2-L")) { return 4; } else if (0 == strCode.compare("C2-S")) { return 5; } else if (0 == strCode.compare("C2-C3")) { return 6; } else if (0 == strCode.compare("C3-L")) { return 7; } else if (0 == strCode.compare("C3-S")) { return 8; } else if (0 == strCode.compare("C3-C4")) { return 9; } else if (0 == strCode.compare("C4-L")) { return 10; } else if (0 == strCode.compare("C4-S")) { return 11; } return -1; } int CGlass_Data::DecodeDefectPose(CDefect_Info *pDefect, CString& strResult, const int defaultInt) { /* code */ int nRet = defaultInt; if (pDefect == NULL) { return nRet; } //1. SideData int idx = pDefect->m_nSideIdx; CSide_Data *pSideData = &m_SideData[idx]; if (!pSideData->m_bFindGlassStartLine) { return nRet; } int nStartLine = pSideData->m_nGlassStartLine; CSIDE_PARM *pSideParam = &m_pGlassRecipe->m_SideParam[idx]; int yMinEdge = nStartLine + pSideParam->m_nCenterJudgeArea_StartLine_To_Start_pxl; int yMaxEdge = nStartLine + pSideParam->m_nCenterJudgeArea_StartLine_To_End_pxl; int yPos = (int)(pDefect->m_ptDefectPos_pxl.y); CString strSign = _T("-"); std::vector vStrings; TrimString(pSideParam->m_strPosDirection, vStrings, strSign); if (vStrings.size() < 3) { strResult.Format(_T("------")); return nRet; } if (yPos <= yMinEdge) { nRet = 0; strResult.Format(_T("%s-%s"), vStrings[0], vStrings[2]); } else if (yPos >= yMaxEdge) { nRet = 2; strResult.Format(_T("%s-%s"), vStrings[1], vStrings[2]); } else { nRet = 1; strResult.Format(_T("%s-%s"), vStrings[0], vStrings[1]); } nRet = DecodePose(strResult); return nRet; } int CGlass_Data::PointToLineDistance(CPoint A, CPoint B, CPoint C) { int nDistance = -1; int A_coeff = B.y - A.y; int B_coeff = A.x - B.x; int C_coeff = B.x * A.y - A.x * B.y; if (0 == A_coeff && 0 == B_coeff) { nDistance = std::sqrt((C.y - A.y) * (C.y - A.y) - (C.x - A.x) * (C.x - A.x)); return nDistance; } nDistance = std::abs(A_coeff * C.x + B_coeff * C.y + C_coeff) / std::sqrt(A_coeff * A_coeff + B_coeff * B_coeff); return nDistance; } CPoint CGlass_Data::RotatePoint(CPoint p, double angle) { double rad = angle * M_PI / 180.0; double cosAngle = cos(rad); double sinAngle = sin(rad); CPoint ptRot; ptRot.x = static_cast(round(p.x * cosAngle - p.y * sinAngle)); ptRot.y = static_cast(round(p.x * sinAngle + p.y * cosAngle)); return ptRot; } CPoint CGlass_Data::TransformToGlobal(DimensionDir eDir, CPoint localPoint) { int nGlassSizeY = m_pGlassRecipe->m_SideParam[DIMENSION_A].m_nSidePanelSize_um; int nGlassSizeX = m_pGlassRecipe->m_SideParam[DIMENSION_B].m_nSidePanelSize_um; std::map corners = { {_T("C1"), {0, 0}}, {_T("C2"), {nGlassSizeX, 0}}, {_T("C3"), {nGlassSizeX, nGlassSizeY}}, {_T("C4"), {0, nGlassSizeY}} }; std::vector vStrings; TrimString(m_pGlassRecipe->m_SideParam[eDir].m_strPosDirection, vStrings, _T("-")); CPoint globalPoint = { 0, 0 }; if (vStrings.size() != 3) return globalPoint; CSide_Data* pSideData = &m_SideData[eDir]; if (!pSideData->m_bFindGlassStartLine) return globalPoint; CPoint ptSideEnd = { 0, 0 }; for (int i = 0; i < MAX_IMAGE_FRAME - 1; i++) { if (pSideData->m_nSideLineFrame[i + 1] < 0) { ptSideEnd.x = pSideData->m_nSideLineFrame[i]; ptSideEnd.y = ((pSideData->m_nGlassEndLine <= 0) ? pSideData->m_nPreGlassEndLine : pSideData->m_nGlassEndLine); break; } } double dAngle = atan2(ptSideEnd.y - pSideData->m_nGlassStartLine, ptSideEnd.x - pSideData->m_nSideLineFrame[0]) * 180.0 / M_PI; CPoint ptDefect = RotatePoint(CPoint(localPoint.x - pSideData->m_nSideLineFrame[0], localPoint.y - pSideData->m_nGlassStartLine), 90 - dAngle); ptDefect.x *= static_cast(round(pSideData->m_dPixelSizeX)); ptDefect.y *= static_cast(round(pSideData->m_dPixelSizeY)); if (ptDefect.x < 0 || ptDefect.y < 0) return globalPoint; auto itStart = corners.find(vStrings[0]); auto itEnd = corners.find(vStrings[1]); if (itStart == corners.end() || itEnd == corners.end()) return globalPoint; CPoint ptStart = itStart->second; CPoint ptEnd = itEnd->second; dAngle = atan2(ptEnd.y - ptStart.y, ptEnd.x - ptStart.x); globalPoint.x = ptDefect.y * cos(dAngle) - ptDefect.x * sin(dAngle) + ptStart.x; globalPoint.y = ptDefect.y * sin(dAngle) - ptDefect.x * cos(dAngle) + ptStart.y; return globalPoint; } BOOL CGlass_Data::SetDefect(CDefect* pDefect) { if (pDefect == NULL) return FALSE; int nSideIdx = pDefect->m_DefectInfo.m_nScanIdx; if(nSideIdx < 0 || MAX_SIDE_COUNT <= nSideIdx) return FALSE; CSingleLock localLock(&m_csGlassDefect); localLock.Lock(); m_nCurDefectIdx_Total++; m_SideData[nSideIdx].m_nTotalDefectCount++; if(pDefect->m_bJudge_NG == TRUE) { pDefect->m_nIdx = m_nCurDefectIdx_NG; m_MapDefect_NG.insert(std::make_pair(pDefect->m_nIdx, pDefect)); m_nCurDefectIdx_NG++; m_SideData[nSideIdx].m_nNgDefectCount++; m_nJudgeDefectCount++; } else { pDefect->m_nIdx = m_nCurDefectIdx_OK; m_MapDefect_OK.insert(std::make_pair(pDefect->m_nIdx, pDefect)); m_nCurDefectIdx_OK++; } localLock.Unlock(); return TRUE; } ////////////////////////////////////////////////////////////////////////// // Scan void CGlass_Data::SetLoadingTime() { CTime time = CTime::GetCurrentTime(); m_tLoadingTime = time; m_strLoadingTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); m_strLoadingDayFileName.Format(_T("%04d%02d%02d"),time.GetYear(),time.GetMonth(),time.GetDay()); m_strLoadingTimeFileName.Format(_T("%02d%02d%02d"),time.GetHour(),time.GetMinute(),time.GetSecond()); } void CGlass_Data::SetUnloadingTime() { CTime time = CTime::GetCurrentTime(); m_strUnloadingTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); } void CGlass_Data::SetScanStartTime() { CTime time = CTime::GetCurrentTime(); m_strScanStartTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); } void CGlass_Data::SetScanEndTime() { CTime time = CTime::GetCurrentTime(); m_strScanEndTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond()); m_strScanEndTimeFileName.Format(_T("%04d_%02d_%02d"),time.GetYear(),time.GetMonth(),time.GetDay()); } void CGlass_Data::GetStageTheta(int iStage,short &nLongTheta,short &nShortTheta) { nLongTheta = m_nStageLongTheta[iStage]; nShortTheta = m_nStageShortTheta[iStage]; } void CGlass_Data::SetStageTheta(int iStage,BOOL bLong,short nTheta) { if(iStage < 0 || iStage > 1) { g_pLog->DisplayMessage(_T("Stage Theta Index Not Normal : %d"),iStage); return; } if(bLong == TRUE) { m_nStageLongTheta[iStage] = nTheta; } else { m_nStageShortTheta[iStage] = nTheta; } }