|
|
#include "StdAfx.h"
|
|
|
#include "RecipeMgr.h"
|
|
|
#include "LogMgr.h"
|
|
|
#include "FileMgr.h"
|
|
|
#include "CStringFuc.h"
|
|
|
#include "WaferRecipeDataMgr.h"
|
|
|
#include "MsgBox.h"
|
|
|
#include "DlgChildRecipe.h"
|
|
|
#include "CommonParaMgr.h"
|
|
|
#include "GlobalFunction.h"
|
|
|
#include "Laser.h"
|
|
|
#include "ProgramLaserTuiHuo.h"
|
|
|
#include "RecipeMgr.h"
|
|
|
#include "DlgRecipeCtrl.h"
|
|
|
#include "MyXmlMgr.h"
|
|
|
#include "ExceptionMsg.h"
|
|
|
#include "AuthorityMgr.h"
|
|
|
#include "CommonParaMgr.h"
|
|
|
#include "Propertie.h"
|
|
|
#include "PropertieMgr.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define RECIPE_FILE_PATH _T("\\RecipePar\\")
|
|
|
#define RECIPE_GROUP_NAME_FILE _T("\\font\\GroupNameList")//组名列表文件
|
|
|
#define SECS_RECIPE_FILE_PATH _T("\\SecsRecipe")
|
|
|
|
|
|
#define RECIPE_GROUP_CNT 10 //recipe 分组的数量
|
|
|
#define ONE_GROUP_PAR_CNT 50 //一个recipe 分组参数的数量
|
|
|
|
|
|
#define NEW_RECIPE_FILE_PATH _T("\\Recipe\\")
|
|
|
|
|
|
|
|
|
#define RECIPE_FILE_SUFFIX "rcp" //recipe 文件使用的后缀
|
|
|
|
|
|
|
|
|
#define XML_ITEM_PAR_TYPE "ParType"
|
|
|
#define XML_ITEM_PAR_VAL "ParVal"
|
|
|
|
|
|
#define RCP_PAR_TYPE_DOUBLE "Double"
|
|
|
#define RCP_PAR_TYPE_STRING "String"
|
|
|
#define RCP_PAR_TYPE_BOOL "Bool"
|
|
|
#define RCP_PAR_TYPE_INT "Int"
|
|
|
|
|
|
#define NULL_RECIPE_NAME "" //无效的recipe 名称
|
|
|
#define PARA_MODIFY_DATA_PATH _T("\\ParaModifyRecord\\")
|
|
|
|
|
|
#define OFFSET_TAB_FILE_PATH "\\OffsetTable\\TableFile\\"
|
|
|
|
|
|
#define MFC_CTRLSCAL _T("\\CommPar\\MFC_CtrlScal.bin") // MFC流量控制系数表
|
|
|
|
|
|
#if 1
|
|
|
CSubRecipe::CSubRecipe(void)
|
|
|
{
|
|
|
m_bUseSubRecipe = true;//生产中是否使用
|
|
|
ReadMFCCtrlScalFile();
|
|
|
//初始化recipe 参数容器
|
|
|
IntiRecipeParVec();
|
|
|
}
|
|
|
|
|
|
//从指定文件中读取Mfc系数
|
|
|
void CSubRecipe::ReadMFCCtrlScalFile()
|
|
|
{
|
|
|
CFileMgr FileMgr;
|
|
|
CString FilePath;
|
|
|
vector<vector<CString>> StrVec;
|
|
|
FileMgr.GetFullFilePath(FilePath, MFC_CTRLSCAL);
|
|
|
FileMgr.ReadFileToStrVec(FilePath, StrVec);
|
|
|
int StrSize = StrVec.size();
|
|
|
for (int i = 0; i < StrSize; i++)
|
|
|
{
|
|
|
if (2 == StrVec[i].size())
|
|
|
{
|
|
|
MFCScalStrVec.push_back(StrVec[i]);
|
|
|
}
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
//初始化recipe 参数容器(中间可以添加新的参数)
|
|
|
void CSubRecipe::IntiRecipeParVec()
|
|
|
{
|
|
|
//可以被编辑的参数要在前面定义
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_FRE;
|
|
|
RecipePar.m_ParShowName = "Laser1 Frequency";
|
|
|
RecipePar.m_ParUnit = "Hz";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 1000;//默认值
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_FRE);
|
|
|
RecipePar.m_DetailInfo = "激光1频率:一秒内激光脉冲个数";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER2_FRE;
|
|
|
RecipePar.m_ParShowName = "Laser2 Frequency";
|
|
|
RecipePar.m_ParUnit = "Hz";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 1000;//默认值
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_FRE);
|
|
|
RecipePar.m_DetailInfo = "激光2频率:一秒内激光脉冲个数";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_PRF2_DELAY;
|
|
|
RecipePar.m_ParShowName = "Two Pulse Delay";
|
|
|
RecipePar.m_ParUnit = "ns";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_PULSE_DELAY);
|
|
|
RecipePar.m_DetailInfo = "双脉冲延时:激光器脉冲延时时间";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_CURR_1;
|
|
|
RecipePar.m_ParShowName = "Laser1 Current";
|
|
|
RecipePar.m_ParUnit = "A";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_CURR_1);
|
|
|
RecipePar.m_DetailInfo = "Laser1电流值:工艺设置电流值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_CURR_2;
|
|
|
RecipePar.m_ParShowName = "Laser2 Current";
|
|
|
RecipePar.m_ParUnit = "A";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_CURR_2);
|
|
|
RecipePar.m_DetailInfo = "Laser2电流值:工艺设置电流值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_1;
|
|
|
RecipePar.m_ParShowName = "Laser1 Edi";
|
|
|
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_EDI_1);
|
|
|
RecipePar.m_DetailInfo = "Laser1目标功率密度 :最终的edi还要加上Laser Edi Offset和补偿表中的Laser Edi Offset值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_2;
|
|
|
RecipePar.m_ParShowName = "Laser2 Edi";
|
|
|
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_EDI_2);
|
|
|
RecipePar.m_DetailInfo = "Laser2目标功率密度 :最终的edi还要加上Laser Edi Offset和补偿表中的Laser Edi Offset值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_OFFSET_1;
|
|
|
RecipePar.m_ParShowName = "Laser1 Edi Offset";
|
|
|
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = -2;
|
|
|
RecipePar.m_DoubleMaxVal = 2;
|
|
|
RecipePar.m_DetailInfo = "Laser1目标功率密度补偿";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_OFFSET_2;
|
|
|
RecipePar.m_ParShowName = "Laser2 Edi Offset";
|
|
|
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = -2;
|
|
|
RecipePar.m_DoubleMaxVal = 2;
|
|
|
RecipePar.m_DetailInfo = "Laser2目标功率密度补偿";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_EDI_CHECK_SCOPE;
|
|
|
RecipePar.m_ParShowName = "Edi Check Scope";
|
|
|
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = 5;
|
|
|
RecipePar.m_DetailInfo = "功率密度复检卡控范围:等于0表示不进行复检,大于表示要进行复检且复检调整后的功率密度在这个误差范围之内";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_OVERLAP_RATIO_X;
|
|
|
RecipePar.m_ParShowName = "Overlap Rate X";
|
|
|
RecipePar.m_ParUnit = "%";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = 99;
|
|
|
RecipePar.m_DetailInfo = "X方向光斑重叠率:会影响X方向扫描速度的计算值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_OVERLAP_RATIO_Y;
|
|
|
RecipePar.m_ParShowName = "Overlap Rate Y";
|
|
|
RecipePar.m_ParUnit = "%";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = 99;
|
|
|
RecipePar.m_DetailInfo = "Y方向光斑重叠率:会影响Y方向移动间隔";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_FOCUS_ADJUST_VAL;
|
|
|
RecipePar.m_ParShowName = "Foucs Adjust Val";
|
|
|
RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_FOCUS_ADJUST);
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_FOCUS_ADJUST);
|
|
|
RecipePar.m_DetailInfo = "Z轴焦距微调值:用于工艺前Z轴在目前设置的激光焦距点上下进行微调";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_FIX_SCAN_SPEED;
|
|
|
RecipePar.m_ParShowName = "Fix Scan Speed";
|
|
|
RecipePar.m_ParUnit = "mm/s";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_SCAN_SPEED);
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_SCAN_SPEED);
|
|
|
RecipePar.m_DetailInfo = "固定扫描速度:等于0时无效,大于0时X方向光斑重叠率无效,工艺过程中将使用这个速度值作为X方向的扫描速度";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_FIX_SCAN_LINE_GAP;
|
|
|
RecipePar.m_ParShowName = "Fix Scan Line Gap";
|
|
|
RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_FIX_SCAN_LINE_GAP);
|
|
|
RecipePar.m_DetailInfo = "固定扫描间隔:等于0时无效,大于0时Y方向光斑重叠率无效,工艺过程中将使用这个值作为Y方向的扫描移动间隔";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_LINE_START_IDX;
|
|
|
RecipePar.m_ParShowName = "Start Scan Line Idx";
|
|
|
//RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = 100000;
|
|
|
RecipePar.m_DetailInfo = "扫描线的起始索引值:表示从第几根线开始扫描,用于补打wafer";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_ALIGNER_ANG;
|
|
|
RecipePar.m_ParShowName = "Wafer Aligner Angle";
|
|
|
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 270;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = 360;
|
|
|
RecipePar.m_DetailInfo = "wafer准直角度:用于控制wafer放到stage上的notch方向,多subrcp的情况第一个sub的值为有效值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
int StrSize = MFCScalStrVec.size();
|
|
|
double m_MinVal = 0.0;
|
|
|
double m_MaxVal = 0.0;
|
|
|
if (StrSize > 0)
|
|
|
{
|
|
|
m_MinVal = CStringToDouble(MFCScalStrVec[0][1]);
|
|
|
m_MaxVal = CStringToDouble(MFCScalStrVec[StrSize - 1][1]);
|
|
|
}
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_N2_VAL;
|
|
|
RecipePar.m_ParShowName = "N2 Val";
|
|
|
RecipePar.m_ParUnit = "L";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = m_MinVal;
|
|
|
RecipePar.m_DoubleMinVal = m_MinVal;
|
|
|
RecipePar.m_DoubleMaxVal = m_MaxVal;
|
|
|
RecipePar.m_DetailInfo = "MFC流量控制值:MFC控制N2流量值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
//下拉框参数------------------------------------------------
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_AREA;
|
|
|
RecipePar.m_ParShowName = "Scan Area";
|
|
|
RecipePar.m_ParType = _RecipeParType_CString;//参数的类型
|
|
|
RecipePar.m_DetailInfo = "扫描区域文件名称:用于指定扫描区域的图形文件,确定扫描的范围";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_AREA_IDX;
|
|
|
RecipePar.m_ParShowName = "Area Idx";
|
|
|
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
|
|
|
RecipePar.m_ParIntVal = 1;
|
|
|
RecipePar.m_DetailInfo = "扫描区域编号:扫描区域文件中包含多个扫描区域时,每个sub rcp只能选择一个区域编号进行工艺";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_N2_STATE;
|
|
|
RecipePar.m_ParShowName = "N2";
|
|
|
RecipePar.m_ParType = _RecipeParType_Bool;//参数的类型
|
|
|
RecipePar.m_ParBoolVal = true;
|
|
|
RecipePar.m_DetailInfo = "N2开关控制,退火过程中是否自动打开N2";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_USE_CUR_N2VAL;
|
|
|
RecipePar.m_ParShowName = "Use CurN2Val";
|
|
|
RecipePar.m_ParType = _RecipeParType_Bool;//参数的类型
|
|
|
RecipePar.m_ParBoolVal = false;
|
|
|
RecipePar.m_DetailInfo = "MFC控制开关:是否使用recipe的MFC流量控制值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
#ifdef __OFFSET_TABLE__
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_OFFSET_TAB;
|
|
|
RecipePar.m_ParShowName = "Offset Table";
|
|
|
RecipePar.m_ParType = _RecipeParType_CString;//参数的类型
|
|
|
RecipePar.m_ParStrVal = RECIPE_OFFSET_TBL_NULL;
|
|
|
RecipePar.m_DetailInfo = "补偿表的名称:用于link指定的补偿表,可以补偿edi和激光电流值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_RUNTIMES;
|
|
|
RecipePar.m_ParShowName = "Run Times";
|
|
|
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
|
|
|
RecipePar.m_ParIntVal = 1;//默认值
|
|
|
RecipePar.m_DetailInfo = "工艺运行次数:正常设置为1,大于1时表示跑cycle,多subrcp的情况第一个sub的值为有效值";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_CASSETTE_TIER_COUNT;
|
|
|
RecipePar.m_ParShowName = "Cassette Tier Cout";
|
|
|
RecipePar.m_ParUnit = "";
|
|
|
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 13;//默认值
|
|
|
RecipePar.m_DoubleMinVal = 13;
|
|
|
RecipePar.m_DoubleMaxVal = 25;
|
|
|
RecipePar.m_DetailInfo = "料盒层数设置:设置料盒层数,机械手根据料盒层数mapping";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
|
|
|
//不能被编辑的参数---------------------------------------------------------------
|
|
|
#if 1
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER1_POW;
|
|
|
RecipePar.m_ParShowName = "Laser1 Power";
|
|
|
RecipePar.m_ParUnit = "w";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_POW_1);
|
|
|
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
|
|
|
//RecipePar.m_DetailInfo = "Laser1功率值:1.Laser固定电流为0时,根据edi自动计算 2.Laser固定电流大于0时,在功率点检表中查找对应的功率值,用于计算衰减角度";
|
|
|
RecipePar.m_DetailInfo = "Laser1功率值:在功率点检表中查找对应的功率值,用于计算衰减角度";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER2_POW;
|
|
|
RecipePar.m_ParShowName = "Laser2 Power";
|
|
|
RecipePar.m_ParUnit = "w";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_POW_2);
|
|
|
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
|
|
|
//RecipePar.m_DetailInfo = "Laser2功率值:1.Laser固定电流为0时,根据edi自动计算 2.Laser固定电流大于0时,在功率点检表中查找对应的功率值,用于计算衰减角度";
|
|
|
RecipePar.m_DetailInfo = "Laser2功率值:在功率点检表中查找对应的功率值,用于计算衰减角度";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_SPEED;
|
|
|
RecipePar.m_ParShowName = "Scan Speed";
|
|
|
RecipePar.m_ParUnit = "mm/s";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_SCAN_SPEED);
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_SCAN_SPEED);
|
|
|
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
|
|
|
RecipePar.m_DetailInfo = "X方向扫描速度:固定扫描速度等于0时,由X方向重叠率计算得出,固定扫描速度大于0时,等于固定扫描速度";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_ROTATO_DIMMER_ANG;
|
|
|
RecipePar.m_ParShowName = "Dimmer1 Angle";
|
|
|
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_DIMMER_ANG_1);
|
|
|
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
|
|
|
RecipePar.m_DetailInfo = "Laser1衰减角度:由edi,频率,功率计算得出的衰减器角度,固定电流值大于0才会生效";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
{
|
|
|
CRecipeParameter RecipePar;
|
|
|
RecipePar.m_ParName = RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2;
|
|
|
RecipePar.m_ParShowName = "Dimmer2 Angle";
|
|
|
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
|
|
|
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
|
|
|
RecipePar.m_ParDoubleVal = 0;
|
|
|
RecipePar.m_DoubleMinVal = 0;
|
|
|
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_DIMMER_ANG_2);
|
|
|
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
|
|
|
RecipePar.m_DetailInfo = "Laser2衰减角度:由edi,频率,功率计算得出的衰减器角度,固定电流值大于0才会生效";
|
|
|
m_RecipeParVec.push_back(RecipePar);
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
#endif
|
|
|
#if 1
|
|
|
//根据参数的类型返回CString 类型值
|
|
|
CString CRecipeParameter::GetParStr()
|
|
|
{
|
|
|
CString ParStr;
|
|
|
switch(m_ParType)
|
|
|
{
|
|
|
case _RecipeParType_Double:
|
|
|
ParStr = Db2CString(m_ParDoubleVal);
|
|
|
break;
|
|
|
case _RecipeParType_Bool:
|
|
|
ParStr = (m_ParBoolVal)?(BOOL_STR_ON):(BOOL_STR_OFF);
|
|
|
break;
|
|
|
case _RecipeParType_CString:
|
|
|
ParStr = m_ParStrVal;
|
|
|
break;
|
|
|
case _RecipeParType_Int:
|
|
|
ParStr = Int2CString(m_ParIntVal);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
return ParStr;
|
|
|
}
|
|
|
CString CRecipeParameter::GetParTypeStr()
|
|
|
{
|
|
|
CString Str;
|
|
|
switch(m_ParType)
|
|
|
{
|
|
|
case _RecipeParType_Double:
|
|
|
Str = RCP_PAR_TYPE_DOUBLE;
|
|
|
break;
|
|
|
case _RecipeParType_Bool:
|
|
|
Str = RCP_PAR_TYPE_BOOL;
|
|
|
break;
|
|
|
case _RecipeParType_CString:
|
|
|
Str = RCP_PAR_TYPE_STRING;
|
|
|
break;
|
|
|
case _RecipeParType_Int:
|
|
|
Str = RCP_PAR_TYPE_INT;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
return Str;
|
|
|
}
|
|
|
|
|
|
void CRecipeParameter::SetValByStr(CString s)
|
|
|
{
|
|
|
switch(m_ParType)
|
|
|
{
|
|
|
case _RecipeParType_Double:
|
|
|
m_ParDoubleVal = CStringToDouble(s);
|
|
|
break;
|
|
|
case _RecipeParType_Bool:
|
|
|
m_ParBoolVal = ((s==BOOL_STR_ON))?(true):(false);
|
|
|
break;
|
|
|
case _RecipeParType_CString:
|
|
|
m_ParStrVal = s;
|
|
|
break;
|
|
|
case _RecipeParType_Int:
|
|
|
m_ParIntVal = CStringToInt(s);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CRecipeParameter::SetTypeByStr(CString TypeStr)
|
|
|
{
|
|
|
if(TypeStr==RCP_PAR_TYPE_DOUBLE)
|
|
|
{
|
|
|
m_ParType = _RecipeParType_Double;
|
|
|
}
|
|
|
if(TypeStr==RCP_PAR_TYPE_STRING)
|
|
|
{
|
|
|
m_ParType = _RecipeParType_CString;
|
|
|
}
|
|
|
if(TypeStr==RCP_PAR_TYPE_BOOL)
|
|
|
{
|
|
|
m_ParType = _RecipeParType_Bool;
|
|
|
}
|
|
|
if(TypeStr==RCP_PAR_TYPE_INT)
|
|
|
{
|
|
|
m_ParType = _RecipeParType_Int;
|
|
|
}
|
|
|
}
|
|
|
void CRecipeParameter::GetRangeStr(CString &Min,CString &Max)
|
|
|
{
|
|
|
if(m_ParType==_RecipeParType_Double)
|
|
|
{
|
|
|
Min = Db2CString(m_DoubleMinVal);
|
|
|
Max = Db2CString(m_DoubleMaxVal);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Min = Max = "---";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
#if 1
|
|
|
CRecipe::CRecipe(void)
|
|
|
{
|
|
|
m_DoubleValCnt = 0;//double 类型参数的数量
|
|
|
m_GroupIdx = -1;//组的编号
|
|
|
m_RecipeIdx = -1;//在组中的编号
|
|
|
|
|
|
m_CurSubRecipeIdx = 0;//当前使用的SubRecipe 索引号
|
|
|
m_bEnableEdit = true;//当前时候可以编辑
|
|
|
RecipeReset();
|
|
|
|
|
|
CSubRecipe SubRecipe;
|
|
|
SubRecipe.m_SubRecipeName = "SubRecipe1";
|
|
|
m_SubRecipeVec.push_back(SubRecipe);//默认有一个SubRecipe
|
|
|
}
|
|
|
void CRecipe::RecipeReset()
|
|
|
{
|
|
|
m_RecipeName = NULL_RECIPE_NAME;//Recipe 名
|
|
|
}
|
|
|
bool CRecipe::IsValid()
|
|
|
{
|
|
|
return (m_RecipeName != NULL_RECIPE_NAME);
|
|
|
}
|
|
|
vector<CRecipeParameter> &CRecipe::GetRecipeParVec()
|
|
|
{
|
|
|
return m_SubRecipeVec[m_CurSubRecipeIdx].m_RecipeParVec;
|
|
|
};
|
|
|
|
|
|
//保存RecipePar 到文件
|
|
|
void CRecipe::SaveRecipeParToFile(CString FilePath)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
//从文件读取recipe 参数
|
|
|
void CRecipe::ReadRecipeParFromFile(CString FilePath)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
//通过参数名获取参数
|
|
|
CRecipeParameter CRecipe::GetRecipePar(CString ParName)
|
|
|
{
|
|
|
CRecipeParameter Par;
|
|
|
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
for(int i=0;i<size;i++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[i];
|
|
|
if(RecipePar.m_ParName == ParName)
|
|
|
{
|
|
|
Par = RecipePar;
|
|
|
}
|
|
|
}
|
|
|
return Par;
|
|
|
}
|
|
|
//设置指定的参数
|
|
|
void CRecipe::SetRecipePar(CString ParName,CRecipeParameter Par)
|
|
|
{
|
|
|
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
for(int i=0;i<size;i++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[i];
|
|
|
if(RecipePar.m_ParName == ParName)
|
|
|
{
|
|
|
RecipePar = Par;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//检查参数范围
|
|
|
bool CRecipe::CheckParRange(bool bShowMsg)
|
|
|
{
|
|
|
gLogMgr->WriteDebugLog("Func---->Check Recipe Par Range");
|
|
|
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
for(int i=0;i<m_DoubleValCnt;i++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[i];
|
|
|
if(!CheckParRangeExt(RecipePar,RecipePar.m_ParDoubleVal,bShowMsg))
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
bool CRecipe::CheckParRangeExt(CRecipeParameter &RecipePar,double ParVal,bool bShowMsg)
|
|
|
{
|
|
|
//优先使用文件中的参数
|
|
|
double DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RecipePar.m_ParName);
|
|
|
if(IsDbEqualZero(DoubleMaxVal))
|
|
|
DoubleMaxVal = RecipePar.m_DoubleMaxVal;
|
|
|
|
|
|
if(ParVal<RecipePar.m_DoubleMinVal || ParVal>DoubleMaxVal)
|
|
|
{
|
|
|
CString s,s1;
|
|
|
s += "[";
|
|
|
s += RecipePar.m_ParShowName;
|
|
|
s += "]";
|
|
|
s1.Format(" : %.2f",ParVal);
|
|
|
s += s1;
|
|
|
s1.Format("\n超出范围[%.2f~%.2f]",RecipePar.m_DoubleMinVal,DoubleMaxVal);
|
|
|
s += s1;
|
|
|
if(bShowMsg)
|
|
|
{
|
|
|
CMsgBox MsgBox;
|
|
|
MsgBox.Show(s);
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
//检查ParName 参数的范围
|
|
|
bool CRecipe::CheckParRangeByName(CString ParName,double val)
|
|
|
{
|
|
|
CRecipeParameter RecipePar = GetRecipePar(ParName);
|
|
|
return CheckParRangeExt(RecipePar,val,true);
|
|
|
}
|
|
|
//获取显示用的名字
|
|
|
CString CRecipe::GetShowName()
|
|
|
{
|
|
|
CString s("无");
|
|
|
if(m_GroupIdx>=0 && m_RecipeIdx>=0)
|
|
|
{
|
|
|
s.Format("[%d][%d]",m_GroupIdx+1,m_RecipeIdx+1);
|
|
|
s += m_RecipeName;
|
|
|
}
|
|
|
else//恢复用recipe
|
|
|
{
|
|
|
s = "Recover : "+m_RecipeName;
|
|
|
}
|
|
|
return s;
|
|
|
}
|
|
|
void CRecipe::AddSubRecipe(CString SubRecipeName)
|
|
|
{
|
|
|
int size = m_SubRecipeVec.size();
|
|
|
if(size>0)
|
|
|
{
|
|
|
CSubRecipe SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];//用当前选择的sub recipe 进行复制
|
|
|
SubRecipe.m_SubRecipeName = SubRecipeName;
|
|
|
m_SubRecipeVec.push_back(SubRecipe);
|
|
|
}
|
|
|
}
|
|
|
void CRecipe::DelSubRecipe(CString SubRecipeName)
|
|
|
{
|
|
|
int size = m_SubRecipeVec.size();
|
|
|
if(m_SubRecipeVec.size()>1)//两个以上才能删除
|
|
|
{
|
|
|
vector<CSubRecipe>::iterator iter = m_SubRecipeVec.begin();
|
|
|
vector<CSubRecipe>::iterator iter_end = m_SubRecipeVec.end();
|
|
|
for(;iter!=iter_end;iter++)
|
|
|
{
|
|
|
if((*iter).m_SubRecipeName == SubRecipeName)
|
|
|
{
|
|
|
m_SubRecipeVec.erase(iter);
|
|
|
m_CurSubRecipeIdx = 0;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
CString CRecipe::GetCurSubRecipeName()
|
|
|
{
|
|
|
CString RecipeName;
|
|
|
if(m_CurSubRecipeIdx>=0 && m_CurSubRecipeIdx<m_SubRecipeVec.size())
|
|
|
{
|
|
|
RecipeName = m_SubRecipeVec[m_CurSubRecipeIdx].m_SubRecipeName;
|
|
|
}
|
|
|
return RecipeName;
|
|
|
}
|
|
|
void CRecipe::SetCurSubRecipeName(CString Name)
|
|
|
{
|
|
|
if(m_CurSubRecipeIdx>=0 && m_CurSubRecipeIdx<m_SubRecipeVec.size())
|
|
|
{
|
|
|
m_SubRecipeVec[m_CurSubRecipeIdx].m_SubRecipeName = Name;
|
|
|
}
|
|
|
}
|
|
|
//读取OffsetTable 到对应的SubRecipe
|
|
|
bool CRecipe::ReadOffsetTableFile(CString TableName)
|
|
|
{
|
|
|
CString TableFilePath = gRecipeMgr->GetOffsetTablePath(TableName);
|
|
|
CSubRecipe &SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];
|
|
|
bool Ret = SubRecipe.m_OffsetTable.ReadOffsetTableFile(TableFilePath);
|
|
|
if(TableName==RECIPE_OFFSET_TBL_NULL)
|
|
|
Ret = true;
|
|
|
return Ret;
|
|
|
}
|
|
|
//获取OffsetTable指定参数的值
|
|
|
double CRecipe::GetOffsetParVal(CString ParName)
|
|
|
{
|
|
|
CSubRecipe &SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];
|
|
|
return SubRecipe.m_OffsetTable.GetOffsetParVal(ParName);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
CRecipeMgr *gRecipeMgr = new CRecipeMgr;
|
|
|
CRecipeMgr::CRecipeMgr(void)
|
|
|
{
|
|
|
m_CurSelGroupIdx = 0;//当前选择的gourp 索引值
|
|
|
m_CurSelRecipeIdx = 0;//当前选择的recipe 索引值
|
|
|
m_CurSelRecipeParIdx = -1;//当前选择的par 索引值
|
|
|
m_pRecipeGroupComb = NULL;
|
|
|
|
|
|
m_FocusAdjustMin = 0;//焦距调整范围最小值
|
|
|
m_FocusAdjustMax = 0;//焦距调整范围最大值
|
|
|
|
|
|
|
|
|
}
|
|
|
CRecipeMgr::~CRecipeMgr(void)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
void CRecipeMgr::OnAppInitialize()
|
|
|
{
|
|
|
//创建recipe 目录
|
|
|
CreatRecipeFilePath();
|
|
|
//初始化recipe dlg
|
|
|
CDlgChildRecipe *pDlg = dynamic_cast<CDlgChildRecipe*>(gChildRecipe);
|
|
|
pDlg->InitDialogItem();
|
|
|
}
|
|
|
//获取参数名list 文件路径
|
|
|
CString CRecipeMgr::GetRecipeNameListPath()
|
|
|
{
|
|
|
CFileMgr FileMgr;
|
|
|
CString FilePath;
|
|
|
FileMgr.GetFullFilePath(FilePath,RECIPE_GROUP_NAME_FILE);//获取完整路径
|
|
|
return FilePath;
|
|
|
}
|
|
|
//获取参数组的路径GroupIdx(0~RECIPE_GROUP_CNT)
|
|
|
CString CRecipeMgr::GetGroupDirPath(int GroupIdx)
|
|
|
{
|
|
|
CFileMgr FileMgr;
|
|
|
CString FilePath;
|
|
|
CString GroupDirName;
|
|
|
GroupDirName.Format("ParGroup%d\\",GroupIdx);
|
|
|
GroupDirName = RECIPE_FILE_PATH + GroupDirName;
|
|
|
FileMgr.GetFullFilePath(FilePath,GroupDirName);//获取完整路径
|
|
|
return FilePath;
|
|
|
}
|
|
|
//设置当前选中的Recipe 索引值
|
|
|
void CRecipeMgr::SetCurSelRecipeIdx(int Idx)
|
|
|
{
|
|
|
int size = m_CurGroupRecipeVec.size();
|
|
|
if(Idx>=0 && Idx<size)
|
|
|
{
|
|
|
m_CurSelRecipeIdx = Idx;
|
|
|
CString s;
|
|
|
s.Format("SetCurSelRecipeIdx : %d",Idx+1);
|
|
|
gLogMgr->WriteDebugLog(s);
|
|
|
}
|
|
|
}
|
|
|
#if 1
|
|
|
//保存当前选择的Recipe
|
|
|
void CRecipeMgr::SaveCurSelRecipe(CRecipe Recipe)
|
|
|
{
|
|
|
int size = m_CurGroupRecipeVec.size();
|
|
|
if(m_CurSelRecipeIdx>=0 && m_CurSelRecipeIdx<size)
|
|
|
{
|
|
|
m_CurGroupRecipeVec[m_CurSelRecipeIdx] = Recipe;
|
|
|
//获取Recipe 参数文件的路径
|
|
|
CString ParPath = GetRecipeFilePath(m_CurSelGroupIdx,m_CurSelRecipeIdx);
|
|
|
Recipe.SaveRecipeParToFile(ParPath);
|
|
|
}
|
|
|
}
|
|
|
//获取Recipe 参数文件的路径
|
|
|
CString CRecipeMgr::GetRecipeFilePath(int GroupIdx,int RecipeIdx)
|
|
|
{
|
|
|
//写入到文件
|
|
|
CFileMgr FileMgr;
|
|
|
CString DirPath = GetGroupDirPath(GroupIdx);
|
|
|
CString FilePath;
|
|
|
FilePath.Format("RecipePar%d.rcp",RecipeIdx);
|
|
|
FilePath = DirPath+FilePath;
|
|
|
return FilePath;
|
|
|
}
|
|
|
|
|
|
//获取当前选择的group 名字
|
|
|
CString CRecipeMgr::GetCurSelGroupName()
|
|
|
{
|
|
|
return m_RecipeGroupNameVec[m_CurSelGroupIdx];
|
|
|
}
|
|
|
//获取当前选择的group recipe 字符串
|
|
|
CString CRecipeMgr::GetSelGroupRecipeStr()
|
|
|
{
|
|
|
CString Num1,Num2;
|
|
|
Num1.Format("<%d>",m_CurSelGroupIdx+1);
|
|
|
Num2.Format("<%d>",m_CurSelRecipeIdx+1);
|
|
|
CString GroupRecipeStr;
|
|
|
GroupRecipeStr += Num1;
|
|
|
GroupRecipeStr += m_RecipeGroupNameVec[m_CurSelGroupIdx];
|
|
|
GroupRecipeStr += Num2;
|
|
|
GroupRecipeStr += m_CurGroupRecipeVec[m_CurSelRecipeIdx].m_RecipeName;
|
|
|
return GroupRecipeStr;
|
|
|
}
|
|
|
|
|
|
//创建当前recipe 的扫描路径
|
|
|
void CRecipeMgr::CreatRecipeScanPath(CRecipe *pRecipe,int SubRecipeIdx)
|
|
|
{
|
|
|
pRecipe->SetCurSubRecipeIdx(SubRecipeIdx);//设置为当前的SubRecipeIdx
|
|
|
CRecipeParameter RecipePar;
|
|
|
//打开扫描区域
|
|
|
CString AreaName;
|
|
|
RecipePar = pRecipe->GetRecipePar(RECIPE_PAR_NAME_SCAN_AREA);
|
|
|
AreaName = RecipePar.m_ParStrVal;
|
|
|
if(!gWaferRecipeDataMgr->SelScanAreaByName(AreaName))
|
|
|
{
|
|
|
CString Msg("扫描区域不存在: ");
|
|
|
Msg += AreaName;
|
|
|
CExceptionMsg ExceptionMsg;
|
|
|
ExceptionMsg.SetMsg(Msg);
|
|
|
throw ExceptionMsg;
|
|
|
}
|
|
|
//创建扫描路径
|
|
|
int AreaIdx;
|
|
|
RecipePar = pRecipe->GetRecipePar(RECIPE_PAR_NAME_AREA_IDX);
|
|
|
AreaIdx = RecipePar.m_ParIntVal-1;
|
|
|
gWaferRecipeDataMgr->CreatScanPath(AreaIdx);
|
|
|
|
|
|
m_pView->RefreshView();
|
|
|
}
|
|
|
void CRecipeMgr::CreatScanPath(CString AreaName,int AreaIdx)
|
|
|
{
|
|
|
//打开路径
|
|
|
if(!gWaferRecipeDataMgr->SelScanAreaByName(AreaName))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
//创建扫描路径
|
|
|
gWaferRecipeDataMgr->CreatScanPath(AreaIdx);
|
|
|
//默认选择area
|
|
|
//CObjContainer &ObjContainer = gLayer.GetObjContainer();
|
|
|
//ObjContainer.SelObjByIdx(AreaIdx);
|
|
|
m_pView->RefreshView();
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
#if 1
|
|
|
CString CRecipeMgr::GetRecipePath()
|
|
|
{
|
|
|
CString DirPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(NEW_RECIPE_FILE_PATH);
|
|
|
return DirPath;
|
|
|
}
|
|
|
void CRecipeMgr::CreatRecipeFilePath()
|
|
|
{
|
|
|
CString DirPath = GetRecipePath();
|
|
|
CFileMgr FileMgr;
|
|
|
if(!FileMgr.IsDirectoryExists(DirPath))
|
|
|
FileMgr.CreatDir(DirPath);
|
|
|
DirPath += "\\";
|
|
|
}
|
|
|
//获取组Recipe文件的完整路径(参数RecipeName 无后缀)
|
|
|
CString CRecipeMgr::GetCtrlRecipeFilePath(CString GroupName,CString RecipeName)
|
|
|
{
|
|
|
CString Path = GetRecipePath();
|
|
|
Path += GroupName;
|
|
|
Path += "\\";
|
|
|
Path += RecipeName;
|
|
|
Path += ".";
|
|
|
Path += RECIPE_FILE_SUFFIX;
|
|
|
return Path;
|
|
|
}
|
|
|
#endif
|
|
|
#if 1
|
|
|
//设置当前选中的group 索引值
|
|
|
void CRecipeMgr::SetCurSelGourpIdx(int Idx)
|
|
|
{
|
|
|
int size = m_NewRecipeGroupNameVec.size();
|
|
|
if(Idx>=0 && Idx<size)
|
|
|
{
|
|
|
m_CurSelGroupName = m_NewRecipeGroupNameVec[Idx];
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_CurSelGroupName = "";
|
|
|
}
|
|
|
}
|
|
|
//是否选择了编辑的recipe
|
|
|
bool CRecipeMgr::IsbSelEditRecipe()
|
|
|
{
|
|
|
return (m_CurSelRecipeName!="");
|
|
|
}
|
|
|
void CRecipeMgr::RecipeCtrlInit(CRecipeCtrlItem &CtrlItem)
|
|
|
{
|
|
|
CString &EditName1 = *(CtrlItem.m_EditName1);
|
|
|
CString &EditName2 = *(CtrlItem.m_EditName2);
|
|
|
ERecipeCtrlType RecipeCtrlType = GetCurRecipeCtrlType();
|
|
|
int size = 0;
|
|
|
switch(RecipeCtrlType)
|
|
|
{
|
|
|
case _RecipeCtrl_AddGroup:
|
|
|
CtrlItem.m_DlgTitle = "Add Recipe Group";
|
|
|
break;
|
|
|
case _RecipeCtrl_DelGroup:
|
|
|
CtrlItem.m_DlgTitle = "Delete Recipe Group";
|
|
|
EditName2 = m_CurSelGroupName;
|
|
|
break;
|
|
|
case _RecipeCtrl_GroupName:
|
|
|
EditName1 = m_CurSelGroupName;
|
|
|
EditName2 = m_CurSelGroupName;
|
|
|
CtrlItem.m_DlgTitle = "Recipe Group ReName";
|
|
|
break;
|
|
|
case _RecipeCtrl_RecipeName:
|
|
|
CtrlItem.m_DlgTitle = "Recipe ReName";
|
|
|
EditName1 = m_CurSelRecipeName;
|
|
|
EditName2 = m_CurSelRecipeName;
|
|
|
break;
|
|
|
case _RecipeCtrl_AddRecipe:
|
|
|
CtrlItem.m_DlgTitle = "Add Recipe";
|
|
|
UpdateRecipeGroupComb(CtrlItem.m_RecipeCtrlGroupComb);
|
|
|
break;
|
|
|
case _RecipeCtrl_MoveRecipe:
|
|
|
CtrlItem.m_DlgTitle = "Move Recipe";
|
|
|
UpdateRecipeGroupComb(CtrlItem.m_RecipeCtrlGroupComb);
|
|
|
EditName2 = m_CurSelRecipeName;
|
|
|
break;
|
|
|
case _RecipeCtrl_CopyRecipe:
|
|
|
CtrlItem.m_DlgTitle = "Copy Recipe";
|
|
|
EditName1 = m_CurSelRecipeName;
|
|
|
EditName2 = m_CurSelRecipeName+"-Copy";
|
|
|
break;
|
|
|
case _RecipeCtrl_DelRecipe:
|
|
|
CtrlItem.m_DlgTitle = "Delete Recipe";
|
|
|
EditName1 = m_CurSelGroupName;
|
|
|
EditName2 = m_CurSelRecipeName;
|
|
|
break;
|
|
|
case _RecipeCtrl_AddSubRecipe:
|
|
|
{
|
|
|
CtrlItem.m_DlgTitle = "Add Sub Recipe";
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
CString Name;
|
|
|
Name.Format("SubRecipe%ld",SubRecipeVec.size()+1);
|
|
|
EditName1 = m_CurSelRecipeName;
|
|
|
EditName2 = Name;
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_DelSubRecipe:
|
|
|
{
|
|
|
CtrlItem.m_DlgTitle = "Delete Sub Recipe";
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
EditName1 = m_CurSelRecipeName;
|
|
|
EditName2 = SubRecipeVec[m_CurEditRecipe.m_CurSubRecipeIdx].m_SubRecipeName;
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_SubRecipeName:
|
|
|
{
|
|
|
CtrlItem.m_DlgTitle = "Sub Recipe ReName";
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
EditName1 = SubRecipeVec[m_CurEditRecipe.m_CurSubRecipeIdx].m_SubRecipeName;
|
|
|
EditName2 = EditName1;
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
//绑定组下拉列表
|
|
|
void CRecipeMgr::BindingRecipeGroupComb(CComboBox *p)
|
|
|
{
|
|
|
m_pRecipeGroupComb = p;
|
|
|
UpdateRecipeGroupVec();
|
|
|
UpdateRecipeGroupComb(m_pRecipeGroupComb);
|
|
|
};
|
|
|
//刷新RecipeGroup 信息
|
|
|
void CRecipeMgr::UpdateRecipeGroupInfo()
|
|
|
{
|
|
|
UpdateRecipeGroupVec();
|
|
|
UpdateRecipeGroupComb(m_pRecipeGroupComb);
|
|
|
}
|
|
|
//更新组列表容器
|
|
|
void CRecipeMgr::UpdateRecipeGroupVec()
|
|
|
{
|
|
|
m_NewRecipeGroupNameVec.clear();
|
|
|
CString DirPath = GetRecipePath();
|
|
|
CFileMgr FileMgr;
|
|
|
vector<CString> FilePathVec;
|
|
|
FileMgr.GetChildFileOrDirName(true,GetRecipePath(),FilePathVec,"");
|
|
|
int size = FilePathVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
CString GroupName = FileMgr.GetFileNameFromPath(FilePathVec[k],true);
|
|
|
m_NewRecipeGroupNameVec.push_back(GroupName);
|
|
|
}
|
|
|
}
|
|
|
void CRecipeMgr::UpdatParBoolComb(CComboBox &Comb)
|
|
|
{
|
|
|
Comb.ResetContent();//清空
|
|
|
Comb.InsertString(0,BOOL_STR_ON);
|
|
|
Comb.InsertString(1,BOOL_STR_OFF);
|
|
|
}
|
|
|
//更新组下拉列表
|
|
|
void CRecipeMgr::UpdateRecipeGroupComb(CComboBox *pComb)
|
|
|
{
|
|
|
if(!pComb)
|
|
|
return;
|
|
|
CComboBox &ComboBox = *pComb;
|
|
|
ComboBox.ResetContent();//清空
|
|
|
int idx = -1;
|
|
|
int size = m_NewRecipeGroupNameVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
ComboBox.InsertString(k,m_NewRecipeGroupNameVec[k]);
|
|
|
if(m_CurSelGroupName == m_NewRecipeGroupNameVec[k])
|
|
|
idx = k;
|
|
|
}
|
|
|
if(idx>=0)
|
|
|
ComboBox.SetCurSel(idx);
|
|
|
}
|
|
|
void CRecipeMgr::UpdateSelRecipeComb(CComboBox &ComboBox,vector<CString> &SelGroupRecipeNameVec)
|
|
|
{
|
|
|
ComboBox.ResetContent();//清空
|
|
|
//从当前选中的recipe 目录读取recipe 文件列表
|
|
|
ReadCurGroupRecipeName(SelGroupRecipeNameVec);
|
|
|
int size = SelGroupRecipeNameVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
ComboBox.InsertString(k,SelGroupRecipeNameVec[k]);
|
|
|
}
|
|
|
}
|
|
|
void CRecipeMgr::UpdateSelSubRecipeComb(CComboBox &ComboBox,CRecipe Recipe)
|
|
|
{
|
|
|
ComboBox.ResetContent();//清空
|
|
|
|
|
|
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
ComboBox.InsertString(k,SubRecipeVec[k].m_SubRecipeName);
|
|
|
}
|
|
|
ComboBox.SetCurSel(0);
|
|
|
}
|
|
|
|
|
|
void CRecipeMgr::InitGroupRecipeList(CListCtrl &List)
|
|
|
{
|
|
|
//设置风格
|
|
|
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
|
|
|
//设置列
|
|
|
int idx = 0;
|
|
|
List.InsertColumn(idx,"Idx",LVCFMT_LEFT,50,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"Recipe Name",LVCFMT_LEFT,300,-1);
|
|
|
idx++;
|
|
|
|
|
|
}
|
|
|
void CRecipeMgr::InitEditSubRecipeList(CListCtrl &List)
|
|
|
{
|
|
|
//设置风格
|
|
|
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
|
|
|
//设置列
|
|
|
int idx = 0;
|
|
|
List.InsertColumn(idx,"Idx",LVCFMT_LEFT,50,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"Sub Recipe Name",LVCFMT_LEFT,430,-1);
|
|
|
idx++;
|
|
|
}
|
|
|
void CRecipeMgr::InitEditRecipeList(CListCtrl &List,bool bShowParRange)
|
|
|
{
|
|
|
//设置风格
|
|
|
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
|
|
|
//设置列
|
|
|
int idx = 0;
|
|
|
List.InsertColumn(idx,"Idx",LVCFMT_CENTER,35,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"ParName",LVCFMT_LEFT,135,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"Type",LVCFMT_CENTER,80,-1);
|
|
|
idx++;
|
|
|
if(bShowParRange)
|
|
|
{
|
|
|
List.InsertColumn(idx,"Min",LVCFMT_CENTER,80,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"Max",LVCFMT_CENTER,80,-1);
|
|
|
idx++;
|
|
|
}
|
|
|
List.InsertColumn(idx,"Unit",LVCFMT_CENTER,80,-1);
|
|
|
idx++;
|
|
|
List.InsertColumn(idx,"Value",LVCFMT_LEFT,250,-1);
|
|
|
idx++;
|
|
|
}
|
|
|
void CRecipeMgr::UpdateGroupRecipeList(CListCtrl &List)
|
|
|
{
|
|
|
//从当前选中的recipe 目录读取recipe 文件列表
|
|
|
ReadCurGroupRecipeName(m_CurSelGroupRecipeNameVec);
|
|
|
List.DeleteAllItems();
|
|
|
int size = m_CurSelGroupRecipeNameVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
List.InsertItem(k," ");//插入一行
|
|
|
List.SetItemText(k,idx++,Int2CString(k+1));//序号
|
|
|
CString RecipeName = m_CurSelGroupRecipeNameVec[k];
|
|
|
RecipeName += ".";
|
|
|
RecipeName += RECIPE_FILE_SUFFIX;
|
|
|
List.SetItemText(k,idx++,m_CurSelGroupRecipeNameVec[k]);
|
|
|
}
|
|
|
}
|
|
|
void CRecipeMgr::UpdateEditSubRecipeList(CListCtrl &List)
|
|
|
{
|
|
|
List.DeleteAllItems();
|
|
|
if(!IsbSelEditRecipe())
|
|
|
return;
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
List.InsertItem(k," ");//插入一行
|
|
|
List.SetItemText(k,idx++,Int2CString(k+1));//序号
|
|
|
List.SetItemText(k,idx++,SubRecipeVec[k].m_SubRecipeName);
|
|
|
}
|
|
|
//高亮选择的行
|
|
|
List.SetItemState(m_CurEditRecipe.m_CurSubRecipeIdx,LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
|
|
|
}
|
|
|
void CRecipeMgr::UpdateEditRecipeList(CListCtrl &RecipeList,CListCtrl &RecipeInfoList,bool bResetErrRangeParIdxSet)
|
|
|
{
|
|
|
RecipeInfoList.DeleteAllItems();
|
|
|
if(bResetErrRangeParIdxSet)
|
|
|
{
|
|
|
RecipeList.DeleteAllItems();
|
|
|
ResetParIdxSet();
|
|
|
}
|
|
|
if(!IsbSelEditRecipe())//没有选择要编辑的Recipe
|
|
|
return;
|
|
|
//更新激光焦距相关config,计算焦距调整范围
|
|
|
UpdateLaserFocusProp();
|
|
|
//更新当前的无效参数索引值
|
|
|
UpdateInvalidParIdxSet(m_CurEditRecipe);
|
|
|
//更新recipe 的非设置参数
|
|
|
UpdateRecipeInfoPar(m_CurEditRecipe);
|
|
|
|
|
|
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
if(size<=0)
|
|
|
return;
|
|
|
int RecipeListIdx = 0;
|
|
|
int RecipeInfoListIdx = 0;
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
#if 0
|
|
|
//改变焦距微调值的范围
|
|
|
if(RecipePar.m_ParName ==RECIPE_PAR_NAME_FOCUS_ADJUST_VAL)
|
|
|
{
|
|
|
RecipePar.m_DoubleMinVal = m_FocusAdjustMin;
|
|
|
RecipePar.m_DoubleMaxVal= m_FocusAdjustMax;
|
|
|
}
|
|
|
#endif
|
|
|
CString Min,Max;
|
|
|
RecipePar.GetRangeStr(Min,Max);
|
|
|
if(RecipePar.m_bRcpInfoPar)//计算参数
|
|
|
{
|
|
|
RecipeInfoList.InsertItem(RecipeInfoListIdx," ");//插入一行
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Int2CString(RecipeInfoListIdx+1));//序号
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Min);//最小值
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Max);//最大值
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParStr());//参数值
|
|
|
RecipeInfoListIdx++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if(bResetErrRangeParIdxSet)
|
|
|
{
|
|
|
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Min);//最小值
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Max);//最大值
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
|
|
|
RecipeListIdx++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
void CRecipeMgr::UpdateEditRecipeListExt(CListCtrl &RecipeList,CRecipe &Recipe)
|
|
|
{
|
|
|
RecipeList.DeleteAllItems();
|
|
|
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
if(size<=0)
|
|
|
return;
|
|
|
int RecipeListIdx = 0;
|
|
|
int RecipeInfoListIdx = 0;
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
CString Min,Max;
|
|
|
RecipePar.GetRangeStr(Min,Max);
|
|
|
if(!RecipePar.m_bRcpInfoPar)
|
|
|
{
|
|
|
{
|
|
|
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Min);//最小值
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Max);//最大值
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
|
|
|
RecipeListIdx++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//不区分编辑和非编辑参数
|
|
|
void CRecipeMgr::UpdateAllRecipeParToList(CRecipe Recipe,CListCtrl &RecipeList)
|
|
|
{
|
|
|
RecipeList.DeleteAllItems();
|
|
|
//更新recipe 的非设置参数
|
|
|
UpdateRecipeInfoPar(Recipe);
|
|
|
|
|
|
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
int RecipeListIdx = 0;
|
|
|
int RecipeInfoListIdx = 0;
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
RecipeList.InsertItem(k," ");//插入一行
|
|
|
RecipeList.SetItemText(k,idx++,Int2CString(k+1));//序号
|
|
|
RecipeList.SetItemText(k,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeList.SetItemText(k,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeList.SetItemText(k,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeList.SetItemText(k,idx++,RecipePar.GetParStr());//参数值
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//更新区域索引值下拉列表
|
|
|
void CRecipeMgr::UpdateAreaIdxCombo(CComboBox &AreaIdxComb)
|
|
|
{
|
|
|
CObjContainer &ObjContainer = gLayer.GetObjContainer();
|
|
|
int AreaCnt = ObjContainer.GetScanAreaCnt();
|
|
|
AreaIdxComb.ResetContent();//清空
|
|
|
int idx = 0;
|
|
|
for(int k=0;k<AreaCnt;k++)
|
|
|
{
|
|
|
CString Str = GetAreaIdxStr(k);
|
|
|
AreaIdxComb.InsertString(idx++,Str);
|
|
|
}
|
|
|
}
|
|
|
CString CRecipeMgr::GetAreaIdxStr(int k)
|
|
|
{
|
|
|
CString Str;
|
|
|
if(k<9)
|
|
|
Str.Format("[0%d]",k+1);
|
|
|
else
|
|
|
Str.Format("[%d]",k+1);
|
|
|
Str += "区域";
|
|
|
return Str;
|
|
|
}
|
|
|
#endif
|
|
|
#if 1
|
|
|
void CRecipeMgr::AddRecipeGroup(CString GroupName)
|
|
|
{
|
|
|
CString GroupPath = GetRecipePath();
|
|
|
GroupPath += "\\";
|
|
|
GroupPath += GroupName;
|
|
|
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.CreatDir(GroupPath);
|
|
|
}
|
|
|
//删除Recipe组
|
|
|
void CRecipeMgr::DeleteRecipeGroup(CString GroupName)
|
|
|
{
|
|
|
CFileMgr FileMgr;
|
|
|
CString Path = GetRecipePath();
|
|
|
Path += GroupName;
|
|
|
Path += "\\";
|
|
|
|
|
|
CWorkTime WorkTime;
|
|
|
CCsvData CsvData;
|
|
|
CsvData.AddData("用户",false);
|
|
|
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
|
|
|
CsvData.AddData("操作时间",false);
|
|
|
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
|
|
|
CsvData.AddData("Group 路径",false);
|
|
|
CsvData.AddData(Path,true);
|
|
|
CsvData.AddData("操作类型",false);
|
|
|
CsvData.AddData("删除recipe group",true);
|
|
|
|
|
|
vector<CString> RcpPathVec;
|
|
|
FileMgr.GetChildFileOrDirName(false,Path,RcpPathVec,RECIPE_FILE_SUFFIX);
|
|
|
int size1 = RcpPathVec.size();
|
|
|
for(int i=0;i<size1;i++)
|
|
|
{
|
|
|
CString Name = FileMgr.GetFileNameFromPath(RcpPathVec[i],true);
|
|
|
CsvData.AddData("删除recipe ",false);
|
|
|
CsvData.AddData(Name,true);
|
|
|
|
|
|
}
|
|
|
|
|
|
CString FileName = WorkTime.GetCurTime("_");
|
|
|
FileName += "_";
|
|
|
FileName += GroupName;
|
|
|
CString DataPath = CreatCurParDataPath();
|
|
|
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
|
|
|
|
|
|
//执行删除
|
|
|
FileMgr.DeleteFolder(Path);
|
|
|
|
|
|
|
|
|
}
|
|
|
//添加recipe
|
|
|
void CRecipeMgr::AddRecipe(CString GroupName,CString RecipeName)
|
|
|
{
|
|
|
if(!CheckRecipeNameExist(RecipeName))
|
|
|
return;
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(GroupName,RecipeName);
|
|
|
gLogMgr->WriteDebugLog(RecipeFilePath);
|
|
|
|
|
|
CRecipe Recipe;
|
|
|
SaveRecipeToXml(RecipeFilePath,Recipe);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_AddRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = RecipeFilePath;
|
|
|
RecipeCtrlPar.m_RcpName = RecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
//删除Recipe
|
|
|
void CRecipeMgr::DeletRecipe(CString RecipeName)
|
|
|
{
|
|
|
CString Path = GetCtrlRecipeFilePath(m_CurSelGroupName,RecipeName);
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.DeleteFolder(Path);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_DelRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = Path;
|
|
|
RecipeCtrlPar.m_RcpName = RecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
//移动recipe 到GroupName
|
|
|
void CRecipeMgr::MoveRecipe(CString GroupName,CString RecipeName)
|
|
|
{
|
|
|
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,RecipeName);
|
|
|
CString NewPath = GetCtrlRecipeFilePath(GroupName,RecipeName);
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.MoveFolder(OldPath,NewPath);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_MoveRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = OldPath;
|
|
|
RecipeCtrlPar.m_NewFilePath = NewPath;
|
|
|
RecipeCtrlPar.m_RcpName = RecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
//复制选择的recipe 到当前的group
|
|
|
void CRecipeMgr::CopyRecipe(CString NewRecipeName)
|
|
|
{
|
|
|
if(!CheckRecipeNameExist(NewRecipeName))
|
|
|
return;
|
|
|
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
|
|
|
CString NewPath = GetCtrlRecipeFilePath(m_CurSelGroupName,NewRecipeName);
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.CopyFolder(OldPath,NewPath);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_CopyRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = OldPath;
|
|
|
RecipeCtrlPar.m_RcpName = m_CurSelRecipeName;
|
|
|
RecipeCtrlPar.m_RcpNameNew = NewRecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
bool CRecipeMgr::ReadEditRecipeFromFile()
|
|
|
{
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
|
|
|
if(ReadRecipeFromXml(RecipeFilePath,m_CurEditRecipe))
|
|
|
{
|
|
|
m_CurEditRecipe.m_RecipeName = m_CurSelRecipeName;
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
bool CRecipeMgr::ReadEditRecipeFromFile(CRecipe &Recipe,int SelGroupIdx,CString SelRecipeName)
|
|
|
{
|
|
|
int size = m_NewRecipeGroupNameVec.size();
|
|
|
if(SelGroupIdx<0||SelGroupIdx>=size)
|
|
|
return false;
|
|
|
CString SelGroupName = m_NewRecipeGroupNameVec[SelGroupIdx];
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(SelGroupName,SelRecipeName);
|
|
|
Recipe.m_RecipeName = SelRecipeName;
|
|
|
return ReadRecipeFromXml(RecipeFilePath,Recipe);
|
|
|
}
|
|
|
//改变组名称
|
|
|
void CRecipeMgr::ChangeGroupName(CString NewGroupName)
|
|
|
{
|
|
|
CString OldGroupPath = GetRecipePath();
|
|
|
CString NewGroupPath = OldGroupPath + NewGroupName;
|
|
|
OldGroupPath += m_CurSelGroupName;
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.ReNameFolder(OldGroupPath,NewGroupPath);
|
|
|
m_CurSelGroupName = NewGroupName;
|
|
|
m_CurEditRecipe.m_FilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
|
|
|
}
|
|
|
//改变recipe 名称
|
|
|
void CRecipeMgr::ChangeRecipeName(CString NewRcpName)
|
|
|
{
|
|
|
if(!CheckRecipeNameExist(NewRcpName))
|
|
|
return;
|
|
|
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
|
|
|
CString NewPath = GetCtrlRecipeFilePath(m_CurSelGroupName,NewRcpName);
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.ReNameFolder(OldPath,NewPath);
|
|
|
SetCurSelRecipeName(NewRcpName);
|
|
|
m_CurEditRecipe.m_FilePath = NewPath;
|
|
|
}
|
|
|
//改变SubRecipe 名称
|
|
|
void CRecipeMgr::ChangeSubRecipeName(CString NewRcpName)
|
|
|
{
|
|
|
m_CurEditRecipe.SetCurSubRecipeName(NewRcpName);
|
|
|
//保存
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
|
|
|
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
|
|
|
}
|
|
|
|
|
|
CString CRecipeMgr::GetRecipeCtrlName(ERecipeCtrlType RecipeCtrlType)
|
|
|
{
|
|
|
CString CtrlName;
|
|
|
switch(RecipeCtrlType)
|
|
|
{
|
|
|
case _RecipeCtrl_AddGroup:
|
|
|
CtrlName = "Add Group";
|
|
|
break;
|
|
|
case _RecipeCtrl_DelGroup:
|
|
|
CtrlName = "Delete Group";
|
|
|
break;
|
|
|
case _RecipeCtrl_GroupName:
|
|
|
CtrlName = "Group ReName";
|
|
|
break;
|
|
|
case _RecipeCtrl_AddRecipe:
|
|
|
CtrlName = "Add Recipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_DelRecipe:
|
|
|
CtrlName = "Delete Recipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_CopyRecipe:
|
|
|
CtrlName = "Copy Recipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_MoveRecipe:
|
|
|
CtrlName = "Move Recipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_RecipeName:
|
|
|
CtrlName = "Recipe ReName";
|
|
|
break;
|
|
|
case _RecipeCtrl_AddSubRecipe:
|
|
|
CtrlName = "Add SubRecipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_DelSubRecipe:
|
|
|
CtrlName = "Delete SubRecipe";
|
|
|
break;
|
|
|
case _RecipeCtrl_SubRecipeName:
|
|
|
CtrlName = "SubRecipe ReName";
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
return CtrlName;
|
|
|
}
|
|
|
//从当前选中的recipe 目录读取recipe 文件列表
|
|
|
void CRecipeMgr::ReadCurGroupRecipeName(vector<CString> &SelGroupRecipeNameVec)
|
|
|
{
|
|
|
SelGroupRecipeNameVec.clear();
|
|
|
CString RecipePath = GetRecipePath();
|
|
|
RecipePath += m_CurSelGroupName;
|
|
|
CFileMgr FileMgr;
|
|
|
vector<CString> FilePathVec;
|
|
|
FileMgr.GetChildFileOrDirName(false,RecipePath,FilePathVec,RECIPE_FILE_SUFFIX);
|
|
|
int size = FilePathVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
SelGroupRecipeNameVec.push_back(FileMgr.GetFileNameFromPath(FilePathVec[k],true));
|
|
|
}
|
|
|
}
|
|
|
CString CRecipeMgr::RecipeCtrlExcute(CRecipeCtrlItem &CtrlItem)
|
|
|
{
|
|
|
CString CtrlStr;
|
|
|
CString ErrMsg;
|
|
|
CString &EditName1 = *(CtrlItem.m_EditName1);
|
|
|
CString &EditName2 = *(CtrlItem.m_EditName2);
|
|
|
CString &SelGroupName = CtrlItem.m_SelGroupName;
|
|
|
|
|
|
bool bUpdateRecipeGroup = false;
|
|
|
ERecipeCtrlType RecipeCtrlType = GetCurRecipeCtrlType();
|
|
|
if(RecipeCtrlType==_RecipeCtrl_AddGroup
|
|
|
||RecipeCtrlType==_RecipeCtrl_GroupName
|
|
|
||RecipeCtrlType==_RecipeCtrl_RecipeName
|
|
|
||RecipeCtrlType==_RecipeCtrl_AddRecipe)
|
|
|
{
|
|
|
if(EditName2.Find('.',0)!= -1)
|
|
|
{
|
|
|
ErrMsg = "不能有小数点!";
|
|
|
return ErrMsg;
|
|
|
}
|
|
|
if(EditName2=="")
|
|
|
{
|
|
|
ErrMsg = "输入不能为空!";
|
|
|
return ErrMsg;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
switch(RecipeCtrlType)
|
|
|
{
|
|
|
case _RecipeCtrl_AddGroup:
|
|
|
AddRecipeGroup(EditName2);
|
|
|
CtrlStr = EditName2;
|
|
|
bUpdateRecipeGroup = true;
|
|
|
break;
|
|
|
case _RecipeCtrl_DelGroup:
|
|
|
DeleteRecipeGroup(EditName2);
|
|
|
CtrlStr = EditName2;
|
|
|
bUpdateRecipeGroup = true;
|
|
|
break;
|
|
|
case _RecipeCtrl_GroupName:
|
|
|
ChangeGroupName(EditName2);
|
|
|
CtrlStr = EditName1 + "->" + EditName2;
|
|
|
bUpdateRecipeGroup = true;
|
|
|
break;
|
|
|
case _RecipeCtrl_RecipeName:
|
|
|
ChangeRecipeName(EditName2);
|
|
|
CtrlStr = EditName1 + "->" + EditName2;
|
|
|
bUpdateRecipeGroup = false;
|
|
|
break;
|
|
|
case _RecipeCtrl_AddRecipe:
|
|
|
AddRecipe(SelGroupName,EditName2);
|
|
|
CtrlStr = EditName2 + " To Group : " + SelGroupName;
|
|
|
break;
|
|
|
case _RecipeCtrl_DelRecipe:
|
|
|
DeletRecipe(EditName2);
|
|
|
CtrlStr = EditName2 + "Delete From Group: " + EditName1;
|
|
|
break;
|
|
|
case _RecipeCtrl_MoveRecipe:
|
|
|
MoveRecipe(SelGroupName,EditName2);
|
|
|
CtrlStr = EditName2 + " To Group : " + SelGroupName;
|
|
|
break;
|
|
|
case _RecipeCtrl_CopyRecipe:
|
|
|
CopyRecipe(EditName2);
|
|
|
CtrlStr = EditName1 + "Copy To: " + EditName2;
|
|
|
break;
|
|
|
case _RecipeCtrl_AddSubRecipe:
|
|
|
AddSubRecipe(EditName2);
|
|
|
CtrlStr = EditName2 + " To Recipe : " + EditName1;
|
|
|
break;
|
|
|
case _RecipeCtrl_DelSubRecipe:
|
|
|
DelSubRecipe(EditName2);
|
|
|
CtrlStr = EditName2 + " From Recipe : " + EditName1;
|
|
|
break;
|
|
|
case _RecipeCtrl_SubRecipeName:
|
|
|
ChangeSubRecipeName(EditName2);
|
|
|
CtrlStr = EditName1 + "->" + EditName2;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
if(bUpdateRecipeGroup)
|
|
|
{
|
|
|
UpdateRecipeGroupVec();
|
|
|
UpdateRecipeGroupComb(m_pRecipeGroupComb);
|
|
|
}
|
|
|
CString CtrlName = "RecipeCtrl-->";
|
|
|
CtrlName += GetRecipeCtrlName(RecipeCtrlType);
|
|
|
CtrlName += " : ";
|
|
|
CString Log = CtrlName + CtrlStr;
|
|
|
gLogMgr->WriteDebugLog(Log);
|
|
|
|
|
|
return ErrMsg;
|
|
|
}
|
|
|
|
|
|
bool CRecipeMgr::EditRecipeByCtrlType(ERecipeCtrlType CtrlType)
|
|
|
{
|
|
|
CString ErrMsg;
|
|
|
//检查执行条件
|
|
|
switch(CtrlType)
|
|
|
{
|
|
|
case _RecipeCtrl_AddGroup:
|
|
|
|
|
|
break;
|
|
|
case _RecipeCtrl_AddRecipe:
|
|
|
|
|
|
break;
|
|
|
case _RecipeCtrl_GroupName:
|
|
|
if(m_CurSelGroupName=="")
|
|
|
{
|
|
|
ErrMsg = "没有选择要操作的group";
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_RecipeName:
|
|
|
case _RecipeCtrl_MoveRecipe:
|
|
|
case _RecipeCtrl_CopyRecipe:
|
|
|
case _RecipeCtrl_DelRecipe:
|
|
|
case _RecipeCtrl_AddSubRecipe:
|
|
|
case _RecipeCtrl_DelSubRecipe:
|
|
|
if(!IsbSelEditRecipe())
|
|
|
ErrMsg = "没有选择要操作的Recipe";
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
if(ErrMsg=="" && CtrlType==_RecipeCtrl_DelSubRecipe)
|
|
|
{
|
|
|
if(m_CurEditRecipe.GetSubRecipeVec().size()<=1)
|
|
|
ErrMsg = "只有一个sub Recipe 不能删除";
|
|
|
}
|
|
|
if(ErrMsg!="")
|
|
|
{
|
|
|
CMsgBox MsgBox;
|
|
|
MsgBox.Show(ErrMsg);
|
|
|
return false;
|
|
|
}
|
|
|
m_CurRecipeCtrlType = CtrlType;
|
|
|
CDlgRecipeCtrl dlg;
|
|
|
return (dlg.DoModal()==IDOK);
|
|
|
}
|
|
|
//添加一个sub recipe 到当前编辑的recipe 中
|
|
|
void CRecipeMgr::AddSubRecipe(CString SubRecipeName)
|
|
|
{
|
|
|
m_CurEditRecipe.AddSubRecipe(SubRecipeName);
|
|
|
//保存
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
|
|
|
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_AddSubRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = RecipeFilePath;
|
|
|
RecipeCtrlPar.m_RcpName = m_CurEditRecipe.m_RecipeName;
|
|
|
RecipeCtrlPar.m_SubRcpName = SubRecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
void CRecipeMgr::DelSubRecipe(CString SubRecipeName)
|
|
|
{
|
|
|
m_CurEditRecipe.DelSubRecipe(SubRecipeName);
|
|
|
//保存
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
|
|
|
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
|
|
|
|
|
|
CRecipeCtrlPar RecipeCtrlPar;
|
|
|
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_DelSubRecipe;
|
|
|
RecipeCtrlPar.m_FilePath = RecipeFilePath;
|
|
|
RecipeCtrlPar.m_RcpName = m_CurEditRecipe.m_RecipeName;
|
|
|
RecipeCtrlPar.m_SubRcpName = SubRecipeName;
|
|
|
SaveRecipeHistoy(RecipeCtrlPar);
|
|
|
}
|
|
|
//移动SubRecipe 的顺序
|
|
|
bool CRecipeMgr::MoveSubRecipe(bool bMoveUp)
|
|
|
{
|
|
|
if(!IsbSelEditRecipe())
|
|
|
{
|
|
|
CMsgBox MsgBox;
|
|
|
MsgBox.Show("没有选择要操作的Recipe");
|
|
|
return false;
|
|
|
}
|
|
|
int CurSubRecipeIdx = m_CurEditRecipe.m_CurSubRecipeIdx;
|
|
|
int SwapSubRecipeIdx = (bMoveUp)?(CurSubRecipeIdx-1):(CurSubRecipeIdx+1);//交换的索引值
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
if(SwapSubRecipeIdx >=0 && SwapSubRecipeIdx<size && SwapSubRecipeIdx != CurSubRecipeIdx)
|
|
|
{
|
|
|
swap(SubRecipeVec[CurSubRecipeIdx],SubRecipeVec[SwapSubRecipeIdx]);
|
|
|
m_CurEditRecipe.m_CurSubRecipeIdx = SwapSubRecipeIdx;//更新当前选择项目
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
void CRecipeMgr::SetSubRecipeIdx(int idx)
|
|
|
{
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
if(idx>=0&&idx<size)
|
|
|
{
|
|
|
m_CurEditRecipe.SetCurSubRecipeIdx(idx);
|
|
|
}
|
|
|
}
|
|
|
void CRecipeMgr::OnSelRecipeIdxChange(int idx)
|
|
|
{
|
|
|
SetCurSelRecipeName("");
|
|
|
int size = m_CurSelGroupRecipeNameVec.size();
|
|
|
if(idx>=0&&idx<size)
|
|
|
{
|
|
|
SetCurSelRecipeName(m_CurSelGroupRecipeNameVec[idx]);
|
|
|
}
|
|
|
}
|
|
|
CString CRecipeMgr::GetCurEditRecipeInfo()
|
|
|
{
|
|
|
CString RecipeInfo;
|
|
|
if(IsbSelEditRecipe())
|
|
|
{
|
|
|
RecipeInfo = m_CurEditRecipe.m_FilePath;
|
|
|
}
|
|
|
return RecipeInfo;
|
|
|
}
|
|
|
CString CRecipeMgr::GetCurEditSubRecipeInfo()
|
|
|
{
|
|
|
CString SubRecipeInfo;
|
|
|
if(IsbSelEditRecipe())
|
|
|
{
|
|
|
SubRecipeInfo = m_CurEditRecipe.GetCurSubRecipeName();
|
|
|
}
|
|
|
return SubRecipeInfo;
|
|
|
}
|
|
|
//选择当前recipe 的扫描区域
|
|
|
void CRecipeMgr::SelRecipeScanArea(CComboBox &ComboBox)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
#if 1
|
|
|
//保存recipe 到XML 文件(如果Xml 已存在,会覆盖)
|
|
|
void CRecipeMgr::SaveRecipeToXml(CString FilePath,CRecipe &Recipe)
|
|
|
{
|
|
|
CMyXmlItem XmlItemRoot;//根节点
|
|
|
XmlItemRoot.m_XmlItemName = "Root";
|
|
|
|
|
|
int SubRecipeCnt = Recipe.m_SubRecipeVec.size();
|
|
|
for(int k=0;k<SubRecipeCnt;k++)
|
|
|
{
|
|
|
CSubRecipe &SubRecipe = Recipe.m_SubRecipeVec[k];
|
|
|
CMyXmlItem XmlItemSubRecipe;
|
|
|
XmlItemSubRecipe.m_XmlItemName = "SubRecipe";
|
|
|
XmlItemSubRecipe.m_XmlItemAttributeName = "Name";
|
|
|
XmlItemSubRecipe.m_XmlItemAttributeVal = SubRecipe.m_SubRecipeName;
|
|
|
int size = SubRecipe.m_RecipeParVec.size();
|
|
|
for(int i=0;i<size;i++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = SubRecipe.m_RecipeParVec[i];
|
|
|
if(RecipePar.m_bRcpInfoPar)//跳过非编辑参数
|
|
|
continue;
|
|
|
CMyXmlItem XmlItemPar;
|
|
|
XmlItemPar.m_XmlItemName = "RecipePar";
|
|
|
XmlItemPar.m_XmlItemAttributeName = "Name";
|
|
|
XmlItemPar.m_XmlItemAttributeVal = RecipePar.m_ParName;//参数名
|
|
|
{//参数类型
|
|
|
CMyXmlItem XmlItemParName;
|
|
|
XmlItemParName.m_XmlItemName = XML_ITEM_PAR_TYPE;
|
|
|
CMyXmlItem XmlItemParVal;
|
|
|
XmlItemParVal.m_XmlItemName = RecipePar.GetParTypeStr();
|
|
|
XmlItemParName.AddXmlItem(XmlItemParVal);
|
|
|
XmlItemPar.AddXmlItem(XmlItemParName);
|
|
|
}
|
|
|
{//参数值
|
|
|
CMyXmlItem XmlItemParName;
|
|
|
XmlItemParName.m_XmlItemName = XML_ITEM_PAR_VAL;
|
|
|
CMyXmlItem XmlItemParVal;
|
|
|
XmlItemParVal.m_XmlItemName = RecipePar.GetParStr();
|
|
|
XmlItemParName.AddXmlItem(XmlItemParVal);
|
|
|
XmlItemPar.AddXmlItem(XmlItemParName);
|
|
|
}
|
|
|
XmlItemSubRecipe.AddXmlItem(XmlItemPar);
|
|
|
}
|
|
|
XmlItemRoot.AddXmlItem(XmlItemSubRecipe);
|
|
|
}
|
|
|
|
|
|
CString Log("Save Rcp : ");
|
|
|
Log += FilePath;
|
|
|
gLogMgr->WriteDebugLog(Log);
|
|
|
CMyXmlMgr XmlMgr;
|
|
|
XmlMgr.SaveXmlItemToFile(FilePath,XmlItemRoot);
|
|
|
|
|
|
Log += " Complete" ;
|
|
|
gLogMgr->WriteDebugLog(Log);
|
|
|
}
|
|
|
//从xml 文件中读取Recipe 参数
|
|
|
bool CRecipeMgr::ReadRecipeFromXml(CString FilePath,CRecipe &Recipe)
|
|
|
{
|
|
|
CMyXmlMgr XmlMgr;
|
|
|
CMyXmlItem XmlItemRoot;
|
|
|
XmlMgr.ReadXmlItemFromFile(FilePath,XmlItemRoot);
|
|
|
vector<CMyXmlItem> &SubRecipeVec = XmlItemRoot.m_XmlItemVec;
|
|
|
int SubRecipeCnt = SubRecipeVec.size();
|
|
|
if(SubRecipeCnt<=0)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
Recipe.m_FilePath = FilePath;
|
|
|
Recipe.m_SubRecipeVec.clear();
|
|
|
Recipe.m_CurSubRecipeIdx = 0;
|
|
|
for(int i=0;i<SubRecipeCnt;i++)
|
|
|
{
|
|
|
CMyXmlItem &XmlItemSubRecipe = SubRecipeVec[i];
|
|
|
//恢复Sub Recipe 的参数
|
|
|
CSubRecipe SubRecipe;
|
|
|
SubRecipe.m_SubRecipeName = XmlItemSubRecipe.m_XmlItemAttributeVal;
|
|
|
vector<CMyXmlItem> &RecipeParVec = XmlItemSubRecipe.m_XmlItemVec;
|
|
|
int ParCnt = RecipeParVec.size();
|
|
|
for(int j=0;j<ParCnt;j++)
|
|
|
{
|
|
|
CMyXmlItem &XmlItemRecipePar = RecipeParVec[j];
|
|
|
CRecipeParameter XmlRecipePar;
|
|
|
XmlRecipePar.m_ParName = XmlItemRecipePar.m_XmlItemAttributeVal;
|
|
|
vector<CMyXmlItem> &RecipeParInfoVec = XmlItemRecipePar.m_XmlItemVec;
|
|
|
int ParInfoCnt = RecipeParInfoVec.size();
|
|
|
for(int k=0;k<ParInfoCnt;k++)
|
|
|
{
|
|
|
CMyXmlItem &XmlItemParInfo = RecipeParInfoVec[k];
|
|
|
CString ParInfoName = XmlItemParInfo.m_XmlItemName;
|
|
|
CString ParInfoVal;
|
|
|
vector<CMyXmlItem> &RecipeParInfoValVec = XmlItemParInfo.m_XmlItemVec;
|
|
|
if(!RecipeParInfoValVec.empty())
|
|
|
{
|
|
|
ParInfoVal = RecipeParInfoValVec[0].m_XmlItemName;
|
|
|
}
|
|
|
if(ParInfoName==XML_ITEM_PAR_TYPE)
|
|
|
{
|
|
|
XmlRecipePar.SetTypeByStr(ParInfoVal);
|
|
|
}
|
|
|
if(ParInfoName==XML_ITEM_PAR_VAL)
|
|
|
{
|
|
|
XmlRecipePar.SetValByStr(ParInfoVal);
|
|
|
}
|
|
|
}
|
|
|
vector<CRecipeParameter> &SubRecipeParVec = SubRecipe.m_RecipeParVec;
|
|
|
int SubRecipeParCnt = SubRecipeParVec.size();
|
|
|
for(int m=0;m<SubRecipeParCnt;m++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = SubRecipeParVec[m];
|
|
|
if(RecipePar.m_ParName == XmlRecipePar.m_ParName)
|
|
|
{
|
|
|
RecipePar.m_ParBoolVal= XmlRecipePar.m_ParBoolVal;
|
|
|
RecipePar.m_ParDoubleVal= XmlRecipePar.m_ParDoubleVal;
|
|
|
RecipePar.m_ParStrVal= XmlRecipePar.m_ParStrVal;
|
|
|
RecipePar.m_ParIntVal= XmlRecipePar.m_ParIntVal;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Recipe.m_SubRecipeVec.push_back(SubRecipe);
|
|
|
}
|
|
|
|
|
|
|
|
|
CString Log("Read Rcp : ");
|
|
|
Log += FilePath;
|
|
|
gLogMgr->WriteDebugLog(Log);
|
|
|
return true;
|
|
|
}
|
|
|
//创建当前检测数据目录
|
|
|
CString CRecipeMgr::CreatCurParDataPath()
|
|
|
{
|
|
|
CString MonitoringDataPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(PARA_MODIFY_DATA_PATH);
|
|
|
CString Path = MonitoringDataPath;
|
|
|
CFileMgr FileMgr;
|
|
|
CWorkTime WorkTime;
|
|
|
Path += WorkTime.GetCurYear();
|
|
|
Path += "\\"+WorkTime.GetCurMonth();
|
|
|
Path += "\\"+WorkTime.GetCurDay();
|
|
|
Path += "\\";
|
|
|
if(!FileMgr.IsDirectoryExists(Path))
|
|
|
{
|
|
|
FileMgr.CreatDir(Path);
|
|
|
}
|
|
|
return Path;
|
|
|
}
|
|
|
void CRecipeMgr::ResetParIdxSet()
|
|
|
{
|
|
|
m_ErrRangeParIdxSet.clear();
|
|
|
m_ChangeParIdxSet.clear();
|
|
|
}
|
|
|
//保存当前编辑的recipe
|
|
|
bool CRecipeMgr::SaveEditRecipePar(CListCtrl &ListCtrl,CListCtrl &RecipeInfoList)
|
|
|
{
|
|
|
CMsgBox MsgBox;
|
|
|
ResetParIdxSet();
|
|
|
if(!IsbSelEditRecipe())
|
|
|
{
|
|
|
MsgBox.Show("没有选择要操作的Recipe");
|
|
|
return false;
|
|
|
}
|
|
|
CWorkTime WorkTime;
|
|
|
bool bHasParChange = false;//是否有参数变化
|
|
|
CCsvData CsvData;
|
|
|
CsvData.AddData("用户",false);
|
|
|
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
|
|
|
CsvData.AddData("操作时间",false);
|
|
|
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
|
|
|
CsvData.AddData("Recipe Name",false);
|
|
|
CsvData.AddData(m_CurEditRecipe.m_RecipeName,true);
|
|
|
CsvData.AddData("SubRecipe Name",false);
|
|
|
CsvData.AddData(m_CurEditRecipe.GetCurSubRecipeName(),true);
|
|
|
CsvData.AddData("SubRecipe Idx",false);
|
|
|
CsvData.AddData(Int2CString(m_CurEditRecipe.GetCurSubRecipeIdx()),true);
|
|
|
CsvData.AddData("rcp路径",false);
|
|
|
CsvData.AddData(m_CurEditRecipe.m_FilePath,true);
|
|
|
|
|
|
CsvData.AddData(" ",false);
|
|
|
CsvData.AddData(" ",true);
|
|
|
|
|
|
CsvData.AddData("参数名",false);
|
|
|
CsvData.AddData("参数值",false);
|
|
|
CsvData.AddData("修改值",true);
|
|
|
|
|
|
CRecipe RecipeTmp = m_CurEditRecipe;//临时recipe 用来记录range 出错的时候的临时值
|
|
|
bool bLaser1EdiZero = false;//Edi 是否为0
|
|
|
bool bLaser2EdiZero = false;
|
|
|
|
|
|
bool bRangeCheckOk = true;//参数范围检查
|
|
|
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
|
|
|
vector<CRecipeParameter> &RecipeParVecTmp = RecipeTmp.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
CString ParValOld,ParValNew;
|
|
|
CString Log("RecipePar : ");
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
CRecipeParameter &RecipeParTmp = RecipeParVecTmp[k];
|
|
|
ParValOld = RecipePar.GetParStr();
|
|
|
Log += RecipePar.m_ParShowName;
|
|
|
Log += "[";
|
|
|
Log += ParValOld;
|
|
|
Log += "]->[";
|
|
|
|
|
|
CString ParValStr = ListCtrl.GetItemText(k,Rcp_List_Val_Col);
|
|
|
if(RecipePar.m_ParType==_RecipeParType_Double)
|
|
|
{
|
|
|
double Val = CStringToDouble(ParValStr);
|
|
|
if(!(Val>=RecipePar.m_DoubleMinVal && Val<=RecipePar.m_DoubleMaxVal))
|
|
|
{
|
|
|
bRangeCheckOk = false;
|
|
|
RecipeParTmp.m_ParDoubleVal = CStringToDouble(ParValStr);
|
|
|
m_ErrRangeParIdxSet.insert(k);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
RecipePar.m_ParDoubleVal = CStringToDouble(ParValStr);
|
|
|
RecipeParTmp.m_ParDoubleVal = RecipePar.m_ParDoubleVal;
|
|
|
if(RecipePar.m_ParName==RECIPE_PAR_NAME_LASER_EDI_1 && IsDbEqualZero(RecipePar.m_ParDoubleVal))
|
|
|
{
|
|
|
bLaser1EdiZero = true;
|
|
|
}
|
|
|
if(RecipePar.m_ParName==RECIPE_PAR_NAME_LASER_EDI_2 && IsDbEqualZero(RecipePar.m_ParDoubleVal))
|
|
|
{
|
|
|
bLaser2EdiZero = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if(RecipePar.m_ParType==_RecipeParType_Bool)
|
|
|
{
|
|
|
RecipePar.m_ParBoolVal = (ParValStr==BOOL_STR_ON)?true:false;
|
|
|
RecipeParTmp.m_ParBoolVal = RecipePar.m_ParBoolVal;
|
|
|
}
|
|
|
else if(RecipePar.m_ParType==_RecipeParType_Int)
|
|
|
{
|
|
|
RecipePar.m_ParIntVal = CStringToDouble(ParValStr);
|
|
|
RecipeParTmp.m_ParIntVal = RecipePar.m_ParIntVal;
|
|
|
}
|
|
|
else if(RecipePar.m_ParType==_RecipeParType_CString)
|
|
|
{
|
|
|
RecipePar.m_ParStrVal = ParValStr;
|
|
|
RecipeParTmp.m_ParStrVal = RecipePar.m_ParStrVal;
|
|
|
}
|
|
|
ParValNew = RecipePar.GetParStr();
|
|
|
Log += ParValNew;
|
|
|
Log += "]";
|
|
|
gLogMgr->WriteDebugLog(Log);
|
|
|
|
|
|
//只记录非计算参数
|
|
|
if(!RecipePar.m_bRcpInfoPar)
|
|
|
{
|
|
|
if(ParValOld!=ParValNew)
|
|
|
{
|
|
|
bHasParChange = true;
|
|
|
m_ChangeParIdxSet.insert(k);
|
|
|
}
|
|
|
else//无变化
|
|
|
{
|
|
|
ParValNew = "";
|
|
|
}
|
|
|
CsvData.AddData(RecipePar.m_ParShowName,false);
|
|
|
CsvData.AddData(ParValOld,false);
|
|
|
CsvData.AddData(ParValNew,true);
|
|
|
}
|
|
|
}
|
|
|
//更新recipe 的非设置参数
|
|
|
UpdateEditRecipeList(ListCtrl,RecipeInfoList,false);
|
|
|
//检查计算参数的范围
|
|
|
{
|
|
|
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
if(!RecipePar.m_bRcpInfoPar)
|
|
|
continue;
|
|
|
if(RecipePar.m_ParType==_RecipeParType_Double)
|
|
|
{
|
|
|
if(!(RecipePar.m_ParDoubleVal>=RecipePar.m_DoubleMinVal && RecipePar.m_ParDoubleVal<=RecipePar.m_DoubleMaxVal))
|
|
|
{
|
|
|
//edi为0的时候dimmer ang == nan不要提示错误
|
|
|
if(RecipePar.m_ParName==RECIPE_PAR_NAME_ROTATO_DIMMER_ANG && bLaser1EdiZero)
|
|
|
continue;
|
|
|
if(RecipePar.m_ParName==RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2 && bLaser2EdiZero)
|
|
|
continue;
|
|
|
bRangeCheckOk = false;
|
|
|
m_ErrRangeParIdxSet.insert(k);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//刷新list 显示
|
|
|
UpdateEditRecipeListExt(ListCtrl,RecipeTmp);
|
|
|
if(!bRangeCheckOk)
|
|
|
{
|
|
|
MsgBox.Show("参数范围检查失败");
|
|
|
return false;
|
|
|
}
|
|
|
//保存修改记录
|
|
|
if(bHasParChange)//有变化时才保存
|
|
|
{
|
|
|
CString FileName = WorkTime.GetCurTime("_");
|
|
|
FileName += "_";
|
|
|
FileName += m_CurEditRecipe.m_RecipeName;
|
|
|
CString DataPath = CreatCurParDataPath();
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
|
|
|
}
|
|
|
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
|
|
|
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
|
|
|
|
|
|
CString s = m_CurEditRecipe.m_RecipeName;
|
|
|
if(bHasParChange)
|
|
|
s += " 修改成功";
|
|
|
else
|
|
|
s += " 参数无变化";
|
|
|
MsgBox.Show(s);
|
|
|
return true;
|
|
|
}
|
|
|
//保存recipe的操作记录
|
|
|
void CRecipeMgr::SaveRecipeHistoy(CRecipeCtrlPar RecipeCtrlPar)
|
|
|
{
|
|
|
CWorkTime WorkTime;
|
|
|
CCsvData CsvData;
|
|
|
CsvData.AddData("用户",false);
|
|
|
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
|
|
|
CsvData.AddData("操作时间",false);
|
|
|
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
|
|
|
CsvData.AddData("rcp路径",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_FilePath,true);
|
|
|
CsvData.AddData("操作类型",false);
|
|
|
CsvData.AddData(GetRecipeCtrlName(RecipeCtrlPar.m_CtrlType),true);
|
|
|
|
|
|
CsvData.AddData("Recipe Name",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_RcpName,true);
|
|
|
|
|
|
|
|
|
switch(RecipeCtrlPar.m_CtrlType)
|
|
|
{
|
|
|
case _RecipeCtrl_CopyRecipe:
|
|
|
{
|
|
|
CsvData.AddData("Copy Recipe Name",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_RcpNameNew,true);
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_RecipeName:
|
|
|
{
|
|
|
CsvData.AddData("New Recipe Name",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_RcpNameNew,true);
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_MoveRecipe:
|
|
|
{
|
|
|
CsvData.AddData("rcp移动路径",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_NewFilePath,true);
|
|
|
}
|
|
|
break;
|
|
|
case _RecipeCtrl_AddSubRecipe:
|
|
|
case _RecipeCtrl_DelSubRecipe:
|
|
|
{
|
|
|
CsvData.AddData("Sub Recipe Name",false);
|
|
|
CsvData.AddData(RecipeCtrlPar.m_SubRcpName,true);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
CString FileName = WorkTime.GetCurTime("_");
|
|
|
FileName += "_";
|
|
|
FileName += RecipeCtrlPar.m_RcpName;
|
|
|
CString DataPath = CreatCurParDataPath();
|
|
|
CFileMgr FileMgr;
|
|
|
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
|
|
|
}
|
|
|
//更新当前的无效参数索引值
|
|
|
void CRecipeMgr::UpdateInvalidParIdxSet(CRecipe &Recipe)
|
|
|
{
|
|
|
m_InvalidParIdxSet.clear();
|
|
|
CRecipeParameter RecipePar;
|
|
|
//edi check scope 为0 时参数无效,使用config 参数
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_EDI_CHECK_SCOPE);
|
|
|
if(IsDbEqualZero(RecipePar.m_ParDoubleVal))
|
|
|
m_InvalidParIdxSet.insert(Rcp_EdiScope_Idx);
|
|
|
//如果设置了固定扫描速度,重叠率X 无效
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_FIX_SCAN_SPEED);
|
|
|
if(!IsDbEqualZero(RecipePar.m_ParDoubleVal))
|
|
|
m_InvalidParIdxSet.insert(Rcp_OverlapX_Idx);
|
|
|
else
|
|
|
m_InvalidParIdxSet.insert(Rcp_FixSpeed_Idx);
|
|
|
//如果设置了固定扫描间隔,重叠率Y 无效
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_FIX_SCAN_LINE_GAP);
|
|
|
if(!IsDbEqualZero(RecipePar.m_ParDoubleVal))
|
|
|
m_InvalidParIdxSet.insert(Rcp_OverlapY_Idx);
|
|
|
else
|
|
|
m_InvalidParIdxSet.insert(Rcp_FixGap_Idx);
|
|
|
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OFFSET_TAB);
|
|
|
if(RecipePar.m_ParStrVal ==RECIPE_OFFSET_TBL_NULL)
|
|
|
m_InvalidParIdxSet.insert(Rcp_OffsetTab_Idx);
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
#if 1
|
|
|
//更新recipe 的非设置参数
|
|
|
bool CRecipeMgr::UpdateRecipeInfoPar(CRecipe &Recipe)
|
|
|
{
|
|
|
CString log;
|
|
|
log = "Flow---->UpdateRecipeInfoPar : ";
|
|
|
log += Recipe.m_RecipeName;
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
//更新系统参数
|
|
|
gLaser->UpdateLaserProp();
|
|
|
int BakSubRecipeIdx = Recipe.GetCurSubRecipeIdx();//用于恢复
|
|
|
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
Recipe.SetCurSubRecipeIdx(k);//标记当前处理的SubRecipe
|
|
|
|
|
|
CRecipeParameter RecipePar;
|
|
|
double OverlapRatio;//扫描重叠率
|
|
|
double Laser1Fre,Laser2Fre;//脉冲频率
|
|
|
double Laser1Edi;//Laser1功率密度
|
|
|
double Laser2Edi;//Laser2功率密度
|
|
|
double Laser1EdiOffset;//Laser1功率密度Offset
|
|
|
double Laser2EdiOffset;//Laser2功率密度Offset
|
|
|
|
|
|
DbSize SpotSize = gLaser->GetSpotSize(_LaserDeviceType_MainLaser1);//光斑尺寸
|
|
|
|
|
|
if(gLaser->IsbScanByDirX())
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OVERLAP_RATIO_X);
|
|
|
else
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OVERLAP_RATIO_Y);
|
|
|
OverlapRatio = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_FRE);
|
|
|
Laser1Fre = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER2_FRE);
|
|
|
Laser2Fre = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_1);
|
|
|
Laser1Edi = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_2);
|
|
|
Laser2Edi = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_OFFSET_1);
|
|
|
Laser1EdiOffset = RecipePar.m_ParDoubleVal;
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_OFFSET_2);
|
|
|
Laser2EdiOffset = RecipePar.m_ParDoubleVal;
|
|
|
|
|
|
//重叠率/频率/光斑尺寸---->扫描速度
|
|
|
double ScanSpeed = gWaferRecipeDataMgr->CalScanSpeedByOverlapRatio(OverlapRatio,Laser1Fre);
|
|
|
if(ScanSpeed>0)
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_SCAN_SPEED);
|
|
|
RecipePar.m_ParDoubleVal = ScanSpeed;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_SCAN_SPEED,RecipePar);
|
|
|
}
|
|
|
//电流是Recipe 中的设定值
|
|
|
//功率是固定电流点检对应的功率值(还和频率有关)
|
|
|
double Laser1FixCurr = 0;
|
|
|
double Laser2FixCurr = 0;
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_CURR_1);
|
|
|
Laser1FixCurr = RecipePar.m_ParDoubleVal;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER_CURR_1,RecipePar);
|
|
|
}
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_CURR_2);
|
|
|
Laser2FixCurr = RecipePar.m_ParDoubleVal;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER_CURR_2,RecipePar);
|
|
|
}
|
|
|
double Laser1FixPow = 0;
|
|
|
double Laser2FixPow = 0;
|
|
|
gLaser->GetLaserFixedCurrentPow(_LaserDeviceType_MainLaser1,Laser1Fre,Laser1FixCurr,Laser1FixPow);
|
|
|
gLaser->GetLaserFixedCurrentPow(_LaserDeviceType_MainLaser2,Laser2Fre,Laser2FixCurr,Laser2FixPow);
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER1_POW);
|
|
|
RecipePar.m_ParDoubleVal = Laser1FixPow;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER1_POW,RecipePar);
|
|
|
}
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER2_POW);
|
|
|
RecipePar.m_ParDoubleVal = Laser2FixPow;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER2_POW,RecipePar);
|
|
|
}
|
|
|
//读取功率补偿表
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OFFSET_TAB);
|
|
|
CString OffsetTableName = RecipePar.m_ParStrVal;
|
|
|
if(!Recipe.ReadOffsetTableFile(OffsetTableName))
|
|
|
{
|
|
|
//标记为异常
|
|
|
m_ErrRangeParIdxSet.insert(Rcp_OffsetTab_Idx);
|
|
|
}
|
|
|
}
|
|
|
//[功率密度/频率/光斑尺寸]--->[衰减器的旋转角度]
|
|
|
{
|
|
|
double OffsetTabEdi = Recipe.GetOffsetParVal(RECIPE_OFFSET_PAR_LASER1_EDI);
|
|
|
double Edi = Laser1Edi + Laser1EdiOffset + OffsetTabEdi;
|
|
|
double RotatoDimmerAng = gWaferRecipeDataMgr->CalRotatoDimmerAng(SpotSize.w,SpotSize.h,Edi,Laser1Fre,Laser1FixPow);
|
|
|
if(!(RotatoDimmerAng>-180 && RotatoDimmerAng<180))//无效计算范围
|
|
|
{
|
|
|
log.Format("Err Ang = %lf",RotatoDimmerAng);
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
}
|
|
|
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG);
|
|
|
RecipePar.m_ParDoubleVal = RotatoDimmerAng;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG,RecipePar);
|
|
|
}
|
|
|
}
|
|
|
{
|
|
|
double OffsetTabEdi = Recipe.GetOffsetParVal(RECIPE_OFFSET_PAR_LASER2_EDI);
|
|
|
double Edi = Laser2Edi + Laser2EdiOffset + OffsetTabEdi;
|
|
|
double RotatoDimmerAng = gWaferRecipeDataMgr->CalRotatoDimmerAng(SpotSize.w,SpotSize.h,Edi,Laser2Fre,Laser2FixPow);
|
|
|
if(!(RotatoDimmerAng>-180 && RotatoDimmerAng<180))//无效计算范围
|
|
|
{
|
|
|
log.Format("Err Ang = %lf",RotatoDimmerAng);
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
}
|
|
|
{
|
|
|
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2);
|
|
|
RecipePar.m_ParDoubleVal = RotatoDimmerAng;
|
|
|
Recipe.SetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2,RecipePar);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Recipe.SetCurSubRecipeIdx(BakSubRecipeIdx);//恢复
|
|
|
return true;
|
|
|
}
|
|
|
//通过参数名获取当前的recipe 参数
|
|
|
CRecipeParameter CRecipeMgr::GetCurRecipePar(CString ParName)
|
|
|
{
|
|
|
return m_CurWorkRecipe.GetRecipePar(ParName);
|
|
|
}
|
|
|
void CRecipeMgr::CreatCurEditRecipeScanPath()
|
|
|
{
|
|
|
//打开扫描区域
|
|
|
CRecipe &CurEditRecipe = m_CurEditRecipe;
|
|
|
CRecipeParameter RecipePar = CurEditRecipe.GetRecipePar(RECIPE_PAR_NAME_SCAN_AREA);
|
|
|
CString AreaName = RecipePar.m_ParStrVal;
|
|
|
RecipePar = CurEditRecipe.GetRecipePar(RECIPE_PAR_NAME_AREA_IDX);
|
|
|
int AreaIdx = RecipePar.m_ParIntVal-1;
|
|
|
CreatScanPath(AreaName,AreaIdx);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
#if 1
|
|
|
void CRecipeMgr::UpdateEditRecipeListExt(CRecipe &Recipe,CListCtrl &RecipeList,CListCtrl &RecipeInfoList)
|
|
|
{
|
|
|
if(!Recipe.IsValid())
|
|
|
return;
|
|
|
RecipeList.DeleteAllItems();
|
|
|
RecipeInfoList.DeleteAllItems();
|
|
|
//更新recipe 的非设置参数
|
|
|
UpdateRecipeInfoPar(Recipe);
|
|
|
|
|
|
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
|
|
|
int size = RecipeParVec.size();
|
|
|
if(size<=0)
|
|
|
return;
|
|
|
int RecipeListIdx = 0;
|
|
|
int RecipeInfoListIdx = 0;
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
CRecipeParameter &RecipePar = RecipeParVec[k];
|
|
|
if(RecipePar.m_bRcpInfoPar)//计算参数
|
|
|
{
|
|
|
RecipeInfoList.InsertItem(RecipeInfoListIdx," ");//插入一行
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Int2CString(RecipeInfoListIdx+1));//序号
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParStr());//参数值
|
|
|
RecipeInfoListIdx++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
|
|
|
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
|
|
|
RecipeListIdx++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CRecipeMgr::UpdateEditSubRecipeListExt(CRecipe &Recipe,CListCtrl &List)
|
|
|
{
|
|
|
List.DeleteAllItems();
|
|
|
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
if(size<=0)
|
|
|
return;
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
List.InsertItem(k," ");//插入一行
|
|
|
List.SetItemText(k,idx++,Int2CString(k+1));//序号
|
|
|
List.SetItemText(k,idx++,SubRecipeVec[k].m_SubRecipeName);
|
|
|
}
|
|
|
//高亮选择的行
|
|
|
List.SetItemState(Recipe.m_CurSubRecipeIdx,LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
|
|
|
}
|
|
|
//获取RecipeName 对应的文件路径
|
|
|
CString CRecipeMgr::GetRecipePathByName(CString RecipeName)
|
|
|
{
|
|
|
vector<CString> RcpGroupPathVec;
|
|
|
CString DirPath = GetRecipePath();
|
|
|
CFileMgr FileMgr;
|
|
|
//先找到所有组文件夹的路径
|
|
|
FileMgr.GetChildFileOrDirName(true,DirPath,RcpGroupPathVec,"");
|
|
|
//获取所有组文件
|
|
|
int size = RcpGroupPathVec.size();
|
|
|
for(int k=0;k<size;k++)
|
|
|
{
|
|
|
vector<CString> RcpPathVec;
|
|
|
FileMgr.GetChildFileOrDirName(false,RcpGroupPathVec[k],RcpPathVec,RECIPE_FILE_SUFFIX);
|
|
|
int size1 = RcpPathVec.size();
|
|
|
for(int i=0;i<size1;i++)
|
|
|
{
|
|
|
CString Name = FileMgr.GetFileNameFromPath(RcpPathVec[i],true);
|
|
|
if(Name == RecipeName)
|
|
|
return RcpPathVec[i];
|
|
|
}
|
|
|
}
|
|
|
return "";
|
|
|
}
|
|
|
//检查recipe是否存在
|
|
|
bool CRecipeMgr::CheckRecipeNameExist(CString RecipeName)
|
|
|
{
|
|
|
CString RecipePath = GetRecipePathByName(RecipeName);
|
|
|
if(RecipePath != "")
|
|
|
{
|
|
|
CString s;
|
|
|
s = RecipePath + "已存在";
|
|
|
CMsgBox MsgBox;
|
|
|
MsgBox.Show(s);
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
//更新激光焦距相关config
|
|
|
void CRecipeMgr::UpdateLaserFocusProp()
|
|
|
{
|
|
|
gLogMgr->WriteDebugLog("Func---->UpdateLaserFocusProp");
|
|
|
//激光焦距值
|
|
|
double FocusZMoveUpVal = 0;
|
|
|
{
|
|
|
//添加属性变量映射
|
|
|
CString Path = "Laser";
|
|
|
CString Name = _T("m_FocusZMoveUpVal");//变量名字
|
|
|
CPropertie Propertie;
|
|
|
Propertie.SetpVal((void*)&FocusZMoveUpVal);
|
|
|
Propertie.SetType(_PROP_TYPE_DOUBLE);
|
|
|
Propertie.SetPath(Path);
|
|
|
Propertie.SetName(Name);
|
|
|
Propertie.WriteRead(true);//读取属性
|
|
|
}
|
|
|
//测距仪Z轴坐标
|
|
|
double DistanceMeterPosZ = 0;
|
|
|
{
|
|
|
//添加属性变量映射
|
|
|
CString Path = "PlatSpecialPosMgr";
|
|
|
CString Name = _T("m_SpecialPosTypeDistance_MeterPos_z");//变量名字
|
|
|
CPropertie Propertie;
|
|
|
Propertie.SetpVal((void*)&DistanceMeterPosZ);
|
|
|
Propertie.SetType(_PROP_TYPE_DOUBLE);
|
|
|
Propertie.SetPath(Path);
|
|
|
Propertie.SetName(Name);
|
|
|
Propertie.WriteRead(true);//读取属性
|
|
|
}
|
|
|
//Z轴安全坐标
|
|
|
double MotorZSafeCoord = 0;
|
|
|
{
|
|
|
//添加属性变量映射
|
|
|
CString Path = "PlatSpecialPosMgr";
|
|
|
CString Name = _T("m_MotorZSafeCoord");//变量名字
|
|
|
CPropertie Propertie;
|
|
|
Propertie.SetpVal((void*)&MotorZSafeCoord);
|
|
|
Propertie.SetType(_PROP_TYPE_DOUBLE);
|
|
|
Propertie.SetPath(Path);
|
|
|
Propertie.SetName(Name);
|
|
|
Propertie.WriteRead(true);//读取属性
|
|
|
}
|
|
|
|
|
|
CString log;
|
|
|
log.Format("FocusZMoveUpVal=%f,DistanceMeterPosZ=%f,MotorZSafeCoord=%f",FocusZMoveUpVal,DistanceMeterPosZ,MotorZSafeCoord);
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
|
|
|
//计算焦距微调范围
|
|
|
double LaserFocusZ = DistanceMeterPosZ + FocusZMoveUpVal;
|
|
|
|
|
|
m_FocusAdjustMin = (MotorZSafeCoord - LaserFocusZ)+0.5;//向上调0.5mm
|
|
|
m_FocusAdjustMax = (LaserFocusZ*-1)-1;////向下调1 mm
|
|
|
|
|
|
log.Format("LaserFocusZ=%f,FocusAdjustMin=%f,FocusAdjustMax=%f",LaserFocusZ,m_FocusAdjustMin,m_FocusAdjustMax);
|
|
|
gLogMgr->WriteDebugLog(log);
|
|
|
}
|
|
|
//获取TabName 的完整路径
|
|
|
CString CRecipeMgr::GetOffsetTablePath(CString TabName)
|
|
|
{
|
|
|
CString TabPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(OFFSET_TAB_FILE_PATH);
|
|
|
TabPath += TabName;
|
|
|
TabPath += ".tbl";
|
|
|
return TabPath;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
CString CRecipeMgr::GetShowParText(int Row)
|
|
|
{
|
|
|
CString str = "";
|
|
|
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
|
|
|
int size = SubRecipeVec.size();
|
|
|
if (size <= 0)
|
|
|
{
|
|
|
str = "无有效Recipe";
|
|
|
}
|
|
|
str = SubRecipeVec[0].m_RecipeParVec[Row].m_DetailInfo;
|
|
|
return str;
|
|
|
}
|
|
|
|
|
|
#endif
|