Hi Helmut,
I think your deleteChildrenRecursively is incorrect - you need to
process the vector in reverse if you delete the current node. Especially
as you have declared the vector parameter 'const &', the compiler
probably can't work out that deleting the node will update the vector.
So deleting some children will be skipped.
Regards, Tony
On 4/10/2017 2:20 AM, Helmut Mülner wrote:
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:
voiddeleteChildrenRecursively(constQt3DCore::QNodeVector& vector)
{
Qt3DCore::QNode* nullParent= nullptr;
for(auto* node: vector) {
auto* entity= dynamic_cast<Qt3DCore::QEntity*>(node);
if(entity) {
autocomps= entity->components();
entity->setParent(nullParent);
for(auto* component: comps) {
component->setParent(nullParent);
entity->removeComponent(component);
deletecomponent;
}
}
deleteChildrenRecursively(node->childNodes());
deletenode;
}
}
voidRailEntityPrivate::load(doubleframeHeight,
conststd::/vector/<std::pair<int, RealPointVector>>& finalPointVecs)
{
Q_Q(RailEntity);
Qt3DCore::QNode* nullParent= nullptr;
qDebug() <<"RailEntityPrivate::load:";
autochilds= q->childNodes();
for(auto& node: childs) {
qDebug() <<node->metaObject()->className() <<"
"<<qPrintable(node->objectName());
}
qDebug() <<"";
Qt3DCore::QNodeVectorrailNodes;
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);
autoec= node->childNodes();
deleteChildrenRecursively(ec);
deleteentity;
}
currentDefectIndex= -1;
computeExtend(finalPointVecs);
/size_t/startList= 0u;
/size_t/endList= finalPointVecs.size();
for(autoi= startList; i< endList; ++i) {
autoentity= newQt3DCore::QEntity(q);
entity->setObjectName(QStringLiteral("RailPart-") +QString::number(i));
autoflength= static_cast<float>(length);
automesh= newRailGeometryRenderer(finalPointVecs[i].second, flength);
automaterial= newQt3DExtras::QNormalDiffuseMapMaterial();
material->setShininess(10.0f);
material->setAmbient(QColor(76, 84, 76));
material->setSpecular(QColor(20, 20, 20));
autoseed= static_cast<unsignedint>(currentFrameNr* 100u + i);
autoheightMap= RailEntityPrivate::createRandomHeightMap(1024, 512, seed);
auto* diffuseImage= newMyTextureImage(heightMap);
material->diffuse()->addTextureImage(diffuseImage);
autonormalMap= RailEntityPrivate::makeNormalMapFromHeightMap(heightMap);
auto* normalImage= newMyTextureImage(normalMap);
material->normal()->addTextureImage(normalImage);
entity->addComponent(mesh);
entity->addComponent(material);
}
centerCamera();
}
voidRailEntity::updateDefects(constDefects& defects)
{
Q_D(RailEntity);
/size_t/defectCount= defects./size/();
/size_t/index= 0;
autochilds= childNodes();
Qt3DCore::QNode* nullParent= nullptr;
qDebug() <<"RailEntity::updateDefects:";
for(auto& node: childs) {
qDebug() <<node->metaObject()->className() <<"
"<<qPrintable(node->objectName());
}
qDebug() <<"";
Qt3DCore::QNodeVectorrailDefectNodes;
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);
autoec= node->childNodes();
deleteChildrenRecursively(ec);
deleteentity;
}
for(constauto& defect: defects) {
QStringname= QLatin1String("RailDefect-") +QString::number(defect.id);
d->insertDefect(name, defect, this);
}
}
voidRailEntityPrivate::insertDefect(QStringname, constDefect& defect,
Qt3DCore::QEntity* parent)
{
QStringclassColor;
if(defectClassModel) {
classColor=defectClassModel->getColor(static_cast<int>(defect.classId));
}
QColorcol= classColor.isEmpty() ? QColor(128, 40, 0) : QColor(classColor);
autoentity= newDefectBoxEntity(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
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest