#include "StdAfx.h" #include "ObjFillMgr.h" #include "CommandArray.h" #include "CommandMgr.h" #include "Layer.h" #include "MsgBox.h" #include "ObjPline.h" #include "FileMgr.h" #include "PenParMgr.h" #include "Laser.h" #include "ProgramLaserTuiHuo.h" #include "WaferRecipeDataMgr.h" #include "RecipeMgr.h" #include "WorkRecord.h" #include "LogMgr.h" #if 1 CObjFillMgr gObjFillMgr; CObjFillMgr::CObjFillMgr(void) { m_FillOffset = 1;//填充间隔mm m_FillAngle = 90;//填充角度(360 角) m_bDelEdgeObj = false;//是否删除轮廓obj m_bCreatConnectLine = true;//是否创建连接线 m_CurScanType = _SCAN_TRACK_S_L_R;//当前的扫描方式 m_StartFillIdx = 0;//从第几根填充线开始 } CObjFillMgr::~CObjFillMgr(void) { } //更新扫描方式 void CObjFillMgr::UpdateCurScanType() { int WaferScanType = gProgramLaserTuiHuo->GetWaferScanType(); if(WaferScanType>=0&&WaferScanType<8) { m_CurScanType = (SCAN_TRACK_E)WaferScanType; CString log; log.Format("Func--->UpdateCurScanType = %ld",WaferScanType); gLogMgr->WriteDebugLog(log); } } //创建选择对象的填充数据 void CObjFillMgr::FillAllSelObj() { //所有obj 左旋转90 度(为了生成横向的扫描线) if(gLaser->IsbScanByDirX()) gLayer.Rotato(90); //更新扫描方式 UpdateCurScanType(); //初始化 m_ObjContainer.Clear(); m_ScanLineVec.clear(); //通过填充obj 来创建扫描线(保存在m_ScanLineVec) if(!CreatScanLineByObjFill()) return; //通过扫描线来创建obj CreatObjByScanLine(); //将填充线添加到layer FillObjAddToLayer(); //所有obj 右旋转90度 if(gLaser->IsbScanByDirX()) gLayer.Rotato(-90); } void CObjFillMgr::FillObjAddToLayer() { CObjContainer &ObjContainer = gLayer.GetObjContainer(); m_ObjContainer.AllObjAddToContainer(ObjContainer,false); } //创建索引号为idx 的obj 的填充 void CObjFillMgr::FillAllSelObjByIdx(int idx) { CObjContainer &ObjContainer = gLayer.GetObjContainer(); ObjContainer.NotSelAllObj(); } //创建指令 void CObjFillMgr::CreatCmd() { if(!m_ObjContainer.Empty()) { //创建撤销指令-------start CCommandArray *pCmd = new CCommandArray; gCommandMgr.AddUndoCommand(pCmd,m_ObjContainer.GetObjVec()); //删除轮廓obj if(m_bDelEdgeObj) { pCmd->SaveBaseObj(gLayer.GetObjContainer()); } //创建撤销指令-------end pCmd->Excute(); } } //创建填充数据 void CObjFillMgr::CreatObjFillData(CObjContainer &ObjContainer) { SFillPar FillPar; FillPar.m_FillAngle = m_FillAngle; FillPar.bFill = true; FillPar.m_FillGap = m_FillOffset; ObjContainer.FillObj(FillPar,false); } //通过填充obj 来创建扫描线 bool CObjFillMgr::CreatScanLineByObjFill() { CObjContainer &ObjContainer = gLayer.GetObjContainer(); //创建填充数据 CreatObjFillData(ObjContainer); //利用obj 填充算法来画出填充线----------------------------- vector> &ObjVec = ObjContainer.GetObjVec(); vector>::iterator iter = ObjVec.begin(); vector>::iterator iter_end = ObjVec.end(); int idx = 0; bool bNeedCloseLaser = true;//扫描不同区域是否需要关闭激光 vector ScanLineVecTmp; for(;iter!=iter_end;iter++,idx++) { ScanLineVecTmp.clear(); int CurPenNum = idx;//笔号设置为obj 的序列号 if(!(*iter)->IsbFillObj() && (*iter)->IsSelected())//过滤掉填充obj { vector> FillDataVec; (*iter)->GetFillData(FillDataVec); bool DirFlg = false;//反向标示 vector>::iterator iter1 = FillDataVec.begin(); vector>::iterator iter1_end = FillDataVec.end(); for(;iter1!=iter1_end;iter1++) { int size = (*iter1).size(); int idx1 = (DirFlg)?1:0; int idx2 = (DirFlg)?0:1; DirFlg = !DirFlg;//反向 Dbxy pt1 = (*iter1)[idx1]; Dbxy pt2 = (*iter1)[idx2]; if(size==2) { CScanLine ScanLine(pt1,pt2);//创建一条线 ScanLine.SetPenNum(CurPenNum); ScanLineVecTmp.push_back(ScanLine); } } //S 形排序-从下到上,从右到左需要逆序 SCAN_TRACK_E ScanTrack = m_CurScanType; if(ScanTrack == _SCAN_TRACK_S_D_U ||ScanTrack == _SCAN_TRACK_S_R_L) { reverse(ScanLineVecTmp.begin(),ScanLineVecTmp.end()); } vector::iterator iter2 = ScanLineVecTmp.begin(); vector::iterator iter2_end = ScanLineVecTmp.end(); bool bFirst = true;//标记第一条line for(;iter2!=iter2_end;iter2++) { if(bFirst && bNeedCloseLaser) { (*iter2).SetbFirstLine(); bFirst = false; } m_ScanLineVec.push_back(*iter2); } } } if(!m_ScanLineVec.empty()) { m_ScanLineVec[0].SetbFirstLine();//第一个对象强行设置 } //调整扫描线,使扫描路径可以覆盖到晶圆 AdjustScanLine1(); //清空填充线 SFillPar FillPar; FillPar.bFill = false; ObjContainer.FillObj(FillPar,false); return true; } //调整扫描线,使扫描路径可以覆盖到晶圆 void CObjFillMgr::AdjustScanLine1() { vector::iterator iter = m_ScanLineVec.begin(); vector::iterator iter_end = m_ScanLineVec.end(); for(;iter!=iter_end;iter++) { Dbxy StartPt = (*iter).GetStartPt(); Dbxy EndPt = (*iter).GetEndPt(); Dbxy pt1 = StartPt; Dbxy pt2 = StartPt; Dbxy pt3 = EndPt; Dbxy pt4 = EndPt; int PenNum = (*iter).GetPenNum(); double FillAngle; GetAngle(FillAngle,PenNum); if(FillAngle>0) { if(pt1.y>pt3.y) { ScanLineCoverWafer(pt1,pt2,true,PenNum); ScanLineCoverWafer(pt3,pt4,false,PenNum); } else { ScanLineCoverWafer(pt3,pt4,true,PenNum); ScanLineCoverWafer(pt1,pt2,false,PenNum); } StartPt.y = pt1.y; EndPt.y = pt3.y; } else { if(pt1.x>pt3.x) { ScanLineCoverWafer(pt1,pt2,true,PenNum); ScanLineCoverWafer(pt3,pt4,false,PenNum); } else { ScanLineCoverWafer(pt3,pt4,true,PenNum); ScanLineCoverWafer(pt1,pt2,false,PenNum); } StartPt.x = pt1.x; EndPt.x = pt3.x; } (*iter).SetStartPt(StartPt); (*iter).SetEndPt(EndPt); } } //调整扫描线覆盖住晶圆bDir 是调整方向 void CObjFillMgr::ScanLineCoverWafer(Dbxy &pt1,Dbxy &pt2,bool bDir,int PenNum) { //边缘划出距离 double Offset = 0; if(Offset<=0)//等于0 会死循环 Offset = 0.05; if(!bDir) Offset*=-1; double FillAngle; GetAngle(FillAngle,PenNum); while(gLayer.HasObjIntersectWithLine(DbLine(CDataPoint(pt1),CDataPoint(pt2)))) { //只对晶圆边缘的点进行调整 if(FillAngle>0) { pt1.y += Offset; pt2.y += Offset; } else { pt1.x += Offset; pt2.x += Offset; } } } //调整每一行的end 点,和下一行的start 点比较,取X 为离晶圆较远的点 void CObjFillMgr::AdjustScanLine2() { int size = m_ScanLineVec.size(); for(int i=0;i0)?(&(EndPt.y)):(&(EndPt.x)); double *pVal2 = (FillAngle>0)?(&(NextStartPt.y)):(&(NextStartPt.x)); if(abs(*pVal1)GetCurScanState(); //int EndScanLineIdx = ScanState.m_EndScanLineIdx; int size = m_ScanLineVec.size(); Dbxy PerPt; int ScanLineIdx = 0; for(int i=0;i EndPt.y) swap(StartPt,EndPt); } if(ScanTrack == _SCAN_TRACK_R_L)//单向扫描-左到右 { if(StartPt.x < EndPt.x) swap(StartPt,EndPt); } if(ScanTrack == _SCAN_TRACK_L_R)//单向扫描-右到左 { if(StartPt.x > EndPt.x) swap(StartPt,EndPt); } //bool bScaned = (EndScanLineIdx>0 && ScanLineIdx<=EndScanLineIdx); bool bScaned = false; PerPt = EndPt; CObjPline *pObjPline = new CObjPline; pObjPline->SetbFillObj(true);//标记为填充对象 pObjPline->SetPenNum(m_ScanLineVec[i].GetPenNum()); pObjPline->Creat(StartPt,EndPt); //标记被扫描过的线段 pObjPline->SetbScaned(bScaned); if(ScanLineIdx>=m_StartFillIdx) m_ObjContainer.AddObject(pObjPline); //扫描线段 ScanLineIdx++; } } //根据扫描模式获取角度,并返回是否横向扫描 bool CObjFillMgr::GetAngle(double &Angle,int PenNum) { SCAN_TRACK_E ScanTrack = m_CurScanType; bool bhorizontal = false; if(ScanTrack == _SCAN_TRACK_S_U_D || ScanTrack == _SCAN_TRACK_S_D_U|| ScanTrack == _SCAN_TRACK_L_R|| ScanTrack == _SCAN_TRACK_R_L) { bhorizontal = true; Angle = 0; } else if(ScanTrack == _SCAN_TRACK_S_L_R || ScanTrack == _SCAN_TRACK_S_R_L|| ScanTrack == _SCAN_TRACK_U_D|| ScanTrack == _SCAN_TRACK_D_U) { Angle = 90; } return bhorizontal; } #endif