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

Reply via email to