0

I face the problem of a slow response with this code

Repeater3D {
    model: <QAbstractListModel>
    Model {
        materials: [
            DefaultMaterial {
                id: pieceMaterial
                diffuseColor: "green"
                diffuseMap: Texture { 
                    sourceItem: Rectangle { color: "red"; text: "A" }
            }

It takes a couple of seconds on a fast computer to create ~5000 rather simple objects. Without the texture speed is okay; and I can set the object color via diffuseColor (in fact max 200 out of the 5000 objects get a texture, which is more or less only a label). But if the diffuseMap is assigned to a Texture the diffuseColor stops working even when the texture content is not visible.

It seems to be a task for a state but I cannot create/assign the whole texture like

    State {
        name: "noContent"
        when: true
        PropertyChanges {
            target: pieceMaterial
            diffuseMap: {}
        }

Any idea?

2 Answers2

0

One solution is you can delay load your delegates. The following populates a ListModel with 4096 records, but, it does it via a Timer, so that the app has a fast startup time:

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
Page {
    background: Rectangle { color: "#848895" }
    Node {
        id: standAloneScene
        DirectionalLight { ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0) }
        Node {
            id: node
            Repeater3D {
                model: ListModel { id: listModel }
                Model {
                    source: "#Cube"
                    x: ix
                    y: iy
                    z: iz
                    materials: [
                        DefaultMaterial {
                            diffuseMap: Texture {
                                sourceItem: Rectangle {
                                    width: 32
                                    height: 32
                                    color: grey.checked ? gy : co
                                    Text {
                                        anchors.centerIn: parent
                                        text: "A"
                                        font.pixelSize: 16
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }
        OrthographicCamera {
            id: cameraOrthographicFront
            lookAtNode: node
            y: 800; z: 1000
            scale: Qt.vector3d(5,5,1)
        }
    }
    Timer {
        running: listModel.count < 4096
        repeat: true
        interval: 10
        onTriggered: {
            for (let n = 0; n < 16; n++) {
                let index = listModel.count;
                let i = index & 15;
                let j = (index >> 4) & 15;
                let k = (index >> 8) & 15;
                let co = Qt.rgba(i/15,j/15,k/15).toString();
                let m = (i+j+k)/3;
                let gy = Qt.rgba(m/15,m/15,m/15).toString();
                let ix = (i - 7) * 110;
                let iy = (j - 7) * 110;
                let iz = (k - 7) * 110;
                listModel.append( { i,j,k,co,gy,ix,iy,iz } );
            }
        }
    }
    View3D {
        anchors.fill: parent
        importScene: standAloneScene
        camera: cameraOrthographicFront
    }
    NumberAnimation {
        target: node
        property: "eulerRotation.y"
        loops: Animation.Infinite
        running: true
        from: 720; to: 0
        duration: 40000
    }
    NumberAnimation {
        target: node
        property: "eulerRotation.x"
        loops: Animation.Infinite
        running: true
        from: 360; to: 0
        duration: 20000
    }
    footer: Frame {
        RowLayout {
            Text { text: listModel.count }
            CheckBox { id: grey; text: "Grey" }
        }
    }
}

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
  • Node > Node... is different from my View3D > Skeleton > Repeater3D approach, and I wonder if the timer works then. Should have shared a link to the whole project / file with the initial question, here it is https://github.com/Scrabble3D/4.0/blob/main/ScrCube.qml – Heiko Tietze May 03 '23 at 08:48
  • Even you identified delay loading as a solution here https://github.com/Scrabble3D/4.0/blob/fc1a6f8c2ef7df39876844879504ebb91d81a052/ScrCube.qml#L44 - the key is to incremental populate, not do it all at once. Don't take the Timer too literally. The concept is to slow the rate of population. Timer/QTimer is only an example of how you may achieve it but it's not the only solution. – Stephen Quan May 03 '23 at 23:38
0

Solved my problem with a Loader3D and two components.

Component {
    id: noContent
    Model {
        materials: DefaultMaterial {
            diffuseColor: foo
        }
    }
}
Component {
    id: hasContent
    Model {
        materials: DefaultMaterial {
            diffuseMap: Texture { 
                autoOrientation: bar
            }
        }
    }
}
Skeleton {
    Repeater3D {
        Loader3D {
            sourceComponent: bSwitch ? noContent : hasContent
            property int foo: aFoo
            property bool bar: aBar
        }
    }
}