Browse Source

improve GB 30834 algorithm.

gsp 3 years ago
parent
commit
ddb9553b70

BIN
Bin/x64/Debug/Config/SysData/IncSysLib/IncASTDData.db


+ 133 - 0
OTSCPP/OTSData/Convert.h

@@ -0,0 +1,133 @@
+#pragma once
+#pragma once
+#include <iostream>   //标准IO
+#include "atlstr.h"   //使用CString类型
+#include <string>     //使用string类型
+#include <sstream>    //使用stringstream需要引入这个头文件 
+using namespace std;  //标准库命名空间(cout、string)
+
+/*
+* 源博客页:https://www.cnblogs.com/timefiles/p/ConvertInValueCStringString.html
+* 博客主页:https://www.cnblogs.com/timefiles
+* 创建时间:2021/6/14
+*/
+
+namespace Convert
+{
+    //函数模板:将常用的数值类型转换为string类型变量(此方法具有普遍适用性) 
+    template<typename T>
+    string ToString(const T& t)
+    {
+        ostringstream oss;  //创建一个格式化输出流
+        oss << t;           //把值传递入流中
+        return oss.str();
+    }
+    string ToString(const int& val) { return to_string(val); }
+    string ToString(const long& val) { return to_string(val); }
+    string ToString(const long long& val) { return to_string(val); }
+    string ToString(const unsigned int& val) { return to_string(val); }
+    string ToString(const unsigned long& val) { return to_string(val); }
+    string ToString(const unsigned long long& val) { return to_string(val); }
+    string ToString(const float& val) { return to_string(val); }
+    string ToString(const double& val) { return to_string(val); }
+    string ToString(const long double& val) { return to_string(val); }
+
+
+    //函数模板:将string类型变量转换为常用的数值类型(此方法具有普遍适用性) 
+    template <class T>
+    T ToValue(const string& str) {
+        istringstream iss(str);
+        T num;
+        iss >> num;
+        return num;
+    }
+    double             ToDouble(const string& str) { return  stod(str); }
+    float              ToFloat(const string& str) { return  stof(str); }
+    int                ToInt(const string& str) { return  stoi(str); }
+    long               ToLong(const string& str) { return  stol(str); }
+    long double        ToLongDouble(const string& str) { return  stold(str); }
+    long long          ToLongLong(const string& str) { return  stoll(str); }
+    unsigned long      ToULong(const string& str) { return  stoul(str); }
+    unsigned long long ToULongLong(const string& str) { return  stoull(str); }
+
+    namespace MFC
+    {
+
+        //将CString类型变量转换为string类型
+        string CStringToString(CString cs) {
+#ifdef _UNICODE
+
+            //如果是unicode工程
+            USES_CONVERSION;
+            std::string str(W2A(cs));
+            return str;
+#else
+            //如果是多字节工程 
+            std::string str(cs.GetBuffer());
+            cs.ReleaseBuffer();
+            return str;
+
+#endif // _UNICODE 
+        }
+
+        //将string类型变量转换为CString类型
+        CString StringToCString(string str) {
+#ifdef _UNICODE
+            //如果是unicode工程
+            USES_CONVERSION;
+            CString ans(str.c_str());
+            return ans;
+#else
+            //如果是多字节工程             
+            CString ans;
+            ans.Format("%s", str.c_str());
+            return ans;
+#endif // _UNICODE  
+        }
+
+
+        //模板函数:将CString类型变量转换为常用的数值类型(此方法具有普遍适用性)
+        template <class T>
+        T ToValue(const CString& cStr)
+        {
+            string str = CStringToString(cStr);
+            return  Convert::ToValue<T>(str);
+        }
+
+        //模板函数:将常用的数值类型转换为CString类型变量(此方法具有普遍适用性)    
+        template<typename T>
+        static CString ToCString(const T& t)
+        {
+            string str = Convert::ToString<T>(t);
+            return StringToCString(str);
+        }
+
+
+        CString ToString(const int& val) { CString str; str.Format(_T("%d"), val); return str; }
+        CString ToString(const long& val) { CString str; str.Format(_T("%ld"), val); return str; }
+        CString ToString(const unsigned int& val) { CString str; str.Format(_T("%ud"), val); return str; }
+        CString ToString(const unsigned long& val) { CString str; str.Format(_T("%uld"), val); return str; }
+        CString ToString(const float& val) { CString str; str.Format(_T("%f"), val); return str; }
+        CString ToString(const double& val) { CString str; str.Format(_T("%lf"), val); return str; }
+
+
+        double             ToDouble(const CString& str) { return  _ttof(str); }
+        float              ToFloat(const CString& str) { return  _ttof(str); }
+        int                ToInt(const CString& str) { return  _ttoi(str); }
+        long               ToLong(const CString& str) { return  _ttol(str); }
+        long long          ToLongLong(const CString& str) { return  _ttoll(str); }
+
+#ifdef _UNICODE
+        //如果是unicode工程
+        long double        ToLongDouble(const CString& str) { wchar_t* pEnd; return  _tcstold(str, &pEnd); }
+        unsigned long      ToULong(const CString& str) { wchar_t* pEnd; return  _tcstoul(str, &pEnd, 10); }
+        unsigned long long ToULongLong(const CString& str) { wchar_t* pEnd; return  _tcstoull(str, &pEnd, 10); }
+#else
+        //如果是多字节工程             
+        long double        ToLongDouble(const CString& str) { char* pEnd; return  _tcstold(str, &pEnd); }
+        unsigned long      ToULong(const CString& str) { char* pEnd; return  _tcstoul(str, &pEnd, 10); }
+        unsigned long long ToULongLong(const CString& str) { char* pEnd; return  _tcstoull(str, &pEnd, 10); }
+#endif // _UNICODE  
+
+    }
+}

+ 1 - 0
OTSCPP/OTSData/GridData.h

@@ -225,6 +225,7 @@ namespace OTSDATA {
 		void SetName(CString a_strName) { m_strName = a_strName; }
 
 		CGridRowsList GetRowList() { return m_listGridRows; }
+		void AddGridRow(CGridRowPtr r) { m_listGridRows.push_back(r); }
 		BOOL SetGridRowsList(CGridRowsList a_listGridRows, BOOL a_bClear = TRUE);
 		
 	protected:

+ 4 - 0
OTSCPP/OTSData/OTSData.vcxproj

@@ -550,6 +550,7 @@
     <ClCompile Include="OTSFieldData.cpp" />
     <ClCompile Include="OTSParticle.cpp" />
     <ClCompile Include="OTSPeak.cpp" />
+    <ClCompile Include="OTSRect.cpp" />
     <ClCompile Include="OTSSegment.cpp" />
     <ClCompile Include="OTSXRayParam.cpp" />
     <ClCompile Include="PosXray.cpp" />
@@ -570,12 +571,15 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="strUtil.h" />
     <ClCompile Include="tinyxml2.cpp" />
     <ClCompile Include="XMLSerialization.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="BSEImg.h" />
+    <ClInclude Include="Convert.h" />
     <ClInclude Include="GridData.h" />
+    <ClInclude Include="OTSRect.h" />
     <ClInclude Include="OTSXRayParam.h" />
     <ClInclude Include="Resource.h" />
     <ClInclude Include="Domain.h" />

+ 12 - 0
OTSCPP/OTSData/OTSData.vcxproj.filters

@@ -89,6 +89,12 @@
     <ClCompile Include="OTSXRayParam.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="OTSRect.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="strUtil.h">
+      <Filter>Header Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="targetver.h">
@@ -175,6 +181,12 @@
     <ClInclude Include="OTSXRayParam.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="OTSRect.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Convert.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="OTSData.def">

+ 5 - 0
OTSCPP/OTSData/OTSFieldData.h

@@ -1,5 +1,6 @@
 #pragma once
 #include "OTSParticle.h"
+#include "OTSRect.h"
 
 namespace OTSDATA {
 
@@ -27,6 +28,9 @@ namespace OTSDATA {
 		CPoint GetPosition() { return m_poiPos; }
 		void SetPosition(CPoint a_poiPos) { m_poiPos = a_poiPos; }
 
+		COTSRect GetRect() { return m_rect; }
+		void SetRect(COTSRect r) { m_rect = r; }
+
 		// field file folder
 		CString GetFieldFileFolder() { return m_strFieldFileFolder; }
 		void SetFieldFileFolder(CString a_strFieldFileFolder) { m_strFieldFileFolder = a_strFieldFileFolder; }
@@ -70,6 +74,7 @@ namespace OTSDATA {
 		// ID
 		int m_nID;
 
+		COTSRect m_rect;
 		// position (from field center manager) 
 		CPoint m_poiPos;
 

+ 5 - 1
OTSCPP/OTSData/OTSParticle.h

@@ -4,6 +4,7 @@
 #include "otsdataconst.h"
 #include "BSEImg.h"
 #include "PosXray.h"
+#include "OTSRect.h"
 
 namespace OTSDATA {
 const double Pi = 3.14159;
@@ -65,6 +66,9 @@ const double Pi = 3.14159;
 		// rectangle
 		CRect GetParticleRect() { return m_rectParticle; }
 		void SetParticleRect(CRect& a_rectParticle) { m_rectParticle = a_rectParticle; }
+
+		COTSRect GetOTSRect() { return m_OTSRect; }
+		void SetOTSRect(COTSRect r) { m_OTSRect = r; }
 		
 		// gray
 		BYTE GetAveGray() { return m_cAveGray; }
@@ -196,7 +200,7 @@ protected:
 
 		// rectangle
 		CRect m_rectParticle;
-
+		COTSRect m_OTSRect;
 	
 
 		// Feret's diameter

+ 92 - 0
OTSCPP/OTSData/OTSRect.cpp

@@ -0,0 +1,92 @@
+#include "stdafx.h"
+#include "OTSRect.h"
+
+
+
+OTSDATA::COTSRect::COTSRect()
+{
+	m_left = 0;
+	m_top = 0;
+	m_right = 0;
+	m_bottom = 0;
+}
+
+OTSDATA::COTSRect::COTSRect(int left, int top, int right, int bottom)
+{
+	m_left = left;
+	m_top = top;
+	m_right = right;
+	m_bottom = bottom;
+}
+
+OTSDATA::COTSRect::COTSRect(CPoint leftTop, CPoint bottomRight)
+{
+	m_left = leftTop.x;
+	m_top = leftTop.y;
+	m_right = bottomRight.x;
+	m_bottom = bottomRight.y;
+}
+BOOL OTSDATA::COTSRect::operator==(const COTSRect& a_oSource)							// ==operator
+{
+	// return FASLE, if the two segments list are in different size		
+	return (m_left == a_oSource.m_left &&
+		m_top == a_oSource.m_top &&
+		m_right == a_oSource.m_right &&
+		m_bottom == a_oSource.m_bottom);
+
+}
+
+void OTSDATA::COTSRect::SetRectData(int left, int top, int right, int bottom)
+{
+	m_left = left;
+	m_top = top;
+	m_right = right;
+	m_bottom = bottom;
+}
+
+bool OTSDATA::COTSRect::PointInRect(CPoint p)
+{
+	if (p.x > m_left && p.x<m_right && p.y>m_bottom && p.y < m_top)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+bool OTSDATA::COTSRect::IntersectOtherRect(COTSRect r)
+{
+	CPoint leftTop = r.GetTopLeft();
+	CPoint rightBottom = r.GetBottomRight();
+	CPoint rightTop = CPoint(rightBottom.x, leftTop.y);
+	CPoint leftBottom = CPoint(leftTop.x, rightBottom.y);
+	if (PointInRect(leftTop))
+	{
+		return true;
+	}
+	else if (PointInRect(rightBottom))
+	{
+		return true;
+	}
+	else if (PointInRect(rightTop))
+	{
+		return true;
+	}
+	else if (PointInRect(leftBottom))
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+
+
+
+}
+
+OTSDATA::COTSRect::~COTSRect()
+{
+}

+ 29 - 0
OTSCPP/OTSData/OTSRect.h

@@ -0,0 +1,29 @@
+#pragma once
+
+namespace OTSDATA
+{
+	class __declspec(dllexport) COTSRect
+	{
+	public:
+		COTSRect();
+		COTSRect(int left, int top, int right, int bottom);
+		COTSRect(CPoint leftTop, CPoint bottomRight);
+		BOOL operator==(const COTSRect&);							// ==operator
+		void SetRectData(int left, int top, int right, int bottom);
+		bool PointInRect(CPoint p);
+		bool IntersectOtherRect(COTSRect r);
+		CPoint GetTopLeft() { return CPoint(m_left, m_top); }
+		CPoint GetBottomRight() { return CPoint(m_right, m_bottom); }
+		int GetWidth() { return (m_right - m_left); }
+		int GetHeight() { return (m_top - m_bottom); }
+		CPoint GetCenterPoint() { double w = GetWidth(); double h = GetHeight(); CPoint lt = GetTopLeft(); return CPoint(lt.x + w / 2, lt.y - h / 2); }
+		virtual ~COTSRect();						// detractor
+	private :
+		int m_left;
+		int m_top;
+		int m_right;
+		int m_bottom;
+
+
+	};
+}

+ 177 - 0
OTSCPP/OTSData/strUtil.h

@@ -0,0 +1,177 @@
+#pragma once
+#include "stdafx.h"
+
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <Windows.h>
+#pragma warning(disable:4996)
+
+
+
+
+namespace StrUtil
+{
+	using namespace std;
+	inline std::wstring AnsiToUnicode(const char* buf);
+	inline std::string AnsiToUtf8(const char* buf);
+	inline std::string UnicodeToAnsi(const wchar_t* buf);
+	inline std::wstring Utf8ToUnicode(const char* buf);
+	inline std::string UnicodeToUtf8(const wchar_t* buf);
+	inline std::string TrimLeft(const std::string& str);
+	inline std::string TrimRight(const std::string& str);
+	inline std::string Trim(const std::string& str);
+	inline std::vector<std::string> Split(std::string& str, const char* c);
+	inline std::string GetModulePath();
+	inline void Replace(std::string& srcstr, const std::string& oldstr, const std::string& newstr);
+	inline HMODULE GetCurrentModule();
+	
+};
+
+namespace StrUtil {
+
+	void Replace(std::string& srcstr, const std::string& oldstr, const std::string& newstr)
+	{
+		string::size_type pos = 0;
+		string::size_type a = oldstr.size();
+		string::size_type b = newstr.size();
+		while ((pos = srcstr.find(oldstr, pos)) != string::npos)
+		{
+			srcstr.replace(pos, a, newstr);
+			pos += b;
+		}
+	}
+
+	std::vector<std::string> Split(std::string& str, const char* c)
+	{
+		char* cstr, * p;
+		std::vector<std::string> res;
+		cstr = new char[str.size() + 1];
+		strcpy(cstr, str.c_str());
+		p = strtok(cstr, c);
+		while (p != NULL)
+		{
+			res.push_back(p);
+			p = strtok(NULL, c);
+		}
+		return res;
+	}
+
+	std::wstring AnsiToUnicode(const char* buf)
+	{
+		int len = ::MultiByteToWideChar(CP_ACP, 0, buf, -1, NULL, 0);
+		if (len == 0) return L"";
+		std::vector<wchar_t> unicode(len);
+		::MultiByteToWideChar(CP_ACP, 0, buf, -1, &unicode[0], len);
+		return &unicode[0];
+	}
+
+	std::string AnsiToUtf8(const char* buf)
+	{
+		return UnicodeToUtf8(AnsiToUnicode(buf).c_str());
+	}
+
+	std::string UnicodeToAnsi(const wchar_t* buf)
+	{
+		int len = ::WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL);
+		if (len == 0) return "";
+		std::vector<char> utf8(len);
+		::WideCharToMultiByte(CP_ACP, 0, buf, -1, &utf8[0], len, NULL, NULL);
+		return &utf8[0];
+	}
+
+	std::wstring Utf8ToUnicode(const char* buf)
+	{
+		int len = ::MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
+		if (len == 0) return L"";
+		std::vector<wchar_t> unicode(len);
+		::MultiByteToWideChar(CP_UTF8, 0, buf, -1, &unicode[0], len);
+		return &unicode[0];
+	}
+
+	std::string UnicodeToUtf8(const wchar_t* buf)
+	{
+		int len = ::WideCharToMultiByte(CP_UTF8, 0, buf, -1, NULL, 0, NULL, NULL);
+		if (len == 0) return "";
+		std::vector<char> utf8(len);
+		::WideCharToMultiByte(CP_UTF8, 0, buf, -1, &utf8[0], len, NULL, NULL);
+		return &utf8[0];
+	}
+
+	std::string TrimLeft(const std::string& str) {
+		std::string t = str;
+		for (std::string::iterator i = t.begin(); i != t.end(); i++) {
+			if (!isspace(*i)) {
+				t.erase(t.begin(), i);
+				break;
+			}
+		}
+		return t;
+	}
+
+	std::string TrimRight(const std::string& str) {
+		if (str.begin() == str.end()) {
+			return str;
+		}
+		std::string t = str;
+		for (std::string::iterator i = t.end() - 1; i != t.begin(); i--) {
+			if (!isspace(*i)) {
+				t.erase(i + 1, t.end());
+				break;
+			}
+		}
+		return t;
+	}
+
+	std::string Trim(const std::string& str) {
+		std::string t = str;
+
+		std::string::iterator i;
+		for (i = t.begin(); i != t.end(); i++) {
+			if (!isspace(*i)) {
+				t.erase(t.begin(), i);
+				break;
+			}
+		}
+		if (i == t.end()) {
+			return t;
+		}
+
+		for (i = t.end() - 1; i != t.begin(); i--) {
+			if (!isspace(*i)) {
+				t.erase(i + 1, t.end());
+				break;
+			}
+		}
+		return t;
+	}
+
+	HMODULE GetCurrentModule()
+	{ // NB: XP+ solution!
+		HMODULE hModule = NULL;
+		GetModuleHandleEx(
+			GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+			(LPCTSTR)GetCurrentModule,
+			&hModule);
+
+		return hModule;
+	}
+
+	std::string GetModulePath()
+	{
+		char fullPath[MAX_PATH];
+		char drive[_MAX_DRIVE];
+		char dir[_MAX_DIR];
+		HMODULE hModule = GetCurrentModule();
+		if (0 == GetModuleFileNameA(hModule, fullPath, MAX_PATH))
+			return "";
+
+		_splitpath(fullPath, drive, dir, NULL, NULL);
+		std::string str = std::string(drive) + dir;
+		return str;
+	}
+
+	
+}
+

+ 13 - 0
OTSCPP/OTSRptCalculate/DTL/IncADataDB.cpp

@@ -293,9 +293,13 @@ namespace OTSSQLITE
 				fldPos.x = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_FldPosX);
 				fldPos.y = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_FldPosY);
 				fld->SetPosition(fldPos);
+				
 				COTSParticleList& ps=fld->GetParticleList();
 				COTSParticlePtr p = COTSParticlePtr(new COTSParticle());
 				p->SetFieldId(fld->GetId());
+				p->SetAbsolutePos(fldPos);
+				double dferet = allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DFERET);
+				p->SetFeretDiameter(dferet);
 				p->SetTagId(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_PARTICLE_ID));
 				p->SetType((OTS_PARTICLE_TYPE)allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_INCA_ID));
 				int top = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_RECT_TOP);
@@ -306,6 +310,9 @@ namespace OTSSQLITE
 				p->SetParticleRect(r);
 				p->SetAveGray(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_AVE_GRAY));
 				p->SetActualArea(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_AREA));
+				int x = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_POS_X);
+				int y= allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_POS_Y);
+				p->SetXRayPos(CPoint(x,y));
 				p->SetAnalysisId(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_XRAY_ID));
 				p->SetDMax(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DMAX));
 				p->SetDMin(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DMIN));
@@ -327,6 +334,9 @@ namespace OTSSQLITE
 				COTSParticleList& ps = fld->GetParticleList();
 				COTSParticlePtr p = COTSParticlePtr(new COTSParticle());
 				p->SetFieldId(fld->GetId());
+				p->SetAbsolutePos(fld->GetPosition());
+				double dferet = allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DFERET);
+				p->SetFeretDiameter(dferet);
 				p->SetTagId(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_PARTICLE_ID));
 				p->SetType((OTS_PARTICLE_TYPE)allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_INCA_ID));
 				int top = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_RECT_TOP);
@@ -337,6 +347,9 @@ namespace OTSSQLITE
 				p->SetParticleRect(r);
 				p->SetAveGray(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_AVE_GRAY));
 				p->SetActualArea(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_AREA));
+				int x = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_POS_X);
+				int y = allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_POS_Y);
+				p->SetXRayPos(CPoint(x, y));
 				p->SetAnalysisId(allRecords->GetColIntValue((int)CIncADataTable::ColumnID::N_XRAY_ID));
 				p->SetDMax(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DMAX));
 				p->SetDMin(allRecords->GetColFloatValue((int)CIncADataTable::ColumnID::F_DMIN));

+ 3 - 2
OTSCPP/OTSRptCalculate/DTL/IncADataTable.h

@@ -21,7 +21,8 @@ namespace OTSSQLITE
 			F_AREA = 7,
 			N_POS_X = 8,
 			N_POS_Y = 9,
-			N_INCA_ID = 10,		
+			F_DFERET = 10,
+			
 			N_SEGMENT_NUM = 11,
 			N_FldPosX = 12,
 			N_FldPosY = 13,
@@ -34,7 +35,7 @@ namespace OTSSQLITE
 			F_DINSCR = 20,
 			F_DMEAN = 21,
 			F_DELONG = 22,
-			F_DFERET = 23,
+			N_INCA_ID = 23,
 			S_NAME = 24,
 			S_COLOR=25,
 			N_SEMPOS_X = 26,

+ 93 - 390
OTSCPP/OTSRptCalculate/GBCal/CGBCalculate.cpp

@@ -6,6 +6,7 @@
 #include "OTSHelper.h"
 #include "OTSImageProcess.h"
 #include "CGBLevel.h"
+#include <GBFieldData.h>
 namespace OTSGBCalculate
 {	
 	using namespace OTSDATA;
@@ -829,14 +830,22 @@ namespace OTSGBCalculate
 					CGridRowsList listRows;
 					CGridRowPtr pRow;
 					CString strWidthName1, strWidthName2, strWidthName3;
+					CString idstr;
+					int fldid;
+					int partId;
 					switch (i)
 					{
 					case 0:
 						pColumn = listCol.at(0);
 						pRow = CGridRowPtr(new CGridRow());
-						pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT);
-						pRow->SetIntValue(part->GetTagId());
-						pColumn->GetRowList().push_back(pRow);
+						pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING);
+						 fldid = part->GetFieldId();
+						 partId = part->GetTagId();
+					
+						idstr.Format("%d_%d", fldid,partId);
+						
+						pRow->SetStringValue(idstr);
+						pColumn->AddGridRow(pRow);
 
 						break;
 					case 1:
@@ -844,35 +853,35 @@ namespace OTSGBCalculate
 						pRow = CGridRowPtr(new CGridRow());
 						pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT);
 						pRow->SetIntValue(part->GetActualArea());
-						pColumn->GetRowList().push_back(pRow);
+						pColumn->AddGridRow(pRow);
 						break;
 					case 2:
 						pColumn = listCol.at(2);
 						pRow = CGridRowPtr(new CGridRow());
 						pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT);
-						pRow->SetIntValue(part->GetFeretDiameter());
-						pColumn->GetRowList().push_back(pRow);
+						pRow->SetDoubleValue(part->GetFeretDiameter());
+						pColumn->AddGridRow(pRow);
 						break;
 					case 3:
 						pColumn = listCol.at(3);
 						pRow = CGridRowPtr(new CGridRow());
 						pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT);
 						pRow->SetIntValue(part->GetAbsolutPos().x);
-						pColumn->GetRowList().push_back(pRow);
+						pColumn->AddGridRow(pRow);
 						break;
 					case 4:
 						pColumn = listCol.at(4);
 						pRow = CGridRowPtr(new CGridRow());
 						pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT);
 						pRow->SetIntValue(part->GetAbsolutPos().y);
-						pColumn->GetRowList().push_back(pRow);
+						pColumn->AddGridRow(pRow);
 						break;
 					case 5:
 						pColumn = listCol.at(5);
 						pRow = CGridRowPtr(new CGridRow());
 						pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT);
 						pRow->SetIntValue((int)OTSGBCalculate::GetDSGrade(part->GetFeretDiameter()));
-						pColumn->GetRowList().push_back(pRow);
+						pColumn->AddGridRow(pRow);
 						break;
 					}
 				}
@@ -1130,30 +1139,20 @@ namespace OTSGBCalculate
 		// get field width
 		int nOTSFieldWidth = pEMDataMsrPtr->GetScanFieldSize();
 		int nOTSFieldHeight = pEMDataMsrPtr->GetScanFieldHeight();
-		if (nOTSFieldWidth == 0)
+		if (nOTSFieldWidth == 0 || nOTSFieldHeight==0)
 		{
 			LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: field width is zero ."));
 			return m_listGBFields;
 		}
 
-		// cal a gb field need how many ots fields rows and columns 
-		int nOTSRowsForGBFld, nOTSColumnsForGBFld;
-		CalOTSFieldsNo(nOTSRowsForGBFld, nOTSColumnsForGBFld, nOTSFieldWidth,nOTSFieldHeight);
-
-		if (nOTSRowsForGBFld == 0 || nOTSColumnsForGBFld == 0)
-		{
-			LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: nOTSRow|nOTSColumn is zero ."));
-			return m_listGBFields;
-		}
+	
 
 		// scan parameters
 		CMsrParamsPtr pMsrParam = pOTSSample->GetMsrParams();
 		//CMsrParamsPtr pMsrParam = pOTSSample->get
 		COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam();
 
-		// get image size
-		/*OTS_ImageResolution_OPTIONS nImageSizeId = pImgScanParam->GetImageResolutionEnumNo();
-		int nResulotionId = RESOLUTION_ID_FIRST_TIE + (int)nImageSizeId;*/
+	
 		CSize sizePixelImage = pImgScanParam->GetImageResolution();
 		//use OTSField width cal the OTSField height
 		
@@ -1162,7 +1161,7 @@ namespace OTSGBCalculate
 		COTSFieldDataList allOTSFields;
 		allOTSFields = pSmplMsrResultFile->GetFieldData();
 		// convert ots fields to gb fields
-		if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, nOTSRowsForGBFld, nOTSColumnsForGBFld,sizePixelImage, nOTSFieldWidth, nOTSFieldHeight))
+		if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight))
 		{
 			LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: call OTSFieldToGBField failed."));
 			return m_listGBFields;
@@ -1170,28 +1169,12 @@ namespace OTSGBCalculate
 		return m_listGBFields;
 	}
 
-	// protected
 
-	// cal a gb field need how many ots fields rows and columns 
-	void  CGBCalculate::CalOTSFieldsNo(int& a_nRow, int& a_nColumn, int a_nFieldWidth,int a_nFieldHeight)
-	{
-		a_nRow = 0;
-		a_nColumn = 0;
-		if (a_nFieldWidth > 0)
-		{
-			a_nColumn  = (int)ceil((double)GB_FIELD_WIDTH / (double)a_nFieldWidth);
-			//OTSField Height always equal to 3 / 4 OTSField Width
-			double dFieldHeight = a_nFieldHeight;//(double)a_nFieldWidth * 3 / 4;
-			a_nRow  = (int)ceil((double)GB_FIELD_WIDTH / dFieldHeight);
-		}
-	}
 
 	// Turn OTSField to GBField
-	BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,int nOTSRowsPerGBfld, int nOTSColumnsPerGBFld,CSize sizePixelImage,int nOTSFieldWidth,int nOTSFieldHeight)
+	BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,CSize sizePixelImage,int nOTSFieldWidth,int nOTSFieldHeight)
 	{
-		/*int nFieldHeight = nOTSFieldHeight;*/
-
-		// doing nothing if no field at all
+	
 		if (allOTSFields.empty())
 		{
 			LogTrace(__FILE__, __LINE__, _T("CalGBFields: listOTSFields  is empty ."));
@@ -1209,60 +1192,27 @@ namespace OTSGBCalculate
 			CPoint poiOTSFieldPosition = allOTSFields[i]->GetPosition();
 
 			pointTopleft.x = min(poiOTSFieldPosition.x, pointTopleft.x);
-			pointTopleft.y = min(poiOTSFieldPosition.y, pointTopleft.y);
+			pointTopleft.y = max(poiOTSFieldPosition.y, pointTopleft.y);
 			pointBottomright.x = max(poiOTSFieldPosition.x, pointBottomright.x);
-			pointBottomright.y = max(poiOTSFieldPosition.y, pointBottomright.y);
-		}
-		
-		// cal ots columns 有效区域内所有的OTScolumn数
-		int nOTSColumnNum = ((pointBottomright.x - pointTopleft.x) / nOTSFieldWidth) + 1;
-
-		// cal ots rows有效区域内所有的OTSRow数
-		int nOTSRowNum = ((pointBottomright.y - pointTopleft.y) / nOTSFieldHeight) + 1;
-
-		int nPossibleGBFieldRowNum = nOTSRowNum /nOTSRowsPerGBfld;//可能有的国标field行数
-		int nPossibleGBFieldColNum = nOTSColumnNum / nOTSColumnsPerGBFld;//列数
-
-		// cal possible GBFields area
-		CPoint pointPosibleAreaTopLeft = pointTopleft;
-		//CPoint poiPosAreaBottomRight = poiBottomright;
-		CPoint pointPossibleAreaBottomRight = pointTopleft;
-
-		pointPosibleAreaTopLeft.x -= nOTSFieldWidth / 2;
-		pointPosibleAreaTopLeft.y -= nOTSFieldHeight / 2;
-
-		//pointPossibleAreaBottomRight.x += (nPossibleGBFieldColNum * nOTSColumnsPerGBFld * nOTSFieldWidth - nOTSFieldWidth / 2);
-		pointPossibleAreaBottomRight.x += (nPossibleGBFieldColNum * nOTSColumnsPerGBFld * nOTSFieldWidth );
-		//pointPossibleAreaBottomRight.y += (nPossibleGBFieldRowNum * nOTSRowsPerGBfld * nFieldHeight - nFieldHeight / 2);
-		pointPossibleAreaBottomRight.y += (nPossibleGBFieldRowNum * nOTSRowsPerGBfld * nOTSFieldHeight);
-		// form rectangle of GBFields area
-		CRect rectOTSFieldsCuted(pointPosibleAreaTopLeft, pointPossibleAreaBottomRight);
-		rectOTSFieldsCuted.NormalizeRect();
-		if (rectOTSFieldsCuted.IsRectEmpty())
-		{
-			LogTrace(__FILE__, __LINE__, _T("CalGBFields: GBFields area is empty ."));
-			return TRUE;
+			pointBottomright.y = min(poiOTSFieldPosition.y, pointBottomright.y);
 		}
 
-		// find all OTSFields inside GBFields area  
-		COTSFieldDataList OTSFieldsInGBFieldsArea;
-		OTSFieldsInGBFieldsArea.clear();
-		CPoint poiOTSFieldPosition;
+		pointTopleft.x -= nOTSFieldWidth / 2;
+		pointTopleft.y += nOTSFieldHeight / 2;
+		pointBottomright.x+= nOTSFieldWidth / 2;
+		pointBottomright.y-= nOTSFieldHeight / 2;
+
+		double totalWidth = pointBottomright.x - pointTopleft.x;
+		double totalHeight = pointTopleft.y - pointBottomright.y;
+
+
+		int nPossibleGBFieldRowNum = totalHeight /GB_FIELD_WIDTH+0.5;//可能有的国标field行数
+		int nPossibleGBFieldColNum = totalWidth / GB_FIELD_WIDTH+0.5;//列数
 
-		for (auto OTSField : allOTSFields)
-		{
-			poiOTSFieldPosition = OTSField->GetPosition();
-			//if over the edge
-			if (rectOTSFieldsCuted.PtInRect(poiOTSFieldPosition))
-			{
-				OTSFieldsInGBFieldsArea.push_back(OTSField);
-			}
-		}
 
 		//get possible OTSFields 
 		m_listGBFields->clear();
 		CPoint pointGBFieldPosition;
-		int nOTSFieldsPerGBField = nOTSRowsPerGBfld * nOTSColumnsPerGBFld;
 		for (int i = 0; i < nPossibleGBFieldRowNum; i++)
 		{
 			for (int j = 0; j < nPossibleGBFieldColNum; j++)
@@ -1271,31 +1221,29 @@ namespace OTSGBCalculate
 				// cal GB field rectangle
 				CPoint poiCurGBFieldTopLeft, poiCurGBFieldBottomRight;
 
-				poiCurGBFieldTopLeft = pointPosibleAreaTopLeft;
+				poiCurGBFieldTopLeft = pointTopleft;
 				//获得左上角的坐标
-				poiCurGBFieldTopLeft.x += nOTSColumnsPerGBFld * j * nOTSFieldWidth;
-				poiCurGBFieldTopLeft.y += nOTSRowsPerGBfld * i * nOTSFieldHeight;
+				poiCurGBFieldTopLeft.x += j * GB_FIELD_WIDTH;
+				poiCurGBFieldTopLeft.y -= i * GB_FIELD_WIDTH;
 				//获得右下角的坐标
-				poiCurGBFieldBottomRight.x = poiCurGBFieldTopLeft.x + nOTSColumnsPerGBFld * nOTSFieldWidth;
-				poiCurGBFieldBottomRight.y = poiCurGBFieldTopLeft.y + nOTSRowsPerGBfld * nOTSFieldHeight;
-				CRect rectGBField(poiCurGBFieldTopLeft, poiCurGBFieldBottomRight);
-				rectGBField.NormalizeRect();
+				poiCurGBFieldBottomRight.x = poiCurGBFieldTopLeft.x + GB_FIELD_WIDTH;
+				poiCurGBFieldBottomRight.y = poiCurGBFieldTopLeft.y - GB_FIELD_WIDTH;
+				COTSRect rectGBField(poiCurGBFieldTopLeft, poiCurGBFieldBottomRight);
+			
 
 				CGBFieldDataPtr pGBFieldData;
-				//切割组合的矩形成为GBfield,
+			
 				
-				pGBFieldData = GetOneGBField(rectGBField, OTSFieldsInGBFieldsArea, nOTSRowsPerGBfld, nOTSColumnsPerGBFld, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight);
+				pGBFieldData = GetOneGBField(rectGBField, allOTSFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight);
 				if (!pGBFieldData)
 				{
 					continue;
 				}
-				rectGBField.bottom = rectGBField.top + GB_FIELD_WIDTH;
-				rectGBField.right = rectGBField.left + GB_FIELD_WIDTH;
+			
+				
 				
+				CPoint poiNewPosition=rectGBField.GetCenterPoint();
 				
-				CPoint poiNewPosition;
-				poiNewPosition.x = rectGBField.left + GB_FIELD_WIDTH / 2;
-				poiNewPosition.y = rectGBField.top + GB_FIELD_WIDTH / 2;
 				
 				pGBFieldData->SetPosition(poiNewPosition);
 
@@ -1328,12 +1276,10 @@ namespace OTSGBCalculate
 	}
 
 	//  get the GB field within a rectangle
-	CGBFieldDataPtr CGBCalculate::GetOneGBField( CRect a_rectGBField, 
-												COTSFieldDataList& allOTSFields, 
-												int nOTSRowsPerGBFld, 
-												int nOTSColumnsPerGBFld,
-												CSize a_sizePixelImage, 
-												int nOTSFieldWidth,int nOTSFieldHeight)
+	CGBFieldDataPtr CGBCalculate::GetOneGBField(COTSRect a_rectGBField,
+		COTSFieldDataList& allOTSFields,
+		CSize a_sizePixelImage,
+		int nOTSFieldWidth, int nOTSFieldHeight)
 	{
 		// GB Field handle
 		CGBFieldDataPtr pGBFieldData = nullptr;
@@ -1346,73 +1292,52 @@ namespace OTSGBCalculate
 		{
 			// get an OTS field
 			CPoint poiOTSField = (*itr)->GetPosition();
-
-			//check if the field is within the rectangle
-			if(a_rectGBField.PtInRect(poiOTSField))
+		
+			COTSRect fldRec = COTSRect(poiOTSField.x - nOTSFieldWidth / 2, poiOTSField.y + nOTSFieldHeight / 2, poiOTSField.x + nOTSFieldWidth / 2, poiOTSField.y - nOTSFieldHeight / 2);
+		
+			if (a_rectGBField.IntersectOtherRect( fldRec))
 			{
-				// found a field 
+		
 
-				// add into the list
+			
+				(*itr)->SetRect(fldRec);
 				myOTSFields.push_back(*itr);
 
-				// remove the field from the measurement field list 
-				// move to the next item
-				//itr = allOTSFields.erase(itr);//There's no need to delete the field. gsp
+			
 				itr++;
-				// jump over
+			
 				continue;
-			}	
+		    }
 
-			// move to the next item
+		
 			itr++;
+	
 		}
 
-		// make sure GBFields list has enough OTSFields
-		int nOTSFieldsOfAGBField = nOTSRowsPerGBFld * nOTSColumnsPerGBFld;
-		if (myOTSFields.size() == nOTSFieldsOfAGBField)
-		{
-			// sort the GBFields list
-			sort(myOTSFields.begin(), myOTSFields.end(), comp);
-
-			// normalize particles for the GBFields
+		
 			pGBFieldData = NormalizeParticles(a_rectGBField, myOTSFields, a_sizePixelImage, nOTSFieldWidth, nOTSFieldHeight);
 			pGBFieldData->myReleventOTSFlds = myOTSFields;
-		}
-		
-		// return GB Field handle
+	
 		return pGBFieldData;
 	}
 
-	// Custom collation rules
-	BOOL compSegment(const COTSSegmentPtr &a, const COTSSegmentPtr &b)
-	{
-		if (a->GetHeight() <= b->GetHeight())
-		{
-			if (a->GetHeight() == b->GetHeight())
-			{
-				if (a->GetStart() < b->GetStart())
-				{
-					return TRUE;
-				}
-			}
-			else {
-				return TRUE;
-			}
-		}
-		return FALSE;
-	}
+
+
 
 	// normalize particles for the GBFields
-	CGBFieldDataPtr CGBCalculate::NormalizeParticles(CRect a_rectGBField, COTSFieldDataList myOTSFields, CSize a_sizePixelImage, int nFieldWidth,int nFieldHeight)
+	CGBFieldDataPtr CGBCalculate::NormalizeParticles(COTSRect a_rectGBField, COTSFieldDataList myOTSFields, CSize a_sizePixelImage, int nFieldWidth,int nFieldHeight)
 	{
 		// inits
 		CGBFieldDataPtr pGBFieldData(new CGBFieldData);
-		
+
+		pGBFieldData->SetMyRect(a_rectGBField);
+
 		COTSParticleList listNormalizedParticles;
 	
-		CPoint pointGBFieldRectTopLeft = a_rectGBField.TopLeft();
-		//a_rectGBField.Width = 707;
-		CRect GBRect = CRect(a_rectGBField.left, a_rectGBField.top, a_rectGBField.left+GB_FIELD_WIDTH, a_rectGBField.top+ GB_FIELD_WIDTH);
+		CPoint pointGBFieldRectTopLeft = a_rectGBField.GetTopLeft();
+
+		COTSRect GBRect = a_rectGBField;
+
 		int nBeforeCalNo = 0;
 		int nAfterCalNo = 0;
 		for (auto OTSField : myOTSFields)
@@ -1420,15 +1345,28 @@ namespace OTSGBCalculate
 			for (auto part : OTSField->GetParticleList())
 			{
 				CPoint fieldPos = OTSField->GetPosition();
-				CPoint fieldTopLeft = CPoint(fieldPos.x - nFieldWidth / 2, fieldPos.y + nFieldHeight);
+				//CPoint fieldTopLeft = CPoint(fieldPos.x - nFieldWidth / 2, fieldPos.y + nFieldHeight/2);
+				CPoint fieldTopLeft = OTSField->GetRect().GetTopLeft();
 				double fwidth = nFieldWidth;
 				double pixelsize = fwidth / a_sizePixelImage.cx;
 				CPoint xrayPosInFieldByPixel= part->GetXRayPos();
 
 				CPoint partPos = CPoint(fieldTopLeft.x + xrayPosInFieldByPixel.x * pixelsize, fieldTopLeft.y - xrayPosInFieldByPixel.y * pixelsize);
 
-					if (GBRect.PtInRect(partPos))
+				
+
+
+					if (GBRect.PointInRect(partPos))
 					{
+						CRect rectInSinglefld = part->GetParticleRect();
+						CPoint OTSLeftTop = CPoint(fieldTopLeft.x + rectInSinglefld.left * pixelsize, fieldTopLeft.y - rectInSinglefld.top * pixelsize);
+						CPoint OTSRightBottom = CPoint(fieldTopLeft.x + rectInSinglefld.right * pixelsize, fieldTopLeft.y - rectInSinglefld.bottom * pixelsize);
+
+						COTSRect recInOTSCord = COTSRect(OTSLeftTop, OTSRightBottom);
+						part->SetOTSRect(recInOTSCord);
+
+
+						pGBFieldData->IdentifyPartChemicalType(part);
 						listNormalizedParticles.push_back(part);
 					}
 
@@ -1444,248 +1382,13 @@ namespace OTSGBCalculate
 		return pGBFieldData;
 	}
 
-	//function Get GBField's FieldSegments List
-	BOOL CGBCalculate::GetGBFieldSegmentsList(int a_nColum, int a_nRow, COTSParticleList a_listOTSFieldParticles, int a_nCalNo, COTSSegmentsList &a_listGBFieldSegments, CSize a_sizePixelImage, int a_nFieldWidth)
-	{
-		CRect rectParticle;
-		CPoint poiParticleTopLeft;
-		COTSSegmentsList listOTSFieldSegments;
-		long nNewStart = 0, nNewLength = 0, nNewHeight;
-		long nOffsetX = a_nColum * a_sizePixelImage.cx;
-		long nOffsetY = a_nRow * a_sizePixelImage.cy;
-		// get one pixel width
-		//double dPixelsize = (double)a_nFieldWidth / a_sizePixelImage.cx;
-		double dPixelsize = (double)a_sizePixelImage.cx/a_nFieldWidth ;
-		double dGBwidth = sqrt(0.5) * 1000;
-		long nGBpixcel = (long)(dGBwidth * dPixelsize);
-
-		//cal the new  segment coordinate
-		for (auto Particle : a_listOTSFieldParticles)
-		{
-			//get the Particle rect
-			rectParticle = Particle->GetParticleRect();
-			poiParticleTopLeft = rectParticle.TopLeft();
-			listOTSFieldSegments = Particle->GetFeature()->GetSegmentsList();
-			for (auto Segment : listOTSFieldSegments)
-			{
-				BOOL bMerge = (a_nColum > 0) && (Segment->GetStart() == 0);
-
-				// off set the segment
-				nNewStart = Segment->GetStart() + nOffsetX;
-				nNewHeight= Segment->GetHeight() + nOffsetY;
-
-				// check should we need to keep the segment
-				// cal if the Segment in the GB 0.5/m2  
-				if (nNewStart > nGBpixcel)
-				{
-					continue;
-				}
-				if (nNewHeight > nGBpixcel)
-				{
-					continue;
-				}
-
-				// do we need to cut the segment 
-				//if over 0.5m2 cut it
-				//get GBField's a_nHeight, long a_nStart, long a_nLength
-				nNewLength = Segment->GetLength();
-				if (nNewStart + Segment->GetLength() > nGBpixcel)
-				{
-					nNewLength = (long)(nGBpixcel - nNewStart);
-				}
-			
-				COTSSegmentPtr pGBFieldSegment(new COTSSegment(nNewHeight, nNewStart, nNewLength));
-				
-				//merge the segment
-				if (bMerge && MergSegment(a_listGBFieldSegments, pGBFieldSegment, a_nCalNo))
-				{
-					continue;
-				}
-
-				a_listGBFieldSegments.push_back(pGBFieldSegment);
-			}
-		}
-		return TRUE;
-	}
-	
-	// merge the segment
-	BOOL CGBCalculate::MergSegment(COTSSegmentsList &a_listGBFieldSegments, COTSSegmentPtr a_pGBFieldSegment, int a_nCalNo)
-	{
-		//search merge segments only on last field 
-		COTSSegmentsList::iterator itr = a_listGBFieldSegments.begin()+ a_nCalNo;
-		while (itr != a_listGBFieldSegments.end())
-		{
-			COTSSegmentPtr pSegmentHead = *itr;
-			long nNextX = pSegmentHead->GetStart() + pSegmentHead->GetLength();
-			//merge only when height are the same
-			if (pSegmentHead->GetHeight() == a_pGBFieldSegment->GetHeight())
-			{
-				//end to start
-				if ((nNextX + 1) == a_pGBFieldSegment->GetStart())
-				{	
-					//merge and return true
-					pSegmentHead->SetLength(pSegmentHead->GetLength() + a_pGBFieldSegment->GetLength());
-					return TRUE;
-				}
-			}		
-			itr++;
-		}
-
-		//didn't merge return false
-		return FALSE;
-	}
-
-	// merge the segment,get new particles
-	BOOL CGBCalculate::GetGBParticles(COTSSegmentsList a_listGBFieldSegments, COTSParticleList &a_listNormalizedParticles)
-	{
-		//change segments to Particles
-		COTSFeatureList listFeatures;
-
-		if (a_listGBFieldSegments.size() == 0)
-		{
-			return FALSE;
-		}
-
-		GetFeatureList1(a_listGBFieldSegments, listFeatures);
-		ChangeFeaturelist(listFeatures, a_listNormalizedParticles);
-		for (auto p : a_listNormalizedParticles)
-		{
-			COTSImageProcess::CalcuParticleImagePropertes(p, PixSize);
-
-		}
-		return TRUE;
-	}
-
 	
-	BOOL CGBCalculate::GetFeatureList1(COTSSegmentsList& a_listSegments, COTSFeatureList& a_listFeatures)
-	{
-		COTSSegmentsList listSegmentNew;
-		std::map<long, COTSSegmentsList > mapOneLineSegments;
-		for (auto s : a_listSegments)
-		{
-			mapOneLineSegments[s->GetHeight()].push_back(s);			
-		}
-		std::map<long, COTSSegmentsList >::iterator lineItr = mapOneLineSegments.begin();//find the highest line
-		while (lineItr!=mapOneLineSegments.end ())
-		{	
-			
-		
-				for (auto s = lineItr->second.begin(); s < lineItr->second.end(); )//find  one segment of this line.
-				{
-
-					COTSSegmentPtr bottomSeg= *s;
-					listSegmentNew.clear();
-					listSegmentNew.push_back(*s);
-					s=lineItr->second.erase(s);
-					std::map<long, COTSSegmentsList >::iterator tempItr = lineItr;
-					tempItr++;
-					for (; tempItr !=mapOneLineSegments.end(); tempItr++)//find all other lines of segments
-					{
-						
-						
-							for (auto nextLineSegment = tempItr->second.begin(); nextLineSegment < tempItr->second.end();)//find next line's all segments
-							{
-								if (bottomSeg->UpDownConection(**nextLineSegment))
-								{
-									listSegmentNew.push_back(*nextLineSegment);
-									bottomSeg = *nextLineSegment;
-									nextLineSegment=tempItr->second.erase(nextLineSegment);
-									break;
-								}
-								
-									if (tempItr->second.size() > 0)
-									{
-										nextLineSegment++;
-									}
-									else
-									{
-										break;
-									}			
-							}
-						
-					}
-					COTSFeaturePtr pFeature = COTSFeaturePtr(new COTSFeature());
-					pFeature->SetSegmentsList(listSegmentNew);
-					//check if this new feature is connected with other found feature.
-					COTSSegmentPtr topSeg = listSegmentNew[0];//find the toppest segment of this new feature.
-					COTSSegmentPtr bottomSegment= listSegmentNew[listSegmentNew.size()-1];//find the lowest segment of this new feature.
-					
-					bool haveMerged=false;
-					for (auto f : a_listFeatures)
-					{
-						for (auto seg : f->GetSegmentsList())
-						{
-							if (bottomSegment->UpDownConection(*seg)|| topSeg->UpDownConection (*seg))
-							{
-								COTSSegmentsList segs = f->GetSegmentsList();
-								for (auto s : listSegmentNew)
-								{
-									segs.push_back(s);
-									
-								}
-								
-								f->SetSegmentsList(segs);
-								haveMerged = true;
-								break ;
-							}
-						}
-						if (haveMerged)
-						{
-							break;
-						}
-					
-					}
-					if (!haveMerged)
-					{
-						a_listFeatures.push_back(pFeature);
-					}
-					
-					if (lineItr->second.size()==0)
-					{					
-						break;
-					}			
-			    }
-			lineItr++;
-		}
-
-
-		return true;
-	}
-	// change feature into particle
-	BOOL CGBCalculate::ChangeFeaturelist(COTSFeatureList& a_listFeatures, COTSParticleList& a_listParticle)
-	{
-		if (a_listFeatures.size() == 0)
-		{
-			LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: there is no feature in the list."));
-			return FALSE;
-		}
-		// compute Rect
-		for (auto pFeature : a_listFeatures)
-		{
-			COTSParticlePtr pParticle = COTSParticlePtr(new COTSParticle());
-			COTSFeaturePtr pFeatureNew = COTSFeaturePtr(new COTSFeature(*pFeature.get()));
-			pParticle->SetFeature(pFeatureNew);
-			if (!pParticle->CalCoverRect())
-			{
-				LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: failed to get particle rect."));
-				return FALSE;
-			}
-			a_listParticle.push_back(pParticle);
-		}
-
-		if ((int)a_listParticle.size() == 0)
-		{
-			LogErrorTrace(__FILE__, __LINE__, _T("Can't get particle."));
-			return FALSE;
-		}
-
-		return TRUE;
-	}
 	void CGBCalculate::SetPixSize(double p)
 	{
 		PixSize = p;
 	}
 
+
 }
 
 

+ 17 - 26
OTSCPP/OTSRptCalculate/GBCal/CGBCalculate.h

@@ -7,17 +7,30 @@ namespace OTSGBCalculate
 {
 	//define String Resources for GB Grid
 	using namespace OTSMODEL;
-
+	const int GB_FIELD_WIDTH = 730;//normally,the number should be 707,we take 730 .Because the particle may be lost when measuring,so we make it a little bigger to compromise it.
 	class __declspec(dllexport) CGBCalculate
 	{
+
 	public:
 		CGBCalculate(CReportMgr* rptMgrPtr);
 		~CGBCalculate();
 		CGridDatasList GetGBInclusion();
 
-		const int GB_FIELD_WIDTH = 720;//normally,the number should be 707,we take 720 .Because the particle may be lost when measuring,so we make it a little bigger to compromise it.
+		
 	protected:
 
+
+		// calculate GB fields
+		CGBFieldList CalGBFields(CSmplMsrResultFileMgrPtr pSmplMgr);
+
+	
+		// convert ots fields to gb fields
+		BOOL OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,  CSize sizePixelImage, int a_nFieldWidth, int a_nFieldHeight);
+		//get the GB field within thr rectangle
+		CGBFieldDataPtr GetOneGBField(COTSRect a_rectGBField, COTSFieldDataList& a_listOTSFields, CSize sizePixelImage, int a_nFieldWidth, int nOTSFieldHeight);
+		//  normalize particles for the GBFields
+		CGBFieldDataPtr NormalizeParticles(COTSRect a_rectGBField, COTSFieldDataList a_listOTSFields, CSize sizePixelImage, int a_nFieldWidth, int a_nFieldHeight);
+
 		//计算一个数据源中所获得的GBFields转化的统计数据
 		CGridDatasList GetGridDataListForOneDataSource(CGBFieldList listCGBField, CALCULATE_TABLE_TYPE tableType);
 		//计算一个数据源中所获得的GBFields转化的统计数据德标
@@ -31,33 +44,11 @@ namespace OTSGBCalculate
 		CGridDataPtr GetGridDIN(COTSParticleList cotsparticlelistA, set<COTSParticlePtr> cotsparticlelistB, COTSParticleList cotsparticlelistC, COTSParticleList cotsparticlelistD);
 		CGridDataPtr GetGridDSLevel(CGBFieldList DsFrames);
 		void SetFrameLevelNo(GB_GRADE_TYPE levela, int nALevel[]);
-
-
-		// calculate GB fields
-		CGBFieldList CalGBFields(CSmplMsrResultFileMgrPtr pSmplMgr);
-
-		// calculate how many fields needed (horizontal) 
-		void CalOTSFieldsNo(int& a_nRow, int& a_nColumn, int a_nFieldWidth,int a_nFieldHeight);
-		// convert ots fields to gb fields
-		BOOL OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields, int a_nRow, int a_nColumn, CSize sizePixelImage,int a_nFieldWidth,int a_nFieldHeight);
-		//get the GB field within thr rectangle
-		CGBFieldDataPtr GetOneGBField(CRect a_rectGBField, COTSFieldDataList& a_listOTSFields, int a_nRow, int a_nColumn, CSize sizePixelImage, int a_nFieldWidth, int nOTSFieldHeight);
-		//  normalize particles for the GBFields
-		CGBFieldDataPtr NormalizeParticles(CRect a_rectGBField, COTSFieldDataList a_listOTSFields, CSize sizePixelImage, int a_nFieldWidth,int a_nFieldHeight);			
-		
-		BOOL GetGBFieldSegmentsList(int nColum, int nRow, COTSParticleList a_listOTSFieldParticles, int a_nCalNo,COTSSegmentsList &a_listGBFieldSegments, CSize a_sizePixelImage, int a_nFieldWidth);
-		// merge the segment
-		BOOL MergSegment(COTSSegmentsList &a_listGBFieldSegments, COTSSegmentPtr pGBFieldSegment, int a_nLastSegmentNo);           
-		// merge the segment,get new particles
-		BOOL GetGBParticles(COTSSegmentsList a_listGBFieldSegments, COTSParticleList &a_listNormalizedParticles);					
-		// get feature list of up-down segment
-		//BOOL GetFeatureList(COTSSegmentsList& a_listSegments, COTSFeatureList& a_listFeatures);
-		BOOL GetFeatureList1(COTSSegmentsList & a_listSegments, COTSFeatureList & a_listFeatures);
-		// change feature into particle
-		BOOL ChangeFeaturelist(COTSFeatureList& a_listFeatures, COTSParticleList& a_listParticle);									
+									
 		// particle list
 		DOUBLE& GetPixSize() { return PixSize; }
 		void SetPixSize(double p);
+
 		DOUBLE PixSize;
 		//pointer to the whole reportprojfilemgr
 		CReportMgr* m_rptMgrPtr;

+ 157 - 84
OTSCPP/OTSRptCalculate/GBCal/GBFieldData.cpp

@@ -14,18 +14,26 @@ namespace OTSGBCalculate
 	{
 		auto adjacentPart = find_if(plist.begin(), plist.end(), [p](COTSParticlePtr pBParticle)
 			{
-				CRect rectParticle = p->GetParticleRect();
-				CPoint ptParticleCenter = rectParticle.CenterPoint();
-				int Bottom = rectParticle.BottomRight().y;
-				int Top = rectParticle.TopLeft().y;
-				CRect rectBCurParticle = pBParticle->GetParticleRect();
-				CPoint ptBParticleCenter = rectBCurParticle.CenterPoint();
-				int BottomB = rectBCurParticle.BottomRight().y;
-				int TopB = rectBCurParticle.TopLeft().y;
+			    //the conditional particle
+			    COTSRect rectParticle = p->GetOTSRect();
+				CPoint ptParticleCenter = rectParticle.GetCenterPoint();
+				int Bottom = rectParticle.GetBottomRight().y;
+				int Top = rectParticle.GetTopLeft().y;
+
+				//the iterational particle
+				COTSRect rectBCurParticle = pBParticle->GetOTSRect();
+				CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
+				int BottomB = rectBCurParticle.GetBottomRight().y;
+				int TopB = rectBCurParticle.GetTopLeft().y;
+
+				if (rectParticle == rectBCurParticle)
+				{
+					return false;
+				}
 
 				double dd = 0, ds = 0;
 				ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
-				if (ds < 10)//recognize these two particle in the same level
+				if (ds < 10 )//recognize these two particle in the same level
 				{
 					if (Bottom > TopB)//current particle is on the above
 					{
@@ -278,7 +286,7 @@ namespace OTSGBCalculate
 					}
 					mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt);
 				}
-				else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O)
+				else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType== GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al)
 				{
 					// C				
 					//计算颗粒宽度是属于细系粗系还是超尺寸
@@ -302,6 +310,7 @@ namespace OTSGBCalculate
 			}
 			else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒
 			{
+				
 				// B, or D or DS
 				// compute Feret's diameter	
 				double dFeretDiameter = pParticle->GetFeretDiameter();
@@ -312,32 +321,70 @@ namespace OTSGBCalculate
 				}
 				else
 				{
-					// B or D
-					GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID);
-					//不能确定是B或D,先设为INVALID
-					listBAndDParticles.push_back(gbP);
+					if (pParticle->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_S)//if it contains sulfide then it is a A particle.
+					{
+						GB_LEVEL_TYPE partType = GB_LEVEL_TYPE::A_TYPE;//把类型设为有效类型,以便不再找这个颗粒
+
+						//计算颗粒宽度是属于细系粗系还是超尺寸
+						GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE);
+						switch (wt)
+						{
+						case GB_WIDTH_TYPE::THIN:
+							listAThinParticles.push_back(pParticle);
+							break;
+						case GB_WIDTH_TYPE::WIDE:
+							listAWideParticles.push_back(pParticle);
+							break;
+						case GB_WIDTH_TYPE::SUPER:
+							listASuperParticles.push_back(pParticle);
+							break;
+						}
+						mapAllParticles[pParticle] = GBParticle(pParticle, partType, wt);
+
+						
+
+					}
+					else
+					{
+						// B or D
+						/*if (pParticle->GetChemicalType() != GB_CHEMICAL_TYPE::INVALID)//here we take all the particles 
+						{*/
+							GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID);
+							//不能确定是B或D,先设为INVALID
+							listBAndDParticles.push_back(gbP);
+						/*}*/
+						
+					}
+					
 
 				}
 			}
 		}
-		{
+		
 			for (auto pGBParticle : listBAndDParticles)
 			{
-				// check if the particle is alone			
+				
+				
+				 //check if the particle is alone			
 				auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle)
 					{
-						CRect rectParticle = pGBParticle.myPart->GetParticleRect();
-						CPoint ptParticleCenter = rectParticle.CenterPoint();
-						int Bottom = rectParticle.BottomRight().y;
-						int Top = rectParticle.TopLeft().y;
-						CRect rectBCurParticle = pBParticle.myPart->GetParticleRect();
-						CPoint ptBParticleCenter = rectBCurParticle.CenterPoint();
-						int BottomB = rectBCurParticle.BottomRight().y;
-						int TopB = rectBCurParticle.TopLeft().y;
-
+					   //the conditional particle 
+					     COTSRect rectParticle = pGBParticle.myPart->GetOTSRect();
+						 CPoint ptParticleCenter = rectParticle.GetCenterPoint();
+						int Bottom = rectParticle.GetBottomRight().y;
+						int Top = rectParticle.GetTopLeft().y;
+						//the current iteration particle
+						COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect();
+						CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
+						int BottomB = rectBCurParticle.GetBottomRight().y;
+						int TopB = rectBCurParticle.GetTopLeft().y;
+						if (rectParticle == rectBCurParticle)
+						{
+							return false;
+						}
 						double dd = 0, ds = 0;
 						ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
-						if (ds < 10)//认为两个颗粒在一条竖直线上,但不在一起
+						if (ds < 10 )//认为两个颗粒在一条竖直线上,但不在一起
 						{
 							if (Bottom > TopB)//current particle is on the above
 							{
@@ -359,67 +406,75 @@ namespace OTSGBCalculate
 
 						return false;
 					});
+			
 				if (adjacentPart == listBAndDParticles.end())//没找到
 				{
-					pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE;
-
-					//计算颗粒宽度是属于细系粗系还是超尺寸
-					GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE);
-					switch (wt)
+					if (pGBParticle.myPart->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_O)
 					{
-					case GB_WIDTH_TYPE::THIN:
-						listDThinParticles.push_back(pGBParticle.myPart);
-						break;
-					case GB_WIDTH_TYPE::WIDE:
-						listDWideParticles.push_back(pGBParticle.myPart);
-						break;
-					case GB_WIDTH_TYPE::SUPER:
-						listDSuperParticles.push_back(pGBParticle.myPart);
-						break;
+						pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE;
+
+						//计算颗粒宽度是属于细系粗系还是超尺寸
+						GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE);
+						switch (wt)
+						{
+						case GB_WIDTH_TYPE::THIN:
+							listDThinParticles.push_back(pGBParticle.myPart);
+							break;
+						case GB_WIDTH_TYPE::WIDE:
+							listDWideParticles.push_back(pGBParticle.myPart);
+							break;
+						case GB_WIDTH_TYPE::SUPER:
+							listDSuperParticles.push_back(pGBParticle.myPart);
+							break;
+						}
+						mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt);
 					}
-					mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt);
+					
 				}
 				else//找到了相邻接的颗粒,不是孤立的则为B类
 				{
-					pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒
-					adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE;
+				
+						pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒
+						adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE;
 
-					//计算颗粒宽度是属于细系粗系还是超尺寸
-					GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE);
-					switch (wt)
-					{
-					case GB_WIDTH_TYPE::THIN:
-						listBThinParticles.insert(pGBParticle.myPart);
-						break;
-					case GB_WIDTH_TYPE::WIDE:
-						listBWideParticles.insert(pGBParticle.myPart);
-						break;
-					case GB_WIDTH_TYPE::SUPER:
-						listBSuperParticles.insert(pGBParticle.myPart);
-						break;
-					}
-					mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt);
-					wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE);
-					switch (wt)
-					{
-					case GB_WIDTH_TYPE::THIN:
-						listBThinParticles.insert(adjacentPart->myPart);
-						break;
-					case GB_WIDTH_TYPE::WIDE:
-						listBWideParticles.insert(adjacentPart->myPart);
-						break;
-					case GB_WIDTH_TYPE::SUPER:
-						listBSuperParticles.insert(adjacentPart->myPart);
-						break;
-					}
-					mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt);
+						//计算颗粒宽度是属于细系粗系还是超尺寸
+						GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE);
+						switch (wt)
+						{
+						case GB_WIDTH_TYPE::THIN:
+							listBThinParticles.insert(pGBParticle.myPart);
+							break;
+						case GB_WIDTH_TYPE::WIDE:
+							listBWideParticles.insert(pGBParticle.myPart);
+							break;
+						case GB_WIDTH_TYPE::SUPER:
+							listBSuperParticles.insert(pGBParticle.myPart);
+							break;
+						}
+						mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt);
+						wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE);
+						switch (wt)
+						{
+						case GB_WIDTH_TYPE::THIN:
+							listBThinParticles.insert(adjacentPart->myPart);
+							break;
+						case GB_WIDTH_TYPE::WIDE:
+							listBWideParticles.insert(adjacentPart->myPart);
+							break;
+						case GB_WIDTH_TYPE::SUPER:
+							listBSuperParticles.insert(adjacentPart->myPart);
+							break;
+						}
+						mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt);
+					
+					
 
 				}
 
 			}
 
 		}
-	}
+	
 
 	// caculate Level by method 2
 	void CGBFieldData::CaculateLevelByMethod2()
@@ -434,7 +489,7 @@ namespace OTSGBCalculate
 		for (auto pParticle : m_listParticles)
 		{
 			
-			IdentifyPartChemicalType(pParticle);
+			//IdentifyPartChemicalType(pParticle);
 			//check the denominator is zero or not
 			CRect rectParticle = pParticle->GetParticleRect();
 			if (rectParticle.Width() == 0)
@@ -687,14 +742,15 @@ namespace OTSGBCalculate
 				// check if the particle is alone			
 				auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle)
 					{
-						CRect rectParticle = pGBParticle.myPart->GetParticleRect();
-						CPoint ptParticleCenter = rectParticle.CenterPoint();
-						int Bottom = rectParticle.BottomRight().y;
-						int Top = rectParticle.TopLeft().y;
-						CRect rectBCurParticle = pBParticle.myPart->GetParticleRect();
-						CPoint ptBParticleCenter = rectBCurParticle.CenterPoint();
-						int BottomB = rectBCurParticle.BottomRight().y;
-						int TopB = rectBCurParticle.TopLeft().y;
+					COTSRect rectParticle = pGBParticle.myPart->GetOTSRect();
+						CPoint ptParticleCenter = rectParticle.GetCenterPoint();
+						int Bottom = rectParticle.GetBottomRight().y;
+						int Top = rectParticle.GetTopLeft().y;
+
+						COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect();
+						CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint();
+						int BottomB = rectBCurParticle.GetBottomRight().y;
+						int TopB = rectBCurParticle.GetTopLeft().y;
 
 						double dd = 0, ds = 0;
 						ds = abs(ptParticleCenter.x - ptBParticleCenter.x);
@@ -1160,6 +1216,8 @@ namespace OTSGBCalculate
 		double dSiWeight = 0;
 		double dAlWeight = 0;
 		double dMnWeight = 0;
+		double dFeWeight = 0;
+		double dCWeight = 0;
 		
 
 
@@ -1193,7 +1251,15 @@ namespace OTSGBCalculate
 			}
 			else if (pElChem->GetName().CompareNoCase(STR_Mn) == 0)
 			{
-				dAlWeight = pElChem->GetPercentage();
+				dMnWeight = pElChem->GetPercentage();
+			}
+			else if (pElChem->GetName().CompareNoCase(STR_Fe) == 0)
+			{
+				dFeWeight = pElChem->GetPercentage();
+			}
+			else if (pElChem->GetName().CompareNoCase(STR_C) == 0)
+			{
+				dCWeight = pElChem->GetPercentage();
 			}
 
 
@@ -1205,15 +1271,18 @@ namespace OTSGBCalculate
 		{
 
 			Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S);
+		
 
 		}
-		else if (dSWeight >= RICH_ELEMENT_SUM && dOWeight < MIN_ELEMENT_SUM)
+		else if (dSWeight >= MIN_ELEMENT_SUM && dOWeight < MIN_ELEMENT_SUM)//
 		{
 			Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S);
+			
 		}
 		else if (dOWeight >= MIN_ELEMENT_SUM && dAlWeight >= MIN_ELEMENT_SUM)
 		{
 			Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_Al);
+			
 		}
 		else if (dOWeight >= MIN_ELEMENT_SUM && dSiWeight >= MIN_ELEMENT_SUM)
 		{
@@ -1223,6 +1292,10 @@ namespace OTSGBCalculate
 		{
 			Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_O);
 		}
+		else
+		{
+			Particle->SetChemicalType(GB_CHEMICAL_TYPE::INVALID);
+		}
 
 
 

+ 9 - 1
OTSCPP/OTSRptCalculate/GBCal/GBFieldData.h

@@ -15,6 +15,8 @@ namespace OTSGBCalculate
 	const CString STR_SUL = _T("S");
 	const CString STR_N = _T("N");
 	const CString STR_Mn = _T("Mn");
+	const CString STR_Fe = _T("Fe");
+	const CString STR_C = _T("C");
 	const double MIN_ELEMENT_SUM = 0.02;
 	const double RICH_ELEMENT_SUM = 5;
 	class  CGBFieldData : public COTSFieldData
@@ -29,6 +31,9 @@ namespace OTSGBCalculate
 
 		virtual ~CGBFieldData();					// detractor
 
+		void SetMyRect(COTSRect r) { m_myRect = r; }
+		COTSRect GetMyRect() { return m_myRect; }
+
 												// serialization
 		virtual void Serialize(bool isStoring, tinyxml2::XMLDocument *classDoc, tinyxml2::XMLElement *rootNode);
 		// id
@@ -82,6 +87,7 @@ namespace OTSGBCalculate
 		void CaculateLevelByMethod2();
 		void CaculateLevelASTM();
 		void CaculateLevelDIN(COTSParticleList listParticle);
+		BOOL IdentifyPartChemicalType(COTSParticlePtr Particle);
 	protected:
 
 		// cleanup 
@@ -102,13 +108,15 @@ namespace OTSGBCalculate
 
 		BOOL CaculateLevelFatWidth(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel);
 		BOOL CaculateSuper(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel);
-		BOOL IdentifyPartChemicalType(COTSParticlePtr Particle);
+		
 	private:
 
 
 		// id
 		int m_nFrameId;
 
+		COTSRect m_myRect;
+
 		// A level
 		CGBLevelPtr m_pALevel;
 

+ 9 - 0
OTSIncAReportApp/1-UI/OTSDisplaySourceGridData/frmReportConditionChoose.cs

@@ -711,6 +711,7 @@ namespace OTSIncAReportApp
                             break;
                         case CALCULATE_TABLE_TYPE.GB_Method1:
                             //国标一
+                            Cursor.Current = Cursors.WaitCursor;
                             string resultfile = m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FilePath + "\\"
                                 + m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FileName;
 
@@ -728,6 +729,8 @@ namespace OTSIncAReportApp
 
                             m_ReportApp.im_ChineseStandardABCDDS.Dock = DockStyle.Fill;
                             m_ReportApp.m_TablesWindow.Controls.Add(m_ReportApp.im_ChineseStandardABCDDS);
+                            m_ReportApp.im_ChineseStandardABCDDS.UseWaitCursor = false;
+                            Cursor.Current = Cursors.Default;
                             m_ReportApp.m_TablesWindow.Activate();
 
 
@@ -736,6 +739,7 @@ namespace OTSIncAReportApp
                             break;
                         case CALCULATE_TABLE_TYPE.GB_Method2:
                             //国标二
+                            Cursor.Current = Cursors.WaitCursor;
                             string resultfile2 = m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FilePath + "\\"
                                  + m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FileName;
 
@@ -751,12 +755,14 @@ namespace OTSIncAReportApp
                             m_ReportApp.im_NationalStandardMethodTwo = new NationalStandardMethodTwo(m_ReportApp.m_rstDataMgr.m_ReportMgr, listGriddataclr2);
                             m_ReportApp.im_NationalStandardMethodTwo.Dock = DockStyle.Fill;
                             m_ReportApp.m_TablesWindow.Controls.Add(m_ReportApp.im_NationalStandardMethodTwo);
+                            Cursor.Current = Cursors.WaitCursor;
                             m_ReportApp.m_TablesWindow.Activate();
                             //OpenOTSINcAreportTemplateAPP(m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FilePath + "\\"
                             //    + m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FileName, "GB2");
                             break;
                         case CALCULATE_TABLE_TYPE.ASTM:
                             //美标
+                            Cursor.Current = Cursors.WaitCursor;
                             string resultfile3 = m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FilePath + "\\"
                                 + m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FileName;
 
@@ -772,12 +778,14 @@ namespace OTSIncAReportApp
                             m_ReportApp.im_ASTMStandardABCDDS = new ASTMStandardABCDDS(m_ReportApp.m_rstDataMgr.m_ReportMgr, listGriddataclr3);
                             m_ReportApp.im_ASTMStandardABCDDS.Dock = DockStyle.Fill;
                             m_ReportApp.m_TablesWindow.Controls.Add(m_ReportApp.im_ASTMStandardABCDDS);
+                            Cursor.Current = Cursors.Default;
                             m_ReportApp.m_TablesWindow.Activate();
                             //OpenOTSINcAreportTemplateAPP(m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FilePath + "\\"
                             //    + m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FileName, "ASTM");
                             break;
                         case CALCULATE_TABLE_TYPE.DIN:
                             //德标
+                            Cursor.Current = Cursors.WaitCursor;
                             string resultfile4 = m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FilePath + "\\"
                                + m_rstDataMgr.ResultFilesList[m_rstDataMgr.GetWorkingResult()].FileName;
 
@@ -793,6 +801,7 @@ namespace OTSIncAReportApp
                             m_ReportApp.im_DINStandardABCDDS = new DINStandardABCDDS(m_ReportApp.m_rstDataMgr.m_ReportMgr, listGriddataclr4);
                             m_ReportApp.im_DINStandardABCDDS.Dock = DockStyle.Fill;
                             m_ReportApp.m_TablesWindow.Controls.Add(m_ReportApp.im_DINStandardABCDDS);
+                            Cursor.Current = Cursors.Default;
                             m_ReportApp.m_TablesWindow.Activate();
                             //OpenOTSINcAreportTemplateAPP(m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FilePath + "\\"
                             //    + m_RstProp.m_ReportApp.m_DataMgrFun.resultFilesList[m_RstProp.m_ReportApp.m_DataMgrFun.WorkingResult].FileName, "DIN");