aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristián Maureira-Fredes <cristian.maureira-fredes@qt.io>2021-11-11 14:30:38 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-29 11:11:40 +0000
commite47762e7ad848bb45676913d75f44f7485494479 (patch)
tree55a6677980acf51cba8606faac3e1049b47c1642
parentf02a0e0f2d8f3f70838753da231cebe3b5cb7b78 (diff)
Add QtQuick3D module
Adding the module that contains a few C++ classes. Adding the 'intro' example. Adding the 'customgeometry' example as well. Fixes: PYSIDE-1708 Change-Id: I0681f087e74c13c024bb1dfa8de545b30f95d7d8 Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit b9ec49942b3ad53343317e631320c58e59736c22) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/quick3d/customgeometry/customgeometry.pyproject3
-rw-r--r--examples/quick3d/customgeometry/doc/customgeometry-example.jpgbin0 -> 51016 bytes
-rw-r--r--examples/quick3d/customgeometry/doc/customgeometry.rst17
-rw-r--r--examples/quick3d/customgeometry/examplepoint.py88
-rw-r--r--examples/quick3d/customgeometry/exampletriangle.py225
-rw-r--r--examples/quick3d/customgeometry/main.py66
-rw-r--r--examples/quick3d/customgeometry/main.qml287
-rw-r--r--examples/quick3d/customgeometry/qt_logo_rect.pngbin0 -> 6319 bytes
-rw-r--r--examples/quick3d/customgeometry/resources.qrc6
-rw-r--r--examples/quick3d/customgeometry/resources_rc.py584
-rw-r--r--examples/quick3d/intro/doc/intro.pngbin0 -> 13781 bytes
-rw-r--r--examples/quick3d/intro/doc/intro.rst9
-rw-r--r--examples/quick3d/intro/intro.pyproject3
-rw-r--r--examples/quick3d/intro/main.py60
-rw-r--r--examples/quick3d/intro/main.qml127
-rw-r--r--sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt51
-rw-r--r--sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml63
-rw-r--r--sources/pyside6/cmake/PySideHelpers.cmake1
-rw-r--r--sources/pyside6/tests/QtQuick3D/CMakeLists.txt1
19 files changed, 1591 insertions, 0 deletions
diff --git a/examples/quick3d/customgeometry/customgeometry.pyproject b/examples/quick3d/customgeometry/customgeometry.pyproject
new file mode 100644
index 000000000..45f906e20
--- /dev/null
+++ b/examples/quick3d/customgeometry/customgeometry.pyproject
@@ -0,0 +1,3 @@
+{
+ "file": ["examplepoint.py", "exampletriangle.py", "main.py", "main.qml", "resources.qrc"]
+}
diff --git a/examples/quick3d/customgeometry/doc/customgeometry-example.jpg b/examples/quick3d/customgeometry/doc/customgeometry-example.jpg
new file mode 100644
index 000000000..8f443c3e9
--- /dev/null
+++ b/examples/quick3d/customgeometry/doc/customgeometry-example.jpg
Binary files differ
diff --git a/examples/quick3d/customgeometry/doc/customgeometry.rst b/examples/quick3d/customgeometry/doc/customgeometry.rst
new file mode 100644
index 000000000..32a18a5fe
--- /dev/null
+++ b/examples/quick3d/customgeometry/doc/customgeometry.rst
@@ -0,0 +1,17 @@
+Custom Geometry Example
+=======================
+
+This example makes use of QQuick3DGeometry and the geometry property
+of Model to render a mesh with vertex, normal, and
+texture coordinates specified from Python instead of a pre-baked asset.
+
+In addition, the GridGeometry is also demonstrated. GridGeometry is a
+built-in QQuick3DGeometry implementation that provides a mesh with line
+primitives suitable for displaying a grid.
+
+The focus on this example will be on the code that provides the custom
+geometry.
+
+.. image:: customgeometry-example.jpg
+ :width: 400
+ :alt: QtQuick3D Custom Geometry Screenshot
diff --git a/examples/quick3d/customgeometry/examplepoint.py b/examples/quick3d/customgeometry/examplepoint.py
new file mode 100644
index 000000000..97c323ff6
--- /dev/null
+++ b/examples/quick3d/customgeometry/examplepoint.py
@@ -0,0 +1,88 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import random
+
+import numpy as np
+from PySide6.QtGui import QVector3D
+from PySide6.QtQml import QmlElement
+from PySide6.QtQuick3D import QQuick3DGeometry
+
+QML_IMPORT_NAME = "ExamplePointGeometry"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class ExamplePointGeometry(QQuick3DGeometry):
+ def __init__(self, parent=None):
+ QQuick3DGeometry.__init__(self, parent)
+ self.updateData()
+
+ def updateData(self):
+ self.clear()
+
+ # We use numpy arrays to handle the vertex data,
+ # but still we need to consider the 'sizeof(float)'
+ # from C to set the Stride, and Attributes for the
+ # underlying Qt methods
+ FLOAT_SIZE = 4
+ NUM_POINTS = 2000
+ stride = 3
+
+ vertexData = np.zeros(NUM_POINTS * stride, dtype=np.float32)
+
+ p = 0
+ for i in range(NUM_POINTS):
+ vertexData[p] = random.uniform(-5.0, +5.0)
+ p += 1
+ vertexData[p] = random.uniform(-5.0, +5.0)
+ p += 1
+ vertexData[p] = 0.0
+ p += 1
+
+ self.setVertexData(vertexData.tobytes())
+ self.setStride(stride * FLOAT_SIZE)
+ self.setBounds(QVector3D(-5.0, -5.0, 0.0), QVector3D(+5.0, +5.0, 0.0))
+
+ self.setPrimitiveType(QQuick3DGeometry.PrimitiveType.Points)
+
+ self.addAttribute(
+ QQuick3DGeometry.Attribute.PositionSemantic, 0, QQuick3DGeometry.Attribute.F32Type
+ )
diff --git a/examples/quick3d/customgeometry/exampletriangle.py b/examples/quick3d/customgeometry/exampletriangle.py
new file mode 100644
index 000000000..aea789338
--- /dev/null
+++ b/examples/quick3d/customgeometry/exampletriangle.py
@@ -0,0 +1,225 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import numpy as np
+from PySide6.QtCore import Property, Signal
+from PySide6.QtGui import QVector3D
+from PySide6.QtQml import QmlElement
+from PySide6.QtQuick3D import QQuick3DGeometry
+
+QML_IMPORT_NAME = "ExampleTriangleGeometry"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class ExampleTriangleGeometry(QQuick3DGeometry):
+
+ normalsChanged = Signal()
+ normalXYChanged = Signal()
+ uvChanged = Signal()
+ uvAdjustChanged = Signal()
+
+ def __init__(self, parent=None):
+ QQuick3DGeometry.__init__(self, parent)
+ self._hasNormals = False
+ self._normalXY = 0.0
+ self._hasUV = False
+ self._uvAdjust = 0.0
+
+ self.updateData()
+
+ @Property(bool, notify=normalsChanged)
+ def normals(self):
+ return self._hasNormals
+
+ @normals.setter
+ def normals(self, enable):
+ if self._hasNormals == enable:
+ return
+
+ self._hasNormals = enable
+ self.normalsChanged.emit()
+ self.updateData()
+ self.update()
+
+ @Property(float, notify=normalXYChanged)
+ def normalXY(self):
+ return self._normalXY
+
+ @normalXY.setter
+ def normalXY(self, xy):
+ if self._normalXY == xy:
+ return
+
+ self._normalXY = xy
+ self.normalXYChanged.emit()
+ self.updateData()
+ self.update()
+
+ @Property(bool, notify=uvChanged)
+ def uv(self):
+ return self._hasUV
+
+ @uv.setter
+ def uv(self, enable):
+ if self._hasUV == enable:
+ return
+
+ self._hasUV = enable
+ self.uvChanged.emit()
+ self.updateData()
+ self.update()
+
+ @Property(float, notify=uvAdjustChanged)
+ def uvAdjust(self):
+ return self._uvAdjust
+
+ @uvAdjust.setter
+ def uvAdjust(self, f):
+ if self._uvAdjust == f:
+ return
+
+ self._uvAdjust = f
+ self.uvAdjustChanged.emit()
+ self.updateData()
+ self.update()
+
+ def updateData(self):
+ self.clear()
+
+ stride = 3
+ if self._hasNormals:
+ stride += 3
+ if self._hasUV:
+ stride += 2
+
+ # We use numpy arrays to handle the vertex data,
+ # but still we need to consider the 'sizeof(float)'
+ # from C to set the Stride, and Attributes for the
+ # underlying Qt methods
+ FLOAT_SIZE = 4
+ vertexData = np.zeros(3 * stride, dtype=np.float32)
+
+ # a triangle, front face = counter-clockwise
+ p = 0
+ vertexData[p] = -1.0
+ p += 1
+ vertexData[p] = -1.0
+ p += 1
+ vertexData[p] = 0.0
+ p += 1
+
+ if self._hasNormals:
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = 1.0
+ p += 1
+
+ if self._hasUV:
+ vertexData[p] = 0.0 + self._uvAdjust
+ p += 1
+ vertexData[p] = 0.0 + self._uvAdjust
+ p += 1
+
+ vertexData[p] = 1.0
+ p += 1
+ vertexData[p] = -1.0
+ p += 1
+ vertexData[p] = 0.0
+ p += 1
+
+ if self._hasNormals:
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = 1.0
+ p += 1
+
+ if self._hasUV:
+ vertexData[p] = 1.0 - self._uvAdjust
+ p += 1
+ vertexData[p] = 0.0 + self._uvAdjust
+ p += 1
+
+ vertexData[p] = 0.0
+ p += 1
+ vertexData[p] = 1.0
+ p += 1
+ vertexData[p] = 0.0
+ p += 1
+
+ if self._hasNormals:
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = self._normalXY
+ p += 1
+ vertexData[p] = 1.0
+ p += 1
+
+ if self._hasUV:
+ vertexData[p] = 1.0 - self._uvAdjust
+ p += 1
+ vertexData[p] = 1.0 - self._uvAdjust
+ p += 1
+
+ self.setVertexData(vertexData.tobytes())
+ self.setStride(stride * FLOAT_SIZE)
+ self.setBounds(QVector3D(-1.0, -1.0, 0.0), QVector3D(+1.0, +1.0, 0.0))
+ self.setPrimitiveType(QQuick3DGeometry.PrimitiveType.Triangles)
+ self.addAttribute(
+ QQuick3DGeometry.Attribute.PositionSemantic, 0, QQuick3DGeometry.Attribute.F32Type
+ )
+
+ if self._hasNormals:
+ self.addAttribute(
+ QQuick3DGeometry.Attribute.NormalSemantic,
+ 3 * FLOAT_SIZE,
+ QQuick3DGeometry.Attribute.F32Type,
+ )
+
+ if self._hasUV:
+ self.addAttribute(
+ QQuick3DGeometry.Attribute.TexCoordSemantic,
+ 6 * FLOAT_SIZE if self._hasNormals else 3 * FLOAT_SIZE,
+ QQuick3DGeometry.Attribute.F32Type,
+ )
diff --git a/examples/quick3d/customgeometry/main.py b/examples/quick3d/customgeometry/main.py
new file mode 100644
index 000000000..7b0fc7085
--- /dev/null
+++ b/examples/quick3d/customgeometry/main.py
@@ -0,0 +1,66 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+
+import os
+import sys
+
+from PySide6.QtCore import QUrl
+from PySide6.QtGui import QGuiApplication, QSurfaceFormat
+from PySide6.QtQml import QQmlApplicationEngine
+from PySide6.QtQuick3D import QQuick3D
+
+# Imports to trigger the resources and registration of QML elements
+import resources_rc
+from examplepoint import ExamplePointGeometry
+from exampletriangle import ExampleTriangleGeometry
+
+if __name__ == "__main__":
+ os.environ["QT_QUICK_CONTROLS_STYLE"] = "Basic"
+ app = QGuiApplication(sys.argv)
+
+ QSurfaceFormat.setDefaultFormat(QQuick3D.idealSurfaceFormat())
+
+ engine = QQmlApplicationEngine()
+ engine.load(QUrl.fromLocalFile(":/main.qml"))
+ if not engine.rootObjects():
+ sys.exit(-1)
+
+ sys.exit(app.exec())
diff --git a/examples/quick3d/customgeometry/main.qml b/examples/quick3d/customgeometry/main.qml
new file mode 100644
index 000000000..acd6bb7aa
--- /dev/null
+++ b/examples/quick3d/customgeometry/main.qml
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt for Python examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick3D
+import QtQuick3D.Helpers
+import ExamplePointGeometry
+import ExampleTriangleGeometry
+
+
+Window {
+ id: window
+ width: 1280
+ height: 720
+ visible: true
+ color: "#848895"
+
+ View3D {
+ id: v3d
+ anchors.fill: parent
+ camera: camera
+
+ PerspectiveCamera {
+ id: camera
+ position: Qt.vector3d(0, 0, 600)
+ }
+
+ DirectionalLight {
+ position: Qt.vector3d(-500, 500, -100)
+ color: Qt.rgba(0.4, 0.2, 0.6, 1.0)
+ ambientColor: Qt.rgba(0.1, 0.1, 0.1, 1.0)
+ }
+
+ PointLight {
+ position: Qt.vector3d(0, 0, 100)
+ color: Qt.rgba(0.1, 1.0, 0.1, 1.0)
+ ambientColor: Qt.rgba(0.2, 0.2, 0.2, 1.0)
+ }
+
+ Model {
+ visible: radioGridGeom.checked
+ scale: Qt.vector3d(100, 100, 100)
+ geometry: GridGeometry {
+ id: grid
+ horizontalLines: 20
+ verticalLines: 20
+ }
+ materials: [
+ DefaultMaterial {
+ lineWidth: sliderLineWidth.value
+ }
+ ]
+ }
+
+ //! [model triangle]
+ Model {
+ visible: radioCustGeom.checked
+ scale: Qt.vector3d(100, 100, 100)
+ geometry: ExampleTriangleGeometry {
+ normals: cbNorm.checked
+ normalXY: sliderNorm.value
+ uv: cbUV.checked
+ uvAdjust: sliderUV.value
+ }
+ materials: [
+ DefaultMaterial {
+ Texture {
+ id: baseColorMap
+ source: "qt_logo_rect.png"
+ }
+ cullMode: DefaultMaterial.NoCulling
+ diffuseMap: cbTexture.checked ? baseColorMap : null
+ specularAmount: 0.5
+ }
+ ]
+ }
+ //! [model triangle]
+
+ Model {
+ visible: radioPointGeom.checked
+ scale: Qt.vector3d(100, 100, 100)
+ geometry: ExamplePointGeometry { }
+ materials: [
+ DefaultMaterial {
+ lighting: DefaultMaterial.NoLighting
+ cullMode: DefaultMaterial.NoCulling
+ diffuseColor: "yellow"
+ pointSize: sliderPointSize.value
+ }
+ ]
+ }
+ }
+
+ WasdController {
+ controlledObject: camera
+ }
+
+ ColumnLayout {
+ Label {
+ text: "Use WASD and mouse to navigate"
+ font.bold: true
+ }
+ ButtonGroup {
+ buttons: [ radioGridGeom, radioCustGeom, radioPointGeom ]
+ }
+ RadioButton {
+ id: radioGridGeom
+ text: "GridGeometry"
+ checked: true
+ focusPolicy: Qt.NoFocus
+ }
+ RadioButton {
+ id: radioCustGeom
+ text: "Custom geometry from application (triangle)"
+ checked: false
+ focusPolicy: Qt.NoFocus
+ }
+ RadioButton {
+ id: radioPointGeom
+ text: "Custom geometry from application (points)"
+ checked: false
+ focusPolicy: Qt.NoFocus
+ }
+ RowLayout {
+ visible: radioGridGeom.checked
+ ColumnLayout {
+ Button {
+ text: "More X cells"
+ onClicked: grid.verticalLines += 1
+ focusPolicy: Qt.NoFocus
+ }
+ Button {
+ text: "Fewer X cells"
+ onClicked: grid.verticalLines -= 1
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ ColumnLayout {
+ Button {
+ text: "More Y cells"
+ onClicked: grid.horizontalLines += 1
+ focusPolicy: Qt.NoFocus
+ }
+ Button {
+ text: "Fewer Y cells"
+ onClicked: grid.horizontalLines -= 1
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ }
+ RowLayout {
+ visible: radioGridGeom.checked
+ Label {
+ text: "Line width (if supported)"
+ }
+ Slider {
+ id: sliderLineWidth
+ from: 1.0
+ to: 10.0
+ stepSize: 0.5
+ value: 1.0
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ RowLayout {
+ visible: radioCustGeom.checked
+ CheckBox {
+ id: cbNorm
+ text: "provide normals in geometry"
+ checked: false
+ focusPolicy: Qt.NoFocus
+ }
+ RowLayout {
+ Label {
+ text: "manual adjust"
+ }
+ Slider {
+ id: sliderNorm
+ from: 0.0
+ to: 1.0
+ stepSize: 0.01
+ value: 0.0
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ }
+ RowLayout {
+ visible: radioCustGeom.checked
+ CheckBox {
+ id: cbTexture
+ text: "enable base color map"
+ checked: false
+ focusPolicy: Qt.NoFocus
+ }
+ CheckBox {
+ id: cbUV
+ text: "provide UV in geometry"
+ checked: false
+ focusPolicy: Qt.NoFocus
+ }
+ RowLayout {
+ Label {
+ text: "UV adjust"
+ }
+ Slider {
+ id: sliderUV
+ from: 0.0
+ to: 1.0
+ stepSize: 0.01
+ value: 0.0
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ }
+ RowLayout {
+ visible: radioPointGeom.checked
+ ColumnLayout {
+ RowLayout {
+ Label {
+ text: "Point size (if supported)"
+ }
+ Slider {
+ id: sliderPointSize
+ from: 1.0
+ to: 16.0
+ stepSize: 1.0
+ value: 1.0
+ focusPolicy: Qt.NoFocus
+ }
+ }
+ }
+ }
+ TextArea {
+ id: infoText
+ readOnly: true
+ }
+ }
+}
diff --git a/examples/quick3d/customgeometry/qt_logo_rect.png b/examples/quick3d/customgeometry/qt_logo_rect.png
new file mode 100644
index 000000000..129b873d5
--- /dev/null
+++ b/examples/quick3d/customgeometry/qt_logo_rect.png
Binary files differ
diff --git a/examples/quick3d/customgeometry/resources.qrc b/examples/quick3d/customgeometry/resources.qrc
new file mode 100644
index 000000000..dc55e9ddd
--- /dev/null
+++ b/examples/quick3d/customgeometry/resources.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>qt_logo_rect.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick3d/customgeometry/resources_rc.py b/examples/quick3d/customgeometry/resources_rc.py
new file mode 100644
index 000000000..37fad6284
--- /dev/null
+++ b/examples/quick3d/customgeometry/resources_rc.py
@@ -0,0 +1,584 @@
+# Resource object code (Python 3)
+# Created by: object code
+# Created by: The Resource Compiler for Qt version 6.2.1
+# WARNING! All changes made in this file will be lost!
+
+from PySide6 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x09=\
+\x00\
+\x00#\x91x\x9c\xe5ZQo\xdb8\x12~\xf7\xaf\x98\
+\xcb\xf5!\xd9s\x14'\xdd\xf6z>\x1c\x0e\xb2\xad$\
+\x02\x1c\xc9\x91\xe4\xa4\xc1bQ\xc8\x12ms+\x8b^\
+\x89\x8a\x9b-\xf2\xdfo\x86\x92l\xd9\x96\x9d\xa6M\xf6\
+p8\x22\xb0-r8\xf3\xcd\xcc\xc7!\xa9\xf6\xe4\xa7\
+\x17l\x0d\xf5\x07]1\x7fH\xf8d*\xe1\xb0{\x04\
+g\xad\xb3\x16xS\x06\xd7\x12Gfs?~\x80\xbe\
+\x0c\xb5\x5c2\x96~ \xdb0\x95r\x9e\xb6ON\x16\
+\x8b\x85\xf6\xbb\xd4\xb88\x89x\xc0\xe2\x94\xc7\x93\x93B\
+\xab7\xe5)\x8cy\xc4\x00\xbf\xe7~\x22A\x8cA\xa2\
+^\xf6\xc5\x9f\xcd#\x96\x96\xcfh\xc7\x13\x22\xfa\xcc\xa5\
+VL}s\xed}\xea\x18\x17\xa6\xf5\xa9ov\x0d\xcb\
+5\xda\x1d\xb7\xf7&\x070\x9b\xb1$\xe0~\x04}e\
+\x90\xc10\xf5'\x8c\xc6\x8a\x0eT<\x15Q\x88H\xe0\
+\xde\x8fx\x08\xc1j\x0e\x9a\xcaq\xa2\xd0\xcc\x7f\x80\x0c\
+\xe7\xcb\x15\xce\x98\xd4\xf8A \x92\xd0\x8f\x03\x06\x0b.\
+\xa7\x0abEE1\x1f\xfcI\xc2\xd8\x8c\xc5\x12\xe6\x89\
+\xb8\xe7!\x0b\x97\xe2\xa4\xc5\x15c\xb9\xf0\x13\x06\x22i\
+\x82\x1fI\x96\xc4\xbe\xe4\xf7,zh\xa2\x9dZ#(\
+3K\xd1\x14\x86\x98\xc7\xa8\xae\x80\x03\x8b\x84K\xc9\xe2\
+\x8a\xc5\x11\x93\x0b\x86=\x0f\x22\x03?\x0e7\xb2\xa5\xc1\
+\xb9H`\x99\x8f\x5c\xafR\x15S0\xe2\x90K.\xe2\
+\x140T5yT\xd2\xc7+\xb1\x5c\xdb8K\x10b\
+BZx<\x16\xc9\xcc\xa7\xc1\x22~,\x07\x1dH\xa0\
+\x11\xf0e\x8d\xdaB\xe28K\xcb$cJ\xb7s\xa8\
+\xafG\x8a\x1c\xdc\xceS\x16\x87,\xa9\x84\xac\xe0\x11)\
+,\xb2\xa3\xbcEi\x11Eb\x91\xb6\x0b\x8b\x07\x0e\x0b\
+y*\x13>\xca\x14z\x8a\x07i\xc6|\xa4\x22K0\
+\x17\xd43\xe2\xb1\x9f<(W\xd2f\x9e\x1d\x0c\x00}\
+\x8bL\x92\x9a\x99\x08\xf9\x98\x07*\x02\x98[\xcc\xf1\x1c\
+aP\x8e\xc2\x15\x17\xe4\x14\xc3@\xa8r\x0c\x94\x87J\
+\xe8q\x92\xd2\xc4$a\x03\x80\x9f`\x1d\x9br\xaa\x00\
+\x15\x88\x90\xc1,K%$\x8c\xa8\xa1\xd4\xfa#qO\
+C\xc5\xca\xcd\xb5\x00\xc4Bb\x04\x9ay\xb0\x22TH\
+z\xaa\x86\xe3p\x03\x15Z\x0d\x22\x9f#\xbd\xb5]P\
+\xd0d%(%\x14t5\xcc\x02\xf6Zh\x0a\xfaS\
+#\x91P\x04\x19q\xdf/3w\x82I\x11\xc4I$\
+\x08\xd2\x00\x97fZ\xbf\x12\xa9U\xfdY\xbai1\xae\
+\xe6\x93\xfa\xd8\x9f1\x02\xb7]\xf7\xd0\x89\x95\x88J\x0b\
+\x97i\xa9\x97X\xad\xf4\x8a$/(#F\x8cB\xaf\
+\x04\xb08\xc4^*\x00\x84k&$\x83<d2\x05\
+\xe4/2<,\xd5\x8cq<\x0fRZ\x96\x8d\x82o\
+\x90\xceY@l\xc3\xb9\x9chX\xd4\x02\xc5\xb84-\
+\xdc)+\xee\xa5\xe9\x82k\x9f{\xb7\xbac\x00\xfe\x1e\
+8\xf6\x8d\xd93z\xd0\xb9\xc3A\x03\xba\xf6\xe0\xce1\
+/.=\xb8\xb4\xfb=\xc3qA\xb7z\xd8ky\x8e\
+\xd9\x19z\xb6\xe3\xaae\xa2\xbb8\xf9@\x8d\xe9\xd6\x1d\
+\x18\x1f\x07\x8e\xe1\xba`;`^\x0d\xfa&\xeaC\x03\
+\x8eny\xa6\xe16\xc1\xb4\xba\xfda\xcf\xb4.\x9a\x80\
+:\xc0\xb2=U\x8c\xcd+\xd3CI\xcfn*\xd3\xdb\
+3\xc1>\x87+\xc3\xe9^\xe2\xa3\xde1\xfb\xa6w\xa7\
+L\x9e\x9b\x9eE\xe6\xcemGU\x04\x18\xe8\x8egv\
+\x87}\xdd\x81\xc1\xd0\x19\xd8\xae\x01\xe4_\xcft\xbb}\
+\xdd\xbc2z\x1ab@\xbb`\xdc\x18\x96\x07\xee\xa5\xde\
+\xef\xaf\xbbKz\xec[\xcbp\xc8\x87\xaa\xbb\xd01\x10\
+\xa9\xde\xe9\x1bdNy\xdb3\x1d\xa3\xeb\x91[\xab_\
+]\x0c\x22\x82\xec7Ue\x1f\x18]\x13\x7fc\x5c\x0c\
+tJw\xee\x9a\x85Z\xd7\xb8\x1e\xa2\x1c\x0eBO\xbf\
+\xd2/\xd0\xc7\xc3\xa7\xa3\x83I\xea\x0e\x1d\xe3\x8a\xb0c\
+H\xdca\xc7\xf5Lo\xe8\x19pa\xdb=\x15v\xd7\
+pnp#t\xff\x09}\xdbU\x81\x1b\xba\x86\x02\xd3\
+\xd3=]\x99G-\x188\x94\xc0\xdf\x9d\xa1k\xaa\x10\
+\x9a\x96g8\xcep\xe0\x99\xb6u\x849\xbf\xc5\x08!\
+R\x1dg\xf7T\xacm\x8b|\xce\xb9c\xd8\xce\x1d\xa9\
+\xa6x\xa8l4\xe1\xf6\xd2\xc0~\x87\xc2\xab\xa2\xa6S\
+8\x5c\x8c^\xd7\xab\x8a\xa1I\x0c\xa6rl\xe5/X\
+\xc6E\xdf\xbc0\xac\xaeA\x026)\xba5]\xe3\x08\
+\x93g\xba$`*\xe3\xc8\x084;T\xbeS\xd2\x10\
+\x9bJ\xd7\xf9:\x9d\x9b*\xbb`\x9e\x83\xde\xbb1\x09\
+\x7f!\x8f|p\xcd\x82>*|\xdd\xcb\x22\xfa\xdaA\
+\xe58aX\xbd\xf20\xf1&\xef~\xb9v\xd2h\xf0\
+\xd9\x5c\xe0\x09\xe7Z^g<\xf8\xbc\xf1\xa8\xd1\xb1)\
+\x11Q\xba\xd9\xdf\xf7q\x83\x93\x9b\xddo{[\x1d\xda\
+%\x8bp\xc9/%\x8d\xfc\x085\x10<\x96\x17L\xe0\
+>\x92<l\x8cyX\x12\xe3I\xc4\x96\xc3\x8d\xc6-\
+\xc7\x92\xb4\x80\xaf\x0d\xaa9<lc\x91\xa1\x0e\xf5\xb8\
+\xe0\xa1\x9c\xb6\xe1\xf4\xecCK=O\x19\x15\xf26\xfc\
+\xfd,\x7f\xbe\xe7)\x1fE\xac\x0d2\xc9X#\xaf}\
+\x91H\xdap\xf0\xd7\x0f?\x7f\xf8\xf0\x8fw\x07\x0d\xd5\
+{\xc3\xd9\xe2m\xaf\xb0Q\xda\xb9\x7f\x1b.\x9f\xf1\xcc\
+3\xc5\xba\xa8\xe1N\x1e\xb5\xe9\x5c\x88E}9\x18`\
+\x8dM\xfcv\xf1\xddX\xf6\x0f\xd0w,\x84t,\xe8\
+\xaa\xa1\x8a\x81\xd2H1\xa7\xda=\x17\xa9\xdai\xda\x18\
+I\xed\x1e\xe7\x8b\xe4mx\xd8j\x02\xfe\xbdo\xb5\x8e\
+\x96\xc2\x8f+S=\x9e\x90!\x11\xfbQ_\x9d\x89\xbf\
+~\x83\xca\xe3w-T\xa9>\x8eO\xab\x8a+\x81B\
+\xf9d2\xf2\x0f[\xda\xcf\x08@;\xa3\x8f\xf7M8\
+\xd56\xc4\xfd\xd9\x88cL\xba\x9b\xb3NiB\xf9\xb1\
+6\xab\x82^1\xe2\xdbq\xe7\xa1x\x1aqn\xb1\xce\
+\xf6>\xc4gK?\xcfv#\xbe\xc2\xd3M\xb4\x01v\
+I\xb6\xc4\x0f\xb9\xb8HxH,\xd6\x82)\x0b>\xb3\
+pM4\x0d|\x12\xac:u\xda\xca}\xaaqlR\
+,\x866\x94J\xe9i\xc3:5\x22\xd4\x04E\xb6\x06\
+\x90\xbb\xfc\x0f:\xcb\x22;b\x96\xb6\xa1X\x1fk\xf0\
+Y\x82\xe7\x9e]\x12\x8fkO\xcb\xc3K\x1b~\xd9R\
+\xd4cc?\x8b\xe4U!S\x83\x93Z\x84fn\xf3\
+\xe5\x9b\xe2}\x87%\xfd\xb2C\xc3\x0bP\xb1Zw#\
+\xf8\xb5.+''\x7f\x81_f*5\xb2($\xbf\
+>#e]<\x22\xbex\xcav\x14\xb6\x9a\xa8\xc4t\
+A\xa1\x90\x06#\x0b\x7f\xd6\xa2X\xc9}\xbc+\x03\xa7\
+\x84\xebc\x96\xdd\x93\xb6\xe1\xcdN]\xd9\xbd\x1e\xfe\x86\
+n\x97\xbaPt[\xd3\x8b\xe7\xdec_d\x86\xc7\xc5\
+\xfaQj\xc4\xe4\x91\x9f2\xb5:\xaf\xfc\xf9N\xc1\xfc\
+\xb6\x81\x05\xfdw\xf9)\x12\x13\xf1\x89\xea\xa06\x8f'\
+\x07\xb5S\x1ek{\x83,\x8a\x88\x1e\xedM\xfc\x9a\x85\
+\xa4\x88\x90\xaa\x93\xdayx\xa3\x1a\xe3\xc1\x19\xf1Q\x98\
+\x0b\xaf\xcaX\xc3\xbf\xd7<\x806\xc4\xa8\xaaV\x0f\xed\
+\x12Y\xe4'\xfaLd1\xe6\xa2\xa5\xbd{\x06\xfd\xcb\
+_\xb5\xec\x7f\x06\xfd\x97\xfb\xf2k\xf0\x7fm\xd3\x87\xaf\
+\xafQOp\xfb\xc0D\xd5\xe5\xb0_\x8c\xbdF\xf2\x8b\
+\xfd\xe3\xe0\x81\xd1m\xb0\x9eusr\xde\xe5\x7f\xb0r\
+\x99\x0d\xca\x8eg\xd7\xba\xfcS}\xdd\xfaiX\x9c\xd1\
+\x22\xbc\x10\xae\xc2\x12\x94\x9d\xa1=\xfa\x8d\xd1\x8b\xaf\xca\
+)\xa3\x98\x8c\xb0\xb3Y\x9c\x1f\xe5*S\xfb\xfeh\x8b\
+%\x12y\x8d\x0e\x0e\xf1Vx\xab\xbb=u\xffE\xa2\
+\xd2\xcb\x0d\x81\xf7\xcb{>\xc1\x80\xad;>F\x04\xda\
+HDa\xe5\xe4\xb5\xeeW'\x93R\xc4\x17\x89\xc8\xe6\
+\x1b\xe6Fj\x84\x98\xb0\xbe\x916\xd7\x8bts\x83\xb4\
+\xb5K\xc2!\x91\xdcT\xcd\xd9kM}\x9d\xcb\xd5\xed\
+v\xdd\xc1b\x85l\xb8\x97\xbb\x1ed\xe9@D<x\
+P\xab\xc5\x12\xe7\xd4\xf3}\xe0Jg\xeb\xc0\xd1\x18\xba\
+]\xae\xb4\xfc:\xee\xcf\xe7Q\xf1\x92\x07\x0e\xcb*p\
+\xb4\x03\xfb\x18\x17\xdc+\x82_\xa6\xe6\xfb\xd0\xabE\x93\
+\xbe\x0av\xb1\xd8\x22>\xb5g\x1c\xe0v,\x9f\xb2\xd5\
+\x06f#\x02W\x02w\xc0\x8f\x10`\xddH\xeb\xcb\x86\
+\x88\xbb\xe8\x8dr\x97Nu\xda\xda\x09\x0d\xfe\xf6/8\
+\xad\x9d\xf6T \xb6\x03\xb2\x01{?\xees\xb6\xc0j\
+\xf3\x03\xc0\x8f_\x16\xf8\xe3\xab$\xe6\xee9\xfem\x1c\
+\xaf\xff\xcb\xa9\xf9!\xe8\xaf\x96\x9c\x17]~u\xdbT\
+%\x0e\xe4J\xfen\x00\x0e\xf9\x18\xd2lN\xef\x18X\
+\xb8QL\xd6\xa1\xbajg\xdeq\xab\xda\xb8\xa2l\xc9\
+P\xf9j\xd3mq\x1b\x92\xc0\xfeV\xcd@*\xd9<\
+?\x13\xd4\x1d\xf7\xd4\xb9\xa0^\xe3\xb7d\xe2\xfb\xe3\xbe\
+\xf7\x12\xd4\xa5\xbe\x8e\xf8\xb2#J\xf9\xc5eWV\x8a\
+\xf7\xdc\xe5=\x87^\xd0Oj7Wj{\x0a\xfd\xf3\
+c\xb0\xcf{j\xbb\xe8T\x01?\xf3\xe3\x0c\xcf\x9e\xbe\
+\xba-m\xc3\xdd^\xb0;\xe9DmE\xa9\xda\x80)\
+\x0f\x15\xa3\xea\x88\xa3P\x89znP\xab\x12\xabU\xbf\
+\x98\x0bv\xed\xd2\xfeg\xaf\xf5\x1f\xe3\x5cq\xef\xdaE\
+;\x16\xfbhI\xdd\xc5\xf2WDx\xdb\x98\xff\x09\x84\
+{\x12\xf7\xf0\xe6\xa9\x952\xbc\xf9\xdfZ$\x88\xf7\xc5\
+\x17HM\x94\x94o\xffG\xcbc\xff\xc5\xfc\x89\x13\xcf\
+\xbe\x94R\xdb\x97VjEj\x15\x06H1n{\xb7\
+\xd4z\xd7\xcb\xb67\xe5\xd4Vi_\xde\x90w\xca\xee\
+\xder\x97\xd0\x89\x05\xef\xf7\x08\xac\xa8\xb0O\xcd\x9e\xad\
+x\x89\xe5\x1b\x19Am;4O\xf3\x84J\x9c\x9e\xb0\
+\xba\x7f@\xa0\xff\xd8@\xc3k\x03(\x1a\xdaq\xf4P\
+{\xfd~l<6\xfe\x03q\xb68\xeb\
+\x00\x00\x18\xaf\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x01_\x00\x00\x01)\x08\x02\x00\x00\x00\xbb\xac\xb6\x0a\
+\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x04gAMA\x00\x00\xb1\x8f\x0b\xfca\x05\x00\x00\x00\
+\x09pHYs\x00\x00\x0e\xc3\x00\x00\x0e\xc3\x01\xc7o\
+\xa8d\x00\x00\x18DIDATx^\xed\x9d\xffk\
+\x14\xd7\xfa\xc7\xef\x7fT\xb8\x5c\x8a\x88\xc8m)Wi\
+S\x09%\x10h\xa9\xd4\x22\xc1\x82\x12\xb0\xa2\x1fR\xa4\
+\x85\x16,---T\x0a\xf9A\xa1\x22\x96\xa2PA\
+\xc1R\x11\x94\x16\xb1\xb9\xc1\xa61,!JZcX\
+B\x1aC\x88\x12\x97\xdc\xe0\xe7=\xf3\xec\x9eLf\x9f\
+]\x93\xcd\x99|\xf3\xf5\xf0b\x98\xcc\x9eo\x1b\xe6y\
+\xed9\xb3\xbb\xb3\xff\xf8w\xff\x1b\x00\x00\xf5`\x07\x00\
+\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\
+\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\
+\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\
+\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\
+\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0f\
+v\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8\
+`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\
+\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\
+\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\
+\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\
+\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\
+\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\
+\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07\
+;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\
+\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\
+\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00\
+|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\
+\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\
+\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\
+\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\
+\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\
+\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\
+\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\
+\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00\
+>\xd8a}i\xaf;\x02\xab\x81\xffgL\xb0\xc3:\
+\xc2\xa9\x1c\x1d\xfe\xa51\xc1\x0e\xebE\xf5<\xde\xd9\xb7\
+g{_\x1b\xac\x92\x1d}m\xb5\x7f)\x82\x88\x06v\
+X/\xda_\xee\x7fcG\xdf\x9e\xd7n\xbf\xb5o\xa8\
+{\xef\xd0Ah\x19\xfd\x03;\x07\xbb^\xee\xef@\x0d\
+q\xc1\x0e\xeb\x82\xa9\xa1\xad}\xe0\x9d\xdfg\xef<%\
+V\x1dw\x1f\x8fv\xfc\xf1\xael\xab\x7fl\xdd\x7f\x1b\
+Z\x04;\xac=\x8b\xb3\x86[3\xfd:\xb3\xe7\x9f\xce\
+/<]\x80\xd6\xa8,\xcc\xeb\x7f88[zc\x00\
+;D\x06;\xac1\x89\x1av\xf6\xed\xd9u\xbb\xf3\xc6\
+\xf4\xcdD\x0d\x0b\xff\xd3Vg\xb9\xb6D\x0ba\xff\xc0\
+\xa1\xd9a\xec\x10\x1d\xec\xb0fhI\x9c\xaa\xa1\xbf\xfd\
+\x95\xfe\x8e\x9f\xa7\xae\xdb\x99\x1d^\x03\xd3S\x9dXq\
+`\x87\xe2\xc0\x0ekFU\x0d\xda^\x9e\xbcj\xa7\xb5\
+I\x015\xac&\xb0Cq`\x87\xb5!\x91\x82M\x1f\
+.N^\xb1s:\xa8\x01;\xac&\xb0Cq`\x87\
+5\xa0\xfa6\xdb\xce\xbe=\xdf\x97\x7f\xd4\xa9\x1c\x8c\x80\
+\x1aV\x1f\xd8\xa18\xb0C\xd1T\xd5\xb0\xbd\xaf\xedl\
+\xf9\x82\xcec\xbc\x107\xb0Cq`\x87BI\xd4\xa0\
+\xf3u[\xdf\xab\xa7\xc6\xcf\xe9$\x0eR@\x0d\xb1\x02\
+;\x14\x07v(\x8eE5\x9c\x1c;\xad3\x185\x14\
+\x11\xd8\xa18\xb0CA\x045\xec\xfe\xea~\xaf\x9d\xc7\
+A\x0d\xd8!b`\x87\xe2\xc0\x0eE\xf1r\x7f\xc7\x8b\
+}\xbb\xbf\xf8\xeb[;\x89QCA\x81\x1d\x8a\x03;\
+\x14A\xbb\xd4\xf0\xaf[\xff91\xfau\x90\x82mQ\
+C\xf4\xc0\x0e\xc5\x81\x1d\xe2\xa2\x05EU\x0d\x1f\x8f~\
+YY\xa8\xe8\xc4\xcd\x0a\x82\x88\x1e\xd8\xa18\xb0CD\
+\xecZC\xa2\x86\x0f\xee}\xfaxaNgm\xa1j\
+P\xb3\xa1\xfd\x1c\xf35r\xc7\x85\x95O\x1b\xd8\x0a\x81\
+\x1d\x8a\x03;\xc4\xa2z\x19\xf2\xc5\xbe\xdd\xc7F>\x99\
+\x9d\x7f\x94\x9c\xb8\x85\xa5bHr\xa1\xf4\xb0\x0cYN\
+$\xe5\x95P\x19M\xd8\xce\xe6\x0d\xecP\x1c\xd8!\x0a\
+\x89\x1a\xc4\xf6\xbe\xb6\xee\xe1\xe3\xd3\xf33\xe1\xacU\xc4\
+M\xbf\x90\xd5\x89\x14\xe4\x9fZh\x15\xf3wejl\
+n\xfc\xee\xe3\xd1\xe1\xc7#\xca\x96\xc1\xd9\x92\xb6\xda\xd7\
+\x11\x1d\xd7\xa3s\x0bO\xaa\xa5\xd3\xe1\x89\xd0\x9a\x1d\xdc\
+\x8c\x81\x1d\x8a\x03;DcG_[\xe7`\x97\x920\
+9ekY\x171\xf1Bk\xda\x06\xf5LT&\x7f\
+\x9d\xfe\xedl\xf9\xc2\xc7\xa3_\x1e(\x1d\xed\x18\xdc\xaf\
+\xa5\x8d$\xa5\xd5\xcd?o\xbd\xa2\xed\xf6\xbeW\x950\
+\xca\x9c\xae\xd2\x91\x0f\xef}\xfe]\xf9\x87\x1b\xd37%\
+\x0b\xab\x9e\x15\x84\xed,3\xb2\xb5\x9a\x10J\x16\x17\xd8\
+\xa18\xb0C4\x94\x93\x87\x86{\xc2\xf9\x1a7+B\
+kaGS\x83\xaf\xee\xf7*\xe7w\xf6\xedy\xe1\xd6\
+KZ\xd1h\x00\xda\xd7H$\x88Wjh_Gv\
+\xf6\xb7\xebQ\x95\x912\xb4\xb3o\xa8\xfb\xb3?\xbf\xb1\
+{\xcf(B\x1a\x1bv\xf0\x99\xb1\x9c\x92\xcbo\xad\xe5\
+\xc0\x0e\xc5\x81\x1d\xa2\xa1\xac;8\xfc\x7f:SW\x94\
+c\xcb\x09k-4;\xfe\xa4\xac\x99\xc2\xeb\x03ok\
+j\xb0-\x9d\x1a\xec\xba\xdd\x99\x8a \xb9\xf0\x91\x1b\x95\
+a\x0f\x995lr!M\xa8\xd6\xb1\x91O\xb4\xf4\xc8\
+6n\xfb\xb6\xd3$\xac\x8c\xb6\xe5\xca\x84f\x22\x1aR\
+\x16[\xc8\x842i\x8d\xa2\x02;\x14\x07v\x88F\xb0\
+\x83\x9d\xaf\xb1\x22\x97c?M]W\x1aH\x0a\xca\x84\
+05\x08\x17>\x96A\xf5\xea\xa9\xeaj\xa2\xa1v^\
+\xbb\xfd\x96}sT\x11zyfJ[\x01=SM\
+C\xd4\x82T\x15h\x1fxG\x8d\xcb_\xd9wm\x8a\
+\x0b\xecP\x1c\xd8!\x1aE\xd8\xc1R+$\xd8\xd9\xf2\
+\x05\xf5b9PK\x83\xe5{!\x8f5\xa2E\x87\x1c\
+\xa1E\x8a\x0d;\xd7c\xa3\xb0\x02\xaa\x12T\x15\xd0\x90\
+41\xd1\xac\x04;lv\xb0C4\x8a\xb3\x835(\
+5(\x0f\x95\xcc\xb5\x1e\xeb\xbdP=bi\x1f\xc8=\
+\x9aa\xb1\xbc\x16)\xd9\x0f}/\xdf\x0e\x9d\x83]v\
+\xb1#\xa0\x89\xc3\x8b}\xbb{\xee\x9e\xc0\x0e\x9b\x1d\xec\
+\x10\x8d\xe8v\xa8f`\xfa\xb6\xe5\xb5\x87\xbf(\x99k\
+j\xf0\xf3<uA\xf5\x1a\xe4\x8e\xdao\xc0\x84\xeb\x94\
+\xb5\xb4q\xeb&\xb7\xae\x92zrw\xa0\xd0\xb6Q\x04\
+;t\x0c\xeeO\xe7\x0b\x8b\x0db\x87-\x03v\x88F\
+\x5c;\x84\xf4\xd3vln\x5c/\xd1j?M\xfel\
+z'\x89m\xfb\xe1]\x09\x95\xe9\xf8\xe3\xdd\xfd\xa5\xc3\
+\xdd\xc3\xc7\xb5U\xf6Z\xbano6\xef\xb0?\xdbw\
+\xdd\xee\x0c\x17)\xc3\xd6\x0d\xec\xf0<\x80\x1d\xa2Q\xc4\
+\xdc\xc1R\xeb\xab\xfb\xbd\x9a\xf9+\xeb\x96f\xb5\xf6\x93\
+?\xcd\x0b\xaf\x0f\xbc}b\xf4\xeb_\xa7\x7f\x1b\x7fR\
+\x9e\xa8LN\xcf\xcf\xcc\xce?\xd2V\xfb:\xd2?3\
+\xa0\x85C\xfb\xc0^\x9bM\xa4)\x94\x17\x84\x0e\xaa\x1d\
+9%t\xdd$\xb1\xed!\xec\xb0\xb5\xc1\x0e\xd1\x88h\
+\x07\xcbL\xfbH\xd5\xe0l\xc9\xbcP\x97\xd2U5h\
++}\xd8g\xb7\x9b\x87\xd2\xb5\xf7\xc1\x19M.jY\
+\x94\x13D\xd2\x9a\xfa\xd2*F\x85\x9b?\x0b\xec\xf0<\
+\x80\x1d\xa2\x11\xdd\x0e\xb6\xd3`\xe2\x90\xa0d\xd6\x94\xc1\
+~5\xc7\xc2*\xbaTK<}\xaayD\x9a\xd2\xf5\
+\xeb\x94\xe4\xf2\x84\x12\xfb\xd8\xc8'*\xa6g\x91\xab\x98\
+\x0d;\x8e\x1d\xb66\xd8!\x1aE\xd8\xa1\x5c\x99x\xed\
+\xf6[\xf5^HI.R\x86\xd7y\xabb\xb5lk\
+;\xe1\x88a\xd78%\x88]\xb7;\xebf\x10\xc9\xf4\
+D\x07e\x1c\x15P\xb1&O\xc4\x9a\xc5\x0e[\x1b\xec\
+\x10\x8d\x22\xecpe\xea\x9a2mi\x0e'\xfb:\xb2\
+\xadv\xbbJ\xeb.Ti\x14\xf6\xa8\xb6V\xfe\xbb\xf2\
+\x0f\xb6*\xc9\xa1\xdc\xd6T\xc5\xee\x91\x9b\xfd\x81O\xab\
+\x9b%)\xb0<;4\xc1\x0ah\xdbr`\x87\xe2\xc0\
+\x0e\xd1\x88k\x07\xdby\x7f\xe4\xa3\x5c\xee\x19J\xec\xf6\
+\x81w\xec\x1b_\xd9Lk\x1eV\xc6\xb6\x95\x85\xca\xde\
+\xa1\x83R\xccR\xf5\xc8;In\x87o\x9a\x86\x96\x1b\
+\xb5\xdf\xc4\x0ev\xf3\x9b\xe6\xd1\xa8\xd9\xe5\x07v(\x0e\
+\xec\x10\x8d\xe8v\x98\x9d\x7f\xa4\xf9\x7f\xdd+|r\xe1\
+P/\xef\xbd\x0f\xce\x84\xc2\xcb\xcf1+i\xeb\x0b\xb5\
+\x90~\x1abI\xfb&\x0b-g\x94oI\xc9\xf4\xb9\
+X-m\xe7\x16\x9ehF`h_#\xec\xf8\xe3\xdd\
+\xdc\xa7\xa1\xc2\xc5\x8b\x87\xf3\xd3\x12D(\x9fC\x0f\x85\
+f\xb5m9\xb0Cq`\x87hD\xb7\xc3\xaf\xd3\xbf\
+\xa5\xa9\x9b\x9f\xff+\x01\xa4\x8c\xc1\xd9\x92\x954\xd2z\
+\xcb\x8aP~ln\x5c\x16\xc8\xe5\xb6\x90}\xfey\xeb\
+\x15-jTF\xcf%\x94\x97\x0b\xbaJG:\x07\xbb\
+\xde\xbc\xf3^\xa0\xfe\xd2\xa6\xd0\xf0\xe4\xb5l\xb1,\x9a\
+\xb3(\x93\xbf\xf8\xeb[9\xc2\xc6\xa3m\xcb\x81\x1d\x8a\
+\x03;D#\x96\x1dB6\x9e\x1c;\x9dN\xdas\xaf\
+\xed\x1d\xdb\xfb^=4\xdc\xa3Wf+\x9cVZA\
+X\x15\xdb\x1e(\x1d\xdd\xd1\xd7\x96m_\xdd\xd9\xdc\xe4\
+\xab\xfb\xbd\xa1\xa4\xed\xc8\x0e\xb2\x89}\x9a[N1j\
+\xc3\xcb\x0e\xb2z$\x94\xc9\xa1G\xd5~\xac\xcb\x96\xd8\
+\xa18\xb0C4\x22\xce\x1d\xac\x05-\xfe\xd5\xe6\xd2^\
+\x92\xd4\xd5\x0b\xbb}'\xc2\xf2\xb6\x85\xec\x0a\xb5R\x01\
+\xe5\xbaH\xe6&\xeaW\xbd\xdbg(Ba\xfd\xf9\xfa\
+\xc0\xdb^\x06\xe6\xe7\x0e\xde\x91E\xf4\x14\xa4\x98\xdc\xad\
+7[\x0e\xecP\x1c\xd8!\x1aq\xe7\x0eB\x93\xf0:\
+;T\xa7\xfd\xe7'.\xa9\xa4\xbd\xa7`\xb5V\x14\xd6\
+\xbev\xae=\xfc\xa5\xd6\xc5b>+\xc14;P\xb2\
+\x95+\x13\xd9\xc25;\xe4\x87\xb4R\xec\xc2\x04v\xd8\
+\xf8`\x87hD\xb4\x83\xb6cs\xe3\xed\x03\xef\xe4R\
+1=\xf5\x93%\xbd\xdd\xd6\xa9\xe5\x8eB\xc2\x8f?)\
+\xa7\x8b\x97\xc5.\x0cK\xe0\xbb\x8fG\xb3\x85\xb1\xc3\xf3\
+\x06v\x88F,;\xd8\x07\xa8\xfbg\x06\xb4\xc8\xcf\xa5\
+\xaeN}%\xa7\xe6\x14\x96\xb7vC\xfa\xb4\xd2\x8a#\
+$\xbc\x1cT\xff\xb6\x88\x12\xf8_\xb7\xfec\x0e\xca\xda\
+\xc1\x0a\xeb\xd1\x80\x95_Z\xbdz$[,\x8b\xec\xb6\
+\xbd\xef\xd5\x0f\xef}\x8e\x1d68\xd8!\x1a\xd1\xec\x90\
+V\xbf<yU\x8b\x88\x5c\xde*\xb5\xb4b\xdf_:\
+<Q\x99T\x99\xd5\xe4\x95\xd5U~\xaa\xb5\xfa\xa4\xd2\
+\x9fzy\xbf8y\xc5J\x06;(\xb1e\x0d\x8d!\
+PSCv\x9c\xc9\xfe\xce\xf4\xc6S.\x12\xdc\x0b\xb7\
+^\x0a\xf7\xf5\xc7\x0e\x1b\x16\xec\x10\x8dxs\x87\xe4\xc3\
+\x08\xb5\xcf2\xe6\xed\xa0\xa4\xed\x1e>\xbe\xfaW]\xab\
+[Y\xa8(K5\xf2z;(\x8d\xb3\x1f\xa9\xd0V\
+\x9d\xbe?\xf2QW\xe9\xc8\x81\xd2\xd1\x80\x14\x96\x1b\xa4\
+\x90\x1a\xda\x07\xf6f\x8be\xd1\x7fi\xdfP\xb7\x1a\xb7\
+;\xe8c\x87\x0d\x0bv\x88F\x14;(U\xac\xfa\xc9\
+\xb1\xd3j0\xd7\x85RQ/\xdd\x9a\x93[\xc9\xd5\xe4\
+\x95\xd5\xd5\xf6\x8b\xbf\xbe\x95\x08\xe4\x9dlG\xca1M\
+\xfe\xf5P(f\xdb\xbf+S\x9a\xb6hkh_9\
+ioR\x064H)L\x83,W&r\xe5\x03:\
+8=?\x93m\xbc\xe5\xc0\x0e\xc5\x81\x1d\xa2\x11k\xee\
+PYH\xe6\x0e\x9f\xfd\xf9\xcd\xb6\xea7,\x02\xd5\xb7\
+3O\x8c~m\xc5V\x93W\xa1\xee\xa9\xf1sJf\
+\xcf\x0em\xca\xf0\x90\xc0\x8d\xfa\xea\x1c\xecRNf\xeb\
+\x9a\xc2l\x90\xcf\x8c\xd5<\x05\x0b\xecP\x1c\xd8!\x1a\
+\xb1\xe6\x0e\xf6\xf5\x84\x0f\xee}\xaa\x1c\xcb%\xad\xd9\xc1\
+>\xec\xb0\x9co14\x89\x90\x96g\xcb\x17\xea;2\
+;h\x1da\xcf\xc5\x0ak\x9bC\x86r\xbfgav\
+\xb0\xcfJ\xab\x85l\x95\x1c\xa1\xf1\x96\x03;\x14\x07v\
+\x88F<;$s\x87c#\x9f\xd4\x92vqUo\
+v\xf8\xea~\xaf\x0a\x84\xef)\xb4\x16!9\xbf/\xff\
+\xa8\x8e\xd4r\xe8\xc5P\xa6\xe9\xe9d\xed\x90\x0d;\xa2\
+G\x9b\xd8\xa1Q\xdd\xb8\x81\x1d\x8a\x03;D#\x96\x1d\
+\xec\xaa\xa4^\xb7\xbd\x97\xf4$\xf1\xec\x8b\xdb\xb1\xecp\
+q\xf2J#;\x1c(\x1d\xb5\x19J}Gv\x04;\
+lm\xb0C4\xa2\xd9!\xad\xde\xc0\x0e\xc9\x1b\x8d\xf6\
+V\xc2\xeaW\x16\x96\xb7\x97'\xaf6\xb2\xc3\xfe\xd2a\
+\xec\xf0<\x83\x1d\xa2\x11\xd7\x0e\xdd\xc3\xc7];l\xeb\
+{\xd5n\xcdb\x0b\x90\x96C\x1dY\xde\xfe4u]\
+\xab\x15\xd7\x0e\xfb\x86\xba\xb1\xc3\xf3\x0cv\x88\xc6\xda\xcc\
+\x1d\xd6\xd2\x0e\xcc\x1d\x9es\xb0C4\xd6\xcc\x0e\xb5\x95\
+E\x1c;\x5c\x99\xba\xd6\xc8\x0e\xe9u\x87\xa4\x97\xfa\x0c\
+\xb7#\xd8ak\x83\x1d\xa2\x11\xd7\x0e\xee{\x16\xfa3\
+{\xdda5\x89\xa7\xbaV\xbd\xf1u\x87\xb6C\xc3=\
+\x8d2\xdc\x8e\xe8Q\xec\xb0\x85\xc1\x0e\xd1\x88e\x07\x9b\
+\xcc\xf7\xdc=Q?wP\xe2e\xdf\xd1Lk\xb4\x18\
+\xea\xc8\xf2\xf6\xfc\xc4\xa5Fv\xe8\x1e>no\xa0\xd4\
+g\xb8\x1d\xc1\x0e[\x1b\xec\x10\x8d(vPX\xda\x7f\
+<\xfae\xfa\x11\xc6%]\x98\x1d>\xfb\xf3\x1b+\xb6\
+\x9a\xc4\x0bu\xbf+\xff\xd0\xe8\xb3\x92\x9a\xbf4\xcap\
+\xec\xf0<\x80\x1d\xa2\x11we\xa1\x09B\xfa\xf5\x87l\
+\x17\xd5ORK\x1c*\xa0b\xabI\xbcP\xf7\xe4\xd8\
+\xe9FvP\x86[\xb1\xfa\x8e\xec\x88\xc6\x80\x1d\xb60\
+\xd8!\x1a\xb1\xe6\x0e\xe1\x86\xd1\xb9\xac\x13\xcaa%\x9e\
+^\xd2\x95r\x86Ui!Bz+\x8d\xeb4\xb4\xe4\
+\xf2g(\x9c\x8dP\x1d;la\xb0C4\xa2\xd9!\
+\xad~~\xe2R\xda\xac\xf3\x0d\xeeC\xc3=\xe1\xc7&\
+\xd2\x1a\xad\x84\xd5\xd5\xf2\xe4\xfd\x91\x8f4r\xcf\x0e\xbb\
+\xbf/\xff\x98-\x9c\x0d\xec\xf0<\x80\x1d\xa2\x11\xd7\x0e\
+7\xa6o&?f\xb14\xf1t\xea\xab\x97\xbdC\x07\
+\xc7\xe6\xc6\x93\x92\xabH<K\xda\xd9\xf9Gj\xcd\x9d\
+\xa4HCv\xd3z\x95\xc4\x0e\xcf'\xd8!\x1a\xb1\xec\
+`\xe9\xa4\xd3\xddn\x00\x9d\xedB\xa7\xfe\xce\xf4\x97u\
+\x7f\x9f\xbd\xa32\xea\xa8\xe5\xdc\xb3\x8a\x9a\x83\xa4W\x1c\
+r\xb7o\xa9\xde9.\xfb\x93\x19i\xa5\xc5\xb0#\xd8\
+ak\x83\x1d\xa2\x11\xd7\x0e\xca\xdb\x8e?\xdeU\x9bi\
+\xe3\xf9\x8f<\x84\x9f\xa2Ik\xac8B\xc2+\xa9\xea\
+\xbb0\x94\xe46Cq\xd3\xdb\x0eb\x87\xad\x0dv\x88\
+FD;\xd8\x92a\xdfP\xf7\xf6\xe4\xc6\x8d\xd9^\xaa\
+o[\xd8\xf5B\x954\xd2z+\x88P\xeb\xfc\xc4\xa5\
+\xfa{L+\xc1\x94f\xea\xfd\xef\xcc\xeft\xa6\xf5\x16\
+\xc3\x8e`\x87\xad\x0dv\x88F,;(,\xa3>\x1e\
+\xfd\xd2K\xdd\xe4\xc6\xb3\xdd\x99_\xc1Mk\xac8\xac\
+b\xcf\xdd\x13\x8d\xba\xc8\xde3\xba\xbe\x17;\xa2g\xda\
+\xe8\xdeP\x1a\xbc}p\xa3\xe5\x11.3\xb0Cq`\
+\x87hD\x9c;XF]\x9c\xbc\x92N\xf8\xf3s~\
+\xa1\x1cX\xfd\xefh\xa6w\xa0\xdf\x9b\xcb\xed0=\xb1\
+7,\x1a5n\x075\xc7\xa9\xbf\xa8\xa9\xeaZ\xfbH\
+.\xd8a\xb3\x83\x1d\xa2\x11}\xee\xa0e\xbf\x9a\xad\xff\
+\xb1\x09\xcb\xde\x93c\xa7\xad\x98\xb6\xcb\xcf@+i+\
+\x97\xcb\x93W\x95Ku\xedWW\x16\xfd3\x03I\xc9\
+\x06\xcf%tm7\xbc_Z=\xb1\xc3\xb1H7\xa4\
+\x7ff`\x87\xe2\xc0\x0e\xd1\x88n\x07\xb5\xa3W\xe6\xdc\
+\x9b\x9a5\x92\x1f\xd1\x0f\xd7\x05l\xdb<\x0fC\x81\xb0\
+sh\xb8\xa7\xfe\xe3\x98\xfaSOd\xdfP\xf7\xf8\x93\
+r\xb6p.BSz\xca\xf5vP\xb3\xd9\xdf\x01v\
+[\x88\x15\xd8\xa18\xb0C4\xa2\xdbAqj\xfc\x5c\
+-\x81\xb3\xaf\xf0\xc9\xbe\xba\xb3\x8fT+B\xf9Fy\
+\x18RT[\x1b\x9e\x16\x0e\xa9w\xac\xd9\xd0xub\
+b_\xf4\xb2ZV1\x17\xa1\xb5\xf7G>\xca]\xb9\
+\xd0h\x95\xa5o\xdey/\xfb\x96\x87\xdbH\x94\xc0\x0e\
+\xc5\x81\x1d\xa2\x11\xd7\x0e\x96Nw\x1f\x8f\xaaY\xbd\x1a\
+\xe7\xfaJiW2|W\xfe\xc1\xaaT\x16\xe6\xc3\x0f\
+\xe7eS1\x1c\x11\x1a\x98\xfd\xf9\xeb\xf4o\x9az\xc8\
+\x0eK\xbd\x93L\x1c\xb4\xd0\xd0C\xcf\xfc\x9d\xce\xd0\xc5\
+\x17\x7f}\x9b\x8e\xd0Z\xa8\xa2\x01\xeb\xa0]\x19\xa9,\
+T\xd4\xce\x22O5\xce\xf9d\xb4\xb5\xc1\x84\xa6Z\x0b\
+\xb5\xa3-v(\x02\xec\x10\x8d\x88vPX\xce(\xb5\
+z\xee\x9eH\x7f\xd8\x22\xf7\x99\xa5d\xdf.\x19\xf4>\
+8c\xef_(\xd4u}6\xa6\xe2\xa8\xde*FG\
+.N^Q\x22\xd5RzI\x9b\xe9\xa2`\xb7\xa6\x03\
+\xea=`\x15s\x11\x8e\x9f-_\xd8\xee,O\x92K\
+\x0f'\xd2\x9b\xd6[\xb1F\xd1\xa8\xfd\xe5\x87\x9e\x91\xb6\
+\xd8\xa1\x08\xb0C4\x22\xda!\x9b\x997\xa6o*\xfd\
+4\xe1\xcfu\x17\x12[yx\xa0t\xf4\xf2\xe4\xd5\xd1\
+\xb9\xfbV\xdd\x8d\x89\xca\xa4\x9a\xfa\xf0\xde\xe7Z\xaa\xd4\
+\xcd\x1a\xaa\xfb:\xae\x8e4\xb3Py{\x16\x8d\xb27\
+;<\x0d\xc0\x13Mr\x87\x08u\xa7\x81i&\xd2?\
+3\xa0fU\xf8\xe7\xa9\xebW\xa6\xae\x9d\x9f\xb8\xa4#\
+vq\xb4Q\x17\xcb\x0c\xecP\x1c\xd8!\x1aq\xe7\x0e\
+\x0aK\x1b\xbd\xfc\xda}\xa2RAd3P$\x7f\xea\
+\xb8\x12^\xbdk\xa9\xff\xc1\xbdO5\x95\xf8\xbe\xfc\xa3\
+rR\xa9hyxj\xfc\x9c^\xc6\xf7\x97\x0e\xeb%\
+]\xedh[\x97\xccU\xd4\x88\xf2Y\x9d6W\x83\x22\
+\xd8AJr\x9b2A\xa8;\x8dMK\x15\xb1\xebv\
+g\xed)\xb4\xbfp\xeb%\xcd\x89\xf8\x1d\xcd\x0d\x0ev\
+\x88F\x5c;X\xceXS\xbf\xcf\xdeQv\xd5N\xfd\
+zA$3y=\xa4\x01X6\xda\x14@\xd9(\xf4\
+h8\xae\xf2i~:\x8d\xa8\xba^\xea\x95`\xe1\xad\
+\x8a\xb0m\x14\xf6\xe8\xec\xfc#=kuQ\x97\x96I\
+\x17\xeaNc\xd3\x0aHCJ\xd7A\xd5\x83*/;\
+\xf0\x1b\xdc\x1b\x1c\xec\x10\x8d\xb8vP(m\x84\xb5\xa6\
+\xe9@\xfa\xd6@\x92\xc6u\xb9]=\xa2\x87j\xf3\x82\
+\xe4\x92DH\xc8\xda\xf1\xe0\x85\x5c\xf5D.i^u\
+\xd8g\x1c,]\x9b'\xad\x8d\xcd\xca|W\xfeA\xf6\
+1\x13\xe5Z\xb6#\xe9\x00\x12\xec\xb8:\xd2Zi\xf5\
+\x1f\xf7\xb4\xc0\x0e\xc5\x81\x1d\xa2Q\x84\x1dlk;'\
+\xc7N\xdb\xeb\x7f\x9a\xe7\xb9<4\xdc\x83\x81\xfaG\x93\
+\xecU:\xd9+\xffOS\xd7Cw\xd6\xe33\xc3\x8a\
+\x8d\xcd\x8d\xb7\x0f\xbc\xa3\xcc\xac-\x1cr\xbd\xe4\xb1\x1e\
+\xbbJG&*\x93\xa1\x91\x96\x03;\x14\x07v\x88F\
+t;(,s\xd2tM\xa2\xf7\xc1\x19\xcd\x08\xd4Q\
+\x83\x05Bk\xb4w\x0ev\xdd\x98\xbeY\xeb\xa8\xdac\
+\xdaa\xb3\xb0\xc2V\xf2\xe2\xe4\x95m}\xbb\xd5ZM\
+\x10\xcd\x06\xa6\x04V\x1a\xef\x1d:X\xaeLX;i\
+{-\x06v(\x0e\xec\x10\x8d\x22\xec\xa0\xb0\xe4\x09y\
+\xf8\xf3\xd4\xf57\xef\xbc\xf7\xcf[\xaf\xa8\xc7\x06\x99P\
+\x9f\x99\xd9#K\x1e\xb5\x97\xf1\xb3\xe5\x0bj\xb9R\xbb\
+\x8d\xed\x8a\xd25TI\xdf\xdal\xd3\xecFm6O\
+Q\xcd}\xb4\xe4\xe9\x18\xdc\xdf\xe4\x1b\xe2\xcb\x0f\xecP\
+\x1c\xd8!\x1a\x05\xd9A\x112\xd0v\xf4\x92{j\xfc\
+\xdc\xeb\x03o+\x15\x95\x0f\xd9\x0b~\x96\x99\xf5d\xc6\
+\x99\xb7\x83\x1ay\x7f\xe4\xa3\xec\x05\xc2\xe5\xa7k\xae|\
+\xff\xcc\xc0\xb1\x91O\xb6'o\xa0$\xef\xa1\xecH\xd8\
+\x93\xa1M\x07\x0du*\xc7e\xaf\x80\xb6\x1c\xd8\xa18\
+\xb0C4\x0a\xb5C\xc8\xc3\xd0\xb8\x16\xed\x9a\xcfw\x0f\
+\x1f\xdfu\xbbS)a+\x0ee\x9d\xb0\xe4\xacaG\
+\x92D\xad\x0d5\x08\xa2*\x94\x17\xfbv\x9f\x9f\xb8\xa4\
+6\xd5\xf8Js5\x0c\xcc\xfe\xd4\x04dt\xee\xfe\xe5\
+\xc9\xab'F\xbf\xd6\xd8\xbaJGd\x01\xad\x5c\xf6\x0d\
+u\xcbA\x9f\xfd\xf9\x8d\xa6\x18\xd7\x1e\xfe\xa22\xd3\xf3\
+3\xf6\x5cV\xdac.\xb0Cq`\x87h(\x03\x0b\
+\xb2\x83E\xc8\xc3\x5c:\xfd]\x99\xba1}\xb3\xf7\xc1\
+\x99\x0f\xef}~\xa0tT\xebyKHC\xfb:\xd2\
+s\xf7\xc4\xa1\xe1\x9et\x9c\xa6\x86EA(\x9d\x94T\
+*\xd9\xf2\xd7\x22\x1a\x0d\xcc\xa2\xd1q\x8b&\x0f-3\
+\xb0Cq`\x87h\x14m\x07E\xc84\xdbi\x94Z\
+z\x01\xd7JA/\xce\xc2>q\xa4\xd0\xbe\x14\x90\x99\
+A\x04\xaa\xdf\xbc\xfa\xe2\xafo\xadd\x93\x96\x1b\x85\x95\
+\xb7\x8a\xcd\xabg\xcbX1\xdb\xb6\x1c\xf6\xdf\x1e\x9c-\
+a\x87\xe8`\x87h\xac\x81\x1d,BR\xe5P\xbf\xc2\
+\xf6\xad\xa4\x85\xfe\xb4\xef;h%\xa2A\xa6\x13\x870\
+w\xa8\x92&U{\xcbw\x94\xb1\xb0*\xa1zsB\
+\xf9\x96\xc3\xda\x09v\xe8\xf8\x03;D\x06;Dc\xcd\
+\xec\xe0F\xc87\x17{H\x03\xd3\x08\xd3OUi\xc0\
+YA$\xfb:n\xe3\x0f\xed\xd8\xfe\xc6\x8c0<\xfb\
+oke\xd1>\xb0w'v\x88\x0av\x88\xc6\xfa\xda\
+\xa1y\x84l\xff}\xf6N\x93\x17Xe\x97\xe6\x17*\
+fOa#\x0b\xc2\xc6\x16\xb6Z\x16mK\xdeL\xb5\
+\x8f\x81@\x1c\xb0C46\x85\x1d\xb4\xfd\xec\xcfo^\
+\xec\xdb\xed~\xaeQO\xa1s\xb0+\xfb\x01g\xdbn\
+\xb4\xc8\x8d\xad\xf7\xc1\x19\xa9\xa1\xf6,\xf2O\x0aZ\x06\
+;Dc\x83\xdbA[\xfb\xc6\xf4\xe8\xdc}\xfb\xe0\xb3\
+]k\xa8\x8d?\xd9\xd1\x11=\x8b\x93c\xa7\xd3\xc2\xf3\
+\xaa\xb5\x01\xed\x10\xd4`;\xa7\xc6\xcfIv\xd9g\x01\
+\xb1\xc0\x0e\xd1\xd8\xf8s\x07ac;[\xbe\xe0\xcd\xc3\
+\x93w7\xb5\xb8\xd0\x02>\xfc\xd6VZ{\x03\x85\x19\
+\xc1\x9e\x8bv\xec\x89\x84\xf1g\x9e\x0bD\x00;Dc\
+#\xdbA\x11\xf2J\xdb\xd9\xf9G]\xa5#\xe9][\
+\x96\xac/\x12;\xa47_\xd0\x5c]\xc5\xc2\xad\xe86\
+B\x04#\x84\x9d\xa5?\xd5\x83\x1a\xe2\x83\x1d\xa2\xb1\xc1\
+\xed\xa0\xb0\xa4\xb2\xe1\xfd4u\xdd\xbe\xef #\x98\x14\
+\xb4\xd6\xd0S\xd8_:\xfc\xf3\xd4\xf5\x87\xf3\xd3Qn\
+\xdc\x141rj\xb88yE\x03\xb6\xf9\x0ej(\x08\
+\xec\x10\x8d\x8do\x07\x85e\x97\x8d0\xfdND\x9b\xbc\
+\xa0\xad\x12L^\xb8\xf6\xf0\x97\xf0\xe9\xa9\x90\x87\x1b!\
+l$aH\x97'\xaf\xdaWKPC\xa1`\x87h\
+l\x16;\x84\xed\xdd\xc7\xa3\xf6\x1d\x8dC\xc3=\xf2\x82\
+\x1d\xb4GC\xb1pp\x1d#\x0c\xc3\xfe\xb1\x9a\xda\xc8\
+\x086\xebA\x0d\x85\x82\x1d\xa2\xb1)\xec\xa0\x08\x99\xaf\
+\xad\xdd\x812=\x9c\x1c\x09\xd8\x9fv|}#\x8c\xc7\
+\xfe\xab7\xa6o\xda\x82(\xfd\x9f\xa3\x86b\xc1\x0e\xd1\
+\xd8,vP\xe4\xf2?d\xa0\xed\xdb\xceF\x8800\
+\xbb\xe3\xfe\xad\x99~MvvV\xbf*\x82\x1a\x0a\x07\
+;Dcs\xd9\xa1\x9au\xb5\xaff\xd8\xc1\xf4\xc1\x8d\
+\x12aT\xf6\xff\xec\x9f\x19\xf0~\xa1\x07\x0a\x04;D\
+c\x13\xd9\xc1B\x89\xb71\xbd\xa0\xc8\xa9\xe1\xf7\xd9;\
+\xf6s\xe1\xb5\xb7`\xb1\xc3Z\x80\x1d\xa2\xb1\xe9\xec\xb0\
+\x91\xc3\xec`\xff\xc9\xda\xbd\x1b\xec\x17\x03Q\xc3\xda\x81\
+\x1d\xa2\x81\x1dbEV\x0d\xc3\x8fG:\x07\xbb\xf4\xbf\
+\xad-(P\xc3\xda\x81\x1d\xa2\x81\x1d\xa2DV\x0d\xa3\
+s\xf7\xf7\x0e\x1d\xcc\xa8a\xc9?\x1c\x8a\x06;D#\
+k\x07\x9d\xe2\xd02\xa6\x86\xf1'\xe5\xfd\xa5\xc3\xdb\xab\
+?\xe1\x8b\x1a\xd6\x01\xec\x10\x0d\xd9\xe1\xd0p\x8fNk\
+b\xf5Q\xaeL\x1c(\x1d\xcd|U\x0c;\xac\x03\xd8\
+!\x1a\xb2\x83N\xe8\xcaB\xe5\xef\xca\x94\xdd\xd3\x11V\
+\xca\xc3\xf9\xe9\xd9\xf9Gcs\xe3\xdd\xc3\xc7k_\x12\
+\xd3\xff\x165\xac\x0f\xd8!\x0av\xfaj\x0b\x11\xd8\x99\
+\xfe\xfe\xc5\xd2\xff-\xac\x03\xd8!\x22\x9c\xc7\xd1\xe1_\
+\xba\x9e`\x87\x88p*G\x84\x7f\xe6\xfa\x83\x1d\x00\xc0\
+\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00\
+|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\
+\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\x01\
+\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\
+\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\xd8\
+\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\
+\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00>\
+\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\xe0\
+\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\x00\
+>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\x00\
+\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\x00\
+\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\x0e\
+\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\xec\
+\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\xc1\
+\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\x1f\
+\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\xf0\
+\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\x00\
+\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\x00\
+\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\x00\
+\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\x07\
+\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0fv\
+\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8`\
+\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\x07;\x00\x80\x0f\
+v\x00\x00\x1f\xec\x00\x00>\xd8\x01\x00|\xb0\x03\x00\xf8\
+`\x07\x00\xf0\xc1\x0e\x00\xe0\x83\x1d\x00\xc0\xe7\x1f\xff\xfe\
+\xef\x1b\x00\x00y\xfe\xfb\xc6\xff\x034\xc3}\xffR)\
+\xdb\xa4\x00\x00\x00\x00IEND\xaeB`\x82\
+"
+
+qt_resource_name = b"\
+\x00\x08\
+\x08\x01Z\x5c\
+\x00m\
+\x00a\x00i\x00n\x00.\x00q\x00m\x00l\
+\x00\x10\
+\x0d\x0d\xd3\xc7\
+\x00q\
+\x00t\x00_\x00l\x00o\x00g\x00o\x00_\x00r\x00e\x00c\x00t\x00.\x00p\x00n\x00g\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01}8\xa9\x8e!\
+\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x09A\
+\x00\x00\x01}3\x1dr4\
+"
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/examples/quick3d/intro/doc/intro.png b/examples/quick3d/intro/doc/intro.png
new file mode 100644
index 000000000..ae54997c4
--- /dev/null
+++ b/examples/quick3d/intro/doc/intro.png
Binary files differ
diff --git a/examples/quick3d/intro/doc/intro.rst b/examples/quick3d/intro/doc/intro.rst
new file mode 100644
index 000000000..0afebd5be
--- /dev/null
+++ b/examples/quick3d/intro/doc/intro.rst
@@ -0,0 +1,9 @@
+Introduction Example Qt Quick 3D
+================================
+
+This example gives an introductory overview of the basic Quick 3D features by going
+through the code of a simple example.
+
+.. image:: intro.png
+ :width: 400
+ :alt: QtQuick3D Introduction Screenshot
diff --git a/examples/quick3d/intro/intro.pyproject b/examples/quick3d/intro/intro.pyproject
new file mode 100644
index 000000000..428f88dc1
--- /dev/null
+++ b/examples/quick3d/intro/intro.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "main.qml"]
+}
diff --git a/examples/quick3d/intro/main.py b/examples/quick3d/intro/main.py
new file mode 100644
index 000000000..050f9d632
--- /dev/null
+++ b/examples/quick3d/intro/main.py
@@ -0,0 +1,60 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+from pathlib import Path
+from PySide6.QtCore import QUrl
+from PySide6.QtGui import QGuiApplication, QSurfaceFormat
+from PySide6.QtQml import QQmlApplicationEngine
+
+from PySide6.QtQuick3D import QQuick3D
+
+if __name__ == "__main__":
+ app = QGuiApplication(sys.argv)
+
+ QSurfaceFormat.setDefaultFormat(QQuick3D.idealSurfaceFormat(4))
+
+ engine = QQmlApplicationEngine()
+ qml_file = os.fspath(Path(__file__).resolve().parent / 'main.qml')
+ engine.load(QUrl.fromLocalFile(qml_file))
+ if not engine.rootObjects():
+ sys.exit(-1)
+
+ sys.exit(app.exec())
diff --git a/examples/quick3d/intro/main.qml b/examples/quick3d/intro/main.qml
new file mode 100644
index 000000000..1c7ba610e
--- /dev/null
+++ b/examples/quick3d/intro/main.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt for Python examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [import]
+import QtQuick
+import QtQuick3D
+//! [import]
+
+Window {
+ id: window
+ width: 1280
+ height: 720
+ visible: true
+
+ View3D {
+ id: view
+ anchors.fill: parent
+
+ //! [environment]
+ environment: SceneEnvironment {
+ clearColor: "skyblue"
+ backgroundMode: SceneEnvironment.Color
+ }
+ //! [environment]
+
+ //! [camera]
+ PerspectiveCamera {
+ position: Qt.vector3d(0, 200, 300)
+ eulerRotation.x: -30
+ }
+ //! [camera]
+
+ //! [light]
+ DirectionalLight {
+ eulerRotation.x: -30
+ eulerRotation.y: -70
+ }
+ //! [light]
+
+ //! [objects]
+ Model {
+ position: Qt.vector3d(0, -200, 0)
+ source: "#Cylinder"
+ scale: Qt.vector3d(2, 0.2, 1)
+ materials: [ DefaultMaterial {
+ diffuseColor: "red"
+ }
+ ]
+ }
+
+ Model {
+ position: Qt.vector3d(0, 150, 0)
+ source: "#Sphere"
+
+ materials: [ DefaultMaterial {
+ diffuseColor: "blue"
+ }
+ ]
+
+ //! [animation]
+ SequentialAnimation on y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ duration: 3000
+ to: -150
+ from: 150
+ easing.type:Easing.InQuad
+ }
+ NumberAnimation {
+ duration: 3000
+ to: 150
+ from: -150
+ easing.type:Easing.OutQuad
+ }
+ }
+ //! [animation]
+ }
+ //! [objects]
+ }
+}
diff --git a/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt b/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt
new file mode 100644
index 000000000..4cde0ae86
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt
@@ -0,0 +1,51 @@
+project(QtQuick3D)
+
+set(QtQuick3D_SRC
+${QtQuick3D_GEN_DIR}/qquick3d_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dobject_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dgeometry_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dgeometry_attribute_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dinstancing_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dinstancing_instancetableentry_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dtexturedata_wrapper.cpp
+# module is always needed
+${QtQuick3D_GEN_DIR}/qtquick3d_module_wrapper.cpp
+)
+
+set(QtQuick3D_include_dirs ${QtQuick3D_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick3D_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuick3D_GEN_DIR})
+
+set(QtQuick3D_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Quick3D_LIBRARIES})
+
+set(QtQuick3D_deps QtGui QtOpenGL QtNetwork QtQml)
+
+create_pyside_module(NAME QtQuick3D
+ INCLUDE_DIRS QtQuick3D_include_dirs
+ LIBRARIES QtQuick3D_libraries
+ DEPS QtQuick3D_deps
+ TYPESYSTEM_PATH QtQuick3D_SOURCE_DIR
+ SOURCES QtQuick3D_SRC)
diff --git a/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml b/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml
new file mode 100644
index 000000000..f75da736f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<typesystem package="PySide6.QtQuick3D">
+ <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/>
+
+ <object-type name="QQuick3D"/>
+ <object-type name="QQuick3DObject">
+ <enum-type name="ItemChange"/>
+ <modify-function signature="QQuick3DObject(QQuick3DObject*)" remove="all"/>
+ </object-type>
+ <object-type name="QQuick3DGeometry">
+ <value-type name="Attribute">
+ <enum-type name="Semantic"/>
+ <enum-type name="ComponentType"/>
+ </value-type>
+ <enum-type name="PrimitiveType"/>
+ </object-type>
+ <object-type name="QQuick3DInstancing">
+ <value-type name="InstanceTableEntry"/>
+ </object-type>
+ <object-type name="QQuick3DTextureData">
+ <enum-type name="Format"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/cmake/PySideHelpers.cmake b/sources/pyside6/cmake/PySideHelpers.cmake
index dc6fe22ce..dd71fc20b 100644
--- a/sources/pyside6/cmake/PySideHelpers.cmake
+++ b/sources/pyside6/cmake/PySideHelpers.cmake
@@ -27,6 +27,7 @@ macro(collect_optional_modules)
NetworkAuth
Qml
Quick
+ Quick3D
QuickControls2
QuickWidgets
RemoteObjects
diff --git a/sources/pyside6/tests/QtQuick3D/CMakeLists.txt b/sources/pyside6/tests/QtQuick3D/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtQuick3D/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here