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
}
}