You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

605 lines
16 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "MappingUI.h"
#include <QMessageBox>
MappingUI::MappingUI(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(ui.pushButton_clearCurSelect, SIGNAL(clicked()), this, SLOT(slot_clearCurSelect()));
connect(ui.pushButton_addCurRow, SIGNAL(clicked()), this, SLOT(slot_addCurRow()));
connect(ui.pushButton_addCurRol, SIGNAL(clicked()), this, SLOT(slot_addCurRol()));
connect(ui.pushButton_addCurArea, SIGNAL(clicked()), this, SLOT(slot_addCurArea()));
}
MappingUI::~MappingUI()
{
ClearSceneAndVec();
}
void MappingUI::UseRecipeMappingAndGetCoord(RecipeAttrObj recipeObj, bool isShowDieText)
{
m_isShowDieText = isShowDieText;
m_recipeAttrObj = recipeObj;
SetMappingToInitStatus();
DrawMapping();
}
void MappingUI::DrawMapping()
{
//先清除所有
ClearSceneAndVec();
if (m_recipeAttrObj.m_PPID.size() < 1)
{
return;
}
//计算每个区域X和Y方向die的数量
CountAreaData();
double rectFirstPointX = m_recipeAttrObj.m_baseDieCoordX - (m_recipeAttrObj.m_dieWidth / 2.0);
double rectFirstPointY = -1 * m_recipeAttrObj.m_baseDIeCoordY - (m_recipeAttrObj.m_dieHeight / 2.0);
{
//添加坐标系
m_baseLineXCoordObj = std::make_shared<MyQGraphicsLineItem>();
m_baseLineXCoordObj->SetLineCoord(m_recipeAttrObj.m_waferDie / 2 * -1 - 5, 0, m_recipeAttrObj.m_waferDie / 2 + 5, 0, false);
m_baseLineXCoordObj->setPos(0, 0);
m_allLineItem.push_back(m_baseLineXCoordObj);
m_mappingScene.addItem(m_baseLineXCoordObj.get());
std::shared_ptr<MyQGraphicsLineItem> YCoordLineObj = std::make_shared<MyQGraphicsLineItem>();
YCoordLineObj->SetLineCoord(0, m_recipeAttrObj.m_waferDie / 2 * -1 - 5, 0, m_recipeAttrObj.m_waferDie / 2 + 5, false);
YCoordLineObj->setPos(m_baseLineXCoordObj->pos().x(), m_baseLineXCoordObj->pos().y());
m_allLineItem.push_back(YCoordLineObj);
m_mappingScene.addItem(YCoordLineObj.get());
}
{
//添加基准die
std::shared_ptr<MyQGraphicsRectItem> baseDieObj = nullptr;
baseDieObj = std::make_shared<MyQGraphicsRectItem>(0, 0, m_recipeAttrObj.m_dieWidth, m_recipeAttrObj.m_dieHeight);
SetDieAttr(baseDieObj, true, false, rectFirstPointX, rectFirstPointY);
baseDieObj->setBrush(BASE_POINT_COLOR);
baseDieObj->setPos(m_baseLineXCoordObj->pos().x() + rectFirstPointX,
m_baseLineXCoordObj->pos().y() + rectFirstPointY);
m_allDieItem.push_back(baseDieObj);
m_mappingScene.addItem(baseDieObj.get());
}
{
//绘制晶圆圆形
std::shared_ptr<QGraphicsEllipseItem> EllipseObj = nullptr;
EllipseObj = std::make_shared<QGraphicsEllipseItem>(0, 0, m_recipeAttrObj.m_waferDie, m_recipeAttrObj.m_waferDie);
m_ellipseItem.push_back(EllipseObj);
EllipseObj->setPen(QPen(RECT_COLOR));
EllipseObj->setPos(m_baseLineXCoordObj->pos().x() - m_recipeAttrObj.m_waferDie / 2,
m_baseLineXCoordObj->pos().y() - m_recipeAttrObj.m_waferDie / 2);
m_mappingScene.addItem(EllipseObj.get());
}
//基准die往上延伸
for (int i = 0; i < MAX_EXTEND_NUM; i++)
{
double xCoord = rectFirstPointX;
double yCoord = rectFirstPointY + i * m_recipeAttrObj.m_dieHeight;
if (yCoord < -1 * m_recipeAttrObj.m_waferDie / 2)
{
break;
}
LeftExtend(xCoord, yCoord);
bool isIncludeBaseDie = false;
i == 0 ? isIncludeBaseDie = true : isIncludeBaseDie = false;
RightExtend(xCoord, yCoord, isIncludeBaseDie);
}
//基准die往下延伸
for (int i = 1; i < MAX_EXTEND_NUM; i++)
{
double xCoord = rectFirstPointX;
double yCoord = rectFirstPointY - i * m_recipeAttrObj.m_dieHeight;
if (yCoord > m_recipeAttrObj.m_waferDie / 2)
{
break;
}
LeftExtend(xCoord, yCoord);
RightExtend(xCoord, yCoord, false);
}
//绘制区域横线,直接划分成固定区域
for (int i = 0; i < m_areaGridNum + 1; i++)
{
std::shared_ptr<QGraphicsLineItem> LineObj = std::make_shared<QGraphicsLineItem>(
-m_recipeAttrObj.m_waferDie / 2,
-m_recipeAttrObj.m_waferDie / 2 + (m_recipeAttrObj.m_waferDie / m_areaGridNum) * i,
m_recipeAttrObj.m_waferDie / 2,
-m_recipeAttrObj.m_waferDie / 2 + (m_recipeAttrObj.m_waferDie / m_areaGridNum) * i);
LineObj->setPen(QPen(AREA_LINE_COLOR));
m_allLineItem.push_back(LineObj);
m_mappingScene.addItem(LineObj.get());
}
//绘制区域竖线,直接划分成固定区域
for (int i = 0; i < m_areaGridNum + 1; i++)
{
std::shared_ptr<QGraphicsLineItem> LineObj = std::make_shared<QGraphicsLineItem>(
-m_recipeAttrObj.m_waferDie / 2 + (m_recipeAttrObj.m_waferDie / m_areaGridNum) * i,
-m_recipeAttrObj.m_waferDie / 2,
-m_recipeAttrObj.m_waferDie / 2 + (m_recipeAttrObj.m_waferDie / m_areaGridNum) * i,
m_recipeAttrObj.m_waferDie / 2);
LineObj->setPen(QPen(AREA_LINE_COLOR));
m_allLineItem.push_back(LineObj);
m_mappingScene.addItem(LineObj.get());
}
ui.graphicsView->setScene(&m_mappingScene);
if (!m_isScale)
{
ui.graphicsView->scale(m_scaleFactor, m_scaleFactor);
m_isScale = true;
}
}
void MappingUI::SetLabelHide()
{
//ui.horizontalLayout->removeWidget(ui.label);
//ui.horizontalLayout->removeWidget(ui.label_2);
ui.horizontalLayout_2->removeWidget(ui.pushButton_clearCurSelect);
ui.horizontalLayout_2->removeWidget(ui.pushButton_addCurRow);
ui.horizontalLayout_2->removeWidget(ui.pushButton_addCurRol);
ui.horizontalLayout_2->removeWidget(ui.pushButton_addCurArea);
ui.horizontalLayout_2->removeItem(ui.horizontalSpacer_2);
//ui.label->hide();
//ui.label_2->hide();
ui.pushButton_clearCurSelect->hide();
ui.pushButton_addCurRow->hide();
ui.pushButton_addCurRol->hide();
ui.pushButton_addCurArea->hide();
//ui.verticalLayout->removeItem(ui.horizontalLayout);
}
void MappingUI::SetMappingToInitStatus()
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark() || iter->Base())
{
continue;
}
iter->setBrush(Qt::NoBrush);
}
m_selectDieVec.clear();
}
void MappingUI::GetCurAreaAllDie(std::vector<std::shared_ptr<MyQGraphicsRectItem>>& outCurAreaDie)
{
outCurAreaDie.clear();
for (auto& iter : m_allDieItem)
{
if (iter->AreaIdX() == m_curAreaIdX && iter->AreaIdY() == m_curAreaIdY)
{
outCurAreaDie.push_back(iter);
}
}
}
void MappingUI::UpdateMappingArea(int areaIdX, int areaidY)
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark() || iter->Base())
{
continue;
}
if (iter->AreaIdX() == areaIdX && iter->AreaIdY() == areaidY)
{
iter->setBrush(DIE_MARK_END);
}
}
}
void MappingUI::DieMarkUIUpdateAlreadyMark()
{
for (auto& iter : m_selectDieVec)
{
if (iter->Mark() || iter->Base())
{
continue;
}
iter->setBrush(DIE_MARK_END);
}
}
void MappingUI::CommonClearSelectDie()
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark() || iter->Base())
{
continue;
}
iter->ShowTextItem(false);
//iter->ShowTextItemFunc();
if (iter->AlreadlyMarked())
{
iter->setBrush(DIE_MARK_END);
}
if (iter->brush().color() == CUR_SELECT_DIE)
{
iter->setBrush(Qt::NoBrush);
}
iter->Select(false);
}
m_selectDieVec.clear();
}
void MappingUI::LeftExtend(double firstX, double firstY)
{
for (int i = 1; i < MAX_EXTEND_NUM; i++)
{
double rectFirstX = firstX - m_recipeAttrObj.m_dieWidth * i;
double rectFirstY = firstY;
if (JudgeIsInWafer(rectFirstX, rectFirstY))
{
AddDieRect(rectFirstX, rectFirstY);
}
else
{
if (rectFirstX < -1 * m_recipeAttrObj.m_waferDie / 2)
{
break;
}
}
}
}
void MappingUI::RightExtend(double firstX, double firstY, bool isIncludeCur)
{
int startPos = 0;
isIncludeCur ? startPos = 1 : startPos = 0;
for (int i = startPos; i < MAX_EXTEND_NUM; i++)
{
double rectFirstX = firstX + m_recipeAttrObj.m_dieWidth * i;
double rectFirstY = firstY;
if (JudgeIsInWafer(rectFirstX, rectFirstY))
{
AddDieRect(rectFirstX, rectFirstY);
}
else
{
if (rectFirstX > m_recipeAttrObj.m_waferDie / 2)
{
break;
}
}
}
}
void MappingUI::AddDieRect(double xCoord, double yCoord)
{
std::shared_ptr<MyQGraphicsRectItem> rectObj = std::make_shared<MyQGraphicsRectItem>(
xCoord,
yCoord,
m_recipeAttrObj.m_dieWidth,
m_recipeAttrObj.m_dieHeight);
rectObj->ShowTextItem(m_isShowDieText);
rectObj->setPen(QPen(RECT_COLOR));
SetDieAttr(rectObj, false, false, xCoord, yCoord);
if (JudgeIsMark(rectObj))
{
rectObj->Mark(true);
rectObj->setBrush(MARK_POINT_COLOR);
}
/*if (JudgeIsMark(xCoord, yCoord))
{
SetDieAttr(rectObj, false, true, xCoord, yCoord);
rectObj->setBrush(MARK_POINT_COLOR);
}
else
{
SetDieAttr(rectObj, false, false, xCoord, yCoord);
}*/
rectObj->setPos(m_baseLineXCoordObj->pos().x() + xCoord, m_baseLineXCoordObj->pos().y() + yCoord);
m_allDieItem.push_back(rectObj);
m_mappingScene.addItem(rectObj.get());
}
void MappingUI::SetDieAttr(std::shared_ptr<MyQGraphicsRectItem>& dieObj, bool isBase, bool isMark, double xCoord, double yCoord)
{
connect(dieObj.get(), SIGNAL(signal_select(double,double)), this, SLOT(slot_UpdateAllDieStatus(double, double)));
dieObj->Base(isBase);
dieObj->Mark(isMark);
dieObj->xCoord(xCoord);
dieObj->yCoord(yCoord);
dieObj->RealDieXCoord(xCoord + m_recipeAttrObj.m_dieWidth / 2.0);
dieObj->RealDieYCoord(-1 * yCoord - m_recipeAttrObj.m_dieHeight / 2.0);
/*if (dieObj->Mark())
{
dieObj->RealDieYCoord(yCoord - m_recipeAttrObj.m_dieHeight / 2.0);
}*/
//计算die最大最小Y坐标
if (dieObj->RealDieYCoord() > m_dieMaxYcoord)
{
m_dieMaxYcoord = dieObj->RealDieYCoord();
}
if (dieObj->RealDieYCoord() < m_dieMinYccord)
{
m_dieMinYccord = dieObj->RealDieYCoord();
}
}
bool MappingUI::JudgeIsInWafer(double xCoord, double yCoord)
{
if (abs(xCoord) > (m_recipeAttrObj.m_waferDie / 2.0) || abs(yCoord) > m_recipeAttrObj.m_waferDie / 2.0)
{
return false;
}
int judgeIsOk = 0;
//矩形左上侧点
if (sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(yCoord, 2)) > abs(xCoord) &&
sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(xCoord, 2)) > abs(yCoord))
{
judgeIsOk++;
}
//矩形左下侧点
if (sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(yCoord + m_recipeAttrObj.m_dieHeight, 2)) > abs(xCoord) &&
sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(xCoord, 2)) > abs(yCoord + m_recipeAttrObj.m_dieHeight))
{
judgeIsOk++;
}
//矩形右上侧点
if (sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(yCoord, 2)) > abs(xCoord + m_recipeAttrObj.m_dieWidth) &&
sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(xCoord + m_recipeAttrObj.m_dieWidth, 2)) > abs(yCoord))
{
judgeIsOk++;
}
//矩形右下侧点
if (sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(yCoord + +m_recipeAttrObj.m_dieHeight, 2)) > abs(xCoord + m_recipeAttrObj.m_dieWidth) &&
sqrt(std::pow(m_recipeAttrObj.m_waferDie / 2, 2) - std::pow(xCoord + m_recipeAttrObj.m_dieWidth, 2)) > abs(yCoord + m_recipeAttrObj.m_dieHeight))
{
judgeIsOk++;
}
if (4 == judgeIsOk)
{
return true;
}
return false;
}
bool MappingUI::JudgeIsMark(std::shared_ptr<MyQGraphicsRectItem>& die)
{
/*if (m_recipeAttrObj.m_mark1CoordX >= xCoord && m_recipeAttrObj.m_mark1CoordX <= (xCoord + m_recipeAttrObj.m_dieWidth) &&
m_recipeAttrObj.m_mark1CoordY >= yCoord && m_recipeAttrObj.m_mark1CoordY <= (yCoord + m_recipeAttrObj.m_dieHeight))
{
return true;
}
if (m_recipeAttrObj.m_mark2CoordX >= xCoord && m_recipeAttrObj.m_mark2CoordX <= (xCoord + m_recipeAttrObj.m_dieWidth) &&
m_recipeAttrObj.m_mark2CoordY >= yCoord && m_recipeAttrObj.m_mark2CoordY <= (yCoord + m_recipeAttrObj.m_dieHeight))
{
return true;
}*/
if (abs(m_recipeAttrObj.m_mark1CoordX - die->RealDieXCoord()) <= m_recipeAttrObj.m_dieWidth / 2.0 &&
abs(m_recipeAttrObj.m_mark1CoordY - die->RealDieYCoord()) <= m_recipeAttrObj.m_dieHeight / 2.0)
{
return true;
}
if (abs(m_recipeAttrObj.m_mark2CoordX - die->RealDieXCoord()) <= m_recipeAttrObj.m_dieWidth / 2.0 &&
abs(m_recipeAttrObj.m_mark2CoordY - die->RealDieYCoord()) <= m_recipeAttrObj.m_dieHeight / 2.0)
{
return true;
}
return false;
}
void MappingUI::CountAreaData()
{
//根据晶圆尺寸,12寸(300mm)分为10个区域,8寸(200mm)分为8个区域,6寸(150mm)分为5个区域
if (abs(m_recipeAttrObj.m_waferDie - 300) < 20)
{
m_areaGridNum = 10;
}
if (abs(m_recipeAttrObj.m_waferDie - 200) < 20)
{
m_areaGridNum = 8;
}
if (abs(m_recipeAttrObj.m_waferDie - 150) < 20)
{
m_areaGridNum = 5;
}
if (abs(m_recipeAttrObj.m_waferDie - 100) < 20)
{
m_areaGridNum = 4;
}
if (abs(m_recipeAttrObj.m_waferDie - 50) < 20)
{
m_areaGridNum = 2;
}
m_areaXDirDieNum = std::ceil(m_recipeAttrObj.m_waferDie / m_areaGridNum / m_recipeAttrObj.m_dieWidth);
m_areaYDirDieNum = std::ceil(m_recipeAttrObj.m_waferDie / m_areaGridNum / m_recipeAttrObj.m_dieHeight);
}
void MappingUI::ClearSceneAndVec()
{
QList<QGraphicsItem *> items = m_mappingScene.items();
foreach(QGraphicsItem *item, items) {
m_mappingScene.removeItem(item);
//delete item; // 如果需要,可以删除项以释放内存
}
m_allDieItem.clear();
m_ellipseItem.clear();
m_allLineItem.clear();
m_curDie = nullptr;
m_dieMaxYcoord = 0.0;
m_dieMinYccord = 0.0;
}
void MappingUI::AddSelectDie(std::shared_ptr<MyQGraphicsRectItem>& selectDie)
{
if (m_selectDieVec.size() < 1)
{
m_selectDieVec.push_back(selectDie);
}
bool isUnique = false;
for (auto& iter : m_selectDieVec)
{
if (abs(iter->RealDieXCoord() - selectDie->RealDieXCoord()) <= JUDGE_DECIMAL &&
abs(iter->RealDieYCoord() - selectDie->RealDieYCoord()) <= JUDGE_DECIMAL)
{
isUnique = true;
}
}
if (!isUnique)
{
m_selectDieVec.push_back(selectDie);
}
}
void MappingUI::wheelEvent(QWheelEvent *event)
{
ui.graphicsView->resetMatrix();
// 滚轮向上放大,向下缩小
qDebug() << event->angleDelta().y();
if (event->angleDelta().y() > 0) {
if (m_scaleFactor < 10)
{
m_scaleFactor *= 1.05; // 放大
}
}
else
{
if (m_scaleFactor > 2)
{
m_scaleFactor /= 1.05; // 缩小
}
}
qDebug() << event->angleDelta().y()<< " "<< m_scaleFactor;
ui.graphicsView->scale(m_scaleFactor, m_scaleFactor);
}
void MappingUI::mousePressEvent(QMouseEvent *event)
{
/*if (event->button() == Qt::LeftButton)
{
for (auto& iter : m_allItem)
{
if (iter->Base() != true && iter->Mark() != true)
{
iter->setBrush(Qt::NoBrush);
}
}
}*/
}
void MappingUI::slot_UpdateAllDieStatus(double xCoord, double yCoord)
{
//iter->setBrush(Qt::NoBrush); //清除UI选中特征,先备注在这儿
for (auto& iter : m_allDieItem)
{
if (abs(xCoord - iter->RealDieXCoord()) <= JUDGE_DECIMAL &&
abs(yCoord - iter->RealDieYCoord()) <= JUDGE_DECIMAL)
{
AddSelectDie(iter);
//UI显示die相关信息
m_curDieCoordX = xCoord;
m_curDieCoordY = yCoord;
m_curAreaIdX = iter->AreaIdX();
m_curAreaIdY = iter->AreaIdY();
m_curDie = iter;
QString str = QString::fromLocal8Bit("X坐标:") + QString::number(xCoord) +
QString::fromLocal8Bit(", Y坐标:") + QString::number(yCoord) +
QString::fromLocal8Bit(", 区域ID->X:") + QString::number(iter->AreaIdX()) +
QString::fromLocal8Bit(", 区域ID->Y:") + QString::number(iter->AreaIdY()) +
QString::fromLocal8Bit(", 序列号:") + iter->SerialNum();
ui.label->setText(str);
if (!iter->Select())
{
m_selectDieVec.erase(
std::remove_if(m_selectDieVec.begin(), m_selectDieVec.end(), [xCoord, yCoord](std::shared_ptr<MyQGraphicsRectItem> obj) {
return abs(xCoord - obj->RealDieXCoord()) <= JUDGE_DECIMAL &&
abs(yCoord - obj->RealDieYCoord()) <= JUDGE_DECIMAL;
}),
m_selectDieVec.end()
);
}
}
}
int i = 0;
}
void MappingUI::slot_clearCurSelect()
{
CommonClearSelectDie();
QMessageBox::StandardButton button = QMessageBox::information(
nullptr,
QString::fromLocal8Bit("提示"),
QString::fromLocal8Bit("清除选中die成功"),
QMessageBox::Yes,
QMessageBox::NoButton);
}
void MappingUI::slot_addCurRow()
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark())
{
continue;
}
if (iter->RealDieYCoord() == m_curDieCoordY)
{
iter->Select(true);
iter->setBrush(CUR_SELECT_DIE);
AddSelectDie(iter);
}
}
}
void MappingUI::slot_addCurRol()
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark())
{
continue;
}
if (iter->RealDieXCoord() == m_curDieCoordX)
{
iter->Select(true);
iter->setBrush(CUR_SELECT_DIE);
m_selectDieVec.push_back(iter);
}
}
}
void MappingUI::slot_addCurArea()
{
for (auto& iter : m_allDieItem)
{
if (iter->Mark())
{
continue;
}
if (iter->AreaIdX() == m_curAreaIdX && iter->AreaIdY() == m_curAreaIdY)
{
iter->Select(true);
iter->setBrush(CUR_SELECT_DIE);
AddSelectDie(iter);
}
}
}