GBFieldData.cpp 35 KB

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