123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
-
- 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.Drawing.Drawing2D;
- using System.Linq;
- namespace OTSIncAReportGraph.OTSIncAReportGraphFuncation
- {
- public class OTSImageDisHelp
- {
- #region 枚举定义
- /// <summary>
- /// 样品台X轴方向
- /// </summary>
- enum OTS_X_AXIS_DIRECTION
- {
- LEFT_TOWARD = 0,
- RIGHT_TOWARD = 1
- }
- /// <summary>
- /// 样品台Y轴方向
- /// </summary>
- enum OTS_Y_AXIS_DIRECTION
- {
- UP_TOWARD = 0,
- DOWN_TOWARD = 1
- }
- #endregion
- #region 定义变量
- private ResultFile resultFile = null;
-
-
-
- //记录field列表的原值
- public List<DisplayField> m_original_list_dfield = null;
- //记录原值,颗粒和线段
- public List<BaseObject> m_original_list_baseobject = null;
- NLog.Logger log;
- //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 = "";
-
- //电镜设置对象
- public ServiceInterface.SemController m_cfun = null;
- //是否已经连接到了电镜
- public bool m_SEMConnectionState = false;
- //连接到电镜的ID号
- public int m_SEM_ID = 0;
-
- #endregion
- #region 构造函数
-
- public OTSImageDisHelp( ResultFile result)
- {
- m_original_list_dfield = new List<DisplayField>();
- m_original_list_baseobject = new List<BaseObject>();
- resultFile = result;
- m_cfun =new ServiceInterface.SemController();
- log = NLog.LogManager.GetCurrentClassLogger();
- }
- #endregion
- #region 封装自定义方法
- public Point GetOTSCoordLeftBottomPoint(List<Point> allFldPos)
- {
- //the ots coordinate system is always positive on the right and up direction.So the leftbottom point would be the smallest point.
- //找出最小的x,y用来做偏移运算
- int i_offset_x = 1000000000;
- int i_offset_y = 1000000000;
- //先取出最小的x,y
- for (int i = 0; i < allFldPos.Count; i++)
- {
- if (i_offset_x > allFldPos[i].X)
- {
- i_offset_x = allFldPos[i].X;
- }
- if (i_offset_y > allFldPos[i].Y)
- {
- i_offset_y = allFldPos[i].Y;
- }
- }
- return new Point(i_offset_x, i_offset_y);
- }
-
- public Point ConvertPhysicalCoordinateToScreenCoord(Point otsleftBottomPoint,double pixelSize, Point currenFldPos)//ots coordinate equals to the physical coordinate.
- {
-
- var OTSPoint=new Point(currenFldPos.X - otsleftBottomPoint.X, currenFldPos.Y - otsleftBottomPoint.Y);
- var screenPoint = new Point((int)(Convert.ToDouble(OTSPoint.X)/pixelSize), (int)(Convert.ToDouble(OTSPoint.Y)/pixelSize));
- return screenPoint;
- }
- public Rectangle ConvertAndGetMaxRect(List<Point> inPoints, int in_width, int in_height)
- {
- //首先要能确定下来,单个物理坐标的宽和高--------------------------------
- int i_wl_width = 0;
- int i_wl_height = 0;
- RectangleF ls_r = GetPhysicalFieldWidthAndHeight(inPoints,in_width,in_height);
- i_wl_width = (int)ls_r.Width;
- i_wl_height = (int)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 < inPoints.Count(); i++)
- {
- Point ls_point = inPoints[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 (inPoints.Count > 0)
- {
- ret_rectangle = new Rectangle(0, 0, point_x_max, point_y_max);
- }
- //这样返回是物理坐标的总大小,应该返回像素坐标大小才对
- return ret_rectangle;
- }
- /// <summary>
- /// 计算单个field的物理大小 传入field的list,还有测量结果管理类对象,在无法计算出单field的物理大小的情况下,到这里取再计算得出
- /// </summary>
- /// <returns></returns>
- public RectangleF GetPhysicalFieldWidthAndHeight(List<Point> points,int imageWidth,int imageHeight)
- {
- int width_max = -10000000;
- int height_max = -10000000;
- int width_max2 = -10000000;
- int height_max2 = -10000000;
- //先找出最大的值,
- for (int i = 0; i < points.Count(); i++)
- {
- if (width_max < points[i].X)
- width_max = points[i].X;
- if (height_max < points[i].Y)
- height_max = points[i].Y;
- }
- //再找出第二大的值
- for (int i = 0; i < points.Count(); i++)
- {
- if (width_max2 < points[i].X && width_max != points[i].X)
- width_max2 = points[i].X;
- if (height_max2 < points[i].Y && height_max != points[i].Y)
- height_max2 = points[i].Y;
- }
- //需要针对第二大的值,获取时进行判断,感觉这里应该如果并未找到第二大的值的情况下,赋于0值,便于以后进行计算
- if (width_max2 == -10000000)
- width_max2 = 0;
- if (height_max2 == -10000000)
- height_max2 = 0;
- RectangleF ret_rect = new RectangleF(0, 0, width_max - width_max2, height_max - height_max2);
- //如果最后计算出的宽高有0则重新到测量数据中获取---------------------------------------
- if (ret_rect.Width == 0 || ret_rect.Height == 0)
- {
- //到参数中去取单个宽
- double d_scanFieldSize_width = Convert.ToDouble(((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]);
- //然后再用单个宽去计算出高是多少
- double d_scanFieldSize_height = 0;
- if (d_scanFieldSize_width != 0)
- d_scanFieldSize_height = (d_scanFieldSize_width / Convert.ToDouble(imageWidth)) * imageHeight;
- ret_rect.Width = (int)d_scanFieldSize_width;
- ret_rect.Height = (int)d_scanFieldSize_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 电镜操作相关方法
- /// <summary>
- /// 连接电镜,分布图使用
- /// </summary>
- public void ConnectToSEM()
- {
-
-
- log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + "Connect to SEM");
- if (!m_SEMConnectionState)
- {
- //和电镜建立通讯连接
- m_SEMConnectionState = m_cfun.Connect();
-
- log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + "Connect to SEM" + ":--" + m_SEMConnectionState + "---");
-
- }
- else
- {
-
- log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + ":allready connected, state:" + m_SEMConnectionState);
- //断开电镜连接
- }
- }
- public void DisConnectSEM()
- {
- m_SEMConnectionState = false;
- m_cfun.DisConnect();
- }
- /// <summary>
- /// 移动电镜到指定的X,Y坐标上,R坐标使用原先的值进行移动
- /// </summary>
- /// <param name="PositionX"></param>
- /// <param name="PositionY"></param>
- public void MoveSemToPointXY(double in_PositionX, double in_PositionY)
- {
-
- log.Trace("Begin MoveSemToPointXY:(" +in_PositionX.ToString()+","+in_PositionY.ToString()+")");
- //首先获取电镜当前的位置,并记录原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);
- }
- else
- {
- log.Error("Failed to GetSemPositionXY");
- return;
- }
- if (m_SEMConnectionState)
- {
- m_cfun.MoveSEMToPoint(new Point((int)in_PositionX, (int)in_PositionY), ls_PositionR);
- }
-
- }
-
-
- #endregion
- #region //--------------------------------------颗粒分布图相关部份---------------------------------------------------------------------
- /// <summary>
- /// 传入颗粒的tagid和fieldid,来获取该颗粒下对应的xray数据
- /// </summary>
- /// <param name="in_clr_tagid"></param>
- /// <param name="in_clr_fieldid"></param>
- /// <param name="Search_xray"></param>
- /// <param name="Analysis_xray"></param>
- 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<Element> list_celementchemistryclr)
- {
- Search_xray = new uint[2000];
- Analysis_xray = new uint[2000];
- xray_id = 0;
- list_celementchemistryclr = new List<Element>();
- //防止为空校验判断
- if (resultFile.List_OTSField == null)
- return;
- Particle particle = resultFile.List_OTSField.Find(x => x.FieldID == in_clr_fieldid).ParticleList.Find(x => x.ParticleId == in_clr_tagid);
- var tmpPart = new ParticleData(resultFile.FilePath).GetParticleXrayDataByFidAndPid(Convert.ToString(particle.FieldId), Convert.ToString(particle.XrayId));
- if (tmpPart != null)
- {
- particle.XRayData = tmpPart.XRayData;
- 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;
- }
- }
-
- }
- /// <summary>
- /// 传入所有的物理field坐标点,和单个物理field的宽高,返回所有field的左上角位置,和整个field组成的rect大小
- /// </summary>
- /// <param name="in_list_point"></param>
- /// <param name="in_width"></param>
- /// <param name="in_height"></param>
- /// <returns></returns>
- public Rectangle GetWlRectTopLeftAndRect(List<Point> 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;
- }
- /// <summary>
- /// 根据Field的ID,来获取Field列表中对应FIeld的OTS 坐标
- /// </summary>
- /// <param name="in_fieldid"></param>
- /// <returns></returns>
- public Point GetOTSPointByFieldID(List<DisplayField> 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].OTSCoordinatePos.X), Convert.ToInt32(in_list_dfield[i].OTSCoordinatePos.Y));
- }
- }
- return ret_point;
- }
- /// <summary>
- /// 将OTS坐标转换为Sem 坐标
- /// </summary>
- /// <param name="POTSCoord"></param>
- /// <returns></returns>
- public Point ChangeOTSToSemCoord(Point POTSCoord)
- {
- //first if m_semstagedata is null to get stage inforation
- Convert.ToDouble(((Dictionary<string, object>)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<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["start"]);
- long xEnd = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["end"]);
- long xCenter = (xStart + xEnd) / 2;
- long yStart = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["start"]);
- long yEnd = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)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<string, object>)resultFile.ResultInfo["SEMStageData"])["xAxisDir"]);
- int ydir = Convert.ToInt32(((Dictionary<string, object>)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;
- }
- #endregion
- /// <summary>
- /// 判断该点是否在多边形的范围内
- /// </summary>
- /// <param name="inPoints"></param>
- /// <param name="WhetherPoint"></param>
- /// <returns></returns>
- public bool WhetherInRange(DisplayParticle Part,/*PointF[] inPoints,*/ Point WhetherPoint)
- {
- var rect = Part.Rect;
- if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
- {
- var itm = (BaseObject)Part;
- itm.GPath = Part.GetRegionFromDSegments();
- PointF[] inPoints = itm.GPath.PathPoints;
- bool b_inrange = false;
- GraphicsPath myGraphicsPath = new GraphicsPath();
- Region myRegion = new Region();
- myGraphicsPath.Reset();
- myGraphicsPath.AddPolygon(inPoints);
- myRegion.MakeEmpty();
- myRegion.Union(myGraphicsPath);
- //返回判断点是否在多边形里
- b_inrange = myRegion.IsVisible(WhetherPoint);
- return b_inrange;
- }
- else
- {
- return false;
- }
- }
- public bool WhetherInRange(RectangleF rec,PointF[] inPoints, Point WhetherPoint)
- {
- var rect = rec;
- if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
- {
- //var itm = (BaseObject)Part;
- //PointF[] inPoints = itm.GPath.PathPoints;
- bool b_inrange = false;
- GraphicsPath myGraphicsPath = new GraphicsPath();
- Region myRegion = new Region();
- myGraphicsPath.Reset();
- myGraphicsPath.AddPolygon(inPoints);
- myRegion.MakeEmpty();
- myRegion.Union(myGraphicsPath);
- //返回判断点是否在多边形里
- b_inrange = myRegion.IsVisible(WhetherPoint);
- return b_inrange;
- }
- else
- {
- return false;
- }
- }
- /// <summary>
- /// 判断该点是否在多边形的范围内的float版本重载
- /// </summary>
- /// <param name="inPoints"></param>
- /// <param name="WhetherPoint"></param>
- /// <returns></returns>
- public bool WhetherInRange(DisplayParticle Part,/* PointF[] inPoints, */PointF WhetherPoint)
- {
- var rect = Part.Rect;
- if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
- {
- var itm = (BaseObject)Part;
- PointF[] inPoints = itm.GPath.PathPoints;
- bool b_inrange = false;
- GraphicsPath myGraphicsPath = new GraphicsPath();
- Region myRegion = new Region();
- myGraphicsPath.Reset();
- myGraphicsPath.AddPolygon(inPoints);
- myRegion.MakeEmpty();
- myRegion.Union(myGraphicsPath);
- //返回判断点是否在多边形里
- b_inrange = myRegion.IsVisible(WhetherPoint);
- return b_inrange;
- }
- else
- {
- return false;
- }
- }
-
-
-
-
-
- }
- }
|