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

Dynamic Qt Quick 3D creation and deletion

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qt quick 3d
5 Posts 3 Posters 828 Views
  • 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