Qt Quick 3D-机械臂模型显示与交互

简介

文章目录

Qt Quick 3D 为在QML中创建基于 Qt Quick 的3D内容和3D用户界面提供了一个高级 API。当使用这个空间场景图时,可以将 Qt Quick 的2D内容(Item)与3D内容(Node)混合在一起。

Quick3D

类似与普通组件,Item是2D对象的基类,在3D组件中,Node是3D对象的基类,例如 Camera, Joint, Light,Model等3D相关的组件都继承自NodeNode 本身也可以作为一个"空"的空间节点(用于组织结构)。通常可以以Node为根节点,在其中加入模型,灯光等元素,最后将该节点导入到三维视图窗口组件View3D中进行显示。官方例程可以参考,Qt Quick 3D Examples and Tutorials | Qt Quick 3D | Qt 6.9.3

机械臂模型搭建

机械臂模型文件来自Robot Arm | Qt 6.9,取其以下文件和文件夹,分别提供了模型描述和模型的网格(mesh)文件。如果要自己搭建模型可以使用相关工具导出,并将模型文件转为mesh,Qt配套的Balsam命令行工具可以将一些常见格式转为View3D支持的mesh格式

查看描述文件层次结构,如下,一个Model套一个Model很像机械臂安装顺序,这样配置内部坐标变换是相对与上一个个父节点(Model)的变换,即相对位置

注意Node只是一个描述组件,并不具有显示功能 ,还需要创建一个名为View3D的组件,使用其importScene属性,传入Node的id,如下

css 复制代码
View3D {  
    id: view  
    anchors.fill: parent  
    importScene: rootNode  
    camera: came  
}

可以将View3D和Node封装在一个Item下方,这样可供外部调用显示

css 复制代码
// Scene3D.qml
Item {
    Node {
        id: rootNode  
    }
    View3D {
        anchors.fill: parent  
        importScene: rootNode 
    }
}

// main.qml
Scene3D {
...
}

也可以添加一些组件或者鼠标事件用来控制机械臂之间的相对夹角,或者旋转相机视图或者旋转模型节点,实现交互功能

代码与演示

完整代码如下,注意需要先从官方例程content << robotarm << demos << examples - qt/qtdoc.git - Qt Documentation中找到meshes文件夹放到和该文件同一个目录下,如果安装了Qt,本地电脑应该也有这个例程

css 复制代码
import QtQuick  
import QtQuick3D  
import QtQuick.Layouts  
import QtQuick.Controls  
  
Item {  
    property int rotation1: rotations[0]  
    property int rotation2: rotations[1]  
    property int rotation3: rotations[2]  
    property int rotation4: rotations[3]  
    property int clawsAngle: rotations[4]  
  
    readonly property alias hand_position: hand_grab_t.scenePosition  
    readonly property alias hand_hinge_position: hand_hinge.scenePosition  
    readonly property alias arm_position: arm.scenePosition  
    readonly property alias forearm_position: forearm.scenePosition  
    readonly property alias root_position: root.scenePosition  
    property var rotations: [50, 50, 50, 0, 0] // 数组需要重新赋值才能触发绑定更新  
  
    property point lastMouse: "0,0"  
    Behavior on rotation1 {  
        PropertyAnimation {  
            duration: 100  
        }  
    }  
    Behavior on rotation2 {  
        PropertyAnimation {  
            duration: 100  
        }  
    }  
    Behavior on rotation3 {  
        PropertyAnimation {  
            duration: 100  
        }  
    }  
    Behavior on rotation4 {  
        PropertyAnimation {  
            duration: 100  
        }  
    }  
    ColumnLayout {  
        anchors.left: parent.left  
        anchors.top: parent.top  
        width: parent.width  
        Repeater {  
            id: sliderRepeater  
            model: [  
                {label: "Rotation 1", min: -180, max: 180, step: 1, index: 0},  
                {label: "Rotation 2", min: -180, max: 180, step: 1, index: 1},  
                {label: "Rotation 3", min: -180, max: 180, step: 1, index: 2},  
                {label: "Rotation 4", min: -180, max: 180, step: 1, index: 3},  
                {label: "Claws Angle", min: 0, max: 90, step: 1, index: 4}  
            ]  
            delegate: Slider {  
                Layout.fillWidth: true  
                Layout.preferredHeight: 40  
                from: modelData.min  
                to: modelData.max  
                stepSize: modelData.step  
                onValueChanged: {  
                    var newRotations = rotations;  
                    newRotations[modelData.index] = value  
                    rotations = newRotations  // 触发绑定更新  
                }  
            }  
        }  
    }  
  
    Node {  
        id: rootNode  
        Node {  
            PerspectiveCamera {  
                id: came  
                // z: 1000  
                // y: 300                position: Qt.vector3d(0, 100, 400)  
                eulerRotation.x: 0 // 俯仰角 (Pitch)                eulerRotation.y: 0 // 偏航角 (Yaw)            }  
            DirectionalLight {  
                ambientColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)  
                brightness: 0.8  
                eulerRotation.x: -25  
            }  
        }  
  
  
        Model {  
            id: base  
            scale.x: 100  
            scale.y: 100  
            scale.z: 100  
            source: "meshes/base.mesh"  
            eulerRotation.x: -90  
            DefaultMaterial {  
                id: steel_material  
                diffuseColor: "#ff595959"  
            }  
            DefaultMaterial {  
                id: plastic_material  
            }  
            materials: [steel_material, plastic_material]  
            Model {  
                id: root  
                y: -5.96047e-08  
                z: 1.0472  
                eulerRotation.z: rotation4  
                source: "meshes/root.mesh"  
  
                DefaultMaterial {  
                    id: plastic_color_material  
                    diffuseColor: "#41cd52"  
                }  
                materials: [plastic_material, plastic_color_material, steel_material]  
  
                Model {  
                    id: forearm  
                    x: 5.32907e-15  
                    y: -0.165542  
                    z: 1.53472  
                    eulerRotation.x: rotation3  
                    source: "meshes/forearm.mesh"  
                    /* 一个复杂的 3D 模型(如 .glb, .gltf 文件)每个部分称为一个 sub-mesh,可能由多个"部分"组成。 */                    materials: [plastic_material, steel_material]  
  
                    Model {  
                        id: arm  
                        x: -7.43453e-07  
                        y: 0.667101  
                        z: 2.23365  
                        eulerRotation.x: rotation2  
                        source: "meshes/arm.mesh"  
  
                        DefaultMaterial {  
                            id: plastic_qt_material  
                            diffuseMap: Texture {  
                                source: "maps/qt.png"  
                                pivotU: 0.5  
                                pivotV: 0.5  
                                generateMipmaps: true  
                                mipFilter: Texture.Linear  
                            }  
                        }  
                        materials: [plastic_material, plastic_qt_material, steel_material]  
  
                        Model {  
                            id: hand_hinge  
                            x: 7.43453e-07  
                            y: 0.0635689  
                            z: 2.12289  
                            eulerRotation.x: rotation1  
                            source: "meshes/hand_hinge.mesh"  
                            materials: [plastic_material]  
  
                            Model {  
                                id: hand  
                                x: 3.35649e-06  
                                y: 2.38419e-07  
                                z: 0.366503  
                                source: "meshes/hand.mesh"  
                                materials: [plastic_material, steel_material]  
  
                                Model {  
                                    id: hand_grab_t_hinge_2  
                                    x: -9.5112e-07  
                                    y: 0.323057  
                                    z: 0.472305  
                                    eulerRotation: hand_grab_t_hinge_1.eulerRotation  
                                    source: "meshes/hand_grab_t_hinge_2.mesh"  
                                    materials: [steel_material]  
                                }  
  
                                Model {  
                                    id: hand_grab_t_hinge_1  
                                    x: -9.3061e-07  
                                    y: 0.143685  
                                    z: 0.728553  
                                    eulerRotation.x: clawsAngle * -1  
                                    source: "meshes/hand_grab_t_hinge_1.mesh"  
                                    materials: [steel_material]  
  
                                    Model {  
                                        id: hand_grab_t  
                                        x: -2.42588e-06  
                                        y: -0.0327932  
                                        z: 0.414757  
                                        eulerRotation.x: hand_grab_t_hinge_1.eulerRotation.x * -1  
                                        source: "meshes/hand_grab_t.mesh"  
                                        materials: [plastic_color_material, steel_material]  
                                    }  
                                }  
  
                                Model {  
                                    id: hand_grab_b_hinge_1  
                                    x: -9.38738e-07  
                                    y: -0.143685  
                                    z: 0.728553  
                                    eulerRotation.x: clawsAngle  
                                    source: "meshes/hand_grab_b_hinge_1.mesh"  
                                    materials: [steel_material]  
  
                                    Model {  
                                        id: hand_grab_b  
                                        x: -2.41775e-06  
                                        y: 0.0327224  
                                        z: 0.413965  
                                        eulerRotation.x: hand_grab_b_hinge_1.eulerRotation.x * -1  
                                        source: "meshes/hand_grab_b.mesh"  
                                        materials: [plastic_color_material, steel_material]  
                                    }  
                                }  
  
                                Model {  
                                    id: hand_grab_b_hinge_2  
                                    x: -9.5112e-07  
                                    y: -0.323058  
                                    z: 0.472305  
                                    eulerRotation: hand_grab_b_hinge_1.eulerRotation  
                                    source: "meshes/hand_grab_b_hinge_2.mesh"  
                                    materials: [steel_material]  
                                }  
                            }  
                        }  
                    }  
                }  
            }  
        }  
    }  
  
    Item {  
        anchors.fill: parent  
        View3D {  
            id: view  
            anchors.fill: parent  
            importScene: rootNode  
            camera: came  
        }  
        MouseArea {  
            id: cameraControlArea  
            anchors.bottom: parent.bottom  
            anchors.left: parent.left  
            anchors.right: parent.right  
            height: 200  
            acceptedButtons: Qt.LeftButton | Qt.RightButton  
            property real lastMouseX: 0  
            property real lastMouseY: 0  
            property var mouse_button: Qt.LeftButton  // 当前按下的鼠标按钮  
            onPressed: function (mouse) {  
                // 记录当前位置作为起点  
                lastMouseX = mouse.x  
                lastMouseY = mouse.y  
                mouse_button = mouse.button  
            }  
  
            onPositionChanged: function (mouse) {  
                if (pressed) {  
                    var deltaX = mouse.x - lastMouseX  
                    var deltaY = mouse.y - lastMouseY  
                    if (mouse_button === Qt.LeftButton) {  
                        base.eulerRotation.y += deltaX  
                    } else if (mouse_button === Qt.RightButton) {  
                        base.position.x += deltaX * 5  
                        base.position.y += -deltaY * 5  
                    }  
                    // 更新上一次鼠标位置  
                    lastMouseX = mouse.x  
                    lastMouseY = mouse.y  
                }  
            }  
            onWheel: function (wheel) {  
                var delta = wheel.angleDelta.y  
                came.z += -delta  
            }  
        }  
    }
相关推荐
长源Gingko7 小时前
Windows中在QTCreator中调试,提示缺少debug information files问题的解决
windows·qt
SundayBear8 小时前
Qt 开发修炼指南:从入门到通透的实战心法
开发语言·qt·嵌入式
ajassi20009 小时前
开源 C++ QT QML 开发(十)通讯--串口
c++·qt·开源
BingeBlog9 小时前
[01] Qt的UI框架选择和对比
开发语言·c++·笔记·qt·ui·开源软件
m0_7431064611 小时前
LOBE-GS:分块&致密化效率提升
人工智能·算法·计算机视觉·3d·几何学
视觉人机器视觉12 小时前
机器视觉Halcon3D中,六大类3D处理算子
人工智能·计算机视觉·3d·视觉检测
Damon小智12 小时前
从零开始XR开发:Three.js实现交互式3D积木搭建器
javascript·3d·xr
扶尔魔ocy14 小时前
【QT常用技术讲解】opencv实现摄像头图像检测并裁剪物体
开发语言·qt·opencv
-dzk-21 小时前
【3DGS复现】Autodl服务器复现3DGS《简单快速》《一次成功》《新手练习复现必备》
运维·服务器·python·计算机视觉·3d·三维重建·三维