GBFieldData.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489
  1. #pragma once
  2. #include "stdafx.h"
  3. #include "GBFieldData.h"
  4. #include "CGBLevel.h"
  5. #include <map>
  6. namespace OTSGBCalculate
  7. {
  8. using namespace std;
  9. using namespace OTSDATA;
  10. namespace
  11. {
  12. CString GetGradeString(GB_GRADE_TYPE grade)
  13. {
  14. CString gr;
  15. switch (grade)
  16. {
  17. case GB_GRADE_TYPE::POINT_0_0:
  18. gr = _T("0");
  19. break;
  20. case GB_GRADE_TYPE::POINT_0_5:
  21. gr = _T("0.5");
  22. break;
  23. case GB_GRADE_TYPE::POINT_1_0:
  24. gr = _T("1.0");
  25. break;
  26. case GB_GRADE_TYPE::POINT_1_5:
  27. gr = _T("1.5");
  28. break;
  29. case GB_GRADE_TYPE::POINT_2_0:
  30. gr = _T("2.0");
  31. break;
  32. case GB_GRADE_TYPE::POINT_2_5:
  33. gr = _T("2.5");
  34. break;
  35. case GB_GRADE_TYPE::POINT_3_0:
  36. gr = _T("3.0");
  37. break;
  38. case GB_GRADE_TYPE::POINT_3_5:
  39. gr = _T("3.5");
  40. break;
  41. case GB_GRADE_TYPE::POINT_4_0:
  42. gr = _T("4.0");
  43. break;
  44. case GB_GRADE_TYPE::POINT_4_5:
  45. gr = _T("4.5");
  46. break;
  47. case GB_GRADE_TYPE::POINT_5_0:
  48. gr = _T("5.0");
  49. break;
  50. default:
  51. break;
  52. }
  53. return gr;
  54. }
  55. CString DoubleToCString(double d)
  56. {
  57. CString s;
  58. s.Format(_T("%.0lf"), d);
  59. return s;
  60. }
  61. }
  62. #pragma region PrivateCode
  63. COTSParticlePtr CGBFieldData::FindAdjacentParticle(COTSParticlePtr p, COTSParticleList plist)
  64. {
  65. auto adjacentPart = find_if(plist.begin(), plist.end(), [p](COTSParticlePtr pBParticle)
  66. {
  67. //the conditional particle
  68. COTSRect rectParticle = p->GetOTSRect();
  69. CPoint ptParticleCenter = rectParticle.GetCenterPoint();
  70. int Bottom = rectParticle.GetBottomRight().y;
  71. int Top = rectParticle.GetTopLeft().y;
  72. //the iterational particle
  73. COTSRect rectBCurParticle = pBParticle->GetOTSRect();
  74. CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
  75. int BottomB = rectBCurParticle.GetBottomRight().y;
  76. int TopB = rectBCurParticle.GetTopLeft().y;
  77. if (rectParticle == rectBCurParticle)
  78. {
  79. return false;
  80. }
  81. double dd = 0, ds = 0;
  82. ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
  83. if (ds < 15 )//recognize these two particle as in the same vertical line.
  84. {
  85. if (Bottom > TopB)//current particle is on the above
  86. {
  87. dd = Bottom - TopB;
  88. if (dd < 40)//recognize these two particle as in the same vertical string.
  89. {
  90. return true;
  91. }
  92. }
  93. else if (BottomB > Top) //current particle is on the below
  94. {
  95. dd = BottomB - Top;
  96. if (dd < 40)
  97. {
  98. return true;
  99. }
  100. }
  101. }
  102. return false;
  103. });
  104. if (adjacentPart == plist.end())
  105. {
  106. return nullptr;
  107. }
  108. else
  109. {
  110. if ((*adjacentPart)->GetType() != OTS_PARTCLE_TYPE::INVALID)
  111. {
  112. return *adjacentPart;
  113. }
  114. else
  115. {
  116. return nullptr;
  117. }
  118. }
  119. }
  120. #pragma endregion
  121. CGBFieldData::CGBFieldData() // constructor
  122. {
  123. Init();
  124. }
  125. CGBFieldData::CGBFieldData(const CGBFieldData& a_oSource) // copy constructor
  126. {
  127. // can't copy itself
  128. if (&a_oSource == this)
  129. {
  130. return;
  131. }
  132. // copy data over
  133. Duplicate(a_oSource);
  134. }
  135. CGBFieldData::CGBFieldData(CGBFieldData* a_poSource) // copy constructor
  136. {
  137. // input check
  138. ASSERT(a_poSource);
  139. if (!a_poSource)
  140. {
  141. return;
  142. }
  143. // can't copy itself
  144. if (a_poSource == this)
  145. {
  146. return;
  147. }
  148. // copy data over
  149. Duplicate(*a_poSource);
  150. }
  151. CGBFieldData& CGBFieldData::operator=(const CGBFieldData& a_oSource) // =operator
  152. {
  153. // cleanup
  154. Cleanup();
  155. // copy the class data over
  156. Duplicate(a_oSource);
  157. // return class
  158. return *this;
  159. }
  160. BOOL CGBFieldData::operator==(const CGBFieldData& a_oSource) // =operator
  161. {
  162. // return test result
  163. return((m_nFrameId == a_oSource.m_nFrameId) &&
  164. (*m_pALevel.get() == *a_oSource.m_pALevel.get()) &&
  165. (*m_pBLevel.get() == *a_oSource.m_pBLevel.get()) &&
  166. (*m_pCLevel.get() == *a_oSource.m_pCLevel.get()) &&
  167. (*m_pDLevel.get() == *a_oSource.m_pDLevel.get()));//&&
  168. }
  169. CGBFieldData::~CGBFieldData() // detractor
  170. {
  171. Cleanup();
  172. }
  173. // cleanup
  174. void CGBFieldData::Cleanup()
  175. {
  176. }
  177. // initialization
  178. void CGBFieldData::Init()
  179. {
  180. // id
  181. m_nFrameId = -1;
  182. // A level
  183. m_pALevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::A_TYPE));
  184. // B level
  185. m_pBLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::B_TYPE));
  186. // C level
  187. m_pCLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::C_TYPE));
  188. // D level
  189. m_pDLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::D_TYPE));
  190. // DSulfide level
  191. m_pDSulfidLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::DSulfide_TYPE));
  192. listAThinParticles.clear();
  193. listAWideParticles.clear();
  194. listASuperParticles.clear();
  195. listBThinParticles.clear();
  196. listBWideParticles.clear();
  197. listBSuperParticles.clear();
  198. listCThinParticles.clear();
  199. listCWideParticles.clear();
  200. listCSuperParticles.clear();
  201. listDThinParticles.clear();
  202. listDWideParticles.clear();
  203. listDSuperParticles.clear();
  204. listDSParticles.clear();
  205. listDSulfideThinParticles.clear();
  206. listDSulfideWideParticles.clear();
  207. listDSulfideSuperParticles.clear();
  208. }
  209. // duplication
  210. void CGBFieldData::Duplicate(const CGBFieldData& a_oSource)
  211. {
  212. // initialization
  213. Init();
  214. // id
  215. int m_nFrameId;
  216. // A level
  217. m_pALevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pALevel.get()));
  218. // B level
  219. m_pBLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pBLevel.get()));
  220. // C level
  221. m_pCLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pCLevel.get()));
  222. // D level
  223. m_pDLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pDLevel.get()));
  224. m_nFrameId = a_oSource.m_nFrameId;
  225. }
  226. // caculate Level by method 1
  227. void CGBFieldData::CategoryByMethod1()
  228. {
  229. // according to the shape
  230. if (m_listParticles.empty())
  231. {
  232. return;
  233. }
  234. vector<GBParticle> listBAndDParticles;//
  235. listBAndDParticles.clear();
  236. // get all the all particles for each level
  237. mapAllParticles.clear();
  238. for (auto pParticle : m_listParticles)
  239. { // compute length width ratio
  240. if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid.
  241. {
  242. continue;
  243. }
  244. if (pParticle->GetClassifyName() == _T("FeO"))//here we take all the particles except Invalid.
  245. {
  246. continue;
  247. }
  248. if (pParticle->GetClassifyName() == _T("SiC"))//here we take all the particles except Invalid.
  249. {
  250. continue;
  251. }
  252. auto w = pParticle->GetDMin();
  253. if (w == 0 )
  254. {
  255. continue;
  256. }
  257. //获取最大长度和最小宽度
  258. double h = pParticle->GetDMax();
  259. double dLengthWidthRatio = h / w;
  260. if (dLengthWidthRatio < 1)
  261. {
  262. dLengthWidthRatio = 1 / dLengthWidthRatio;
  263. }
  264. if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类
  265. {
  266. //A or C class
  267. GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType();
  268. if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S)
  269. {
  270. // A
  271. //计算颗粒宽度是属于细系粗系还是超尺寸
  272. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
  273. switch (wt)
  274. {
  275. case GB_WIDTH_TYPE::THIN:
  276. listAThinParticles.push_back(pParticle);
  277. break;
  278. case GB_WIDTH_TYPE::WIDE:
  279. listAWideParticles.push_back(pParticle);
  280. break;
  281. case GB_WIDTH_TYPE::SUPER:
  282. listASuperParticles.push_back(pParticle);
  283. break;
  284. }
  285. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt);
  286. }
  287. else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType== GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al)
  288. {
  289. // C
  290. //计算颗粒宽度是属于细系粗系还是超尺寸
  291. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE);
  292. switch (wt)
  293. {
  294. case GB_WIDTH_TYPE::THIN:
  295. listCThinParticles.push_back(pParticle);
  296. break;
  297. case GB_WIDTH_TYPE::WIDE:
  298. listCWideParticles.push_back(pParticle);
  299. break;
  300. case GB_WIDTH_TYPE::SUPER:
  301. listCSuperParticles.push_back(pParticle);
  302. break;
  303. }
  304. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt);
  305. }
  306. }
  307. else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒
  308. {
  309. // B, or D or DS
  310. // compute Feret's diameter
  311. double dFeretDiameter = pParticle->GetFeretDiameter();
  312. if (dFeretDiameter >= 13)
  313. {
  314. // DS
  315. listDSParticles.push_back(pParticle);
  316. }
  317. else
  318. {
  319. if (pParticle->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_S)//if it contains sulfide then it is a A particle.
  320. {
  321. GB_LEVEL_TYPE partType = GB_LEVEL_TYPE::A_TYPE;//把类型设为有效类型,以便不再找这个颗粒
  322. //计算颗粒宽度是属于细系粗系还是超尺寸
  323. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
  324. switch (wt)
  325. {
  326. case GB_WIDTH_TYPE::THIN:
  327. listAThinParticles.push_back(pParticle);
  328. break;
  329. case GB_WIDTH_TYPE::WIDE:
  330. listAWideParticles.push_back(pParticle);
  331. break;
  332. case GB_WIDTH_TYPE::SUPER:
  333. listASuperParticles.push_back(pParticle);
  334. break;
  335. }
  336. mapAllParticles[pParticle] = GBParticle(pParticle, partType, wt);
  337. }
  338. else
  339. {
  340. // B or D
  341. GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID);
  342. //不能确定是B或D,先设为INVALID
  343. listBAndDParticles.push_back(gbP);
  344. }
  345. }
  346. }
  347. }
  348. int n = listDSParticles.size();
  349. for (auto pGBParticle : listBAndDParticles)
  350. {
  351. //check if the particle is alone
  352. auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle)
  353. {
  354. //the conditional particle
  355. COTSRect rectParticle = pGBParticle.myPart->GetOTSRect();
  356. CPoint ptParticleCenter = rectParticle.GetCenterPoint();
  357. int Bottom = rectParticle.GetBottomRight().y;
  358. int Top = rectParticle.GetTopLeft().y;
  359. //the current iteration particle
  360. COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect();
  361. CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
  362. int BottomB = rectBCurParticle.GetBottomRight().y;
  363. int TopB = rectBCurParticle.GetTopLeft().y;
  364. if (rectParticle == rectBCurParticle)
  365. {
  366. return false;
  367. }
  368. double dd = 0, ds = 0;
  369. ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
  370. if (ds < 10 )//认为两个颗粒在一条竖直线上,但不在一起
  371. {
  372. if (Bottom > TopB)//current particle is on the above
  373. {
  374. dd = Bottom - TopB;
  375. if (dd < 40)//认为这两个颗粒在一个串条上
  376. {
  377. return true;
  378. }
  379. }
  380. else if (BottomB > Top) //current particle is on the below
  381. {
  382. dd = BottomB - Top;
  383. if (dd < 40)
  384. {
  385. return true;
  386. }
  387. }
  388. }
  389. return false;
  390. });
  391. if (adjacentPart == listBAndDParticles.end())//没找到
  392. {
  393. if (pGBParticle.myPart->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_O)
  394. {
  395. pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE;
  396. //计算颗粒宽度是属于细系粗系还是超尺寸
  397. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE);
  398. switch (wt)
  399. {
  400. case GB_WIDTH_TYPE::THIN:
  401. listDThinParticles.push_back(pGBParticle.myPart);
  402. break;
  403. case GB_WIDTH_TYPE::WIDE:
  404. listDWideParticles.push_back(pGBParticle.myPart);
  405. break;
  406. case GB_WIDTH_TYPE::SUPER:
  407. listDSuperParticles.push_back(pGBParticle.myPart);
  408. break;
  409. }
  410. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt);
  411. }
  412. }
  413. else//找到了相邻接的颗粒,不是孤立的则为B类
  414. {
  415. pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒
  416. adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE;
  417. //计算颗粒宽度是属于细系粗系还是超尺寸
  418. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE);
  419. switch (wt)
  420. {
  421. case GB_WIDTH_TYPE::THIN:
  422. listBThinParticles.insert(pGBParticle.myPart);
  423. break;
  424. case GB_WIDTH_TYPE::WIDE:
  425. listBWideParticles.insert(pGBParticle.myPart);
  426. break;
  427. case GB_WIDTH_TYPE::SUPER:
  428. listBSuperParticles.insert(pGBParticle.myPart);
  429. break;
  430. }
  431. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  432. wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE);
  433. switch (wt)
  434. {
  435. case GB_WIDTH_TYPE::THIN:
  436. listBThinParticles.insert(adjacentPart->myPart);
  437. break;
  438. case GB_WIDTH_TYPE::WIDE:
  439. listBWideParticles.insert(adjacentPart->myPart);
  440. break;
  441. case GB_WIDTH_TYPE::SUPER:
  442. listBSuperParticles.insert(adjacentPart->myPart);
  443. break;
  444. }
  445. mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  446. }
  447. }
  448. }
  449. // caculate Level by method 2
  450. void CGBFieldData::CategoryByMethod2()
  451. {
  452. vector<COTSParticlePtr> listABCParticles;//
  453. listABCParticles.clear();
  454. if (m_listParticles.empty())
  455. {
  456. return;
  457. }
  458. // get all the all particles for each level
  459. for (auto pParticle : m_listParticles)
  460. {
  461. if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid.
  462. {
  463. continue;
  464. }
  465. if (pParticle->GetClassifyName() == _T("FeO"))//here we take all the particles except Invalid.
  466. {
  467. continue;
  468. }
  469. if (pParticle->GetClassifyName() == _T("SiC"))//here we take all the particles except Invalid.
  470. {
  471. continue;
  472. }
  473. //check the denominator is zero or not
  474. auto w = pParticle->GetDMin();
  475. if (w == 0)
  476. {
  477. continue;
  478. }
  479. //获取最小外接矩形的宽和高
  480. double h = pParticle->GetDMax();
  481. double dLengthWidthRatio = h / w;
  482. if (dLengthWidthRatio < 1)
  483. {
  484. dLengthWidthRatio = 1 / dLengthWidthRatio;
  485. }
  486. if (dLengthWidthRatio < 3)//长宽比小于3的颗粒,且为孤立的颗粒,根据是否含硫化物,分为D类和DSulfide类,如果费雷特直径大于13 归为DS类
  487. {
  488. double dFeretDiameter = pParticle->GetFeretDiameter();
  489. if (dFeretDiameter >= 13)
  490. {
  491. // DS
  492. listDSParticles.push_back(pParticle);
  493. }
  494. else
  495. {
  496. // D or Dsulfide
  497. auto p = FindAdjacentParticle(pParticle, m_listParticles);
  498. if (p == nullptr)//pParticle is a isolated particle.
  499. {
  500. GB_CHEMICAL_TYPE ChemicalType = pParticle->GetChemicalType();
  501. if (ChemicalType == GB_CHEMICAL_TYPE::CHE_S)
  502. {
  503. auto wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::DSulfide_TYPE);
  504. switch (wt)
  505. {
  506. case GB_WIDTH_TYPE::THIN:
  507. listDSulfideThinParticles.push_back(pParticle);
  508. break;
  509. case GB_WIDTH_TYPE::WIDE:
  510. listDSulfideWideParticles.push_back(pParticle);
  511. break;
  512. case GB_WIDTH_TYPE::SUPER:
  513. listDSulfideSuperParticles.push_back(pParticle);
  514. break;
  515. }
  516. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::DSulfide_TYPE, wt);
  517. }
  518. else
  519. {
  520. auto wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::D_TYPE);
  521. switch (wt)
  522. {
  523. case GB_WIDTH_TYPE::THIN:
  524. listDThinParticles.push_back(pParticle);
  525. break;
  526. case GB_WIDTH_TYPE::WIDE:
  527. listDWideParticles.push_back(pParticle);
  528. break;
  529. case GB_WIDTH_TYPE::SUPER:
  530. listDSuperParticles.push_back(pParticle);
  531. break;
  532. }
  533. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::D_TYPE, wt);
  534. }
  535. }
  536. else
  537. {
  538. listABCParticles.push_back(pParticle);
  539. }
  540. }
  541. }
  542. else
  543. {
  544. listABCParticles.push_back(pParticle);
  545. }
  546. }
  547. for (auto pParticle : listABCParticles)
  548. {
  549. GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType();
  550. if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S)
  551. {
  552. // A
  553. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
  554. switch (wt)
  555. {
  556. case GB_WIDTH_TYPE::THIN:
  557. listAThinParticles.push_back(pParticle);
  558. break;
  559. case GB_WIDTH_TYPE::WIDE:
  560. listAWideParticles.push_back(pParticle);
  561. break;
  562. case GB_WIDTH_TYPE::SUPER:
  563. listASuperParticles.push_back(pParticle);
  564. break;
  565. }
  566. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt);
  567. }
  568. else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Al)
  569. {
  570. // B
  571. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::B_TYPE);
  572. switch (wt)
  573. {
  574. case GB_WIDTH_TYPE::THIN:
  575. listBThinParticles.insert(pParticle);
  576. break;
  577. case GB_WIDTH_TYPE::WIDE:
  578. listBWideParticles.insert(pParticle);
  579. break;
  580. case GB_WIDTH_TYPE::SUPER:
  581. listBSuperParticles.insert(pParticle);
  582. break;
  583. }
  584. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::B_TYPE, wt);
  585. }
  586. else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Si)
  587. {
  588. // C
  589. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE);
  590. switch (wt)
  591. {
  592. case GB_WIDTH_TYPE::THIN:
  593. listCThinParticles.push_back(pParticle);
  594. break;
  595. case GB_WIDTH_TYPE::WIDE:
  596. listCWideParticles.push_back(pParticle);
  597. break;
  598. case GB_WIDTH_TYPE::SUPER:
  599. listCSuperParticles.push_back(pParticle);
  600. break;
  601. }
  602. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt);
  603. }
  604. }
  605. }
  606. // caculate Level by ASTM
  607. void CGBFieldData::CategoryByASTM()
  608. {
  609. // according to the shape
  610. if (m_listParticles.empty())
  611. {
  612. return;
  613. }
  614. vector<GBParticle> listBAndDParticles;//
  615. listBAndDParticles.clear();
  616. // get all the all particles for each level
  617. mapAllParticles.clear();
  618. for (auto pParticle : m_listParticles)
  619. { // compute length width ratio
  620. if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid.
  621. {
  622. continue;
  623. }
  624. if (pParticle->GetClassifyName() == _T("FeO"))//here we take all the particles except Invalid.
  625. {
  626. continue;
  627. }
  628. if (pParticle->GetClassifyName() == _T("SiC"))//here we take all the particles except Invalid.
  629. {
  630. continue;
  631. }
  632. auto w = pParticle->GetDMin();
  633. if (w == 0)
  634. {
  635. continue;
  636. }
  637. //获取最大长度和最小宽度
  638. double h = pParticle->GetDMax();
  639. double dLengthWidthRatio = h / w;
  640. if (dLengthWidthRatio < 1)
  641. {
  642. dLengthWidthRatio = 1 / dLengthWidthRatio;
  643. }
  644. if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类
  645. {
  646. //A or C class
  647. GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType();
  648. if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S)
  649. {
  650. // A
  651. //计算颗粒宽度是属于细系粗系还是超尺寸
  652. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
  653. switch (wt)
  654. {
  655. case GB_WIDTH_TYPE::THIN:
  656. listAThinParticles.push_back(pParticle);
  657. break;
  658. case GB_WIDTH_TYPE::WIDE:
  659. listAWideParticles.push_back(pParticle);
  660. break;
  661. case GB_WIDTH_TYPE::SUPER:
  662. listASuperParticles.push_back(pParticle);
  663. break;
  664. }
  665. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt);
  666. }
  667. else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType == GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al)
  668. {
  669. // C
  670. //计算颗粒宽度是属于细系粗系还是超尺寸
  671. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE);
  672. switch (wt)
  673. {
  674. case GB_WIDTH_TYPE::THIN:
  675. listCThinParticles.push_back(pParticle);
  676. break;
  677. case GB_WIDTH_TYPE::WIDE:
  678. listCWideParticles.push_back(pParticle);
  679. break;
  680. case GB_WIDTH_TYPE::SUPER:
  681. listCSuperParticles.push_back(pParticle);
  682. break;
  683. }
  684. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt);
  685. }
  686. }
  687. else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒
  688. {
  689. // B, or D or DS
  690. // compute Feret's diameter
  691. double dFeretDiameter = pParticle->GetFeretDiameter();
  692. if (dFeretDiameter >= 13)
  693. {
  694. // DS
  695. listDSParticles.push_back(pParticle);
  696. }
  697. else
  698. {
  699. // B or D
  700. GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID);
  701. //不能确定是B或D,先设为INVALID
  702. listBAndDParticles.push_back(gbP);
  703. }
  704. }
  705. }
  706. for (auto pGBParticle : listBAndDParticles)
  707. {
  708. // check if the particle is alone
  709. auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle)
  710. {
  711. COTSRect rectParticle = pGBParticle.myPart->GetOTSRect();
  712. CPoint ptParticleCenter = rectParticle.GetCenterPoint();
  713. int Bottom = rectParticle.GetBottomRight().y;
  714. int Top = rectParticle.GetTopLeft().y;
  715. COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect();
  716. CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
  717. int BottomB = rectBCurParticle.GetBottomRight().y;
  718. int TopB = rectBCurParticle.GetTopLeft().y;
  719. double dd = 0, ds = 0;
  720. ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
  721. if (ds <= 15)//认为两个颗粒在一条竖直线上,但不在一起
  722. {
  723. if (Bottom > TopB)//current particle is on the above
  724. {
  725. dd = Bottom - TopB;
  726. if (dd < 40)//认为这两个颗粒在一个串条上
  727. {
  728. return true;
  729. }
  730. }
  731. else if (BottomB > Top) //current particle is on the below
  732. {
  733. dd = BottomB - Top;
  734. if (dd < 40)
  735. {
  736. return true;
  737. }
  738. }
  739. }
  740. return false;
  741. });
  742. if (adjacentPart == listBAndDParticles.end())//没找到
  743. {
  744. pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE;
  745. //计算颗粒宽度是属于细系粗系还是超尺寸
  746. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE);
  747. switch (wt)
  748. {
  749. case GB_WIDTH_TYPE::THIN:
  750. listDThinParticles.push_back(pGBParticle.myPart);
  751. break;
  752. case GB_WIDTH_TYPE::WIDE:
  753. listDWideParticles.push_back(pGBParticle.myPart);
  754. break;
  755. case GB_WIDTH_TYPE::SUPER:
  756. listDSuperParticles.push_back(pGBParticle.myPart);
  757. break;
  758. }
  759. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt);
  760. }
  761. else//找到了相邻接的颗粒,不是孤立的则为B类
  762. {
  763. pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒
  764. adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE;
  765. //计算颗粒宽度是属于细系粗系还是超尺寸
  766. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE);
  767. switch (wt)
  768. {
  769. case GB_WIDTH_TYPE::THIN:
  770. listBThinParticles.insert(pGBParticle.myPart);
  771. break;
  772. case GB_WIDTH_TYPE::WIDE:
  773. listBWideParticles.insert(pGBParticle.myPart);
  774. break;
  775. case GB_WIDTH_TYPE::SUPER:
  776. listBSuperParticles.insert(pGBParticle.myPart);
  777. break;
  778. }
  779. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  780. wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE);
  781. switch (wt)
  782. {
  783. case GB_WIDTH_TYPE::THIN:
  784. listBThinParticles.insert(adjacentPart->myPart);
  785. break;
  786. case GB_WIDTH_TYPE::WIDE:
  787. listBWideParticles.insert(adjacentPart->myPart);
  788. break;
  789. case GB_WIDTH_TYPE::SUPER:
  790. listBSuperParticles.insert(adjacentPart->myPart);
  791. break;
  792. }
  793. mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  794. }
  795. }
  796. }
  797. // caculate Level by DIN
  798. void CGBFieldData::CaculateLevelDIN(COTSParticleList listParticle)
  799. {
  800. // according to the shape
  801. if (listParticle.empty())
  802. {
  803. return;
  804. }
  805. vector<GBParticle> listBAndDParticles;//
  806. listBAndDParticles.clear();
  807. // get all the all particles for each level
  808. mapAllParticles.clear();
  809. for (auto pParticle : listParticle)
  810. { // compute length width ratio
  811. if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid.
  812. {
  813. continue;
  814. }
  815. CRect rectParticle = pParticle->GetParticleRect();
  816. //check the denominator is zero or not
  817. if (rectParticle.Width() == 0)
  818. {
  819. continue;
  820. }
  821. //获取最大长度和最小宽度
  822. double h = pParticle->GetDMax();
  823. double w = pParticle->GetDMin();
  824. double dLengthWidthRatio = h / w;
  825. if (dLengthWidthRatio < 1)
  826. {
  827. dLengthWidthRatio = 1 / dLengthWidthRatio;
  828. }
  829. if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类
  830. {
  831. //A or C class
  832. GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType();
  833. if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S)
  834. {
  835. // A
  836. //计算颗粒宽度是属于细系粗系还是超尺寸
  837. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
  838. if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER)
  839. {
  840. listAThinParticles.push_back(pParticle);
  841. }
  842. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt);
  843. }
  844. else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O)
  845. {
  846. // C
  847. //计算颗粒宽度是属于细系粗系还是超尺寸
  848. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE);
  849. if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER)
  850. {
  851. listAThinParticles.push_back(pParticle);
  852. }
  853. mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt);
  854. }
  855. }
  856. else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒
  857. {
  858. // B, or D or DS
  859. // compute Feret's diameter
  860. double dFeretDiameter = pParticle->GetFeretDiameter();
  861. if (dFeretDiameter >= 13)
  862. {
  863. // DS
  864. listDSParticles.push_back(pParticle);
  865. }
  866. else
  867. {
  868. // B or D
  869. GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID);
  870. //不能确定是B或D,先设为INVALID
  871. listBAndDParticles.push_back(gbP);
  872. }
  873. }
  874. }
  875. {
  876. for (auto pGBParticle : listBAndDParticles)
  877. {
  878. // check if the particle is alone
  879. auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle)
  880. {
  881. CRect rectParticle = pGBParticle.myPart->GetParticleRect();
  882. CPoint ptParticleCenter = rectParticle.CenterPoint();
  883. int Bottom = rectParticle.BottomRight().y;
  884. int Top = rectParticle.TopLeft().y;
  885. CRect rectBCurParticle = pBParticle.myPart->GetParticleRect();
  886. CPoint ptBParticleCenter = rectBCurParticle.CenterPoint();
  887. int BottomB = rectBCurParticle.BottomRight().y;
  888. int TopB = rectBCurParticle.TopLeft().y;
  889. double dd = 0, ds = 0;
  890. ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
  891. if (ds <= 15)//认为两个颗粒在一条竖直线上,但不在一起
  892. {
  893. if (Bottom > TopB)//current particle is on the above
  894. {
  895. dd = Bottom - TopB;
  896. if (dd < 40)//认为这两个颗粒在一个串条上
  897. {
  898. return true;
  899. }
  900. }
  901. else if (BottomB > Top) //current particle is on the below
  902. {
  903. dd = BottomB - Top;
  904. if (dd < 40)
  905. {
  906. return true;
  907. }
  908. }
  909. }
  910. return false;
  911. });
  912. if (adjacentPart == listBAndDParticles.end())//没找到
  913. {
  914. pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE;
  915. //计算颗粒宽度是属于细系粗系还是超尺寸
  916. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE);
  917. if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER)
  918. {
  919. listDThinParticles.push_back(pGBParticle.myPart);
  920. }
  921. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt);
  922. }
  923. else//找到了相邻接的颗粒,不是孤立的则为B类
  924. {
  925. pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒
  926. adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE;
  927. //计算颗粒宽度是属于细系粗系还是超尺寸
  928. GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE);
  929. if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER)
  930. {
  931. listBThinParticles.insert(pGBParticle.myPart);
  932. }
  933. mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  934. wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE);
  935. if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER)
  936. {
  937. listBThinParticles.insert(adjacentPart->myPart);
  938. }
  939. mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt);
  940. }
  941. }
  942. }
  943. }
  944. // caculate Level Width
  945. BOOL CGBFieldData::CaculateLevelThinWidth(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel)
  946. {
  947. if (a_listParticles.empty())
  948. {
  949. return FALSE;
  950. }
  951. double dMin = 2, dMax = 0;
  952. switch ((int)a_nLevel)
  953. {
  954. case (int)GB_LEVEL_TYPE::A_TYPE:
  955. dMax = 4;
  956. break;
  957. case (int)GB_LEVEL_TYPE::B_TYPE:
  958. dMax = 9;
  959. break;
  960. case (int)GB_LEVEL_TYPE::C_TYPE:
  961. dMax = 5;
  962. break;
  963. case (int)GB_LEVEL_TYPE::D_TYPE:
  964. dMax = 8;
  965. break;
  966. }
  967. BOOL bThin = TRUE;
  968. for (auto pParticle : a_listParticles)
  969. {
  970. CRect rectParticle = pParticle->GetParticleRect();
  971. double dWidth = (double)rectParticle.Width();
  972. if (dWidth < dMin || dWidth > dMax)
  973. {
  974. bThin = FALSE;
  975. break;
  976. }
  977. }
  978. return bThin;
  979. }
  980. GB_WIDTH_TYPE CGBFieldData::CaculateLevelWidth(COTSParticlePtr Particle, GB_LEVEL_TYPE a_nLevel)
  981. {
  982. double dWidth = (double)Particle->GetDMin();
  983. double dMin = 2, dMax = 0;
  984. switch ((int)a_nLevel)
  985. {
  986. case (int)GB_LEVEL_TYPE::A_TYPE:
  987. dMax = 4;
  988. break;
  989. case (int)GB_LEVEL_TYPE::B_TYPE:
  990. dMax = 9;
  991. break;
  992. case (int)GB_LEVEL_TYPE::C_TYPE:
  993. dMax = 5;
  994. break;
  995. case (int)GB_LEVEL_TYPE::D_TYPE:
  996. dMax = 8;
  997. break;
  998. }
  999. //if (dWidth < dMin)
  1000. //{
  1001. // return GB_WIDTH_TYPE::INVALID;//小于2um不考虑
  1002. //}
  1003. /*else*/
  1004. if (dWidth >= 0 && dWidth <= dMax)
  1005. {
  1006. return GB_WIDTH_TYPE::THIN;
  1007. }
  1008. switch ((int)a_nLevel)
  1009. {
  1010. case (int)GB_LEVEL_TYPE::A_TYPE:
  1011. dMin = 4;
  1012. dMax = 12;
  1013. break;
  1014. case (int)GB_LEVEL_TYPE::B_TYPE:
  1015. dMin = 9;
  1016. dMax = 15;
  1017. break;
  1018. case (int)GB_LEVEL_TYPE::C_TYPE:
  1019. dMin = 5;
  1020. dMax = 12;
  1021. break;
  1022. case (int)GB_LEVEL_TYPE::D_TYPE:
  1023. dMin = 8;
  1024. dMax = 13;
  1025. break;
  1026. }
  1027. if (dWidth > dMin && dWidth <= dMax)
  1028. {
  1029. return GB_WIDTH_TYPE::WIDE;
  1030. }
  1031. switch ((int)a_nLevel)
  1032. {
  1033. case (int)GB_LEVEL_TYPE::A_TYPE:
  1034. dMin = 12;
  1035. break;
  1036. case (int)GB_LEVEL_TYPE::B_TYPE:
  1037. dMin = 15;
  1038. break;
  1039. case (int)GB_LEVEL_TYPE::C_TYPE:
  1040. dMin = 12;
  1041. break;
  1042. case (int)GB_LEVEL_TYPE::D_TYPE:
  1043. dMin = 13;
  1044. break;
  1045. }
  1046. if (dWidth > dMin)
  1047. {
  1048. return GB_WIDTH_TYPE::SUPER;
  1049. }
  1050. return GB_WIDTH_TYPE::INVALID;
  1051. }
  1052. BOOL CGBFieldData::CaculateLevelFatWidth(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel)
  1053. {
  1054. if (a_listParticles.empty())
  1055. {
  1056. return FALSE;
  1057. }
  1058. double dMin = 0, dMax = 0;
  1059. switch ((int)a_nLevel)
  1060. {
  1061. case (int)GB_LEVEL_TYPE::A_TYPE:
  1062. dMin = 4;
  1063. dMax = 12;
  1064. break;
  1065. case (int)GB_LEVEL_TYPE::B_TYPE:
  1066. dMin = 9;
  1067. dMax = 15;
  1068. break;
  1069. case (int)GB_LEVEL_TYPE::C_TYPE:
  1070. dMin = 5;
  1071. dMax = 12;
  1072. break;
  1073. case (int)GB_LEVEL_TYPE::D_TYPE:
  1074. dMin = 8;
  1075. dMax = 13;
  1076. break;
  1077. }
  1078. BOOL bFat = TRUE;
  1079. for (auto pParticle : a_listParticles)
  1080. {
  1081. CRect rectParticle = pParticle->GetParticleRect();
  1082. double dWidth = (double)rectParticle.Width();
  1083. if (dWidth < dMin || dWidth > dMax)
  1084. {
  1085. bFat = FALSE;
  1086. break;
  1087. }
  1088. }
  1089. return bFat;
  1090. }
  1091. BOOL CGBFieldData::CaculateSuper(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel)
  1092. {
  1093. if (a_listParticles.empty())
  1094. {
  1095. return FALSE;
  1096. }
  1097. double dMin = 0;
  1098. switch ((int)a_nLevel)
  1099. {
  1100. case (int)GB_LEVEL_TYPE::A_TYPE:
  1101. dMin = 12;
  1102. break;
  1103. case (int)GB_LEVEL_TYPE::B_TYPE:
  1104. dMin = 15;
  1105. break;
  1106. case (int)GB_LEVEL_TYPE::C_TYPE:
  1107. dMin = 12;
  1108. break;
  1109. case (int)GB_LEVEL_TYPE::D_TYPE:
  1110. dMin = 13;
  1111. break;
  1112. }
  1113. BOOL bSuper = TRUE;
  1114. for (auto pParticle : a_listParticles)
  1115. {
  1116. CRect rectParticle = pParticle->GetParticleRect();
  1117. double dWidth = (double)rectParticle.Width();
  1118. if (dWidth < dMin)
  1119. {
  1120. bSuper = FALSE;
  1121. break;
  1122. }
  1123. }
  1124. return bSuper;
  1125. }
  1126. BOOL CGBFieldData::IdentifyPartChemicalType(COTSParticlePtr Particle)
  1127. {
  1128. if (Particle->GetXrayInfo() == NULL)
  1129. {
  1130. Particle->SetChemicalType(GB_CHEMICAL_TYPE::INVALID);
  1131. return false;
  1132. }
  1133. auto chamicalList = Particle->GetXrayInfo()->GetElementQuantifyData();
  1134. double dOWeight = 0;
  1135. double dSWeight = 0;
  1136. double dNWeight = 0;
  1137. double dSiWeight = 0;
  1138. double dAlWeight = 0;
  1139. double dMnWeight = 0;
  1140. double dFeWeight = 0;
  1141. double dCWeight = 0;
  1142. for (auto pElChem : chamicalList)
  1143. {
  1144. if (pElChem->GetName().CompareNoCase(STR_O) == 0)
  1145. {
  1146. dOWeight = pElChem->GetPercentage();
  1147. }
  1148. else if (pElChem->GetName().CompareNoCase(STR_SUL) == 0)
  1149. {
  1150. dSWeight = pElChem->GetPercentage();
  1151. }
  1152. else if (pElChem->GetName().CompareNoCase(STR_N) == 0)
  1153. {
  1154. dNWeight = pElChem->GetPercentage();
  1155. }
  1156. else if (pElChem->GetName().CompareNoCase(STR_SI) == 0)
  1157. {
  1158. dSiWeight = pElChem->GetPercentage();
  1159. }
  1160. else if (pElChem->GetName().CompareNoCase(STR_Al) == 0)
  1161. {
  1162. dAlWeight = pElChem->GetPercentage();
  1163. }
  1164. else if (pElChem->GetName().CompareNoCase(STR_Mn) == 0)
  1165. {
  1166. dMnWeight = pElChem->GetPercentage();
  1167. }
  1168. else if (pElChem->GetName().CompareNoCase(STR_Fe) == 0)
  1169. {
  1170. dFeWeight = pElChem->GetPercentage();
  1171. }
  1172. else if (pElChem->GetName().CompareNoCase(STR_C) == 0)
  1173. {
  1174. dCWeight = pElChem->GetPercentage();
  1175. }
  1176. }
  1177. if (dSWeight >= MIN_ELEMENT_SUM && dMnWeight > MIN_ELEMENT_SUM)
  1178. {
  1179. Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S);
  1180. }
  1181. else if (dSWeight >= MIN_ELEMENT_SUM && dOWeight < MIN_ELEMENT_SUM)//
  1182. {
  1183. Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S);
  1184. }
  1185. else if (dOWeight >= MIN_ELEMENT_SUM && dAlWeight >= MIN_ELEMENT_SUM)
  1186. {
  1187. Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_Al);
  1188. }
  1189. else if (dOWeight >= MIN_ELEMENT_SUM && dSiWeight >= MIN_ELEMENT_SUM)
  1190. {
  1191. Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_Si);
  1192. }
  1193. else if (dOWeight >= RICH_ELEMENT_SUM)
  1194. {
  1195. Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_O);
  1196. }
  1197. else
  1198. {
  1199. Particle->SetChemicalType(GB_CHEMICAL_TYPE::INVALID);
  1200. }
  1201. return TRUE;
  1202. }
  1203. std::string CGBFieldData::GetGBGradeString()
  1204. {
  1205. std::string grdStr;
  1206. CString Astring = _T("A:") + GetGradeString(m_pALevel->GetThinGrade()) + _T(" ") +
  1207. GetGradeString(m_pALevel->GetWideGrade()) + _T(" ") +
  1208. GetGradeString(m_pALevel->GetSuperGrade()) + _T(" ");
  1209. CString Bstring = _T("B:") + GetGradeString(m_pBLevel->GetThinGrade()) + _T(" ") +
  1210. GetGradeString(m_pBLevel->GetWideGrade()) + _T(" ") +
  1211. GetGradeString(m_pBLevel->GetSuperGrade()) + _T(" ");
  1212. CString Cstring = _T("C:") + GetGradeString(m_pCLevel->GetThinGrade()) + _T(" ") +
  1213. GetGradeString(m_pCLevel->GetWideGrade()) + _T(" ") +
  1214. GetGradeString(m_pCLevel->GetSuperGrade()) + _T(" ");
  1215. CString Dstring = _T("D:") + GetGradeString(m_pDLevel->GetThinGrade())+_T(" ") +
  1216. GetGradeString(m_pDLevel->GetWideGrade()) +_T(" ") +
  1217. GetGradeString(m_pDLevel->GetSuperGrade()) +_T(" ");
  1218. if (calcuType == GB_METHODE_TYPE::METHODE_2)
  1219. {
  1220. CString DSulstring = _T("DSulfide:") + GetGradeString(GetDSulfideLevel()->GetThinGrade()) + _T(" ") +
  1221. GetGradeString(GetDSulfideLevel()->GetWideGrade()) + _T(" ") +
  1222. GetGradeString(GetDSulfideLevel()->GetSuperGrade());
  1223. grdStr= std::string((Astring + Bstring + Cstring + Dstring + DSulstring).GetBuffer());
  1224. }
  1225. else
  1226. {
  1227. grdStr= std::string((Astring + Bstring + Cstring + Dstring ).GetBuffer());
  1228. }
  1229. return grdStr;
  1230. }
  1231. std::string CGBFieldData::GetGBGradeDetail()
  1232. {
  1233. std::string grdStr;
  1234. CString Astring = _T("A:") + GetGradeString(m_pALevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pALevel->GetThinLength()) + _T(")") + _T(" ") +
  1235. GetGradeString(m_pALevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pALevel->GetWideLength()) + _T(")") + _T(" ") +
  1236. GetGradeString(m_pALevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pALevel->GetSuperLength()) + _T(")") + _T(" ");
  1237. CString Bstring = _T("B:") + GetGradeString(m_pBLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetThinLength()) + _T(")") + _T(" ") +
  1238. GetGradeString(m_pBLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetWideLength()) + _T(")") + _T(" ") +
  1239. GetGradeString(m_pBLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetSuperLength()) + _T(")") + _T(" ");
  1240. CString Cstring = _T("C:") + GetGradeString(m_pCLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetThinLength()) + _T(")") + _T(" ") +
  1241. GetGradeString(m_pCLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetWideLength()) + _T(")") + _T(" ") +
  1242. GetGradeString(m_pCLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetSuperLength()) + _T(")") + _T(" ");
  1243. CString Dstring = _T("D:") + GetGradeString(m_pDLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetThinLength()) + _T(")") + _T(" ") +
  1244. GetGradeString(m_pDLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetWideLength()) + _T(")") + _T(" ") +
  1245. GetGradeString(m_pDLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetSuperLength()) + _T(")") + _T(" ");
  1246. if (calcuType == GB_METHODE_TYPE::METHODE_2)
  1247. {
  1248. CString DSulstring = _T("DSulfide:") + GetGradeString(GetDSulfideLevel()->GetThinGrade()) + _T(" ") +
  1249. GetGradeString(GetDSulfideLevel()->GetWideGrade()) + _T(" ") +
  1250. GetGradeString(GetDSulfideLevel()->GetSuperGrade());
  1251. grdStr = std::string((Astring + Bstring + Cstring + Dstring + DSulstring).GetBuffer());
  1252. }
  1253. else
  1254. {
  1255. grdStr = std::string((Astring + Bstring + Cstring + Dstring).GetBuffer());
  1256. }
  1257. return grdStr;
  1258. }
  1259. GB_GRADE_TYPE CGBFieldData::GetGBTopGrade()
  1260. {
  1261. GB_GRADE_TYPE gr = GetALevel()->GetThinGrade();
  1262. gr = std::max<GB_GRADE_TYPE>(gr, GetALevel()->GetWideGrade());
  1263. gr = std::max<GB_GRADE_TYPE>(gr, GetALevel()->GetSuperGrade());
  1264. gr = std::max<GB_GRADE_TYPE>(gr, GetBLevel()->GetThinGrade());
  1265. gr = std::max<GB_GRADE_TYPE>(gr, GetBLevel()->GetWideGrade());
  1266. gr = std::max<GB_GRADE_TYPE>(gr, GetBLevel()->GetSuperGrade());
  1267. gr = std::max<GB_GRADE_TYPE>(gr, GetCLevel()->GetThinGrade());
  1268. gr = std::max<GB_GRADE_TYPE>(gr, GetCLevel()->GetWideGrade());
  1269. gr = std::max<GB_GRADE_TYPE>(gr, GetCLevel()->GetSuperGrade());
  1270. gr = std::max<GB_GRADE_TYPE>(gr, GetDLevel()->GetThinGrade());
  1271. gr = std::max<GB_GRADE_TYPE>(gr, GetDLevel()->GetWideGrade());
  1272. gr = std::max<GB_GRADE_TYPE>(gr, GetDLevel()->GetSuperGrade());
  1273. gr = std::max<GB_GRADE_TYPE>(gr, GetDSulfideLevel()->GetThinGrade());
  1274. gr = std::max<GB_GRADE_TYPE>(gr, GetDSulfideLevel()->GetWideGrade());
  1275. gr = std::max<GB_GRADE_TYPE>(gr, GetDSulfideLevel()->GetSuperGrade());
  1276. return gr;
  1277. }
  1278. }