ulookabit2
ulookabit2

Reputation: 41

Qt3D draw lines consumes too much memory

how to draw line with Qt3D? how to delete the painted line? I found the following code consume too much memory if you draw many lines, although it works. this method allocates too much storage for drawing only one line and it does not free them. if you use delete the pointer, then it crashed. how to solve this problem?

#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QAttribute>
#include <Qt3DRender/QBuffer>
#include <Qt3DRender/QGeometry>

drawLine(const QVector3D &start, const QVector3D &end, const QColor &color)
{
    if(!m_bShow) {
        return;
    }

    auto *geometry = new Qt3DRender::QGeometry(m_pRootEntity);
    QByteArray bufferBytes;
    bufferBytes.resize(3*2*sizeof (float));
    float *pos = reinterpret_cast<float*>(bufferBytes.data());
    *pos++ = start.x();
    *pos++ = start.y();
    *pos++ = start.z();
    *pos++ = end.x();
    *pos++ = end.y();
    *pos++ = end.z();

    auto *buf = new Qt3DRender::QBuffer(geometry);
    buf->setData(bufferBytes);

    auto *positionAttribute = new Qt3DRender::QAttribute(geometry);
    positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
    positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
    positionAttribute->setVertexSize(3);
    positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
    positionAttribute->setBuffer(buf);
    positionAttribute->setByteStride(3 * sizeof(float));
    positionAttribute->setCount(2);
    geometry->addAttribute(positionAttribute); // We add the vertices in the geometry

    //connectivity between vertices
    QByteArray indexBytes;
    indexBytes.resize(2 * sizeof(unsigned int)); // start to end
    unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
    *indices++ = 0;
    *indices++ = 1;
    auto *indexBuffer = new Qt3DRender::QBuffer(geometry);
    indexBuffer->setData(indexBytes);

    auto *indexAttribute = new Qt3DRender::QAttribute(geometry);
    indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
    indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
    indexAttribute->setBuffer(indexBuffer);
    indexAttribute->setCount(2);
    geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry

    //mesh
    auto *line = new Qt3DRender::QGeometryRenderer(m_pRootEntity);
    line->setGeometry(geometry);
    line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);

    //material
    auto *material = new Qt3DExtras::QDiffuseSpecularMaterial(m_pRootEntity);
    material->setAmbient(color);

    auto *lineEntity = new Qt3DCore::QEntity(m_pRootEntity);

    lineEntity->addComponent(line);
    lineEntity->addComponent(material);
}

Upvotes: 3

Views: 349

Answers (1)

ulookabit2
ulookabit2

Reputation: 41

Finally, I solved this question.
First, put the line entity to a container:
m_lineEntityList.push_back(lineEntity),
then remove the line entity's components:

 while(!m_lineEntityList.isEmpty()) {
    Qt3DCore::QEntity* pEntity = m_lineEntityList.last();
    Qt3DCore::QComponentVector entityVector = pEntity->components();
    while (!entityVector.isEmpty()) {
        pEntity->removeComponent(entityVector.last());
        entityVector.pop_back();
    }
    m_lineEntityList.pop_back();
}

Upvotes: 1

Related Questions