Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Dynamic Qt Quick 3D creation and deletion
Forum Updated to NodeBB v4.3 + New Features

Dynamic Qt Quick 3D creation and deletion

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qt quick 3d
5 Posts 3 Posters 855 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sieve
    wrote on 1 Oct 2020, 00:55 last edited by
    #1

    Hello all.

    Short story, dynamically creating new items that contain Qt Quick 3D :: View3D crashes my application.

    Seems like this crash happens when a new View3D is created; after the destruction of all other items with View3D.
    Currently I am keeping an item with View3D alive, but does anybody know a proper solution, or a better workaround?

    A simple scenario:
    * 1. Push a couple of items that contain View3D into a StackView ( item ownership doesn't matter as long as the object is detroyed after pop )
    * 2. Pop until the stack is empty ( initial element is not a View3D )
    * 3. Push another item that contains View3D
    * 4. Expected application crash

    Below is a minimum working example

    main.qml

    import QtQuick 2.15
    import QtQuick3D 1.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.15
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Crash Test")
    
        StackView {
            id: sv_main
    
            anchors.fill: parent
    
            /******************************************************
             *
             *  Disable below property and execute the
             *  following to crash this example software
             *  1. Push a couple of Quick 3D elements into the stack
             *  2. Pop until the stack is empty
             *  3. Push another Quick 3D Element
             *  4. Expected crash
             *
             ******************************************************/
    
    //        initialItem: comp_initial
        }
    
        Row {
            spacing: 8
    
            anchors {
                horizontalCenter: parent.horizontalCenter
                bottom: parent.bottom
                margins: 16
            }
    
            Button {
                text: "Push"
                onClicked: sv_main.push( "qrc:/Quick3dView.qml" )
            }
    
            Button {
                enabled: sv_main.depth > 1
                text: "Pop"
                onClicked: sv_main.pop()
            }
        }
    
        Component {
            id: comp_initial
    
            Label {
                text: "StackView is empty.\n Click \"Push\" to insert a Qt Quick 3D view into the stack."
                horizontalAlignment: Label.AlignHCenter
                verticalAlignment: Label.AlignVCenter
                background: Rectangle { color: "lightgreen" }
    
    
                Text {
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: sv_main.depth
                    font.pixelSize: 64
                }
            }
        }
    }
    

    Quick3dView.qml

    import QtQuick 2.15
    import QtQuick3D 1.15
    import QtQuick.Controls 2.15
    
    Item {
        id: root
    
        View3D {
            anchors.fill: root
            environment: SceneEnvironment {
                clearColor: Qt.rgba( Math.random(), Math.random(), Math.random(), 1.0 )
                backgroundMode: SceneEnvironment.Color
            }
            camera: pcam
    
            Component.onCompleted: console.log( "Completed: " + this )
            Component.onDestruction: console.log( "Destruction: " + this )
    
            PerspectiveCamera {
                id: pcam
    
                position: Qt.vector3d(0, 0, 300)
            }
    
            DirectionalLight {}
    
            Model {
                id: mdl_cube
    
                position: Qt.vector3d(0, 0, 0)
                source: "#Cube"
    
                materials: [ DefaultMaterial {
                        diffuseColor: "blue"
                    }
                ]
    
                ParallelAnimation {
                    running: true
                    loops: Animation.Infinite
    
                    NumberAnimation {
                        target: mdl_cube
                        properties: "eulerRotation.x"
                        duration: 3000
                        from: 0
                        to: 360
                        easing.type:Easing.Linear
                    }
    
                    NumberAnimation {
                        target: mdl_cube
                        properties: "eulerRotation.y"
                        duration: 3000
                        from: 0
                        to: 360
                        easing.type:Easing.Linear
                    }
                }
            }
    
            Text {
                anchors.horizontalCenter: parent.horizontalCenter
                text: root.StackView.index
                font.pixelSize: 64
            }
        }
    }
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sieve
      wrote on 2 Oct 2020, 04:51 last edited by Sieve 10 Feb 2020, 04:52
      #2

      Marking as solved since Qt Support acknowledged this as a bug.

      Will test again and post my results after a future release for those who are interested in.

      1 Reply Last reply
      0
      • O Offline
        O Offline
        Obsess
        wrote on 2 Jan 2021, 22:07 last edited by
        #3

        Hi Sieve, I just updated to Qt 6 and am hitting this same issue. I'm using Qt Quick 3D on different pages of my app which results in dynamically creating and deleting View3Ds. This results in a crash.

        Did you have a bug number for this issue?

        1 Reply Last reply
        0
        • Q Offline
          Q Offline
          QCuteInt
          wrote on 11 Jun 2021, 12:48 last edited by
          #4

          I've been blocked by this as well (Qt 6.1). I've managed to find a work around although it's not ideal. You can dynamically create the View3D but instead of deleting you can store it in a reuse buffer. Then if you need a View3D you can just grab one from the buffer or create it if empty. The one snag seems to be that the view requires a valid parent. I tried setting it to null but the crash happens when you re-parent or add the re-used view. I set the view to invisible and then re-parent. Here is a minimal working example.

          import QtQuick
          import QtQuick3D
          import QtQuick.Controls
          import QtQuick.Layouts
          
          Window {
              id: window
              width: 1280
              height: 720
              visible: true
              color: "#848895"
          
              Item {
                  id: root
                  anchors.fill: parent
                  ColumnLayout {
                      anchors.fill: parent
                      RowLayout {
                          Button {
                              text: "Remove"
                              onClicked: keeper.removeView()
                          }
                          Button {
                              text: "Add"
                              onClicked: {
                                  var v = keeper.getView()
                                  if (v) {
                                      v.parent = flow
                                      v.visible = true
                                  }
                              }
                          }
                      }
                      Flow {
                          id: flow
                          Layout.fillWidth: true
                          Layout.fillHeight: true
                      }
                  }
          
                  property int viewCount: 0
                  Component {
                      id: viewComponent
                      Item {
                          width: 200
                          height: 200
                          visible: false
                          View3D {
                              anchors.fill: parent
                              environment: SceneEnvironment {
                                  clearColor: Qt.rgba (1, 0, 0, 1)
                                  backgroundMode: SceneEnvironment.Color
                              }
          
                              PerspectiveCamera { z: 200 }
                              DirectionalLight { eulerRotation.x: -25 }
                              Model {
                                  source: "#Cube"
                                  materials: DefaultMaterial { diffuseColor: Qt.rgba(0.8, 0.8, 0.8, 1.0) }
                                  PropertyAnimation on eulerRotation.y {
                                      loops: Animation.Infinite
                                      duration: 5000
                                      to: 0
                                      from: -360
                                  }
                              }
          
                              Component.onCompleted: print ("View Created:", ++root.viewCount)
                              Component.onDestruction: print ("View Destroyed", --root.viewCount)
                          }
                      }
                  }
              }
          
              Item {
                  id: keeper
                  visible: false
                  property var views: []
                  property var removed: []
          
                  function getView() {
                      if (0 < removed.length) {
                          views.push(removed.pop())
                      }
                      else {
                          views.push(viewComponent.createObject(flow))
                      }
                      return views[views.length - 1]
                  }
          
                  function removeView() {
                      if (0 < views.length) {
                          var v = views.pop()
                          v.visible = false
                          v.parent = keeper
                          removed.push(v)
                      }
                  }
              }
          }
          
          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            QCuteInt
            wrote on 2 Jul 2021, 15:42 last edited by
            #5

            The code in my previous post works in some cases but additional conditions must also be met. I eliminated crashes, I think, in Qt 6.1.2 with the following:

            1. A buffer to prevent deletion of the View3D in the code above is required.
            2. The parent hierarchy of the View3D must not have a null parent. Creating an Item with a null parent, adding a View3D, and then settings the item's parent can lead to a crash.
            3. Visibility is important. If adding a View3D to an Item, it seems best to create/add a View3D when the item becomes visible. I'm also releasing the view when the item becomes invisible. This seems to keep Qt happy and so far the crashes are gone.
            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved