Browse Source

提交遗漏

yun 1 week ago
parent
commit
17d9b20cb5

+ 390 - 0
View/die-bonder-ui/CameraMaterialGroupWnd/MaterialWindow/Bond.cpp

@@ -1 +1,391 @@
 #include "Bond.h"
+#include <QDebug>
+#include <QPair>
+#include <QSet>
+#include <QMap>
+#include <cmath>
+
+Bond::Bond(QWidget* parent) : QWidget(parent) {
+    generateTestData();
+}
+
+void Bond::generateTestData() {
+    // 生成测试数据: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) {
+                            POINT_INFO_STRUCT_1 point;
+                            point.stIndex.iPcbMatId = iPcbMatId;
+                            point.stIndex.iPtMatId = iPtMatId;
+                            point.stIndex.iRow = pcbRow;
+                            point.stIndex.iCol = pcbCol;
+                            point.stIndex.iPtRow = dieRow;
+                            point.stIndex.iPtCol = dieCol;
+                            point.stIndex.iIndex = ++dieIndex;
+                            point.stBondStatus.bDieStatus = static_cast<DIE_STATUS_1>(std::rand() % 7);
+                            bondData.append(point);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+void Bond::initFrom(QWidget* parent) {
+    scene = new QGraphicsScene(parent);
+    view = new BondGraphicsView(scene);
+
+    int width = parent->width();
+    int height = parent->height();
+
+    // Step 1: 收集PCB全局布局信息
+    QMap<QPair<int, int>, int> pcbPosMap;
+    QSet<int> uniquePcbIds;
+    foreach(const POINT_INFO_STRUCT_1 & point, bondData) {
+        QPair<int, int> pos(point.stIndex.iRow, point.stIndex.iCol);
+        if (!pcbPosMap.contains(pos)) {
+            pcbPosMap[pos] = point.stIndex.iPcbMatId;
+        }
+        uniquePcbIds.insert(point.stIndex.iPcbMatId);
+    }
+
+    // 计算PCB全局行列数
+    int maxPcbRow = 0, maxPcbCol = 0;
+    for (const QPair<int, int>& 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<int>(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<int, QMap<int, QList<POINT_INFO_STRUCT_1>>> groupedData;
+    foreach(const POINT_INFO_STRUCT_1 & point, bondData) {
+        groupedData[point.stIndex.iPcbMatId][point.stIndex.iPtMatId].append(point);
+    }
+
+    // 绘制PCB并记录位置
+    QMap<int, QRectF> pcbRects;
+    for (int row = 0; row < pcbRows; ++row) {
+        for (int col = 0; col < pcbCols; ++col) {
+            QPair<int, int> 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"));
+                scene->addItem(pcbItem);
+
+                // 添加PCB标签
+                QGraphicsTextItem* text = new QGraphicsTextItem(QString("PCB%1").arg(pcbId));
+                text->setFont(font);
+
+                qreal fixedHeight = qMin(pcbWidth / std::ceil(static_cast<qreal>(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());
+                scene->addItem(text);
+            }
+        }
+    }
+
+    // Step 4: 绘制PT矩阵和固晶点
+    foreach(int pcbId, uniquePcbIds) {
+        QRectF pcbRect = pcbRects.value(pcbId);
+        if (!pcbRect.isValid()) continue;
+
+        // 获取当前PCB的所有PT矩阵
+        QList<int> 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<qreal>(ptMatCount) / ptRows);
+        while (ptRows * ptCols < ptMatCount) ptCols++;
+
+        qreal ptMargin = qMin(pcbWidth / ptCols * 0.1, pcbHeight / ptRows * 0.1);
+        int fontSize_1 = qMax(static_cast<int>(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"));
+            scene->addItem(ptItem);
+
+            // 添加PT矩阵标签
+            QGraphicsTextItem* ptText = new QGraphicsTextItem(QString("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());
+            scene->addItem(ptText);
+
+            // Step 5: 绘制固晶点
+            QList<POINT_INFO_STRUCT_1> points = groupedData[pcbId][ptId];
+            if (points.isEmpty()) continue;
+
+            // 获取固晶点矩阵尺寸
+            QPair<int, int> 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<int>(qMin(dieWidth, dieHeight) * 0.2), 1);
+            QFont font_2;
+            font_2.setPointSize(fontSize_2);
+
+            foreach(const POINT_INFO_STRUCT_1 & 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);
+                scene->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));
+            }
+        }
+    }
+
+    view->setScene(scene);
+    view->resize(width, height);
+}
+
+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<QPair<int, int>, int> pcbPosMap;
+    QSet<int> uniquePcbIds;
+    foreach(const POINT_INFO_STRUCT_1 & point, bondData) {
+        QPair<int, int> pos(point.stIndex.iRow, point.stIndex.iCol);
+        if (!pcbPosMap.contains(pos)) {
+            pcbPosMap[pos] = point.stIndex.iPcbMatId;
+        }
+        uniquePcbIds.insert(point.stIndex.iPcbMatId);
+    }
+
+    // 计算PCB全局行列数
+    int maxPcbRow = 0, maxPcbCol = 0;
+    for (const QPair<int, int>& 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;
+    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<int, QMap<int, QList<POINT_INFO_STRUCT_1>>> groupedData;
+    foreach(const POINT_INFO_STRUCT_1 & point, bondData) {
+        groupedData[point.stIndex.iPcbMatId][point.stIndex.iPtMatId].append(point);
+    }
+
+    // 绘制PCB并记录位置
+    QMap<int, QRectF> pcbRects;
+    for (int row = 0; row < pcbRows; ++row) {
+        for (int col = 0; col < pcbCols; ++col) {
+            QPair<int, int> 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<int> 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<qreal>(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<POINT_INFO_STRUCT_1> points = groupedData[pcbId][ptId];
+            if (points.isEmpty()) continue;
+
+            // 获取固晶点矩阵尺寸
+            QPair<int, int> 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 POINT_INFO_STRUCT_1 & 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();
+}
+
+QColor Bond::getColorByStatus(DIE_STATUS_1 status) {
+    switch (status) {
+    case NO_PICK: return QColor(200, 200, 200);
+    case WAF_PICK_DONE: return QColor(100, 200, 230);
+    case TRANSFER_BOND_DONE: return QColor(255, 255, 0);
+    case TRANSFER_PICK_DONE: return QColor(255, 165, 0);
+    case LOOKUP_CALIB_DONE: return QColor(0, 150, 255);
+    case BOND_DONE: return QColor(144, 238, 144);
+    case BOND_DEL: return QColor(255, 50, 50);
+    default: return Qt::gray;
+    }
+}
+
+QPixmap Bond::getGlobalPixmap() const {
+    return globalPixmap;
+}

+ 16 - 17
View/die-bonder-ui/CameraMaterialGroupWnd/MaterialWindow/Bond.h

@@ -1,31 +1,30 @@
 #ifndef BOND_H
 #define BOND_H
-#include <QApplication>
+
 #include <QWidget>
-#include <QPainter>
-#include <QMouseEvent>
-#include <vector>
-#include <QString>
-#include <QDebug>
-#include "CInterface.h"
+#include <QGraphicsScene>
+#include <QMap>
 #include "BondGraphicsView.h"
-#include <QFrame>
-// 自定义绘制窗口类
+
 class Bond : public QWidget {
+    Q_OBJECT
 public:
-    Bond(int flag, QWidget *parent = nullptr);
-    void paintInitFrom(QWidget *parent);
+    explicit Bond(QWidget* parent = nullptr);
+    void initFrom(QWidget* parent);
+    void paintInitFrom(QWidget* parent);
     QPixmap getGlobalPixmap() const;
-    void initFrom(QWidget *parent);
+
     BondGraphicsView* view;
     QGraphicsScene* scene;
-private slots:
-    void handleLayerRightClicked(int layer);
-protected:
-    void paintEvent(QPaintEvent *event) override;
 
 private:
-    MATERIAL_BOX_STRUCT boxes; // 所有料盒的数据
+    QList<POINT_INFO_STRUCT_1> bondData;
+    QMap<int, QPair<int, int>> pcbDimensions;
+    QMap<int, QMap<int, QPair<int, int>>> ptDimensions;
     QPixmap globalPixmap;
+
+    void generateTestData();
+    QColor getColorByStatus(DIE_STATUS_1 status);
 };
+
 #endif // BOND_H