//时间：20200610
//作者：郝爽
//功能：测量线程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;

using SmartSEMControl;
using MeasureData;
using FileManager;

namespace MeasureThread
{
    //图片模式
    public enum ImageMode
    {
        FIB,
        SEM
    }

    public delegate void ThreadStatusHandler(object sender, ThreadStatusEventArgs e);  //声明委托
    public delegate void CutHolesStatusHandler(object sender, CutHolesStatusEventArgs e);

    public class ThreadStatusEventArgs
    {
        //状态
        public string State
        {
            get { return m_state; }
            set { m_state = value; }
        }
        private string m_state;
        //时间
        public DateTime Time
        {
            get { return m_time; }
            set { m_time = value; }
        }
        private DateTime m_time;
        //步骤代码
        public String Step_Code
        {
            get { return step_Code; }
            set { step_Code = value; }
        }
        private String step_Code;
        //其他消息
        public String Message
        {
            get { return this.message; }
            set { this.message = value; }
        }
        private String message;

        //孔名
        public String HoleName
        {
            get { return this.holeName; }
            set { this.holeName = value; }
        }
        private String holeName;

        //图片信息
        public class PictureInformation
        {
            public String Picture_FullPath
            {
                get { return picture_FullPath; }
                set { picture_FullPath = value; }
            }
            private String picture_FullPath;

            public double Work_Voltage
            {
                get { return work_Voltage; }
                set { work_Voltage = value; }
            }
            private double work_Voltage;

            public double Magnification
            {
                get { return magnification; }
                set { magnification = value; }
            }
            private double magnification;

            public double Work_Distance
            {
                get { return work_Distance; }
                set { work_Distance = value; }
            }
            private double work_Distance;

            public String Work_Status
            {
                get { return work_Status; }
                set { work_Status = value; }
            }
            private String work_Status;
        }
        //图片信息实例类
        public PictureInformation Picture_Information
        {
            get { return picture_Information; }
            set { picture_Information = value; }
        }
        private PictureInformation picture_Information;

        //图像信息
        public class ImageInformation
        {
            public int Method_Name
            {
                get { return method_Name; }
                set { method_Name = value; }
            }
            private int method_Name;

            public Source_Img_Degree_Direction SIDD;
            public Cut_Position CP;
            public Cut_Success CS;
            public Trapezoid_Top_Center_Position TTCP;
            public Auto_Foucs AF;
            public Auto_Stigmatic AS;
            public Center_Position_OffsetAngle_Direction CPOD;
            public Measure_Size MS;

            public ImageInformation()
            {
                SIDD = new Source_Img_Degree_Direction();
                CP = new Cut_Position();
                CS = new Cut_Success();
                TTCP = new Trapezoid_Top_Center_Position();
                AF = new Auto_Foucs();
                AS = new Auto_Stigmatic();
                CPOD = new Center_Position_OffsetAngle_Direction();
                MS = new Measure_Size();
            }

            //1-计算原始图像偏移角度及方向
            public class Source_Img_Degree_Direction
            {
                public Boolean Is_Image = false;

                public double Degree
                {
                    get { return degree; }
                    set { degree = value; }
                }
                private double degree;

                public int Direction
                {
                    get { return direction; }
                    set { direction = value; }
                }
                private int direction;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;
            }

            //2-计算切割点位置
            public class Cut_Position
            {
                public Boolean Is_Image = false;

                public double Offsetx
                {
                    get { return offsetx; }
                    set { offsetx = value; }
                }
                private double offsetx;

                public double Offsety
                {
                    get { return offsety; }
                    set { offsety = value; }
                }
                private double offsety;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;
            }

            //3-是否切割成功
            public class Cut_Success
            {
                public Boolean Is_Image = false;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;

            }

            //4-计算切割后图像梯形区域上边中心点坐标
            public class Trapezoid_Top_Center_Position
            {
                public Boolean Is_Image = false;

                public double TopCenterX
                {
                    get { return topCenterX; }
                    set { topCenterX = value; }
                }
                private double topCenterX;

                public double TopCenterY
                {
                    get { return topCenterY; }
                    set { topCenterY = value; }
                }
                private double topCenterY;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;
            }

            //5-自动对焦
            public class Auto_Foucs
            {
                public Boolean Is_Image = true;

                public String Img_Path
                {
                    get { return img_Path; }
                    set { img_Path = value; }
                }
                private String img_Path;
            }

            //6-自动像闪
            public class Auto_Stigmatic
            {
                public Boolean Is_Image = true;

                public String Img_Path
                {
                    get { return img_Path; }
                    set { img_Path = value; }
                }
                private String img_Path;
            }

            //7-计算切割面区域中心坐标，以及偏移角度及方向
            public class Center_Position_OffsetAngle_Direction
            {
                public Boolean Is_Image = false; 

                public double CenterX
                {
                    get { return centerX; }
                    set { centerX = value; }
                }
                private double centerX;

                public double CenterY
                {
                    get { return centerY; }
                    set { centerY = value; }
                }
                private double centerY;

                public double Degree
                {
                    get { return degree; }
                    set { degree = value; }
                }
                private double degree;

                public int Direction
                {
                    get { return direction; }
                    set { direction = value; }
                }
                private int direction;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;
            }

            //8-测量尺寸
            public class Measure_Size
            {
                public Boolean Is_Image = false;

                public int State
                {
                    get { return state; }
                    set { state = value; }
                }
                private int state;
            }
        }
        //图像信息实例类
        public ImageInformation Image_Information
        {
            get { return image_Information; }
            set { image_Information = value; }
        }
        private ImageInformation image_Information;

        public ThreadStatusEventArgs(string a_State)
        {
            picture_Information = new PictureInformation();
            image_Information = new ImageInformation();
        }
    }

    public class CutHolesStatusEventArgs
    {
        public string State
        {
            get { return m_state; }
            set { m_state = value; }
        }
        private string m_state;

        public string HoleName
        {
            get { return m_holeName; }
            set { m_holeName = value; }
        }
        private string m_holeName;

        public CutHolesStatusEventArgs(string a_state, string a_holeName)
        {
            this.m_state = a_state;
            this.m_holeName = a_holeName;
        }
    }

    public class Measure
    {
        public event ThreadStatusHandler SendThreadStatus;  // 声明事件
        public event CutHolesStatusHandler SendCutHolesStatus;  // 声明事件

        //定义一个全局的消息类
        ThreadStatusEventArgs arg = new ThreadStatusEventArgs("0-0");

        //全局只有一个fatorySEM
        static FactoryHardware factorySEM = FactoryHardware.Instance;
        ISEMControl iSEM = factorySEM.ISEM;

        //@的作用是不用转义字符\\只打一个就行
        const String ImageName1 = @"ImageSEM600X.tif"; //传给客户，作水平校正
        const String ImageName2 = @"ImageFIB600X1.tif";//传给客户，找到切割点
        const String ImageName3 = @"ImageFIB600X2.tif";
        const String ImageName4 = @"ImageSEM300X.tif";//传给客户，找到已经切割点
        const String ImageName5 = @"ImageSEM6000X.tif";//传给客户，水平校正
        const String ImageName6 = @"ImageSEMMag.tif";//传给客户，测量层高

        const String MacoInsertPt = "GIS Insert.MLF"; //传入PT针
        const String MacoRetractPt = "GIS Retract.MLF"; //退出PT针
        const String MacoScanPic = "Scan picture.MLF";//一般质量抓图的宏
        const String MacoGoodPic = "Good picture.MLF";//高质量抓图的宏
        const String MacoExportTif = "Export TIFF.MLF";// 导出有标尺的图像，这个图像为使用工具SmartSEM工具的图像

        const String ElyDeposition = @"Deposition.ely"; //沉积
        const String ElyCrossSection = @"CrossSection.ely"; //切割

        const float fMin = (float)0.0000002; //单位是米

        int m_nWorkHoleNo = -1;

        //测量文件
        private MeasureFile m_measureFile;
        public MeasureFile MeasureFile
        {
            get { return this.m_measureFile; }
            set { this.m_measureFile = value; }
        }

        //测量的切割孔
        private List<MeasureData.CutHole> m_cutHoles;
        public List<MeasureData.CutHole> cutHoles
        {
            get { return this.m_cutHoles; }
            set { this.m_cutHoles = value; }
        }

        //工作文件夹
        private string m_WorkingFolder;
        public string WorkingFolder
        {
            get { return this.m_WorkingFolder; }
            set { this.m_WorkingFolder = value; }
        }

        //程序当前路径
        private string m_ProgramFolder = Directory.GetCurrentDirectory();

        //线程状态
        private ThreadStatus m_ThreadStatus;
        public ThreadStatus TStatus
        {
            get { return this.m_ThreadStatus; }
            set { this.m_ThreadStatus = value; }
        }

        //测量参数
        private MeasureParam m_MsParam;
        public MeasureParam MeasParam
        {
            get { return this.m_MsParam; }
            set { this.m_MsParam = value; }
        }

        //构造函数
        public Measure()
        {
            Init();
        }

        private void Init()
        {
            MeasParam = new MeasureParam();
            TStatus = new ThreadStatus();
            cutHoles = new List<MeasureData.CutHole>();
        }

        //初始化测量业务, 读测量文件，判断是否有可测试的切孔
        public bool InitMeas(MeasureFile a_measureFile)
        {
            m_measureFile = a_measureFile;
            List<CutHole> listHoles = m_measureFile.ListCutHole;

            foreach (CutHole h in listHoles)
            {
                if (h.SWITCH == true)
                {
                    m_cutHoles.Add(h);
                }
            }

            if (m_cutHoles.Count == 0)
                return false;

            this.m_MsParam = m_measureFile.MParam;

            return true;
        }

        public void SendMsg(string step_code)
        {
            arg.Step_Code = step_code;
            arg.Time = DateTime.Now;
            switch(step_code)
            {
                //拍照
                case "1-3":
                case "1-9":
                case "1-16":
                case "1-24":
                    //电压、放大倍数、工作距离、位置信息、图片路径
                    arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();
                    arg.Picture_Information.Work_Status = "SEM";
                    arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();
                    arg.Picture_Information.Magnification = iSEM.GetMagnification();
                    break;
                case "1-10":
                case "1-18":
                    //获取偏移信息
                    break;
                case "1-12":
                case "1-20":
                    //验证移动准备性
                    break;
                case "1-26":
                    //取消电子束校正并初始化
                    break;
                default:
                    arg.State = "1";
                    break;
            }
            SendThreadStatus(this, arg);
        }
        public void SendCutHoleMsg(string a_state, string a_holeName)
        {
            CutHolesStatusEventArgs arg = new CutHolesStatusEventArgs(a_state, a_holeName);
            arg.HoleName = a_holeName;
            arg.State = a_state;
            SendCutHolesStatus(this, arg);
        }
        //测量流程
        public void DoMeasure()
        {
            //创建线程的测量状态的更新
            this.TStatus.ComputeTime(THREAD_TIME_TYPE.START);

            if (SendThreadStatus != null)
            {
                SendMsg("开始测量。");
            }


            //检查硬件连接是否正常
            if (!ConnectHardware())
            {
                SendMsg("连接硬件失败。");
                this.TStatus.ComputeTime(THREAD_TIME_TYPE.STOPPED);
                return;
            }

            SendMsg("硬件连接成功。");

            //设置工作文件夹

            if (!SetWorkingFolderStr())
            {
                SendMsg("设置工作文件夹失败");
                this.TStatus.ComputeTime(THREAD_TIME_TYPE.STOPPED);
                return;
            }

            SendMsg("创建工作文件路径为" + WorkingFolder);

            float[] firstPosition;
            for (int i = 0; i < m_cutHoles.Count; i++)
            {
                m_nWorkHoleNo = i;
                arg.HoleName = cutHoles[m_nWorkHoleNo].HoleName;
                if (i == 0)
                {
                    SendMsg("第一个切孔开始测量");
                    //切孔操作-开始
                    SendCutHoleMsg(((int)ThreadState.InProcess).ToString(), m_cutHoles[i].HoleName);
                    firstPosition = iSEM.GetStagePosition();
                    //第一个孔的测试
                    FirstHole();
                    //切孔操作-完成
                    SendCutHoleMsg(((int)ThreadState.Success).ToString(), m_cutHoles[i].HoleName);
                }
                else
                {
                    //非第一个孔的测试
                    SendMsg("第" + i.ToString() + "个切孔开始测量");
                    //切孔操作-开始
                    SendCutHoleMsg(((int)ThreadState.InProcess).ToString(), m_cutHoles[i].HoleName);
                    OtherHole();
                    //切孔操作-完成
                    SendCutHoleMsg(((int)ThreadState.Success).ToString(), m_cutHoles[i].HoleName);
                }
            }


        }

        //检查硬件连接是否正常
        public bool ConnectHardware()
        {
            //返回硬件的连接状态
            return iSEM.ConnectStatus();
        }

        //设置工作文件夹
        public bool SetWorkingFolderStr()
        {

            WorkingFolder = m_measureFile.FilePath;

            return true;
            ////获取工作文件路径
            //string pathName = m_measureFile.FilePath;

            ////判断工作文件路径是否为空或无效
            //if (string.IsNullOrEmpty(pathName))
            //{
            //    SendMsg("路径无效");
            //    return false;
            //}
            ////文件未保存
            //else if (pathName.CompareTo(MeasureFile.UNTITLED_FILE_NAME) == 0)
            //{
            //    SendMsg("工程文件未保存");
            //    return false;
            //}

            ////获取工作文件所在文件夹
            //string folder = System.IO.Path.GetDirectoryName(pathName);
            //if (string.IsNullOrEmpty(folder))
            //{
            //    SendMsg("工程文件无效");
            //    return false;
            //}

            //WorkingFolder += @"\\";

            //LogManager.Init(WorkingFolder);

            //return false;
        }

        //插入PT针
        public bool InsertPT()
        {
            string fn = m_ProgramFolder + "\\Macro\\" + MacoInsertPt;
            SendMsg("调用宏插入PT针宏文件" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(1000);
            return true;
        }

        //撤出PT针
        public bool RetractPT()
        {
            string fn = m_ProgramFolder + "\\Macro\\" + MacoRetractPt;
            SendMsg("调用宏撤出PT针宏文件" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(1000);
            return true;
        }

        //PT沉积
        public bool PTWork()
        {
            //执行PT沉积的ELY文件
            string fn = m_ProgramFolder + "\\Macro\\" + ElyDeposition;
            SendMsg("执行PT沉积Ely文件:" + fn);
            if (!ExcuteEly(fn))
            {
                return false;
            }

            //等待沉积完成
            while (true)
            {
                Thread.Sleep(10000);
                if (iSEM.GetFIBMode() == 0)
                {
                    break;
                }
            }
            return true;
        }

        //FIB切割
        public bool FIBWork()
        {
            //执行PT沉积的ELY文件
            string fn = m_ProgramFolder + "\\Macro\\" + ElyCrossSection;
            SendMsg("执行FIB切割Ely文件:" + fn);
            if (!ExcuteEly(fn))
            {
                return false;
            }

            //等待切割完成
            while (true)
            {
                Thread.Sleep(10000);
                if (iSEM.GetFIBMode() == 0)
                {
                    break;
                }
            }

            return true;
        }

        public bool ExcuteEly(string a_filename)
        {
            //执行ELy文件有三个动作
            //1. 选择ELY文件
            SendMsg("选择ELY文件");
            if (!iSEM.CmdFIBLoadELY(a_filename))
            {
                SendMsg("选择ELY文件失败");
                return false;
            }
            Thread.Sleep(1000);
            //2. 确认ELY文件
            SendMsg("确认ELY文件");
            if (!iSEM.CmdFIBEXPOSUREELY())
            {
                SendMsg("确认ELY文件失败");
                return false;
            }
            Thread.Sleep(1000);
            //3. 执行ELY文件
            SendMsg("执行ELY文件");
            if (!iSEM.CmdFIBSTARTELY())
            {
                SendMsg("执行ELY文件失败");
                return false;
            }
            Thread.Sleep(1000);

            return true;
        }
        /// <summary>
        ///13. 自动 定位功能
        /// </summary>
        /// <returns></returns>
        public bool GetPoistion()
        {
            //SendMsg("自动定位");
            //13.自动定位切割
            {
                //1.控制SEM放大600X
                if (!iSEM.SetMagnification(m_measureFile.MParam.Photograph_Magnification))
                {
                    return false;
                }
                arg.Message = "放大600倍";
                SendMsg("1-1");

                //2.控制SEM自动对焦、亮度、对比度
                // if (!MeasParam.FocusMode)
                {
                    if (DialogResult.Yes == MessageBox.Show("图像自动对焦已完成？", "确认消息", MessageBoxButtons.YesNo))
                    {
                        arg.Message = "自动对焦完成";
                        SendMsg("1-2");
                        //return true;
                    }
                    else
                    {
                        arg.Message = "自动对焦失败";
                        SendMsg("1-2");
                        return false;
                    }
                    //弹出手动对焦的窗口
                }
                //else
                //{
                //    //调用自动对焦模块
                //}

                //3.设置SEM进行角度补偿54度
                //if (!TiltCorrection(54))
                //{
                //    SendMsg("设置SEM进行角度补偿54度");
                //    return false;
                //}
                //arg.Message = "设置校正54度";
                //SendMsg("1-15");
                //Thread.Sleep(5000);

                //4.控制SEM拍照
                
                //5.保存照片
                {
                    //1. 创建目录，已经完成
                    //2. 设置图片名称
                    //3. 保存图片1
                    WorkingFolder = m_measureFile.FilePath;
                    String fileName1 = WorkingFolder + "\\" + m_nWorkHoleNo.ToString() + "Hole" + ImageName1;
                    arg.Picture_Information.Picture_FullPath = fileName1;
                    if (!GetImage(ImageMode.SEM, fileName1))
                    {
                        arg.Message = "SEM拍照失败";
                        SendMsg("1-3");
                        return false;
                    }
                    arg.Message = "SEM拍照成功";
                    SendMsg("1-3");
                    Thread.Sleep(3000);
                }
                
                //6.设置FIB拍照参数——扫描时间、束流等
                //7.控制FIB自动亮度、对比度
                SendMsg("切换FIB控制");
                if (!iSEM.CmdFIBModeFIB())
                {
                    SendMsg("FIB模式切换失败");
                    return false;
                }

                Thread.Sleep(10000);

                //8.控制FIB拍照
                //9.保存照片
                SendMsg("FIB拍照");
                {
                    //1. 设置图片名称
                    //2. 保存图片2
                    String fileName2 = WorkingFolder + "\\" + m_nWorkHoleNo.ToString() + "Hole" + ImageName2;
                    if (!GetImage(ImageMode.FIB, fileName2))
                    {
                        SendMsg("FIB拍照失败");
                        return false;
                    }

                    Thread.Sleep(3000);
                }

                //10.将照片传给客户，返回梯形位置坐标，及样品类型参数（是否需要PT沉积，PT坐标位置，PT宽度、PT高度、梯形上、下边及深度、扫描时间、束流、样品放大倍数1、样品放大倍数2等切割参数）
                SendMsg("调用识别位置");

                if (DialogResult.Yes == MessageBox.Show("移动已完成？", "确认消息", MessageBoxButtons.YesNo))
                {
                    SendMsg("移动已完成");
                    //return true;
                }
                else
                {
                    SendMsg("移动已失败");
                    return false;
                }


                SendMsg("进行PT沉积");
                //11.自动工具样品类型参数确定是否需要PT沉积
                {
                    //1. 根据客户PT沉积坐标控制FIB调整到中心位置
                    //2. 验证移动准确性：获取当前FIB中心位置坐标，与客户返回坐标对比，验证是否一定正确
                    //3. 根据坐标进行PT沉积   
                    if (!PTWork())
                    {
                        SendMsg("PT沉积失败");
                        return false;
                    }


                }


                return true;
                //模拟为客户返回的坐标值
                float x0 = 0, y0 = 0;
                SendMsg("移动到新(" + x0.ToString() + "," + y0.ToString() + ")位置失败");

                //12.根据梯形坐标控制FIB调整到中心位置
                if (!iSEM.MoveStageXY(x0, y0))
                {
                    SendMsg("移动到新(" + x0.ToString() + "," + y0.ToString() + ")位置失败");
                    return false;
                }

                //电镜移动是有一个延时的操作的？

                //13.验证移动准确性：获取当前FIB中心位置坐标，与客户返回坐标对比，验证是否移动正确
                float x1 = iSEM.GetStageAtX();
                float y1 = iSEM.GetStageAtY();
                if (Math.Abs(x0 - x1) > fMin && Math.Abs(y0 - y1) > fMin)
                {
                    SendMsg("目标位置(" + x0.ToString() + "," + y0.ToString() + ")移动失败");
                    return false;
                }

                //14.保存样品1第1号孔中心位置6轴坐标1 XYZMRT到数据库，保存客户返回值信息到数据库
                float[] firstPosition = iSEM.GetStagePosition();
                //这里要调用文件保存功能
                SendMsg("坐标1(" + firstPosition[0].ToString() + ","
                    + firstPosition[1].ToString() + ","
                    + firstPosition[2].ToString() + ","
                    + firstPosition[3].ToString() + ","
                    + firstPosition[4].ToString() + ","
                    + firstPosition[5].ToString() + ")");
            }

            return false;
        }

        /// <summary>
        /// 14. FIB切割
        /// </summary>
        /// <returns></returns>
        public bool FIBCross()
        {
            //14.自动控制FIB切割
            {
                //1.根据参数设置FIB草率时间（使图清晰），设置梯形上下边及深度、设置束流
                //2.控制FIB进行切割
                SendMsg("FIB切割");
                if (!FIBWork())
                {
                    SendMsg("FIB切割失败");
                    return false;
                }

                Thread.Sleep(5000);

                //3.控制FIB拍照600X
                //4.保存图片
                {
                    //1.设置图片名称
                    //2.保存图片3
                    WorkingFolder = m_measureFile.FilePath;
                    String fileName3 = WorkingFolder + "\\" + m_nWorkHoleNo.ToString() + "Hole" + ImageName3;
                    SendMsg("SEM拍照存储到" + fileName3);
                    if (!GetImage(ImageMode.FIB, fileName3))
                    {
                        SendMsg("FIB拍照失败");
                        return false;
                    }

                    Thread.Sleep(3000);
                }
                //5.验证切割准确性：与切割前对比，如果对比误差大，则停止自动执行，进行报警

                //6.设置FIB解冻：先读取状态，如果冻结状态则进行解冻
            }
            return true;
        }

        /// <summary>
        /// 16.自动调整SEM找到切割位置，这里不是简单的拉直旋转
        /// </summary>
        /// <returns></returns>
        public bool FindCross()
        {
            //16.自动调整SEM找到切割位置
            {
                //1.控制SEM放大到300倍
                if (!iSEM.SetMagnification(300))
                {
                    return false;
                }
                //2.控制SEM自动对焦、亮度、对比度-接口
                if (!MeasParam.FocusMode)
                {
                    //弹出手动对焦的窗口
                }
                else
                {
                    //调用自动对焦模块
                }

                Thread.Sleep(5000);

                //3.控制SEM拍照
                String fileName4 = WorkingFolder + ImageName4;
                if (!GetImage(ImageMode.SEM, fileName4))
                {
                    return false;
                }

                Thread.Sleep(3000);
                //4.将照片传给客户，获取偏移坐标，以及偏移角度
                float x4 = 0, y4 = 0;
                float angle = 0;

                //5.根据坐标控制SEM移动到切孔位置，居中
                if (!iSEM.MoveStageXY(x4, y4))
                {
                    return false;
                }

                if (!iSEM.SetScanRotation(angle))
                {
                    return false;
                }

                ////6.验证移动准确性：获取当前SEM中心位置坐标，与客户返回坐标对比，验证是否移动正确
                //float x5 = iSEM.GetStageAtX();
                //float y5 = iSEM.GetStageAtY();
                //if (Math.Abs(x5 - x4) > fMin && Math.Abs(y5 - y4) > fMin)
                //{
                //    return false;
                //}
            }
            return true;
        }

        public bool CommonWork()
        {
            SendMsg("插入PT针");
            //12.根据样品类型参数确定是否需要PT沉积，控制PT针插入
            //if (firstHole.PT == true)
            {
                if (!InsertPT())
                {
                    SendMsg("插入PT针失败");
                    return false;
                }
            }

            //13. 自动 定位功能
            SendMsg("自动定位切割位置");
            if (!GetPoistion())
            {
                SendMsg("自动定位切割位置失败");
                return false;
            }

            //14.自动控制FIB切割
            SendMsg("FIB切割");
            if (!FIBCross())
            {
                SendMsg("FIB切割失败");
                return false;
            }
            //{
            //    //1.根据参数设置FIB草率时间（使图清晰），设置梯形上下边及深度、设置束流
            //    //2.控制FIB进行切割

            //    //3.控制FIB拍照600X
            //    //4.保存图片
            //    {
            //        //1.设置图片名称
            //        //2.保存图片3
            //        String fileName3 = WorkingFolder + ImageName3;
            //        if (!GetImage(ImageMode.FIB, fileName3))
            //        {
            //            return false;
            //        }
            //    }
            //    //5.验证切割准确性：与切割前对比，如果对比误差大，则停止自动执行，进行报警

            //    //6.设置FIB解冻：先读取状态，如果冻结状态则进行解冻
            //}
            //15.根据样品类型决定是否撤出PT针
            SendMsg("撤出PT针");
            //if (firstHole.PT == false)
            //{
            if (!RetractPT())
            {
                SendMsg("撤出PT针失败");
                return false;
            }
            //}

            // 16.找到切割位置
            SendMsg("找到切割位置");

            //17.自动控制SEM拍截面照
            SendMsg("观测层高");

            SendMsg("切换SEM控制");
            if (!iSEM.CmdFIBModeSEM())
            {
                SendMsg("SEM模式切换失败");
                return false;
            }

            Thread.Sleep(10000);

            SendMsg("放大6000倍");
            if (!iSEM.SetMagnification(6000))
            {
                SendMsg("放大倍数调整失败");
                return false;
            }

            if (DialogResult.Yes == MessageBox.Show("图像拍摄已完成？", "确认消息", MessageBoxButtons.YesNo))
            {
                SendMsg("拍摄照片完成");
                //return true;
            }
            else
            {
                SendMsg("拍摄照片失败");
                return false;
            }

            SendMsg("图像校正36度");
            //3.设置SEM角度补偿cos36度
            if (!TiltCorrection(36))
            {
                return false;
            }

            Thread.Sleep(3000);

            string fn;
            //用宏抓一般图

            Thread.Sleep(5000);
            fn = m_ProgramFolder + "\\Macro\\" + MacoScanPic;
            SendMsg("用宏抓一般图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(5000);

            //用宏抓好图
            fn = m_ProgramFolder + "\\Macro\\" + MacoGoodPic;
            SendMsg("用宏抓好图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(30000);

            Thread.Sleep(10000);

            WorkingFolder = m_measureFile.FilePath;
            String fileName6 = WorkingFolder + "\\" + m_nWorkHoleNo.ToString() + "Hole" + ImageName6;
            SendMsg("SEM拍照存储到" + fileName6);
            if (!GetImage(ImageMode.SEM, fileName6))
            {
                SendMsg("SEM拍照失败");
                return false;
            }


            //用宏抓标志图
            fn = m_ProgramFolder + "\\Macro\\" + MacoExportTif;
            SendMsg("用宏抓标志图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(30000);

            //恢复简单抓图
            Thread.Sleep(5000);
            fn = m_ProgramFolder + "\\Macro\\" + MacoScanPic;
            SendMsg("用宏抓一般图" + fn);
            iSEM.CMDMCFFilename(fn);


            SendMsg("所有图结束");
            return true;
        }

        //第一个孔的测试过程
        public bool FirstHole()
        {
            MeasureData.CutHole firstHole = m_cutHoles[0];            
            SendMsg("插入PT针");
            //12.根据样品类型参数确定是否需要PT沉积，控制PT针插入
            //if (firstHole.PT == true)
            {
                if (!InsertPT())
                {
                    SendMsg("插入PT针失败");
                    return false;
                }
            }

            //13. 自动 定位功能
            SendMsg("自动定位切割位置");
            if (!GetPoistion())
            {
                SendMsg("自动定位切割位置失败");
                return false;
            }

            //14.自动控制FIB切割
            SendMsg("FIB切割");
            if (!FIBCross())
            {
                SendMsg("FIB切割失败");
                return false;
            }
            //{
            //    //1.根据参数设置FIB草率时间（使图清晰），设置梯形上下边及深度、设置束流
            //    //2.控制FIB进行切割

            //    //3.控制FIB拍照600X
            //    //4.保存图片
            //    {
            //        //1.设置图片名称
            //        //2.保存图片3
            //        String fileName3 = WorkingFolder + ImageName3;
            //        if (!GetImage(ImageMode.FIB, fileName3))
            //        {
            //            return false;
            //        }
            //    }
            //    //5.验证切割准确性：与切割前对比，如果对比误差大，则停止自动执行，进行报警

            //    //6.设置FIB解冻：先读取状态，如果冻结状态则进行解冻
            //}
            //15.根据样品类型决定是否撤出PT针
            SendMsg("撤出PT针");
            //if (firstHole.PT == false)
            //{
                if (!RetractPT())
                {
                    SendMsg("撤出PT针失败");
                    return false;
                }
            //}

            // 16.找到切割位置
            SendMsg("找到切割位置");

            //17.自动控制SEM拍截面照
            SendMsg("观测层高");

            SendMsg("切换SEM控制");
            if (!iSEM.CmdFIBModeSEM())
            {
                SendMsg("SEM模式切换失败");
                return false;
            }

            Thread.Sleep(10000);

            SendMsg("放大6000倍");
            if (!iSEM.SetMagnification(6000))
            {
                SendMsg("放大倍数调整失败");
                return false;
            }

            if (DialogResult.Yes == MessageBox.Show("图像拍摄已完成？", "确认消息", MessageBoxButtons.YesNo))
            {
                SendMsg("拍摄照片完成");
                //return true;
            }
            else
            {
                SendMsg("拍摄照片失败");
                return false;
            }

            SendMsg("图像校正36度");
            //3.设置SEM角度补偿cos36度
            if (!TiltCorrection(36))
            {
                return false;
            }

            Thread.Sleep(3000);

            string fn;
            //用宏抓一般图

            Thread.Sleep(5000);
            fn = m_ProgramFolder + "\\Macro\\" + MacoScanPic;
            SendMsg("用宏抓一般图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(5000);

            //用宏抓好图
            fn = m_ProgramFolder + "\\Macro\\" + MacoGoodPic;
            SendMsg("用宏抓好图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(30000);

            Thread.Sleep(10000);

            WorkingFolder = m_measureFile.FilePath;
            String fileName6 = WorkingFolder + "\\" + m_nWorkHoleNo.ToString() + "Hole" + ImageName6;
            SendMsg("SEM拍照存储到" + fileName6);
            if (!GetImage(ImageMode.SEM, fileName6))
            {
                SendMsg("SEM拍照失败");
                return false;
            }


            //用宏抓标志图
            fn = m_ProgramFolder + "\\Macro\\" + MacoExportTif;
            SendMsg("用宏抓标志图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(30000);

            Thread.Sleep(5000);
            fn = m_ProgramFolder + "\\Macro\\" + MacoScanPic;
            SendMsg("用宏抓一般图" + fn);
            iSEM.CMDMCFFilename(fn);
            //延时1s？？
            Thread.Sleep(5000);


            SendMsg("所有图结束");

            ////17.自动控制SEM拍截面照
            //{
            //    //1.控制SEM放大到指定参数大小范围，6000x
            //    if (!iSEM.SetMagnification(6000))
            //    {
            //        return false;
            //    }
            //    //2.控制SEM自动对焦、消像散、亮度、对比度
            //    if (!MeasParam.FocusMode)
            //    {
            //        //弹出手动对焦的窗口
            //    }
            //    else
            //    {
            //        //调用自动对焦模块
            //    }

            //    //3.设置SEM角度补偿cos36度
            //    if (!TiltCorrection(36))
            //    {
            //        return false;
            //    }

            //    //4.控制SEM拍照
            //    //5.保存照片4
            //    String fileName5 = WorkingFolder + ImageName5;
            //    if (!GetImage(ImageMode.SEM, fileName5))
            //    {
            //        return false;
            //    }
            //    //6.将照片传给客户，获取偏移坐标
            //    float x6 = 0, y6 = 0;
            //    float angle1 = 0;
            //    float mage = 10000;

            //    //7.根据坐标控制SEM移动到分析位置
            //    if (!iSEM.MoveStageXY(x6, y6))
            //    {
            //        return false;
            //    }
            //    //8.验证移动准确性：获取当前SEM中心位置坐标，与客户返回坐标对比，验证是否移动正确

            //    float x7 = iSEM.GetStageAtX();
            //    float y7 = iSEM.GetStageAtY();
            //    if (Math.Abs(x6 - x7) > fMin && Math.Abs(y6 - y7) > fMin)
            //    {
            //        return false;
            //    }

            //    //9.控制SEM平行校正，并记录校正前初始值
            //    float foldAnagle = iSEM.GetScanRotation();
            //    if (foldAnagle == float.NaN)
            //    {
            //        return false;
            //    }

            //    if (!iSEM.SetScanRotation(angle1))
            //    {
            //        return false;
            //    }

            //    //10.控制SEM放大到指定参数大小范围
            //    if (!iSEM.SetMagnification(mage))
            //    {
            //        return false;
            //    }

            //    //11.控制SEM自动对焦、消像散、亮度、对比度
            //    if (!MeasParam.FocusMode)
            //    {
            //        //弹出手动对焦的窗口
            //    }
            //    else
            //    {
            //        //调用自动对焦模块
            //    }


            //    //12.控制SEM对分析位置拍照
            //    String fileName6 = WorkingFolder + ImageName6;
            //    if (!GetImage(ImageMode.SEM, fileName6))
            //    {
            //        return false;
            //    }
            //    //13.保存照片
            //    //14.控制SEM取消电子束校正，回到初始值

            //    if (!iSEM.SetScanRotation(foldAnagle))
            //    {
            //        return false;
            //    }
            //}
            ////18.自动层高分析
            //{
            //    //1.获取SEM Pixel Size给客户传入参数
            //    if (iSEM.GetPixelSize() == float.NaN)
            //    {
            //        return false;
            //    }
            //    //2.将照片传给客户，客户进行层高分析（返回分析后的图像、相对坐标、分辨率、各层编号以及各层对应的层高数据），如果客户自行出分析报告则无需返回数据
            //}
            ////19.自动能谱分析
            //{
            //    //1. 确定能谱位置
            //    //2. 控制牛津打能谱
            //    //3. 能谱分析——面扫+线扫描
            //}

            return true;
        }

        //非第一个孔的测试过程
        public void OtherHole()
        {
            //for (int i = 1; i < m_cutHoles.Count; i++)
            //{
            SendMsg("当前切孔号为"+ m_nWorkHoleNo.ToString());
                CutHole currentHole = m_cutHoles[m_nWorkHoleNo];
                //1. 初始化
                {
                    //1. 设置FIB解冻：先读取状态，如果冻结则进行解冻
                    //读取图像冻结状态
                    float ffrozen = iSEM.GetImageFrozen();
                    if (ffrozen == float.NaN)
                    {
                        return;
                    }

                    if (DialogResult.Yes == MessageBox.Show("样品台可以旋转恢复到水平吗？", "确认消息", MessageBoxButtons.YesNo))
                    {
                        SendMsg("样品台恢复到水平");
                        //return true;
                    }
                    else
                    {
                        SendMsg("禁止样品台恢复到水平");
                        return;
                    }

                    //2. 调节样品1号孔的样品台6轴坐标
                    //3. 将样品1号孔坐标2存入数据库
                    //4. 控制样品台T轴归0，R轴变为坐标1、Z/M轴作为坐标2保存不变
                    if (!iSEM.SetStageGotoT(0))
                    {
                        return;
                    }

                    while (true)
                    {
                        Thread.Sleep(10000);

                        if (iSEM.GetStageIs() == 0)
                        {
                            break;
                        }
                    }

                    //5. 获取光镜2号孔XY坐标
                    SendMsg("移动到"+m_nWorkHoleNo+"号孔位置:(" + currentHole.Position.X.ToString()+","+currentHole.Position.Y.ToString()+")");
                    
                    //6. 根据光镜坐标控制样品台移动
                    if (!iSEM.MoveStageXY(currentHole.Position.X, currentHole.Position.Y))
                    {
                        SendMsg("移动失败");
                    }

                    while (true)
                    {
                        Thread.Sleep(10000);

                        if (iSEM.GetStageIs() == 0)
                        {
                            break;
                        }
                    }                    

                    //7. 控制样品台，调整T轴54度、M/Z/R轴不变
                    if (DialogResult.Yes == MessageBox.Show("样品台可以旋转吗？", "确认消息", MessageBoxButtons.YesNo))
                    {
                        SendMsg("样品台旋转");
                        //return true;
                    }
                    else
                    {
                        SendMsg("禁止样品台旋转");
                        return;
                    }

                    if (!iSEM.SetStageGotoT(54))
                    {
                        return;
                    }

                    while (true)
                    {
                        Thread.Sleep(10000);

                        if (iSEM.GetStageIs() == 0)
                        {
                            break;
                        }
                    }
                }
                SendMsg("拉直操作");

                SendMsg("其他操作与1号孔操作一致");
                if (!CommonWork())
                {
                    return;
                }
                //2. 定位切割
                {
                    //1. 拉直操作
                    {
                        //1.1 控制SEM进行拍照
                        //1.2 图片传给客户，返回偏移角度
                        //1.3 根据返回角度，控制样品台转动
                    }
                    //2. 与1号孔13步相同
                }
                //3. 以后步骤与1号孔以后步骤一致
            //}
        }

        //角度补偿
        public bool TiltCorrection(float a_fAngle)
        {
            //记录原来电镜的状态
            // bool bTilt = false;
            //float fOldTilt = iSEM.GetTiltCorrection();
            //if (fOldTilt == float.NaN)
            //{
            //    return false;
            //}
            //else if (fOldTilt == 1)
            //{
            //    bTilt = true;
            //}
            //else if (fOldTilt == 0)
            //{
            //    bTilt = false;
            //}

            //float fOldAngle = iSEM.GetTiltAngle();
            //if (fOldAngle == float.NaN)
            //{
            //    return false;
            //}

            //开启校正
            SendMsg("开启校正");
            if (!iSEM.SetTiltAngleOn())
            {
                return false;
            }

            //设置校正角度
            //if (!iSEM.SetTiltAngle(fOldAngle))
            //{
            //    return false;
            //}

            //恢复原始状态
            SendMsg("校正角度"+ a_fAngle.ToString());
            if (!iSEM.SetTiltAngle(a_fAngle))
            {
                return false;
            }
            //if (bTilt)
            //{
            //    if (!iSEM.SetTiltCorrectionOn())
            //    {
            //        return false;
            //    }
            //}
            //else
            //{
            //    if (!iSEM.SetTiltCorrectionOff())
            //    {
            //        return false;
            //    }
            //}
            return true;
        }

        //拍图
        public bool GetImage(ImageMode a_mode, String a_fileName)
        {
            //1. 图像解冻
            float foldFrozen = iSEM.GetImageFrozen();
            if (foldFrozen == float.NaN)
            {
                return false;
            }

            if (!iSEM.ImageLive())
            {
                return false;
            }

            //2. 确认图像模式
            if (ImageMode.SEM == a_mode)
            {
                if (!iSEM.CmdFIBModeSEM())
                {
                    return false;
                }
            }
            else if (ImageMode.FIB == a_mode)
            {
                if (!iSEM.CmdFIBModeFIB())
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

            //3. 获取分辨率
            int[] ImageSize = iSEM.GetImageStore();
            if (ImageSize[0] == 0 || ImageSize[1] == 0)
            {
                return false;
            }
            short width = (short)ImageSize[0];
            short height = (short)ImageSize[1];

            //4. 抓图
            if (!iSEM.GrabImage(a_fileName, 0, 0, width, height, 0))
            {
                return false;
            }

            //5. 恢复初始状态
            if (foldFrozen == 0)
            {
                if (!iSEM.ImageLive())
                {
                    return false;
                }
            }
            else if (foldFrozen == 1)
            {
                if (!iSEM.ImageFrozen())
                {
                    return false;
                }
            }

            return true;
        }

        //自动聚焦
        public bool AutoFocus(string a_strPath, out int a_nWd)
        {
            a_nWd = 0;
            a_nWd = (int)Math.Ceiling(iSEM.GetWorkingDistance() * 100000000 + 0.5);//获取当前的工作距离

            return true;

        }
    }
}
