
#include <vcl.h>
#include <inifiles.hpp>
#include <Mmsystem.h>
#pragma hdrstop

#include "CameraSetting3D_Form.h"
#include "RangerCameraSetup_Form.h"
#include "Message_Form.h"
#include "Keyboard_Form.h"
#include "AdvMachineControl_Form.h"
#include "MultiLanguage.h"
#include "SystemSetup.h"
#include "math.h"
#include "Clipbrd.hpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma link "TntExtCtrls"
#pragma link "TntForms"
#pragma link "TntStdCtrls"
#pragma link "CSPIN"
#pragma link "TntComCtrls"
#pragma resource "*.dfm"

// Line Scan Image
#define LINE_FRAME_WIDTH_RANGER_3D					480
#define LINE_FRAME_HEIGHT_RANGER_3D					640

// One Frame Image
// 1280 * 1024

#define SELECTION_IMAGE_MARGIN_LEFT 	10
#define SELECTION_IMAGE_MARGIN_TOP 		10

#define CLICK_EVENT_GET_COLOR_INFO          0
#define CLICK_EVENT_SET_ROI_POS             1

#define PI    3.141592
#define MAX_LABEL_COUNT 1000
//***************************************************************************
//20201106 cjg added 3d camera param
//***************************************************************************
#define IMAGE_COUNT_MASK 					0xFFF
#define IMAGE_MAX_COUNT 					4096

int Nfa3DcamOffset[16];

unsigned int Image_Count;

float Nfa3DcamOffset_Float[16];

double Max_Offset_Float[16];
double Avg_Offset_Float[16];
double Sum_Offset_Float[16];
//***************************************************************************

TCameraSetting3DForm *CameraSetting3DForm;
//---------------------------------------------------------------------------
__fastcall TCameraSetting3DForm::TCameraSetting3DForm(TComponent* Owner)
	: TTntForm(Owner)
{
  if(DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
    ComponentSetFontName(this, "SimSun");
  else if(DefaultLCID == 1041)
    ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

  GetDefaultString();
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::GetDefaultString()
{
  AdvMachineControlButton->Caption = CAMERASETTING3DFORM_BUTTON_CAPTION_01;
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::FormCreate(TObject *Sender)
{
	int tmpSpbIndex = 0;
	int tmpCamIndex = 0;
	int tmpGlobalCamIndex = 0;
	int tmpCameraLink = 0;
	int cam3D_Index = 5;	//#define CAMERA_POSITION_3D 5
	int i;
	GlobalCameraIndex = 0;
	RangerCaptureMode = ERCM_3D;
	AreaFrameCaptureWidth = AREA_FRAME_WIDTH_RANGER_3D;
	AreaFrameCaptureHeight = AREA_FRAME_HEIGHT_RANGER_3D;
	LineFrameCaptureWidth = LINE_FRAME_WIDTH_RANGER_3D;
	LineFrameCaptureHeight = LINE_FRAME_HEIGHT_RANGER_3D;
	DestImage = CaptureImage;
	DestImage->Width = max(AreaFrameCaptureWidth, LineFrameCaptureWidth);
	DestImage->Height = max(AreaFrameCaptureHeight, LineFrameCaptureHeight / 2);
	DestImage->Picture->Bitmap->Width = DestImage->Width;
	DestImage->Picture->Bitmap->Height = DestImage->Height;
	DestImage->Picture->Bitmap->PixelFormat = pf24bit;

	CaptureData = new char[(max(AreaFrameCaptureWidth, LineFrameCaptureWidth) + 1) * (max(AreaFrameCaptureHeight, LineFrameCaptureHeight) + 1) * 2];
  FullScaleImage = new char[FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT];

  fstThreeDCameraIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
  secThreeDCameraIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
  bSendSetupData = false;
	FirstCalEnable = false;
	SaveSpeedValue = false;
	TTntSpeedButton *firstCameraSpeedButton = NULL;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		TTntSpeedButton *cameraSpeedButton = (TTntSpeedButton *) FindComponent("CameraSpeedButton" + IntToStr(globalCameraIndex + 1));
		if (cameraSpeedButton)
		{
			if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
			{
				cameraSpeedButton->Enabled = true;
        cameraSpeedButton->Click(); // for value setting
				if (firstCameraSpeedButton == NULL)
        {
          firstCameraSpeedButton = cameraSpeedButton;

          int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
          TriggerMethodRadioBox1->Caption = "SD1 3D Camera Trigger Method SPB#" + IntToStr(spbIndex + 1);
          TriggerMethodRadioBox1->ItemIndex = SPBSystemSetupData[spbIndex].ThreeDCaptureMethod;

          fstThreeDCameraIndex = globalCameraIndex;
        }
        else
        {
          int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
          TriggerMethodRadioBox2->Caption = "SD2 3D Camera Trigger Method SPB#" + IntToStr(spbIndex + 1);
          TriggerMethodRadioBox2->ItemIndex = SPBSystemSetupData[spbIndex].ThreeDCaptureMethod;

          secThreeDCameraIndex = globalCameraIndex;

          break;
        }
			}
			else
			{
				cameraSpeedButton->Enabled = false;
			}
		}
	}

  bSendSetupData = true;

	if (firstCameraSpeedButton)
	{
     LineScanTime_3D[0] = RANGER_3D_BASE_SHUTTER_SPEED;
     LineScanTime_3D[1] = RANGER_3D_BASE_SHUTTER_SPEED2;

    if(firstCameraSpeedButton->Tag == 4)
      LineScanTimeEdit->Text = IntToStr(RANGER_3D_BASE_SHUTTER_SPEED);
    else
      LineScanTimeEdit->Text = IntToStr(RANGER_3D_BASE_SHUTTER_SPEED2);


		firstCameraSpeedButton->Click();
		firstCameraSpeedButton->Down = true;
	}

  qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq->DoubleBuffered = true;
  PreviewInspectionImageGroupBox->DoubleBuffered = true;
	SaveImageCount = 1;

  eImageClickEvent = CLICK_EVENT_GET_COLOR_INFO;

  if(!ProductData.ProductName.IsEmpty())
  {
    AdvMachineControlForm->ApplyProductInfo();
  }
  else
  {
    AdvMachineControlForm->ApplyDefaultParams();
  }

  memset(ThreeDRAWData, 0, sizeof(unsigned short) * LINE_FRAME_WIDTH_RANGER_3D * LINE_FRAME_HEIGHT_RANGER_3D);

  MousePos.x = DestImage->Width / 2;
  MousePos.y = DestImage->Height / 2;
  RefreshSubImage();
  RefreshPixelInfo(MousePos.x, MousePos.y);

  for (int m = 0; m < 90000; m++)
	{
		if (m == 0)
			SqrtData[m] = 128;
		else SqrtData[m] = sqrt(m)*128.0;
	}

  for (int m = 0; m <= 10000; m++)
	{
		ArcSinData[m] = (int)(asin((float)m / 10000.0)*180.0 / 3.141592 + 0.5);
	}

  bImageGrabMode = false;
  
//20201106 cjg added 3d camera param
//20201020 cjg 3D camera param control (check 3D camera version)

   	memset(&SpbCamVer, 0, sizeof(SpbCamVer));
   	
    for(i=0; i<2; i++)
    {
		tmpGlobalCamIndex = 0;
		if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
		{
			tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
		    tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
	        tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
	        
			if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_CAMERA_VERSION, &tmpCameraLink, sizeof(int), &SpbCamVer, sizeof(SpbCamVer)))
			{
				ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
			}
			else
			{
				if(SpbCamVer.Cam_Ver_Major != 0xFF && SpbCamVer.Cam_Ver_Minor != 0xFF)
				{
					FirstCalEnableBtn->Visible = true;
					FirstCalEnableBtn->Enabled = true;

		            CamVerDisk1->Caption     = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
		            CamVerDisk1Copy->Caption = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
				}
			}
		}

		tmpGlobalCamIndex = 4;
		if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
		{
			tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
		    tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
	        tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
	        
			if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_CAMERA_VERSION, &tmpCameraLink, sizeof(int), &SpbCamVer, sizeof(SpbCamVer)))
			{
				ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
			}
			else
			{
				if(SpbCamVer.Cam_Ver_Major != 0xFF && SpbCamVer.Cam_Ver_Minor != 0xFF)
				{
					FirstCalEnableBtn->Visible = true;
					FirstCalEnableBtn->Enabled = true;

		            CamVerDisk1->Caption     = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
		            CamVerDisk1Copy->Caption = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
				}
			}
		}

		tmpGlobalCamIndex = 8;
		if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
		{
			tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
		    tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
	        tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
	        
			if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_CAMERA_VERSION, &tmpCameraLink, sizeof(int), &SpbCamVer, sizeof(SpbCamVer)))
			{
				ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
			}
			else
			{
				if(SpbCamVer.Cam_Ver_Major != 0xFF && SpbCamVer.Cam_Ver_Minor != 0xFF)
				{
					FirstCalEnableBtn->Visible = true;
					FirstCalEnableBtn->Enabled = true;

		            CamVerDisk2->Caption     = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
		            CamVerDisk2Copy->Caption = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
				}
			}
		}

		tmpGlobalCamIndex = 12;
		if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
		{
			tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
		    tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
	        tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
	        
			if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_CAMERA_VERSION, &tmpCameraLink, sizeof(int), &SpbCamVer, sizeof(SpbCamVer)))
			{
				ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
			}
			else
			{
				if(SpbCamVer.Cam_Ver_Major != 0xFF && SpbCamVer.Cam_Ver_Minor != 0xFF)
				{
					FirstCalEnableBtn->Visible = true;
					FirstCalEnableBtn->Enabled = true;

		            CamVerDisk2->Caption     = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
		            CamVerDisk2Copy->Caption = IntToStr(SpbCamVer.Cam_Ver_Major) + "." + IntToStr(SpbCamVer.Cam_Ver_Minor);
				}
			}
		}
    }

    cbCamCalibMode->ItemIndex = 0;

	cb3D_Cam_ADC_Resolution->ItemIndex = 0;
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CaptureStartButtonClick(TObject *Sender)
{
 	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	TCaptureCommandParam captureCommandParam;
	captureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;
	captureCommandParam.CameraMask = 0x01 << camIndex;
	if (CalibrationModeSpeedButton->Down)
	{
		captureCommandParam.FrameBufferCount = 2;
		captureCommandParam.ShutterSpeed[camIndex] = 100;
		captureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;
	}
	else
	{
		captureCommandParam.FrameBufferCount = 4;
		captureCommandParam.ShutterSpeed[camIndex] = StrToInt(LineScanTimeEdit->Text);
		captureCommandParam.CaptureKind = CAPTURE_KIND_LINE;
	}

  int ExposureTime;
  ExposureTime = StrToInt(cmdNFACameraData6->Text);

  RefreshCameraInfo(ExposureTime);

  //SELMA200, 20180410, moon, CMD_CAPTURE_START 가 미치는 영향 확인할것(SPB)
  if (Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &captureCommandParam, sizeof(TCaptureCommandParam)))
	{
		CaptureStart(false, false);
	}

//20201106 cjg added 3d camera param
//20201020 cjg 3D camera param control
    Image_Count = 0;
    memset(Max_Offset_Float, 0, sizeof(Max_Offset_Float));
    memset(Sum_Offset_Float, 0, sizeof(Sum_Offset_Float));
    memset(Avg_Offset_Float, 0, sizeof(Avg_Offset_Float));
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CameraSpeedButtonClick(
	  TObject *Sender)
{
  bool bInitialSW = false;
	TTntSpeedButton *theSpeedButton = (TTntSpeedButton *) Sender;
	GlobalCameraIndex = theSpeedButton->Tag;

  if(GlobalCameraIndex == 4)
    LineScanTimeEdit->Text = IntToStr(LineScanTime_3D[0]);
  else
    LineScanTimeEdit->Text = IntToStr(LineScanTime_3D[1]);
    
	// load ini file
	AnsiString fileName = ProgramPath.Env + "\\ThreeDCameraDefaultInfo.ini";

  if(!Read3DCameraDefaultInformation(fileName, GlobalCameraIndex))
	{
    bInitialSW = true;
	}

  if(ThreeDCameraDefaultInformation[GlobalCameraIndex].BiningMode == 0)
    cmdNFACameraData1->ItemIndex = 0;
  else
    cmdNFACameraData1->ItemIndex = 1;

  cmdNFACameraData2->Text =     IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX);
  cmdNFACameraData3->Text =     IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth);
  cmdNFACameraData4->Text =     IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY);
  cmdNFACameraData5->Text =     IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight);

  cmdNFACameraData6->Text =      IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ExposureTime);
  cmdNFACameraData7->Text =      IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].Thresold3D);

  cmdNFACameraData8->Value = ThreeDCameraDefaultInformation[GlobalCameraIndex].AnalogCameraGain;

  ThreeDCameraDefaultInformation[GlobalCameraIndex].ImageOutputMode = 1;
  ThreeDModeSpeedButton->Down = true;
  ThreeDModeSpeedButton->Click();

  cmdNFACameraData9->ItemIndex = ThreeDCameraDefaultInformation[GlobalCameraIndex].TriggerMode;
  CSpinEdit1->Value = ThreeDCameraDefaultInformation[GlobalCameraIndex].WaveTableIndex;

  ThreeDCameraSetup(GlobalCameraIndex, true);
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CaptureStart(bool bFrame, bool bFullCapture)
{
	CaptureStartTime = GetTickCount();
	bFrameCapture = bFrame;
	CaptureCheckTimer->Enabled = true;
        TimeoutCheck_3D = 0;
	if (!bFrame)
	{
		CaptureFirstStartTime = GetTickCount();
		CaptureCount = 0;

		if (SaveSpeedButton->Down && SaveSpeedValue)
		{
			ImageSubDirIndex++;
			CurrentImageIndex = 1;
			SubDirEdit->Text = IntToStr(ImageSubDirIndex);
		}
	}
	else
	{
	}
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CaptureStopButtonClick(
	  TObject *Sender)
{
	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;

  bImageGrabMode = false;
  SpeedButton2->Down = true;
  ProcessImageBtn->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CaptureCheckTimerTimer(
	TObject *Sender)
{
	bool bCaptureExist;

	char cameraIndex;
	unsigned int data[2];
	unsigned int receivedData[2];

	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;
	data[0] = camIndex;
    data[1] = 0;

//20201106 cjg added 3d camera param
	int tmp2ByteOffset;
	int sumOffset[16];
	int flagHigh8bit = 0;
	int i,x,y = 0;
	unsigned short tmp2ByteVal = 0;
	float tmpAvgCh[16] = {0.0};
	TTntEdit *EditAvg = NULL;

  //SELMA200, 의미없어보여서 막아둠
	if (RangerCaptureMode == ERCM_CALIB)
	{
		data[1] = FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT;
	}
	else
	{
		data[1] = LineFrameCaptureWidth * LineFrameCaptureHeight;
	}

  memset(ThreeDRAWData, 0, sizeof(unsigned short) * LINE_FRAME_WIDTH_RANGER_3D * LINE_FRAME_HEIGHT_RANGER_3D);

	try
	{
		if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
			receivedData, sizeof(unsigned int) * 2))
		{
			throw(0);
		}

		BufferImage->Canvas->Brush->Color = clBlack;
		BufferImage->Canvas->FillRect(Rect(0, 0, BufferImage->Width, BufferImage->Height));
		if (receivedData[0])
		{
			bCaptureExist = true;
			BufferImage->Canvas->Brush->Color = clLime;
			BufferImage->Canvas->FillRect(Rect(0, BufferImage->Height - BufferImage->Height * receivedData[0] / receivedData[1], BufferImage->Width, BufferImage->Height));
		}
		else
		{
			bCaptureExist = false;
		}
		if (bCaptureExist)
		{
			if (RangerCaptureMode == ERCM_CALIB)
			{
        // One Frame Image
        // Full Scale Image 받아야함(영역 정보를 확인해야하므로)
        // 640 * 1024 Upload
        
				if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
					FullScaleImage, FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT))
				{
					throw(0);
				}
//20201106 cjg added 3d camera param
				else
				{
					if(Camera3D_OffsetParamData.Cam_Calib_Mode == 1 || Camera3D_OffsetParamData.Cam_Calib_Mode == 2)
					{
						Image_Count++;
			        	ImageCountEdit->Text = IntToStr(Image_Count);
					}
				}
				
//20201106 cjg added 3d camera param
				if(Camera3D_OffsetParamData.Cam_Calib_Mode == 1 || Camera3D_OffsetParamData.Cam_Calib_Mode == 2)
				{					        
				    switch(Camera3D_OffsetParamData.Cam_Calib_Mode)
				    {
				        case 1 :
				        case 2 :							    
				              memset(sumOffset, 0, sizeof(sumOffset));
							  for (y = 0; y < 16; y++)
							  {
							  	for (x = (y*2); x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=(16*2))
							  	{
							  		tmp2ByteOffset = FullScaleImage[x] | (FullScaleImage[x+1]<<8);	
									sumOffset[y] += tmp2ByteOffset;
								}
							  }

							for(i = 0 ; i < 16 ; i++)
							{
								tmpAvgCh[i] = (float)sumOffset[i]/20480.0;	// FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT / 16 ch / 2byte
							}
							for(i = 0 ; i < 16 ; i++)
							{
								Max_Offset_Float[i] = ((Max_Offset_Float[i] > tmpAvgCh[i]) ? Max_Offset_Float[i] : tmpAvgCh[i]); 
								Sum_Offset_Float[i] += tmpAvgCh[i];
								Avg_Offset_Float[i] = Sum_Offset_Float[i]/Image_Count;
							}

							for(i = 0 ; i < 16 ; i++)
							{
								if(Camera3D_OffsetParamData.Cam_Calib_Mode == 1)	EditAvg = (TTntEdit *)FindComponent("Average_1_" + IntToStr(i));
								else 												EditAvg = (TTntEdit *)FindComponent("Average_2_" + IntToStr(i));
								
								if(flagOffsetMode == MAX_OFFSET_PROCESS)		EditAvg->Text = String().sprintf("%6.1f", Max_Offset_Float[i]);
								else if(flagOffsetMode == AVG_OFFSET_PROCESS)	EditAvg->Text = String().sprintf("%6.1f", Avg_Offset_Float[i]);
								else 											EditAvg->Text = String().sprintf("%6.1f", tmpAvgCh[i]);
							}

							flagHigh8bit = 0;
							
					        for (x = 0; x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=2)
							{
		                        tmp2ByteVal = FullScaleImage[x] | (FullScaleImage[x +1] << 8);

								if(tmp2ByteVal > 0xFF)	
								{
									flagHigh8bit = 1;
									break;
								}
								else
								{
									flagHigh8bit = 0;
								}
					        }

		                    if(flagHigh8bit)    lblRemovePacket->Caption = "Upper 8bit";
		                    else                lblRemovePacket->Caption = "Lower 8bit";

					        for (x = 0; x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=2)
							{
	                        	tmp2ByteVal = FullScaleImage[x] | (FullScaleImage[x +1] << 8);
								
								if(flagHigh8bit == 1)       tmp2ByteVal = (tmp2ByteVal >> 4) & 0xFF;
								else						tmp2ByteVal = tmp2ByteVal & 0xFF;
										
								ProcessedScaleImage[x/2] = (unsigned char)tmp2ByteVal;
					        }
					        
				            break;				            
				        default :		        
				            break;
				    }
				}
				
        memcpy(ScaleConversionImage, FullScaleImage, AREA_FRAME_WIDTH_RANGER_3D * AREA_FRAME_HEIGHT_RANGER_3D);

//20201106 cjg added 3d camera param
				if(Camera3D_OffsetParamData.Cam_Calib_Mode == 1 || Camera3D_OffsetParamData.Cam_Calib_Mode == 2)
				{	
					for (int y = 0; y < AreaFrameCaptureHeight; y++)
					{
						byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

						for (int x = 0; x < AreaFrameCaptureWidth; x++)
						{
							pBitmap[0] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];
							pBitmap[1] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];
							pBitmap[2] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];

							pBitmap += 3;
						}
					}
				}
				else
				{
					for (int y = 0; y < FULL_SCALE_IMAGE_HEIGHT; y++)
					{
						byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

						for (int x = 0; x < FULL_SCALE_IMAGE_WIDTH; x++)
						{
								pBitmap[0] = FullScaleImage[y * FULL_SCALE_IMAGE_WIDTH + x];
								pBitmap[1] = FullScaleImage[y * FULL_SCALE_IMAGE_WIDTH + x];
								pBitmap[2] = FullScaleImage[y * FULL_SCALE_IMAGE_WIDTH + x];
				
							pBitmap += 3;
						}
					}
				}

        int ROIStartX, ROIEndX, ROIStartY, ROIEndY;

		        ROIStartX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2;
		        ROIEndX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2 + ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth / 2;
//20201106 cjg added 3d camera param
//20201020 cjg capture height size change 512->1024		
		        //ROIStartY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY / 2;
		        //ROIEndY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY / 2 + ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight / 2;
		        ROIStartY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY;
		        ROIEndY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY + ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight;
		        
        DestImage->Canvas->Pen->Width = 1;
        DestImage->Canvas->Pen->Style = psDot;
        DestImage->Canvas->Pen->Color = clRed;
        DestImage->Canvas->Brush->Style = bsClear;
        DestImage->Canvas->Rectangle(ROIStartX, ROIStartY, ROIEndX, ROIEndY);
//				DestImage->Repaint();

//20210228 cjg laser guide line
        if(cb3D_LaserGuideEnable->Checked)
        {
            DestImage->Canvas->Pen->Width = 1;
            DestImage->Canvas->Pen->Style = psDot;
            DestImage->Canvas->Pen->Color = clYellow;
            DestImage->Canvas->Brush->Style = bsClear;
            DestImage->Canvas->MoveTo(0,ROIEndY + StrToInt(e3D_LaserGuideGapVal->Text));
            DestImage->Canvas->LineTo(1277, ROIEndY + StrToInt(e3D_LaserGuideGapVal->Text));
        }
        DestImage->Repaint();
			}
			else if (RangerCaptureMode == ERCM_3D)
			{
				if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
					CaptureData, LineFrameCaptureWidth * LineFrameCaptureHeight))
				{
					throw(0);
				}

        unsigned char ConversionImage[LINE_FRAME_WIDTH_RANGER_3D * LINE_FRAME_HEIGHT_RANGER_3D];
        memset(ConversionImage, 0, LINE_FRAME_WIDTH_RANGER_3D * LINE_FRAME_HEIGHT_RANGER_3D);

        float value;
        float subval;
        int k;
        int tempAddress;

        for (int y = 0; y < LineFrameCaptureHeight / 2; y++)
				{
					for (int x = 0; x < LineFrameCaptureWidth * 2; x=x+2)
					{
            //value = CaptureData[(y * LineFrameCaptureWidth * 2) + x + 1] * 256;
            //subval = CaptureData[(y * LineFrameCaptureWidth * 2) + x + 2];

            subval = CaptureData[(y * LineFrameCaptureWidth * 2) + x + 0];
            value = CaptureData[(y * LineFrameCaptureWidth * 2) + x + 1] * 256;
            k = min(255, (int)(((value + subval) / 65535) * 255.0));

            //k = min(255, CaptureData[(y * LineFrameCaptureWidth * 2) + x + 1]);

            tempAddress = LINE_FRAME_WIDTH_RANGER_3D * y + x / 2;

            if(k)
            {
              ThreeDRAWData[tempAddress] = value + subval; 
              ConversionImage[tempAddress] = (unsigned char)(255 - k);
            }
            else
            {
              ThreeDRAWData[tempAddress] = 0;
              ConversionImage[tempAddress] = 0;

            }
					}
				}

        for (int y = 0; y < LineFrameCaptureHeight / 2; y++)
				{
					byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];
					for (int x = 0; x < LineFrameCaptureWidth; x++)
					{
            tempAddress = LineFrameCaptureWidth * y + x;

            pBitmap[3*x + 0] = ConversionImage[tempAddress];
            pBitmap[3*x + 1] = ConversionImage[tempAddress];
            pBitmap[3*x + 2] = ConversionImage[tempAddress];
					}
				}

				DestImage->Repaint();
			}

      if(bImageGrabMode)
      {
        Doprocessing();
      }

			if (SaveSpeedButton->Down && SaveSpeedValue)
			{
				AnsiString dir = ImageDirectoryListBox->Directory + "\\" + IntToStr(ImageSubDirIndex);
				TFileStream *ImageFileStream;
				AnsiString ImagePath;
				if (!DirectoryExists(dir))
				{
					ForceDirectories(dir);
					UpdateImageFileList();
				}
				ImagePath +=dir+ "\\Image" + IntToStr(CurrentImageIndex) +".raw";
				ImageFileStream = new TFileStream(ImagePath,fmCreate);
				if(ImageFileStream)
				{
//20201106 cjg added 3d camera param
					if(RangerCaptureMode == ERCM_CALIB)	ImageFileStream->Write(FullScaleImage, FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT);
					else								ImageFileStream->Write(CaptureData,SYSTEM_CAMERA_WIDTH_3D* SYSTEM_CAMERA_HEIGHT_3D);
					
					delete ImageFileStream;
				}				
				DestImage->Picture->Bitmap->SaveToFile(dir + "\\Image" + IntToStr(CurrentImageIndex) + ".bmp");
				CurrentImageIndex++;
				ImageFileListBox->Update();
			}

			unsigned int elapsedTime = GetTickCount() - CaptureStartTime;
			if (elapsedTime > 0)
			{
				lblFPS->Caption = FloatToStr(1000 * 1000 / elapsedTime / 1000.0) + "FPS";
			}
			CaptureStartTime = GetTickCount();
			CaptureCount++;
			elapsedTime = GetTickCount() - CaptureFirstStartTime;
			if (elapsedTime > 0)
			{
				lblAvgFPS->Caption = FloatToStr(1000 * 1000 / elapsedTime * CaptureCount / 1000.0) + "FPS";
			}
			DestImage->Repaint();
			if (shRefresh->Brush->Color == clWhite)
			{
				shRefresh->Brush->Color = clBlack;
			}
			else
			{
				shRefresh->Brush->Color = clWhite;
			}
			if (bFrameCapture)
			{
				CaptureCheckTimer->Enabled = false;

        bImageGrabMode = false;
        SpeedButton2->Down = true;
        ProcessImageBtn->Enabled = true;
			}
		}
		else
		{
		}
	}
	catch (...)
	{
    CaptureCheckTimer->Enabled = false;
    bImageGrabMode = false;
    SpeedButton2->Down = true;
    ProcessImageBtn->Enabled = true;
	}
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::UpdateImageFileList(void)
{
	AnsiString dir = ImageDirectoryListBox->Directory + "\\" + IntToStr(ImageSubDirIndex);
	if (DirectoryExists(dir))
	{
		ImageFileListBox->Directory = dir;
	}
	else
	{
		ImageFileListBox->Clear();
	}
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::FormDestroy(TObject *Sender)
{
	delete[] CaptureData;
  delete[] FullScaleImage;
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::CalibrationModeSpeedButtonClick(
      TObject *Sender)
{
	RangerCaptureMode = ERCM_CALIB;
	DestImage->Width = AreaFrameCaptureWidth;
	DestImage->Height = AreaFrameCaptureHeight;
	DestImage->Picture->Bitmap->Width = DestImage->Width;
	DestImage->Picture->Bitmap->Height = DestImage->Height;
	DestImage->Picture->Bitmap->PixelFormat = pf24bit;

  DestImage->Canvas->Pen->Color = clWhite;
  DestImage->Canvas->Brush->Color = clWhite;
  DestImage->Canvas->Brush->Style = bsSolid;
  DestImage->Canvas->Rectangle(0, 0, DestImage->Width, DestImage->Height);
  
  HCBCaptureStartButton->Enabled = false;
  HCBCaptureStopButton->Enabled = false;

  CaptureStartButton->Enabled = false;
  CaptureStopButton->Enabled = false;

  Label2->Visible = false;
  RAWValueLabel->Visible = false;
  PreviewInspectionImageGroupBox->Visible = false;

  CaptureImage->BringToFront();

  CalModeBox->Width = AreaFrameCaptureWidth;
  ImageClickMode1->Width = 302;
  ImageClickMode2->Width = 302;
  ImageClickMode2->Left = 322;

  ImageClickMode1->Down = true;
  ImageClickMode1->Click();
  ImageClickMode2->Enabled = true;

  int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;
  bImageGrabMode = false;
  SpeedButton2->Down = true;
  ProcessImageBtn->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::ThreeDModeSpeedButtonClick(
	  TObject *Sender)
{
	RangerCaptureMode = ERCM_3D;
	DestImage->Width = LineFrameCaptureWidth;
	//DestImage->Height = LineFrameCaptureHeight;
  DestImage->Height = LineFrameCaptureHeight/2;
	DestImage->Picture->Bitmap->Width = DestImage->Width;
	DestImage->Picture->Bitmap->Height = DestImage->Height;
	DestImage->Picture->Bitmap->PixelFormat = pf24bit;

  DestImage->Canvas->Pen->Color = clWhite;
  DestImage->Canvas->Brush->Color = clWhite;
  DestImage->Canvas->Brush->Style = bsSolid;
  DestImage->Canvas->Rectangle(0, 0, DestImage->Width, DestImage->Height);
    
  HCBCaptureStartButton->Enabled = false;
  HCBCaptureStopButton->Enabled = false;

  CaptureStartButton->Enabled = false;
  CaptureStopButton->Enabled = false;

  Label2->Visible = true;
  RAWValueLabel->Visible = true;
  PreviewInspectionImageGroupBox->Visible = true;
  InitThreeDPrcComponents();

  CaptureImage->BringToFront();

  CalModeBox->Width = LineFrameCaptureWidth;
  ImageClickMode1->Width = 224;
  ImageClickMode2->Width = 224;
  ImageClickMode2->Left = 242;

  ImageClickMode1->Down = true;
  ImageClickMode1->Click();
  ImageClickMode2->Enabled = false;

  int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;
  bImageGrabMode = false;
  SpeedButton2->Down = true;
  ProcessImageBtn->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CloseButtonClick(TObject *Sender)
{
   RangerCaptureMode = ERCM_3D;

  // Calibration mode 해제
  // ROI를 설정한상태로 적용되도록 변경
  if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  ThreeDCameraSetup(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1, false);

  if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_3D)
  ThreeDCameraSetup(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1, false);
  
  for(int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_CONFIG);
  }

  if(LineScanTime_3D[0] != RANGER_3D_BASE_SHUTTER_SPEED || LineScanTime_3D[1] != RANGER_3D_BASE_SHUTTER_SPEED2)
  {
    //(Before : " + IntToStr(RANGER_3D_BASE_SHUTTER_SPEED) +
    //" //// " + "After : " + IntToStr(nThreeDLineScanFreq) + ")"
    if(MessageDlgFA("System Line Scan Frequency is Changed. Would you like to save it? ", mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
    {
      RANGER_3D_BASE_SHUTTER_SPEED = LineScanTime_3D[0];
      RANGER_3D_BASE_SHUTTER_SPEED2 = LineScanTime_3D[1];

      WriteDiskLineScanFrequency(ProgramPath.Env + "\\DiskLineScanFrequency.ini");
    }
  }

  if(!ProductData.ProductName.IsEmpty())
  {
    AdvMachineControlForm->ApplyProductInfo();
  }
  else
  {
    AdvMachineControlForm->ApplyDefaultParams();
  } 

  this->Close();
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::HCBCaptureStartButtonClick(
      TObject *Sender)
{
		bool bSuccess = true;

	TCaptureSetupData captureSetupData;

	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	captureSetupData.CaptureType = CAPTURE_TYPE_SINGLE_CAPTURE;
	captureSetupData.CaptureMode = CAPTURE_MODE_DEFAULT;

	if (CalibrationModeSpeedButton->Down)
	{
		captureSetupData.FrameBufferCount = 2;
		captureSetupData.ShutterSpeed[camIndex] = 100;
		captureSetupData.TriggerFreq[camIndex] = StrToInt(LineScanTimeEdit->Text);
    captureSetupData.SubsamplingMode[camIndex] = 0;
	}
	else
	{
		captureSetupData.FrameBufferCount = 4;
		captureSetupData.ShutterSpeed[camIndex] = 100;
		captureSetupData.TriggerFreq[camIndex] = StrToInt(LineScanTimeEdit->Text);
    captureSetupData.SubsamplingMode[camIndex] = 0;
	}

	captureSetupData.ShutterDelay[camIndex] = 0;
  captureSetupData.CameraMask = (0x0001 << camIndex);
	captureSetupData.ContainParams = 1;

  int ExposureTime;
  ExposureTime = StrToInt(cmdNFACameraData6->Text);
  
  RefreshCameraInfo(ExposureTime);
  captureSetupData.TabletType = 2;
  captureSetupData.SensorLength= 1000;
	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData),
    	NULL, 0))
  {
		bSuccess = false;
  }

	if (bSuccess)
	{
		CaptureStart(false, false);

		TCaptureCommandParam_HCB captureCommandParam_HCB;
		captureCommandParam_HCB.Action = 1;
		captureCommandParam_HCB.FrameTime = 100 * 20 + 0.5;
		captureCommandParam_HCB.LEDMask[0] = 0;
		captureCommandParam_HCB.LEDOnTime[0] = 3 * 20 + 0.5;
		captureCommandParam_HCB.ShutterDelay = 1 * 20 + 0.5;
		if (!Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
			NULL, 0))
		{
      CaptureCheckTimer->Enabled = false;

      bImageGrabMode = false;
      SpeedButton2->Down = true;
      ProcessImageBtn->Enabled = true;
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::HCBCaptureStopButtonClick(
	  TObject *Sender)
{
	TCaptureCommandParam_HCB captureCommandParam_HCB;
	captureCommandParam_HCB.Action = 0;

  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    for(int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
    {
      Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
    }
  }
    
	Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB), NULL, 0);
    
	CaptureCheckTimer->Enabled = false;
  bImageGrabMode = false;
  SpeedButton2->Down = true;
  ProcessImageBtn->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::RefreshSubImage(void)
{
	EnlargeImage->Canvas->CopyRect(Rect(0, 0, EnlargeImage->Width, EnlargeImage->Height), CaptureImage->Canvas, Rect(MousePos.x - 25, MousePos.y - 25, MousePos.x + 25, MousePos.y + 25));
	EnlargeImage->Canvas->Pen->Width = 1;
	EnlargeImage->Canvas->Pen->Mode = pmXor;
	EnlargeImage->Canvas->Pen->Style = psSolid;
	EnlargeImage->Canvas->MoveTo(25, 24);
	EnlargeImage->Canvas->LineTo(25, 26);
	EnlargeImage->Canvas->MoveTo(24, 25);
	EnlargeImage->Canvas->LineTo(26, 25);
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::RefreshPixelInfo(int X, int Y)
{
	TColor color = CaptureImage->Canvas->Pixels[X][Y];
	int redVal = color & 0xFF;
	int greenVal = (color >> 8) & 0xFF;
	int blueVal = (color >> 16) & 0xFF;

	AnsiString redText = IntToStr(redVal);
	AnsiString greenText = IntToStr(greenVal);
	AnsiString blueText = IntToStr(blueVal);

	RedImage->Canvas->Brush->Color = clRed;
	RedImage->Canvas->Font->Color = clWhite;
	RedImage->Canvas->TextRect(Rect(0, 0, redVal * RedImage->Width / 255, RedImage->Height),
		(RedImage->Width - RedImage->Canvas->TextWidth(redText)) / 2,
		(RedImage->Height - RedImage->Canvas->TextHeight(redText)) / 2, redText);
  	RedImage->Canvas->Brush->Color = clWhite;
	RedImage->Canvas->Font->Color = clRed;
	RedImage->Canvas->TextRect(Rect(redVal * RedImage->Width / 255, 0, RedImage->Width, RedImage->Height),
		(RedImage->Width - RedImage->Canvas->TextWidth(redText)) / 2,
		(RedImage->Height - RedImage->Canvas->TextHeight(redText)) / 2, redText);
  RedImage->Refresh();

	GreenImage->Canvas->Brush->Color = clGreen;
	GreenImage->Canvas->Font->Color = clWhite;
	GreenImage->Canvas->TextRect(Rect(0, 0, greenVal * GreenImage->Width / 255, GreenImage->Height),
		(GreenImage->Width - GreenImage->Canvas->TextWidth(greenText)) / 2,
		(GreenImage->Height - GreenImage->Canvas->TextHeight(greenText)) / 2, greenText);
	GreenImage->Canvas->Brush->Color = clWhite;
	GreenImage->Canvas->Font->Color = clGreen;
	GreenImage->Canvas->TextRect(Rect(greenVal * GreenImage->Width / 255, 0, GreenImage->Width, GreenImage->Height),
		(GreenImage->Width - GreenImage->Canvas->TextWidth(greenText)) / 2,
		(GreenImage->Height - GreenImage->Canvas->TextHeight(greenText)) / 2, greenText);
  GreenImage->Refresh();

	BlueImage->Canvas->Brush->Color = clBlue;
	BlueImage->Canvas->Font->Color = clWhite;
	BlueImage->Canvas->TextRect(Rect(0, 0, blueVal * BlueImage->Width / 255, BlueImage->Height),
		(BlueImage->Width - BlueImage->Canvas->TextWidth(blueText)) / 2,
		(BlueImage->Height - BlueImage->Canvas->TextHeight(blueText)) / 2, blueText);
	BlueImage->Canvas->Brush->Color = clWhite;
	BlueImage->Canvas->Font->Color = clBlue;
	BlueImage->Canvas->TextRect(Rect(blueVal * BlueImage->Width / 255, 0, BlueImage->Width, BlueImage->Height),
		(BlueImage->Width - BlueImage->Canvas->TextWidth(blueText)) / 2,
		(BlueImage->Height - BlueImage->Canvas->TextHeight(blueText)) / 2, blueText);
  BlueImage->Refresh();

 
  int rawValue = ThreeDRAWData[LINE_FRAME_WIDTH_RANGER_3D * Y + X];
  RAWValueLabel->Caption = IntToStr(rawValue) + " (0x" + IntToHex(rawValue, 4) + ")";
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::NumEditClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
    try
    {
		  theEdit->Text = KeyboardForm->Text;

      if(theEdit->Name == "LineScanTimeEdit")
      {
        if(CameraSpeedButton5->Down)
          LineScanTime_3D[0] = StrToInt(theEdit->Text);
        else
          LineScanTime_3D[1] = StrToInt(theEdit->Text);
      }
    }
    catch(...)
    {
      ShowMessage("Input Error");
    }
	}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::AdvMachineControlButtonClick(
      TObject *Sender)
{
	AdvMachineControlForm->ShowModal();	
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::SetupButtonClick(TObject *Sender)
{
  //camera comm write
  bool Result = ThreeDCameraSetup(GlobalCameraIndex, true);

  if(!Result)
  {
    ShowMessage("Setup success");

    if(RangerCaptureMode == ERCM_3D)
    {
      HCBCaptureStartButton->Enabled = true;
      HCBCaptureStopButton->Enabled = true;

      CaptureStartButton->Enabled = true;
      CaptureStopButton->Enabled = true;
    }
    else
    {
      HCBCaptureStartButton->Enabled = false;
      HCBCaptureStopButton->Enabled = false;

      CaptureStartButton->Enabled = true;
      CaptureStopButton->Enabled = true;
    }
  }
}
//---------------------------------------------------------------------------

bool __fastcall TCameraSetting3DForm::ThreeDCameraSetup(int cameraIndex, bool bCalib)
{
  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[cameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;
  bImageGrabMode = false;
  SpeedButton2->Down = true;
  ProcessImageBtn->Enabled = true;
  
  if(bCalib == true)
  {
    // Set Transmission Data
    int StartX, EndX, StartY, EndY;
    StartX = StrToInt(cmdNFACameraData2->Text);
    EndX = StartX + StrToInt(cmdNFACameraData3->Text);
    StartY = StrToInt(cmdNFACameraData4->Text);
    EndY = StartY + StrToInt(cmdNFACameraData5->Text);

    if(RangerCaptureMode == ERCM_CALIB)
    {
      Data[ECAMERA_PARAM_3D_WAVE_TABLE] = 11;

      Data[ECAMERA_PARAM_3D_ROI_START_X] = 0;
      Data[ECAMERA_PARAM_3D_ROI_END_X] = 1279;
      Data[ECAMERA_PARAM_3D_ROI_START_Y] = 0;
      Data[ECAMERA_PARAM_3D_ROI_END_Y] = 1023;

      Data[ECAMERA_PARAM_3D_IMAGE_MODE] = 1;
    }
    else
    {
      Data[ECAMERA_PARAM_3D_WAVE_TABLE] = CSpinEdit1->Value;

      Data[ECAMERA_PARAM_3D_ROI_START_X] = StrToInt(cmdNFACameraData2->Text);
      Data[ECAMERA_PARAM_3D_ROI_END_X] = min(1279, Data[1] + StrToInt(cmdNFACameraData3->Text));
      Data[ECAMERA_PARAM_3D_ROI_START_Y] = StrToInt(cmdNFACameraData4->Text);
      Data[ECAMERA_PARAM_3D_ROI_END_Y] = min(1023, Data[3] + StrToInt(cmdNFACameraData5->Text));

      Data[ECAMERA_PARAM_3D_IMAGE_MODE] = 2;
    }

    Data[ECAMERA_PARAM_3D_SHUTTER_TIME] = StrToInt(cmdNFACameraData6->Text);
    Data[ECAMERA_PARAM_3D_THRESHOLD] = StrToInt(cmdNFACameraData7->Text);

    Data[ECAMERA_PARAM_3D_ANALOG_GAIN] = cmdNFACameraData8->Value;

    Data[ECAMERA_PARAM_3D_BINNING_MODE] = cmdNFACameraData1->ItemIndex;
    Data[ECAMERA_PARAM_3D_TRIGGER_MODE] = cmdNFACameraData9->ItemIndex;

    ThreeDCameraDefaultInformation[cameraIndex].WaveTableIndex = CSpinEdit1->Value;

    ThreeDCameraDefaultInformation[cameraIndex].ROIStartX = StartX;
    ThreeDCameraDefaultInformation[cameraIndex].ROIWidth = EndX - StartX;
    ThreeDCameraDefaultInformation[cameraIndex].ROIStartY = StartY;
    ThreeDCameraDefaultInformation[cameraIndex].ROIHeight = EndY - StartY;

    ThreeDCameraDefaultInformation[cameraIndex].ExposureTime = Data[5];
    ThreeDCameraDefaultInformation[cameraIndex].Thresold3D = Data[6];
    ThreeDCameraDefaultInformation[cameraIndex].AnalogCameraGain = Data[7];
    ThreeDCameraDefaultInformation[cameraIndex].ImageOutputMode = Data[8];
    ThreeDCameraDefaultInformation[cameraIndex].BiningMode = Data[9];
    ThreeDCameraDefaultInformation[cameraIndex].TriggerMode = Data[10];

    ThreeDCameraDefaultInformation[cameraIndex].DataSettingSW = 1;
  }
  else
  {
    // Set Transmission Data

    ThreeDCameraDefaultInformation[cameraIndex].ImageOutputMode = 2;
    
    Data[ECAMERA_PARAM_3D_WAVE_TABLE] = ThreeDCameraDefaultInformation[cameraIndex].WaveTableIndex;

    Data[ECAMERA_PARAM_3D_ROI_START_X] = ThreeDCameraDefaultInformation[cameraIndex].ROIStartX;
    Data[ECAMERA_PARAM_3D_ROI_END_X] = min(1279, Data[1] + ThreeDCameraDefaultInformation[cameraIndex].ROIWidth);
    Data[ECAMERA_PARAM_3D_ROI_START_Y] = ThreeDCameraDefaultInformation[cameraIndex].ROIStartY;
    Data[ECAMERA_PARAM_3D_ROI_END_Y] = min(1023, Data[3] + ThreeDCameraDefaultInformation[cameraIndex].ROIHeight);

    Data[ECAMERA_PARAM_3D_SHUTTER_TIME] = ThreeDCameraDefaultInformation[cameraIndex].ExposureTime;
    Data[ECAMERA_PARAM_3D_THRESHOLD] = ThreeDCameraDefaultInformation[cameraIndex].Thresold3D;
    Data[ECAMERA_PARAM_3D_ANALOG_GAIN] = ThreeDCameraDefaultInformation[cameraIndex].AnalogCameraGain;
    Data[ECAMERA_PARAM_3D_IMAGE_MODE] = ThreeDCameraDefaultInformation[cameraIndex].ImageOutputMode;
    Data[ECAMERA_PARAM_3D_BINNING_MODE] = ThreeDCameraDefaultInformation[cameraIndex].BiningMode;
    Data[ECAMERA_PARAM_3D_TRIGGER_MODE] = ThreeDCameraDefaultInformation[cameraIndex].TriggerMode;
  }

  const int MAX_COMM_DATA_LENGTH = 20;
  char TxData[MAX_COMM_DATA_LENGTH];
  char RxData[MAX_COMM_DATA_LENGTH];
  bool bRead = false;
  bool bBreakSW = false;
  bool bErrorData = false;

  TCommDataLength CommDataLength;

  for(int dIndex = 0; dIndex < MAX_3D_CAMERA_DATA_INDEX; dIndex++)
  {
    // check
    if(dIndex == ECAMERA_PARAM_3D_WAVE_TABLE) continue;
    if(dIndex == ECAMERA_PARAM_3D_THRESHOLD) continue;

    if(Data[dIndex] != -1)
    {
      memset(TxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);
      memset(RxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);

      CommDataLength = MakeCameraWriteDataPacket(TxData, cameraIndex, Data, dIndex);

      if(!RequestCameraCommand(TxData, RxData, CommDataLength.SendDataLength, CommDataLength.ReceivedDataLength, cameraIndex, 0))
      {
        bBreakSW = true;
      }

      if(RxData[0] == 'T' && RxData[1] == 'O')
      {
		    bBreakSW = true;
	    }

      if(bBreakSW)
      {
        bErrorData = true;
        break;
      }

      // Write 한 정보 패스
      if(dIndex == ECAMERA_PARAM_3D_ROI_START_X) dIndex += 3;
    }
  }

  if(bErrorData)
  {
    ShowMessage("Fail to write");
  }
  else
  {
    if(bCalib)
    {
      if(RangerCaptureMode == ERCM_CALIB)
      {
        Data[1] = StrToInt(cmdNFACameraData2->Text);
        Data[2] = min(1279, Data[1] + StrToInt(cmdNFACameraData3->Text));
        Data[3] = StrToInt(cmdNFACameraData4->Text);
        Data[4] = min(1023, Data[3] + StrToInt(cmdNFACameraData5->Text));

        ThreeDCameraDefaultInformation[cameraIndex].ROIStartX = Data[1];
        ThreeDCameraDefaultInformation[cameraIndex].ROIWidth = Data[2] - Data[1];
        ThreeDCameraDefaultInformation[cameraIndex].ROIStartY = Data[3];
        ThreeDCameraDefaultInformation[cameraIndex].ROIHeight = Data[4] - Data[3];
      }

      // Write 한 정보를 ini 파일로 유지
      VariableCameraInformation[cameraIndex].ROIStartX =  Data[ECAMERA_PARAM_3D_ROI_START_X];
      VariableCameraInformation[cameraIndex].ROIStartY =  Data[ECAMERA_PARAM_3D_ROI_START_Y];
      VariableCameraInformation[cameraIndex].ROIEndX =    Data[ECAMERA_PARAM_3D_ROI_END_X];
      VariableCameraInformation[cameraIndex].ROIEndY =    Data[ECAMERA_PARAM_3D_ROI_END_Y];

      AnsiString filePath;

      //write한 데이터 중 가변 변수
      filePath = ProgramPath.Env + "\\NFACameraInformation.ini";
      WriteCameraInformation(filePath, cameraIndex);

      //write한 전체 데이터
      filePath = ProgramPath.Env + "\\ThreeDCameraDefaultInfo.ini";
      Write3DCameraDefaultInformation(filePath, cameraIndex);
    }
    else
    {
      FlashWrite(cameraIndex);
    }
  }

  return bErrorData;
}
//---------------------------------------------------------------------------
TCommDataLength __fastcall TCameraSetting3DForm::MakeCameraWriteDataPacket(char *code, int cameraIndex, int *cameraData, int dataIndex)
{
  /*********************************************************************************
    B1      B2      B3      B4      B5      B6      B7      ~Bn     Bn+1      Bn+2
    Header  Length          ID      Cmd             Data            Tail      Chk
  **********************************************************************************/
  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  int camIndex = CameraMapInfo[cameraIndex].CamIndex;

  unsigned int pLength;
  unsigned char LCmd, HCmd;
  TCommDataLength CommDataLength;

  const int HEADER_ST_PTR   = 0;
  const int LENGTH_ST_PTR   = 1;
  const int CAM_INFO_ST_PTR = 3;
  const int CMD_ST_PTR      = 4;
  const int DATA_ST_PTR     = 6;

  const int FIXED_PACKET_LENGTH  = 8;

  if(dataIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_BINNING_MODE_L;
    HCmd = CAMERA_DATA_CMD_BINNING_MODE_H;

    code[DATA_ST_PTR] = TxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ROI_START_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_START_Y ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_Y)
  {
    CommDataLength.SendDataLength = 9;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_L;
    HCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_H;
 
    code[DATA_ST_PTR + 0] = 0x00; // CH
    code[DATA_ST_PTR + 1] = (0x00FF & cameraData[dataIndex + 0]);
    code[DATA_ST_PTR + 2] = (0xFF00 & cameraData[dataIndex + 0]) >> 8;
    code[DATA_ST_PTR + 3] = (0x00FF & cameraData[dataIndex + 1]);
    code[DATA_ST_PTR + 4] = (0xFF00 & cameraData[dataIndex + 1]) >> 8;
    code[DATA_ST_PTR + 5] = (0x00FF & cameraData[dataIndex + 2]);
    code[DATA_ST_PTR + 6] = (0xFF00 & cameraData[dataIndex + 2]) >> 8;
    code[DATA_ST_PTR + 7] = (0x00FF & cameraData[dataIndex + 3]);
    code[DATA_ST_PTR + 8] = (0xFF00 & cameraData[dataIndex + 3]) >> 8;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_SHUTTER_TIME)
  {
    // check     
    CommDataLength.SendDataLength = 4;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_SHUTTER_L;
    HCmd = CAMERA_DATA_CMD_SHUTTER_H;

    code[DATA_ST_PTR + 0] = (0x000000FF & cameraData[dataIndex]);
    code[DATA_ST_PTR + 1] = (0x0000FF00 & cameraData[dataIndex]) >> 8;
    code[DATA_ST_PTR + 2] = (0x00FF0000 & cameraData[dataIndex]) >> 16;
    code[DATA_ST_PTR + 3] = (0xFF000000 & cameraData[dataIndex]) >> 24;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_THRESHOLD)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_THR_L;
    HCmd = CAMERA_DATA_CMD_THR_H;

    code[DATA_ST_PTR] = cameraData[dataIndex];
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_A_GAIN_L;
    HCmd = CAMERA_DATA_CMD_A_GAIN_H;

    code[DATA_ST_PTR] = TxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_L;
    HCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_H;

    code[DATA_ST_PTR] = TxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_TRIGGER_MODE_L;
    HCmd = CAMERA_DATA_CMD_TRIGGER_MODE_H;

    code[DATA_ST_PTR] = TxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_WAVE_TABLE_L;
    HCmd = CAMERA_DATA_WAVE_TABLE_H;

    code[DATA_ST_PTR] = TxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  
  code[HEADER_ST_PTR] = CAMERA_DATA_HEADER;

  code[LENGTH_ST_PTR + 0] = (0x00FF & CommDataLength.SendDataLength);
  code[LENGTH_ST_PTR + 1] = (0xFF00 & CommDataLength.SendDataLength) >> 8;

  code[CMD_ST_PTR + 0] = LCmd;
  code[CMD_ST_PTR + 1] = HCmd;

  code[CAM_INFO_ST_PTR + 0] = (camIndex + 1) << 4;

  code[DATA_ST_PTR + CommDataLength.SendDataLength + 0] = 0xAE; // Tail
  code[DATA_ST_PTR + CommDataLength.SendDataLength + 1] = 0x00; // CheckSum

  CommDataLength.SendDataLength += FIXED_PACKET_LENGTH;
  CommDataLength.ReceivedDataLength += FIXED_PACKET_LENGTH;

  return CommDataLength;
}
//---------------------------------------------------------------------------

unsigned char __fastcall TCameraSetting3DForm::TxValueInterpreter(int cameraIndex, int *cameraData, int dIndex)
{
   unsigned char rValue = 0x00;

  if(dIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    if(cameraData[dIndex] == 0)
      rValue = 0x00;
    else
      rValue = 0x03;
  }
  else if(dIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    // 확인필요!!
    rValue = cameraData[dIndex]; 
  }
  else if(dIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    rValue = cameraData[dIndex];
  }
  else if(dIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    rValue = cameraData[dIndex];
  }
  else if(dIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    rValue = cameraData[dIndex];
  }

  return rValue;
}
//---------------------------------------------------------------------------

bool __fastcall TCameraSetting3DForm::RequestCameraCommand(char *sendData, char *receivedData, unsigned int SendDataLength, unsigned int ReceiveDataLength, int cameraIndex, int highLatencyCmdSW)
{
  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  bool errorSW;
  const int MAX_COMM_DATA_LENGTH = 20;
  char tempSendData[MAX_COMM_DATA_LENGTH];
  memcpy(tempSendData + 2, sendData, sizeof(char) * SendDataLength);
  *(tempSendData + 0) = SendDataLength;
  *(tempSendData + 1) = ReceiveDataLength;
  SendDataLength += 2;

  errorSW = false;
  if(0)//highLatencyCmdSW)
  {
    Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);
    if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_CONTROL_PARTIAL_MODE, tempSendData, SendDataLength, receivedData, ReceiveDataLength))
    {
      errorSW = true;
    }
    Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
  }
  else
  {
    Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);
    if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_CONTROL_NORMAL_MODE, tempSendData, SendDataLength, receivedData, ReceiveDataLength))
    {
      errorSW = true;
    }
    Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
  }

  if(errorSW)
  {
    ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
  }
  return !errorSW;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::RefreshCameraInfo(int ShutterTime)
{
  TROIInfo ROIInfo;
  int ShutterSpeed = 0;
  int WriteMask = 0;
  ShutterSpeed = ShutterTime;

  WriteMask |= CAMERA_WRITE_MASK_3D_SH;

  SetCameraInformation(ROIInfo, ShutterSpeed, NULL,0, GlobalCameraIndex, WriteMask);
}

//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::cmdNFACameraData2Click(
      TObject *Sender)
{
  TEdit *theEdit = (TEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;

	if (KeyboardForm->ShowKeypad() == mrOk)
	{
    try
    {
      int tempValue;
      tempValue = StrToInt(KeyboardForm->Text);

      if(theEdit->Tag == 0) // Width
      {
        if(tempValue < 0 || tempValue > 1278)
        {
          throw(0);
        }
        else if(StrToInt(cmdNFACameraData3->Text) + tempValue > 1278)
        {
          cmdNFACameraData3->Text = IntToStr(1278 - tempValue);
        }
      }
      else if(theEdit->Tag == 1) // Width
      {
        if(tempValue < 0 || tempValue > 511)
        {
          throw(0);
        }
        else if(StrToInt(cmdNFACameraData2->Text) + tempValue > 1279)
        {
          tempValue = 1279 - StrToInt(cmdNFACameraData2->Text);
        }
      }
      else if(theEdit->Tag == 2) // Height
      {
        if(tempValue < 0 || tempValue > 1022)
        {
          throw(0);
        }
        else if(StrToInt(cmdNFACameraData5->Text) + tempValue > 1022)
        {
          cmdNFACameraData5->Text = IntToStr(1022 - tempValue);
        }
      }
      else if(theEdit->Tag == 3) // Height
      {
        if(tempValue < 0 || tempValue > 127)
        {
          throw(0);
        }
        else if(StrToInt(cmdNFACameraData4->Text) + tempValue > 1023)
        {
          tempValue = 1023 - StrToInt(cmdNFACameraData2->Text);
        }
      }

		  theEdit->Text = IntToStr(tempValue);
    }
    catch(...)
    {
      ShowMessage("Input error");
    }
	}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::cmdNFACameraData8Click(
      TObject *Sender)
{
  TCSpinEdit *theEdit = (TCSpinEdit *) Sender;
	KeyboardForm->Text = theEdit->Text; 
  
	if (KeyboardForm->ShowKeypad() == mrOk)
	{
    try
    {
		  theEdit->Value = StrToInt(KeyboardForm->Text);
    }
    catch(...)
    {
      ShowMessage("Input error");
    }
	}  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::Button1Click(TObject *Sender)
{
 //GlobalCameraIndex = 0; // test
  
  const int MAX_COMM_DATA_LENGTH = 20;
  char TxData[MAX_COMM_DATA_LENGTH];
  char RxData[MAX_COMM_DATA_LENGTH];
  bool bBreakSW = false;
  bool bErrorData = false;

  TCommDataLength CommDataLength;

  for(int dIndex = 0; dIndex < MAX_3D_CAMERA_DATA_INDEX; dIndex++)
  {
    // check
    if(dIndex == ECAMERA_PARAM_3D_THRESHOLD) continue;

    if(Data[dIndex] != -1)
    {
      memset(TxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);
      memset(RxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);

      CommDataLength = ReadMakeCameraDataPacket(TxData, GlobalCameraIndex, dIndex);
      if(!RequestCameraCommand(TxData, RxData, CommDataLength.SendDataLength, CommDataLength.ReceivedDataLength,GlobalCameraIndex, 0))
      {
        bBreakSW = true;
      }

      if(RxData[0] == 'T' && RxData[1] == 'O')
      {
		    bBreakSW = true;
	    }

      if(bBreakSW)
      {
        bErrorData = true;
        break;
      }

      GetCameraValue(RxData, GlobalCameraIndex, dIndex);

      // Read 한 정보 패스
      if(dIndex == ECAMERA_PARAM_3D_ROI_START_X) dIndex += 3;
    }
  }

  if(bErrorData)
  {
    ShowMessage("Fail to read");
  }
  else
  {
    ShowMessage("Success to read");
  }
}
//---------------------------------------------------------------------------

TCommDataLength __fastcall TCameraSetting3DForm::ReadMakeCameraDataPacket(char *code, int cameraIndex, int dataIndex)
{
  /*********************************************************************************
    B1      B2      B3      B4      B5      B6      B7      ~Bn     Bn+1      Bn+2
    Header  Length          ID      Cmd             Data            Tail      Chk
  **********************************************************************************/
  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  int camIndex = CameraMapInfo[cameraIndex].CamIndex;

  unsigned int pLength;
  unsigned char LCmd, HCmd;
  TCommDataLength CommDataLength;

  const int HEADER_ST_PTR   = 0;
  const int LENGTH_ST_PTR   = 1;
  const int CAM_INFO_ST_PTR = 3;
  const int CMD_ST_PTR      = 4;
  const int DATA_ST_PTR     = 6;

  const int FIXED_PACKET_LENGTH  = 8;

  if(dataIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_BINNING_MODE_L;
    HCmd = CAMERA_DATA_CMD_BINNING_MODE_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ROI_START_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_START_Y ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_Y)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 9;

    LCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_L;
    HCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_H;
 
    code[DATA_ST_PTR] = 0x00; // CH
  }
  else if(dataIndex == ECAMERA_PARAM_3D_SHUTTER_TIME)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 4;

    LCmd = CAMERA_DATA_CMD_SHUTTER_L;
    HCmd = CAMERA_DATA_CMD_SHUTTER_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_THRESHOLD)
  {
    // check
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_THR_L;
    HCmd = CAMERA_DATA_CMD_THR_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_A_GAIN_L;
    HCmd = CAMERA_DATA_CMD_A_GAIN_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_L;
    HCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_TRIGGER_MODE_L;
    HCmd = CAMERA_DATA_CMD_TRIGGER_MODE_H;

    code[DATA_ST_PTR] = 0x00;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_WAVE_TABLE_L;
    HCmd = CAMERA_DATA_WAVE_TABLE_H;

    code[DATA_ST_PTR] = 0x00;
  }
  
  code[HEADER_ST_PTR] = CAMERA_DATA_HEADER;

  code[LENGTH_ST_PTR + 0] = (0x00FF & CommDataLength.SendDataLength);
  code[LENGTH_ST_PTR + 1] = (0xFF00 & CommDataLength.SendDataLength) >> 8;

  code[CMD_ST_PTR + 0] = LCmd;
  code[CMD_ST_PTR + 1] = HCmd + 0x01;

  code[CAM_INFO_ST_PTR + 0] = (camIndex + 1) << 4;

  code[DATA_ST_PTR + CommDataLength.SendDataLength + 0] = 0xAE; // Tail
  code[DATA_ST_PTR + CommDataLength.SendDataLength + 1] = 0x00; // CheckSum

  CommDataLength.SendDataLength += FIXED_PACKET_LENGTH;
  CommDataLength.ReceivedDataLength += FIXED_PACKET_LENGTH;

  return CommDataLength;
}

//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::GetCameraValue(char *buff, int cameraIndex, int dataIndex)
{
  const int DATA_ST_PTR = 6;

  if(dataIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    cmdNFACameraData1->ItemIndex = buff[DATA_ST_PTR];
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ROI_START_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_START_Y ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_Y)
  {
    int startX;
    int endX;
    int startY;
    int endY;

    startX =  (buff[DATA_ST_PTR + 1] & 0x000000FF) | ((buff[DATA_ST_PTR + 2] & 0x000000FF) << 8);
    endX =    (buff[DATA_ST_PTR + 3] & 0x000000FF) | ((buff[DATA_ST_PTR + 4] & 0x000000FF) << 8);
    startY =  (buff[DATA_ST_PTR + 5] & 0x000000FF) | ((buff[DATA_ST_PTR + 6] & 0x000000FF) << 8);
    endY =    (buff[DATA_ST_PTR + 7] & 0x000000FF) | ((buff[DATA_ST_PTR + 8] & 0x000000FF) << 8);

    cmdNFACameraData2->Text = IntToStr(startX);
    cmdNFACameraData3->Text = IntToStr(endX - startX);
    cmdNFACameraData4->Text = IntToStr(startY);
    cmdNFACameraData5->Text = IntToStr(endY - startY);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_SHUTTER_TIME)
  {
    //check
    int SutterSpeed = ((buff[DATA_ST_PTR + 0] & 0x000000FF) |
                       ((buff[DATA_ST_PTR + 1] & 0x000000FF) << 8) |
                       ((buff[DATA_ST_PTR + 2] & 0x000000FF) << 16) |
                       ((buff[DATA_ST_PTR + 3] & 0x000000FF) << 24));

    cmdNFACameraData6->Text = IntToStr(SutterSpeed);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_THRESHOLD)
  {
    //check
    cmdNFACameraData7->Text = IntToStr(buff[DATA_ST_PTR] & 0x000000FF);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    cmdNFACameraData8->Value = buff[DATA_ST_PTR] & 0x000000FF;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    if(buff[DATA_ST_PTR] == 0)
    {
      CalibrationModeSpeedButton->Down = true;
    }
    else
    {
      ThreeDModeSpeedButton->Down = true;
    }
  }
  else if(dataIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    cmdNFACameraData9->ItemIndex = buff[DATA_ST_PTR];
  }
  else if(dataIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    CSpinEdit1->Value = buff[DATA_ST_PTR] & 0x000000FF;
  }
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::FlashWrite(int cameraIndex)
{
  const int MAX_COMM_DATA_LENGTH = 20;
  char TxData[MAX_COMM_DATA_LENGTH];
  char RxData[MAX_COMM_DATA_LENGTH];
  bool bRead = true;
  bool bError = false;
  TCommDataLength CommDataLength;

  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  int camIndex = CameraMapInfo[cameraIndex].CamIndex;

  memset(TxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);
  memset(RxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);

  CommDataLength.SendDataLength = 9;
  CommDataLength.ReceivedDataLength = 9;

  TxData[0] = 0xA1;
  TxData[1] = 0x01;
  TxData[2] = 0x00;
  TxData[3] = ((camIndex + 1) << 4) & 0xF0;
  TxData[4] = CAMERA_DATA_FLASH_WRITE_L;
  TxData[5] = CAMERA_DATA_FLASH_WRITE_H;
  TxData[6] = 0x01;
  TxData[7] = 0xAE;
  TxData[8] = 0x00;

  if(!RequestCameraCommand(TxData, RxData, CommDataLength.SendDataLength, CommDataLength.ReceivedDataLength, cameraIndex, 0))
  {
    ShowMessage("[Error]IPB Communication");

    bError = true;
  }

  if(RxData[0] == 'T' && RxData[1] == 'O')
  {
    ShowMessage("[Error]Camera Timeout");

    bError = true;
  }
}
//----------------------------------------------------------------
void __fastcall TCameraSetting3DForm::Button2Click(TObject *Sender)
{
  ThreeDCameraDefaultInformation[GlobalCameraIndex].BiningMode =          0;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX =           0;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth =            479;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY =           0;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight =           127;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ImageOutputMode =     1;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].ExposureTime =        50000;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].Thresold3D =          50;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].AnalogCameraGain =    0;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].TriggerMode = 1;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].WaveTableIndex = 3;
  ThreeDCameraDefaultInformation[GlobalCameraIndex].DataSettingSW  = 0;

  if(ThreeDCameraDefaultInformation[GlobalCameraIndex].BiningMode == 0)
    cmdNFACameraData1->ItemIndex = 0;
  else
    cmdNFACameraData1->ItemIndex = 1;
  cmdNFACameraData2->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX);
  cmdNFACameraData3->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth);
  cmdNFACameraData4->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY);
  cmdNFACameraData5->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight);
  cmdNFACameraData6->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].ExposureTime);
  cmdNFACameraData7->Text = IntToStr(ThreeDCameraDefaultInformation[GlobalCameraIndex].Thresold3D);
  cmdNFACameraData8->Value = ThreeDCameraDefaultInformation[GlobalCameraIndex].AnalogCameraGain;

  ThreeDModeSpeedButton->Down = true;
  ThreeDModeSpeedButton->Click();

  cmdNFACameraData9->ItemIndex = ThreeDCameraDefaultInformation[GlobalCameraIndex].TriggerMode;
  CSpinEdit1->Value = ThreeDCameraDefaultInformation[GlobalCameraIndex].WaveTableIndex;

  ThreeDCameraSetup(GlobalCameraIndex, true);

  //SetDefaultValue(GlobalCameraIndex);
}
//------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::SetDefaultValue(int cameraIndex)
{
  const int MAX_COMM_DATA_LENGTH = 20;
  char TxData[MAX_COMM_DATA_LENGTH];
  char RxData[MAX_COMM_DATA_LENGTH];
  bool bRead = true;
  bool bError = false;
  TCommDataLength CommDataLength;

  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  int camIndex = CameraMapInfo[cameraIndex].CamIndex;

  memset(TxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);
  memset(RxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);

  CommDataLength.SendDataLength = 9;
  CommDataLength.ReceivedDataLength = 9;

  TxData[0] = 0xA1;
  TxData[1] = 0x01;
  TxData[2] = 0x00;
  TxData[3] = ((camIndex + 1) << 4) & 0xF0;
  TxData[4] = CAMERA_DATA_FLASH_WRITE_L;
  TxData[5] = CAMERA_DATA_FLASH_WRITE_H;
  TxData[6] = 0x00;
  TxData[7] = 0xAE;
  TxData[8] = 0x00;

  if(!RequestCameraCommand(TxData, RxData, CommDataLength.SendDataLength, CommDataLength.ReceivedDataLength, cameraIndex, 0))
  {
    ShowMessage("[Error]IPB Communication");

    bError = true;
  }

  if(RxData[0] == 'T' && RxData[1] == 'O')
  {
    ShowMessage("[Error]Camera Timeout");

    bError = true;
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------
void gThreeDCameraSetup(int cameraIndex)
{
  // load ini file
	AnsiString fileName = ProgramPath.Env + "\\ThreeDCameraDefaultInfo.ini";

  if(FileExists(fileName))
  {
    if(!Read3DCameraDefaultInformation(fileName, cameraIndex))
    {
      //MessageDlgFA("(3D)Camera: " + IntToStr(cameraIndex + 1) + "The initial value does not exist. Please proceed with camera settings.", mtConfirmation, TMsgDlgButtons() << mbOK);
      MessageDlgFA("(3D)Camera: " + IntToStr(cameraIndex + 1) + "The initial value does not exist. Please proceed with camera settings.", mtConfirmation, TMsgDlgButtons() << mbOK);
      return;
    }
  }
  else
  {
    //MessageDlgFA("3D)Camera: "+IntToStr(cameraIndex + 1) + "The initial value does not exist. Please proceed with camera settings.", mtConfirmation, TMsgDlgButtons() << mbOK);
    MessageDlgFA(CAMERASETTING3DFORM_MSG_03 + " " + IntToStr(cameraIndex + 1) + " " + CAMERASETTING3DFORM_MSG_04, mtConfirmation, TMsgDlgButtons() << mbOK);
    return;
  }

  // Set Transmission Data

  ThreeDCameraDefaultInformation[cameraIndex].ImageOutputMode = 2;

  int CameraData[MAX_3D_CAMERA_DATA_INDEX];
  CameraData[ECAMERA_PARAM_3D_WAVE_TABLE] = ThreeDCameraDefaultInformation[cameraIndex].WaveTableIndex;

  CameraData[ECAMERA_PARAM_3D_ROI_START_X] = ThreeDCameraDefaultInformation[cameraIndex].ROIStartX;
  CameraData[ECAMERA_PARAM_3D_ROI_END_X] = min(1279, CameraData[1] + ThreeDCameraDefaultInformation[cameraIndex].ROIWidth);
  CameraData[ECAMERA_PARAM_3D_ROI_START_Y] = ThreeDCameraDefaultInformation[cameraIndex].ROIStartY;
  CameraData[ECAMERA_PARAM_3D_ROI_END_Y] = min(1023, CameraData[3] + ThreeDCameraDefaultInformation[cameraIndex].ROIHeight);

  CameraData[ECAMERA_PARAM_3D_SHUTTER_TIME] = ThreeDCameraDefaultInformation[cameraIndex].ExposureTime;
  CameraData[ECAMERA_PARAM_3D_THRESHOLD] = ThreeDCameraDefaultInformation[cameraIndex].Thresold3D;
  CameraData[ECAMERA_PARAM_3D_ANALOG_GAIN] = ThreeDCameraDefaultInformation[cameraIndex].AnalogCameraGain;
  CameraData[ECAMERA_PARAM_3D_IMAGE_MODE] = ThreeDCameraDefaultInformation[cameraIndex].ImageOutputMode;
  CameraData[ECAMERA_PARAM_3D_BINNING_MODE] = ThreeDCameraDefaultInformation[cameraIndex].BiningMode;
  CameraData[ECAMERA_PARAM_3D_TRIGGER_MODE] = ThreeDCameraDefaultInformation[cameraIndex].TriggerMode;
  
  const int MAX_COMM_DATA_LENGTH = 20;
  char TxData[MAX_COMM_DATA_LENGTH];
  char RxData[MAX_COMM_DATA_LENGTH];
  bool bRead = false;
  bool bBreakSW = false;
  bool bErrorData = false;

  TCommDataLength CommDataLength;

  for(int dIndex = 0; dIndex < MAX_3D_CAMERA_DATA_INDEX; dIndex++)
  {
    // check
    if(dIndex == ECAMERA_PARAM_3D_WAVE_TABLE) continue;
    if(dIndex == ECAMERA_PARAM_3D_THRESHOLD) continue;

    if(CameraData[dIndex] != -1)
    {
      memset(TxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);
      memset(RxData, 0, sizeof(char) * MAX_COMM_DATA_LENGTH);

      CommDataLength = gMakeCameraWriteDataPacket(TxData, cameraIndex, CameraData, dIndex);

      if(!gRequestCameraCommand(TxData, RxData, CommDataLength.SendDataLength, CommDataLength.ReceivedDataLength, cameraIndex, 0))
      {
        bBreakSW = true;
      }

      if(RxData[0] == 'T' && RxData[1] == 'O')
      {
		    bBreakSW = true;
	    }

      if(bBreakSW)
      {
        bErrorData = true;
        break;
      }

      // Write 한 정보 패스
      if(dIndex == ECAMERA_PARAM_3D_ROI_START_X) dIndex += 3;
    }
  }

  if(bErrorData)
  {
    MessageDlgFA("Failed to set #" + IntToStr(cameraIndex + 1) + " 3D Camera ", mtConfirmation, TMsgDlgButtons() << mbOK);
  }
}
//---------------------------------------------------------------------------
TCommDataLength gMakeCameraWriteDataPacket(char *code, int cameraIndex, int *cameraData, int dataIndex)
{
  /*********************************************************************************
    B1      B2      B3      B4      B5      B6      B7      ~Bn     Bn+1      Bn+2
    Header  Length          ID      Cmd             Data            Tail      Chk
  **********************************************************************************/
  int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  int camIndex = CameraMapInfo[cameraIndex].CamIndex;

  unsigned int pLength;
  unsigned char LCmd, HCmd;
  TCommDataLength CommDataLength;

  const int HEADER_ST_PTR   = 0;
  const int LENGTH_ST_PTR   = 1;
  const int CAM_INFO_ST_PTR = 3;
  const int CMD_ST_PTR      = 4;
  const int DATA_ST_PTR     = 6;

  const int FIXED_PACKET_LENGTH  = 8;

  if(dataIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_BINNING_MODE_L;
    HCmd = CAMERA_DATA_CMD_BINNING_MODE_H;

    code[DATA_ST_PTR] = gTxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ROI_START_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_X ||
          dataIndex == ECAMERA_PARAM_3D_ROI_START_Y ||
          dataIndex == ECAMERA_PARAM_3D_ROI_END_Y)
  {
    CommDataLength.SendDataLength = 9;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_L;
    HCmd = CAMERA_DATA_CMD_ACTIVE_WINDOW_H;
 
    code[DATA_ST_PTR + 0] = 0x00; // CH
    code[DATA_ST_PTR + 1] = (0x00FF & cameraData[dataIndex + 0]);
    code[DATA_ST_PTR + 2] = (0xFF00 & cameraData[dataIndex + 0]) >> 8;
    code[DATA_ST_PTR + 3] = (0x00FF & cameraData[dataIndex + 1]);
    code[DATA_ST_PTR + 4] = (0xFF00 & cameraData[dataIndex + 1]) >> 8;
    code[DATA_ST_PTR + 5] = (0x00FF & cameraData[dataIndex + 2]);
    code[DATA_ST_PTR + 6] = (0xFF00 & cameraData[dataIndex + 2]) >> 8;
    code[DATA_ST_PTR + 7] = (0x00FF & cameraData[dataIndex + 3]);
    code[DATA_ST_PTR + 8] = (0xFF00 & cameraData[dataIndex + 3]) >> 8;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_SHUTTER_TIME)
  {
    // check     
    CommDataLength.SendDataLength = 4;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_SHUTTER_L;
    HCmd = CAMERA_DATA_CMD_SHUTTER_H;

    code[DATA_ST_PTR + 0] = (0x000000FF & cameraData[dataIndex]);
    code[DATA_ST_PTR + 1] = (0x0000FF00 & cameraData[dataIndex]) >> 8;
    code[DATA_ST_PTR + 2] = (0x00FF0000 & cameraData[dataIndex]) >> 16;
    code[DATA_ST_PTR + 3] = (0xFF000000 & cameraData[dataIndex]) >> 24;
  }
  else if(dataIndex == ECAMERA_PARAM_3D_THRESHOLD)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_THR_L;
    HCmd = CAMERA_DATA_CMD_THR_H;

    code[DATA_ST_PTR] = cameraData[dataIndex];
  }
  else if(dataIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_A_GAIN_L;
    HCmd = CAMERA_DATA_CMD_A_GAIN_H;

    code[DATA_ST_PTR] = gTxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_L;
    HCmd = CAMERA_DATA_CMD_3D_IMAGE_MODE_H;

    code[DATA_ST_PTR] = gTxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_CMD_TRIGGER_MODE_L;
    HCmd = CAMERA_DATA_CMD_TRIGGER_MODE_H;

    code[DATA_ST_PTR] = gTxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  else if(dataIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    CommDataLength.SendDataLength = 1;
    CommDataLength.ReceivedDataLength = 1;

    LCmd = CAMERA_DATA_WAVE_TABLE_L;
    HCmd = CAMERA_DATA_WAVE_TABLE_H;

    code[DATA_ST_PTR] = gTxValueInterpreter(cameraIndex, cameraData, dataIndex);
  }
  
  code[HEADER_ST_PTR] = CAMERA_DATA_HEADER;

  code[LENGTH_ST_PTR + 0] = (0x00FF & CommDataLength.SendDataLength);
  code[LENGTH_ST_PTR + 1] = (0xFF00 & CommDataLength.SendDataLength) >> 8;

  code[CMD_ST_PTR + 0] = LCmd;
  code[CMD_ST_PTR + 1] = HCmd;

  code[CAM_INFO_ST_PTR + 0] = (camIndex + 1) << 4;

  code[DATA_ST_PTR + CommDataLength.SendDataLength + 0] = 0xAE; // Tail
  code[DATA_ST_PTR + CommDataLength.SendDataLength + 1] = 0x00; // CheckSum

  CommDataLength.SendDataLength += FIXED_PACKET_LENGTH;
  CommDataLength.ReceivedDataLength += FIXED_PACKET_LENGTH;

  return CommDataLength;
}

//---------------------------------------------------------------------------

bool gRequestCameraCommand(char *sendData, char *receivedData, unsigned int SendDataLength, unsigned int ReceiveDataLength, int cameraIndex, int highLatencyCmdSW)
{
	int spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
  bool errorSW;
  const int MAX_COMM_DATA_LENGTH = 20;
  char tempSendData[MAX_COMM_DATA_LENGTH];
  memcpy(tempSendData + 2, sendData, sizeof(char) * SendDataLength);
  *(tempSendData + 0) = SendDataLength;
  *(tempSendData + 1) = ReceiveDataLength;
  SendDataLength += 2;

  errorSW = false;
  if(0)//highLatencyCmdSW)
  {
    Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);
    if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_CONTROL_PARTIAL_MODE, tempSendData, SendDataLength, receivedData, ReceiveDataLength))
    {
      errorSW = true;
    }
    Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
  }
  else
  {
    Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);
    if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_CONTROL_NORMAL_MODE, tempSendData, SendDataLength, receivedData, ReceiveDataLength))
    {
      errorSW = true;
    }
    Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
  }

  if(errorSW)
  {
    ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
  }
  return !errorSW;
}
//---------------------------------------------------------------------------

unsigned char gTxValueInterpreter(int cameraIndex, int *cameraData, int dIndex)
{
  unsigned char rValue = 0x00;

  if(dIndex == ECAMERA_PARAM_3D_BINNING_MODE)
  {
    if(cameraData[dIndex] == 0)
      rValue = 0x00;
    else
      rValue = 0x03;
  }
  else if(dIndex == ECAMERA_PARAM_3D_ANALOG_GAIN)
  {
    // 확인필요!!
    rValue = cameraData[dIndex]; 
  }
  else if(dIndex == ECAMERA_PARAM_3D_IMAGE_MODE)
  {
    rValue = cameraData[dIndex];
  }
  else if(dIndex == ECAMERA_PARAM_3D_TRIGGER_MODE)
  {
    rValue = cameraData[dIndex];
  }
  else if(dIndex == ECAMERA_PARAM_3D_WAVE_TABLE)
  {
    rValue = cameraData[dIndex];
  }

  return rValue;
}

//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::ImageClickMode1Click(TObject *Sender)
{
  eImageClickEvent = CLICK_EVENT_GET_COLOR_INFO;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::ImageClickMode2Click(TObject *Sender)
{
  eImageClickEvent = CLICK_EVENT_SET_ROI_POS;

  if (RangerCaptureMode == ERCM_CALIB)
  {
    int ROIStartX, ROIEndX, ROIStartY, ROIEndY;
    
    ROIStartX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2;
    ROIEndX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2 + ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth / 2;
    ROIStartY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY;
    ROIEndY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY+ ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight;
  
    DestImage->Canvas->Pen->Width = 1;
    DestImage->Canvas->Pen->Style = psDot;
    DestImage->Canvas->Pen->Color = clRed;
    DestImage->Canvas->Brush->Style = bsClear;
    DestImage->Canvas->Rectangle(ROIStartX, ROIStartY, ROIEndX, ROIEndY);
    DestImage->Repaint();
  }
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CaptureImageMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  if(RangerCaptureMode == ERCM_CALIB)
  {
    if(eImageClickEvent == CLICK_EVENT_SET_ROI_POS)
    {
      int ErrorCode = 0;
      try
      {
        int ROIStartX, ROIEndX, ROIStartY, ROIEndY;
        int tempX, tempY;

        int x = X * 2;
        int y = Y;

        tempX = (x / 32) * 32;
        tempY = y;

        int Width, Height;
        Width = StrToInt(cmdNFACameraData3->Text);
        Height = StrToInt(cmdNFACameraData5->Text);

        if(tempX + Width > 1279)
        {
          ErrorCode = 1;
          throw(0);
        }

        if(tempY + Height > 1022)
        {
          ErrorCode = 2;
          throw(0);
        }

        cmdNFACameraData2->Text = IntToStr(tempX);
        cmdNFACameraData4->Text = IntToStr(tempY);

        ThreeDCameraSetup(GlobalCameraIndex, true);

        for (int y = 0; y < AREA_FRAME_HEIGHT_RANGER_3D; y++)
        {
          byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

          for (int x = 0; x < AREA_FRAME_WIDTH_RANGER_3D; x++)
          {
            pBitmap[0] = ScaleConversionImage[y * AreaFrameCaptureWidth + x];
            pBitmap[1] = ScaleConversionImage[y * AreaFrameCaptureWidth + x];
            pBitmap[2] = ScaleConversionImage[y * AreaFrameCaptureWidth + x];

            pBitmap += 3;
          }
        }

        ROIStartX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2;
        ROIEndX = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartX / 2 + ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIWidth / 2;
        ROIStartY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY;
        ROIEndY = ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIStartY+ ThreeDCameraDefaultInformation[GlobalCameraIndex].ROIHeight;

        DestImage->Canvas->Pen->Width = 1;
        DestImage->Canvas->Pen->Style = psDot;
        DestImage->Canvas->Pen->Color = clRed;
        DestImage->Canvas->Brush->Style = bsClear;
        DestImage->Canvas->Rectangle(ROIStartX, ROIStartY, ROIEndX, ROIEndY);
//        DestImage->Repaint();

//20210228 cjg laser guide line
        if(cb3D_LaserGuideEnable->Checked)
        {
            DestImage->Canvas->Pen->Width = 1;
            DestImage->Canvas->Pen->Style = psDot;
            DestImage->Canvas->Pen->Color = clYellow;
            DestImage->Canvas->Brush->Style = bsClear;
            DestImage->Canvas->MoveTo(0,ROIEndY + StrToInt(e3D_LaserGuideGapVal->Text));
            DestImage->Canvas->LineTo(1277, ROIEndY + StrToInt(e3D_LaserGuideGapVal->Text));
        }
        DestImage->Repaint();
      }
      catch(...)
      {
        if(ErrorCode == 1)
          ShowMessage("X-axis area is out of tolerance.");//X축 영역이 허용범위를 벗어났습니다.");
        else if(ErrorCode == 2)
          ShowMessage("Y-axis area is out of tolerance.");
      }
    }
    else
    {
      MousePos.x = X;
      MousePos.y = Y;
      RefreshSubImage();
      RefreshPixelInfo(MousePos.x, MousePos.y);
    }
  }
  else
  {
    if(eImageClickEvent == CLICK_EVENT_GET_COLOR_INFO)
    {
      MousePos.x = X;
      MousePos.y = Y;
      RefreshSubImage();
      RefreshPixelInfo(MousePos.x, MousePos.y);
    }
  }
}
//---------------------------------------------------------------------------


void __fastcall TCameraSetting3DForm::TriggerMethodRadioBox1Click(
      TObject *Sender)
{
  if(bSendSetupData)
  {
    int spbIndex = CameraMapInfo[fstThreeDCameraIndex].SPBIndex;
    SPBSystemSetupData[spbIndex].ThreeDCaptureMethod = TriggerMethodRadioBox1->ItemIndex;

    TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\SystemInfor.ini");
    if (iniFile)
    {
      iniFile->WriteInteger("SPB " + IntToStr(spbIndex + 1), "ThreeD Capture Method", SPBSystemSetupData[spbIndex].ThreeDCaptureMethod);

      delete iniFile;
    }

    SendSystemSetupData();
  }
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::TriggerMethodRadioBox2Click(
      TObject *Sender)
{
  if(bSendSetupData)
  {
    int spbIndex = CameraMapInfo[secThreeDCameraIndex].SPBIndex;
    SPBSystemSetupData[spbIndex].ThreeDCaptureMethod = TriggerMethodRadioBox2->ItemIndex;

    TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\SystemInfor.ini");
    if (iniFile)
    {
      iniFile->WriteInteger("SPB " + IntToStr(spbIndex + 1), "ThreeD Capture Method", SPBSystemSetupData[spbIndex].ThreeDCaptureMethod);

      delete iniFile;
    }

    SendSystemSetupData();
  }
}

//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::FirstCalEnableBtnClick(TObject *Sender)
{
	if(FirstCalEnable)
	{
    TntPageControl1->Visible = false;
    TntPageControl1->Enabled = false;
		ySliceImage->Visible = false;
		FirstCalEnableBtn->Caption = "Disabled Camera Setup Mode";
		FirstCalEnable = false;

    DummySpeedBtn->Down = true;
	}
	else
	{
    TntPageControl1->Visible = true;
    TntPageControl1->Enabled = true;
		ySliceImage->Visible = true;
		FirstCalEnableBtn->Caption = "Enabled Camera Setup Mode";
		FirstCalEnable = true;

    DummySpeedBtn->Down = false;
	}
}
//---------------------------------------------------------------------------



bool __fastcall TCameraSetting3DForm::FristCalConfigRead(int cameraIndex)
{
	TCameraInitParam initParam;
	int spbIndex;
  	memset(&initParam, 0x00, sizeof(initParam));
	spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_FIRST_CONFIG_READ, NULL, 0, &initParam, sizeof(initParam)))
	{
		ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
    		return 0;
	}
	else
	{
		for(int i = 0 ; i < 8 ; i++)
		{
			TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
			TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
			EditOffset->Text = IntToStr(initParam.Cam_Init_Offset[i]);
			EditGain->Text = IntToStr(initParam.Cma_Sys_Gain[i]);
		}
		CutOffLavel->Text=IntToStr(initParam.CutOff_Level);
		GainLevel->Text=IntToStr(initParam.Gain_Level);
		CogThreshold->Text=IntToStr(initParam.COG_Threshold);
		CogGain->Text=IntToStr(initParam.COG_Gain);
		CogOffset->Text=IntToStr(initParam.COG_Offset);
	}
  return 1;
}

bool __fastcall TCameraSetting3DForm::FristCalConfigWrite(int cameraIndex)
{
	TCameraInitParam initParam;
	int spbIndex;

	spbIndex = CameraMapInfo[cameraIndex].SPBIndex;
	for(int i = 0 ; i < 8 ; i++)
	{
		TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
		TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));

		initParam.Cam_Init_Offset[i] = StrToInt(EditOffset->Text);
		initParam.Cma_Sys_Gain[i] = StrToInt(EditGain->Text);
	}	
	initParam.CutOff_Level = StrToInt(CutOffLavel->Text);
	initParam.Gain_Level = StrToInt(GainLevel->Text);
	initParam.COG_Threshold = StrToInt(CogThreshold->Text);
	initParam.COG_Gain = StrToInt(CogGain->Text);
	initParam.COG_Offset = StrToInt(CogOffset->Text);

	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAMERA_FIRST_CONFIG_WRITE, &initParam, sizeof(initParam), NULL, 0))
	{
		ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
   		return 0;
	}
  return 1;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::SaveSpeedButtonClick(TObject *Sender)
{
	if(SaveSpeedValue)
	{
		SaveSpeedValue = false;
	}
	else
	{
		SaveSpeedValue = true;
	}
}
//---------------------------------------------------------------------------




void __fastcall TCameraSetting3DForm::CaptureImageMouseMove(
      TObject *Sender, TShiftState Shift, int X, int Y)
{
  if(RangerCaptureMode == ERCM_3D)
  {
    int x, y;
    int width;
    int height;
    unsigned char tempImage[480 * 256];
    memset(tempImage, 0, 480 * 256);

    width = CaptureImage->Picture->Bitmap->Width;
    height = CaptureImage->Picture->Bitmap->Height;

    for(x = 0; x < 480; x++)
    {
      Byte *ptr = (Byte *)CaptureImage->Picture->Bitmap->ScanLine[Y];

      int value = ptr[3*x + 1];
      if(value)
      {
        tempImage[480 * (255- value) + x] = 255;
      }
    }

    Graphics::TBitmap *img = new Graphics::TBitmap;
    img->Width = 480;
    img->Height = 256;
    img->PixelFormat = pf24bit;

    for(y = 0; y < 256; y++)
    {
      Byte *ptr = (Byte *)img->ScanLine[y];
      for(x = 0; x < 480; x++)
      {
        ptr[3*x + 0] = 0;
        ptr[3*x + 1] = 0;
        ptr[3*x + 2] = 0;

        if(tempImage[480 * y + x])
        {
          ptr[3*x + 0] = 255;
          ptr[3*x + 1] = 255;
          ptr[3*x + 2] = 255;
        }
      }
    }

    ySliceImage->Picture->Bitmap->Assign(img);
    ySliceImage->Refresh();

    delete img;
  }
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::InitThreeDPrcComponents()
{
  bImageGrabMode = false;
  ProcessImageBtn->Enabled = true;
  SpeedButton2->Down = true;
  ProcessingResultLabel->Font->Color = clBlack;
  ProcessingResultLabel->Caption = "NONE";

  PreviewImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
  PreviewImage->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
  PreviewImage->Canvas->Pen->Color = clBlack;
  PreviewImage->Canvas->Brush->Color = clBlack;
  PreviewImage->Canvas->Brush->Style = bsSolid;
  PreviewImage->Canvas->Rectangle(0, 0, PreviewImage->Picture->Bitmap->Width, PreviewImage->Picture->Bitmap->Height);

  StretchImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
  StretchImage->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
  StretchImage->Canvas->Pen->Color = clBlack;
  StretchImage->Canvas->Brush->Color = clBlack;
  StretchImage->Canvas->Brush->Style = bsSolid;
  StretchImage->Canvas->Rectangle(0, 0, StretchImage->Picture->Bitmap->Width, StretchImage->Picture->Bitmap->Height);
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::ProcessImageBtnClick(TObject *Sender)
{
  Doprocessing();
}
//---------------------------------------------------------------------------
int __fastcall TCameraSetting3DForm::PreProcessingForThreeD(unsigned char *ThreeD_Image)
{
	int x, y, r, m, n;
	int protoThrshold;
	int gradX, gradY;
	int tempCount;
	int i, j;
	int tempSum;
	int checkSW;
	int startX, endX, startY, endY;
	int tempAddress;
	int maxG;
	int smallSizeImagWidth;
	int smallSizeImagHeight;
	int maxLabelN;
	int edgeCheckSW;
	int rotateX, rotateY;
	int matchingValue;
	int thresholdForHalfArea;
	int histoSum;
	int histo[256];
	int eraseCount;
	int repeat;
	int halfImageWidth;
	int halfImageHeight;
	int tempAddress2;
	int smallTempAddress;
	short tempRotationShapePoint[3000][2];

	int meanStepBright = 0;
	int meanStepBrightCnt = 0;
	int stepN;
	int pixelDataForStepBrightCount[8];
	int notTransformPixelDataForStepBrightCount[8];
	int brightStepValue;
	int brightLevelStep[8];
	int extractPixelPercent;
	int selfValue;
	int selfValue_up;
	int selfValue_down;
	int selfValue_left;
	int selfValue_right;
	int selfValue_left_up;
	int selfValue_right_up;
	int selfValue_right_down;
	int selfValue_left_down;
	int up = -halfImageWidth;
	int down = halfImageWidth;
	int left = -1;
	int right = 1;
	int upleft = (-halfImageWidth - 1);
	int upright = (-halfImageWidth + 1);
	int downleft = (halfImageWidth - 1);
	int downright = (halfImageWidth + 1);
	int diffHeight1;
	int diffHeight2;
	int eraseSW;
	int edgeEraseRange;
  int ProtoTabletRotationAngle;
  int errorSW;
  int binMinX, binMaxX, binMinY, binMaxY;
  int maxBoundarySize;

  maxBoundarySize = 4;

  errorSW = 0;

	startX = 4;
	endX = SYSTEM_CAMERA_WIDTH - 4;
	startY = 4;
	endY = SYSTEM_CAMERA_HEIGHT - 4;

	protoThrshold = 1;

	smallSizeImagWidth = SYSTEM_CAMERA_WIDTH / 4;
	smallSizeImagHeight = SYSTEM_CAMERA_HEIGHT / 4;
	halfImageWidth = SYSTEM_CAMERA_WIDTH / 2;
	halfImageHeight = SYSTEM_CAMERA_HEIGHT / 2;

  memset(HalfTempImage, 0, halfImageWidth * halfImageHeight);
  memset(HalfShapeData, 0, halfImageWidth * halfImageHeight);
  memset(HalfShapeBinaryImage, 0, halfImageWidth * halfImageHeight);
  memset(HalfShrinkShapeBinaryImage, 0, halfImageWidth * halfImageHeight);
  memset(HalfLabelImage, 0, 2 * halfImageWidth * halfImageHeight);
  memset(AdjustThreeD_Data, 0, SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT);

  up = -halfImageWidth;
  down = halfImageWidth;
  left = -1;
  right = 1;
  upleft = (-halfImageWidth - 1);
  upright = (-halfImageWidth + 1);
  downleft = (halfImageWidth - 1);
  downright = (halfImageWidth + 1);

  for (y = startY; y < endY; y += 2)
  {
    for (x = startX; x < endX; x += 2)
    {
      tempAddress = (y / 2) * halfImageWidth + (x / 2);
      HalfTempImage[tempAddress] = ThreeD_Image[y * SYSTEM_CAMERA_WIDTH + x];
      HalfShapeData[tempAddress] = HalfTempImage[tempAddress];
    }
  }

  diffHeight1 = (int)(tan(70.0 * PI / 180.0) * 2.0 * 40.0 / 30.0);
  diffHeight2 = (int)(tan(70.0 * PI / 180.0) * 4.0 * 40.0 / 30.0);

  for (y = startY / 2; y < endY / 2; y++)
  {
    for (x = startX / 2; x < endX / 2; x++)
    {
      tempAddress = y * halfImageWidth + x;
      selfValue = HalfTempImage[tempAddress];
      if (selfValue > 1)
      {
        eraseSW = 0;
        selfValue_up = HalfTempImage[tempAddress + up];
        selfValue_down = HalfTempImage[tempAddress + down];
        selfValue_left = HalfTempImage[tempAddress - 1];
        selfValue_right = HalfTempImage[tempAddress + 1];
        selfValue_left_up = HalfTempImage[tempAddress + upleft];
        selfValue_right_up = HalfTempImage[tempAddress + upright];
        selfValue_right_down = HalfTempImage[tempAddress + downright];
        selfValue_left_down = HalfTempImage[tempAddress + downleft];

        if ((abs(selfValue - selfValue_up) > diffHeight1) && selfValue_up)
          eraseSW = 1;
        else if ((abs(selfValue - selfValue_down) > diffHeight1) && selfValue_down)
          eraseSW = 1;
        else if ((abs(selfValue - selfValue_left) > diffHeight1) && selfValue_left)
          eraseSW = 1;
        else if ((abs(selfValue - selfValue_right) > diffHeight1) && selfValue_right)
          eraseSW = 1;
        else if ((abs(selfValue_down - selfValue_up) > diffHeight2) && selfValue_up && selfValue_down)
          eraseSW = 1;
        else if ((abs(selfValue_right - selfValue_left) > diffHeight2) && selfValue_right && selfValue_left)
          eraseSW = 1;
        else if ((abs(selfValue_right_up - selfValue_left_down) > diffHeight2) && selfValue_right_up && selfValue_left_down)
          eraseSW = 1;
        else if ((abs(selfValue_right_down - selfValue_left_up) > diffHeight2) && selfValue_right_down && selfValue_left_up)
          eraseSW = 1;

        if (eraseSW == 1)
        {
          for (i = y - 1; i <= y + 1; i++)
          {
            for (j = x - 1; j <= x + 1; j++)
            {
              HalfShapeData[i * halfImageWidth + j] = 0;
            }
          }
        }
      }
    }
  }

  for (y = startY / 2; y < endY / 2; y++)
  {
    for (x = startX / 2; x < endX / 2; x++)
    {
      tempAddress = y * halfImageWidth + x;
      if (HalfShapeData[tempAddress] > protoThrshold)
      {
        HalfShapeBinaryImage[tempAddress] = 1;
      }
    }
  }

  maxLabelN = LabellingForTabletImage(HalfLabelImage, HalfShapeBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, halfImageWidth, halfImageHeight);
  if (maxLabelN != 0)
  {
    binMinX = halfImageWidth;
    binMaxX = 0;
    binMinY = halfImageHeight;
    binMaxY = 0;

    for (y = startY / 2 + 1; y < endY / 2 - 1; y++)
    {
      for (x = startX / 2 + 1; x < endX / 2 - 1; x++)
      {
        tempAddress = halfImageWidth * y + x;
        if (HalfLabelImage[tempAddress] == maxLabelN)
        {
          HalfShapeBinaryImage[tempAddress] = 2;
          HalfShrinkShapeBinaryImage[tempAddress] = 1;

          if(binMinX >= x) binMinX = x;
          if(binMaxX <= x) binMaxX = x;
          if(binMinY >= y) binMinY = y;
          if(binMaxY <= y) binMaxY = y;
        }
      }
    }

    if(binMinX <= maxBoundarySize ||
        binMaxX >= halfImageWidth - maxBoundarySize ||
        binMinY <= maxBoundarySize ||
        binMaxY >= halfImageHeight - maxBoundarySize)
    {
      errorSW = 2;
      return errorSW;
    }
    else if(binMinX == halfImageWidth ||
            binMaxX == 0 ||
            binMinY == halfImageHeight ||
            binMaxY == 0)
    {
      errorSW = 1;
      return errorSW;
    }
  }
  else
  {
    errorSW = 1;
    return errorSW;
  }

  for (y = startY / 2; y < endY / 2; y++)
  {
    for (x = startX / 2; x < endX / 2; x++)
    {
      tempAddress = y * halfImageWidth + x;
      if (HalfShapeBinaryImage[tempAddress] == 2)
      {
        edgeCheckSW = 0;
        for (i = y - 1; i <= y + 1; i++)
        {
          for (j = x - 1; j <= x + 1; j++)
          {
            if (HalfShapeBinaryImage[halfImageWidth * i + j] != 2)
            {
              edgeCheckSW = 1;
            }
          }
        }
        if (edgeCheckSW == 1)
        {
          for (i = y - 2; i <= y + 2; i++)
          {
            for (j = x - 2; j <= x + 2; j++)
            {
              HalfShrinkShapeBinaryImage[halfImageWidth * i + j] = 0;
            }
          }
        }
      }
    }
  }

  memset(HalfLabelImage, 0, 2 * halfImageWidth * halfImageHeight);
  memset(HalfShapeBinaryImage, 0, halfImageWidth * halfImageHeight);
  memset(HalfExtendShapeBinaryImage, 0, halfImageWidth * halfImageHeight);
  for (y = startY / 2; y < endY / 2; y++)
  {
    for (x = startX / 2; x < endX / 2; x++)
    {
      tempAddress = y * halfImageWidth + x;
      HalfShapeBinaryImage[tempAddress] = HalfTempImage[tempAddress];
    }
  }
  maxLabelN = LabellingForTabletImage(HalfLabelImage, HalfShapeBinaryImage, startX / 2, endX / 2, startY / 2, endY / 2, halfImageWidth, halfImageHeight);

  if (maxLabelN != 0)
  {
    binMinX = halfImageWidth;
    binMaxX = 0;
    binMinY = halfImageHeight;
    binMaxY = 0;
    
    for (y = startY / 2 + 1; y < endY / 2 - 1; y++)
    {
      for (x = startX / 2 + 1; x < endX / 2 - 1; x++)
      {
        tempAddress = halfImageWidth * (y)+x;
        if (HalfLabelImage[tempAddress] == maxLabelN)
        {
          HalfShapeBinaryImage[tempAddress] = 2;
          HalfExtendShapeBinaryImage[tempAddress] = 1;

          if(binMinX >= x) binMinX = x;
          if(binMaxX <= x) binMaxX = x;
          if(binMinY >= y) binMinY = y;
          if(binMaxY <= y) binMaxY = y;
        }
      }
    }

    if(binMinX <= maxBoundarySize ||
        binMaxX >= halfImageWidth - maxBoundarySize ||
        binMinY <= maxBoundarySize ||
        binMaxY >= halfImageHeight - maxBoundarySize)
    {
      errorSW = 2;
      return errorSW;
    }
    else if(binMinX == halfImageWidth ||
            binMaxX == 0 ||
            binMinY == halfImageHeight ||
            binMaxY == 0)
    {
      errorSW = 1;
      return errorSW;
    }
  }
  else
  {
    errorSW = 1;
    return errorSW;
  }

  for (y = startY / 2; y < endY / 2; y++)
  {
    for (x = startX / 2; x < endX / 2; x++)
    {
      tempAddress = y * (halfImageWidth)+x;
      if (HalfShapeBinaryImage[tempAddress] == 2)
      {
        for (i = y - 1; i <= y + 1; i++)
        {
          for (j = x - 1; j <= x + 1; j++)
          {
            HalfExtendShapeBinaryImage[i * halfImageWidth + j] = 1;
          }
        }
      }
    }
  }

  ProtoTabletCenterX = 0;
  ProtoTabletCenterY = 0;
  ProtoTabletCenterZ = 0;
  
  tempCount = 0;
  memset(ShapeBinaryImage, 0, SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT);
  memset(Temp_ShapeBinaryImage, 0, SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT);
  for (y = startY; y < endY; y++)
  {
    for (x = startX; x < endX; x++)
    {
      tempAddress = y * SYSTEM_CAMERA_WIDTH + x;
      if (HalfExtendShapeBinaryImage[(y / 2) * halfImageWidth + (x / 2)] == 1)
      {
        if (ThreeD_Image[tempAddress] > protoThrshold)
        {
          ShapeBinaryImage[tempAddress] = 1;
          Temp_ShapeBinaryImage[tempAddress] = 1;
          ProtoTabletCenterX += x;
          ProtoTabletCenterY += y;
          ProtoTabletCenterZ += ThreeD_Image[tempAddress];
          tempCount++;
        }
      }
    }
  }

  if (tempCount)
  {
    ProtoTabletCenterX /= tempCount;
    ProtoTabletCenterY /= tempCount;
    ProtoTabletCenterZ /= tempCount;
  }

  ProtoTabletRotationAngle = 0;
  if (ProtoTabletCenterX < 0) ProtoTabletCenterX = 0;
  if (ProtoTabletCenterX >= SYSTEM_CAMERA_WIDTH) ProtoTabletCenterX = SYSTEM_CAMERA_WIDTH - 1;
  if (ProtoTabletCenterY < 0) ProtoTabletCenterY = 0;
  if (ProtoTabletCenterY >= SYSTEM_CAMERA_HEIGHT) ProtoTabletCenterY = SYSTEM_CAMERA_HEIGHT - 1;

  FindRotationAxis(ThreeD_Image);
  Adjust_3D_Data(ThreeD_Image);

  return errorSW;
}

//---------------------------------------------------------------------------
int __fastcall TCameraSetting3DForm::LabellingForTabletImage(short *label_Image, unsigned char *smallSizeBinaryImage, int startX, int endX, int startY, int endY, int imageWidth, int imageHeight)
{
	int i, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	int newLval;
	int temp;
	int tempAddress;
	int maxLabelN;
	int maxLabelCount;
	int breakSW;
	unsigned short Pixel_N_Of_Label[MAX_LABEL_COUNT]; //4k
	int StartX_Label[MAX_LABEL_COUNT];
	int EndX_Label[MAX_LABEL_COUNT];
	int StartY_Label[MAX_LABEL_COUNT];
	int EndY_Label[MAX_LABEL_COUNT];

	currentLabel = 0;
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
		StartX_Label[i] = 640;
		EndX_Label[i] = 0;
		StartY_Label[i] = 640;
		EndY_Label[i] = 0;
	}

	breakSW = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			temp_address = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + temp_address))
			{
				if (*(label_Image + temp_address - imageWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'  
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - imageWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - imageWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > MAX_LABEL_COUNT)  newLval = MAX_LABEL_COUNT - 1;
	new_count = newLval;

	for (y = 0; y < imageHeight; y++)
	{
		for (x = 0; x < imageWidth; x++)
		{
			tempAddress = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + tempAddress))
			{
				temp = *(label_Image + tempAddress);
				temp = CollisionArray[temp];
				*(label_Image + tempAddress) = temp;
				Pixel_N_Of_Label[temp]++;
				if (StartX_Label[temp] > x)  StartX_Label[temp] = x;
				if (StartY_Label[temp] > y)  StartY_Label[temp] = y;
				if (EndX_Label[temp] < x)  EndX_Label[temp] = x;
				if (EndY_Label[temp] < y)  EndY_Label[temp] = y;
			}
		}
	}
	maxLabelN = 0;
	maxLabelCount = 0;
	for (i = 1; i <= new_count; i++)
	{
		if (Pixel_N_Of_Label[i] > maxLabelCount)
		{
			maxLabelN = i;
			maxLabelCount = Pixel_N_Of_Label[i];
		}
	}
	return(maxLabelN);
}
//---------------------------------------------------------------------------

int __fastcall TCameraSetting3DForm::FindRotationAxis(unsigned char *ThreeD_Image)
{
	int x, y, m;
	int startX, endX, startY, endY;
	int tempAddress;
	int edgeSW;
	int accumulationCount;
	int normalVecter[3];
	int point1[3];
	int point2[3];
	int point3[3];
	int vecterSizeSqr;
	int vecterSize;
	int tempCX, tempCY;
	int pX, pY;
	int uLength;
	int sinV;

	short shapeEdge[360][4];    //[0] = x, [1] = y, [3] = z  , [4] = is
	int angle;

	MeanNormalVecter[0] = 0;
	MeanNormalVecter[1] = 0;
	MeanNormalVecter[2] = 0;
	accumulationCount = 0;

	for (m = 0; m < 360; m++)
	{
		shapeEdge[m][0] = 0;
		shapeEdge[m][1] = 0;
		shapeEdge[m][2] = 0;
		shapeEdge[m][3] = 0;
	}
	startX = 4 / 2;
	endX = (SYSTEM_CAMERA_WIDTH - 4) / 2;
	startY = 4 / 2;
	endY = (SYSTEM_CAMERA_HEIGHT - 4) / 2;

	tempCX = ProtoTabletCenterX / 2;
	tempCY = ProtoTabletCenterY / 2;
  
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			tempAddress = y * (SYSTEM_CAMERA_WIDTH / 2) + x;
			if (HalfShrinkShapeBinaryImage[tempAddress] == 1)
			{
				edgeSW = 0;
				if (HalfShrinkShapeBinaryImage[tempAddress - 1] == 0)
				{
					edgeSW = 1;
				}
				else if (HalfShrinkShapeBinaryImage[tempAddress + 1] == 0)
				{
					edgeSW = 1;
				}
				else if (HalfShrinkShapeBinaryImage[tempAddress + SYSTEM_CAMERA_WIDTH / 2] == 0)
				{
					edgeSW = 1;
				}
				else if (HalfShrinkShapeBinaryImage[tempAddress - SYSTEM_CAMERA_WIDTH / 2] == 0)
				{
					edgeSW = 1;
				}
				if (edgeSW == 1)
				{
					pX = x - tempCX;
					pY = y - tempCY;
					uLength = pX * pX + pY * pY;
					if (uLength < 90000)
					{
						uLength = SqrtData[uLength]; //sqrtdata는 128이 곱해 진 상태.
						sinV = 1280000 * pX / uLength;
						if (sinV > 10000) sinV = 10000;
						if (pX >= 0 && pY <= 0)
							angle = ArcSinData[sinV];
						else if (pX >= 0 && pY > 0)
							angle = 180 - ArcSinData[sinV];
						else if (pX < 0 && pY > 0)
							angle = 180 + ArcSinData[-sinV];
						else
							angle = 360 - ArcSinData[-sinV];
					}

					angle = (angle + 360) % 360;
					shapeEdge[angle][0] = x * 2;
					shapeEdge[angle][1] = y * 2;
					shapeEdge[angle][2] = ThreeD_Image[(y * SYSTEM_CAMERA_WIDTH + x) * 2] * 30 / 40;
					shapeEdge[angle][3] = 1;
				}
			}
		}
	}

	//// 3점을 지나는 평면의 노멀 벡터 구하기///////
  for (m = 0; m < 360; m++)
  {
    if (shapeEdge[m][3] * shapeEdge[(m + 120) % 360][3] * shapeEdge[(m + 240) % 360][3] == 1)
    {
      point1[0] = shapeEdge[m][0];
      point1[1] = shapeEdge[m][1];
      point1[2] = shapeEdge[m][2];
      point2[0] = shapeEdge[(m + 120) % 360][0];
      point2[1] = shapeEdge[(m + 120) % 360][1];
      point2[2] = shapeEdge[(m + 120) % 360][2];
      point3[0] = shapeEdge[(m + 240) % 360][0];
      point3[1] = shapeEdge[(m + 240) % 360][1];
      point3[2] = shapeEdge[(m + 240) % 360][2];
      FindNormalVecter(point1, point2, point3, normalVecter);
      MeanNormalVecter[0] += normalVecter[0];
      MeanNormalVecter[1] += normalVecter[1];
      MeanNormalVecter[2] += normalVecter[2];
      accumulationCount++;
    }
  }

	if (accumulationCount)
	{
		MeanNormalVecter[0] /= accumulationCount;
		MeanNormalVecter[1] /= accumulationCount;
		MeanNormalVecter[2] /= accumulationCount;
	}
	if (MeanNormalVecter[2] < 0)
	{
		MeanNormalVecter[0] = -MeanNormalVecter[0];
		MeanNormalVecter[1] = -MeanNormalVecter[1];
		MeanNormalVecter[2] = -MeanNormalVecter[2];
	}

	vecterSizeSqr = MeanNormalVecter[0] * MeanNormalVecter[0] + MeanNormalVecter[1] * MeanNormalVecter[1] + MeanNormalVecter[2] * MeanNormalVecter[2];
	if (vecterSizeSqr)
	{
		vecterSize = sqrt(vecterSizeSqr);
		MeanNormalVecter[0] = 1024 * MeanNormalVecter[0] / vecterSize;    //(b, -a, 0)
		MeanNormalVecter[1] = 1024 * MeanNormalVecter[1] / vecterSize;    //(b, -a, 0)
		MeanNormalVecter[2] = 1024 * MeanNormalVecter[2] / vecterSize;    //(b, -a, 0)
	}
	else
	{
		MeanNormalVecter[0] = 0;
		MeanNormalVecter[1] = 0;
		MeanNormalVecter[2] = 0;
	}

	vecterSizeSqr = MeanNormalVecter[0] * MeanNormalVecter[0] + MeanNormalVecter[1] * MeanNormalVecter[1];
	if (vecterSizeSqr)
	{
		vecterSize = sqrt(vecterSizeSqr);
	}

	Cos_RotationAngle = MeanNormalVecter[2];  //c    1024가 곱해진 상태
	if (MeanNormalVecter[0] * MeanNormalVecter[0] + MeanNormalVecter[1] * MeanNormalVecter[1] != 0)
		Sin_RotationAngle = sqrt(MeanNormalVecter[0] * MeanNormalVecter[0] + MeanNormalVecter[1] * MeanNormalVecter[1]);  // a*a + b*b   1024가 곱해진 상태
	else
		Sin_RotationAngle = 0;

	Sin_RotationAngle = sqrt(1024 * 1024 - Cos_RotationAngle * Cos_RotationAngle);
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::Adjust_3D_Data(unsigned char *ThreeD_Image)
{
	int x, y, i, j;
	int startX, startY, endX, endY;
	int x_r, y_r, z_r;
	int tempX, tempY, tempZ;
	int constant1;
	int constant2;
	int tempAddress;
	int zSum;
	int zSumCount;
	int real_ProtoTabletCenterX;
	int real_ProtoTabletCenterY;
	int real_ProtoTabletCenterZ;
	int heightResolution;
  unsigned char TempThreeD_Image[SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT];

	startX = 4;
	endX = SYSTEM_CAMERA_WIDTH - 4;
	startY = 4;
	endY = SYSTEM_CAMERA_HEIGHT - 4;

	heightResolution = THREE_D_CAMERA_ZOOM * 1000 / 642 / 2;
	real_ProtoTabletCenterX = ProtoTabletCenterX * THREE_D_CAMERA_ZOOM;
	real_ProtoTabletCenterY = ProtoTabletCenterY * THREE_D_CAMERA_ZOOM;
	real_ProtoTabletCenterZ = ProtoTabletCenterZ * heightResolution;

	for (x = 0; x < 620 * 2 * 40; x++)
	{
		xyTransData[x] = ((x) / THREE_D_CAMERA_ZOOM);
	}
	for (x = 0; x < 256 * 2 * 30; x++)
	{
		zTransData[x] = ((x) / heightResolution);
	}
  
	if (Sin_RotationAngle)
	{
		constant1 = (1024 * 1024)*(1024 - Cos_RotationAngle) / (Sin_RotationAngle*Sin_RotationAngle);
		memset(TempThreeD_Image, 0, SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT);
		memset(AdjustThreeD_Data, 0, SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT);

		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (ShapeBinaryImage[y * SYSTEM_CAMERA_WIDTH + x])
				{
					tempX = (x - ProtoTabletCenterX)*THREE_D_CAMERA_ZOOM;
					tempY = (y - ProtoTabletCenterY)*THREE_D_CAMERA_ZOOM;
					tempZ = (ThreeD_Image[y*SYSTEM_CAMERA_WIDTH + x] - ProtoTabletCenterZ)*heightResolution;
					constant2 = constant1 * (MeanNormalVecter[1] * tempX - MeanNormalVecter[0] * tempY) / 1024;
					x_r = (tempX*Cos_RotationAngle + constant2 * MeanNormalVecter[1] / 1024 - MeanNormalVecter[0] * tempZ) / 1024 + real_ProtoTabletCenterX;
					y_r = (tempY*Cos_RotationAngle - constant2 * MeanNormalVecter[0] / 1024 - MeanNormalVecter[1] * tempZ) / 1024 + real_ProtoTabletCenterY;
					z_r = (tempZ*Cos_RotationAngle + (MeanNormalVecter[1] * tempY + MeanNormalVecter[0] * tempX)) / 1024 + real_ProtoTabletCenterZ;
					x_r = xyTransData[x_r];
					y_r = xyTransData[y_r];
					if (z_r < 0) z_r = 0;
					z_r = zTransData[z_r];
					tempAddress = y_r * SYSTEM_CAMERA_WIDTH + x_r;
					if (AdjustThreeD_Data[tempAddress] < z_r)
					{
						AdjustThreeD_Data[tempAddress] = z_r;
						TempThreeD_Image[tempAddress] = z_r;
					}
				}
			}
		}
    
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				tempAddress = y * SYSTEM_CAMERA_WIDTH + x;
				if (TempThreeD_Image[tempAddress] == 0)
				{
					zSum = 0;
					zSumCount = 0;
					for (i = y - 1; i <= y + 1; i++)
					{
						for (j = x - 1; j <= x + 1; j++)
						{
							if (TempThreeD_Image[i*SYSTEM_CAMERA_WIDTH + j])
							{
								zSum += TempThreeD_Image[i*SYSTEM_CAMERA_WIDTH + j];
								zSumCount++;
							}
						}
					}
					if (zSumCount)
						AdjustThreeD_Data[tempAddress] = zSum / zSumCount;
				}
			}
		}
	}
	else
	{
		memset(AdjustThreeD_Data, 0, SYSTEM_CAMERA_WIDTH*SYSTEM_CAMERA_HEIGHT);
		for (y = startY; y < endY; y++)
		{
			for (x = startX; x < endX; x++)
			{
				if (ShapeBinaryImage[y*SYSTEM_CAMERA_WIDTH + x])
				{
					AdjustThreeD_Data[y*SYSTEM_CAMERA_WIDTH + x] = ThreeD_Image[y*SYSTEM_CAMERA_WIDTH + x];
				}
			}
		}
	}
}

//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::FindNormalVecter(int *point1, int *point2, int *point3, int *normalVecter)
{
	//평면의 방정식 ax + by + cz = 1
	int a, b, c;
	int vecterSizeSqr;
	int vecterSize;
	int divideValue;
	TThreeDPoint ThreeDPoint1;
	TThreeDPoint ThreeDPoint2;
	TThreeDPoint ThreeDPoint3;
	ThreeDPoint1.px = point1[0];
	ThreeDPoint1.py = point1[1];
	ThreeDPoint1.pz = point1[2];
	ThreeDPoint2.px = point2[0];
	ThreeDPoint2.py = point2[1];
	ThreeDPoint2.pz = point2[2];
	ThreeDPoint3.px = point3[0];
	ThreeDPoint3.py = point3[1];
	ThreeDPoint3.pz = point3[2];
	a = ThreeDPoint1.py*ThreeDPoint3.pz + ThreeDPoint2.py*ThreeDPoint1.pz + ThreeDPoint3.py*ThreeDPoint2.pz
		- ThreeDPoint1.py*ThreeDPoint2.pz - ThreeDPoint2.py*ThreeDPoint3.pz - ThreeDPoint3.py*ThreeDPoint1.pz;
	b = ThreeDPoint1.px*ThreeDPoint2.pz + ThreeDPoint2.px*ThreeDPoint3.pz + ThreeDPoint3.px*ThreeDPoint1.pz
		- ThreeDPoint1.px*ThreeDPoint3.pz - ThreeDPoint2.px*ThreeDPoint1.pz - ThreeDPoint3.px*ThreeDPoint2.pz;
	c = ThreeDPoint1.px*ThreeDPoint3.py + ThreeDPoint2.px*ThreeDPoint1.py + ThreeDPoint3.px*ThreeDPoint2.py
		- ThreeDPoint1.px*ThreeDPoint2.py - ThreeDPoint2.px*ThreeDPoint3.py - ThreeDPoint3.px*ThreeDPoint1.py;

	// a*=4;
	// b*=4;
	// b = 0;
	if (abs(a) >= abs(b) && abs(a) >= abs(c))  //a가 가장 큰 경우
	{
		divideValue = abs(a) / 5000;
	}
	else if (abs(b) >= abs(a) && abs(b) >= abs(c)) // b가 가장 큰 경우
	{
		divideValue = abs(b) / 5000;
	}
	else   //c가 가장 큰 경우
	{
		divideValue = abs(c) / 5000;
	}
	if (divideValue)
	{
		a = a / divideValue;
		b = b / divideValue;
		c = c / divideValue;
	}
	if (c < 0)
	{
		a = -a;
		b = -b;
		c = -c;
	}
	vecterSizeSqr = (a*a + b * b + c * c);
	if (vecterSizeSqr)
	{
		vecterSize = sqrt(vecterSizeSqr);
		normalVecter[0] = 1024 * (a) / vecterSize;
		normalVecter[1] = 1024 * (b) / vecterSize;
		normalVecter[2] = 1024 * (c) / vecterSize;
	}
	else
	{
		normalVecter[0] = 0;
		normalVecter[1] = 0;
		normalVecter[2] = 0;
	}
}
//---------------------------------------------------------------------------
void __fastcall TCameraSetting3DForm::SpeedButton1Click(TObject *Sender)
{
  if(CaptureCheckTimer->Enabled == false)
  {
    ShowMessage("It can only be used while image shooting");
    SpeedButton2->Down = true;
    return;
  }

  ProcessImageBtn->Enabled = false;
  bImageGrabMode = true; 
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::Doprocessing()
{
  unsigned char halfThreeDData[(SYSTEM_CAMERA_WIDTH / 2) * SYSTEM_CAMERA_HEIGHT];
  memset(halfThreeDData, 0, (SYSTEM_CAMERA_WIDTH / 2) * SYSTEM_CAMERA_HEIGHT);

  unsigned char StretchThreeDData[SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT];
  memset(StretchThreeDData, 0, SYSTEM_CAMERA_WIDTH  * SYSTEM_CAMERA_HEIGHT);

  int x, y;
  int tempAddress;
  int halfImageWidth;
  Byte *ptr;

  halfImageWidth = SYSTEM_CAMERA_WIDTH / 2;

  for(y = 0; y < SYSTEM_CAMERA_WIDTH / 2; y++)
  {
    ptr = (Byte *)DestImage->Picture->Bitmap->ScanLine[y];
    for(x = 0; x < SYSTEM_CAMERA_HEIGHT; x++)
    {
      tempAddress = halfImageWidth * x + y;
      halfThreeDData[tempAddress] = ptr[3 * x + 1];
    }
  }

  for(y = 0; y < SYSTEM_CAMERA_HEIGHT; y++)
  {
    for(x = 0; x < SYSTEM_CAMERA_WIDTH; x++)
    {
      tempAddress = SYSTEM_CAMERA_WIDTH * y + x;
      StretchThreeDData[tempAddress] = halfThreeDData[halfImageWidth * y + (x / 2)];
    }
  }

  int errorID = PreProcessingForThreeD(StretchThreeDData);

  if(errorID == 1)
  {
    ProcessingResultLabel->Font->Color = clRed;
    ProcessingResultLabel->Caption = "Failed (Blank Image)";
  }
  else if(errorID == 2)
  {
    ProcessingResultLabel->Font->Color = clRed;
    ProcessingResultLabel->Caption = "Failed (Out Of Area)";
  }
  else
  {
    ProcessingResultLabel->Font->Color = clBlack;
    ProcessingResultLabel->Caption = "Completed";

    if(bImageGrabMode)
    {
      bImageGrabMode = false;
      SpeedButton2->Down = true;
      ProcessImageBtn->Enabled = true;
    }
  }

  PreviewImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
  PreviewImage->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
  PreviewImage->Canvas->Pen->Color = clBlack;
  PreviewImage->Canvas->Brush->Color = clBlack;
  PreviewImage->Canvas->Brush->Style = bsSolid;
  PreviewImage->Canvas->Rectangle(0, 0, PreviewImage->Picture->Bitmap->Width, PreviewImage->Picture->Bitmap->Height);

  StretchImage->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
  StretchImage->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
  StretchImage->Canvas->Pen->Color = clBlack;
  StretchImage->Canvas->Brush->Color = clBlack;
  StretchImage->Canvas->Brush->Style = bsSolid;
  StretchImage->Canvas->Rectangle(0, 0, StretchImage->Picture->Bitmap->Width, StretchImage->Picture->Bitmap->Height);

  Graphics::TBitmap *img1;
	img1 = new Graphics::TBitmap();
	img1->Width = SYSTEM_CAMERA_WIDTH;
	img1->Height = SYSTEM_CAMERA_HEIGHT;
	img1->PixelFormat = pf24bit;

  for(y = 0; y < SYSTEM_CAMERA_HEIGHT; y++)
  {
    ptr = (Byte *)img1->ScanLine[y];
    for(x = 0; x < SYSTEM_CAMERA_WIDTH; x++)
    {
      tempAddress = SYSTEM_CAMERA_WIDTH * y + x;
      ptr[3 * x + 0] = StretchThreeDData[tempAddress];
      ptr[3 * x + 1] = StretchThreeDData[tempAddress];
      ptr[3 * x + 2] = StretchThreeDData[tempAddress];
    }
  }

  StretchImage->Picture->Bitmap->Assign(img1);
  StretchImage->Refresh();

  for(y = 0; y < SYSTEM_CAMERA_HEIGHT; y++)
  {
    ptr = (Byte *)img1->ScanLine[y];
    for(x = 0; x < SYSTEM_CAMERA_WIDTH; x++)
    {
      tempAddress = SYSTEM_CAMERA_WIDTH * y + x;
      ptr[3 * x + 0] = AdjustThreeD_Data[tempAddress];
      ptr[3 * x + 1] = AdjustThreeD_Data[tempAddress];
      ptr[3 * x + 2] = AdjustThreeD_Data[tempAddress];
    }
  }

  PreviewImage->Picture->Bitmap->Assign(img1);
  PreviewImage->Refresh();

  delete img1;
}
void __fastcall TCameraSetting3DForm::btnCOGdefaultClick(TObject *Sender)
{
	Camera3D_COGParamData.CutOff_Level = 260;
    CutOffLavel->Text = IntToStr(Camera3D_COGParamData.CutOff_Level);

	Camera3D_COGParamData.Gain_Level = 800;
    GainLevel->Text = IntToStr(Camera3D_COGParamData.Gain_Level);

	Camera3D_COGParamData.COG_Threshold = 150;
    CogThreshold->Text = IntToStr(Camera3D_COGParamData.COG_Threshold);

	Camera3D_COGParamData.COG_Gain = 17700;
    CogGain->Text = IntToStr(Camera3D_COGParamData.COG_Gain);

	Camera3D_COGParamData.COG_Offset = 60928;
    CogOffset->Text = IntToStr(Camera3D_COGParamData.COG_Offset);     
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnCOGWriteClick(TObject *Sender)
{
	int camIndex;
	int spbIndex;

	if(CameraSpeedButton5->Down)
	{
		camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	else
	{
		camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	
	spbIndex = CameraMapInfo[camIndex].SPBIndex;

	Camera3D_COGParamData.CutOff_Level = 	(int)StrToFloat(CutOffLavel->Text);
	Camera3D_COGParamData.Gain_Level = 		(int)StrToFloat(GainLevel->Text);
	Camera3D_COGParamData.COG_Threshold = 	(int)StrToFloat(CogThreshold->Text);
	Camera3D_COGParamData.COG_Gain = 		(int)StrToFloat(CogGain->Text);
	Camera3D_COGParamData.COG_Offset = 		(int)StrToFloat(CogOffset->Text);	

	if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_COG_WRITE, &Camera3D_COGParamData, sizeof(Camera3D_COGParamData), NULL, 0))
	{
		ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
   		return;
	}
	else
	{
		ShowMessage("Write Complete #" + IntToStr(camIndex + 1) + " Camera");
	}      
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnCOGReadClick(TObject *Sender)
{
	int camIndex;
	int spbIndex;
	
  	memset(&Camera3D_COGParamData, 0x00, sizeof(Camera3D_COGParamData));
  	
	if(CameraSpeedButton5->Down)
	{
		camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	else
	{
		camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	
	spbIndex = CameraMapInfo[camIndex].SPBIndex;
	
	if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_COG_READ, NULL, 0, &Camera3D_COGParamData, sizeof(Camera3D_COGParamData)))
	{
		ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
    		return;
	}
	else
	{
		CutOffLavel->Text=IntToStr(Camera3D_COGParamData.CutOff_Level);
		GainLevel->Text=IntToStr(Camera3D_COGParamData.Gain_Level);
		CogThreshold->Text=IntToStr(Camera3D_COGParamData.COG_Threshold);
		CogGain->Text=IntToStr(Camera3D_COGParamData.COG_Gain);
		CogOffset->Text=IntToStr(Camera3D_COGParamData.COG_Offset);
		
		ShowMessage("Read Complete #" + IntToStr(camIndex + 1) + " Camera");
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CaptureStartButton_copy2Click(
      TObject *Sender)
{
 	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	TCaptureCommandParam captureCommandParam;
	captureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;
	captureCommandParam.CameraMask = 0x01 << camIndex;
	if (CalibrationModeSpeedButton->Down)
	{
		captureCommandParam.FrameBufferCount = 2;
		captureCommandParam.ShutterSpeed[camIndex] = 100;
		captureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;
	}
	else
	{
		captureCommandParam.FrameBufferCount = 4;
		captureCommandParam.ShutterSpeed[camIndex] = StrToInt(LineScanTimeEdit->Text);
		captureCommandParam.CaptureKind = CAPTURE_KIND_LINE;
	}

  int ExposureTime;
  ExposureTime = StrToInt(cmdNFACameraData6->Text);

  RefreshCameraInfo(ExposureTime);

  //SELMA200, 20180410, moon, CMD_CAPTURE_START 가 미치는 영향 확인할것(SPB)
  if (Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &captureCommandParam, sizeof(TCaptureCommandParam)))
	{
		CaptureStart(false, false);
	}

    Image_Count = 0;

    memset(Max_Offset_Float, 0, sizeof(Max_Offset_Float));
    memset(Sum_Offset_Float, 0, sizeof(Sum_Offset_Float));
    memset(Avg_Offset_Float, 0, sizeof(Avg_Offset_Float));  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CaptureStopButton_copy2Click(
      TObject *Sender)
{
	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::Offset_MaxClick(TObject *Sender)
{
    flagOffsetMode = MAX_OFFSET_PROCESS;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::Offset_AvgClick(TObject *Sender)
{
    flagOffsetMode = AVG_OFFSET_PROCESS;
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnDefaultOffsetModeClick(
      TObject *Sender)
{
    flagOffsetMode = DEFAULT_OFFSET_PROCESS;  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnAutoGainCalClick(TObject *Sender)
{
	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;
	int i,x, y;
	int flagCaptureFail = 0; 
	int tmp2ByteOffset;
	int sumOffset[16];   
    int ExposureTime;
    int numInteger = 0;
    int numFloat = 0;

	unsigned int data[2] = {0};
	unsigned int receivedData[2];

//    float tmpAvgCh[16] = {0.0};  
	float avgMode1Val[16] = {0.0};
	float avgMode2Val[16] = {0.0}; 
	float diffModeOffset[16] ={0.0};
	float gainVal[16] = {0.0};
	float maxDiffModeOffset = 0.0;

	DWORD StartMMTime, EndMMTime;

	data[0] = camIndex;
    data[1] = 0; 

	AutoCal_CaptureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;//CAPTURE_MODE_FRAME;
	AutoCal_CaptureCommandParam.CameraMask = 0x01 << camIndex;

	if (CalibrationModeSpeedButton->Down)
	{
		AutoCal_CaptureCommandParam.FrameBufferCount = 2;
		AutoCal_CaptureCommandParam.ShutterSpeed[camIndex] = 100;
		AutoCal_CaptureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;
	}
 
  	//capture config
	ExposureTime = StrToInt(cmdNFACameraData6->Text);

	flagOffsetMode = DEFAULT_OFFSET_PROCESS; 

	//Calib mode 1 set
    if(Camera3D_OffsetParamData.Cam_Calib_Mode != 1)
    {
    	Camera3D_OffsetParamData.Cam_Calib_Mode = 1;
	    //CamCalibMode->Text = IntToStr(Camera3D_OffsetParamData.Cam_Calib_Mode);
        cbCamCalibMode->ItemIndex = 1;

    	//Write
	    if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
	    {
	    	ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
   	    	return;
	    }
        else
        {
            //Sleep(2000);
        }
    }

  	//capture start
	ExposureTime = StrToInt(cmdNFACameraData6->Text);
	
	RefreshCameraInfo(ExposureTime);

  	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &AutoCal_CaptureCommandParam, sizeof(TCaptureCommandParam)))
	{
		throw(0);
	}

	//dummy loop 4 cnt
	for(i=0; i<5; i++)
	{
		StartMMTime = timeGetTime();

		while(1)
		{
			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
				receivedData, sizeof(unsigned int) * 2))
			{
				throw(0);
			}
			else
			{		
				if(receivedData[0] == 0) 
				{	
					EndMMTime = timeGetTime();
					if((EndMMTime - StartMMTime) > 5000) 
					{
						flagCaptureFail = 1;
						ShowMessage("CaptureTimeOut 5 sec");
						throw(0);
					}
				}
                else
                {
                    flagCaptureFail = 0;
                    break;
                }
			}
		}

		if(flagCaptureFail == 0)
		{
			data[1] = FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT;

			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
				FullScaleImage, FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT))
			{
				throw(0);
			}
		}
	}
    Image_Count++;
    ImageCountEdit->Text = IntToStr(Image_Count);

    //capture stop
    Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));

	// get avg data
    if(flagCaptureFail == 0)
    {		
        //calc avg
		memset(sumOffset, 0, sizeof(sumOffset));
		for (y = 0; y < 16; y++)
		{
			for (x = (y*2); x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=(16*2))
			{
		  		tmp2ByteOffset = FullScaleImage[x] | (FullScaleImage[x+1]<<8);
				sumOffset[y] += tmp2ByteOffset;
			}
		}

		for(i = 0 ; i < 16 ; i++)
		{
			avgMode1Val[i] = (float)sumOffset[i]/20480.0;
		}

		for(i = 0 ; i < 16 ; i++)
		{
			TTntEdit *EditAvg = (TTntEdit *)FindComponent("Average_1_" + IntToStr(i));

            numInteger = (int)(avgMode1Val[i]);
            numFloat   = ((int)(avgMode1Val[i] * 10)) % 10;
			EditAvg->Text = IntToStr(numInteger) + "." + IntToStr(numFloat);
		}
	}
		
	
	//Calib mode 2 set
    if(Camera3D_OffsetParamData.Cam_Calib_Mode != 2)
    {
    	Camera3D_OffsetParamData.Cam_Calib_Mode = 2;
	    //CamCalibMode->Text = IntToStr(Camera3D_OffsetParamData.Cam_Calib_Mode);
        cbCamCalibMode->ItemIndex = 2;

    	//Write
	    if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
	    {
	    	ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
   	    	return;
	    }
        else
        {
            //Sleep(2000);
        }
    }

  	//capture start
	ExposureTime = StrToInt(cmdNFACameraData6->Text);
	
	RefreshCameraInfo(ExposureTime);

  	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &AutoCal_CaptureCommandParam, sizeof(TCaptureCommandParam)))
	{
		throw(0);
	}

	// dummy loop 4 cnt
	for(i=0; i<5; i++)
	{
		StartMMTime = timeGetTime();

		while(1)
		{
			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
				receivedData, sizeof(unsigned int) * 2))
			{
				throw(0);
			}
			else
			{		
				if(receivedData[0] == 0) 
				{	
					EndMMTime = timeGetTime();
					if((EndMMTime - StartMMTime) > 5000) 
					{
						flagCaptureFail = 1;
						ShowMessage("CaptureTimeOut 5 sec");
						throw(0);
					}
				}
                else
                {
                    flagCaptureFail = 0;
                    break;
                }
			}
		}

		if(flagCaptureFail == 0)
		{
			data[1] = FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT;

			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
				FullScaleImage, FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT))
			{
				throw(0);
			}
		}
	}
    Image_Count++;
    ImageCountEdit->Text = IntToStr(Image_Count);

    //capture stop
    Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
    
    // get avg data
    if(flagCaptureFail == 0)
    {		
        //calc avg
		memset(sumOffset, 0, sizeof(sumOffset));
		for (y = 0; y < 16; y++)
		{
			for (x = (y*2); x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=(16*2))
			{
		  		tmp2ByteOffset = FullScaleImage[x] | (FullScaleImage[x+1]<<8);
				sumOffset[y] += tmp2ByteOffset;
			}
		}

		for(i = 0 ; i < 16 ; i++)
		{
			avgMode2Val[i] = (float)sumOffset[i]/20480.0;
		}

		for(i = 0 ; i < 16 ; i++)
		{
			TTntEdit *EditAvg = (TTntEdit *)FindComponent("Average_2_" + IntToStr(i));

            numInteger = (int)(avgMode2Val[i]);
            numFloat   = ((int)(avgMode2Val[i] * 10)) % 10;
			EditAvg->Text = IntToStr(numInteger) + "." + IntToStr(numFloat);
		}
	}

	//Gain Calculation
	for(i=0; i<16; i++)
	{
		diffModeOffset[i] = avgMode2Val[i] - avgMode1Val[i];
        
		if(diffModeOffset[i] == 0)
		{
			ShowMessage("Mode1 or Mode 2 is 0, please fix it");
			throw(0);
		}
	}

	for(i=0; i<16; i++)
	{
		if(maxDiffModeOffset < diffModeOffset[i])
		{
			maxDiffModeOffset = diffModeOffset[i]; 	
		}
	}

	for(i=0; i<16; i++)
	{
		gainVal[i] = maxDiffModeOffset / diffModeOffset[i];
		gainVal[i] = gainVal[i] * 4095;
	}

	for(i=0; i<16; i++)
	{
		TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
		EditGain->Text = IntToStr((int)gainVal[i]);
	}

	//Calib mode 1 set
    if(Camera3D_OffsetParamData.Cam_Calib_Mode != 1)
    {
    	Camera3D_OffsetParamData.Cam_Calib_Mode = 1;
	    //CamCalibMode->Text = IntToStr(Camera3D_OffsetParamData.Cam_Calib_Mode);
        cbCamCalibMode->ItemIndex = 1;

    	//Write
	    if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
	    {
	    	ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
   	    	return;
	    }
        else
        {
            //Sleep(2000);
        }
    }

    ShowMessage("Auto Gain Cal Complete");  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::AutoCalButtonClick(TObject *Sender)
{
//    int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;
//	int ExposureTime;
	int i;
	
	AutoCal_CaptureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;//CAPTURE_MODE_FRAME;
	AutoCal_CaptureCommandParam.CameraMask = 0x01 << camIndex;

	if (CalibrationModeSpeedButton->Down)
	{
		AutoCal_CaptureCommandParam.FrameBufferCount = 2;
		AutoCal_CaptureCommandParam.ShutterSpeed[camIndex] = 100;
		AutoCal_CaptureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;
	}
	else
	{
		AutoCal_CaptureCommandParam.FrameBufferCount = 4;
		AutoCal_CaptureCommandParam.ShutterSpeed[camIndex] = StrToInt(LineScanTimeEdit->Text);
		AutoCal_CaptureCommandParam.CaptureKind = CAPTURE_KIND_LINE;
	}
  	//capture config
//	ExposureTime = StrToInt(cmdNFACameraData6->Text);

	flagOffsetMode = DEFAULT_OFFSET_PROCESS;
	AutoCalChkTimer->Enabled = true;
    Image_Count = 0;

    
	memset(Nfa3DcamOffset_Float, 0, sizeof(Nfa3DcamOffset_Float));

    for(i = 0; i < 16; i++)
    {
        TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
        Nfa3DcamOffset_Float[i] = StrToFloat(EditOffset->Text);
    }  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::AutoCalStopButtonClick(
      TObject *Sender)
{
    AutoCalChkTimer->Enabled = false;  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::defaultParamClick(TObject *Sender)
{
	int i;
	
    Camera3D_OffsetParamData.Cam_Calib_Mode = 1;
//    CamCalibMode->Text = "1";
	cbCamCalibMode->ItemIndex = 1;

	for(i = 0 ; i < 16 ; i++)
	{
	    Camera3D_OffsetParamData.Cma_Sys_Gain[i] = 4095;
        TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
        EditGain->Text = "4095";
	}  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CaptureStartButton_copy1Click(
      TObject *Sender)
{
 	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	TCaptureCommandParam captureCommandParam;
	captureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;
	captureCommandParam.CameraMask = 0x01 << camIndex;
	if (CalibrationModeSpeedButton->Down)
	{
		captureCommandParam.FrameBufferCount = 2;
		captureCommandParam.ShutterSpeed[camIndex] = 100;
		captureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;
	}
	else
	{
		captureCommandParam.FrameBufferCount = 4;
		captureCommandParam.ShutterSpeed[camIndex] = StrToInt(LineScanTimeEdit->Text);
		captureCommandParam.CaptureKind = CAPTURE_KIND_LINE;
	}

	int ExposureTime;
	ExposureTime = StrToInt(cmdNFACameraData6->Text);

	RefreshCameraInfo(ExposureTime);

  //SELMA200, 20180410, moon, CMD_CAPTURE_START 가 미치는 영향 확인할것(SPB)
	if(Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &captureCommandParam, sizeof(TCaptureCommandParam)))
	{
		CaptureStart(false, false);
	}

    Image_Count = 0;

    memset(Max_Offset_Float, 0, sizeof(Max_Offset_Float));
    memset(Sum_Offset_Float, 0, sizeof(Sum_Offset_Float));
    memset(Avg_Offset_Float, 0, sizeof(Avg_Offset_Float));  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CaptureStopButton_copy1Click(
      TObject *Sender)
{
	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

	Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
	CaptureCheckTimer->Enabled = false;  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnOffsetSetClick(TObject *Sender)
{
    int i;

	for(i = 0 ; i < 16 ; i++)
	{
        if(flagOffsetMode == MAX_OFFSET_PROCESS)
        {
                TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
                Nfa3DcamOffset_Float[i] += Max_Offset_Float[i];
                if(Nfa3DcamOffset_Float[i] > 65535) Nfa3DcamOffset_Float[i] = 65535;
            	EditOffset->Text = String().sprintf("%6.1f", Nfa3DcamOffset_Float[i]);
        }
        else if(flagOffsetMode == AVG_OFFSET_PROCESS)
        {
                TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
                Nfa3DcamOffset_Float[i] += Avg_Offset_Float[i];
                if(Nfa3DcamOffset_Float[i] > 65535) Nfa3DcamOffset_Float[i] = 65535;
            	EditOffset->Text = String().sprintf("%6.1f", Nfa3DcamOffset_Float[i]);
        }
        else      // DEFAULT_OFFSET_PROCESS
        {
        		TTntEdit *EditAvg = (TTntEdit *)FindComponent("Average_1_" + IntToStr(i));		
                TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
                
                Nfa3DcamOffset_Float[i] += StrToFloat(EditAvg->Text);
                if(Nfa3DcamOffset_Float[i] > 65535) Nfa3DcamOffset_Float[i] = 65535;
                EditOffset->Text = String().sprintf("%6.1f", Nfa3DcamOffset_Float[i]);
        }
    }  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnOffsetWriteClick(TObject *Sender)
{
	int camIndex;
	int spbIndex;

		if(CameraSpeedButton5->Down)
		{
			camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
		}
		else
		{
			camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
		}
		
		spbIndex = CameraMapInfo[camIndex].SPBIndex;

		for(int i = 0 ; i < 16 ; i++)
		{
			TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
			Camera3D_OffsetParamData.Cam_Init_Offset[i] = (int)StrToFloat(EditOffset->Text);

			TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));		
			Camera3D_OffsetParamData.Cma_Sys_Gain[i] = (int)StrToFloat(EditGain->Text);
		}
	
	    //Camera3D_OffsetParamData.Cam_Calib_Mode = 	(int)StrToFloat(CamCalibMode->Text);
        Camera3D_OffsetParamData.Cam_Calib_Mode = cbCamCalibMode->ItemIndex;

		if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
		{
			ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
	   		return;
		}
		else
		{
			ShowMessage("Write Complete #" + IntToStr(camIndex + 1) + " Camera");
	    	SetCaptureDisplaySize();
		}

        if(Camera3D_OffsetParamData.Cam_Calib_Mode == 1 || Camera3D_OffsetParamData.Cam_Calib_Mode == 2)
        {
            lblRemovePacket->Visible = true;
        }
        else
        {
            lblRemovePacket->Visible = false;
        }  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnOffsetReadClick(TObject *Sender)
{
	int camIndex;
	int spbIndex;
	
  	memset(&Camera3D_OffsetParamData, 0x00, sizeof(Camera3D_OffsetParamData));
  	
	if(CameraSpeedButton5->Down)
	{
		camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	else
	{
		camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	
	spbIndex = CameraMapInfo[camIndex].SPBIndex;
	
	if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_READ, NULL, 0, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData)))
	{
		ShowMessage("Communication Error #" + IntToStr(spbIndex + 1) + " IPB");
    		return;
	}
	else
	{
		for(int i = 0 ; i < 16 ; i++)
		{
			TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
			
			EditOffset->Text = IntToStr(Camera3D_OffsetParamData.Cam_Init_Offset[i]);
			
            Nfa3DcamOffset_Float[i] = Camera3D_OffsetParamData.Cam_Init_Offset[i];

			TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
			EditGain->Text = IntToStr(Camera3D_OffsetParamData.Cma_Sys_Gain[i]);
		}
		
		//CamCalibMode->Text=IntToStr(Camera3D_OffsetParamData.Cam_Calib_Mode);
		cbCamCalibMode->ItemIndex = Camera3D_OffsetParamData.Cam_Calib_Mode;
		
		ShowMessage("Read Complete #" + IntToStr(camIndex + 1) + " Camera");
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnGainCalClick(TObject *Sender)
{
	float mode1Offset[16] ={0.0};
	float mode2Offset[16] ={0.0};
	float diffModeOffset[16] ={0.0};
	float gainVal[16] = {0.0};
	
	float maxDiffModeOffset = 0.0;
	int i;
	
	for(i=0; i<16; i++)
	{
        TTntEdit *EditOffset1 = (TTntEdit *)FindComponent("Average_1_" + IntToStr(i));
        TTntEdit *EditOffset2 = (TTntEdit *)FindComponent("Average_2_" + IntToStr(i));
    	
		mode1Offset[i] = StrToFloat(EditOffset1->Text);
		mode2Offset[i] = StrToFloat(EditOffset2->Text);
	}

	for(i=0; i<16; i++)
	{
		diffModeOffset[i] = mode2Offset[i] - mode1Offset[i];
		
		if(diffModeOffset[i] == 0)
		{
			ShowMessage("Mode1 or Mode 2 is 0, please fix it");
			throw(0);
		}
	}

	for(i=0; i<16; i++)
	{
		if(maxDiffModeOffset < diffModeOffset[i])
		{
			maxDiffModeOffset = diffModeOffset[i]; 	
		}
	}

	for(i=0; i<16; i++)
	{
		gainVal[i] = maxDiffModeOffset / diffModeOffset[i];
		gainVal[i] = gainVal[i] * 4095;
	}

	for(i=0; i<16; i++)
	{
		TTntEdit *EditGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
		EditGain->Text = IntToStr((int)gainVal[i]);
	}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnSysGainResetClick(TObject *Sender)
{
	for(int i = 0 ; i < 16 ; i++)
	{
		TTntEdit *EditSysGain = (TTntEdit *)FindComponent("SysGain_" + IntToStr(i));
		EditSysGain->Text = "0";
	}  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnChOffsetResetClick(
      TObject *Sender)
{
	for(int i = 0 ; i < 16 ; i++)
	{
		TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
		EditOffset->Text = "0";
	}

	memset(Nfa3DcamOffset_Float, 0, sizeof(Nfa3DcamOffset_Float));  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnLogCopyClick(TObject *Sender)
{
	int i;
    String strBuf = "";

    for(i = 0; i < 16; i++)
    {
        TTntEdit *EditOffset = (TTntEdit *) FindComponent ("Offset_" + IntToStr(i));
        strBuf += (EditOffset->Text + "\t");
    }

    strBuf += "\n";
    
    for(i = 0; i < 16; i++)
    {
        TTntEdit *EditGain = (TTntEdit *) FindComponent("SysGain_" + IntToStr(i));
        strBuf += (EditGain->Text + "\t");
    }
    
    Clipboard()->AsText = strBuf;  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::chkLogEnableClick(TObject *Sender)
{
    if(chkLogEnable->Checked)
    {
        btnLogCopy->Visible = true;
        btnLogCopy->Enabled = true;
    }
    else
    {
        btnLogCopy->Visible = false;
        btnLogCopy->Enabled = false;
    }  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::AutoCalChkTimerTimer(TObject *Sender)
{

 	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;
	int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;
	int i,x, y;	
	int flagCaptureFail = 0;
	int tmp2ByteOffset;
	int sumOffset[16];
	int flagHigh8bit = 0;
	int offsetUpdate = 0;
	int offsetComplete	= 0;
    int ExposureTime;
    int numInteger = 0;
    int numFloat = 0;

	unsigned int data[2] = {0};
	unsigned int receivedData[2];

	unsigned short tmp2ByteVal = 0;

	float tmpAvgCh[16] = {0.0};
    float Auto_Offset_Value = 0;

	DWORD StartMMTime, EndMMTime;

	Auto_Cal_Cnt = StrToInt(EAutoCalCnt->Text);

  
   	data[0] = camIndex;
    data[1] = 0; 
	
	//Calib mode 1 set

    if(Camera3D_OffsetParamData.Cam_Calib_Mode != 1)
    {
    	Camera3D_OffsetParamData.Cam_Calib_Mode = 1;
	    //CamCalibMode->Text = IntToStr(Camera3D_OffsetParamData.Cam_Calib_Mode);
        cbCamCalibMode->ItemIndex = 1;

    	//Write
	    if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
	    {
	    	ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
   	    	return;
	    }
        else
        {
            //Sleep(2000);
        }
    }

	//Get N th CaptureData

  	//capture config
	ExposureTime = StrToInt(cmdNFACameraData6->Text);
	
	RefreshCameraInfo(ExposureTime);

  	if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &AutoCal_CaptureCommandParam, sizeof(TCaptureCommandParam)))
	{
		throw(0);
	}

    // dummy loop 4 cnt 
	for(i=0; i<5; i++)
	{
		StartMMTime = timeGetTime();

		while(1)
		{
			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
				receivedData, sizeof(unsigned int) * 2))
			{
				throw(0);
			}
			else
			{		
				if(receivedData[0] == 0) 
				{	
					EndMMTime = timeGetTime();
					if((EndMMTime - StartMMTime) > 5000) 
					{
						flagCaptureFail = 1;
						ShowMessage("CaptureTimeOut 5 sec");
						throw(0);
					}
				}
                else
                {
                    flagCaptureFail = 0;
                    break;
                }
			}
		}

		if(flagCaptureFail == 0)
		{
			data[1] = FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT;

			if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
				FullScaleImage, FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT))
			{
				throw(0);
			}
		}
	}
    Image_Count++;
    ImageCountEdit->Text = IntToStr(Image_Count);
    Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));

    if(flagCaptureFail == 0)
    {		
        //calc avg
		memset(sumOffset, 0, sizeof(sumOffset));
		for (y = 0; y < 16; y++)
		{
			for (x = (y*2); x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=(16*2))
			{
		  		tmp2ByteOffset = FullScaleImage[x] | (FullScaleImage[x+1]<<8);
				sumOffset[y] += tmp2ByteOffset;
			}
		}

		for(i = 0 ; i < 16 ; i++)
		{
			tmpAvgCh[i] = (float)sumOffset[i]/20480.0;
		}

		for(i = 0 ; i < 16 ; i++)
		{
			Max_Offset_Float[i] = ((Max_Offset_Float[i] > tmpAvgCh[i]) ? Max_Offset_Float[i] : tmpAvgCh[i]); 
			Sum_Offset_Float[i] += tmpAvgCh[i];
			Avg_Offset_Float[i] = Sum_Offset_Float[i]/Image_Count;
		}

		for(i = 0 ; i < 16 ; i++)
		{
			TTntEdit *EditAvg = (TTntEdit *)FindComponent("Average_1_" + IntToStr(i));

			if(flagOffsetMode == MAX_OFFSET_PROCESS)
			{
                numInteger = (int)(Max_Offset_Float[i]);
                numFloat   = ((int)(Max_Offset_Float[i] * 10)) % 10;
				EditAvg->Text = IntToStr(numInteger) + "." + IntToStr(numFloat);
			}
			else if(flagOffsetMode == AVG_OFFSET_PROCESS)
			{
                numInteger = (int)(Avg_Offset_Float[i]);
                numFloat   = ((int)(Avg_Offset_Float[i] * 10)) % 10;
				EditAvg->Text = IntToStr(numInteger) + "." + IntToStr(numFloat);
			}
			else
			{
                numInteger = (int)(tmpAvgCh[i]);
                numFloat   = ((int)(tmpAvgCh[i] * 10)) % 10;
				EditAvg->Text = IntToStr(numInteger) + "." + IntToStr(numFloat);
			}
		}

		// make bmp data
		memset(ProcessedScaleImage, 0, (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT / 2));
		
		flagHigh8bit = 0;
		
        for (x = 0; x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=2)
		{
            tmp2ByteVal = FullScaleImage[x] | (FullScaleImage[x +1] << 8);

			if(tmp2ByteVal > 0xFF)	
			{
				flagHigh8bit = 1;
				break;
			}
			else
			{
				flagHigh8bit = 0;
			}
        }

        if(flagHigh8bit)    lblRemovePacket->Caption = "Upper 8bit";
        else                lblRemovePacket->Caption = "Lower 8bit";

        for (x = 0; x < (FULL_SCALE_IMAGE_WIDTH * FULL_SCALE_IMAGE_HEIGHT); x+=2)
		{
        	tmp2ByteVal = FullScaleImage[x] | (FullScaleImage[x +1] << 8);
			
			if(flagHigh8bit == 1)       tmp2ByteVal = (tmp2ByteVal >> 4) & 0xFF;
			else						tmp2ByteVal = tmp2ByteVal & 0xFF;
					
			ProcessedScaleImage[x/2] = (unsigned char)tmp2ByteVal;
        }
		
    	// Show Image
		for (y = 0; y < AreaFrameCaptureHeight; y++)
		{
			byte *pBitmap = (byte *)CaptureImage->Picture->Bitmap->ScanLine[y];

			for (x = 0; x < AreaFrameCaptureWidth; x++)
			{
				pBitmap[0] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];
				pBitmap[1] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];
				pBitmap[2] = ProcessedScaleImage[y * AreaFrameCaptureWidth + x];	
				
				pBitmap += 3;
			}
		}
		CaptureImage->Repaint();
				
		//check offset complete
		offsetUpdate = 0;

		for(i = 0 ; i < 16 ; i++)
		{
            tmpAvgCh[i] = ((int)(tmpAvgCh[i] * 10))/10.0;
            Auto_Offset_Value = StrToFloat(EAutoOffset->Text);

			if(tmpAvgCh[i] > Auto_Offset_Value)
			{
				offsetUpdate++;
				Nfa3DcamOffset_Float[i] += tmpAvgCh[i];		

				if(Nfa3DcamOffset_Float[i] > 65535) 
                {
                	Nfa3DcamOffset_Float[i] = 65535;
                }
                
                Camera3D_OffsetParamData.Cam_Init_Offset[i] = (int)Nfa3DcamOffset_Float[i] ;
                
                TTntEdit *EditOffset = (TTntEdit *)FindComponent("Offset_" + IntToStr(i));
                EditOffset->Text = String().sprintf("%6.1f", Nfa3DcamOffset_Float[i]);
			}
		}


		if(offsetUpdate > 0)
		{
		//set offset Write
			if (!Comm_Request(COMM_SPB + spbIndex, CMD_3D_CAMERA_CAL_OFFSET_WRITE, &Camera3D_OffsetParamData, sizeof(Camera3D_OffsetParamData), NULL, 0))
			{
				ShowMessage("Communication Error #" + IntToStr(camIndex + 1) + " Camera");
		   		return;
			}
			else
			{
				//ShowMessage("Write Complete #" + IntToStr(camIndex + 1) + " Camera");
			}
		}
		else
		{
			offsetComplete = 1;
		}

		// flash light
		if (shRefresh->Brush->Color == clWhite)
		{
			shRefresh->Brush->Color = clBlack;
		}
		else
		{
			shRefresh->Brush->Color = clWhite;
		}

		if(offsetComplete == 1)
        {
        	if(Auto_Cal_Cnt == 0 || Image_Count == Auto_Cal_Cnt)
        	{
    	        AutoCalChkTimer->Enabled = false;
                ShowMessage("Auto Offset Complete");
    	    }
        }
        else
        {
        	Image_Count = 0;
        }
    }
    else
    {
        AutoCalChkTimer->Enabled = false;
    }  
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnWrite3D_Cam_ADC_ResClick(
      TObject *Sender)
{
	int camIndex;
    int tmpSpbIndex;
    int tmpCamIndex;
    int tmpCameraLink;
    int tmpGlobalCamIndex;
   	int cam3D_Index = 5;	//#define CAMERA_POSITION_3D 5

		if(CameraSpeedButton5->Down)
		{
			camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
		}
		else
		{
			camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
		}

    	tmpGlobalCamIndex = camIndex;

	    if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
		{
	        tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
			tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
		    tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
		    
		    Camera3D_ADC_Resolution.Cam_Index = tmpCameraLink; 
		    Camera3D_ADC_Resolution.Cam_ADC_Resolution = cb3D_Cam_ADC_Resolution->ItemIndex;

		    if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_SET_CAMERA_ADC_RESOLUTION, &Camera3D_ADC_Resolution, sizeof(Camera3D_ADC_Resolution),  NULL, 0))
		    {
			    ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
	    	    return;
	        }
		    else
		    {
	            ShowMessage("Write Complete #" + IntToStr(camIndex + 1) + " Camera");
	        }
	    }
		else
		{
			ShowMessage("3D Cam Maaping Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
		}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::btnRead3D_Cam_ADC_ResClick(
      TObject *Sender)
{
	int camIndex;
    int tmpSpbIndex;
    int tmpCamIndex;
    int tmpCameraLink;
    int tmpGlobalCamIndex;
   	int cam3D_Index = 5;	//#define CAMERA_POSITION_3D 5

  	memset(&Camera3D_ADC_Resolution, 0x00, sizeof(Camera3D_ADC_Resolution));
  	
	if(CameraSpeedButton5->Down)
	{
		camIndex = SD1_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}
	else
	{
		camIndex = SD2_3D_FRONT_FACE_CAMERA_INDEX - 1;
	}

    tmpGlobalCamIndex = camIndex;

    if(CameraMapInfo[tmpGlobalCamIndex].CameraInspectPosition == cam3D_Index)
	{
        tmpSpbIndex = CameraMapInfo[tmpGlobalCamIndex].SPBIndex;
		tmpCamIndex = CameraMapInfo[tmpGlobalCamIndex].CamIndex;
	    tmpCameraLink = SPBSystemSetupData[tmpSpbIndex].CameraHardwarePosition[tmpCamIndex];
	    Camera3D_ADC_Resolution.Cam_Index = tmpCameraLink; 

	    if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_GET_CAMERA_ADC_RESOLUTION, &Camera3D_ADC_Resolution, sizeof(Camera3D_ADC_Resolution), &Camera3D_ADC_Resolution, sizeof(Camera3D_ADC_Resolution)))
	    {
		    ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
    	    return;
        }
	    else
	    {
		    cb3D_Cam_ADC_Resolution->ItemIndex = Camera3D_ADC_Resolution.Cam_ADC_Resolution;
            ShowMessage("Read Complete #" + IntToStr(camIndex + 1) + " Camera");
        }
    }
	else
	{
		ShowMessage("3D Cam Maaping Error #" + IntToStr(tmpSpbIndex + 1) + " IPB");
	}  
}
//---------------------------------------------------------------------------
//20201106 cjg added 3d camera param
//2020-09-04 cjg added 3D camera param
void __fastcall TCameraSetting3DForm::SetCaptureDisplaySize()
{
	int calibModeVal = 0;

	if(RangerCaptureMode == ERCM_CALIB)
	{
//	    if(((StrToInt(CamCalibMode->Text) >= 0) && (StrToInt(CamCalibMode->Text) <= 10)))
//	    {
//			calibModeVal = StrToInt(CamCalibMode->Text);
			calibModeVal = cbCamCalibMode->ItemIndex;
			
		    switch(calibModeVal)
		    {
		        case 0 :
		            AreaFrameCaptureWidth   = 640;
		            AreaFrameCaptureHeight  = 1024;
		            break;
		        case 1 :
		        case 2 :
                    AreaFrameCaptureWidth   = 1280;
		            AreaFrameCaptureHeight  = 256;
		            break;
		        default :
		            AreaFrameCaptureWidth   = 640;
		            AreaFrameCaptureHeight  = 1024;
		            break;
		    }
          
	        CaptureImage->Width = AreaFrameCaptureWidth;
	        CaptureImage->Height = AreaFrameCaptureHeight;//AreaFrameCaptureHeight
	        CaptureImage->Picture->Bitmap->Width = DestImage->Width;
	        CaptureImage->Picture->Bitmap->Height = DestImage->Height;
	        CaptureImage->Picture->Bitmap->PixelFormat = pf24bit;
//	    }
    }
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CutOffLavelClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::GainLevelClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CogThresholdClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CogGainClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::CogOffsetClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}    
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::e3D_LaserGuideGapValClick(
      TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
        try
        {
            theEdit->Text = KeyboardForm->Text;
        }
        catch(...)
        {
          ShowMessage("Wrong input value.");
        }
	}          
}
//---------------------------------------------------------------------------

void __fastcall TCameraSetting3DForm::TntFormActivate(TObject *Sender)
{
  SetScreenPosition(this);  
}
//---------------------------------------------------------------------------

