Qt Quick 3D - Custom Geometry Example | Qt Quick 3D 6.7.0
Description: Demonstrates providing custom vertex data from C++ and QML.

- Qt 6.7
- Qt Quick 3D
- Qt Quick 3D Examples and Tutorials
- Qt Quick 3D - Custom Geometry Example
- Qt Quick 3D | Commercial or GPLv3

# Qt Quick 3D - Custom Geometry Example

     // Copyright (C) 2023 The Qt Company Ltd.
     // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

     import QtQuick
     import QtQuick3D.Helpers

     ProceduralMesh {
         property int rings: 50
         property int segments: 50
         property real radius: 100.0
         property real tubeRadius: 10.0
         property var meshArrays: generateTorus(rings, segments, radius, tubeRadius)
         positions: meshArrays.verts
         normals: meshArrays.normals
         uv0s: meshArrays.uvs
         indexes: meshArrays.indices

         function generateTorus(rings: int, segments: int, radius: real, tubeRadius: real) : var {
             let verts = []
             let normals = []
             let uvs = []
             let indices = []

             for (let i = 0; i <= rings; ++i) {
                 for (let j = 0; j <= segments; ++j) {
                     const u = i / rings * Math.PI * 2;
                     const v = j / segments * Math.PI * 2;

                     const centerX = radius * Math.cos(u);
                     const centerZ = radius * Math.sin(u);

                     const posX = centerX + tubeRadius * Math.cos(v) * Math.cos(u);
                     const posY = tubeRadius * Math.sin(v);
                     const posZ = centerZ + tubeRadius * Math.cos(v) * Math.sin(u);

                     verts.push(Qt.vector3d(posX, posY, posZ));

                     const normal = Qt.vector3d(posX - centerX, posY, posZ - centerZ).normalized();
                     normals.push(normal);

                     uvs.push(Qt.vector2d(i / rings, j / segments));
                 }
             }

             for (let i = 0; i < rings; ++i) {
                 for (let j = 0; j < segments; ++j) {
                     const a = (segments + 1) * i + j;
                     const b = (segments + 1) * (i + 1) + j;
                     const c = (segments + 1) * (i + 1) + j + 1;
                     const d = (segments + 1) * i + j + 1;

                     // Generate two triangles for each quad in the mesh
                     // Adjust order to be counter-clockwise
                     indices.push(a, d, b);
                     indices.push(b, d, c);
                 }
             }
             return { verts: verts, normals: normals, uvs: uvs, indices: indices }
         }
     }