OTSProjMgrFile.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923
  1. #pragma once
  2. #include "stdafx.h"
  3. #include "OTSProjMgrFile.h"
  4. #include "OTSProgMgr.h"
  5. #include "StageFile.h"
  6. #include "STDXMLFileMnr.h"
  7. #include "MsrParamFileMgr.h"
  8. #include "OTSImageProcess.h"
  9. #include "OTSFileSys.h"
  10. #include "OTSHelper.h"
  11. #include "resource.h"
  12. #include "SmplMsrResultFile.h"
  13. #include "IncAFileMgr.h"
  14. #include <io.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. namespace OTSMODEL {
  18. using namespace OTSIMGPROC;
  19. // project file mark
  20. const int PROJ_MGR_FILE_MARK = 'P' + 'R' + 'O' + 'J' + 'E' + 'T' + 'M' + 'A' + 'N' + 'A' + 'G' + 'E' + 'R';
  21. // project file version string
  22. const CString PROJ_MGR_FILE_VERSION = _T("1.1.1");
  23. // project file extension
  24. const CString PROJ_EXTION = _T("prj");
  25. // project file filter
  26. const CString PROJECT_FILE_FILTER = _T("Project Files (*.prj)|*.prj|All Files (*.*)|*.*||");
  27. // EDGE threshold if length > 15000 edge is 1000, if length > 10000 edge is 500, otherwise no edge, unit is um
  28. const long LENGTH_THRESHOLD = 150000;
  29. const long LENGTH_THRESHOLD_MIN = 10000;
  30. const long EDGE = 1000;
  31. const long EDGE_MIN = 500;
  32. // COTSProjMgrFile
  33. // constructor
  34. COTSProjMgrFile::COTSProjMgrFile()
  35. {
  36. Init();
  37. }
  38. // copy constructor
  39. COTSProjMgrFile::COTSProjMgrFile(const COTSProjMgrFile& a_oSource)
  40. {
  41. // can't copy itself
  42. if (&a_oSource == this)
  43. {
  44. return;
  45. }
  46. // copy data over
  47. Duplicate(a_oSource);
  48. }
  49. COTSProjMgrFile::COTSProjMgrFile(COTSProjMgrFile* a_poSource)
  50. {
  51. // input check
  52. ASSERT(a_poSource);
  53. if (!a_poSource)
  54. {
  55. return;
  56. }
  57. // can't copy itself
  58. if (a_poSource == this)
  59. {
  60. return;
  61. }
  62. // copy data over
  63. Duplicate(*a_poSource);
  64. }
  65. // =operator
  66. COTSProjMgrFile& COTSProjMgrFile::operator=(const COTSProjMgrFile& a_oSource)
  67. {
  68. // cleanup
  69. Cleanup();
  70. // copy the class data over
  71. Duplicate(a_oSource);
  72. // return class
  73. return *this;
  74. }
  75. // destructor
  76. COTSProjMgrFile::~COTSProjMgrFile()
  77. {
  78. // cleanup
  79. Cleanup();
  80. }
  81. // serialization
  82. void COTSProjMgrFile::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
  83. {
  84. xmls::xInt xProjMgrFileMark;
  85. xmls::xString xProjMgrFileVersion;
  86. xmls::xString xstrPathName;
  87. xmls::Collection< CHoleBSEImg> xholeBSEImgs;
  88. xmls::Collection<COTSSample> xsamples;
  89. xmls::Slo slo;
  90. slo.Register("ProjMgrFileMark", &xProjMgrFileMark);
  91. slo.Register("ProjMgrFileVersion", &xProjMgrFileVersion);
  92. slo.Register("strPathName", &xstrPathName);
  93. slo.Register("SEMStageData", m_pSEMStageData.get());
  94. slo.Register("Stage", m_pStage.get());
  95. slo.Register("HoleBSEImg", &xholeBSEImgs);
  96. slo.Register("Samples", &xsamples);
  97. if (isStoring)
  98. {
  99. xProjMgrFileMark = PROJ_MGR_FILE_MARK;
  100. xProjMgrFileVersion = PROJ_MGR_FILE_VERSION;
  101. xstrPathName = m_strPathName;
  102. xholeBSEImgs.Clear();
  103. for (auto hole : m_listHoleBSEImg)
  104. {
  105. xholeBSEImgs.addItem(hole.get());
  106. }
  107. xsamples.Clear();
  108. for (auto sample : m_listSamples)
  109. {
  110. xsamples.addItem(sample.get());
  111. }
  112. slo.Serialize(true, classDoc, rootNode);
  113. }
  114. else
  115. {
  116. slo.Serialize(false, classDoc, rootNode);
  117. m_strPathName = xstrPathName.value().c_str();
  118. m_listHoleBSEImg.clear();
  119. for (unsigned int i = 0; i < xholeBSEImgs.size(); i++)
  120. {
  121. m_listHoleBSEImg.push_back(CHoleBSEImgPtr(xholeBSEImgs.getItem(i)));
  122. }
  123. m_listSamples.clear();
  124. for (int i = 0; i < (int)xsamples.size(); i++)
  125. {
  126. m_listSamples.push_back(COTSSamplePtr(xsamples.getItem(i)));
  127. }
  128. }
  129. }
  130. // class member functions
  131. // public
  132. // file
  133. BOOL COTSProjMgrFile::NewFile()
  134. {
  135. // file invalidation
  136. if (!IsValid())
  137. {
  138. // shouldn't happen, file is invalid
  139. LogErrorTrace(__FILE__, __LINE__, _T("Load: file is invalid."));
  140. return FALSE;
  141. }
  142. // set file name
  143. SetPathName(UNTITLED_FILE_NAME);
  144. // Ok, return TRUE
  145. return TRUE;
  146. }
  147. BOOL COTSProjMgrFile::Load()
  148. {
  149. // use dll resource
  150. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  151. // open file dialog,
  152. CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, PROJECT_FILE_FILTER);
  153. if (dlg.DoModal() != IDOK)
  154. {
  155. // user didn't click OK button, return FALSE
  156. LogTrace(__FILE__, __LINE__, _T("Load: user canceled on file open dialog."));
  157. return FALSE;
  158. }
  159. //Init data
  160. Cleanup();
  161. // get file name
  162. CString strPathName = dlg.GetPathName();
  163. // check if the file exist
  164. if (!COTSFileSys::Exists(strPathName))
  165. {
  166. // shouldn't happen, file does not exist
  167. LogErrorTrace(__FILE__, __LINE__, _T("Load: file (%s) does not exist."), strPathName);
  168. return FALSE;
  169. }
  170. tinyxml2::XMLDocument doc;
  171. doc.LoadFile(strPathName);//载入xml文件
  172. tinyxml2::XMLElement *rootNode;
  173. rootNode = doc.FirstChildElement(RootClassName);
  174. Serialize(false, &doc, rootNode);
  175. m_strPathName = strPathName;
  176. // get path of the pathname
  177. CString strFilePath = COTSHelper::GetFolderName(strPathName);
  178. if (strFilePath.IsEmpty())
  179. {
  180. // file path string is an empty string
  181. LogErrorTrace(__FILE__, __LINE__, _T("Load: file path string is an empty string."));
  182. return FALSE;
  183. }
  184. //-------------
  185. for(auto smpl:m_listSamples)
  186. {
  187. // field file sub folder string
  188. CString strFieldFileSubFolder = strFilePath + _T("\\")+smpl->GetName()+_T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER + _T("\\");
  189. // check if the field file sub folder exists
  190. if (!COTSFileSys::Exists(strFieldFileSubFolder))
  191. {// field files folder doesn't exist
  192. //LogErrorTrace(__FILE__, __LINE__, _T("Load: field files folder doesn't exist (%s)."), strFieldFileSubFolder);
  193. continue;
  194. }
  195. CString strIncAFilename = strFieldFileSubFolder + _T("\\") + SMPL_MSR_RESULT_INCLUSION_FILE;
  196. CIncAFileMgrPtr pIncAFileMgr = CIncAFileMgrPtr(new CIncAFileMgr(strIncAFilename));
  197. COTSFieldDataList allFlds;
  198. CMsrSampleStatusPtr poMsrStatus = smpl->GetMsrStatus();
  199. CMsrResultsPtr poMsrResults = smpl->GetMsrResults();
  200. double aFldArea = smpl->CalculateAFieldArea();
  201. if (pIncAFileMgr->GetAllFieldsFromDB(allFlds, poMsrStatus, poMsrResults, aFldArea))
  202. {
  203. smpl->SetFieldsData(allFlds);
  204. // file validation
  205. if (!m_pSEMStageData || *(m_pSEMStageData.get()) == CSEMStageData())
  206. {
  207. // invalid SME stage data
  208. LogErrorTrace(__FILE__, __LINE__, _T("Load: invalid SME stage data."));
  209. return FALSE;
  210. }
  211. if (!m_pStage || *(m_pStage.get()) == CStage())
  212. {
  213. // invalid stage
  214. LogErrorTrace(__FILE__, __LINE__, _T("Load: empty SEM stage data."));
  215. return FALSE;
  216. }
  217. // set modify flag
  218. SetModify(FALSE);
  219. // set pathname
  220. SetPathName(strPathName);
  221. // set working sample
  222. if (m_listSamples.size() > 0)
  223. {
  224. m_nWorkingSampeIndex = 0;
  225. }
  226. else
  227. {
  228. m_nWorkingSampeIndex = -1;
  229. }
  230. }
  231. else
  232. {
  233. return FALSE;
  234. }
  235. }
  236. if (!m_listSamples.empty())
  237. {
  238. m_nWorkingSampeIndex = 0;
  239. }
  240. //-----------------------------------------
  241. return TRUE;
  242. }
  243. BOOL COTSProjMgrFile::Save()
  244. {
  245. // Save or Save As, if strPathName is not empty, it is exist in the computer, this is a save action
  246. CString strPathName = GetPathName();
  247. // is this a new file?
  248. strPathName.Trim();
  249. if (strPathName.CompareNoCase(UNTITLED_FILE_NAME) == 0)
  250. {
  251. if (!SaveAs())
  252. {
  253. return FALSE;
  254. }
  255. // this is a new file
  256. for (auto pSample : m_listSamples)
  257. {
  258. DeleteSampleFiles(pSample->GetName());
  259. }
  260. //DeleteSampleFiles
  261. // return save as result
  262. }
  263. tinyxml2::XMLDocument doc;
  264. if (COTSFileSys::Exists(strPathName))
  265. {
  266. doc.LoadFile(strPathName);//载入xml文件
  267. }
  268. doc.Clear();
  269. tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();//添加xml文件头申明
  270. doc.InsertFirstChild(declaration);
  271. tinyxml2::XMLElement *rootNode;
  272. rootNode = doc.NewElement(RootClassName);
  273. Serialize(true, &doc, rootNode);
  274. doc.InsertEndChild(rootNode);
  275. int result = doc.SaveFile(strPathName);
  276. // set file modify flag
  277. SetModify(FALSE);
  278. // Ok, return TRUE
  279. return TRUE;
  280. }
  281. BOOL COTSProjMgrFile::SaveAs()
  282. {
  283. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  284. // save file dialog
  285. CString strFileName = _T("");
  286. if (!m_strPathName.IsEmpty())
  287. {
  288. strFileName = COTSHelper::GetFileName(m_strPathName);
  289. }
  290. CFileDialog dlg(FALSE, PROJ_EXTION, strFileName, OFN_OVERWRITEPROMPT, PROJECT_FILE_FILTER);
  291. if (dlg.DoModal() != IDOK)
  292. {
  293. // user didn't click OK button, return FALSE
  294. LogTrace(__FILE__, __LINE__, _T("SaveAs: user canceled on file open dialog."));
  295. return FALSE;
  296. }
  297. // get file pathname
  298. CString strPathName = dlg.GetPathName();
  299. //--------xml serialize-------
  300. tinyxml2::XMLDocument doc;
  301. if (COTSFileSys::Exists(strPathName))
  302. {
  303. doc.LoadFile(strPathName);//载入xml文件
  304. }
  305. doc.Clear();
  306. tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();//添加xml文件头申明
  307. doc.InsertFirstChild(declaration);
  308. tinyxml2::XMLElement *rootNode;
  309. rootNode = doc.NewElement(RootClassName);
  310. doc.InsertEndChild(rootNode);
  311. Serialize(true, &doc, rootNode);
  312. int result = doc.SaveFile(strPathName);
  313. //-----------------------------
  314. // set file modify flag
  315. m_bModify = FALSE;
  316. // Set project Path
  317. SetPathName(strPathName);
  318. // Ok, return TRUE
  319. return TRUE;
  320. }
  321. BOOL COTSProjMgrFile::IsValid()
  322. {
  323. if (!m_pSEMStageData || m_pSEMStageData.get() == nullptr)
  324. {
  325. return FALSE;
  326. }
  327. else if (!m_pStage || m_pStage.get() == nullptr)
  328. {
  329. return FALSE;
  330. }
  331. else if (!m_pGenParam || !m_pImageProcParam || !m_pImageScanParam || !m_pXRayParam)
  332. {
  333. return FALSE;
  334. }
  335. // Ok, return TRUE
  336. return TRUE;
  337. }
  338. // SEM stage data
  339. void COTSProjMgrFile::SetSEMStageData(CSEMStageDataPtr a_pCSEMStageData)
  340. {
  341. // safety check
  342. ASSERT(a_pCSEMStageData);
  343. if (!a_pCSEMStageData)
  344. {
  345. // invalid stage data pointer
  346. LogErrorTrace(__FILE__, __LINE__, _T("SetStageData: invalid input stage data pointer."));
  347. return;
  348. }
  349. m_pSEMStageData = CSEMStageDataPtr(new CSEMStageData(a_pCSEMStageData.get()));
  350. }
  351. // stage (working stage)
  352. void COTSProjMgrFile::SetStage(CStagePtr a_pStage)
  353. {
  354. // safety check
  355. ASSERT(a_pStage);
  356. if (!a_pStage)
  357. {
  358. // invalid input
  359. LogErrorTrace(__FILE__, __LINE__, _T("SetStage: invalid input stage pointer."));
  360. return;
  361. }
  362. m_pStage = CStagePtr(new CStage(a_pStage.get()));
  363. }
  364. // general parameters
  365. void COTSProjMgrFile::SetGenParam(COTSGeneralParametersPtr a_pGenParam)
  366. {
  367. ASSERT(a_pGenParam);
  368. if (!a_pGenParam)
  369. {
  370. // invalid input
  371. LogErrorTrace(__FILE__, __LINE__, _T("SetGenParam: invalid input general parameter pointer."));
  372. return;
  373. }
  374. m_pGenParam = COTSGeneralParametersPtr(new COTSGeneralParameters(a_pGenParam.get()));
  375. }
  376. // image scan parameters
  377. void COTSProjMgrFile::SetImageScanParam(COTSImageScanParamPtr a_pImageScanParam)
  378. {
  379. ASSERT(a_pImageScanParam);
  380. if (!a_pImageScanParam)
  381. {
  382. // invalid input
  383. LogErrorTrace(__FILE__, __LINE__, _T("SetImageScanParam: invalid input image scan parameter pointer."));
  384. return;
  385. }
  386. m_pImageScanParam = COTSImageScanParamPtr(new COTSImageScanParam(a_pImageScanParam.get()));
  387. }
  388. // image process parameters
  389. void COTSProjMgrFile::SetImageProcParam(COTSImageProcessParamPtr a_pImageProcParam)
  390. {
  391. ASSERT(a_pImageProcParam);
  392. if (!a_pImageProcParam)
  393. {
  394. // invalid input
  395. LogErrorTrace(__FILE__, __LINE__, _T("SetImageProcParam: invalid input image process parameter pointer."));
  396. return;
  397. }
  398. m_pImageProcParam = COTSImageProcessParamPtr(new COTSImageProcessParam(a_pImageProcParam.get()));
  399. }
  400. // x ray parameters
  401. void COTSProjMgrFile::SetXRayParam(COTSXRayParamPtr a_pXRayParam)
  402. {
  403. ASSERT(a_pXRayParam);
  404. if (!a_pXRayParam)
  405. {
  406. LogErrorTrace(__FILE__, __LINE__, _T("SetXRayParam: invalid X-Ray parameter pointer."));
  407. return;
  408. }
  409. m_pXRayParam = COTSXRayParamPtr(new COTSXRayParam(a_pXRayParam.get()));
  410. }
  411. // samples list
  412. bool COTSProjMgrFile::SetSampleList(COTSSamplesList& a_listSample, BOOL a_bClear/* = TRUE*/)
  413. {
  414. // clear samples list if necessary
  415. if (a_bClear)
  416. {
  417. m_listSamples.clear();
  418. }
  419. // go through the sample list of the source
  420. for (auto pSample : a_listSample)
  421. {
  422. // add the new sample into sample list
  423. m_listSamples.push_back(pSample);
  424. }
  425. return true;
  426. }
  427. COTSSamplePtr COTSProjMgrFile::GetSampleByIndex(int a_nIndex)
  428. {
  429. // safe check
  430. if (a_nIndex < 0 || a_nIndex >= (int)m_listSamples.size())
  431. {
  432. // invalid sample id
  433. LogErrorTrace(__FILE__, __LINE__, _T("GetSample: invalid sample id."));
  434. return nullptr;
  435. }
  436. // get the matching sample
  437. COTSSamplePtr pSample = m_listSamples[a_nIndex];
  438. // return the sample
  439. return pSample;
  440. }
  441. COTSSamplePtr COTSProjMgrFile::GetSampleByName(CString a_strSampleName)
  442. {
  443. // find the name matching sample
  444. auto itr = std::find_if(m_listSamples.begin(), m_listSamples.end(), [a_strSampleName](COTSSamplePtr p) { return p->GetName().CompareNoCase(a_strSampleName) == 0; });
  445. // get the matching sample if found
  446. COTSSamplePtr pSample = nullptr;
  447. if (itr != m_listSamples.end())
  448. {
  449. pSample = *itr;
  450. }
  451. // return the sample
  452. return pSample;
  453. }
  454. COTSSamplePtr COTSProjMgrFile::AddSample(CString a_strHoleName)
  455. {
  456. // this file is valid, pass the test will make sure all the parameters are ok.
  457. if (!IsValid())
  458. {
  459. // shouldn't be here, invalid file
  460. LogErrorTrace(__FILE__, __LINE__, _T("AddSample: invalid file."));
  461. return nullptr;
  462. }
  463. // get new sample name
  464. CString strNewSampleName = GetNewSampleName();
  465. // make sure the new sample name is not an empty string
  466. strNewSampleName.Trim();
  467. //判断当前文件夹下是否有新的文件 有就删除
  468. DeleteSampleFiles(strNewSampleName);
  469. // get a suitable sample hole for the new sample
  470. CHolePtr pHole = SelectASmpleHole(a_strHoleName);
  471. // check the sample hole
  472. if (!pHole)
  473. {
  474. // failed to get sample hole for the new sample
  475. LogErrorTrace(__FILE__, __LINE__, _T("AddSample: failed to get sample hole for the new sample."));
  476. return nullptr;
  477. }
  478. // particle analysis STD lib
  479. CPartSTDDataPtr pPartSTDDataPtr = m_pGenParam->GetPartSTDLib();
  480. // measure data parameters containing particle analysis std, image scan parameter, image process parameter and x-ray parameter
  481. CMsrParamsPtr poMsrParams = CMsrParamsPtr(new CMsrParams());
  482. STEEL_TECHNOLOGY a_nVal = (STEEL_TECHNOLOGY)m_pGenParam->GetSteelTechnology();
  483. poMsrParams->SetSteelTechnology(a_nVal);
  484. poMsrParams->SetPartSTDData(pPartSTDDataPtr);
  485. poMsrParams->SetImageScanParam(m_pImageScanParam);
  486. poMsrParams->SetImageProcessParam(m_pImageProcParam);
  487. poMsrParams->SetXRayParam(m_pXRayParam);
  488. // measurement area
  489. //CDomainPtr pMsrArea = CalculateMsrArea(pHole);
  490. CDomainPtr pMsrArea = CalculateDefaultArea(pHole);
  491. // create a sample
  492. COTSSamplePtr pSample = COTSSamplePtr(new COTSSample());
  493. // set sample parameters
  494. pSample->SetName(strNewSampleName);
  495. pSample->SetSampleHoleName(pHole->GetName());
  496. pSample->SetSwitch(m_pGenParam->GetMeasurementSwitch());
  497. pSample->SetMsrParams(poMsrParams);
  498. pSample->SetMsrArea(pMsrArea);
  499. // add the new sample into the samples list
  500. m_listSamples.push_back(pSample);
  501. // set the project file modified.
  502. SetModify();
  503. // set the new as working sample
  504. m_nWorkingSampeIndex = (int)m_listSamples.size() - 1;
  505. // return the new sample
  506. return pSample;
  507. }
  508. //2020-7-30 张佳鑫
  509. BOOL COTSProjMgrFile::DeleteSampleFiles(CString a_nString)
  510. {
  511. CString strSamplePath = COTSHelper::GetFolderName(m_strPathName); //m_strPathName + _T("\\") + m_listSamples[a_nIndex]->GetName();
  512. // this sample has been measured, need to delete all the measure result files.
  513. if (COTSFileSys::IsFolder(strSamplePath))
  514. {
  515. strSamplePath = strSamplePath + _T("\\") + a_nString;
  516. CString strSampleFieldPath = strSamplePath + _T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER;
  517. if (!COTSFileSys::DeleteAllFiles(strSampleFieldPath))
  518. {
  519. return FALSE;
  520. }
  521. SetFileAttributes(strSampleFieldPath, FILE_ATTRIBUTE_NORMAL); //设置文件夹的属性
  522. RemoveDirectory(strSampleFieldPath); //删除文件夹
  523. if (!COTSFileSys::DeleteAllFiles(strSamplePath))
  524. {
  525. return FALSE;
  526. }
  527. SetFileAttributes(strSamplePath, FILE_ATTRIBUTE_NORMAL); //设置文件夹的属性
  528. RemoveDirectory(strSamplePath); //删除文件夹
  529. }
  530. }
  531. BOOL COTSProjMgrFile::DeleteSampleByIndex(int a_nIndex)
  532. {
  533. // find the sample's result file
  534. CString strSamplePath = COTSHelper::GetFolderName(m_strPathName); //m_strPathName + _T("\\") + m_listSamples[a_nIndex]->GetName();
  535. // this sample has been measured, need to delete all the measure result files.
  536. if(COTSFileSys::IsFolder(strSamplePath))
  537. {
  538. strSamplePath = strSamplePath + _T("\\") + m_listSamples[a_nIndex]->GetName();
  539. CString strSampleFieldPath = strSamplePath + _T("\\") + SMPL_MSR_RESULT_FIELDS_FILE_SUBFOLDER;
  540. if (!COTSFileSys::DeleteAllFiles(strSampleFieldPath))
  541. {
  542. return FALSE;
  543. }
  544. SetFileAttributes(strSampleFieldPath, FILE_ATTRIBUTE_NORMAL); //设置文件夹的属性
  545. RemoveDirectory(strSampleFieldPath); //删除文件夹
  546. if (!COTSFileSys::DeleteAllFiles(strSamplePath))
  547. {
  548. return FALSE;
  549. }
  550. SetFileAttributes(strSamplePath, FILE_ATTRIBUTE_NORMAL); //设置文件夹的属性
  551. RemoveDirectory(strSamplePath); //删除文件夹
  552. }
  553. // check the index
  554. if (a_nIndex < 0 || a_nIndex >= (int)m_listSamples.size())
  555. {
  556. // invalid input sample index
  557. LogErrorTrace(__FILE__, __LINE__, _T("DeleteSampleByIndex::input sample index"));
  558. return FALSE;
  559. }
  560. // calculate new working sample index
  561. int nNewWorkingSampeIndex;
  562. if (a_nIndex < m_nWorkingSampeIndex)
  563. {
  564. nNewWorkingSampeIndex = m_nWorkingSampeIndex - 1;
  565. }
  566. else if (a_nIndex > m_nWorkingSampeIndex)
  567. {
  568. nNewWorkingSampeIndex = m_nWorkingSampeIndex;
  569. }
  570. else
  571. {
  572. // deleting working sample.
  573. if (a_nIndex == (int)m_listSamples.size() - 1)
  574. {
  575. // this is the last sample, select the above sample as working sample
  576. // if this is only sample in the list working sample index will be -1;
  577. nNewWorkingSampeIndex = m_nWorkingSampeIndex - 1;
  578. }
  579. else
  580. {
  581. // select next sample as working sample
  582. nNewWorkingSampeIndex = m_nWorkingSampeIndex;
  583. }
  584. }
  585. // delete the sample
  586. m_listSamples.erase(m_listSamples.begin() + a_nIndex);
  587. // the file is modified.
  588. SetModify();
  589. // reset working sample index
  590. m_nWorkingSampeIndex = nNewWorkingSampeIndex;
  591. // ok, return TRUE
  592. return TRUE;
  593. }
  594. BOOL COTSProjMgrFile::DeleteSampleByName(CString a_strSampleName)
  595. {
  596. // check input sample name
  597. a_strSampleName.Trim();
  598. if (a_strSampleName.IsEmpty())
  599. {
  600. // input sample name is empty
  601. LogErrorTrace(__FILE__, __LINE__, _T("DeleteSampleByName: input sample name is an empty string."));
  602. return FALSE;
  603. }
  604. // go through sample list
  605. int nIndex = 0;
  606. for (auto pSample : m_listSamples)
  607. {
  608. // return TRUE if this is not an exclude sample and its name is same with input
  609. CString strSampleName = pSample->GetName();
  610. if (strSampleName.CompareNoCase(a_strSampleName) == 0)
  611. {
  612. // find the sample, return deleting result
  613. return DeleteSampleByIndex(nIndex);
  614. }
  615. ++nIndex;
  616. }
  617. // can't find the sample in the samples list, return FALSE
  618. return FALSE;
  619. }
  620. BOOL COTSProjMgrFile::SameNameInList(CString a_strSampleName, int a_nExclude /*= -1*/)
  621. {
  622. // make sure the input sample name is not empty
  623. a_strSampleName.Trim();
  624. if (a_strSampleName.IsEmpty())
  625. {
  626. // shouldn't happen, input name is an empty string
  627. LogErrorTrace(__FILE__, __LINE__, _T("SameNameInList: input name is an empty string."));
  628. return FALSE;
  629. }
  630. // go through sample list
  631. int nIndex = 0;
  632. for (auto pSample : m_listSamples)
  633. {
  634. // return TRUE if this is not an exclude sample and its name is same with input
  635. CString strSampleName = pSample->GetName();
  636. if (nIndex != a_nExclude && strSampleName.CompareNoCase(a_strSampleName) == 0)
  637. {
  638. // find a same name sample
  639. return TRUE;
  640. }
  641. ++nIndex;
  642. }
  643. // no, same name sample in the same list, return FALSE
  644. return FALSE;
  645. }
  646. BOOL COTSProjMgrFile::ResetSamplesListOrder(std::vector<CString> a_listSampleNames)
  647. {
  648. // no sample in the samples list; shouldn't be here
  649. if (m_listSamples.size() == 0)
  650. {
  651. LogErrorTrace(__FILE__, __LINE__, _T("ResetSamplesListOrder: no sample in samples list."));
  652. return FALSE;
  653. }
  654. // make sure that input sample names list size is same with the samples list
  655. if (m_listSamples.size() != a_listSampleNames.size())
  656. {
  657. LogErrorTrace(__FILE__, __LINE__, _T("ResetSamplesListOrder: sample names list has different size with the samples list."));
  658. return FALSE;
  659. }
  660. // new sample list
  661. COTSSamplesList listSamples;
  662. // go through the sample names list
  663. for (auto strSampleName : a_listSampleNames)
  664. {
  665. // find the sample
  666. auto itr = find_if(m_listSamples.begin(), m_listSamples.end(), [strSampleName](COTSSamplePtr p) { return p->GetName().CompareNoCase(strSampleName) == 0; });
  667. if (itr == m_listSamples.end())
  668. {
  669. // failed to find the sample
  670. LogErrorTrace(__FILE__, __LINE__, _T("ResetSamplesListOrder: failed to find the sample (%s)."), strSampleName);
  671. return FALSE;
  672. }
  673. // add the sample into the new list
  674. listSamples.push_back(*itr);
  675. }
  676. // reset the samples list
  677. m_listSamples.clear();
  678. for (auto pSample : listSamples)
  679. {
  680. m_listSamples.push_back(pSample);
  681. }
  682. // set modify flag
  683. SetModify();
  684. // Ok, return TRUE
  685. return TRUE;
  686. }
  687. BOOL COTSProjMgrFile::InsrtSample(COTSSamplePtr a_pSample, int a_nIndex)
  688. {
  689. // input check
  690. ASSERT(a_pSample);
  691. if (!a_pSample)
  692. {
  693. // invalid input sample pointer
  694. LogErrorTrace(__FILE__, __LINE__, _T("InsrtSample: invalid input sample pointer."));
  695. return FALSE;
  696. }
  697. if (m_listSamples.size() == 0 || a_nIndex >= (int)m_listSamples.size())
  698. {
  699. m_listSamples.push_back(a_pSample);
  700. }
  701. else if (a_nIndex <= 0)
  702. {
  703. m_listSamples.insert(m_listSamples.begin(), a_pSample);
  704. }
  705. else
  706. {
  707. m_listSamples.insert(m_listSamples.begin() + a_nIndex, a_pSample);
  708. }
  709. // Ok, return TRUE
  710. return TRUE;
  711. }
  712. BOOL COTSProjMgrFile::ChangeSamplePosition(int a_nIndexFrom, int a_nIndexTo)
  713. {
  714. // make sure both index are valid
  715. if (a_nIndexFrom < 0 || a_nIndexFrom >= (int)m_listSamples.size())
  716. {
  717. // invalid from index
  718. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSamplePosition: invalid from index."));
  719. return FALSE;
  720. }
  721. if (a_nIndexTo < 0 || a_nIndexTo >= (int)m_listSamples.size())
  722. {
  723. // invalid to index
  724. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSamplePosition: invalid to index."));
  725. return FALSE;
  726. }
  727. // need to do nothing if the two indexes are the same
  728. if (a_nIndexFrom != a_nIndexTo)
  729. {
  730. // move to last?
  731. BOOL bLast = (a_nIndexTo == ((int)m_listSamples.size() - 1));
  732. // get the sample
  733. COTSSamplePtr pSample = m_listSamples.at(a_nIndexFrom);
  734. // remove it from the samples list
  735. m_listSamples.erase(m_listSamples.begin() + a_nIndexFrom);
  736. // put the sample back in
  737. if (bLast)
  738. {
  739. m_listSamples.push_back(pSample);
  740. }
  741. else
  742. {
  743. m_listSamples.insert(m_listSamples.begin() + a_nIndexTo, pSample);
  744. }
  745. }
  746. // Ok, return TRUE
  747. return TRUE;
  748. }
  749. BOOL COTSProjMgrFile::MoveSamplePosition(COTSSamplePtr a_pTargetSample, COTSSamplePtr a_RefpSample, BOOL a_bBefore /*= TRUE*/)
  750. {
  751. // check input
  752. ASSERT(a_pTargetSample);
  753. if (!a_pTargetSample)
  754. {
  755. // invalid input target sample pointer
  756. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: invalid input target sample pointer."));
  757. return FALSE;
  758. }
  759. ASSERT(a_RefpSample);
  760. if (!a_RefpSample)
  761. {
  762. // invalid input ref sample pointer
  763. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: invalid input ref sample pointer."));
  764. return FALSE;
  765. }
  766. auto itrTarget = std::find(m_listSamples.begin(), m_listSamples.end(), a_pTargetSample);
  767. if (itrTarget == m_listSamples.end())
  768. {
  769. // target sample in not in the samples list
  770. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: target sample in not in the samples list."));
  771. return FALSE;
  772. }
  773. auto itrRef = std::find(m_listSamples.begin(), m_listSamples.end(), a_RefpSample);
  774. if (itrRef == m_listSamples.end())
  775. {
  776. // ref sample in not in the samples list
  777. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: ref sample in not in the samples list."));
  778. return FALSE;
  779. }
  780. // need to do nothing if the two sample are same
  781. if (itrTarget != itrRef)
  782. {
  783. // remove the sample from the samples list
  784. m_listSamples.erase(itrTarget);
  785. // find ref sample position again
  786. itrRef = std::find(m_listSamples.begin(), m_listSamples.end(), a_RefpSample);
  787. if (itrRef == m_listSamples.end())
  788. {
  789. // shouldn't happen, ref sample in not in the samples list
  790. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: ref sample in not in the samples list."));
  791. return FALSE;
  792. }
  793. // put the sample back in
  794. if (a_bBefore)
  795. {
  796. m_listSamples.insert(itrRef, a_pTargetSample);
  797. }
  798. else
  799. {
  800. m_listSamples.insert(itrRef + 1, a_pTargetSample);
  801. }
  802. }
  803. // Ok, return TRUE
  804. return TRUE;
  805. }
  806. BOOL COTSProjMgrFile::MoveSamplePosition(CString a_strTargetSampleName, CString a_strRefSampleName, BOOL a_bBefore /*= TRUE*/)
  807. {
  808. // input check
  809. a_strTargetSampleName.Trim();
  810. if (a_strTargetSampleName.IsEmpty())
  811. {
  812. // input target sample is an empty string
  813. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: input target sample is an empty string."));
  814. return FALSE;
  815. }
  816. a_strRefSampleName.Trim();
  817. if (a_strRefSampleName.IsEmpty())
  818. {
  819. // input ref sample is an empty string
  820. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: input ref sample is an empty string."));
  821. return FALSE;
  822. }
  823. auto itr = std::find_if(m_listSamples.begin(), m_listSamples.end(), [a_strTargetSampleName](COTSSamplePtr p) { return p->GetName().CompareNoCase(a_strTargetSampleName) == 0; });
  824. if (itr == m_listSamples.end())
  825. {
  826. // target sample name is not the name of any sample in the samples list
  827. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: target sample is not the name of any sample in the samples list."));
  828. return FALSE;
  829. }
  830. COTSSamplePtr pTargetSample = *itr;
  831. itr = std::find_if(m_listSamples.begin(), m_listSamples.end(), [a_strRefSampleName](COTSSamplePtr p) { return p->GetName().CompareNoCase(a_strRefSampleName) == 0; });
  832. if (itr == m_listSamples.end())
  833. {
  834. // ref sample name is not the name of any sample in the samples list
  835. LogErrorTrace(__FILE__, __LINE__, _T("MoveSamplePosition: ref sample is not the name of any sample in the samples list."));
  836. return FALSE;
  837. }
  838. COTSSamplePtr pRefSample = *itr;
  839. // need to do nothing if the two name are same
  840. if (a_strTargetSampleName.CompareNoCase(a_strRefSampleName) != 0)
  841. {
  842. return MoveSamplePosition(pTargetSample, pRefSample, a_bBefore);
  843. }
  844. // Ok, return TRUE
  845. return TRUE;
  846. }
  847. // working sample
  848. COTSSamplePtr COTSProjMgrFile::GetWorkingSample()
  849. {
  850. // check if the working sample index
  851. if ( m_nWorkingSampeIndex < 0 || m_nWorkingSampeIndex >= (int)m_listSamples.size())
  852. {
  853. // invalid working sample index
  854. return nullptr;
  855. }
  856. return GetSampleByIndex(m_nWorkingSampeIndex);
  857. }
  858. BOOL COTSProjMgrFile::SetWorkingSampleByIndex(int a_nIndex)
  859. {
  860. // special treatment
  861. if (a_nIndex == -1 && m_listSamples.size() == 0)
  862. {
  863. m_nWorkingSampeIndex = -1;
  864. return TRUE;
  865. }
  866. // check if the working sample index
  867. if (0 > a_nIndex || a_nIndex >= (int)m_listSamples.size())
  868. {
  869. // invalid sample index
  870. return FALSE;
  871. }
  872. m_nWorkingSampeIndex = a_nIndex;
  873. return TRUE;
  874. }
  875. BOOL COTSProjMgrFile::SetWorkingSampleByName(CString a_pSampleName)
  876. {
  877. // check input sample name
  878. a_pSampleName.Trim();
  879. if (a_pSampleName.IsEmpty())
  880. {
  881. // input sample name is empty
  882. LogErrorTrace(__FILE__, __LINE__, _T("SetWorkingSampleByName: input sample name is an empty string."));
  883. return FALSE;
  884. }
  885. // go through sample list
  886. int nIndex = 0;
  887. for (auto pSample : m_listSamples)
  888. {
  889. // return TRUE if this is not an exclude sample and its name is same with input
  890. CString strSampleName = pSample->GetName();
  891. if (strSampleName.CompareNoCase(a_pSampleName) == 0)
  892. {
  893. // find the sample, return deleting result
  894. return SetWorkingSampleByIndex(nIndex);
  895. }
  896. ++nIndex;
  897. }
  898. // failed to find the named sample
  899. LogErrorTrace(__FILE__, __LINE__, _T("SetWorkingSampleByName: failed to find the named sample."));
  900. // failed to find the named sample return FALSE
  901. return FALSE;
  902. }
  903. BOOL COTSProjMgrFile::DeleteWorkingSample()
  904. {
  905. // check if the working sample index
  906. if (m_nWorkingSampeIndex < 0 || m_nWorkingSampeIndex >= (int)m_listSamples.size())
  907. {
  908. // invalid working sample index
  909. return FALSE;
  910. }
  911. // return the result of DeleteSampleByIndex
  912. return DeleteSampleByIndex(m_nWorkingSampeIndex);
  913. }
  914. // hole BSE images list
  915. void COTSProjMgrFile::SetHoleBESImgList(CHoleBSEImgsList& a_listHoleBSEImg, BOOL a_bClear/* = TRUE*/)
  916. {
  917. // clear the hole BSE image list if necessary
  918. if (a_bClear)
  919. {
  920. m_listHoleBSEImg.clear();
  921. }
  922. // go through the input list
  923. for (auto pHoleBSEImg : a_listHoleBSEImg)
  924. {
  925. // create a hole BSE image copy
  926. CHoleBSEImgPtr pHoleBSEImgNew(new CHoleBSEImg(pHoleBSEImg.get()));
  927. // add the new hole BSE image into HoleBSEImage list
  928. m_listHoleBSEImg.push_back(pHoleBSEImgNew);
  929. }
  930. if (m_nWorkingSampeIndex != -1)
  931. {
  932. COTSSamplePtr pSample = GetWorkingSample();
  933. pSample->SetPropItemGrps();
  934. }
  935. }
  936. // samples list
  937. bool COTSProjMgrFile::SetSysSTDItem(CSTDItemsList& a_listSysSTDItem, BOOL a_bClear/* = TRUE*/)
  938. {
  939. // clear samples list if necessary
  940. if (a_bClear)
  941. {
  942. m_listSysSTDItem.clear();
  943. }
  944. // go through the sample list of the source
  945. for (auto pItem : a_listSysSTDItem)
  946. {
  947. // create a sample copy
  948. //CSTDItemPtr pItemNew(new CSTDItem(*pItem.get()));
  949. // add the new sample into sample list
  950. m_listSysSTDItem.push_back(pItem);
  951. }
  952. return true;
  953. }
  954. // file name
  955. CString COTSProjMgrFile::GetFileName()
  956. {
  957. // make a copy of file path name
  958. CString strPathName = m_strPathName;
  959. // is this a new file?
  960. strPathName.Trim();
  961. if (strPathName.CompareNoCase(UNTITLED_FILE_NAME) == 0)
  962. {
  963. return strPathName;
  964. }
  965. // get file name
  966. CString strFileName = COTSHelper::GetFileNameWithoutExtension(strPathName);
  967. strFileName = COTSHelper::GetFileName(strFileName);
  968. // return file name
  969. return strFileName;
  970. }
  971. // if the new sample name can be used.
  972. BOOL COTSProjMgrFile::IsValidSampleName(CString a_sName)
  973. {
  974. int nindex = -1;
  975. for (auto pSample : m_listSamples)
  976. {
  977. nindex++;
  978. CString sSampleName = pSample->GetName();
  979. if (!a_sName.CompareNoCase(sSampleName))
  980. {
  981. if (nindex != m_nWorkingSampeIndex)
  982. {
  983. LogErrorTrace(__FILE__, __LINE__, _T("This name has been used."));
  984. return FALSE;
  985. }
  986. }
  987. }
  988. return TRUE;
  989. }
  990. // get std file list, a_nPos = -1, current do not use any STD lib, a_nPos = 0, current use STD lib.
  991. BOOL COTSProjMgrFile::GetParamFileList(int& a_nPos, std::vector<CString>& a_listParamFileName)
  992. {
  993. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  994. // get folder name from general GetParamFileListparameter.
  995. ASSERT(m_pGenParam);
  996. if (!m_pGenParam)
  997. {
  998. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: Can't find the folder."));
  999. return false;
  1000. }
  1001. CString a_strFolderName = m_pGenParam->GetMsrParamFileFolderName();
  1002. if (a_strFolderName == _T(""))
  1003. {
  1004. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: empty folder name."));
  1005. return false;
  1006. }
  1007. // lib name list
  1008. a_listParamFileName.clear();
  1009. // file list
  1010. std::vector<CString> listParamFile;
  1011. listParamFile.clear();
  1012. // get file list
  1013. if (!COTSHelper::GetFileNameList(a_strFolderName, MESUREMENT_PARAM_FILE_EXT, listParamFile))
  1014. {
  1015. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList::There is no %s file in the folder %s"), STD_FILE_EXT, a_strFolderName);
  1016. return FALSE;
  1017. }
  1018. a_nPos = -1;
  1019. // the first postion is default value
  1020. CString sDefault;
  1021. sDefault= MultiLang::GetInstance().GetCStringByKey(IDS_DEFAULT);
  1022. a_listParamFileName.push_back(sDefault);
  1023. // get the param
  1024. CMsrParamFileMgrPtr pParamMrg = CMsrParamFileMgrPtr(new CMsrParamFileMrg());
  1025. // get current param
  1026. CMsrParamsPtr pCurrentParam = CMsrParamsPtr(new CMsrParams());
  1027. COTSSamplePtr pSample = GetWorkingSample();
  1028. if (pSample == nullptr)
  1029. {
  1030. LogTrace(__FILE__, __LINE__, _T("GetParamFileList: failed to get working sample."));
  1031. }
  1032. else
  1033. {
  1034. pCurrentParam = pSample->GetMsrParams();
  1035. if (pCurrentParam == nullptr)
  1036. {
  1037. LogTrace(__FILE__, __LINE__, _T("GetParamFileList: failed to get working sample's param."));
  1038. }
  1039. else
  1040. {
  1041. if ((*(pCurrentParam->GetPartSTDData().get()) == *(m_pGenParam->GetPartSTDLib().get()))
  1042. && (*(pCurrentParam->GetImageProcessParam().get()) == *(m_pImageProcParam.get()))
  1043. && (*(pCurrentParam->GetImageScanParam().get()) == *(m_pImageScanParam.get()))
  1044. && (*(pCurrentParam->GetXRayParam().get()) == *(m_pXRayParam.get())))
  1045. {
  1046. a_nPos = 0;
  1047. }
  1048. }
  1049. }
  1050. int index = -1;
  1051. for (auto sPathName : listParamFile)
  1052. {
  1053. // get file name
  1054. CString strFileName = COTSHelper::GetFileNameWithoutExtension(sPathName);
  1055. strFileName = COTSHelper::GetFileName(strFileName);
  1056. index++;
  1057. //compare which param is used in the list
  1058. CString sParamFileName = listParamFile[index];
  1059. if (sParamFileName.IsEmpty())
  1060. {
  1061. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::wrong param file name."));
  1062. return FALSE;
  1063. }
  1064. //load STD
  1065. CString sPathName = a_strFolderName + sParamFileName;
  1066. if (!pParamMrg->Load(sPathName))
  1067. {
  1068. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::can't load param."));
  1069. return FALSE;
  1070. }
  1071. CMsrParamsPtr pNewParam = pParamMrg->GetMsrParams();
  1072. if (*pNewParam.get() == *pCurrentParam.get())
  1073. {
  1074. a_nPos = (index+1);
  1075. }
  1076. a_listParamFileName.push_back(strFileName);
  1077. }
  1078. return TRUE;
  1079. }
  1080. // change param from file
  1081. BOOL COTSProjMgrFile::ChangeParamFromList(int a_nPos)
  1082. {
  1083. // get folder name from general parameter.
  1084. ASSERT(m_pGenParam);
  1085. if (!m_pGenParam)
  1086. {
  1087. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: Can't find the folder."));
  1088. return false;
  1089. }
  1090. CString a_strFolderName = m_pGenParam->GetMsrParamFileFolderName();
  1091. if (a_strFolderName == _T(""))
  1092. {
  1093. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: empty folder name."));
  1094. return false;
  1095. }
  1096. // file list
  1097. std::vector<CString> listParamFile;
  1098. listParamFile.clear();
  1099. // get file list
  1100. if (!COTSHelper::GetFileNameList(a_strFolderName, MESUREMENT_PARAM_FILE_EXT, listParamFile))
  1101. {
  1102. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList::There is no %s file in the folder %s"), STD_FILE_EXT, a_strFolderName);
  1103. return FALSE;
  1104. }
  1105. // check the pos if is valid
  1106. CMsrParamsPtr pNewParam = CMsrParamsPtr(new CMsrParams());
  1107. int nSize = (int)listParamFile.size();
  1108. if(a_nPos == 0)
  1109. {
  1110. //set param to default value
  1111. CPartSTDDataPtr pPartSTD = m_pGenParam->GetPartSTDLib();
  1112. pNewParam->SetPartSTDData(pPartSTD);
  1113. pNewParam->SetImageScanParam(m_pImageScanParam);
  1114. pNewParam->SetImageProcessParam(m_pImageProcParam);
  1115. pNewParam->SetXRayParam(m_pXRayParam);
  1116. }
  1117. else if (a_nPos < 0 || a_nPos >(nSize+1))
  1118. {
  1119. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::choose wrong position."));
  1120. return FALSE;
  1121. }
  1122. else
  1123. {
  1124. // get the param
  1125. CMsrParamFileMgrPtr pParamMrg = CMsrParamFileMgrPtr(new CMsrParamFileMrg());
  1126. CString sParamFileName = listParamFile[a_nPos-1];
  1127. if (sParamFileName.IsEmpty())
  1128. {
  1129. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::wrong param file name."));
  1130. return FALSE;
  1131. }
  1132. //load STD
  1133. CString sPathName = a_strFolderName + sParamFileName;
  1134. if (!pParamMrg->Load(sPathName))
  1135. {
  1136. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::can't load param."));
  1137. return FALSE;
  1138. }
  1139. pNewParam = pParamMrg->GetMsrParams();
  1140. ASSERT(pNewParam);
  1141. if (!pNewParam)
  1142. {
  1143. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::load an empty param."));
  1144. return FALSE;
  1145. }
  1146. }
  1147. // updata STD to working sample
  1148. COTSSamplePtr pSample = GetWorkingSample();
  1149. ASSERT(pSample);
  1150. if (!pSample)
  1151. {
  1152. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList: failed to get working sample."));
  1153. return FALSE;
  1154. }
  1155. pSample->SetMsrParams(pNewParam);
  1156. return TRUE;
  1157. }
  1158. // get std file list, a_nPos = -1, current do not use any STD lib, a_nPos = 0, current use STD lib.
  1159. BOOL COTSProjMgrFile::GetSTDFileList(int& a_nPos, std::vector<CString>& a_listSTDLibName)
  1160. {
  1161. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1162. // get folder name from general parameter.
  1163. ASSERT(m_pGenParam);
  1164. if (!m_pGenParam)
  1165. {
  1166. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: Can't find the folder."));
  1167. return false;
  1168. }
  1169. CString a_strFolderName = m_pGenParam->GetPartSTDLibFolderName();
  1170. if (a_strFolderName == _T(""))
  1171. {
  1172. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList: empty folder name."));
  1173. return false;
  1174. }
  1175. // lib name list
  1176. a_listSTDLibName.clear();
  1177. // file list
  1178. std::vector<CString> listSTDFile;
  1179. listSTDFile.clear();
  1180. // get file list
  1181. if (!COTSHelper::GetFileNameList(a_strFolderName, STD_FILE_EXT, listSTDFile))
  1182. {
  1183. LogErrorTrace(__FILE__, __LINE__, _T("GetSTDFileList::There is no %s file in the folder %s"), STD_FILE_EXT, a_strFolderName);
  1184. return FALSE;
  1185. }
  1186. //before the use choose one STD, always should be null.
  1187. a_nPos = -1;
  1188. // get folder's STD name.
  1189. CPartSTDFileMnrPtr pPartSTDFileMnr = CPartSTDFileMnrPtr(new CSTDXMLFileMnr());
  1190. // get current std
  1191. CPartSTDDataPtr pCurrentSTD ;
  1192. CMsrParamsPtr pCurrentParam ;
  1193. COTSSamplePtr pSample = GetWorkingSample();
  1194. if (pSample == nullptr)
  1195. {
  1196. LogTrace(__FILE__, __LINE__, _T("GetSTDFileList: failed to get working sample."));
  1197. }
  1198. else
  1199. {
  1200. pCurrentParam = pSample->GetMsrParams();
  1201. if (pCurrentParam == nullptr)
  1202. {
  1203. LogTrace(__FILE__, __LINE__, _T("GetSTDFileList: failed to get working param."));
  1204. }
  1205. pCurrentSTD = pCurrentParam->GetPartSTDData();
  1206. CString sDefault = pCurrentSTD->GetName();
  1207. a_nPos = 0;
  1208. a_listSTDLibName.push_back(sDefault);
  1209. }
  1210. // read file name
  1211. int index = -1;
  1212. for (auto sFileName : listSTDFile)
  1213. {
  1214. index++;
  1215. // read the file
  1216. CString sPathName = a_strFolderName + sFileName;
  1217. if (!pPartSTDFileMnr->Load(sPathName))
  1218. {
  1219. LogTrace(__FILE__, __LINE__, _T("GetSTDFileList::There is no %s in the folder %s"), sFileName, a_strFolderName);
  1220. return FALSE;
  1221. }
  1222. // get STDData from file
  1223. CPartSTDDataPtr pPartSTDData = pPartSTDFileMnr->GetPartSTDData();
  1224. ASSERT(pPartSTDData);
  1225. if (!pPartSTDData)
  1226. {
  1227. LogTrace(__FILE__, __LINE__, _T("There is no %s in the folder %s"), sFileName, a_strFolderName);
  1228. return FALSE;
  1229. }
  1230. if (*pCurrentSTD.get() == *pPartSTDData.get())
  1231. {
  1232. a_nPos = (index+1);
  1233. }
  1234. // get lib name
  1235. CString sLibName = pPartSTDData->GetName();
  1236. a_listSTDLibName.push_back(sLibName);
  1237. }
  1238. return TRUE;
  1239. }
  1240. // change STD
  1241. BOOL COTSProjMgrFile::ChangeSTDFromList(int a_nPos)
  1242. {
  1243. // get folder name from general parameter.
  1244. ASSERT(m_pGenParam);
  1245. if (!m_pGenParam)
  1246. {
  1247. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList: Can't find the folder."));
  1248. return false;
  1249. }
  1250. CString a_strFolderName = m_pGenParam->GetPartSTDLibFolderName();
  1251. if (a_strFolderName == _T(""))
  1252. {
  1253. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList: empty folder name."));
  1254. return false;
  1255. }
  1256. // file list
  1257. std::vector<CString> listSTDFile;
  1258. listSTDFile.clear();
  1259. // get file list
  1260. if (!COTSHelper::GetFileNameList(a_strFolderName, STD_FILE_EXT, listSTDFile))
  1261. {
  1262. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::There is no %s file in the folder %s"), STD_FILE_EXT, a_strFolderName);
  1263. return FALSE;
  1264. }
  1265. // check the pos if is valid
  1266. CPartSTDDataPtr pNewSTD = CPartSTDDataPtr(new CPartSTDData());
  1267. int nSize = (int)listSTDFile.size();
  1268. if (a_nPos == 0)
  1269. {
  1270. pNewSTD = m_pGenParam->GetPartSTDLib();
  1271. }
  1272. else if (a_nPos < 0 || a_nPos > nSize)
  1273. {
  1274. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::choose wrong position."));
  1275. return FALSE;
  1276. }
  1277. else
  1278. {
  1279. // get the STD
  1280. CPartSTDFileMnrPtr pSTDMnr = CPartSTDFileMnrPtr(new CSTDXMLFileMnr());
  1281. CString sSTDFileName = listSTDFile[a_nPos-1];
  1282. if (sSTDFileName.IsEmpty())
  1283. {
  1284. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::wrong STD file name."));
  1285. return FALSE;
  1286. }
  1287. //load STD
  1288. CString sPathName = a_strFolderName + sSTDFileName;
  1289. if (!pSTDMnr->Load(sPathName))
  1290. {
  1291. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::can't load STD."));
  1292. return FALSE;
  1293. }
  1294. pNewSTD = pSTDMnr->GetPartSTDData();
  1295. pNewSTD->SetName(sSTDFileName);
  1296. ASSERT(pNewSTD);
  1297. if (!pNewSTD)
  1298. {
  1299. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList::load an empty STD."));
  1300. return FALSE;
  1301. }
  1302. }
  1303. // updata STD to working sample
  1304. COTSSamplePtr pSample = GetWorkingSample();
  1305. ASSERT(pSample);
  1306. if (!pSample)
  1307. {
  1308. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList: failed to get working sample."));
  1309. return FALSE;
  1310. }
  1311. CMsrParamsPtr pParam = pSample->GetMsrParams();
  1312. ASSERT(pParam);
  1313. if (!pParam)
  1314. {
  1315. LogErrorTrace(__FILE__, __LINE__, _T("ChangeSTDFromList: working sample's param is empty."));
  1316. return FALSE;
  1317. }
  1318. pParam->SetPartSTDData(pNewSTD);
  1319. pSample->SetMsrParams(pParam);
  1320. return TRUE;
  1321. }
  1322. // get measured sample list
  1323. BOOL COTSProjMgrFile::GetMsredSampleList(COTSSamplesList& a_listMsredSample)
  1324. {
  1325. a_listMsredSample.clear();
  1326. for (auto pSample : m_listSamples)
  1327. {
  1328. if (*(pSample->GetMsrResults().get()) == CMsrResults())
  1329. {
  1330. continue;
  1331. }
  1332. else
  1333. {
  1334. a_listMsredSample.push_back(pSample);//the reference count will increament automatically.
  1335. }
  1336. }
  1337. return TRUE;
  1338. }
  1339. // remove background
  1340. BOOL COTSProjMgrFile::RemoveBackGround(CBSEImgPtr a_pImgIn, COTSImageProcessParamPtr a_pImgProcessParam, CBSEImgPtr a_pImgOut)
  1341. {
  1342. //safety check
  1343. ASSERT(a_pImgIn);
  1344. if (!a_pImgIn)
  1345. {
  1346. LogTrace(__FILE__, __LINE__, _T("RemoveBackGround: invalid input BSE."));
  1347. return FALSE;
  1348. }
  1349. ASSERT(a_pImgProcessParam);
  1350. if (!a_pImgProcessParam)
  1351. {
  1352. LogTrace(__FILE__, __LINE__, _T("RemoveBackGround: invalid image process param."));
  1353. return FALSE;
  1354. }
  1355. ASSERT(a_pImgOut);
  1356. if (!a_pImgOut)
  1357. {
  1358. LogTrace(__FILE__, __LINE__, _T("RemoveBackGround: invalid output BSE."));
  1359. return FALSE;
  1360. }
  1361. // Binary
  1362. int nWidth = a_pImgIn->GetWidth();
  1363. int nHeight = a_pImgIn->GetHeight();
  1364. int nImgSize = nWidth * nHeight;
  1365. BYTE* pPixel = new BYTE[nImgSize];
  1366. BYTE* pSrcImg = a_pImgIn->GetImageDataPointer();
  1367. BYTE* pTargetImg = new BYTE[nImgSize];
  1368. long nBGStart = a_pImgProcessParam->GetBGGray().GetStart();
  1369. long nBGEnd = a_pImgProcessParam->GetBGGray().GetEnd();
  1370. long nPtStart = a_pImgProcessParam->GetParticleGray().GetStart();
  1371. long nPtEnd = a_pImgProcessParam->GetParticleGray().GetEnd();
  1372. // delete background
  1373. for (int i = 0; i < nImgSize; i++)
  1374. {
  1375. if (pSrcImg[i] >= nBGStart && pSrcImg[i] <= nBGEnd)
  1376. {
  1377. pPixel[i] = 0;
  1378. }
  1379. else
  1380. {
  1381. pPixel[i] = 255;
  1382. }
  1383. }
  1384. // image process
  1385. COTSImageProcess::BErode3(pPixel, pTargetImg, 5, nHeight, nWidth);
  1386. COTSImageProcess::BDilate3(pTargetImg, pPixel, 5, nHeight, nWidth);
  1387. // show the image
  1388. for (int i = 0; i < nImgSize; i++)
  1389. {
  1390. *(pPixel + i) = 255 - *(pPixel + i);
  1391. if (*(pPixel + i) == 0)
  1392. {
  1393. *(pPixel + i) = *(pSrcImg + i);
  1394. }
  1395. }
  1396. a_pImgOut->SetImageRect(a_pImgIn->GetImageRect());
  1397. a_pImgOut->SetImageData(pPixel);
  1398. // memory release
  1399. delete[]pPixel;
  1400. delete[]pTargetImg;
  1401. return TRUE;
  1402. }
  1403. BOOL COTSProjMgrFile::GetSystemSTDLib(OTS_SOFT_PACKAGE_ID a_nPacketId)
  1404. {
  1405. CSTDFileMgrPtr pSTDFileMgr = CSTDFileMgrPtr(new CSTDFileMgr());
  1406. // get software pack measure preference file pathname
  1407. //CString SysSTDLibFilePath = COTSFileSys::GetOTSPackSysSTDLibFilePathName(a_nPacketId);
  1408. //if (SysSTDLibFilePath.IsEmpty())
  1409. //{
  1410. // // shouldn't happen, software pack measure preference file pathname is empty, return nullptr
  1411. // LogErrorTrace(__FILE__, __LINE__, _T("GetSystemSTDLib: failed to find program manager param file pathname."));
  1412. // return FALSE;
  1413. //}
  1414. // program manager param file exists?
  1415. /*if (!COTSFileSys::Exists(SysSTDLibFilePath))
  1416. {
  1417. LogErrorTrace(__FILE__, __LINE__, _T("GetSystemSTDLib: there is no STD lib file."));
  1418. return FALSE;
  1419. }*/
  1420. CSTDItemsList listSTDItem = pSTDFileMgr->GetSTDItemList();
  1421. if (listSTDItem.empty())
  1422. {
  1423. if (!pSTDFileMgr->Load( TRUE))
  1424. {
  1425. LogErrorTrace(__FILE__, __LINE__, _T("GetSystemSTDLib: can't load system STD lib data."));
  1426. return FALSE;
  1427. }
  1428. }
  1429. SetSysSTDItem(listSTDItem, TRUE);
  1430. return TRUE;
  1431. }
  1432. // protected
  1433. // cleanup
  1434. void COTSProjMgrFile::Cleanup()
  1435. {
  1436. m_listHoleBSEImg.clear();
  1437. m_listSamples.clear();
  1438. m_listSysSTDItem.clear();
  1439. m_bModify = FALSE;
  1440. m_strPathName = _T("");
  1441. m_nWorkingSampeIndex = -1;
  1442. }
  1443. // initialization
  1444. void COTSProjMgrFile::Init()
  1445. {
  1446. m_pSEMStageData = CSEMStageDataPtr(new CSEMStageData());
  1447. m_pStage = CStagePtr(new CStage());
  1448. m_pGenParam = COTSGeneralParametersPtr(new COTSGeneralParameters());
  1449. m_pImageScanParam = COTSImageScanParamPtr(new COTSImageScanParam());
  1450. m_pImageProcParam = COTSImageProcessParamPtr(new COTSImageProcessParam());
  1451. m_pXRayParam = COTSXRayParamPtr(new COTSXRayParam());
  1452. m_listSamples.clear();
  1453. m_listHoleBSEImg.clear();
  1454. m_listSysSTDItem.clear();
  1455. m_bModify = FALSE;
  1456. m_strPathName = _T("");
  1457. m_nWorkingSampeIndex = -1;
  1458. }
  1459. // duplication
  1460. void COTSProjMgrFile::Duplicate(const COTSProjMgrFile& a_oSource)
  1461. {
  1462. // initialization
  1463. Init();
  1464. // copy data over
  1465. m_pSEMStageData = CSEMStageDataPtr(new CSEMStageData( a_oSource.m_pSEMStageData.get()));
  1466. m_pStage = CStagePtr(new CStage(a_oSource.m_pStage.get()));
  1467. m_pGenParam = COTSGeneralParametersPtr(new COTSGeneralParameters( a_oSource.m_pGenParam.get()));
  1468. m_pImageScanParam = COTSImageScanParamPtr(new COTSImageScanParam( a_oSource.m_pImageScanParam.get()));
  1469. m_pImageProcParam = COTSImageProcessParamPtr(new COTSImageProcessParam(a_oSource.m_pImageProcParam.get()));
  1470. m_pXRayParam = COTSXRayParamPtr(new COTSXRayParam(a_oSource.m_pXRayParam.get()));
  1471. for (auto pHoleBSEImg : a_oSource.m_listHoleBSEImg)
  1472. {
  1473. CHoleBSEImgPtr pHoleBSEImgNew(new CHoleBSEImg(pHoleBSEImg.get()));
  1474. m_listHoleBSEImg.push_back(pHoleBSEImgNew);
  1475. }
  1476. for (auto pSample : a_oSource.m_listSamples)
  1477. {
  1478. COTSSamplePtr pSampleNew(new COTSSample(pSample.get()));
  1479. m_listSamples.push_back(pSampleNew);
  1480. }
  1481. for (auto pItem : a_oSource.m_listSysSTDItem)
  1482. {
  1483. CSTDItemPtr pItemNew = CSTDItemPtr(new CSTDItem(*pItem.get()));
  1484. m_listSysSTDItem.push_back(pItemNew);
  1485. }
  1486. m_bModify = a_oSource.m_bModify;
  1487. m_strPathName = a_oSource.m_strPathName;
  1488. m_nWorkingSampeIndex = a_oSource.m_nWorkingSampeIndex;
  1489. }
  1490. // get new sample name
  1491. CString COTSProjMgrFile::GetNewSampleName()
  1492. {
  1493. // new sample name
  1494. CString strNewSmplName = _T("");
  1495. // safety check
  1496. ASSERT(m_pGenParam);
  1497. if (!m_pGenParam)
  1498. {
  1499. // shouldn't happen, invalid general parameter pointer.
  1500. LogErrorTrace(__FILE__, __LINE__, _T("GetNewSampleName: invalid general parameter pointer."));
  1501. return strNewSmplName;
  1502. }
  1503. // new sample name base
  1504. CString strNewSmplNameBase = m_pGenParam->GetSampleName() + _T("%d");
  1505. int nIndex = 1;
  1506. do
  1507. {
  1508. // new sample name is new sample name base + number string
  1509. strNewSmplName.Format(strNewSmplNameBase, nIndex);
  1510. ++nIndex;
  1511. }
  1512. // make sure that the new sample name is not same with any sample in the samples list
  1513. while (SameNameInList(strNewSmplName));
  1514. // new sample name
  1515. return strNewSmplName;
  1516. }
  1517. // select a suitable sample hole for a new sample
  1518. CHolePtr COTSProjMgrFile::SelectASmpleHole(CString a_strHoleName /*= _T("")*/)
  1519. {
  1520. // safety check
  1521. ASSERT(m_pStage);
  1522. if (!m_pStage)
  1523. {
  1524. // shouldn't happen, invalid stage pointer.
  1525. LogErrorTrace(__FILE__, __LINE__, _T("COTSProjMgrFile: invalid stage pointer."));
  1526. return nullptr;
  1527. }
  1528. // get holes list of the stage
  1529. CHolesList& listHoles = m_pStage->GetHoleList();
  1530. // make sure the holes list is not empty
  1531. if (listHoles.size() == 0)
  1532. {
  1533. // shouldn't happen, stage have no hole.
  1534. LogErrorTrace(__FILE__, __LINE__, _T("COTSProjMgrFile: stage have no hole."));
  1535. return nullptr;
  1536. }
  1537. // check the input hole name
  1538. a_strHoleName.Trim();
  1539. if (!a_strHoleName.IsEmpty())
  1540. {
  1541. // try to find matched hole
  1542. auto itr = std::find_if(listHoles.begin(), listHoles.end(), [a_strHoleName](CHolePtr p) { return p->GetName().CompareNoCase(a_strHoleName) == 0; });
  1543. if (itr != listHoles.end())
  1544. {
  1545. // found the matched hole, return its pointer
  1546. CHolePtr pHole = *itr;
  1547. return pHole;
  1548. }
  1549. }
  1550. // can't find a matched hole, then pick the first empty hole
  1551. // go through the holes list
  1552. for (auto pHole : listHoles)
  1553. {
  1554. // has this hole any sample in it?
  1555. CString strHoleName = pHole->GetName();
  1556. auto itr = find_if(m_listSamples.begin(), m_listSamples.end(), [strHoleName](COTSSamplePtr p) { return p->GetSampleHoleName().CompareNoCase(strHoleName) == 0; });
  1557. if (itr == m_listSamples.end())
  1558. {
  1559. // this hole has no sample in it
  1560. return pHole;
  1561. }
  1562. }
  1563. // no empty hole, then the first hole will be the one
  1564. return listHoles[0];
  1565. }
  1566. // calculate measurement area
  1567. CDomainPtr COTSProjMgrFile::CalculateMsrArea(CHolePtr a_pHole)
  1568. {
  1569. // safety check
  1570. ASSERT(a_pHole);
  1571. if (!a_pHole)
  1572. {
  1573. // input hole invalid.
  1574. LogErrorTrace(__FILE__, __LINE__, _T("CalculateMsrArea: input hole invalid."));
  1575. return nullptr;
  1576. }
  1577. CDomainPtr pMsrArea = CDomainPtr(new CDomain(a_pHole->GetShape(), a_pHole->GetDomainRect()));
  1578. // create measurement area
  1579. // reset measurement area
  1580. // measurement area should smaller than the sample hole
  1581. CRect rectMsrArea = pMsrArea->GetDomainRect();
  1582. int nWidth = rectMsrArea.Width();
  1583. int nHeight = rectMsrArea.Height();
  1584. int nDeflateX = CalculateDeflateValue(nWidth);
  1585. int nDeflateY = CalculateDeflateValue(nHeight);
  1586. rectMsrArea.DeflateRect(nDeflateX, nDeflateY);
  1587. pMsrArea->SetDomainRect(rectMsrArea);
  1588. // return measurement area
  1589. return pMsrArea;
  1590. }
  1591. CDomainPtr COTSProjMgrFile::CalculateDefaultArea(CHolePtr a_pHole)
  1592. {
  1593. // safety check
  1594. ASSERT(m_pGenParam);
  1595. if (!m_pGenParam)
  1596. {
  1597. // input hole invalid.
  1598. LogErrorTrace(__FILE__, __LINE__, _T("CalculateDefaultArea: input invalid."));
  1599. return nullptr;
  1600. }
  1601. ASSERT(a_pHole);
  1602. if (!a_pHole)
  1603. {
  1604. // input hole invalid.
  1605. LogErrorTrace(__FILE__, __LINE__, _T("CalculateDefaultArea: input hole invalid."));
  1606. return nullptr;
  1607. }
  1608. CRect rectHole = a_pHole->GetDomainRect();
  1609. CPoint ptCenter = rectHole.CenterPoint();
  1610. DOMAIN_SHAPE nShape = m_pGenParam->GetShape();
  1611. double dArea = m_pGenParam->GetArea() * 1000000;
  1612. CPoint ptLeftTop;
  1613. CPoint ptRightBottom;
  1614. int nEdge = 0;
  1615. int nRadius = 0;
  1616. switch ((int)nShape)
  1617. {
  1618. case (int)DOMAIN_SHAPE::RECTANGLE:
  1619. nEdge = (int)sqrt(dArea) / 2;
  1620. ptLeftTop.x = ptCenter.x - nEdge;
  1621. ptLeftTop.y = ptCenter.y - nEdge;
  1622. ptRightBottom.x = ptCenter.x + nEdge;
  1623. ptRightBottom.y = ptCenter.y + nEdge;
  1624. break;
  1625. case (int)DOMAIN_SHAPE::ROUND:
  1626. nRadius = (int)sqrt(dArea / 3.1415926);
  1627. ptLeftTop.x = ptCenter.x - nRadius;
  1628. ptLeftTop.y = ptCenter.y - nRadius;
  1629. ptRightBottom.x = ptCenter.x + nRadius;
  1630. ptRightBottom.y = ptCenter.y + nRadius;
  1631. break;
  1632. }
  1633. CRect MsrRect = CRect(ptLeftTop, ptRightBottom);
  1634. CDomainPtr pMsrArea = CDomainPtr(new CDomain(nShape, MsrRect));
  1635. // return measurement area
  1636. return pMsrArea;
  1637. }
  1638. // calculate deflate value
  1639. int COTSProjMgrFile::CalculateDeflateValue(int a_nWitchOrHeight)
  1640. {
  1641. // deflate 1000 if width or height is greater than 15000
  1642. if (a_nWitchOrHeight >= LENGTH_THRESHOLD)
  1643. {
  1644. return EDGE;
  1645. }
  1646. // deflate 500 if width or height is greater than 15000
  1647. else if (a_nWitchOrHeight >= LENGTH_THRESHOLD_MIN)
  1648. {
  1649. return EDGE_MIN;
  1650. }
  1651. // otherwise, no deflate
  1652. return 0;
  1653. }
  1654. }