[Interest] Strange visibility problem after updating entities in Qt3D

Helmut Mülner helmut.muelner at gmail.com
Tue Oct 3 17:20:19 CEST 2017


Background:

==========

   I have a QML application with big parts written in C++ (mostly models)
that are exposed to QML with setContextProperty.

 

  I also have a 3DScene in QML:

 

Scene3D {

    id: scene3d

    width: 4

    focus: true

    aspects: ["input", "logic"]

    cameraAspectRatioMode: Scene3D.AutomaticAspectRatio

    enabled: visible

    visible: false

    entity: controller.railViewer

}

 

Step 1:

=====

railViewer is a pointer to a class derived from Qt3DCore::QEntity.

It displays a part of a rail with special markers for “defects”.

There is a “current defect” that is highlighted.

My entity has the following childs (I gave “my” entities an objectName):

Qt3DRender::QRenderSettings   

Qt3DExtras::QOrbitCameraController   

Qt3DRender::QObjectPicker   

Qt3DInput::QInputSettings   

Qt3DCore::QEntity   RailPart-0

Qt3DCore::QEntity   RailPart-1

Qt3DCore::QEntity   RailPart-2

Qt3DCore::QEntity   RailPart-3

Qt3DCore::QEntity   RailPart-4

Qt3DCore::QEntity   RailPart-5

Qt3DCore::QEntity   RailPart-6

Qt3DCore::QEntity   RailPart-7

DefectBoxEntity   RailDefect-1501

set alpha to  0.95 for  0

DefectBoxEntity   RailDefect-1502

set alpha to  0.4 for  1

(see rail1.jpg).

The 3D view works like a charm.

 

 

Step 2:

=====

 

Now I want to show another rail (it may have fewer or more parts) and
another set of defects.

The view from the side looks good (see rail2.jpg).

But if I tilt the view, the visibility of the first two boxes is wrong.

My childs now are:

Qt3DRender::QRenderSettings   

Qt3DExtras::QOrbitCameraController   

Qt3DRender::QObjectPicker   

Qt3DInput::QInputSettings   

Qt3DCore::QEntity   RailPart-0

Qt3DCore::QEntity   RailPart-1

Qt3DCore::QEntity   RailPart-2

Qt3DCore::QEntity   RailPart-3

Qt3DCore::QEntity   RailPart-4

Qt3DCore::QEntity   RailPart-5

Qt3DCore::QEntity   RailPart-6

Qt3DCore::QEntity   RailPart-7

DefectBoxEntity   RailDefect-501

set alpha to  0.95 for  0

DefectBoxEntity   RailDefect-502

set alpha to  0.4 for  1

DefectBoxEntity   RailDefect-503

set alpha to  0.4 for  2

DefectBoxEntity   RailDefect-504

set alpha to  0.4 for  3

DefectBoxEntity   RailDefect-505

set alpha to  0.4 for  4

DefectBoxEntity   RailDefect-506

set alpha to  0.4 for  5

DefectBoxEntity   RailDefect-507

set alpha to  0.4 for  6

DefectBoxEntity   RailDefect-508

set alpha to  0.4 for  7

 

To update the scene I remove all Rail.* entities and insert the new ones.

 

These are the relevant parts of this code:

 

void deleteChildrenRecursively(const Qt3DCore::QNodeVector& vector)

{

    Qt3DCore::QNode* nullParent = nullptr;

    for (auto* node : vector) {

        auto* entity = dynamic_cast<Qt3DCore::QEntity*>(node);

        if (entity) {

            auto comps = entity->components();

            entity->setParent(nullParent);

            for (auto* component : comps) {

                component->setParent(nullParent);

                entity->removeComponent(component);

                delete component;

            }

        }

        deleteChildrenRecursively(node->childNodes());

        delete node;

    }

}

 

void RailEntityPrivate::load(double frameHeight, const
std::vector<std::pair<int, RealPointVector>>& finalPointVecs)

{

    Q_Q(RailEntity);

    Qt3DCore::QNode* nullParent = nullptr;

    qDebug() << "RailEntityPrivate::load:";

    auto childs = q->childNodes();

    for (auto& node : childs) {

        qDebug() << node->metaObject()->className() << " " <<
qPrintable(node->objectName());

    }

    qDebug() << "";

    Qt3DCore::QNodeVector railNodes;

    length = frameHeight * 3.0;

    railNodes.reserve(childs.size());

    for (auto* node : childs) {

        if (node->objectName().startsWith(QLatin1String("Rail"))) {

            railNodes.push_back(node);

        }

    }

    for (auto* node : railNodes) {

        Qt3DCore::QEntity* entity = (Qt3DCore::QEntity*)node;

        entity->setParent(nullParent);

        auto ec = node->childNodes();

        deleteChildrenRecursively(ec);

        delete entity;

    }

 

    currentDefectIndex = -1;

    computeExtend(finalPointVecs);

    size_t startList = 0u;

    size_t endList = finalPointVecs.size();

    for (auto i = startList; i < endList; ++i) {

        auto entity = new Qt3DCore::QEntity(q);

        entity->setObjectName(QStringLiteral("RailPart-") +
QString::number(i));

        auto flength = static_cast<float>(length);

        auto mesh = new RailGeometryRenderer(finalPointVecs[i].second,
flength);

        auto material = new Qt3DExtras::QNormalDiffuseMapMaterial();

        material->setShininess(10.0f);

        material->setAmbient(QColor(76, 84, 76));

        material->setSpecular(QColor(20, 20, 20));

        auto seed = static_cast<unsigned int>(currentFrameNr * 100u + i);

        auto heightMap = RailEntityPrivate::createRandomHeightMap(1024, 512,
seed);

        auto* diffuseImage = new MyTextureImage(heightMap);

        material->diffuse()->addTextureImage(diffuseImage);

        auto normalMap =
RailEntityPrivate::makeNormalMapFromHeightMap(heightMap);

        auto* normalImage = new MyTextureImage(normalMap);

        material->normal()->addTextureImage(normalImage);

        entity->addComponent(mesh);

        entity->addComponent(material);

    }

    centerCamera();

}

void RailEntity::updateDefects(const Defects& defects)

{

    Q_D(RailEntity);

    size_t defectCount = defects.size();

    size_t index = 0;

    auto childs = childNodes();

    Qt3DCore::QNode* nullParent = nullptr;

    qDebug() << "RailEntity::updateDefects:";

    for (auto& node : childs) {

        qDebug() << node->metaObject()->className() << " " <<
qPrintable(node->objectName());

    }

    qDebug() << "";

    Qt3DCore::QNodeVector railDefectNodes;

    railDefectNodes.reserve(childs.size());

    for (auto* node : childs) {

        if (node->objectName().startsWith(QLatin1String("RailDefect-"))) {

            railDefectNodes.push_back(node);

        }

    }

    for (auto* node : railDefectNodes) {

        Qt3DCore::QEntity* entity = (Qt3DCore::QEntity*)node;

        entity->setParent(nullParent);

        auto ec = node->childNodes();

        deleteChildrenRecursively(ec);

        delete entity;

    }

    for (const auto& defect : defects) {

        QString name = QLatin1String("RailDefect-") +
QString::number(defect.id);

        d->insertDefect(name, defect, this);

    }

}

void RailEntityPrivate::insertDefect(QString name, const Defect& defect,
Qt3DCore::QEntity* parent)

{

    QString classColor;

    if (defectClassModel) {

        classColor =
defectClassModel->getColor(static_cast<int>(defect.classId));

    }

    QColor col = classColor.isEmpty() ? QColor(128, 40, 0) :
QColor(classColor);

    auto entity = new DefectBoxEntity(defect, col, startMM, parent);

    entity->setObjectName(name);

}

 

 

DefectBoxEntity has a transform, a base QPhongAlphaMaterial and 12
QCuboidMeshes with associated transforms and using the base material.

 

 

I suspect that either I do something wrong when I delete the “old” entities
or there is a general synchronization problem with the rendering backend.

 

Anybody with ideas or suggestions?

 

Best regards,

Helmut

 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171003/7826db71/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rail1.jpg
Type: image/jpeg
Size: 64209 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171003/7826db71/attachment.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rail2.jpg
Type: image/jpeg
Size: 59309 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171003/7826db71/attachment-0001.jpg>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rail3.jpg
Type: image/jpeg
Size: 77744 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171003/7826db71/attachment-0002.jpg>


More information about the Interest mailing list