using NSOTSController; using OTSIncAReportApp.DataOperation.DataAccess; using OTSIncAReportApp.DataOperation.Model; using OTSIncAReportApp.SysMgrTools; using OTSIncAReportGraph.Class; using OTSIncAReportGraph.Controls; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; namespace OTSIncAReportGraph.OTSIncAReportGraphFuncation { class OTSIncAReportFun { #region 枚举定义 /// /// 样品台X轴方向 /// enum OTS_X_AXIS_DIRECTION { LEFT_TOWARD = 0, RIGHT_TOWARD = 1 } /// /// 样品台Y轴方向 /// enum OTS_Y_AXIS_DIRECTION { UP_TOWARD = 0, DOWN_TOWARD = 1 } #endregion #region 定义变量 private ResultFile resultFile = null; //新版排序图窗体对象 private Control_DrawDistrbutionSortImage m_Control_DrawdistrbutionsortImage = null; //新版分布图和BSE图整合对象 private Control_DrawDistrbutionImageAndBSE m_Control_DrawDistrbutionImageAndBSE = null; //全局对象,为了能够快速的获取到xray数据,而做为一个临时变量进行保存,使用前应该判断是否为空 public List m_list_COTSFieldMgrClr = null; NLog.Logger log = NLog.LogManager.GetCurrentClassLogger(); //field的数量 public int m_field_count = 0; //particle的数量 public int m_particle_count = 0; //加载使用的时间 public string m_time_str = ""; //加载使用时间计算时间段2 public string m_time_str2 = ""; //防止segment过多的数量限制,先写300吧,过少也不好,过防止过多程序而卡死 public int m_segment_overflownumber = 400; //电镜设置对象 public NSOTSController.COTSControlFunExport m_cfun = null; //是否已经连接到了电镜 public bool m_SEMConnectionState = false; //连接到电镜的ID号 public int m_SEM_ID = 0; //国际化 Language lan = new Language(); Hashtable table; #endregion #region 构造函数 /// /// 构造函数,接收新版分布图和排序图的构造函数 /// /// /// public OTSIncAReportFun(Control_DrawDistrbutionImageAndBSE in_Control_DrawDistrbutionImageAndBSE, ResultFile result) { m_Control_DrawDistrbutionImageAndBSE = in_Control_DrawDistrbutionImageAndBSE; resultFile = result; table = lan.GetNameTable("OTSIncAReportFun"); } /// /// 构造函数,接收新版颗粒排序图的构造 /// /// /// public OTSIncAReportFun(Control_DrawDistrbutionSortImage in_Control_DrawDistrbutionSortimage, ResultFile result) { m_Control_DrawdistrbutionsortImage = in_Control_DrawDistrbutionSortimage; resultFile = result; table = lan.GetNameTable("OTSIncAReportFun"); } #endregion #region 封装自定义方法 /// /// 根据颗粒排序图获取已经选择上的颗粒,返回被选择上的颗粒的列表 /// /// public List GetSelectedParticleList_ForDrawDistrbutionImageAndBSE() { List ls_list_cotsparticleclr = new List(); //防止为空校验判断 if (m_list_COTSFieldMgrClr == null) return ls_list_cotsparticleclr; //先取出,所有被选择的dparticle列表的 List ls_list_dp = new List(); foreach (DParticle ls_dp in m_Control_DrawDistrbutionImageAndBSE.m_list_baseobject) { if (ls_dp.Operator == ParticleOperator.SELECTED) { ls_list_dp.Add(ls_dp); } } //并开始查找包含tagid和fieldid的cotsparticle的对象,保存到list当中 for (int i = 0; i < ls_list_dp.Count(); i++) { for (int j = 0; j < m_list_COTSFieldMgrClr.Count(); j++) { //先获取该field中的所有particle List list_cotsparticleclr = new List(); list_cotsparticleclr = m_list_COTSFieldMgrClr[j].ParticleList; for (int k = 0; k < list_cotsparticleclr.Count(); k++) { if (list_cotsparticleclr[k].ParticleId == ls_list_dp[i].CLRTagID && list_cotsparticleclr[k].FieldId == ls_list_dp[i].CLRFieldID) { ls_list_cotsparticleclr.Add(list_cotsparticleclr[k]); } } } } return ls_list_cotsparticleclr; } /// /// 计算像素总画面Image大小,及进行物理坐标与分辨率坐标的换算操作 传入物理坐标,及宽高,来 /// /// 传入的物理坐标数组 /// 单个field宽 /// 单个field高 /// public Rectangle ConvertAndGetMaxRect(List in_list_point, int in_width, int in_height) { //首先要能确定下来,单个物理坐标的宽和高-------------------------------- int i_wl_width = 0; int i_wl_height = 0; Rectangle ls_r = GetOneFieldWidthAndHeight(in_list_point); i_wl_width = ls_r.Width; i_wl_height = ls_r.Height; //----------------------------------------------------------------------------- int point_x_min = 10000000; int point_x_max = -10000000; int point_y_min = 10000000; int point_y_max = -10000000; for (int i = 0; i < in_list_point.Count(); i++) { Point ls_point = in_list_point[i]; //取出正数最大x if (ls_point.X > point_x_max) point_x_max = ls_point.X; if (ls_point.Y > point_y_max) point_y_max = ls_point.Y; if (ls_point.X < point_x_min) point_x_min = ls_point.X; if (ls_point.Y < point_y_min) point_y_min = ls_point.Y; } //然后分别用最大值+abs(最小值),就是x,和y轴的总长值 point_x_max = point_x_max - point_x_min; point_y_max = point_y_max - point_y_min; //该算法有个问题,就是不能直观的得到整个范围的大小,要除以倍数再补1能补充缺少的一个field视域********** point_x_max = ((point_x_max / i_wl_width) + 1) * i_wl_width; point_y_max = ((point_y_max / i_wl_height) + 1) * i_wl_height; //将物理宽高,变换成分辨率宽高 if (i_wl_width != 0) point_x_max = (point_x_max / i_wl_width) * in_width; else point_x_max = 0; if (i_wl_height != 0) point_y_max = (point_y_max / i_wl_height) * in_height; else point_y_max = 0; Rectangle ret_rectangle = new Rectangle(0, 0, 0, 0); //判断一下防止出错,只有在有数据的情况下,进行赋值才行 if (in_list_point.Count > 0) { ret_rectangle = new Rectangle(0, 0, point_x_max, point_y_max); } //这样返回是物理坐标的总大小,应该返回像素坐标大小才对 return ret_rectangle; } /// /// 通过传入的各field物理坐标列表,和单个field的屏幕分辨率,及单个的field的物理坐标,来获取当前field在整个image中的屏幕像素坐标偏移,并且是OTS向上为正做了Y轴相反运算 /// /// /// /// /// /// /// public Point GetFieldPhysicsConvertToScreen(List in_list_point, int in_screen_width, int in_screen_height, Point in_physics_point) { //先确定单个物理坐标的宽和高 Rectangle rect_onefield_wl = GetOneFieldWidthAndHeight(in_list_point); //找出最小的x,y用来做偏移运算 int i_offset_x = 1000000000; int i_offset_y = 1000000000; //先取出最小的x,y for (int i = 0; i < in_list_point.Count; i++) { if (i_offset_x > in_list_point[i].X) { i_offset_x = in_list_point[i].X; } if (i_offset_y > in_list_point[i].Y) { i_offset_y = in_list_point[i].Y; } } List list_point = new List(); //将各Field的OTS坐标与屏幕左上角的坐标进行相减,取出与屏幕左上角的偏移量,也就是取出了屏幕坐标 int index = 0; for (int i = 0; i < in_list_point.Count; i++) { list_point.Add(new Point(in_list_point[i].X - i_offset_x, in_list_point[i].Y - i_offset_y)); //根据物理坐标的对应关系,找到了在数组中的位置,下面将用该位置对应得出像素坐标的位置,并进行返回 if (in_list_point[i] == in_physics_point) { index = i; } } //再将物理像素list_point换算成像素list_point,再用index定位 for (int i = 0; i < list_point.Count; i++) { //将单个物理像素变换成屏幕像素分辨率 int i_bs_x = 0; int i_bs_y = 0; if (rect_onefield_wl.Width != 0) i_bs_x = list_point[i].X / rect_onefield_wl.Width; if (rect_onefield_wl.Height != 0) i_bs_y = list_point[i].Y / rect_onefield_wl.Height; //再将屏幕像素分辨率按倍数赋值给list_point //考虑到OTS坐标整体是Y轴向上为正,所以这里需要根据总高,减y轴就是向上为正 list_point[i] = new Point(in_screen_width * i_bs_x, in_screen_height * i_bs_y); } #region Y轴向上为正转换--------------------------------------------------------------------------------------- //但上面由于相减,会出现y轴为负的情况,所以这里要根据Y轴是否出现负值,再次做偏移运算 //找到最小的y轴,也就是 [Y轴偏移量] int i_offset_y_second = 100000000; //找到最大的Y轴,用于做相反运算,Y轴向上 int i_screen_y = -100000000; for (int i = 0; i < list_point.Count; i++) { if (i_offset_y_second > list_point[i].Y) { i_offset_y_second = list_point[i].Y;//这个偏移Y就是最小的Y,可能是负数,也可能是0 } if (i_screen_y < list_point[i].Y) { i_screen_y = list_point[i].Y; } } //对Y轴进行反转,OTS坐标向屏幕坐标转换 for (int i = 0; i < list_point.Count; i++) { list_point[i] = new Point(list_point[i].X, i_screen_y - list_point[i].Y); } //再将所有的Field与这个 [Y轴偏移量] 相加,防止OTS向上为正转换屏幕坐标,造成的Y轴为负的情况 for (int i = 0; i < list_point.Count; i++) { list_point[i] = new Point(list_point[i].X, list_point[i].Y + Math.Abs(i_offset_y_second)); } #endregion Y轴向上为正转换结束-------------------------------------------------------------------------- return list_point[index]; } /// /// 计算单个field的物理大小 传入field的list,还有测量结果管理类对象,在无法计算出单file的物理大小的情况下,到这里取再计算得出 /// /// public Rectangle GetOneFieldWidthAndHeight(List in_list_point) { int i_wl_width_max = -10000000; int i_wl_height_max = -10000000; int i_wl_width_max2 = -10000000; int i_wl_height_max2 = -10000000; //先找出最大的值, for (int i = 0; i < in_list_point.Count(); i++) { if (i_wl_width_max < in_list_point[i].X) i_wl_width_max = in_list_point[i].X; if (i_wl_height_max < in_list_point[i].Y) i_wl_height_max = in_list_point[i].Y; } //再找出第二大的值 for (int i = 0; i < in_list_point.Count(); i++) { if (i_wl_width_max2 < in_list_point[i].X && i_wl_width_max != in_list_point[i].X) i_wl_width_max2 = in_list_point[i].X; if (i_wl_height_max2 < in_list_point[i].Y && i_wl_height_max != in_list_point[i].Y) i_wl_height_max2 = in_list_point[i].Y; } //需要针对第二大的值,获取时进行判断,感觉这里应该如果并未找到第二大的值的情况下,赋于0值,便于以后进行计算 if (i_wl_width_max2 == -10000000) i_wl_width_max2 = 0; if (i_wl_height_max2 == -10000000) i_wl_height_max2 = 0; Rectangle ret_rect = new Rectangle(0, 0, i_wl_width_max - i_wl_width_max2, i_wl_height_max - i_wl_height_max2); //如果最后计算出的宽高有0则重新到测量数据中获取--------------------------------------- if (ret_rect.Width == 0 || ret_rect.Height == 0) { //到参数中去取单个宽 double d_onefilesize_width = Convert.ToDouble(((Dictionary)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]); //然后再用单个宽去计算出高是多少 double d_onefilesize_height = 0; if (d_onefilesize_width != 0) d_onefilesize_height = (d_onefilesize_width / 4) * 3; ret_rect.Width = (int)d_onefilesize_width; ret_rect.Height = (int)d_onefilesize_height; } ///-----------because all the fields 's height/width=0.75 so here we make an enforce. gsp add at 2019/10/31 ///sometimes the gbfields are not conform to this for the cuting and merging operation. if (ret_rect.Height / ret_rect.Width != 0.75f) { ret_rect = new Rectangle(ret_rect.X, ret_rect.Y, ret_rect.Width, (int)(ret_rect.Width * 0.75f)); } return ret_rect; } #endregion #region 电镜操作相关方法 /// /// 连接电镜,分布图使用 /// public void Connection_ForDrawDistrbutionImageAndBSE() { string str1 = "分布图准备开始连接SEM电镜"; str1 = table["str1"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str1); if (!m_SEMConnectionState) { m_cfun = new COTSControlFunExport();//重新new一下试试呢,不New并不好用 It's better to reinitialize, but it's not good to uninitialize //和电镜建立通讯连接 m_SEMConnectionState = m_cfun.ConncetSem(); string str2 = "调用连接后状态"; str2 = table["str2"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str2 + ":--" + m_SEMConnectionState + "---"); ///获取当前电镜的ID号 m_SEM_ID = m_cfun.GetSemType(); string str3 = "获得电镜的ID"; str3 = table["str3"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str3 + ":--" + m_SEM_ID.ToString() + "---"); } else { //断开电镜连接 string str4 = "电镜是已经连接的状态,准备断开"; str4 = table["str4"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str4 + ":--" + m_SEMConnectionState + "---"); //if (m_cfun.DisConnectSem()) //{ // string str5 = "电镜是已经连接的状态,完成断开后状态"; // str5 = table["str5"].ToString(); // log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str5 + ":--" + m_SEMConnectionState + "---"); //} } } /// /// 连接电镜,排序图使用 /// public void Connection_ForDrawDistrbutionSortImage() { string str6 = "分布图准备开始连接SEM电镜"; str6 = table["str6"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str6); if (!m_SEMConnectionState) { m_cfun = new COTSControlFunExport();//重新new一下试试呢,不New并不好用 It's better to reinitialize, but it's not good to uninitialize //和电镜建立通讯连接 m_SEMConnectionState = m_cfun.ConncetSem(); string str7 = "调用连接后状态"; str7 = table["str7"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str7 + ":--" + m_SEMConnectionState + "---"); ///获取当前电镜的ID号 m_SEM_ID = m_cfun.GetSemType(); string str8 = "获得电镜的ID"; str8 = table["str8"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str8 + ":--" + m_SEM_ID.ToString() + "---"); } else { //断开电镜连接 string str9 = "电镜是已经连接的状态,准备断开"; str9 = table["str9"].ToString(); log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)str9:--" + m_SEMConnectionState + "---"); //if (m_cfun.DisConnectSem()) //{ // string str10 = "电镜是已经连接的状态,完成断开后状态"; // str10 = table["str10"].ToString(); // log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + str10 + ":--" + m_SEMConnectionState + "---"); //} } } /// /// 移动电镜到指定的X,Y坐标上,R坐标使用原先的值进行移动 /// /// /// public void MoveSemToPointXY_ForDrawDistrbutionImageAndBSE(double in_PositionX, double in_PositionY) { string str11 = "分布图准备开始移动电镜到"; str11 = table["str11"].ToString(); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str11); //首先获取电镜当前的位置,并记录原R值 double ls_PositionX = 0; double ls_PositionY = 0; double ls_PositionR = 0; if (m_SEMConnectionState) { m_cfun.GetSemPositionXY(ref ls_PositionX, ref ls_PositionY, ref ls_PositionR); string str12 = "获取原先电镜位置为X"; str12 = table["str12"].ToString(); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str12 + ":" + ls_PositionX.ToString() + " Y:" + ls_PositionY.ToString() + " R:" + ls_PositionR.ToString()); } else { string str13 = "获取电镜位置时状态错误"; str13 = table["str13"].ToString(); log.Error("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str13); } if (m_SEMConnectionState) { m_cfun.MoveSEMToPoint(in_PositionX, in_PositionY, ls_PositionR); string str14 = "移动电镜到指定位置"; str14 = table["str14"].ToString(); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str14 + ":" + in_PositionX.ToString() + " Y:" + in_PositionY.ToString() + " R:" + ls_PositionR.ToString()); } else { string str15 = "移动电镜时状态错误"; str15 = table["str15"].ToString(); log.Error("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str15); } } /// /// 移动电镜到指定的X,Y坐标上,R坐标使用原先的值进行移动 /// /// /// public void MoveSemToPointXY_ForDrawDistrbutionSortImage(double in_PositionX, double in_PositionY) { string str16 = "分布图准备开始移动电镜到"; str16 = table["str16"].ToString(); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str16); //首先获取电镜当前的位置,并记录原R值 double ls_PositionX = 0; double ls_PositionY = 0; double ls_PositionR = 0; if (m_SEMConnectionState) { string str17 = "获取原先电镜位置为X"; str17 = table["str17"].ToString(); m_cfun.GetSemPositionXY(ref ls_PositionX, ref ls_PositionY, ref ls_PositionR); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str17 + ":" + ls_PositionX.ToString() + " Y:" + ls_PositionY.ToString() + " R:" + ls_PositionR.ToString()); } else { string str18 = "获取电镜位置时状态错误"; str18 = table["str18"].ToString(); log.Error("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str18); } if (m_SEMConnectionState) { m_cfun.MoveSEMToPoint(in_PositionX, in_PositionY, ls_PositionR); string str19 = "移动电镜到指定位置"; str19 = table["str19"].ToString(); log.Trace("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str19 + ":" + in_PositionX.ToString() + " Y:" + in_PositionY.ToString() + " R:" + ls_PositionR.ToString()); } else { string str20 = "移动电镜时状态错误"; str20 = table["str20"].ToString(); log.Error("(MoveSemToPointXY_ForDrawDistrbutionImageAndBSE)" + str20); } } /// /// 断开电镜连接 /// public void DisConnectSEM_ForDrawDistrbutionImageAndBSE() { string str21 = "准备关闭电镜连接"; str21 = table["str21"].ToString(); log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str21); //if (m_cfun.DisConnectSem() == true) //{ // string str22 = "准备关闭电镜连接"; // str22 = table["str22"].ToString(); // log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str22); //} string str23 = "准备释放DLL"; str23 = table["str23"].ToString(); log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str23); m_cfun.FreeHardware(); m_SEMConnectionState = false; } /// /// 断开电镜连接 /// public void DisConnectSEM_ForDrawDistrbutionSortImage() { string str24 = "准备关闭电镜连接"; str24 = table["str24"].ToString(); log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str24); //if (m_cfun.DisConnectSem() == true) //{ // log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str24); //} string str25 = "准备释放DLL"; str25 = table["str25"].ToString(); log.Trace("(DisConnectSEM_ForDrawDistrbutionImageAndBSE)" + str25); m_cfun.FreeHardware(); m_SEMConnectionState = false; } /// /// 移动SEM电镜到XY坐标,总过程方法 /// /// /// public void MoveSemToXY_ForDrawDistrbutionImageAndBSE_Total(int PositionX, int PositionY) { //第一步,连接电镜 Connection_ForDrawDistrbutionImageAndBSE(); //第二步,移动到指定位置,先读取再设置 if (m_SEMConnectionState == true) { MoveSemToPointXY_ForDrawDistrbutionImageAndBSE(PositionX, PositionY); } //第三步,断开电镜连接 DisConnectSEM_ForDrawDistrbutionImageAndBSE(); } #endregion #region //--------------------------------------颗粒分布图相关部份--------------------------------------------------------------------- /// /// 传入颗粒的tagid和fieldid,来获取该颗粒下对应的xray数据 /// /// /// /// /// public void GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(int in_clr_tagid, int in_clr_fieldid, out uint[] Search_xray, out uint[] Analysis_xray, out int xray_id, out List list_celementchemistryclr) { Search_xray = new uint[2000]; Analysis_xray = new uint[2000]; xray_id = 0; list_celementchemistryclr = new List(); //防止为空校验判断 if (m_list_COTSFieldMgrClr == null) return; Particle particle = m_list_COTSFieldMgrClr.Find(x => x.FieldID == in_clr_fieldid).ParticleList.Find(x => x.ParticleId == in_clr_tagid); if (particle.XrayId > -1) { for (int i = 0; i < 2000; i++) { Analysis_xray[i] = BitConverter.ToUInt32(particle.XRayData, i * 4); } Search_xray = Analysis_xray; xray_id = particle.XrayId; list_celementchemistryclr = particle.ElementList; } } /// /// 传入所有的物理field坐标点,和单个物理field的宽高,返回所有field的左上角位置,和整个field组成的rect大小 /// /// /// /// /// public Rectangle GetWlRectTopLeftAndRect(List in_list_point, int in_width, int in_height) { //分别获取整个rect的xy最小值和最大值 int i_rect_x_min = 100000000; int i_rect_y_min = 100000000; int i_rect_x_max = -100000000; int i_rect_y_max = -100000000; for (int i = 0; i < in_list_point.Count; i++) { if (i_rect_x_min > in_list_point[i].X) i_rect_x_min = in_list_point[i].X; if (i_rect_y_min > in_list_point[i].Y) i_rect_y_min = in_list_point[i].Y; if (i_rect_x_max < in_list_point[i].X) i_rect_x_max = in_list_point[i].X; if (i_rect_y_max < in_list_point[i].Y) i_rect_y_max = in_list_point[i].Y; } Rectangle ret_rect = new Rectangle(i_rect_x_min, i_rect_y_min, i_rect_x_max - i_rect_x_min, i_rect_y_max - i_rect_y_min); return ret_rect; } /// /// 根据Field的ID,来获取Field列表中对应FIeld的OTS 坐标 /// /// /// public Point GetOTSPointByFieldID(List in_list_dfield, int in_fieldid) { Point ret_point = new Point(0, 0); for (int i = 0; i < in_list_dfield.Count; i++) { //这里TagID先代表的是底层返回的ID if (in_list_dfield[i].FieldID == in_fieldid.ToString()) { ret_point = new Point(Convert.ToInt32(in_list_dfield[i].OTS_RECT.X), Convert.ToInt32(in_list_dfield[i].OTS_RECT.Y)); } } return ret_point; } /// /// 将OTS坐标转换为Sem 坐标 /// /// /// public Point ChangeOTSToSemCoord(Point POTSCoord) { //first if m_semstagedata is null to get stage inforation Convert.ToDouble(((Dictionary)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]); //after obtaining stage info,calc stage point data Point ret_SEM_point = new Point(); // get center point, um long xStart = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["start"]); long xEnd = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["end"]); long xCenter = (xStart + xEnd) / 2; long yStart = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["start"]); long yEnd = Convert.ToInt64(((Dictionary)((Dictionary)((Dictionary)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["end"]); long yCenter = (yStart + yEnd) / 2; // delte = SEM - OTSa long deltex = xCenter - 0; long deltey = yCenter - 0; int xdir = Convert.ToInt32(((Dictionary)resultFile.ResultInfo["SEMStageData"])["xAxisDir"]); int ydir = Convert.ToInt32(((Dictionary)resultFile.ResultInfo["SEMStageData"])["yAxisDir"]); if (xdir == (int)OTS_X_AXIS_DIRECTION.LEFT_TOWARD) { ret_SEM_point.X = -1 * (POTSCoord.X - Convert.ToInt32(deltex)); } else if (xdir == (int)OTS_X_AXIS_DIRECTION.RIGHT_TOWARD) { ret_SEM_point.X = POTSCoord.X + Convert.ToInt32(deltex); } if (ydir == (int)OTS_Y_AXIS_DIRECTION.UP_TOWARD) { ret_SEM_point.Y = POTSCoord.Y + Convert.ToInt32(deltey); } else if (ydir == (int)OTS_Y_AXIS_DIRECTION.DOWN_TOWARD) { ret_SEM_point.Y = -1 * (POTSCoord.Y - Convert.ToInt32(deltey)); } return ret_SEM_point; } /// /// 获取组整个获取分布图和排序图图像数据的底层数据组建方式,的总过程 /// public void GetDistrbutionImageAndBSE_Total() { string str27 = "开始从底层加载数据...."; str27 = table["str27"].ToString(); m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(1, str27); //对底层加载速度进行计时 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); string path = resultFile.FilePath; FieldData fieldData = new FieldData(path); List fieldlist = fieldData.GetFieldList(); //防止有时底层返回的Field的List是0,直接返回 if (fieldlist.Count == 0) { string str28 = "底层返回视域数据数量为0...."; str28 = table["str28"].ToString(); m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(100, str28); return; } //底层加载field对象结束 stopwatch.Stop(); TimeSpan timespan = stopwatch.Elapsed; //重置计数器,对组建和计算图像进行计时 stopwatch.Reset(); stopwatch.Start(); string str29 = "开始组建图像视域...."; str29 = table["str29"].ToString(); m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(15, str29); //将field的list对象给全局变量中,供后面获取xray使用,不需要再次重新加载数据,以提升速度 m_list_COTSFieldMgrClr = fieldlist; //第一次循环,用来计算单个Field的像素分辨率,和将所有的物理位置存放到List当中 List list_point = new List(); int i_field_width = 0, i_field_height = 0; //获取到该field的分辨率大小,循环中都是一样的 if (fieldlist.Count > 0) { Bitmap bitmp = DrawFuncation.ReadImageFile(fieldlist[0].FieldImage); i_field_width = bitmp.Width; i_field_height = bitmp.Height; } for (int i = 0; i < fieldlist.Count(); i++) { //然后取出物理坐标,这个一会要与分辨率坐标进行变算一下 Point ls_point = new Point() { X = fieldlist[i].FieldPosX, Y = fieldlist[i].FieldPosY }; list_point.Add(ls_point); } //对单个视域的屏幕像素宽高,进行记录 m_Control_DrawDistrbutionImageAndBSE.m_OneField_Screen_BackRectf = new RectangleF(0, 0, i_field_width, i_field_height); //获取单个OTS视域像素宽高,并进行记录 Rectangle OTS_FieldRect = GetOneFieldWidthAndHeight(list_point); m_Control_DrawDistrbutionImageAndBSE.m_OneField_OTS_Rectf = OTS_FieldRect; //计算出整个绘制图像总Rectagnle的大小 m_Control_DrawDistrbutionImageAndBSE.m_backrectf = ConvertAndGetMaxRect(list_point, i_field_width, i_field_height); string str30 = "计算标尺...."; str30 = table["str30"].ToString(); //更新进度条提示 m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(18, str30); #region //标尺相关------------------------------------------------------------------------------ //在此处通过上面的i_field_width,ifield_height和list_point,来计算出个像素与实际物理值的比例 Rectangle ls_jsblrect = GetOneFieldWidthAndHeight(list_point); //然后用宽度来除以i_field_width 获取单个的像素比例 double d_onepixel_scale = Convert.ToDouble(ls_jsblrect.Width) / Convert.ToDouble(i_field_width); //再用该比例对标尺进行相应的赋值 m_Control_DrawDistrbutionImageAndBSE.m_f_onepixel_size = (float)d_onepixel_scale; //对整个物理像素的范围进行获取与设置 Rectangle ls_offsetandtopleftrect = GetWlRectTopLeftAndRect(list_point, ls_jsblrect.Width, ls_jsblrect.Height); m_Control_DrawDistrbutionImageAndBSE.m_back_wl_rectf = new RectangleF(ls_offsetandtopleftrect.X, ls_offsetandtopleftrect.Y , ls_offsetandtopleftrect.Width, ls_offsetandtopleftrect.Height); #endregion //--------------------------------------------------------------------------------------- string str31 = "组建整图数据...."; str31 = table["str31"].ToString(); //更新进度条提示 m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(20, str31); //70的进度条给到下面的循环中,计算进度条各分类进度分配 float ls_int_progresscalc = 0; if (fieldlist.Count > 0) ls_int_progresscalc = (float)70 / (float)fieldlist.Count; string str32 = "已完成第"; str32 = table["str32"].ToString(); string str33 = "个视域数据组建,共"; str33 = table["str33"].ToString(); string str34 = "个视域..."; str34 = table["str34"].ToString(); //再通过Field取到对应的Particle,循环一次 for (int i = 0; i < fieldlist.Count(); i++) { //更新进度条提示 m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(20 + (int)(ls_int_progresscalc * (i + 1)), str32 + i.ToString() + str33 + m_list_COTSFieldMgrClr.Count.ToString() + str34); //先获取该Field中的所有Particle List list_cotsparticleclr = new List(); list_cotsparticleclr = fieldlist[i].ParticleList; //取出该Field的物理坐标,将其转换成对应的屏幕像素坐标,屏幕左上角为原点(0,0)的偏移值,用于后面计算各Segment的位置使用 //应该也就是这里根据OTS坐标转换到屏幕像素坐标,Y轴是反的,所以在这里对从OTS坐标转换成屏幕坐标的地方进行反转! Point thisfield_point = new Point() { X = fieldlist[i].FieldPosX, Y = fieldlist[i].FieldPosY }; Point offset_point = GetFieldPhysicsConvertToScreen(list_point, i_field_width, i_field_height, thisfield_point); //保存该Field最终在屏幕上显示的位置及大小 DField df = new DField(); df.FieldID = fieldlist[i].FieldID.ToString(); df.Show_Rect = new Rectangle(offset_point, new Size(i_field_width, i_field_height)); df.Current_Rect = new Rectangle(offset_point, new Size(i_field_width, i_field_height)); df.OTS_RECT = new RectangleF(thisfield_point.X, thisfield_point.Y, OTS_FieldRect.Width, OTS_FieldRect.Height); m_Control_DrawDistrbutionImageAndBSE.m_list_dfield.Add(df); //然后将取出的数据,转换成Bitmap对象 Bitmap ls_bt = DrawFuncation.ReadImageFile(fieldlist[i].FieldImage); //再循环计算所有的Particle对象 foreach (Particle ls_cotsparticleclr in list_cotsparticleclr) { //从Clr中获取所有的Segment的List对象 List list_cotssegmentclr = new List(); list_cotssegmentclr = ls_cotsparticleclr.FeatureList; //创建颗粒分布图对应的类对象 List list_dsegment = new List(); //创建DParticle颗粒,保存与之对应的颗粒tagid和particleid,为了后面取xray数据及多选时获取多选cotsparticleclr列表 DParticle ls_dp = new DParticle(); ls_dp.CLRTagID = ls_cotsparticleclr.ParticleId; ls_dp.CLRFieldID = ls_cotsparticleclr.FieldId; ls_dp.STDTypeID = ls_cotsparticleclr.TypeId; ls_dp.TypeId = ls_cotsparticleclr.TypeId; ls_dp.TypeName = ls_cotsparticleclr.TypeName; ls_dp.XRayId = ls_cotsparticleclr.XrayId; ls_dp.SEMPosX = ls_cotsparticleclr.SEMPosX; ls_dp.SEMPosY = ls_cotsparticleclr.SEMPosY; //获取该颗粒在STD标准库中已分析出化合物对应的颜色 ls_dp.Color = GetColorBySTDTypeIDForBSEAndSorImage(ls_cotsparticleclr.TypeColor, ls_cotsparticleclr.TypeId); //防止超大颗粒,会让程序死掉 if (list_cotssegmentclr.Count < m_segment_overflownumber) { //再循环取出里面所有的segment foreach (Feature ls_cotssegmentclr in list_cotssegmentclr) { #region 创建DSegment对象,并将STD分析出的化合物颜色保存到DSegment对象中 //对Particle里的Segment进行偏移的计算等,创建了DSegment的大小 DSegment ds = new DSegment(); ds.Rect = new Rectangle(ls_cotssegmentclr.Start + offset_point.X, //i_field_height - ls_cotssegmentclr.GetHeight() + offset_point.Y,//这是让单个Field的图像按Y轴反过来 ls_cotssegmentclr.Height + offset_point.Y, ls_cotssegmentclr.Length, 1); ds.Color = ls_dp.Color;//将线的颜色对应到颗粒的颜色 #endregion #region //这里是在Field中,抠取出原BSE图像到DSegment中-------------------------------- //ls_bt.RotateFlip(RotateFlipType.Rotate180FlipX);//使用系统带的图像处理方法,进行Y轴的翻转,与上面记录位置对应 //合成图像完成,开始抠取像素----------------------------------------------------------------- int i_ls_length = ls_cotssegmentclr.Length; List ls_list_colors = new List(); for (int m = 0; m < i_ls_length; m++) { //这里实现一下代码保护 int lsjs_x = ls_cotssegmentclr.Start + m; //int lsjs_y = i_field_height - ls_cotssegmentclr.GetHeight();//这个反转要与上面对应 int lsjs_y = ls_cotssegmentclr.Height; if (lsjs_x < 0) lsjs_x = 0; if (lsjs_x >= i_field_width) lsjs_x = i_field_width - 1; if (lsjs_y < 0) lsjs_y = 0; if (lsjs_y >= i_field_height) lsjs_y = i_field_height - 1; //按理说这里应该加上个横向抠取像素颜色,这里需要再处理一下 ls_list_colors.Add(ls_bt.GetPixel(lsjs_x, lsjs_y)); } //保存原BSE图中的颜色列表 ds.List_Colors = ls_list_colors; #endregion //------------------------------------------------------------------------------ list_dsegment.Add(ds); //ls_bt.Dispose(); } } //设置Particle在0.5F倍数以上时才进行显示 ls_dp.Zoom_DisPlayMultiplier = 0.5f; ls_dp.Zoom_DisPlay = true; //将segment对应的设置到particle中 ls_dp.DSegments = list_dsegment; //并对DParticle相关信息进行计算 ls_dp.Rect = ls_dp.GetRectFromDSegment(); ls_dp.GPath = ls_dp.GetRegionFromDSegments(); ls_dp.SmallRect = ls_dp.GetSmallRectangleFromRect(); //将每个颗粒添加到颗粒分布图中的列表中 m_Control_DrawDistrbutionImageAndBSE.m_list_baseobject.Add(ls_dp); if (ls_dp.XRayId > -1) { m_Control_DrawDistrbutionImageAndBSE.m_list_usebject.Add(ls_dp); } } } string str35 = "转换分辨率..."; str35 = table["str35"].ToString(); //更新进度条相关显示 m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(90, str35); //然后这里还需要计算出,各field的宽和高,帧图边框分别需要显示多少个框 if (i_field_width != 0 && i_field_height != 0) { m_Control_DrawDistrbutionImageAndBSE.m_i_grid_showlinesnumber_width = Convert.ToInt32(m_Control_DrawDistrbutionImageAndBSE.BackRectF.Width / i_field_width); m_Control_DrawDistrbutionImageAndBSE.m_i_grid_showlinesnumber_height = Convert.ToInt32(m_Control_DrawDistrbutionImageAndBSE.BackRectF.Height / i_field_height); } string str36 = "完成其它工作..."; str36 = table["str36"].ToString(); //结束组建计算图像计数 stopwatch.Stop(); TimeSpan timespan2 = stopwatch.Elapsed; m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(95, str36); string str37 = "分钟 "; str37 = table["str37"].ToString(); string str38 = "秒 共("; str38 = table["str38"].ToString(); string str39 = ")毫秒"; str39 = table["str39"].ToString(); //相关计数 m_field_count = fieldlist.Count; m_particle_count = m_Control_DrawDistrbutionImageAndBSE.m_list_baseobject.Count; m_time_str = timespan.TotalMinutes.ToString("0.00") + str37 + timespan.TotalSeconds.ToString("0.00") + str38 + timespan.TotalMilliseconds.ToString() + str39; m_time_str2 = timespan2.TotalMinutes.ToString("0.00") + str37 + timespan2.TotalSeconds.ToString("0.00") + str38 + timespan2.TotalMilliseconds.ToString() + str39; } //读取进度条,虚拟读取,直接通过所有时域 void setPr(float ls_int_progresscalc, string str32, string str33, string str34) { for (int i = 0; i < m_list_COTSFieldMgrClr.Count; i++) { m_Control_DrawDistrbutionImageAndBSE.m_frm_userprogress.SetProgressValueAndText(20 + (int)(ls_int_progresscalc * (i + 1)), str32 + i.ToString() + str33 + m_list_COTSFieldMgrClr.Count.ToString() + str34); } } /// /// 分布图和BSE图中,从底层获取相关结果后,重新组织显示 /// /// public void GetDrawDistrbutionImageAndBSE_ByQuery(OTSIncAReportApp.OTSSampleReportInfo.OTSSampleMeaInfo sourceGridData) { var display = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 7); string display_type = display.itemVal.ToString(); int disinde = display.comboDownList.IndexOf(display_type); var list = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 10); string size = list.itemVal.ToString(); int inde = list.comboDownList.IndexOf(size); string size_cal_method_type = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 13).itemVal.ToString(); string con = ""; switch (size_cal_method_type) { case "DMAX": con = "DMAX"; break; case "DMIN": con = "DMIN"; break; case "Area": con = "Area"; break; case "FERET": con = "DFERET"; break; } string min = "0"; string max = "999"; if (inde != 0) { max = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 12).itemVal.ToString(); ; min = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 11).itemVal.ToString(); ; if (max.ToLower() == "max") { max = "999"; } } string path = resultFile.FilePath; ParticleData particleData = new ParticleData(path); List particles = particleData.GetParticleListByCon(con, max, min, disinde); foreach (DParticle ls_dp in m_Control_DrawDistrbutionImageAndBSE.m_list_baseobject) { int dis = 0; foreach (Particle particle in particles) { //找到对应的颗粒,将分类设置进去 if (ls_dp.CLRTagID == particle.ParticleId && ls_dp.CLRFieldID == particle.FieldId) { //这里居然添加进来了7个,原来是这里,在底层直接取出了6个相同的颗粒到一起。 ls_dp.ParticleFL = particle.TypeName; ls_dp.Operator = ParticleOperator.DISPLAY; dis = 1; break; } } if (dis == 0) { ls_dp.Operator = ParticleOperator.NODISPLAY; } } } #endregion #region //--------------------------------------颗粒排序图相关部份--------------------------------------------------------------------- /// /// 根据颗粒排序图获取已经选择上的颗粒,返回被选择上的颗粒的列表 /// /// public List GetSelectedParticleList_ForDrawDistrbutionSortImage() { List ls_list_cotsparticleclr = new List(); //防止为空校验判断 if (m_list_COTSFieldMgrClr == null) { return ls_list_cotsparticleclr; } //先取出,所有被选择的dparticle列表的 List ls_list_dp = new List(); foreach (SortParticleDistribution spd in m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution) { foreach (DParticle ls_dp in spd.List_DParticle) { if (ls_dp.Operator == ParticleOperator.SELECTED) { ls_list_dp.Add(ls_dp); } } } //并开始查找包含tagid和fieldid的cotsparticle的对象,保存到list当中 for (int i = 0; i < ls_list_dp.Count(); i++) { for (int j = 0; j < m_list_COTSFieldMgrClr.Count(); j++) { //先获取该field中的所有particle List list_cotsparticleclr = new List(); list_cotsparticleclr = m_list_COTSFieldMgrClr[j].ParticleList; for (int k = 0; k < list_cotsparticleclr.Count(); k++) { if (list_cotsparticleclr[k].ParticleId == ls_list_dp[i].CLRTagID && list_cotsparticleclr[k].FieldId == ls_list_dp[i].CLRFieldID) { //将cotsparticleclr保存到list当中 ls_list_cotsparticleclr.Add(list_cotsparticleclr[k]); } } } } return ls_list_cotsparticleclr; } /// /// 根据传入的fieldid和tagid返回该颗粒的OTS坐标 /// /// /// /// public Point GetOTSPointFromOld_list_sortparticledistribution(int in_fieldid, int in_tagid, Control_DrawDistrbutionSortImage in_control_drawdistrbutionsortimage) { Point ret_point = new Point(0, 0); if (m_list_COTSFieldMgrClr != null) { Field field = m_list_COTSFieldMgrClr.Find(x => x.FieldID == in_fieldid); ret_point = new Point() { X = field.FieldPosX, Y = field.FieldPosY }; } return ret_point; } /// /// 排序图获取底层数据,组建整张排序图的总方法过程 /// public void GetDistrbutionSortImage_Total() { string str48 = "开始从底层加载数据...."; str48 = table["str48"].ToString(); m_Control_DrawdistrbutionsortImage.m_frm_userprogress.SetProgressValueAndText(1, str48); string path = resultFile.FilePath; FieldData fieldData = new FieldData(path); List fieldlist = fieldData.GetFieldList(); //将field的list对象给全局变量中,供后面获取xray使用 m_list_COTSFieldMgrClr = fieldlist; string str49 = "开始组建图像资源...."; str49 = table["str49"].ToString(); m_Control_DrawdistrbutionsortImage.m_frm_userprogress.SetProgressValueAndText(15, str49); //第一次,用来计算,总大小等,获取Field的坐标,id,同时获取对应的ImgClr里的宽高,图像大小 List list_point = new List(); int i_field_width = 0, i_field_height = 0; //获取到该field的分辨率大小,循环中都是一样的 if (fieldlist.Count > 0) { Bitmap bitmp = DrawFuncation.ReadImageFile(fieldlist[0].FieldImage); i_field_width = bitmp.Width; i_field_height = bitmp.Height; } for (int i = 0; i < fieldlist.Count(); i++) { //然后取出物理坐标,这个一会要与分辨率坐标进行变算一下 Point ls_point = new Point() { X = fieldlist[i].FieldPosX, Y = fieldlist[i].FieldPosY }; list_point.Add(ls_point); } //对单个Field视域的屏幕像素宽高,进行记录 m_Control_DrawdistrbutionsortImage.m_OneField_Screen_BackRectf = new RectangleF(0, 0, i_field_width, i_field_height); //获取单个OTS视域像素宽高,并进行记录 Rectangle OTS_FieldRect = GetOneFieldWidthAndHeight(list_point); m_Control_DrawdistrbutionsortImage.m_OneField_OTS_Rectf = OTS_FieldRect; string str50 = "计算标尺...."; str50 = table["str50"].ToString(); m_Control_DrawdistrbutionsortImage.m_frm_userprogress.SetProgressValueAndText(18, str50); #region //标尺相关------------------------------------------------------------------------------ //在此处通过上面的i_field_width,ifield_height和list_point,来计算出个像素与实际物理值的比例 Rectangle ls_jsblrect = GetOneFieldWidthAndHeight(list_point); //然后用宽度来除以i_field_width 获取单个的像素比例 double d_onepixel_scale = Convert.ToDouble(ls_jsblrect.Width) / Convert.ToDouble(i_field_width); //再用该比例对标尺进行相应的赋值 m_Control_DrawdistrbutionsortImage.m_f_onepixel_size = (float)d_onepixel_scale; #endregion //--------------------------------------------------------------------------------------- string str51 = "组建整图数据...."; str51 = table["str51"].ToString(); m_Control_DrawdistrbutionsortImage.m_frm_userprogress.SetProgressValueAndText(20, str51); //70的进度条给到下面的循环中 float ls_int_progresscalc = 0; if (fieldlist.Count > 0) ls_int_progresscalc = (float)80 / (float)fieldlist.Count; string str52 = "已完成第"; str52 = table["str52"].ToString(); string str53 = "个数据,共"; str53 = table["str53"].ToString(); string str54 = "个数据..."; str54 = table["str54"].ToString(); //第二次,再通过Field取到对应的Particle,循环一次 for (int i = 0; i < fieldlist.Count(); i++) { m_Control_DrawdistrbutionsortImage.m_frm_userprogress.SetProgressValueAndText(20 + (int)(ls_int_progresscalc * (i + 1)), str52 + i.ToString() + str53 + m_list_COTSFieldMgrClr.Count.ToString() + str54); //先获取该field中的所有particle List list_cotsparticleclr = new List(); list_cotsparticleclr = fieldlist[i].ParticleList; //取出该Field中,从物理坐标转换到像素坐标后.不知道该算法是否可靠,先进行测试判断 Point offset_point = GetFieldPhysicsConvertToScreen(list_point, i_field_width, i_field_height, new Point() { X = fieldlist[i].FieldPosX, Y = fieldlist[i].FieldPosY }); //然后将取出的数据,转换成Bitmap对象 Bitmap ls_bt = DrawFuncation.ReadImageFile(fieldlist[i].FieldImage); //再循环取出所有的particle foreach (Particle ls_cotsparticleclr in list_cotsparticleclr) { List list_cotssegmentclr = new List(); list_cotssegmentclr = ls_cotsparticleclr.FeatureList; //创建颗粒分布图对应的类对象 List list_dsegment = new List(); //定义particle颗粒,并获取该颗粒与标准库中对应的颜色 DParticle ls_dp = new DParticle(); //ls_dp.Color = DrawFuncation.colorHx16toRGB(GetSTDItemClrByTypeIndex_ForDistrbutionSortImage(ls_cotsparticleclr.GetType()).GetColor()); ls_dp.CLRFieldID = ls_cotsparticleclr.FieldId; //为我封装的颗粒保存上,底层对应的FieldID ls_dp.CLRTagID = ls_cotsparticleclr.ParticleId; //为我封装的颗粒对象保存上,底层对应的TagID ls_dp.STDTypeID = ls_cotsparticleclr.TypeId; //为我封装的颗粒对象保存上,类型 ls_dp.TypeId = ls_cotsparticleclr.TypeId; ls_dp.TypeName = ls_cotsparticleclr.TypeName; ls_dp.XRayId = ls_cotsparticleclr.XrayId; ls_dp.SEMPosX = ls_cotsparticleclr.SEMPosX; ls_dp.SEMPosY = ls_cotsparticleclr.SEMPosY; ls_dp.Color = GetColorBySTDTypeIDForBSEAndSorImage(ls_cotsparticleclr.TypeColor, ls_cotsparticleclr.TypeId); //防止segment过多造成程序卡死 if (list_cotssegmentclr.Count < m_segment_overflownumber) //再循环取出里面所有的segment foreach (Feature ls_cotssegmentclr in list_cotssegmentclr) { //这里的坐标未转换 DSegment ds = new DSegment(); ds.Rect = new Rectangle(ls_cotssegmentclr.Start + offset_point.X, //i_field_height - ls_cotssegmentclr.GetHeight() + offset_point.Y, ls_cotssegmentclr.Height + offset_point.Y, ls_cotssegmentclr.Length, 1); //图像上下反了,翻转一下,上下翻转 //ls_bt.RotateFlip(RotateFlipType.Rotate180FlipX);//使用系统带的图像处理方法,进行x轴的翻转 //合成图像完成,开始抠取像素---------------------为显示BSE原图而用-------------------------------------------- int i_ls_length = ls_cotssegmentclr.Length; List ls_list_colors = new List(); for (int m = 0; m < i_ls_length; m++) { //这里实现一下代码保护 int lsjs_x = ls_cotssegmentclr.Start + m; //int lsjs_y = i_field_height - ls_cotssegmentclr.GetHeight(); int lsjs_y = ls_cotssegmentclr.Height; if (lsjs_x < 0) lsjs_x = 0; if (lsjs_x >= i_field_width) lsjs_x = i_field_width - 1; if (lsjs_y < 0) lsjs_y = 0; if (lsjs_y >= i_field_height) lsjs_y = i_field_height - 1; //按理说这里应该加上个横向抠取像素颜色,这里需要再处理一下 ls_list_colors.Add(ls_bt.GetPixel(lsjs_x, lsjs_y)); } //---------------------------------------------存入标准库相关的信息------------------------------------------------ ds.Color = ls_dp.Color;//将线的颜色对应到颗粒的颜色 //------------------------------------------------------------------------------------------------------ ds.List_Colors = ls_list_colors; list_dsegment.Add(ds); //ls_bt.Dispose(); } ls_dp.Zoom_DisPlayMultiplier = 0.5f; ls_dp.Zoom_DisPlay = true; ls_dp.DSegments = list_dsegment; //将segment对应的设置到particle中 //并对DParticle相关信息进行计算 ls_dp.Rect = ls_dp.GetRectFromDSegment(); ls_dp.GPath = ls_dp.GetRegionFromDSegments(); ls_dp.SmallRect = ls_dp.GetSmallRectangleFromRect(); //将每个颗粒添加到颗粒分布图中的列表中 m_Control_DrawdistrbutionsortImage.m_list_baseobject.Add(ls_dp); } } //--------------然后开始操作分布图定义的结构,接接所有的field,组成一个完整的image的rect大小,定义 } /// /// 根据type,从三种分类的分析库中提取当前分析物的颜色 /// /// /// /// public Color GetColorBySTDTypeIDForBSEAndSorImage(string in_cotssampleclr, int in_stdtypeid) { Color ret_c = new Color(); if (in_stdtypeid < 1000) { OTSSysSTDMgrClass osc = new OTSSysSTDMgrClass(); //小于1000,使用系统默认分类 ret_c = osc.GetColorByEnum(in_stdtypeid); } else if (in_stdtypeid >= 1000) { //大于等于1000,并且小于10000时,使用用户标准库来分析夹杂物名称 if (!in_cotssampleclr.Contains("#")) { ret_c = DrawFuncation.colorHx16toRGB("#" + in_cotssampleclr);//接收必须是#000000的格式 } else { ret_c = DrawFuncation.colorHx16toRGB(in_cotssampleclr);//接收必须是#000000的格式 } } return ret_c; } /// /// 颗粒排序图中的颗粒,重新组织显示颗粒排序规则 /// public void GetDistrbutionSortimage_ByQuery(OTSIncAReportApp.OTSSampleReportInfo.OTSSampleMeaInfo sourceGridData) { List FLNameList = new List(); //List FLID = new List() { -1,0, 1, 2, 4, 6, 7, 8, 9 }; List FLID = new List() { 0, 1, 2, 4, 6, 9, 10}; List NameList = new List(); int fltype = 0; //先清除list m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution.Clear(); m_Control_DrawdistrbutionsortImage.m_old_list_sortparticledistribution.Clear(); m_Control_DrawdistrbutionsortImage.m_f_zoom_record = 1; //------------------------------------分解结果内容部份------------------------------------ string display_type = ""; string con = ""; var list = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 4); string sort_type = list.itemVal.ToString(); int _type = list.comboDownList.IndexOf(sort_type); switch (_type) { case 0: fltype = 0; break; case 1: fltype = 1; break; case 2: fltype = 2; display_type = sourceGridData.SampleDataList.Find(s => Convert.ToInt32(s.iItemId) == 13).itemVal.ToString(); switch (display_type) { case "DMAX": con = "DMAX"; break; case "DMIN": con = "DMIN"; break; case "Area": con = "Area"; break; case "FERET": con = "DFERET"; break; } break; } string path = resultFile.FilePath; ParticleData particleData = new ParticleData(path); List particles = particleData.GetParticleListByCon("", "", "", 0); foreach (DParticle ls_dp in m_Control_DrawdistrbutionsortImage.m_list_baseobject) { int dis = 0; foreach (Particle particle in particles) { //找到对应的颗粒,将分类设置进去 if (ls_dp.CLRTagID == particle.ParticleId && ls_dp.CLRFieldID == particle.FieldId) { if (!FLNameList.Contains(particle.TypeName) && particle.TypeName != "") { FLNameList.Add(particle.TypeName); } if (fltype == 0) { ls_dp.ParticleFL = particle.TypeId.ToString(); } if (fltype == 1) { ls_dp.ParticleFL = particle.TypeName.ToString(); } if (fltype == 2) { if (con == "DMAX") ls_dp.ParticleFL = particle.DMAX.ToString(); if (con == "DMIN") ls_dp.ParticleFL = particle.DMIN.ToString(); if (con == "Area") ls_dp.ParticleFL = particle.Area.ToString(); if (con == "DFERET") ls_dp.ParticleFL = particle.FERET.ToString(); } ls_dp.Operator = ParticleOperator.DISPLAY; dis = 1; break; } } if (dis == 0) { ls_dp.Operator = ParticleOperator.NODISPLAY; } } if (fltype == 0) { //NameList = new List() { table["partcletype0"].ToString(), table["partcletype1"].ToString(), table["partcletype2"].ToString(), table["partcletype4"].ToString(), table["partcletype6"].ToString(), table["partcletype7"].ToString(), table["partcletype8"].ToString(), table["partcletype9"].ToString(), table["partcletype10"].ToString() }; NameList = new List() { table["partcletype0"].ToString(), table["partcletype1"].ToString(), table["partcletype2"].ToString(), table["partcletype4"].ToString(), table["partcletype6"].ToString(), table["partcletype9"].ToString(), table["partcletype10"].ToString() }; } if (fltype == 1) { NameList = FLNameList; } if (fltype == 2) { //获取粒级表 string flpath = m_Control_DrawdistrbutionsortImage.m_ReportApp.m_RptConfigFile.FileFolderSize + m_Control_DrawdistrbutionsortImage.m_ReportApp.m_RptConfigFile.PartSizeFile; DataSet ds = XMLoperate.GetXml(flpath); string sizestr = ds.Tables[0].Rows[0]["Sizes"].ToString(); List sizeList = new List(); for (int i = 0; i < sizestr.Split(',').Length - 1; i++) { if (sizestr.Split(',')[i].Length > 0) { double d1 = Convert.ToDouble(sizestr.Split(',')[i]); double d2 = Convert.ToDouble(sizestr.Split(',')[i + 1]); sizeList.Add(d1.ToString() + "~" + d2.ToString()); } } double d = Convert.ToDouble(sizestr.Split(',')[sizestr.Split(',').Length - 1]); sizeList.Add(d.ToString() + "~MAX"); NameList = sizeList; } //为颗粒排序图,创建分栏grid foreach (string name in NameList) { SortParticleDistribution sortparticledistribution = new SortParticleDistribution(); sortparticledistribution.RectF = new RectangleF(m_Control_DrawdistrbutionsortImage.ClientRectangle.X, m_Control_DrawdistrbutionsortImage.ClientRectangle.Y, 800, m_Control_DrawdistrbutionsortImage.ClientRectangle.Height); sortparticledistribution.ShowStr = name;//设置分类grid m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution.Add(sortparticledistribution); } //然后再重新将list_baseobject中的颗粒,分别添加到对应的sortgrid中 foreach (DParticle ls_dp in m_Control_DrawdistrbutionsortImage.m_list_baseobject) { var sort = m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution; for (int i = 0; i < sort.Count; i++) { if (fltype == 0) { if (ls_dp.STDTypeID == FLID[i]) { //将对应的颗粒添加到分栏grid中 DParticle sort_dp = ls_dp.Clone() as DParticle; sort_dp.Rect = sort_dp.GetRectFromDSegment(); sort[i].List_DParticle.Add(sort_dp); break; } else if (ls_dp.STDTypeID > 10000) { //将对应的颗粒添加到分栏grid中 DParticle sort_dp = ls_dp.Clone() as DParticle; sort_dp.Rect = sort_dp.GetRectFromDSegment(); sort[sort.Count - 1].List_DParticle.Add(sort_dp); break; } } else if (fltype == 1) { if (ls_dp.TypeName == NameList[i]) { //将对应的颗粒添加到分栏grid中 DParticle sort_dp = ls_dp.Clone() as DParticle; sort_dp.Rect = sort_dp.GetRectFromDSegment(); sort[i].List_DParticle.Add(sort_dp); break; } } else if (fltype == 2) { double min = Convert.ToDouble(NameList[i].Split('~')[0]); double max = 0; if (NameList[i].Split('~')[1].ToLower() != "max") { max = Convert.ToDouble(NameList[i].Split('~')[1]); } else { max = 999; } double size = Convert.ToDouble(ls_dp.ParticleFL); if (size <= max && size >= min) { //将对应的颗粒添加到分栏grid中 DParticle sort_dp = ls_dp.Clone() as DParticle; sort_dp.Rect = sort_dp.GetRectFromDSegment(); sort[i].List_DParticle.Add(sort_dp); break; } } } } //循环分栏grid,对各分栏grid进行摆放 for (int i = 0; i < m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution.Count(); i++) { //计算y轴,的增量 float ls_height = 0; if (i == 0) { ls_height = 0; } else { ls_height = m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i - 1].RectF.Y + m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i - 1].RectF.Height - 10; } m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i].RectF = new RectangleF( m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i].RectF.X, m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i].RectF.Y + ls_height, m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i].RectF.Width, m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution[i].GetSortGridHeight() + 50);//为每栏的高度增加了50补充,防止图像溢出 } //然后再重新对分栏grid中的颗粒,重新进行摆放 foreach (SortParticleDistribution ls_spd in m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution) { ls_spd.SortDParticle(m_Control_DrawdistrbutionsortImage.FZOOMRecord); } //最后,将分栏grid,分别存放到old的分栏grid中 foreach (SortParticleDistribution ls_sortparticledistribution in m_Control_DrawdistrbutionsortImage.m_list_sortparticledistribution) { SortParticleDistribution old_sortparticledistribution = ls_sortparticledistribution.Clone() as SortParticleDistribution; m_Control_DrawdistrbutionsortImage.m_old_list_sortparticledistribution.Add(old_sortparticledistribution); foreach (DParticle ls_dp in old_sortparticledistribution.List_DParticle) { ls_dp.Rect = ls_dp.GetRectFromDSegment(); } } } #endregion } }