3

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);
}
Eddy Alleman
  • 1,096
  • 2
  • 10
  • 21
ulookabit2
  • 41
  • 2
  • 3
    "this method allocates too much storage for drawing only one line and it does not free them", well yeah, you're using `new` everywhere in your code, and you're not using `delete` anywhere. Using `new` at all in modern C++ is not reccomended at all – Kaldrr Aug 29 '19 at 09:59
  • As far as I know you're not supposed to use `delete` manually in Qt3D. It cleans up after you when you shut it down. How much memory does it consume? Qt3D is not especially resource-friendly. At least that's what I found when I used it. – Florian Blume Aug 29 '19 at 16:05

1 Answers1

1

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();
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
ulookabit2
  • 41
  • 2