//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //생성 :
        //추가 :
        //목적 : 라이브 동작 ( Input Tray )
        //설명 :
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool DoProcessLive(int iCameraIndex, bool bLiveMode)
        {
            bool bReturn     = false;
            var  pDocument   = CDocument.GetDocument;
            int  iTimeOut    = 5000;
            int  iTimePeriod = 10;

            do
            {
                CProcessVisionProcess150 obj = m_objProcessVisionProcess150[iCameraIndex] as CProcessVisionProcess150;
                // 라이브 ON
                if (true == bLiveMode)
                {
                    if (CDefine.enumLiveMode.LIVE_MODE_ON == pDocument.GetLiveMode(iCameraIndex))
                    {
                        obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_LIVE_START);
                    }
                }
                // 라이브 OFF
                else
                {
                    if (CDefine.enumLiveMode.LIVE_MODE_OFF == pDocument.GetLiveMode(iCameraIndex))
                    {
                        obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_LIVE_END);
                    }
                }

                while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                {
                    iTimeOut -= iTimePeriod;
                    Thread.Sleep(iTimePeriod);
                }
                if (0 >= iTimeOut)
                {
                    break;
                }

                bReturn = true;
            } while(false);

            return(bReturn);
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //생성 :
        //추가 :
        //목적 : 초기화 함수
        //설명 :
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public override bool Initialize()
        {
            bool bReturn = false;

            do
            {
                var pDocument = CDocument.GetDocument;
                // 비전 얼라인
                m_objProcessVisionProcess150 = new CProcessAbstract[( int )CDefine.enumCamera.CAMERA_FINAL];
                for (int iLoopCount = ( int )CDefine.enumCamera.CAMERA_1; iLoopCount < ( int )CDefine.enumCamera.CAMERA_FINAL; iLoopCount++)
                {
                    CProcessVisionProcess150 obj = new CProcessVisionProcess150();
                    obj.Initialize(iLoopCount);
                    m_objProcessVisionProcess150[iLoopCount] = obj;
                    m_typeProcessVisionProcess150            = obj.GetType();
                }

                // PLC 객체 참조
                m_objPLC = pDocument.m_objProcessMain.m_objPLC;
                // 조명 컨트롤러 객체 참조
                m_objLightController = new CDeviceLightController[pDocument.m_objProcessMain.m_objLightController.Length];
                for (int iLoopCount = 0; iLoopCount < pDocument.m_objProcessMain.m_objLightController.Length; iLoopCount++)
                {
                    m_objLightController[iLoopCount] = pDocument.m_objProcessMain.m_objLightController[iLoopCount];
                }
                // 메인 스레드
                m_ThreadManager = new Thread[( int )CDefine.enumCamera.CAMERA_FINAL];
                for (int iLoopCount = 0; iLoopCount < m_ThreadManager.Length; iLoopCount++)
                {
                    m_ThreadManager[iLoopCount] = new Thread(ThreadManager);
                    structureManagerArgs objArgs = new structureManagerArgs(this, iLoopCount);
                    m_ThreadManager[iLoopCount].Start(objArgs);
                }

                bReturn = true;
            } while(false);

            return(bReturn);
        }
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //생성 :
 //추가 :
 //목적 : 해제
 //설명 :
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 public override void DeInitialize()
 {
     // 스레드 종료
     m_bThreadExit = true;
     // 메인 스레드
     for (int iLoopCount = 0; iLoopCount < m_ThreadManager.Length; iLoopCount++)
     {
         m_ThreadManager[iLoopCount].Join();
     }
     // 비전 얼라인
     for (int iLoopCount = ( int )CDefine.enumCamera.CAMERA_1; iLoopCount < ( int )CDefine.enumCamera.CAMERA_FINAL; iLoopCount++)
     {
         if (null != m_objProcessVisionProcess150[iLoopCount])
         {
             CProcessVisionProcess150 obj = m_objProcessVisionProcess150[iLoopCount] as CProcessVisionProcess150;
             if (null != obj)
             {
                 obj.DeInitialize();
             }
         }
     }
 }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //생성 :
        //추가 :
        //목적 : 트리거 ( Input Tray )
        //설명 :
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool DoProcessTrigger(int iCameraIndex)
        {
            bool bReturn     = false;
            var  pDocument   = CDocument.GetDocument;
            int  iTimeOut    = 5000;
            int  iTimePeriod = 3;

            do
            {
                CProcessVisionProcess150 obj = m_objProcessVisionProcess150[iCameraIndex] as CProcessVisionProcess150;
                // 라이브 모드 OFF
                obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_LIVE_END);

                while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                {
                    iTimeOut -= iTimePeriod;
                    Thread.Sleep(iTimePeriod);
                }
                if (0 >= iTimeOut)
                {
                    break;
                }

                // 설비 정지 모드인 경우
                if (CDefine.enumRunMode.RUN_MODE_STOP == pDocument.GetRunMode())
                {
                    // 트리거 ON
                    obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_START_GRAB);

                    iTimeOut = 5000;
                    while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                    {
                        iTimeOut -= iTimePeriod;
                        Thread.Sleep(iTimePeriod);
                    }
                    if (0 >= iTimeOut)
                    {
                        break;
                    }
                }
                // 설비 자동 모드인 경우
                else
                {
                    // 정지 트리거 타입
                    // 트리거 ON
                    if (CDefine.enumTrigger.TRIGGER_ON == pDocument.GetTrigger(iCameraIndex))
                    {
                        obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_START_GRAB);
                    }

                    iTimeOut = 5000;
                    while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                    {
                        iTimeOut -= iTimePeriod;
                        Thread.Sleep(iTimePeriod);
                    }
                    if (0 >= iTimeOut)
                    {
                        break;
                    }
                }


                bReturn = true;
            } while(false);

            return(bReturn);
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //생성 :
        //추가 :
        //목적 : 검사 시작
        //설명 :
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool DoProcessInspection(int iCameraIndex)
        {
            bool      bReturn   = false;
            var       pDocument = CDocument.GetDocument;
            Stopwatch objTact   = new Stopwatch();

            Stopwatch objStopwatch = new Stopwatch();

            string strPlcCameraName = string.Format("CAMERA_{0}", iCameraIndex + 1);

            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "DoProcessInspection");

            //PLC객체
            HLDevice.CDevicePLC objPLC = pDocument.m_objProcessMain.m_objPLC;
            // 결과구조체
            CInspectionResult.CResult objResult          = new CInspectionResult.CResult();
            CConfig.CRecipeParameter  objRecipeParameter = pDocument.m_objConfig.GetRecipeParameter(iCameraIndex);
            int iAlarmCode = ( int )CDefine.enumVisionAlarmType.NONE;

            do
            {
                // 택타임 측정
                objTact.Start();
                // 비전 Busy상태
                if (false == m_objPLC.HLWriteWordFromPLC("PC_BUSY", ( short )CDefine.enumVisionStatus.STATUS_BUSY))
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]Vision_Status_Busy On");
                }
                else
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]Vision_Status_Busy On");
                }

                // 셀ID를 읽음
                string strCellID = ReadCellID();
                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Read Cell ID : " + strCellID);

                // string strCellID = "";
                // PLC 데이터 읽기
                short[] iReadData = new short[( int )CDefine.enumPLCInputIndex.PLC_FINAL];
                m_objPLC.HLReadWordFromPLC(CDefine.enumPLCInputIndex.PLC_MODEL_CHANGE.ToString(), iReadData.Length, ref iReadData);

                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Read Recipe ID : " + iReadData[( int )CDefine.enumPLCInputIndex.PLC_MODEL_CHANGE].ToString());
                // 레시피 체크
                if (false == DoProcessRecipe(iReadData[( int )CDefine.enumPLCInputIndex.PLC_MODEL_CHANGE]))
                {
                    break;
                }

                int iCurrentInspectionIndex = iReadData[( int )CDefine.enumPLCInputIndex.PLC_INSPECTION_INDEX] - 1;


                // 티치모드이면 저장되어있는 포지션을 바로 사용하자
                CConfig.CSystemParameter objSystemParameter = pDocument.m_objConfig.GetSystemParameter();
                if (true == objSystemParameter.bVidiTeachMode)
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Teach Mode");
                    iCurrentInspectionIndex = pDocument.GetInspectionIndex();
                }

                // 설정한 검사포지션수 초과시 NG
                if (iCurrentInspectionIndex > objRecipeParameter.iCountInspectionPosition)
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)((int)CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "INSPECTION POSITION OVER");
                    iAlarmCode = (int)CDefine.enumVisionAlarmType.INSPECTION_POSITION_OVER_RANGE;
                    break;
                }

                if (0 > iCurrentInspectionIndex)
                {
                    iCurrentInspectionIndex = 0;
                }
                // 검사인덱스를 가지고 있고
                pDocument.SetInspectionIndex(iCurrentInspectionIndex);

                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Inspection Index : " + (iCurrentInspectionIndex + 1).ToString());

                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Grab Start");
                // 그랩
                objStopwatch.Start();
                if (false == DoProcessTrigger(iCameraIndex))
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "Grab Fail");
                    iAlarmCode = ( int )CDefine.enumVisionAlarmType.GRAB_FAIL;
                    break;
                }
                objStopwatch.Stop();
                CDocument.GetDocument.SetUpdateLog(CDefine.enumLogType.LOG_ETC, "Grab Sequence TactTime : " + objStopwatch.ElapsedMilliseconds.ToString());

                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "PMS Start");

                objStopwatch.Restart();
                // PMS 이미지 만들기
                CProcessVisionProcess150 obj = m_objProcessVisionProcess150[iCameraIndex] as CProcessVisionProcess150;
                // 트리거 ON
                obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_START_PMS);

                // Busy Off
                Thread.Sleep(20);
                if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_BUSY.ToString(), ( short )CDefine.enumVisionStatus.STATUS_IDLE))
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]Vision_Status_Busy Off");
                }
                else
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]Vision_Status_Busy Off");
                }

                int iTimeOut    = 25000;
                int iTimePeriod = 3;
                while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                {
                    iTimeOut -= iTimePeriod;
                    Thread.Sleep(iTimePeriod);
                }
                objStopwatch.Stop();
                CDocument.GetDocument.SetUpdateLog(CDefine.enumLogType.LOG_ETC, "PMS Image Sequence TactTime : " + objStopwatch.ElapsedMilliseconds.ToString());
                if (0 >= iTimeOut)
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "PMS Image Time Out");
                    iAlarmCode = ( int )CDefine.enumVisionAlarmType.PMS_IMAGE_SETTING_FAIL;
                    break;
                }

                if (CProcessVisionProcess150.enumStatus.STS_ERROR == obj.GetStatus())
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "PMS IMAGE NG");
                    iAlarmCode = ( int )CDefine.enumVisionAlarmType.PMS_IMAGE_SETTING_FAIL;
                    break;
                }

                //////////////////////////////////////////////////
                // PMS이미지 까지 합성했다면.

                //Vidi Start
                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "VIDI Start");
                objStopwatch.Restart();
                obj.SetCommand(CProcessVisionProcess150.enumCommand.CMD_START_INSPECTION);
                iTimeOut    = 25000;
                iTimePeriod = 3;
                while (CProcessVisionProcess150.enumCommand.CMD_IDLE != obj.GetCommand() && iTimeOut > 0)
                {
                    iTimeOut -= iTimePeriod;
                    Thread.Sleep(iTimePeriod);
                }
                objStopwatch.Stop();
                CDocument.GetDocument.SetUpdateLog(CDefine.enumLogType.LOG_ETC, "VIDI Sequence TactTime : " + objStopwatch.ElapsedMilliseconds.ToString());

                if (0 >= iTimeOut)
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "VIDI Time Out");
                    objResult = pDocument.GetInspectionResultAlign(iCurrentInspectionIndex);
                    objResult.objResultCommon.strCellID           = strCellID;
                    objResult.objResultCommon.eResult             = CDefine.enumResult.RESULT_NG;
                    objResult.objResultCommon.iInspectionPosition = iCurrentInspectionIndex;
                    iAlarmCode = ( int )CDefine.enumVisionAlarmType.VIDI_INSPECTION_FAIL;
                    break;
                }
                if (CProcessVisionProcess150.enumStatus.STS_ERROR == obj.GetStatus())
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_PROCESS_CAMERA_0 + iCameraIndex), "VIDI Run NG");
                    objResult = pDocument.GetInspectionResultAlign(iCurrentInspectionIndex);
                    objResult.objResultCommon.strCellID           = strCellID;
                    objResult.objResultCommon.eResult             = CDefine.enumResult.RESULT_NG;
                    objResult.objResultCommon.iInspectionPosition = iCurrentInspectionIndex;
                    iAlarmCode = ( int )CDefine.enumVisionAlarmType.VIDI_INSPECTION_FAIL;
                    break;
                }

                // 여기서 결과 도출
                objResult = pDocument.GetInspectionResultAlign(iCurrentInspectionIndex);
                objResult.objResultCommon.strCellID = strCellID;


                // 최종결과는 양품으로 설정하고, 1개라도 NG가 나오면 NG로 바꾸자
                objResult.objResultCommon.eResult = CDefine.enumResult.RESULT_OK;
                // 여기에 결과를 채우자, 일단은 1,0으로 채움
                // 1포지션에 검사결과가 5개씩 있다고 가정
                objResult.objResultCommon.iInspectionPosition = iCurrentInspectionIndex;
                short[] iResult = new short[objResult.objResultCommon.iVidiResultCount];// ( int )CDefine.enumResultIndex.RESULT_FINAL ];
                for (int iLoopCount = 0; iLoopCount < objResult.objResultCommon.iVidiResultCount; iLoopCount++)
                {
                    // 일단 1보다 작으면 양품으로 테스트하자
                    if (objRecipeParameter.objInspectionParameter[pDocument.GetInspectionIndex()].dVidiScore > objResult.objResultCommon.objVidiScore[iLoopCount])
                    {
                        objResult.objResultCommon.objVidiResult.Add(CDefine.enumResult.RESULT_OK);
                        iResult[iLoopCount] = 1;
                    }
                    else
                    {
                        objResult.objResultCommon.eResult = CDefine.enumResult.RESULT_NG;
                        objResult.objResultCommon.objVidiResult.Add(CDefine.enumResult.RESULT_NG);
                        iAlarmCode = ( int )CDefine.enumVisionAlarmType.VIDI_INSPECTION_FAIL;
                    }
                    string strResult = string.Format("INDEX : {0}, VIDI_Score : {1:F2}, VIDI_Result : {2}", iLoopCount + 1, objResult.objResultCommon.objVidiScore[iLoopCount], CDefine.enumResult.RESULT_OK == objResult.objResultCommon.eResult ? "OK" : "NG");
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), strResult);
                }

                //String strPLCAddressName = string.Format( "PC_INSPECTION_RESULT_{0}", iCurrentInspectionIndex * ( int )CDefine.enumResultIndex.RESULT_FINAL );
                //String strPLCAddressName = string.Format(CDefine.enumPCOutIndex.PC_INSPECTION_RESULT_1.ToString() );

                //if ( false == m_objPLC.HLWriteWordFromPLC( strPLCAddressName, iResult.Length, iResult ) )
                //    pDocument.SetUpdateLog( ( CDefine.enumLogType )( ( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex ), "[SEND_PLC RESULT][FAIL]"+ strPLCAddressName  );
                //else
                //    pDocument.SetUpdateLog( ( CDefine.enumLogType )( ( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex ), "[SEND_PLC RESULT]" + strPLCAddressName );



                bReturn = true;
            } while(false);
            bool bInspectResult = false;

            // 에러코드
            if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_ALARM_CODE.ToString(), ( short )iAlarmCode))
            {
                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]Set AlarmCode");
            }
            else
            {
                pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]Set AlarmCode");
            }

            if (false == bReturn)
            {
                if (true == pDocument.m_objConfig.GetSystemParameter().bPassMode)
                {
                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "VISION PASS MODE");

                    if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_OK.ToString(), ( short )CDefine.enumComplete.COMPLETE_ON))
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_INSPECTION_OK On");
                    }
                    else
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_INSPECTION_OK On");
                    }

                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), "VISION PASS MODE : FINAL_RESULT_OK");
                    bInspectResult = true;
                }
                else
                {
                    if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_NG.ToString(), ( short )CDefine.enumComplete.COMPLETE_ON))
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_INSPECTION_NG On");
                    }
                    else
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_INSPECTION_NG On");
                    }

                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), "FINAL_RESULT_NG");
                    bInspectResult = false;
                }
            }
            else
            {
                if (CDefine.enumResult.RESULT_OK == objResult.objResultCommon.eResult)
                {
                    if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_OK.ToString(), ( short )CDefine.enumComplete.COMPLETE_ON))
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_INSPECTION_OK On");
                    }
                    else
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_INSPECTION_OK On");
                    }

                    pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), "FINAL_RESULT_OK");
                    bInspectResult = true;
                }
                else
                {
                    if (true == pDocument.m_objConfig.GetSystemParameter().bPassMode)
                    {
                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "VISION PASS MODE");

                        if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_OK.ToString(), ( short )CDefine.enumComplete.COMPLETE_ON))
                        {
                            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_INSPECTION_OK On");
                        }
                        else
                        {
                            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_INSPECTION_OK On");
                        }

                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), "VISION PASS MODE : FINAL_RESULT_OK");
                        bInspectResult = true;
                    }
                    else
                    {
                        if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_INSPECTION_NG.ToString(), ( short )CDefine.enumComplete.COMPLETE_ON))
                        {
                            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_INSPECTION_NG On");
                        }
                        else
                        {
                            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_INSPECTION_NG On");
                        }

                        pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_RESULT_STAGE_0 + iCameraIndex), "FINAL_RESULT_NG");
                        bInspectResult = false;
                    }
                }
            }
            pDocument.SetDisplayResult(pDocument.GetInspectionIndex(), bInspectResult);

            if (false == m_objPLC.HLWriteWordFromPLC(CDefine.enumPCOutIndex.PC_COMPLETE.ToString(), (short)CDefine.enumComplete.COMPLETE_ON))
            {
                pDocument.SetUpdateLog((CDefine.enumLogType)((int)CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC][FAIL]PC_COMPLETE On");
            }
            else
            {
                pDocument.SetUpdateLog((CDefine.enumLogType)((int)CDefine.enumLogType.LOG_VISION_INTERFACE_CAMERA_0 + iCameraIndex), "[SEND_PLC]PC_COMPLETE On");
            }

            // 트리거 OFF
            pDocument.SetTrigger(( int )CDefine.enumCamera.CAMERA_1 + iCameraIndex, CDefine.enumTrigger.TRIGGER_OFF);

            objTact.Stop();
            objResult.objResultCommon.strTactTime = objTact.ElapsedMilliseconds.ToString();
            pDocument.SetUpdateDisplayPMS(pDocument.GetInspectionIndex(), ( int )CFormMainProcess150.enumDisplayIndex.PMS);

            // 이미지 저장경로 넣기
            objResult.strSaveImagePath = pDocument.m_objConfig.GetSystemParameter().strImageSavePath;
            pDocument.SetInspectionResultAlign(pDocument.GetInspectionIndex(), (CInspectionResult.CResult)objResult.Clone());

            // 여기서 결과 디스플레이를 뿌리자
            for (int iLoopCount = 0; iLoopCount < (CDefine.DEF_MAX_COUNT_CROP_REGION - 3); iLoopCount++)
            {
                pDocument.SetUpdateDisplayResultVIDI(pDocument.GetInspectionIndex(), ( int )CFormMainProcess150.enumDisplayIndex.VIDI_1 + iLoopCount);
            }

            // 여기서 결과 디스플레이를 뿌리자
            for (int iLoopCount = 0; iLoopCount < (CDefine.DEF_MAX_COUNT_CROP_REGION - 3); iLoopCount++)
            {
                pDocument.SetUpdateDisplayResultMeasure(pDocument.GetInspectionIndex(), ( int )CFormMainProcess150.enumDisplayIndex.MEASURE_1 + iLoopCount);
            }

            // 이미지 저장
            SaveImage((CInspectionResult.CResult)objResult.Clone());
            // 택타임 측정
            pDocument.SetUpdateLog((CDefine.enumLogType)(( int )CDefine.enumLogType.LOG_VISION_TACT_TIME_CAMERA_0 + iCameraIndex), objTact.ElapsedMilliseconds.ToString() + "ms");

            return(bReturn);
        }