#include "Bond.h" #include #include #include #include #include Bond::Bond(QWidget* parent) : QWidget(parent) { } void Bond::UpdataGenerateTestData() { // 生成测试数据:2x2 PCB,每个PCB 2x2 PT矩阵,每个PT矩阵 2x3固晶点 int pcbIndex = 0; int dieIndex = 0; std::srand(std::time(nullptr)); for (int pcbRow = 0; pcbRow < 2; ++pcbRow) { for (int pcbCol = 0; pcbCol < 2; ++pcbCol) { int iPcbMatId = ++pcbIndex; pcbDimensions[iPcbMatId] = qMakePair(2, 2); // PCB包含2x2 PT矩阵 int ptIndex = 0; for (int ptRow = 0; ptRow < 2; ++ptRow) { for (int ptCol = 0; ptCol < 2; ++ptCol) { int iPtMatId = ++ptIndex; ptDimensions[iPcbMatId][iPtMatId] = qMakePair(2, 3); // PT矩阵包含2x3固晶点 for (int dieRow = 0; dieRow < 2; ++dieRow) { for (int dieCol = 0; dieCol < 3; ++dieCol) { ns_mat::POINT_INFO_STRUCT point; point.stIndex.iPcbMatId = iPcbMatId; point.stIndex.iPtMatId = iPtMatId; point.stIndex.iPcbRow = pcbRow; point.stIndex.iPcbCol = pcbCol; point.stIndex.iPtRow = dieRow; point.stIndex.iPtCol = dieCol; point.stIndex.iIndex = ++dieIndex; point.stBondStatus.bDieStatus = static_cast(std::rand() % 7); bondData.append(point); } } } } } } } /* void Bond::initFrom(QWidget* parent) { m_pScene = new QGraphicsScene(parent); m_pView = new BondGraphicsView(m_pScene); int width = parent->width(); int height = parent->height(); // Step 1: 收集PCB全局布局信息 QMap, int> pcbPosMap; QSet uniquePcbIds; foreach(const ns_mat::POINT_INFO_STRUCT & point, bondData) { QPair pos(point.stIndex.iPcbRow, point.stIndex.iPcbCol); if (!pcbPosMap.contains(pos)) { pcbPosMap[pos] = point.stIndex.iPcbMatId; } uniquePcbIds.insert(point.stIndex.iPcbMatId); } // 计算PCB全局行列数 int maxPcbRow = 0, maxPcbCol = 0; for (const QPair& pos : pcbPosMap.keys()) { maxPcbRow = qMax(maxPcbRow, pos.first); maxPcbCol = qMax(maxPcbCol, pos.second); } int pcbRows = maxPcbRow + 1; int pcbCols = maxPcbCol + 1; // Step 2: 计算PCB布局参数 qreal margin = width / maxPcbCol * 0.05; qreal pcbSpacing = margin; int fontSize = qMax(static_cast(margin), 1); QFont font; font.setPointSize(fontSize); qreal totalWidth = width - 2 * margin; qreal totalHeight = height - 2 * margin; qreal pcbWidth = (totalWidth - (pcbCols - 1) * pcbSpacing) / pcbCols; qreal pcbHeight = (totalHeight - (pcbRows - 1) * pcbSpacing) / pcbRows; // Step 3: 预处理数据分组 QMap>> groupedData; foreach(const ns_mat::POINT_INFO_STRUCT & point, bondData) { groupedData[point.stIndex.iPcbMatId][point.stIndex.iPtMatId].append(point); } // 绘制PCB并记录位置 QMap pcbRects; for (int row = 0; row < pcbRows; ++row) { for (int col = 0; col < pcbCols; ++col) { QPair pos(row, col); if (pcbPosMap.contains(pos)) { int pcbId = pcbPosMap[pos]; QRectF rect( margin + col * (pcbWidth + pcbSpacing), margin + row * (pcbHeight + pcbSpacing), pcbWidth, pcbHeight ); pcbRects[pcbId] = rect; // 绘制PCB背景 QGraphicsRectItem* pcbItem = new QGraphicsRectItem(rect); pcbItem->setBrush(QColor("#e1d4e6")); m_pScene->addItem(pcbItem); // 添加PCB标签 QGraphicsTextItem* text = new QGraphicsTextItem(QString(tr("PCB%1")).arg(pcbId)); text->setFont(font); qreal fixedHeight = qMin(pcbWidth / std::ceil(static_cast(groupedData[pcbId].keys().size()) / std::ceil(std::sqrt(groupedData[pcbId].keys().size()))) * 0.1 , pcbHeight / std::ceil(std::sqrt(groupedData[pcbId].keys().size())) * 0.1); qreal actualHeight = text->boundingRect().height(); if (actualHeight > 0) { qreal scaleFactor = fixedHeight / actualHeight; text->setScale(scaleFactor); } text->setPos(rect.x(), rect.y()); m_pScene->addItem(text); } } } // Step 4: 绘制PT矩阵和固晶点 foreach(int pcbId, uniquePcbIds) { QRectF pcbRect = pcbRects.value(pcbId); if (!pcbRect.isValid()) continue; // 获取当前PCB的所有PT矩阵 QList ptMatIds = groupedData[pcbId].keys(); int ptMatCount = ptMatIds.size(); if (ptMatCount == 0) continue; // 计算PT矩阵布局行列数(方形布局) int ptRows = std::ceil(std::sqrt(ptMatCount)); int ptCols = std::ceil(static_cast(ptMatCount) / ptRows); while (ptRows * ptCols < ptMatCount) ptCols++; qreal ptMargin = qMin(pcbWidth / ptCols * 0.1, pcbHeight / ptRows * 0.1); int fontSize_1 = qMax(static_cast(ptMargin), 1); QFont font_1; font_1.setPointSize(fontSize_1); // 计算PT矩阵尺寸 qreal ptWidth = (pcbRect.width() - (ptCols + 1) * ptMargin) / ptCols; qreal ptHeight = (pcbRect.height() - (ptRows + 1) * ptMargin) / ptRows; // 绘制每个PT矩阵 for (int i = 0; i < ptMatIds.size(); ++i) { int ptId = ptMatIds[i]; int row = i / ptCols; int col = i % ptCols; QRectF ptRect( pcbRect.x() + col * (ptWidth + ptMargin) + ptMargin, pcbRect.y() + row * (ptHeight + ptMargin) + ptMargin, ptWidth, ptHeight ); // 绘制PT矩阵背景 QGraphicsRectItem* ptItem = new QGraphicsRectItem(ptRect); ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(ptItem); // 添加PT矩阵标签 QGraphicsTextItem* ptText = new QGraphicsTextItem(QString(tr("PT矩阵%1")).arg(ptId)); ptText->setFont(font_1); qreal fixedHeight_1 = qMin(ptWidth / ptDimensions[pcbId][ptId].second * 0.3, ptHeight / ptDimensions[pcbId][ptId].first * 0.3); qreal actualHeight_1 = ptText->boundingRect().height(); if (actualHeight_1 > 0) { qreal scaleFactor_1 = fixedHeight_1 / actualHeight_1; ptText->setScale(scaleFactor_1); } ptText->setPos(ptRect.x(), ptRect.y()); m_pScene->addItem(ptText); // Step 5: 绘制固晶点 QList points = groupedData[pcbId][ptId]; if (points.isEmpty()) continue; // 获取固晶点矩阵尺寸 QPair dieDims = ptDimensions[pcbId][ptId]; int dieRows = dieDims.first; int dieCols = dieDims.second; qreal dieMargin = qMin(ptWidth / dieCols * 0.3, ptHeight / dieRows * 0.3); // 计算固晶点尺寸 qreal dieWidth = (ptRect.width() - (dieCols + 1) * dieMargin) / dieCols; qreal dieHeight = (ptRect.height() - (dieRows + 1) * dieMargin) / dieRows; int fontSize_2 = qMax(static_cast(qMin(dieWidth, dieHeight) * 0.2), 1); QFont font_2; font_2.setPointSize(fontSize_2); foreach(const ns_mat::POINT_INFO_STRUCT & point, points) { // 计算固晶点位置 QRectF dieRect( ptRect.x() + point.stIndex.iPtCol * (dieWidth + dieMargin) + dieMargin, ptRect.y() + point.stIndex.iPtRow * (dieHeight + dieMargin) + dieMargin, dieWidth, dieHeight ); // 绘制固晶点 BondItem* dieItem = new BondItem(point); dieItem->setRect(dieRect); m_pScene->addItem(dieItem); // 添加固晶点编号 QGraphicsTextItem* dieText = new QGraphicsTextItem(dieItem); dieText->setPlainText("PT" + QString::number(point.stIndex.iIndex)); dieText->setFont(font_2); dieText->setPos(dieRect.center() - QPointF(dieText->boundingRect().width() / 2, dieText->boundingRect().height() / 2)); } } } m_pView->setScene(m_pScene); m_pView->resize(width, height); } */ void Bond::initFrom(QWidget* parent) { m_pScene = new QGraphicsScene(parent); m_pView = new BondGraphicsView(m_pScene); m_pView->setCViewInterface(m_pCViewInterface); int width = parent->width(); int height = parent->height(); double maxWidth = maxPoint.x() - minPoint.x(); double maxHeight = maxPoint.y() - minPoint.y(); double ratio; if (maxHeight > maxWidth) { ratio = maxHeight / (width - 100); } else { ratio = maxWidth / (width - 100); } //目前没提供pt固晶点大小,以下用测试大小,后续可替换(实际大小,接口替换处) double dieWidth = 20000; double dieHeight = 20000; QFont matrixFont; double matrixFontSize = qMin(dieWidth/ratio, dieHeight / ratio)*0.1; matrixFont.setPointSizeF(matrixFontSize); // 使用浮点大小 for (int i = 0; i < bondData.size(); ++i) { // 绘制固晶点 //转换大小 double dieWidthr = dieWidth / ratio; double dieHeightr = dieHeight / ratio; double diex, diey; diex = (bondData[i].stBondStatus.stAlnBondPosition.x - minPoint.x() + dieWidth) / ratio; diey = (bondData[i].stBondStatus.stAlnBondPosition.y - minPoint.y() + dieHeight) / ratio; // 计算固晶点位置 QRectF dieRect( diex, diey, dieWidthr, dieHeightr ); BondItem* dieItem = new BondItem(bondData[i]); dieItem->setRect(dieRect); dieItem->setZValue(1.0); m_pScene->addItem(dieItem); // 添加固晶点编号 QGraphicsTextItem* dieText = new QGraphicsTextItem(dieItem); dieText->setPlainText("PT" + QString::number(bondData[i].stIndex.iIndex)); double dieFontSize = qMin(dieWidthr, dieHeightr) * 0.2; QFont font; font.setPointSizeF(dieFontSize); // 使用浮点大小 dieText->setFont(font); dieText->setPos(dieRect.center() - QPointF(dieText->boundingRect().width() / 2, dieText->boundingRect().height() / 2)); } /* //绘制pt矩阵和Pcb矩阵 for (auto outerIt = m_pcbMaxPointmap.begin(); outerIt != m_pcbMaxPointmap.end(); ++outerIt) { int outerKey = outerIt.key(); // 外层 key const QMap& innerMap = outerIt.value(); qDebug() << "Outer Key:" << outerKey; for (auto innerIt = innerMap.begin(); innerIt != innerMap.end(); ++innerIt) { int innerKey = innerIt.key(); // 内层 key const QPointF& maxPtPoint = innerIt.value(); const QPointF& minPtPoint = m_pcbMinPointmap.value(outerKey).value(innerKey); qDebug() << " Inner Key:" << innerKey; } } */ QPen ptpen(Qt::blue, 0.5); QPen pcbpen(Qt::red, 0.5); QPen subpen(Qt::black, 0.5); //绘制pt矩阵和Pcb矩阵 POINT_INFO_STRUCT maxPcbPoint = m_vptMaxPoints[0]; POINT_INFO_STRUCT minPcbPoint = m_vptMaxPoints[0]; int pcbmatx, pcbmaty, pcbmatWidth, pcbmatHeight; QVector maxSubPoints; QVector minSubPoints; for (int i = 0;i < m_vptMaxPoints.size();i++) { if (minPcbPoint.stIndex.iPcbRow != m_vptMinPoints[i].stIndex.iPcbRow || minPcbPoint.stIndex.iPcbCol != m_vptMinPoints[i].stIndex.iPcbCol) { //绘制pcb矩阵 pcbmatx = (minPcbPoint.stBondStatus.stAlnBondPosition.x - minPoint.x() + 0.4 * dieWidth) / ratio; pcbmaty = (minPcbPoint.stBondStatus.stAlnBondPosition.y - minPoint.y() + 0.4 * dieHeight) / ratio; pcbmatWidth = (maxPcbPoint.stBondStatus.stAlnBondPosition.x - minPcbPoint.stBondStatus.stAlnBondPosition.x + dieWidth * 2.2) / ratio; pcbmatHeight = (maxPcbPoint.stBondStatus.stAlnBondPosition.y - minPcbPoint.stBondStatus.stAlnBondPosition.y + dieHeight * 2.2) / ratio; QRectF pcbRect( pcbmatx, pcbmaty, pcbmatWidth, pcbmatHeight ); // 绘制PCB矩阵背景 QGraphicsRectItem* pcbItem = new QGraphicsRectItem(pcbRect); pcbItem->setPen(pcbpen); //ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(pcbItem); // 添加PCB标签 QRectF pcbTextRect( pcbmatx, pcbmaty, dieWidth / ratio * 0.6, dieHeight / ratio * 0.2 ); QGraphicsRectItem* pcbTextItem = new QGraphicsRectItem(pcbTextRect); pcbTextItem->setPen(Qt::NoPen); m_pScene->addItem(pcbTextItem); QGraphicsTextItem* pcbText = new QGraphicsTextItem(pcbTextItem); pcbText->setPlainText(QString(QString(tr("Pcb%1*%2")).arg(minPcbPoint.stIndex.iPcbRow).arg(minPcbPoint.stIndex.iPcbCol))); pcbText->setFont(matrixFont); // 将文本居中于 pcbTextRect pcbText->setPos(pcbTextRect.center() - QPointF(pcbText->boundingRect().width() / 2, pcbText->boundingRect().height() / 2)); pcbText->setFont(matrixFont); maxSubPoints.append(maxPcbPoint); minSubPoints.append(minPcbPoint); maxPcbPoint = m_vptMaxPoints[i]; minPcbPoint = m_vptMinPoints[i]; } else { if (m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.x > maxPcbPoint.stBondStatus.stAlnBondPosition.x) maxPcbPoint = m_vptMaxPoints[i]; if (m_vptMinPoints[i].stBondStatus.stAlnBondPosition.x < minPcbPoint.stBondStatus.stAlnBondPosition.x) minPcbPoint = m_vptMinPoints[i]; if (m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.y > maxPcbPoint.stBondStatus.stAlnBondPosition.y) maxPcbPoint = m_vptMaxPoints[i]; if (m_vptMinPoints[i].stBondStatus.stAlnBondPosition.y < minPcbPoint.stBondStatus.stAlnBondPosition.y) minPcbPoint = m_vptMinPoints[i]; } int ptmatx, ptmaty, ptmatWidth, ptmatHeight; ptmatx = (m_vptMinPoints[i].stBondStatus.stAlnBondPosition.x - minPoint.x() + 0.7 * dieWidth) / ratio ; ptmaty = (m_vptMinPoints[i].stBondStatus.stAlnBondPosition.y - minPoint.y() + 0.7 * dieHeight) / ratio ; ptmatWidth = (m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.x - m_vptMinPoints[i].stBondStatus.stAlnBondPosition.x +dieWidth*1.6)/ratio; ptmatHeight = (m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.y - m_vptMinPoints[i].stBondStatus.stAlnBondPosition.y + dieHeight*1.6) / ratio; QRectF ptRect( ptmatx, ptmaty, ptmatWidth, ptmatHeight ); //qDebug() << m_vptMinPoints[i].stBondStatus.stAlnBondPosition.x << " " << m_vptMinPoints[i].stBondStatus.stAlnBondPosition.y; //qDebug() << m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.x << " " << m_vptMaxPoints[i].stBondStatus.stAlnBondPosition.y; // 绘制PT矩阵背景 QGraphicsRectItem* ptItem = new QGraphicsRectItem(ptRect); ptItem->setPen(ptpen); //ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(ptItem); // 添加PT矩阵标签 QRectF ptTextRect( ptmatx, ptmaty, dieWidth/ratio* 0.6, dieHeight / ratio * 0.2 ); QGraphicsRectItem* ptTextItem = new QGraphicsRectItem(ptTextRect); ptTextItem->setPen(Qt::NoPen); m_pScene->addItem(ptTextItem); QGraphicsTextItem* ptText = new QGraphicsTextItem(ptTextItem); ptText->setPlainText(QString(tr("PtMat%1")).arg(m_vptMinPoints[i].stIndex.iPtMatId)); ptText->setFont(matrixFont); // 将文本居中于 ptTextRect ptText->setPos(ptTextRect.center()- QPointF(ptText->boundingRect().width() / 2, ptText->boundingRect().height() / 2)); } pcbmatx = (minPcbPoint.stBondStatus.stAlnBondPosition.x - minPoint.x() + 0.4 * dieWidth) / ratio; pcbmaty = (minPcbPoint.stBondStatus.stAlnBondPosition.y - minPoint.y() + 0.4 * dieHeight) / ratio; pcbmatWidth = (maxPcbPoint.stBondStatus.stAlnBondPosition.x - minPcbPoint.stBondStatus.stAlnBondPosition.x + dieWidth * 2.2) / ratio; pcbmatHeight = (maxPcbPoint.stBondStatus.stAlnBondPosition.y - minPcbPoint.stBondStatus.stAlnBondPosition.y + dieHeight * 2.2) / ratio; QRectF pcbRect( pcbmatx, pcbmaty, pcbmatWidth, pcbmatHeight ); // 绘制PCB矩阵背景 QGraphicsRectItem* pcbItem = new QGraphicsRectItem(pcbRect); pcbItem->setPen(pcbpen); //ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(pcbItem); // 添加PCB标签 QRectF pcbTextRect( pcbmatx, pcbmaty, dieWidth / ratio * 0.6, dieHeight / ratio * 0.2 ); QGraphicsRectItem* pcbTextItem = new QGraphicsRectItem(pcbTextRect); pcbTextItem->setPen(Qt::NoPen); m_pScene->addItem(pcbTextItem); QGraphicsTextItem* pcbText = new QGraphicsTextItem(pcbTextItem); pcbText->setPlainText(QString(QString(tr("Pcb%1*%2")).arg(minPcbPoint.stIndex.iPcbRow).arg(minPcbPoint.stIndex.iPcbCol))); pcbText->setFont(matrixFont); // 将文本居中于 pcbTextRect pcbText->setPos(pcbTextRect.center() - QPointF(pcbText->boundingRect().width() / 2, pcbText->boundingRect().height() / 2)); pcbText->setFont(matrixFont); //绘制sub矩阵 maxSubPoints.append(maxPcbPoint); minSubPoints.append(minPcbPoint); POINT_INFO_STRUCT maxSubPoint = maxSubPoints[0]; POINT_INFO_STRUCT minSubPoint = minSubPoints[0]; int submatx, submaty, submatWidth, submatHeight; for (int i = 0;i < maxSubPoints.size();i++) { if (maxSubPoint.stIndex.iPcbMatId != maxSubPoints[i].stIndex.iPcbMatId) { submatx = (minSubPoint.stBondStatus.stAlnBondPosition.x - minPoint.x() + 0.1 * dieWidth) / ratio; submaty = (minSubPoint.stBondStatus.stAlnBondPosition.y - minPoint.y() + 0.1 * dieHeight) / ratio; submatWidth = (maxSubPoint.stBondStatus.stAlnBondPosition.x - minSubPoint.stBondStatus.stAlnBondPosition.x + dieWidth * 2.8) / ratio; submatHeight = (maxSubPoint.stBondStatus.stAlnBondPosition.y - minSubPoint.stBondStatus.stAlnBondPosition.y + dieHeight * 2.8) / ratio; QRectF subRect( submatx, submaty, submatWidth, submatHeight ); // 绘制SUB矩阵背景 QGraphicsRectItem* subItem = new QGraphicsRectItem(subRect); subItem->setPen(subpen); //ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(subItem); // 添加PCB标签 QRectF subTextRect( submatx, submaty, dieWidth / ratio * 0.6, dieHeight / ratio * 0.2 ); QGraphicsRectItem* subTextItem = new QGraphicsRectItem(subTextRect); subTextItem->setPen(Qt::NoPen); m_pScene->addItem(subTextItem); QGraphicsTextItem* subText = new QGraphicsTextItem(subTextItem); subText->setPlainText(QString(QString(tr("Sub%1")).arg(minSubPoint.stIndex.iPcbMatId))); subText->setFont(matrixFont); // 将文本居中于 pcbTextRect subText->setPos(subTextRect.center() - QPointF(subText->boundingRect().width() / 2, subText->boundingRect().height() / 2)); subText->setFont(matrixFont); } else { if (maxSubPoints[i].stBondStatus.stAlnBondPosition.x > maxSubPoint.stBondStatus.stAlnBondPosition.x) maxSubPoint = maxSubPoints[i]; if (minSubPoints[i].stBondStatus.stAlnBondPosition.x < minSubPoint.stBondStatus.stAlnBondPosition.x) minPcbPoint = minSubPoints[i]; if (maxSubPoints[i].stBondStatus.stAlnBondPosition.y > maxSubPoint.stBondStatus.stAlnBondPosition.y) maxSubPoint = maxSubPoints[i]; if (minSubPoints[i].stBondStatus.stAlnBondPosition.y < minSubPoint.stBondStatus.stAlnBondPosition.y) minSubPoint = minSubPoints[i]; } } submatx = (minSubPoint.stBondStatus.stAlnBondPosition.x - minPoint.x() + 0.1 * dieWidth) / ratio; submaty = (minSubPoint.stBondStatus.stAlnBondPosition.y - minPoint.y() + 0.1 * dieHeight) / ratio; submatWidth = (maxSubPoint.stBondStatus.stAlnBondPosition.x - minSubPoint.stBondStatus.stAlnBondPosition.x + dieWidth * 2.8) / ratio; submatHeight = (maxSubPoint.stBondStatus.stAlnBondPosition.y - minSubPoint.stBondStatus.stAlnBondPosition.y + dieHeight * 2.8) / ratio; QRectF subRect( submatx, submaty, submatWidth, submatHeight ); QGraphicsRectItem* subItem = new QGraphicsRectItem(subRect); // 设置边框颜色为红色,线宽为2 subItem->setPen(subpen); // 绘制SUB矩阵背景 //ptItem->setBrush(QColor("#d5e4f8")); m_pScene->addItem(subItem); // 添加PCB标签 QRectF subTextRect( submatx, submaty, dieWidth / ratio * 0.6, dieHeight / ratio * 0.2 ); QGraphicsRectItem* subTextItem = new QGraphicsRectItem(subTextRect); subTextItem->setPen(Qt::NoPen); m_pScene->addItem(subTextItem); QGraphicsTextItem* subText = new QGraphicsTextItem(subTextItem); subText->setPlainText(QString(QString(tr("Sub%1")).arg(minSubPoint.stIndex.iPcbMatId))); subText->setFont(matrixFont); // 将文本居中于 pcbTextRect subText->setPos(subTextRect.center() - QPointF(subText->boundingRect().width() / 2, subText->boundingRect().height() / 2)); subText->setFont(matrixFont); m_pView->setScene(m_pScene); m_pView->resize(width, height); // 创建一个 QPixmap 对象用于保存绘制的图像 globalPixmap = QPixmap(width, height); globalPixmap.fill(Qt::white); // 填充背景色为白色 QPixmap originalPixmap = QPixmap::grabWidget(m_pView); // 设置目标尺寸(例如:宽度 200,高度 150) QSize targetSize(width, height); // 不保持比例,直接拉伸到指定尺寸 QPixmap scaledPixmap = originalPixmap.scaled( targetSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); globalPixmap = scaledPixmap; } void Bond::paintInitFrom(QWidget* parent) { /* int width = parent->width(); int height = parent->height(); globalPixmap = QPixmap(width, height); globalPixmap.fill(Qt::white); QPainter painter(&globalPixmap); painter.setRenderHint(QPainter::Antialiasing); QFont baseFont = painter.font(); // Step 1: 收集PCB全局布局信息 QMap, int> pcbPosMap; QSet uniquePcbIds; foreach(const ns_mat::POINT_INFO_STRUCT & point, bondData) { QPair pos(point.stIndex.iPcbRow, point.stIndex.iPcbCol); if (!pcbPosMap.contains(pos)) { pcbPosMap[pos] = point.stIndex.iPcbMatId; } uniquePcbIds.insert(point.stIndex.iPcbMatId); } // 计算PCB全局行列数 int maxPcbRow = 0, maxPcbCol = 0; for (const QPair& pos : pcbPosMap.keys()) { maxPcbRow = qMax(maxPcbRow, pos.first); maxPcbCol = qMax(maxPcbCol, pos.second); } int pcbRows = maxPcbRow + 1; int pcbCols = maxPcbCol + 1; //TODO:yang maxPcbCol = 1; // Step 2: 计算PCB布局参数 qreal margin = width / maxPcbCol * 0.05; qreal pcbSpacing = margin; qreal totalWidth = width - 2 * margin; qreal totalHeight = height - 2 * margin; qreal pcbWidth = (totalWidth - (pcbCols - 1) * pcbSpacing) / pcbCols; qreal pcbHeight = (totalHeight - (pcbRows - 1) * pcbSpacing) / pcbRows; // Step 3: 预处理数据分组 QMap>> groupedData; foreach(const ns_mat::POINT_INFO_STRUCT & point, bondData) { groupedData[point.stIndex.iPcbMatId][point.stIndex.iPtMatId].append(point); } // 绘制PCB并记录位置 QMap pcbRects; for (int row = 0; row < pcbRows; ++row) { for (int col = 0; col < pcbCols; ++col) { QPair pos(row, col); if (pcbPosMap.contains(pos)) { int pcbId = pcbPosMap[pos]; QRectF rect( margin + col * (pcbWidth + pcbSpacing), margin + row * (pcbHeight + pcbSpacing), pcbWidth, pcbHeight ); pcbRects[pcbId] = rect; // 绘制PCB背景 painter.setPen(Qt::NoPen); painter.setBrush(QColor("#e1d4e6")); painter.drawRect(rect); } } } // Step 4: 绘制PT矩阵和固晶点 foreach(int pcbId, uniquePcbIds) { QRectF pcbRect = pcbRects.value(pcbId); if (!pcbRect.isValid()) continue; // 获取当前PCB的所有PT矩阵 QList ptMatIds = groupedData[pcbId].keys(); int ptMatCount = ptMatIds.size(); if (ptMatCount == 0) continue; // 计算PT矩阵布局行列数(方形布局) int ptRows = std::ceil(std::sqrt(ptMatCount)); int ptCols = std::ceil(static_cast(ptMatCount) / ptRows); while (ptRows * ptCols < ptMatCount) ptCols++; qreal ptMargin = qMin(pcbWidth / ptCols * 0.1, pcbHeight / ptRows * 0.1); // 计算PT矩阵尺寸 qreal ptWidth = (pcbRect.width() - (ptCols + 1) * ptMargin) / ptCols; qreal ptHeight = (pcbRect.height() - (ptRows + 1) * ptMargin) / ptRows; // 绘制每个PT矩阵 for (int i = 0; i < ptMatIds.size(); ++i) { int ptId = ptMatIds[i]; int row = i / ptCols; int col = i % ptCols; QRectF ptRect( pcbRect.x() + col * (ptWidth + ptMargin) + ptMargin, pcbRect.y() + row * (ptHeight + ptMargin) + ptMargin, ptWidth, ptHeight ); // 绘制PT矩阵背景 painter.setPen(Qt::NoPen); painter.setBrush(QColor("#d5e4f8")); painter.drawRect(ptRect); // Step 5: 绘制固晶点 QList points = groupedData[pcbId][ptId]; if (points.isEmpty()) continue; // 获取固晶点矩阵尺寸 QPair dieDims = ptDimensions[pcbId][ptId]; int dieRows = dieDims.first; int dieCols = dieDims.second; qreal dieMargin = qMin(ptWidth / dieCols * 0.3, ptHeight / dieRows * 0.3); // 计算固晶点尺寸 qreal dieWidth = (ptRect.width() - (dieCols + 1) * dieMargin) / dieCols; qreal dieHeight = (ptRect.height() - (dieRows + 1) * dieMargin) / dieRows; foreach(const ns_mat::POINT_INFO_STRUCT & point, points) { // 计算固晶点位置 QRectF dieRect( ptRect.x() + point.stIndex.iPtCol * (dieWidth + dieMargin) + dieMargin, ptRect.y() + point.stIndex.iPtRow * (dieHeight + dieMargin) + dieMargin, dieWidth, dieHeight ); // 绘制固晶点 painter.setPen(Qt::NoPen); //painter.setBrush(getColorByStatus(point.stBondStatus.bDieStatus)); painter.drawRect(dieRect); } } } painter.end(); */ } void Bond::UpdataVal(std::vector& stPointInfo) { maxPoint = QPointF(stPointInfo[0].stBondStatus.stAlnBondPosition.x, stPointInfo[0].stBondStatus.stAlnBondPosition.y); minPoint = QPointF(stPointInfo[0].stBondStatus.stAlnBondPosition.x, stPointInfo[0].stBondStatus.stAlnBondPosition.y); QVector ptMatrix; QMap>> pcbMatrix; UINT iPcbMatId = stPointInfo[0].stIndex.iPcbMatId; UINT iPtId = stPointInfo[0].stIndex.iPtMatId; POINT_INFO_STRUCT ptMinPoint = stPointInfo[0]; POINT_INFO_STRUCT ptMaxPoint = stPointInfo[0]; QMap ptMinPointmap; QMap ptMaxPointmap; QMap> pcbMinPointmap; QMap> pcbMaxPointmap; int pcbRow = stPointInfo[0].stIndex.iPcbRow; int pcbCol = stPointInfo[0].stIndex.iPcbCol; int pcbId = 1; for (auto&a: stPointInfo) { bondData.append(a); if (a.stIndex.iPtMatId == iPtId) { ptMatrix.append(a); } else { m_vptMaxPoints.append(ptMaxPoint); m_vptMinPoints.append(ptMinPoint); iPtId = a.stIndex.iPtMatId; ptMaxPoint = a; ptMinPoint = a; } //遍历找到最小和最大边界点 if (a.stBondStatus.stAlnBondPosition.x > maxPoint.x()) maxPoint.setX(a.stBondStatus.stAlnBondPosition.x); if(a.stBondStatus.stAlnBondPosition.x < minPoint.x()) minPoint.setX(a.stBondStatus.stAlnBondPosition.x); if (a.stBondStatus.stAlnBondPosition.y > maxPoint.y()) maxPoint.setY(a.stBondStatus.stAlnBondPosition.y); if (a.stBondStatus.stAlnBondPosition.y < minPoint.y()) minPoint.setY(a.stBondStatus.stAlnBondPosition.y); //判断pt最小和最大对角点 if (a.stBondStatus.stAlnBondPosition.x > ptMaxPoint.stBondStatus.stAlnBondPosition.x) ptMaxPoint = a; if (a.stBondStatus.stAlnBondPosition.x < ptMinPoint.stBondStatus.stAlnBondPosition.x) ptMinPoint = a; if (a.stBondStatus.stAlnBondPosition.y > ptMaxPoint.stBondStatus.stAlnBondPosition.y) ptMaxPoint = a; if (a.stBondStatus.stAlnBondPosition.y < ptMinPoint.stBondStatus.stAlnBondPosition.y) ptMinPoint = a; /* if (a.stIndex.iPcbMatId == iPcbMatId && a.stIndex.iPtMatId == iPtId && (pcbRow == a.stIndex.iPcbRow && pcbCol == a.stIndex.iPcbCol)) { ptMatrix.append(a); } else { if (a.stIndex.iPcbMatId == iPcbMatId && (pcbRow == a.stIndex.iPcbRow && pcbCol == a.stIndex.iPcbCol)) { m_pPtMatrixMap.insert(iPtId, ptMatrix); ptMatrix.clear(); ptMinPointmap.insert(iPtId, ptMinPoint); ptMaxPointmap.insert(iPtId, ptMaxPoint); ptMinPointmap.clear(); ptMaxPointmap.clear(); iPtId = a.stIndex.iPtMatId; } else { m_pPcbMatrixMap.insert(iPcbMatId, m_pPtMatrixMap); m_pcbMinPointmap.insert(iPcbMatId, ptMinPointmap); m_pcbMaxPointmap.insert(iPcbMatId, ptMaxPointmap); pcbMatrix.clear(); iPcbMatId = a.stIndex.iPcbMatId; m_pPtMatrixMap.clear(); } } */ qDebug() << a.stBondStatus.stAlnBondPosition.x << " " << a.stBondStatus.stAlnBondPosition.y; //qDebug() << a.stIndex.iPtMatId << " " << a.stIndex.iPcbMatId; } m_vptMaxPoints.append(ptMaxPoint); m_vptMinPoints.append(ptMinPoint); //m_pPtMatrixMap.insert(iPtId, ptMatrix); //m_pPcbMatrixMap.insert(iPcbMatId, m_pPtMatrixMap); //ptMinPointmap.insert(iPtId, ptMinPoint); //ptMaxPointmap.insert(iPtId, ptMaxPoint); //m_pcbMinPointmap.insert(iPcbId, ptMinPointmap); //m_pcbMaxPointmap.insert(iPcbId, ptMaxPointmap); } QPixmap Bond::getGlobalPixmap() const { return globalPixmap; } void Bond::setBondInfo(ns_module::CViewInterface* CViewInterface) { m_pCViewInterface = CViewInterface; }