#pragma once #include "stdafx.h" #include "CGBCalculate.h" #include "OTSFieldData.h" #include "GBImgPropCal.h" #include "OTSHelper.h" #include "OTSImageProcess.h" namespace OTSGBCalculate { using namespace OTSDATA; using namespace OTSIMGPROC; CGBCalculate::CGBCalculate(CReportMgr* rptMgrPtr) { m_rptMgrPtr = rptMgrPtr; } CGBCalculate::~CGBCalculate() { } // class methods // public CGridDatasList CGBCalculate::GetGBInclusion() { // use the dll resource AFX_MANAGE_STATE(AfxGetStaticModuleState()); CGBFieldList listCGBField; //CGBFieldMgr pCGBFieldMgr; COTSParticleList listOTSParticle; COTSParticlePtr pOTSParticle; CGBImgPropCal pGBImgPropCal; CGridDatasList listGridData; listGridData.clear(); CGridDatasList multGridList; multGridList.clear(); // depart compound source name CPropParamPtr currentProp = m_rptMgrPtr->GetPropertyParamGrid(); std::vector listDataSource = currentProp->GetDataSourceList(); int nSelectedDataSourceIndex = currentProp->GetDataSourceId(); CString sDataSourceNames = listDataSource[nSelectedDataSourceIndex]; std::vector listSelectedDataSource = COTSHelper::SplitString(sDataSourceNames, _T("+")); for (auto strDataSourceName : listSelectedDataSource) { listCGBField.clear(); CGridDataPtr pGridData = CGridDataPtr(new CGridData()); // data source id std::vector listDataSource; listDataSource.clear(); listDataSource = currentProp->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = currentProp->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); CSmplMsrResultFileMgrPtr rstFileMgrPrt = m_rptMgrPtr->GetASmplMsrResultMgrByFileName(strDataSourceName); // sample measurment result file manager CSmplMsrResultFileMgr* pSmplMsrResultFileMgr; pSmplMsrResultFileMgr = rstFileMgrPrt.get(); CSmplMsrResultFilePtr pSmplMsrResultFile = pSmplMsrResultFileMgr->GetSmplMsrResultFile(); COTSSamplePtr pSample = pSmplMsrResultFile->GetSample(); double dPixelSize = pSample->GetPixelSize(); SetPixSize(dPixelSize); CGBFieldList listRawGBFields=CalGBFields(pSmplMsrResultFileMgr); listCGBField = listRawGBFields; //for each (COTSFieldDataPtr GBfield in listRawGBFields) //{ // listOTSParticle = GBfield->GetParticleList(); // for each (COTSParticlePtr Particle in listOTSParticle) // { // double a_dPartFTD; // double a_dMinWidth; // double a_dMaxLength; // double a_dRatio; // /*pGBImgPropCal.GetParticleFTD(Particle, dPixelSize, a_dPartFTD, a_dMinWidth , a_dMaxLength, a_dRatio); // // Particle->SetFeretDiameter(a_dPartFTD); // // Particle->SetWidth(a_dMinWidth); // Particle->SetHeight(a_dMaxLength);*/ // } // //cal stdFrame // CGBFieldDataPtr GBFld(new CGBFieldData()); // GBFld->SetParticleList(listOTSParticle,TRUE); // GBFld->SetPosition(GBfield->GetPosition()); // // listCGBField.push_back(GBFld); //} CALCULATE_TABLE_TYPE ty = m_rptMgrPtr->GetPropertyParamGrid()->GetCalTableType(); if (ty == CALCULATE_TABLE_TYPE::DIN) { listGridData = this->GetGridDataListForOneDataSourceDIN(pSmplMsrResultFile->GetAllParticles(), ty); } else { listGridData = this->GetGridDataListForOneDataSource(listCGBField, ty); } multGridList.insert (multGridList.end (), listGridData.begin(), listGridData.end()); } return multGridList; } CGridDatasList CGBCalculate::GetGridDataListForOneDataSource(CGBFieldList listCGBField, CALCULATE_TABLE_TYPE tableType) { CGridDatasList listGridData; //Definition numbers //use the nXLevel array to memory how many fields in each level. CONST int LEVEL_LENGTH = 11; int nALevel[LEVEL_LENGTH]; //nALevelZero, nALevel_0_5, nALevel_1_0, nALevel_1_5, nALevel_2_0, nALevel_2_5, nALevel_3_0, nALevel_3_5, nALevel_4_0, nALevel_4_5, nALevel_5_0 ; int nALevel_w[LEVEL_LENGTH]; //nALevelZero_f, nALevel_0_5_f, nALevel_1_0_f, nALevel_1_5_f, nALevel_2_0_f, nALevel_2_5_f, nALevel_3_0_f, nALevel_3_5_f, nALevel_4_0_f, nALevel_4_5_f, nALevel_5_0_f; int nALevel_s[LEVEL_LENGTH]; int nBLevel[LEVEL_LENGTH]; //nBLevelZero, nBLevel_0_5, nBLevel_1_0, nBLevel_1_5, nBLevel_2_0, nBLevel_2_5, nBLevel_3_0, nBLevel_3_5, nBLevel_4_0, nBLevel_4_5, nBLevel_5_0; int nBLevel_w[LEVEL_LENGTH]; //nBLevelZero_f, nBLevel_0_5_f, nBLevel_1_0_f, nBLevel_1_5_f, nBLevel_2_0_f, nBLevel_2_5_f, nBLevel_3_0_f, nBLevel_3_5_f, nBLevel_4_0_f, nBLevel_4_5_f, nBLevel_5_0_f; int nBLevel_s[LEVEL_LENGTH]; int nCLevel[LEVEL_LENGTH]; //nCLevelZero, nCLevel_0_5, nCLevel_1_0, nCLevel_1_5, nCLevel_2_0, nCLevel_2_5, nCLevel_3_0, nCLevel_3_5, nCLevel_4_0, nCLevel_4_5, nCLevel_5_0; int nCLevel_w[LEVEL_LENGTH]; //nCLevelZero_f, nCLevel_0_5_f, nCLevel_1_0_f, nCLevel_1_5_f, nCLevel_2_0_f, nCLevel_2_5_f, nCLevel_3_0_f, nCLevel_3_5_f, nCLevel_4_0_f, nCLevel_4_5_f, nCLevel_5_0_f; int nCLevel_s[LEVEL_LENGTH]; int nDLevel[LEVEL_LENGTH];// nDLevelZero, nDLevel_0_5, nDLevel_1_0, nDLevel_1_5, nDLevel_2_0, nDLevel_2_5, nDLevel_3_0, nDLevel_3_5, nDLevel_4_0, nDLevel_4_5, nDLevel_5_0; int nDLevel_w[LEVEL_LENGTH]; //nDLevelZero_f, nDLevel_0_5_f, nDLevel_1_0_f, nDLevel_1_5_f, nDLevel_2_0_f, nDLevel_2_5_f, nDLevel_3_0_f, nDLevel_3_5_f, nDLevel_4_0_f, nDLevel_4_5_f, nDLevel_5_0_f; int nDLevel_s[LEVEL_LENGTH]; int nDSulfideLevel[LEVEL_LENGTH];// nDLevelZero, nDLevel_0_5, nDLevel_1_0, nDLevel_1_5, nDLevel_2_0, nDLevel_2_5, nDLevel_3_0, nDLevel_3_5, nDLevel_4_0, nDLevel_4_5, nDLevel_5_0; int nDSulfideLevel_w[LEVEL_LENGTH]; //nDLevelZero_f, nDLevel_0_5_f, nDLevel_1_0_f, nDLevel_1_5_f, nDLevel_2_0_f, nDLevel_2_5_f, nDLevel_3_0_f, nDLevel_3_5_f, nDLevel_4_0_f, nDLevel_4_5_f, nDLevel_5_0_f; int nDSulfideLevel_s[LEVEL_LENGTH]; CGBFieldList listDSFrame; //initlize for (int i = 0; i < LEVEL_LENGTH; i++) { nALevel[i]= 0; nALevel_w[i] = 0; nALevel_s[i] = 0; nBLevel[i]=0; nBLevel_w[i] = 0; nBLevel_s[i]=0; nCLevel[i]=0; nCLevel_w[i]=0; nCLevel_s[i]=0; nDLevel[i]=0; nDLevel_w[i]=0; nDLevel_s[i] = 0; nDSulfideLevel[i] = 0; nDSulfideLevel_w[i] = 0; nDSulfideLevel_s[i] = 0; } //loop CGBField list and cal the level numbers for (CGBFieldDataPtr GBFld : listCGBField) { //CalLevel mode switch (tableType) { case CALCULATE_TABLE_TYPE::GB_Method1: GBFld->CaculateLevelByMethod1(); break; case CALCULATE_TABLE_TYPE::GB_Method2: GBFld->CaculateLevelByMethod2(); break; case CALCULATE_TABLE_TYPE::ASTM: GBFld->CaculateLevelASTM(); break; default: break; } GB_GRADE_TYPE levelt = GBFld->GetALevel()->GetThinGrade(); GB_GRADE_TYPE levelw = GBFld->GetALevel()->GetWideGrade(); GB_GRADE_TYPE levels = GBFld->GetALevel()->GetSuperGrade(); SetFrameLevelNo(levelt, nALevel); SetFrameLevelNo(levelw, nALevel_w); SetFrameLevelNo(levels, nALevel_s); levelt = GBFld->GetBLevel()->GetThinGrade(); levelw = GBFld->GetBLevel()->GetWideGrade(); levels = GBFld->GetBLevel()->GetSuperGrade(); SetFrameLevelNo(levelt, nBLevel); SetFrameLevelNo(levelw, nBLevel_w); SetFrameLevelNo(levels, nBLevel_s); levelt = GBFld->GetCLevel()->GetThinGrade(); levelw = GBFld->GetCLevel()->GetWideGrade(); levels = GBFld->GetCLevel()->GetSuperGrade(); SetFrameLevelNo(levelt, nCLevel); SetFrameLevelNo(levelw, nCLevel_w); SetFrameLevelNo(levels, nCLevel_s); levelt = GBFld->GetDLevel()->GetThinGrade(); levelw = GBFld->GetDLevel()->GetWideGrade(); levels = GBFld->GetDLevel()->GetSuperGrade(); SetFrameLevelNo(levelt, nDLevel); SetFrameLevelNo(levelw, nDLevel_w); SetFrameLevelNo(levels, nDLevel_s); } //Get ListGrid for Level //CalLevel mode CGridDataPtr AGrid; CGridDataPtr BGrid; CGridDataPtr CGrid; CGridDataPtr DGrid; CGridDataPtr DSulfideGrid; CGridDataPtr DSGrid; CGridDataPtr GBFieldGrid; switch (tableType) { case CALCULATE_TABLE_TYPE::GB_Method1: AGrid = GetGridLevel("A", nALevel, nALevel_w, nALevel_s); BGrid = GetGridLevel("B", nBLevel, nBLevel_w, nBLevel_s); CGrid = GetGridLevel("C", nCLevel, nCLevel_w, nCLevel_s); DGrid = GetGridLevel("D", nDLevel, nDLevel_w, nDLevel_s); DSGrid = GetGridDSLevel(listCGBField); GBFieldGrid = GetGBFieldGrid(listCGBField); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSGrid); listGridData.push_back(GBFieldGrid); //listGridData return listGridData; break; case CALCULATE_TABLE_TYPE::GB_Method2: AGrid = GetGridLevel("A", nALevel, nALevel_w, nALevel_s); BGrid = GetGridLevel("B", nBLevel, nBLevel_w, nBLevel_s); CGrid = GetGridLevel("C", nCLevel, nCLevel_w, nCLevel_s); DGrid = GetGridLevel("D", nDLevel, nDLevel_w, nDLevel_s); DSulfideGrid = GetGridLevel("DSulfide", nDSulfideLevel, nDSulfideLevel_w, nDSulfideLevel_s); DSGrid = GetGridDSLevel(listCGBField); GBFieldGrid = GetGBFieldGrid(listCGBField); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSulfideGrid); listGridData.push_back(DSGrid); listGridData.push_back(GBFieldGrid); //listGridData return listGridData; break; case CALCULATE_TABLE_TYPE::ASTM: AGrid = GetGridLevel("A", nALevel, nALevel_w, nALevel_s); BGrid = GetGridLevel("B", nBLevel, nBLevel_w, nBLevel_s); CGrid = GetGridLevel("C", nCLevel, nCLevel_w, nCLevel_s); DGrid = GetGridLevel("D", nDLevel, nDLevel_w, nDLevel_s); DSGrid = GetGridDSLevel(listCGBField); GBFieldGrid = GetGBFieldGrid(listCGBField); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSGrid); listGridData.push_back(GBFieldGrid); //listGridData return listGridData; break; default: return listGridData; break; } } CGridDatasList CGBCalculate::GetGridDataListForOneDataSourceDIN(COTSParticleList listParticle, CALCULATE_TABLE_TYPE tableType ) { CGridDatasList listGridData; COTSParticleList cotsparticlelistA; set cotsparticlelistB; COTSParticleList cotsparticlelistC; COTSParticleList cotsparticlelistD; //loop CGBField list and cal the level numbers CGBFieldDataPtr GBFld(new CGBFieldData()); GBFld->SetParticleList(listParticle, TRUE); GBFld->CaculateLevelDIN(listParticle); cotsparticlelistA = GBFld->listAThinParticles; cotsparticlelistB = GBFld->listBThinParticles; cotsparticlelistC = GBFld->listCThinParticles; cotsparticlelistD = GBFld->listDThinParticles; //Get ListGrid for Level //CalLevel mode CGridDataPtr AGrid; AGrid = GetGridDIN(cotsparticlelistA, cotsparticlelistB, cotsparticlelistC, cotsparticlelistD); listGridData.push_back(AGrid); //listGridData return listGridData; } //CGridDataPtr CGBFieldMgr::GetGBFieldGrid(CGBFieldList listCGBField, CGridInPtr a_pGridIn); CGridDataPtr CGBCalculate::GetGBFieldGrid(CGBFieldList listCGBField) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 11;//表格总列数 fieldpos 占2列,ABCDDS 占5列,particle占1列,particle 类别占1列,particle宽度占1列 CGridColumnPtr pColumn; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; switch (i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("FieldPosX"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(GBF->GetPosition().x); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 1: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("FieldPosY"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(GBF->GetPosition().y); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 2: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("ALevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string Athin, Awide, Asuper; auto Alevel = GBF->GetALevel(); auto thin = Alevel->GetThinGrade(); Athin = GetLevelStr(thin); Awide = GetLevelStr(Alevel->GetWideGrade()); Asuper = GetLevelStr(Alevel->GetSuperGrade()); pRow->SetStringValue((Athin + "," + Awide + "," + Asuper).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 3: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("BLevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string thin, wide, super; auto level = GBF->GetBLevel(); thin = GetLevelStr(level->GetThinGrade()); wide = GetLevelStr(level->GetWideGrade()); super = GetLevelStr(level->GetSuperGrade()); pRow->SetStringValue((thin + "," + wide + "," + super).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 4: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("CLevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string thin, wide, super; auto level = GBF->GetCLevel(); thin = GetLevelStr(level->GetThinGrade()); wide = GetLevelStr(level->GetWideGrade()); super = GetLevelStr(level->GetSuperGrade()); pRow->SetStringValue((thin + "," + wide + "," + super).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 5: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("DLevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string thin, wide, super; auto level = GBF->GetDLevel(); thin = GetLevelStr(level->GetThinGrade()); wide = GetLevelStr(level->GetWideGrade()); super = GetLevelStr(level->GetSuperGrade()); pRow->SetStringValue((thin + "," + wide + "," + super).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 6: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("DSLevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string thin, wide, super; auto level = GBF->GetDSLevel(); thin = GetLevelStr(level->GetThinGrade()); wide = GetLevelStr(level->GetWideGrade()); super = GetLevelStr(level->GetSuperGrade()); pRow->SetStringValue((thin + "," + wide + "," + super).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 7: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("DSulfideLevel"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING ); std::string thin, wide, super; auto level = GBF->GetDSulfideLevel(); thin = GetLevelStr(level->GetThinGrade()); wide = GetLevelStr(level->GetWideGrade()); super = GetLevelStr(level->GetSuperGrade()); pRow->SetStringValue((thin + "," + wide + "," + super).c_str()); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 8: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("Particle"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { pRow = CGridRowPtr(new CGridRow()); pRow->SetParticle(p); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 9: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("ParticleGBClass"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { int l = (int)GBF->mapAllParticles[p].myType; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(l); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 10: pColumn = CGridColumnPtr(new CGridColumn()); pColumn->SetName("ParticleGBWidthClass"); for (auto GBF : listCGBField) { for (auto p : GBF->GetParticleList()) { int w = (int)GBF->mapAllParticles[p].myWidth; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(w); listRows.push_back(pRow); } } pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; default: break; } } pGridData->SetGridColumnList(listCol); return pGridData; } std::string CGBCalculate::GetLevelStr(GB_GRADE_TYPE l) { std::string s; switch (l) { case GB_GRADE_TYPE::POINT_0_0 : s = "0"; break; case GB_GRADE_TYPE::POINT_0_5: s = "0.5"; break; case GB_GRADE_TYPE::POINT_1_0: s = "1"; break; case GB_GRADE_TYPE::POINT_1_5: s = "1.5"; break; case GB_GRADE_TYPE::POINT_2_0: s = "2"; break; case GB_GRADE_TYPE::POINT_2_5: s = "2.5"; break; case GB_GRADE_TYPE::POINT_3_0: s = "3"; break; case GB_GRADE_TYPE::POINT_3_5: s = "3.5"; break; case GB_GRADE_TYPE::POINT_4_0: s = "4"; break; case GB_GRADE_TYPE::POINT_4_5: s = "4.5"; break; case GB_GRADE_TYPE::POINT_5_0: s = "5"; break; default: s = "0"; break; } return s; } //get grid with level ABCD CGridDataPtr CGBCalculate::GetGridLevel(CString GridType,int a_nLevel[], int a_nLevel_w[], int a_nLevel_s[]) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 11 + 1 + 1;//表格总列数 12个级别再加上前面的“分类”列和“宽度/um”列 CGridColumnPtr pColumn; for (int i=0;i< columnNum;i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; switch( i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); //strName = MultiLang::GetInstance ().GetCStringByKey (GBStr1); strName = "Class"; pColumn->SetName(strName); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("Thin"); //MultiLang::GetInstance().GetCStringByKey(GBStr2) listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("Thick"); //MultiLang::GetInstance().GetCStringByKey(GBStr3) listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OverSize"); //MultiLang::GetInstance().GetCStringByKey(GBStr4) listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 1: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Width/um"; //MultiLang::GetInstance().GetCStringByKey(GBStr5); pColumn->SetName(strName); if (GridType == "A") { strWidthName1 = "2.0~4.0"; strWidthName2 = "4.0~12.0"; strWidthName3 = ">12.0"; } if (GridType == "B") { strWidthName1 = "2.0~9.0"; strWidthName2 = "9.0~15.0"; strWidthName3 = ">15.0"; } if (GridType == "C") { strWidthName1 = "2.0~5.0"; strWidthName2 = "5.0~12.0"; strWidthName3 = ">12.0"; } if (GridType == "D") { strWidthName1 = "2.0~8.0"; strWidthName2 = "8.0~13.0"; strWidthName3 = ">13.0"; } if (GridType == "DSulfide") { strWidthName1 = "2.0~8.0"; strWidthName2 = "8.0~13.0"; strWidthName3 = ">13.0"; } pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName1); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName2); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName3); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; default: pColumn = CGridColumnPtr(new CGridColumn()); CString name; name.Format(_T("%.1f"), (i - 2) / 2.0);//i=2 输出0 i=3 输出0.5 i=4 输出1 以此类推 pColumn->SetName(name); CGridRowsList listRows; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel[i - 2]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel_w[i - 2]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel_s[i - 2]); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; } } pGridData->SetGridColumnList(listCol); return pGridData; } CGridDataPtr CGBCalculate::GetGridDSLevel(CGBFieldList listCGBField) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 6; CGridColumnPtr pColumn; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows[6]; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; switch (i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); strName = "No."; //MultiLang::GetInstance().GetCStringByKey(GBStr6); pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[0]); listCol.push_back(pColumn); break; case 1: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Area/um2"; //MultiLang::GetInstance().GetCStringByKey(GBStr7); pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[1]); listCol.push_back(pColumn); break; case 2: pColumn = CGridColumnPtr(new CGridColumn()); strName = "MaxFeret/um";// MultiLang::GetInstance().GetCStringByKey(GBStr8); pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[2]); listCol.push_back(pColumn); break; case 3: pColumn = CGridColumnPtr(new CGridColumn()); strName = "X/mm"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[3]); listCol.push_back(pColumn); break; case 4: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Y/mm"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[4]); listCol.push_back(pColumn); break; case 5: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Grade";// MultiLang::GetInstance().GetCStringByKey(GBStr9); pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[5]); listCol.push_back(pColumn); break; } } for (CGBFieldDataPtr frame : listCGBField) { for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; switch (i) { case 0: pColumn = listCol.at(0); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(frame->GetFrameId()); pColumn->GetRowList ().push_back(pRow); break; case 1: pColumn = listCol.at(1); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(0); pColumn->GetRowList().push_back(pRow); break; case 2: pColumn = listCol.at(2); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetIntValue((int)frame->GetDSLevel()->GetMaxFeretDiameter()); pColumn->GetRowList().push_back(pRow); break; case 3: pColumn = listCol.at(3); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(0); pColumn->GetRowList().push_back(pRow); break; case 4: pColumn = listCol.at(4); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(0); pColumn->GetRowList().push_back(pRow); break; case 5: pColumn = listCol.at(5); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue((double)frame->GetDSLevel()->GetMyDSGrade()); pColumn->GetRowList().push_back(pRow); break; } } } pGridData->SetGridColumnList(listCol); return pGridData; } //get grid with level ABCD CGridDataPtr CGBCalculate::GetGridDIN(COTSParticleList cotsparticlelistA, set cotsparticlelistB, COTSParticleList cotsparticlelistC, COTSParticleList cotsparticlelistD) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 12;//表格总列数 11个级别再加上前面的“分类”列 CGridColumnPtr pColumn; int levA[9] = { 0,0,0,0,0,0,0,0,0 }; int levB[9] = { 0,0,0,0,0,0,0,0,0 }; int levC[9] = { 0,0,0,0,0,0,0,0,0 }; int levD[9] = { 0,0,0,0,0,0,0,0,0 }; double fg[9] = { 0.05,0.1,0.2,0.5,1,2,5,10,20 }; //指数 double ka = 0, kb = 0, kc = 0, kd = 0; //统计不同大小颗粒出现次数 for (auto pParticle : cotsparticlelistA) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levA[i] += 1; ka = ka + fg[i]; } } if (area >= fg[8]) { levA[8] += 1; ka = ka + fg[8]; } } for (auto pParticle : cotsparticlelistB) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levB[i] += 1; kb = kb + fg[i]; } } if (area >= fg[8]) { levB[8] += 1; kb = kb + fg[8]; } } for (auto pParticle : cotsparticlelistC) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levC[i] += 1; kc = kc + fg[i]; } } if (area >= fg[8]) { levC[8] += 1; kc = kc + fg[8]; } } for (auto pParticle : cotsparticlelistD) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levD[i] += 1; kd = kd + fg[i]; } } if (area >= fg[8]) { levD[8] += 1; kd = kd + fg[8]; } } double to = kb + kc + kd; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3, strWidthName4; switch (i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Class"; pColumn->SetName(strName); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("SS"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OA"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OS"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OG"); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 10: pColumn = CGridColumnPtr(new CGridColumn()); strName = "S"; pColumn->SetName(strName); strWidthName1.Format(_T("%lf"), ka); strWidthName2 = ""; strWidthName3 = ""; strWidthName4 = ""; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(ka); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 11: pColumn = CGridColumnPtr(new CGridColumn()); strName = "O"; pColumn->SetName(strName); strWidthName1.Format(_T("%lf"), to); strWidthName2 = ""; strWidthName3 = ""; strWidthName4 = ""; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kb); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kc); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kd); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; default: pColumn = CGridColumnPtr(new CGridColumn()); strName.Format("%d", i - 1); pColumn->SetName(strName); CGridRowsList listRows; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levA[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levB[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levC[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levD[i - 1]); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; } } pGridData->SetGridColumnList(listCol); return pGridData; } void CGBCalculate::SetFrameLevelNo(GB_GRADE_TYPE a_level, int a_nLevel[]) { a_nLevel[(int)a_level] += 1; } // calculate GB fields CGBFieldList CGBCalculate::CalGBFields(CSmplMsrResultFileMgr* pSmplMgr) { CGBFieldList m_listGBFields; m_listGBFields.clear(); ASSERT(pSmplMgr); CSmplMsrResultFilePtr pSmplMsrResultFile = pSmplMgr->GetSmplMsrResultFile(); ASSERT(pSmplMsrResultFile); COTSSamplePtr pOTSSample = pSmplMsrResultFile->GetSample(); ASSERT(pOTSSample); CSEMDataMsrPtr pEMDataMsrPtr = pOTSSample->GetSEMDataMsr(); ASSERT(pEMDataMsrPtr); // get field width int nOTSFieldWidth = pEMDataMsrPtr->GetScanFieldSize(); if (nOTSFieldWidth == 0) { LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: field width is zero .")); return m_listGBFields; } // cal a gb field need how many ots fields rows and columns int nOTSRowsForGBFld, nOTSColumnsForGBFld; CalOTSFieldsNo(nOTSRowsForGBFld, nOTSColumnsForGBFld, nOTSFieldWidth); if (nOTSRowsForGBFld == 0 || nOTSColumnsForGBFld == 0) { LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: nOTSRow|nOTSColumn is zero .")); return m_listGBFields; } // scan parameters CMsrParamsPtr pMsrParam = pOTSSample->GetMsrParams(); //CMsrParamsPtr pMsrParam = pOTSSample->get COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam(); // get image size OTS_FIVE_TIES_OPTIONS nImageSizeId = pImgScanParam->GetImagePixelSize(); int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId; CSize sizePixelImage = RESOLUTION_VALUE[nResulotionId]; //use OTSField width cal the OTSField height //get OTSfilds list COTSFieldDataList allOTSFields; allOTSFields = pSmplMsrResultFile->GetFieldData(); // convert ots fields to gb fields if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, nOTSRowsForGBFld, nOTSColumnsForGBFld,sizePixelImage, nOTSFieldWidth)) { LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: call OTSFieldToGBField failed.")); return m_listGBFields; } return m_listGBFields; } // protected // cal a gb field need how many ots fields rows and columns void CGBCalculate::CalOTSFieldsNo(int& a_nRow, int& a_nColumn, int a_nFieldWidth) { a_nRow = 0; a_nColumn = 0; if (a_nFieldWidth > 0) { a_nColumn = (int)ceil((double)GB_FIELD_WIDTH / (double)a_nFieldWidth); //OTSField Height always equal to 3 / 4 OTSField Width double dFieldHeight = (double)a_nFieldWidth * 3 / 4; a_nRow = (int)ceil((double)GB_FIELD_WIDTH / dFieldHeight); } } // Turn OTSField to GBField BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,int nOTSRowsPerGBfld, int nOTSColumnsPerGBFld,CSize sizePixelImage,int nOTSFieldWidth) { int nFieldHeight = (int)((double)nOTSFieldWidth * 3 / 4); // doing nothing if no field at all if (allOTSFields.empty()) { LogTrace(__FILE__, __LINE__, _T("CalGBFields: listOTSFields is empty .")); return TRUE; } // get topleft point and bottomright point of the measurement convered area CPoint pointTopleft, pointBottomright; pointTopleft = pointBottomright = allOTSFields[0]->GetPosition(); //判断有效区域 for (unsigned int i = 0; i< allOTSFields.size(); i++) { //get current OTSField Position,the position is in the center of the field CPoint poiOTSFieldPosition = allOTSFields[i]->GetPosition(); pointTopleft.x = min(poiOTSFieldPosition.x, pointTopleft.x); pointTopleft.y = min(poiOTSFieldPosition.y, pointTopleft.y); pointBottomright.x = max(poiOTSFieldPosition.x, pointBottomright.x); pointBottomright.y = max(poiOTSFieldPosition.y, pointBottomright.y); } // cal ots columns 有效区域内所有的OTScolumn数 int nOTSColumnNum = ((pointBottomright.x - pointTopleft.x) / nOTSFieldWidth) + 1; // cal ots rows有效区域内所有的OTSRow数 int nOTSRowNum = ((pointBottomright.y - pointTopleft.y) / nFieldHeight) + 1; int nPossibleGBFieldRowNum = nOTSRowNum /nOTSRowsPerGBfld;//可能有的国标field行数 int nPossibleGBFieldColNum = nOTSColumnNum / nOTSColumnsPerGBFld;//列数 // cal possible GBFields area CPoint pointPosibleAreaTopLeft = pointTopleft; //CPoint poiPosAreaBottomRight = poiBottomright; CPoint pointPossibleAreaBottomRight = pointTopleft; pointPosibleAreaTopLeft.x -= nOTSFieldWidth / 2; pointPosibleAreaTopLeft.y -= nFieldHeight / 2; //pointPossibleAreaBottomRight.x += (nPossibleGBFieldColNum * nOTSColumnsPerGBFld * nOTSFieldWidth - nOTSFieldWidth / 2); pointPossibleAreaBottomRight.x += (nPossibleGBFieldColNum * nOTSColumnsPerGBFld * nOTSFieldWidth ); //pointPossibleAreaBottomRight.y += (nPossibleGBFieldRowNum * nOTSRowsPerGBfld * nFieldHeight - nFieldHeight / 2); pointPossibleAreaBottomRight.y += (nPossibleGBFieldRowNum * nOTSRowsPerGBfld * nFieldHeight); // form rectangle of GBFields area CRect rectOTSFieldsCuted(pointPosibleAreaTopLeft, pointPossibleAreaBottomRight); rectOTSFieldsCuted.NormalizeRect(); if (rectOTSFieldsCuted.IsRectEmpty()) { LogTrace(__FILE__, __LINE__, _T("CalGBFields: GBFields area is empty .")); return TRUE; } // find all OTSFields inside GBFields area COTSFieldDataList OTSFieldsInGBFieldsArea; OTSFieldsInGBFieldsArea.clear(); CPoint poiOTSFieldPosition; for (auto OTSField : allOTSFields) { poiOTSFieldPosition = OTSField->GetPosition(); //if over the edge if (rectOTSFieldsCuted.PtInRect(poiOTSFieldPosition)) { OTSFieldsInGBFieldsArea.push_back(OTSField); } } //get possible OTSFields m_listGBFields->clear(); CPoint pointGBFieldPosition; int nOTSFieldsPerGBField = nOTSRowsPerGBfld * nOTSColumnsPerGBFld; for (int i = 0; i < nPossibleGBFieldRowNum; i++) { for (int j = 0; j < nPossibleGBFieldColNum; j++) { // cal GB field rectangle CPoint poiCurGBFieldTopLeft, poiCurGBFieldBottomRight; poiCurGBFieldTopLeft = pointPosibleAreaTopLeft; //获得左上角的坐标 poiCurGBFieldTopLeft.x += nOTSColumnsPerGBFld * j * nOTSFieldWidth; poiCurGBFieldTopLeft.y += nOTSRowsPerGBfld * i * nFieldHeight; //获得右下角的坐标 poiCurGBFieldBottomRight.x = poiCurGBFieldTopLeft.x + nOTSColumnsPerGBFld * nOTSFieldWidth; poiCurGBFieldBottomRight.y = poiCurGBFieldTopLeft.y + nOTSRowsPerGBfld * nFieldHeight; CRect rectGBField(poiCurGBFieldTopLeft, poiCurGBFieldBottomRight); rectGBField.NormalizeRect(); CGBFieldDataPtr pGBFieldData; //切割组合的矩形成为GBfield,并处理其中的segment pGBFieldData = GetOneGBField(rectGBField, OTSFieldsInGBFieldsArea, nOTSRowsPerGBfld, nOTSColumnsPerGBFld, sizePixelImage, nOTSFieldWidth); if (!pGBFieldData) { continue; } rectGBField.bottom = rectGBField.top + GB_FIELD_WIDTH; rectGBField.right = rectGBField.left + GB_FIELD_WIDTH; CPoint poiNewPosition; poiNewPosition.x = rectGBField.left + GB_FIELD_WIDTH / 2; poiNewPosition.y = rectGBField.top + GB_FIELD_WIDTH / 2; pGBFieldData->SetPosition(poiNewPosition); // add the GBField into the GBFields list m_listGBFields->push_back(pGBFieldData); } } // ok, return TRUE return TRUE; } // Custom collation rules BOOL comp(const COTSFieldDataPtr &a, const COTSFieldDataPtr &b) { if (a->GetPosition().y <= b->GetPosition().y) { if (a->GetPosition().y == b->GetPosition().y) { if (a->GetPosition().x < b->GetPosition().x) { return TRUE; } } else { return TRUE; } } return FALSE; } // get the GB field within a rectangle CGBFieldDataPtr CGBCalculate::GetOneGBField( CRect a_rectGBField, COTSFieldDataList& allOTSFields, int nOTSRowsPerGBFld, int nOTSColumnsPerGBFld, CSize a_sizePixelImage, int nOTSFieldWidth) { // GB Field handle CGBFieldDataPtr pGBFieldData = nullptr; // get OTS fields within the rectangle COTSFieldDataList myOTSFields; myOTSFields.clear(); COTSFieldDataList::iterator itr = allOTSFields.begin(); while (itr != allOTSFields.end()) { // get an OTS field CPoint poiOTSField = (*itr)->GetPosition(); //check if the field is within the rectangle if(a_rectGBField.PtInRect(poiOTSField)) { // found a field // add into the list myOTSFields.push_back(*itr); // remove the field from the measurement field list // move to the next item //itr = allOTSFields.erase(itr);//There's no need to delete the field. gsp itr++; // jump over continue; } // move to the next item itr++; } // make sure GBFields list has enough OTSFields int nOTSFieldsOfAGBField = nOTSRowsPerGBFld * nOTSColumnsPerGBFld; if (myOTSFields.size() == nOTSFieldsOfAGBField) { // sort the GBFields list sort(myOTSFields.begin(), myOTSFields.end(), comp); // normalize particles for the GBFields pGBFieldData = NormalizeParticles(a_rectGBField, myOTSFields, a_sizePixelImage, nOTSFieldWidth); pGBFieldData->myReleventOTSFlds = myOTSFields; } // return GB Field handle return pGBFieldData; } // Custom collation rules BOOL compSegment(const COTSSegmentPtr &a, const COTSSegmentPtr &b) { if (a->GetHeight() <= b->GetHeight()) { if (a->GetHeight() == b->GetHeight()) { if (a->GetStart() < b->GetStart()) { return TRUE; } } else { return TRUE; } } return FALSE; } // normalize particles for the GBFields CGBFieldDataPtr CGBCalculate::NormalizeParticles(CRect a_rectGBField, COTSFieldDataList myOTSFields, CSize a_sizePixelImage, int nOTSFieldWidth) { // inits CGBFieldDataPtr pGBFieldData(new CGBFieldData); int nFieldHeight = (int)((double)nOTSFieldWidth * 3 / 4); //go through all OTS fields form the GB field to get all segments of the GB field COTSSegmentsList listGBFieldSegments; CPoint pointGBFieldRectTopLeft = a_rectGBField.TopLeft(); int nBeforeCalNo = 0; int nAfterCalNo = 0; for (auto OTSField : myOTSFields) { CPoint pointField = OTSField->GetPosition(); COTSParticleList myOTSParticles = OTSField->GetParticleList(); long fieldLeftTopX, fieldLeftTopY; CPoint pointCalculate; fieldLeftTopX = pointField.x - (nOTSFieldWidth/2); fieldLeftTopY = pointField.y - (nFieldHeight/2); pointCalculate.x = fieldLeftTopX - pointGBFieldRectTopLeft.x; pointCalculate.y = fieldLeftTopY - pointGBFieldRectTopLeft.y; //found the field's Column and Row int nColum = (int)(((double)pointCalculate.x/ (double)nOTSFieldWidth)+0.5); int nRow = (int)(((double)pointCalculate.y/ (double)nFieldHeight)+0.5); //function Get GBField's FieldSegments List nBeforeCalNo = (int)listGBFieldSegments.size(); GetGBFieldSegmentsList(nColum, nRow, myOTSParticles, nAfterCalNo,listGBFieldSegments, a_sizePixelImage, nOTSFieldWidth); nAfterCalNo = nBeforeCalNo; } COTSParticleList listNormalizedParticles; // get new particles GetGBParticles(listGBFieldSegments, listNormalizedParticles); // put new particle in the GB Field pGBFieldData->SetParticleList(listNormalizedParticles); return pGBFieldData; } //function Get GBField's FieldSegments List BOOL CGBCalculate::GetGBFieldSegmentsList(int a_nColum, int a_nRow, COTSParticleList a_listOTSFieldParticles, int a_nCalNo, COTSSegmentsList &a_listGBFieldSegments, CSize a_sizePixelImage, int a_nFieldWidth) { CRect rectParticle; CPoint poiParticleTopLeft; COTSSegmentsList listOTSFieldSegments; long nNewStart = 0, nNewLength = 0, nNewHeight; long nOffsetX = a_nColum * a_sizePixelImage.cx; long nOffsetY = a_nRow * a_sizePixelImage.cy; // get one pixel width //double dPixelsize = (double)a_nFieldWidth / a_sizePixelImage.cx; double dPixelsize = (double)a_sizePixelImage.cx/a_nFieldWidth ; double dGBwidth = sqrt(0.5) * 1000; long nGBpixcel = (long)(dGBwidth * dPixelsize); //cal the new segment coordinate for (auto Particle : a_listOTSFieldParticles) { //get the Particle rect rectParticle = Particle->GetParticleRect(); poiParticleTopLeft = rectParticle.TopLeft(); listOTSFieldSegments = Particle->GetFeature()->GetSegmentsList(); for (auto Segment : listOTSFieldSegments) { BOOL bMerge = (a_nColum > 0) && (Segment->GetStart() == 0); // off set the segment nNewStart = Segment->GetStart() + nOffsetX; nNewHeight= Segment->GetHeight() + nOffsetY; // check should we need to keep the segment // cal if the Segment in the GB 0.5/m2 if (nNewStart > nGBpixcel) { continue; } if (nNewHeight > nGBpixcel) { continue; } // do we need to cut the segment //if over 0.5m2 cut it //get GBField's a_nHeight, long a_nStart, long a_nLength nNewLength = Segment->GetLength(); if (nNewStart + Segment->GetLength() > nGBpixcel) { nNewLength = (long)(nGBpixcel - nNewStart); } COTSSegmentPtr pGBFieldSegment(new COTSSegment(nNewHeight, nNewStart, nNewLength)); //merge the segment if (bMerge && MergSegment(a_listGBFieldSegments, pGBFieldSegment, a_nCalNo)) { continue; } a_listGBFieldSegments.push_back(pGBFieldSegment); } } return TRUE; } // merge the segment BOOL CGBCalculate::MergSegment(COTSSegmentsList &a_listGBFieldSegments, COTSSegmentPtr a_pGBFieldSegment, int a_nCalNo) { //search merge segments only on last field COTSSegmentsList::iterator itr = a_listGBFieldSegments.begin()+ a_nCalNo; while (itr != a_listGBFieldSegments.end()) { COTSSegmentPtr pSegmentHead = *itr; long nNextX = pSegmentHead->GetStart() + pSegmentHead->GetLength(); //merge only when height are the same if (pSegmentHead->GetHeight() == a_pGBFieldSegment->GetHeight()) { //end to start if ((nNextX + 1) == a_pGBFieldSegment->GetStart()) { //merge and return true pSegmentHead->SetLength(pSegmentHead->GetLength() + a_pGBFieldSegment->GetLength()); return TRUE; } } itr++; } //didn't merge return false return FALSE; } // merge the segment,get new particles BOOL CGBCalculate::GetGBParticles(COTSSegmentsList a_listGBFieldSegments, COTSParticleList &a_listNormalizedParticles) { //change segments to Particles COTSFeatureList listFeatures; if (a_listGBFieldSegments.size() == 0) { return FALSE; } GetFeatureList1(a_listGBFieldSegments, listFeatures); ChangeFeaturelist(listFeatures, a_listNormalizedParticles); for (auto p : a_listNormalizedParticles) { COTSImageProcess::CalcuParticleImagePropertes(p, PixSize); } return TRUE; } BOOL CGBCalculate::GetFeatureList1(COTSSegmentsList& a_listSegments, COTSFeatureList& a_listFeatures) { COTSSegmentsList listSegmentNew; std::map mapOneLineSegments; for (auto s : a_listSegments) { mapOneLineSegments[s->GetHeight()].push_back(s); } std::map::iterator lineItr = mapOneLineSegments.begin();//find the highest line while (lineItr!=mapOneLineSegments.end ()) { for (auto s = lineItr->second.begin(); s < lineItr->second.end(); )//find one segment of this line. { COTSSegmentPtr bottomSeg= *s; listSegmentNew.clear(); listSegmentNew.push_back(*s); s=lineItr->second.erase(s); std::map::iterator tempItr = lineItr; tempItr++; for (; tempItr !=mapOneLineSegments.end(); tempItr++)//find all other lines of segments { for (auto nextLineSegment = tempItr->second.begin(); nextLineSegment < tempItr->second.end();)//find next line's all segments { if (bottomSeg->UpDownConection(**nextLineSegment)) { listSegmentNew.push_back(*nextLineSegment); bottomSeg = *nextLineSegment; nextLineSegment=tempItr->second.erase(nextLineSegment); break; } if (tempItr->second.size() > 0) { nextLineSegment++; } else { break; } } } COTSFeaturePtr pFeature = COTSFeaturePtr(new COTSFeature()); pFeature->SetSegmentsList(listSegmentNew); //check if this new feature is connected with other found feature. COTSSegmentPtr topSeg = listSegmentNew[0];//find the toppest segment of this new feature. COTSSegmentPtr bottomSegment= listSegmentNew[listSegmentNew.size()-1];//find the lowest segment of this new feature. bool haveMerged=false; for (auto f : a_listFeatures) { for (auto seg : f->GetSegmentsList()) { if (bottomSegment->UpDownConection(*seg)|| topSeg->UpDownConection (*seg)) { COTSSegmentsList segs = f->GetSegmentsList(); for (auto s : listSegmentNew) { segs.push_back(s); } f->SetSegmentsList(segs); haveMerged = true; break ; } } if (haveMerged) { break; } } if (!haveMerged) { a_listFeatures.push_back(pFeature); } if (lineItr->second.size()==0) { break; } } lineItr++; } return true; } // change feature into particle BOOL CGBCalculate::ChangeFeaturelist(COTSFeatureList& a_listFeatures, COTSParticleList& a_listParticle) { if (a_listFeatures.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: there is no feature in the list.")); return FALSE; } // compute Rect for (auto pFeature : a_listFeatures) { COTSParticlePtr pParticle = COTSParticlePtr(new COTSParticle()); COTSFeaturePtr pFeatureNew = COTSFeaturePtr(new COTSFeature(*pFeature.get())); pParticle->SetFeature(pFeatureNew); if (!pParticle->CalCoverRect()) { LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: failed to get particle rect.")); return FALSE; } a_listParticle.push_back(pParticle); } if ((int)a_listParticle.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("Can't get particle.")); return FALSE; } return TRUE; } void CGBCalculate::SetPixSize(double p) { PixSize = p; } }