[Interest] Strange visibility problem after updating entities in Qt3D

Tony Rietwyk tony at rightsoft.com.au
Wed Oct 4 03:44:54 CEST 2017


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 at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20171004/28298867/attachment.html>


More information about the Interest mailing list