[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