#ifdef _WIN32
#include <windows.h>
#pragma comment(lib, "Msimg32.lib")
#endif



struct CloudEntity 
{ 
    float* pVertexes = nullptr;
    unsigned int nNumOfVertexes = 0; 
    std::vector<std::pair<unsigned int*, unsigned int>> vecPrimitiveVertexIndexes; 
};
enum class ScalarLocation { PointData = 0, CellData };
class XCadLib_DLL_EXPORT XGraphCloudItem : public XGraphItem
{
public:
    XGraphCloudItem();
    XGraphCloudItem(const CloudEntity& cloudEntity);
    XGraphCloudItem(const XGraphCloudItem& other);
    virtual ~XGraphCloudItem();

    // Cloud data management
    void SetCloudData(const CloudEntity& cloudEntity);
    void ClearData();

    // 颜色相关方法
    void SetColors(ScalarLocation scalarLocation, const std::vector<QColor>& vecColors);
    void ClearColors();
    bool HasColors() const { return m_hasColors; }
    ScalarLocation GetScalarLocation() const { return m_scalarLocation; }
    const QVector<QColor>& GetColors() const { return m_colors; }

private:
    void UpdateBoundingRect();
    QPointF GetVertex2D(unsigned int index) const;
    QPolygonF GetPrimitive2D(unsigned int primitiveIndex) const;
    QColor GetPrimitiveColor(int primitiveIndex) const;
    QColor GetVertexColor(int vertexIndex) const;
    void SetColorData(ScalarLocation scalarLocation, const std::vector<QColor>& vecColors);

    private:
    QColor XGraphCloudItem::CalculateAverageColor(unsigned int* pIndexes, unsigned int nIndexCount) const;

    bool CalculateBarycentricCoordinates(const QPointF& p, const QPointF& a, 
                                        const QPointF& b, const QPointF& c,
                                        qreal& u, qreal& v, qreal& w) const;
    void DrawTriangleWithGradientSubdivision(XPainter& rPainter, const QPolygonF& triangle,
                                            const QColor& color1, const QColor& color2,
                                            const QColor& color3) const;
    void SubdivideAndDrawTriangle(XPainter& rPainter,
                                 const QPointF& p1, const QPointF& p2, const QPointF& p3,
                                 const QColor& c1, const QColor& c2, const QColor& c3,
                                 int level) const;
    QColor InterpolateColor(const QColor& c1, const QColor& c2, qreal t) const;

#ifdef _WIN32
        void DrawWithGDI(XPainter &rPainter, const QRectF &scene, const QTransform &trans) const;
        void GDIToImage(QImage *pImage, TRIVERTEX *pVertex, int nVertexCount, GRADIENT_TRIANGLE *pTriangles, int nTriangleCount) const;
#endif
private:
    CloudEntity m_oCloudEntity;             // 存储原始云图数据
    QRectF m_oBoundingRect;                 // Cached bounding rectangle
    bool m_bBoundingRectValid;              // Flag to indicate if bounding rect needs update
    
    QVector<QColor> m_verColors;              // 颜色数组
    ScalarLocation m_oScalarLocation;       // 颜色位置类型
    bool m_bHasColors;                      // 是否有颜色数据
};XGraphCloudItem::XGraphCloudItem()
    : XGraphItem()
    , m_boundingRectValid(false)
    , m_hasColors(false)
    , m_scalarLocation(ScalarLocation::PointData)
{
    m_cloudEntity.pVertexes = nullptr;
    m_cloudEntity.nNumOfVertexes = 0;
}

XGraphCloudItem::XGraphCloudItem(const CloudEntity& cloudEntity)
    : XGraphItem()
    , m_cloudEntity(cloudEntity)
    , m_boundingRectValid(false)
    , m_hasColors(false)
    , m_scalarLocation(ScalarLocation::PointData)
{
}

XGraphCloudItem::XGraphCloudItem(const XGraphCloudItem& other)
    : XGraphItem(other)
    , m_cloudEntity(other.m_cloudEntity)
    , m_boundingRect(other.m_boundingRect)
    , m_boundingRectValid(other.m_boundingRectValid)
    , m_colors(other.m_colors)
    , m_scalarLocation(other.m_scalarLocation)
    , m_hasColors(other.m_hasColors)
{
}

void XGraphCloudItem::SetCloudData(const CloudEntity& cloudEntity)
{
    m_cloudEntity = cloudEntity;
    m_boundingRectValid = false;
}

void XGraphCloudItem::ClearData()
{
    m_cloudEntity.pVertexes = nullptr;
    m_cloudEntity.nNumOfVertexes = 0;
    m_cloudEntity.vecPrimitiveVertexIndexes.clear();
    m_colors.clear();
    m_boundingRectValid = false;
    m_hasColors = false;
}

QPointF XGraphCloudItem::GetVertex2D(unsigned int index) const
{
    if (index >= m_cloudEntity.nNumOfVertexes || m_cloudEntity.pVertexes == nullptr)
    {
        return QPointF(0, 0);
    }
    
    float x = m_cloudEntity.pVertexes[index * 3];     // x coordinate
    float y = m_cloudEntity.pVertexes[index * 3 + 1]; // y coordinate
    // z coordinate is ignored for 2D
    
    return QPointF(x, y);
}

QPolygonF XGraphCloudItem::GetPrimitive2D(unsigned int primitiveIndex) const
{
    QPolygonF polygon;
    
    if (primitiveIndex >= m_cloudEntity.vecPrimitiveVertexIndexes.size())
    {
        return polygon;
    }
    
    const auto& indexPair = m_cloudEntity.vecPrimitiveVertexIndexes[primitiveIndex];
    unsigned int* pIndexes = indexPair.first;
    unsigned int nIndexCount = indexPair.second;
    
    if (nIndexCount >= 3 && pIndexes != nullptr)
    {
        polygon.reserve(nIndexCount);
        
        for (unsigned int i = 0; i < nIndexCount; ++i)
        {
            unsigned int vertexIndex = pIndexes[i];
            if (vertexIndex < m_cloudEntity.nNumOfVertexes)
            {
                polygon.append(GetVertex2D(vertexIndex));
            }
        }
    }
    
    return polygon;
}

QPointF XGraphCloudItem::GetCenter() const
{
    if (m_cloudEntity.nNumOfVertexes == 0 || m_cloudEntity.pVertexes == nullptr)
    {
        return QPointF(0, 0);
    }
    
    QPointF center(0, 0);
    for (unsigned int i = 0; i < m_cloudEntity.nNumOfVertexes; ++i)
    {
        center += GetVertex2D(i);
    }
    
    center.setX(center.x() / m_cloudEntity.nNumOfVertexes);
    center.setY(center.y() / m_cloudEntity.nNumOfVertexes);
    
    return center;
}

void XGraphCloudItem::UpdateBoundingRect()
{
    if (m_cloudEntity.nNumOfVertexes == 0 || m_cloudEntity.pVertexes == nullptr)
    {
        m_boundingRect = QRectF();
        m_boundingRectValid = true;
        return;
    }
    
    QPointF firstVertex = GetVertex2D(0);
    qreal minX = firstVertex.x();
    qreal maxX = minX;
    qreal minY = firstVertex.y();
    qreal maxY = minY;
    
    for (unsigned int i = 1; i < m_cloudEntity.nNumOfVertexes; ++i)
    {
        QPointF vertex = GetVertex2D(i);
        minX = std::min(minX, vertex.x());
        maxX = std::max(maxX, vertex.x());
        minY = std::min(minY, vertex.y());
        maxY = std::max(maxY, vertex.y());
    }
    
    m_boundingRect = QRectF(QPointF(minX, minY), QPointF(maxX, maxY));
    m_boundingRectValid = true;
}

bool XGraphCloudItem::Intersects(const QRectF& sceneRect) const
{
    if (!Bound().intersects(sceneRect))
    {
        return false;
    }
    
    // Check if any primitive intersects with the scene rect
    for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
    {
        QPolygonF primitive = GetPrimitive2D(i);
        if (primitive.size() >= 3)
        {
            QPainterPath path;
            path.addPolygon(primitive);
            if (path.intersects(sceneRect))
            {
                return true;
            }
        }
    }
    
    return false;
}

bool XGraphCloudItem::Intersects(const QPainterPath& path) const
{
    for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
    {
        QPolygonF primitive = GetPrimitive2D(i);
        if (primitive.size() >= 3)
        {
            QPainterPath primitivePath;
            primitivePath.addPolygon(primitive);
            if (primitivePath.intersects(path))
            {
                return true;
            }
        }
    }
    
    return false;
}

bool XGraphCloudItem::IntersectsEdge(const QRectF& sceneRect, QPointF& start, QPointF& end) const
{
    if (!Bound().intersects(sceneRect))
    {
        return false;
    }
    
    for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
    {
        QPolygonF primitive = GetPrimitive2D(i);
        if (primitive.size() >= 3)
        {
            if (XCadLib::IntersectsEdge(sceneRect, primitive, start, end, true))
            {
                return true;
            }
        }
    }
    
    return false;
}

bool XGraphCloudItem::IntersectsVertex(const QRectF& sceneRect, QPointF& pt) const
{
    for (unsigned int i = 0; i < m_cloudEntity.nNumOfVertexes; ++i)
    {
        QPointF vertex = GetVertex2D(i);
        if (sceneRect.contains(vertex))
        {
            pt = vertex;
            return true;
        }
    }
    
    return false;
}

bool XGraphCloudItem::EdgesEnclosedByRect(const QRectF& sceneRect, QVector<QPair<QPointF, QPointF>>& lineSegmentsSet) const
{
    bool hasEnclosedEdges = false;
    
    for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
    {
        QPolygonF primitive = GetPrimitive2D(i);
        if (primitive.size() >= 3)
        {
            if (XCadLib::EdgesEnclosedByRect(sceneRect, primitive, lineSegmentsSet))
            {
                hasEnclosedEdges = true;
            }
        }
    }
    
    return hasEnclosedEdges;
}

QPainterPath XGraphCloudItem::GetPath() const
{
    QPainterPath path;
    
    for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
    {
        QPolygonF primitive = GetPrimitive2D(i);
        if (primitive.size() >= 3)
        {
            path.addPolygon(primitive);
        }
    }
    
    return path;
}

QColor XGraphCloudItem::GetPrimitiveColor(int primitiveIndex) const
{
    if (!m_hasColors || primitiveIndex < 0 || primitiveIndex >= static_cast<int>(m_cloudEntity.vecPrimitiveVertexIndexes.size()))
    {
        return QColor(Qt::lightGray); // 默认颜色
    }
    
    if (m_scalarLocation == ScalarLocation::CellData && primitiveIndex < m_colors.size())
    {
        return m_colors[primitiveIndex];
    }
    
    return QColor(Qt::lightGray); // 默认颜色
}

QColor XGraphCloudItem::GetVertexColor(int vertexIndex) const
{
    if (!m_hasColors || vertexIndex < 0 || vertexIndex >= static_cast<int>(m_cloudEntity.nNumOfVertexes))
    {
        return QColor(Qt::lightGray); // 默认颜色
    }
    
    if (m_scalarLocation == ScalarLocation::PointData && vertexIndex < m_colors.size())
    {
        return m_colors[vertexIndex];
    }
    
    return QColor(Qt::lightGray); // 默认颜色
}

void XGraphCloudItem::SetColorData(ScalarLocation scalarLocation, const std::vector<QColor>& vecColors)
{
    m_scalarLocation = scalarLocation;
    m_colors.clear();
    
    if (scalarLocation == ScalarLocation::PointData)
    {
        if (vecColors.size() == m_cloudEntity.nNumOfVertexes)
        {
            m_colors.reserve(vecColors.size());
            for (const QColor& color : vecColors)
            {
                m_colors.append(color);
            }
            m_hasColors = true;
        }
    }
    else if (scalarLocation == ScalarLocation::CellData)
    {
        if (vecColors.size() == m_cloudEntity.vecPrimitiveVertexIndexes.size())
        {
            m_colors.reserve(vecColors.size());
            for (const QColor& color : vecColors)
            {
                m_colors.append(color);
            }
            m_hasColors = true;
        }
    }
}

void XGraphCloudItem::RenderImp(XPainter& rPainter, const QRectF& scene, const QTransform& trans, const XCadLibConfig& cfg) const
{
 auto curBound = Bound();
    if (!curBound.intersects(scene))
    {
        return;
    }
    
    auto pixelRect = trans.mapRect(curBound);
    auto pixelSize = MaxValue(pixelRect.width(), pixelRect.height());
    
    if (pixelSize < s_nMIN_DISPLAY_PIXEL)
    {
        rPainter.DrawPixel(pixelRect.center().toPoint());
    }
    else
    {
#ifdef _WIN32
        if(m_bHasColors && m_oScalarLocation == ScalarLocation::PointData)
        {
            DrawWithGDI(rPainter, scene, trans);
            return;
        }
#endif
        for (unsigned int i = 0; i < m_cloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
        {
            const auto& indexPair = m_cloudEntity.vecPrimitiveVertexIndexes[i];
            unsigned int* pIndexes = indexPair.first;
            unsigned int nIndexCount = indexPair.second;
            
            if (nIndexCount < 3 || pIndexes == nullptr)
                continue;
            
            QPolygonF primitive = GetPrimitive2D(i);
            QPolygonF transformedPrimitive = trans.map(primitive);
            
            if (m_hasColors && m_scalarLocation == ScalarLocation::CellData)
            {
                QColor primitiveColor = GetPrimitiveColor(i);
                rPainter.SetBrush(QBrush(primitiveColor));
                rPainter.DrawPolygon(transformedPrimitive);
            }
            else if (m_hasColors && m_scalarLocation == ScalarLocation::PointData)
            {
                // 对于三角形，直接绘制渐变
                if (nIndexCount == 3)
                {
                    DrawTriangleWithGradientSubdivision(rPainter, transformedPrimitive,
                                                       GetVertexColor(pIndexes[0]),
                                                       GetVertexColor(pIndexes[1]),
                                                       GetVertexColor(pIndexes[2]));
                }
                else
                {
                    // 对于多边形，先三角化再绘制
                    QPointF center = transformedPrimitive.boundingRect().center();
                    QColor centerColor = CalculateAverageColor(pIndexes, nIndexCount);
                    
                    for (unsigned int j = 0; j < nIndexCount; ++j)
                    {
                        unsigned int nextJ = (j + 1) % nIndexCount;
                        QPolygonF triangle;
                        triangle << transformedPrimitive[j] << transformedPrimitive[nextJ] << center;
                        
                        DrawTriangleWithGradientSubdivision(rPainter, triangle,
                                                           GetVertexColor(pIndexes[j]),
                                                           GetVertexColor(pIndexes[nextJ]),
                                                           centerColor);
                    }
                }
            }
            else
            {
                rPainter.SetBrush(QBrush(Qt::lightGray));
                rPainter.DrawPolygon(transformedPrimitive);
            }
        }
    }
}

    void XGraphCloudItem::DrawTriangleWithGradientSubdivision(XPainter& rPainter, 
                                                         const QPolygonF& triangle,
                                                         const QColor& color1, 
                                                         const QColor& color2,
                                                         const QColor& color3) const
{
    if (triangle.size() != 3)
        return;
    
    // 计算颜色差异
    qreal colorDifference = CalculateColorDifference(color1, color2, color3);
    
    // 计算三角形面积
    qreal area = qAbs((triangle[1].x() - triangle[0].x()) * (triangle[2].y() - triangle[0].y()) -
                      (triangle[2].x() - triangle[0].x()) * (triangle[1].y() - triangle[0].y())) / 2.0;
    
    // 根据颜色差异和面积确定细分级别
    int subdivisionLevel = 0;
    
    // 如果颜色差异很小，不需要太多细分
    if (colorDifference < 50) 
    {
        subdivisionLevel = (area > 500) ? 1 : 0;
    }
    // 中等颜色差异
    else if (colorDifference < 150) 
    {
        if (area > 50) subdivisionLevel = 1;
        if (area > 200) subdivisionLevel = 2;
        if (area > 800) subdivisionLevel = 3;
    }
    // 大颜色差异，需要更多细分
    else 
    {
        if (area > 30) subdivisionLevel = 2;
        if (area > 100) subdivisionLevel = 3;
        if (area > 400) subdivisionLevel = 4;
        if (area > 1600) subdivisionLevel = 5;
    }
    
    SubdivideAndDrawTriangle(rPainter, triangle[0], triangle[1], triangle[2],
                            color1, color2, color3, subdivisionLevel);
}

qreal XGraphCloudItem::CalculateColorDifference(const QColor& c1, const QColor& c2, const QColor& c3) const
{
    // 计算三个颜色之间的最大差异
    qreal diff12 = qSqrt(qPow(c1.red() - c2.red(), 2) + 
                        qPow(c1.green() - c2.green(), 2) + 
                        qPow(c1.blue() - c2.blue(), 2));
    qreal diff23 = qSqrt(qPow(c2.red() - c3.red(), 2) + 
                        qPow(c2.green() - c3.green(), 2) + 
                        qPow(c2.blue() - c3.blue(), 2));
    qreal diff31 = qSqrt(qPow(c3.red() - c1.red(), 2) + 
                        qPow(c3.green() - c1.green(), 2) + 
                        qPow(c3.blue() - c1.blue(), 2));
    
    return qMax(diff12, qMax(diff23, diff31));
}
void XGraphCloudItem::SubdivideAndDrawTriangle(XPainter& rPainter,
                                              const QPointF& p1, const QPointF& p2, const QPointF& p3,
                                              const QColor& c1, const QColor& c2, const QColor& c3,
                                              int level) const
{
    if (level <= 0)
    {
        // 绘制单色三角形（使用三个顶点颜色的平均值）
        QColor avgColor((c1.red() + c2.red() + c3.red()) / 3,
                       (c1.green() + c2.green() + c3.green()) / 3,
                       (c1.blue() + c2.blue() + c3.blue()) / 3,
                       (c1.alpha() + c2.alpha() + c3.alpha()) / 3);
        
        QPolygonF tri;
        tri << p1 << p2 << p3;
        rPainter.SetBrush(QBrush(avgColor));
        rPainter.SetPen(QPen(Qt::NoPen)); // 无边框
        rPainter.DrawPolygon(tri);
        return;
    }
    
    // 计算中点
    QPointF p12 = (p1 + p2) / 2.0;
    QPointF p23 = (p2 + p3) / 2.0;
    QPointF p31 = (p3 + p1) / 2.0;
    
    // 插值颜色
    QColor c12 = InterpolateColor(c1, c2, 0.5);
    QColor c23 = InterpolateColor(c2, c3, 0.5);
    QColor c31 = InterpolateColor(c3, c1, 0.5);
    
    // 递归绘制四个子三角形
    SubdivideAndDrawTriangle(rPainter, p1, p12, p31, c1, c12, c31, level - 1);
    SubdivideAndDrawTriangle(rPainter, p12, p2, p23, c12, c2, c23, level - 1);
    SubdivideAndDrawTriangle(rPainter, p31, p23, p3, c31, c23, c3, level - 1);
    SubdivideAndDrawTriangle(rPainter, p12, p23, p31, c12, c23, c31, level - 1);
}
QColor XGraphCloudItem::InterpolateColor(const QColor& c1, const QColor& c2, qreal t) const
{
    return QColor(
        qBound(0, int(c1.red() * (1 - t) + c2.red() * t), 255),
        qBound(0, int(c1.green() * (1 - t) + c2.green() * t), 255),
        qBound(0, int(c1.blue() * (1 - t) + c2.blue() * t), 255),
        qBound(0, int(c1.alpha() * (1 - t) + c2.alpha() * t), 255)
    );
}
QColor XGraphCloudItem::CalculateAverageColor(unsigned int* pIndexes, unsigned int nIndexCount) const
{
    if (!pIndexes || nIndexCount == 0)
        return Qt::lightGray;
    
    int r = 0, g = 0, b = 0, a = 0;
    int validColors = 0;
    
    for (unsigned int i = 0; i < nIndexCount; ++i)
    {
        QColor color = GetVertexColor(pIndexes[i]);
        if (color.isValid())
        {
            r += color.red();
            g += color.green();
            b += color.blue();
            a += color.alpha();
            validColors++;
        }
    }
    
    if (validColors > 0)
    {
        return QColor(r / validColors, g / validColors, 
                     b / validColors, a / validColors);
    }
    
    return Qt::lightGray;
}

#ifdef _WIN32
    void XGraphCloudItem::DrawWithGDI(XPainter &rPainter, const QRectF &scene, const QTransform &rTrans) const
    {
        if(!m_bHasColors || m_oScalarLocation != ScalarLocation::PointData)
            return;
        QPainter &painter = rPainter.Painter();
        QPaintDevice *pDevice = painter.device();
        if(!pDevice)
            return;
        int nWidth = pDevice->width();
        int nHeight = pDevice->height();

        std::vector<TRIVERTEX> vecVertices;
        std::vector<GRADIENT_TRIANGLE> vecTriangles;
        vecVertices.reserve(m_oCloudEntity.nNumOfVertexes);
        vecTriangles.reserve(m_oCloudEntity.vecPrimitiveVertexIndexes.size() * 2);

        int nVertexOffset = 0;
        for(unsigned int i = 0; i < m_oCloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
        {
            const auto &rIndexPair = m_oCloudEntity.vecPrimitiveVertexIndexes[i];
            unsigned int *pIndexes = rIndexPair.first;
            unsigned int nIndexCount = rIndexPair.second;
            if(nIndexCount < 3 || pIndexes == nullptr)
                continue;
            std::vector<QPointF> vecTransformedPoints;
            std::vector<QColor> vecColors;
            for(unsigned int j = 0; j < nIndexCount; ++j)
            {
                unsigned int nVertexIndex = pIndexes[j];
                QPointF pt = GetVertex2D(nVertexIndex);
                QPointF transformedPt = rTrans.map(pt);
                vecTransformedPoints.push_back(transformedPt);
                vecColors.push_back(GetVertexColor(nVertexIndex));
            }
            if(nIndexCount == 3)
            {
                int nBaseIndex = static_cast<int>(vecVertices.size());
                for(int j = 0; j < 3; ++j)
                {
                    TRIVERTEX vertex;
                    vertex.x = static_cast<LONG>(vecTransformedPoints[j].x());
                    vertex.y = static_cast<LONG>(vecTransformedPoints[j].y());
                    vertex.Red = static_cast<COLOR16>(vecColors[j].red() << 8);
                    vertex.Green = static_cast<COLOR16>(vecColors[j].green() << 8);
                    vertex.Blue = static_cast<COLOR16>(vecColors[j].blue() << 8);
                    vertex.Alpha = static_cast<COLOR16>(vecColors[j].alpha() << 8);
                    vecVertices.push_back(vertex);

                }
                GRADIENT_TRIANGLE triangle;
                triangle.Vertex1 = nBaseIndex;
                triangle.Vertex2 = nBaseIndex + 1;
                triangle.Vertex3 = nBaseIndex + 2;
                vecTriangles.push_back(triangle);
            }
            else
            {
                int nBaseIndex = static_cast<int>(vecVertices.size());
                for(int j = 0; j < nIndexCount; ++j)
                {
                    TRIVERTEX vertex;
                    vertex.x = static_cast<LONG>(vecTransformedPoints[j].x());
                    vertex.y = static_cast<LONG>(vecTransformedPoints[j].y());
                    vertex.Red = static_cast<COLOR16>(vecColors[j].red() << 8);
                    vertex.Green = static_cast<COLOR16>(vecColors[j].green() << 8);
                    vertex.Blue = static_cast<COLOR16>(vecColors[j].blue() << 8);
                    vertex.Alpha = static_cast<COLOR16>(vecColors[j].alpha() << 8);
                    vecVertices.push_back(vertex);
                }
                for(unsigned int k = 1; k < nIndexCount - 1; ++k)
                {
                    GRADIENT_TRIANGLE triangle;
                    triangle.Vertex1 = nBaseIndex;
                    triangle.Vertex2 = nBaseIndex + k;
                    triangle.Vertex3 = nBaseIndex + k + 1;
                    vecTriangles.push_back(triangle);
                }
            }
        }
        if(vecVertices.empty() || vecTriangles.empty())
            return;
        QImage oTempImage(nWidth, nHeight, QImage::Format_ARGB32);
        oTempImage.fill(Qt::transparent);
        GDIToImage(&oTempImage, vecVertices.data(), static_cast<int>(vecVertices.size()),
            vecTriangles.data(), static_cast<int>(vecTriangles.size()));
        painter.drawImage(0, 0, oTempImage);
        for(unsigned int i = 0; i < m_oCloudEntity.vecPrimitiveVertexIndexes.size(); ++i)
        {
            QPolygonF oPrimitive = GetPrimitive2D(i);
            QPolygonF oTransformedPrimitive = rTrans.map(oPrimitive);
            DrawPolygonOutline(rPainter, oTransformedPrimitive);
        }
    }

    void XGraphCloudItem::GDIToImage(QImage *pImage, TRIVERTEX *pVertex, int nVertexCount, GRADIENT_TRIANGLE *pTriangles, int nTriangleCount) const
    {
        int nWidth = pImage->width();
        int nHeight = pImage->height();
        int nPixCount = nWidth * nHeight;

        HDC hdc = GetDC(nullptr);
        HDC hMemDC = CreateCompatibleDC(hdc);
        HBITMAP hMemBitmap = CreateCompatibleBitmap(hdc, nWidth, nHeight);
        HGDIOBJ hOldBitmap = SelectObject(hMemDC, hMemBitmap);
        ReleaseDC(nullptr, hdc);

        RECT rect = {0, 0, nWidth, nHeight};
        HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));
        FillRect(hMemDC, &rect, hBrush);
        DeleteObject(hBrush);

        GradientFill(hMemDC, pVertex, nVertexCount, pTriangles, nTriangleCount, GRADIENT_FILL_TRIANGLE);

        BITMAPINFO oBitmapInfo = { 0 };
        oBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        oBitmapInfo.bmiHeader.biWidth = nWidth;
        oBitmapInfo.bmiHeader.biHeight = -nHeight;
        oBitmapInfo.bmiHeader.biPlanes = 1;
        oBitmapInfo.bmiHeader.biBitCount = 32;
        oBitmapInfo.bmiHeader.biCompression = BI_RGB;
        GetDIBits(hMemDC, hMemBitmap, 0, nHeight, pImage->bits(), &oBitmapInfo, DIB_RGB_COLORS);

        int32_t *pPixel = (int32_t*)pImage->bits();
        for(int i = 0; i < nPixCount; ++i)
        {
            if ((pPixel[i] & 0x00FFFFFF) != 0x00FFFFFF)
            {
                pImage->bits()[i * 4 + 3] = 255; 
            }
            else
            {
                pImage->bits()[i * 4 + 3] = 0;
            }
        }
        SelectObject(hMemDC, hOldBitmap);
        DeleteDC(hMemDC);
        DeleteObject(hMemBitmap);
    }
#endif这样在windows下确实大大提升了效率，但是在linux下还是用原来的方法，效率低下，在linux下有什么好方法，给出修改后的代码