使用Qt3D绘制机械手场景

news2024/12/24 10:01:36

文章目录

  • 1.前言
  • 2.效果
  • 3.实现过程
    • 3.1.场景代码
    • 3.2.自定义模型的渲染
    • 3.3.绘制直线或者网格
  • 4.有待解决的一些问题
    • 4.1.线宽的设置、背面消隐(culling)的设置
    • 4.2.法线的问题

1.前言

之前是使用Coin3D来绘制机械手场景的【Qt利用Coin3D(OpenInventor)进行3d绘图】。
后来需要在HarmonyOS显示这个机械手模型,但是想要编译Coin3D到HarmonyOS的话,显然太难了。
然后尝试使用OpenGL原生的函数来绘制,但是HarmonyOS对很多函数都不支持,一查,发现HarmonyOS支持OpenglES。那就麻烦了。
最后,一番兜兜转转,还是用回Qt3D吧。

2.效果

效果也还行,但是某些功能还得研究一下。
在这里插入图片描述点、线、面、灯光等各种功能都ok。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8c52fb4533714e9588d87d3ac7d45ca5.png在这里插入图片描述

3.实现过程

主要是参考了Qt自带的例程以及网上的一些资料。

3.1.场景代码

在这里插入图片描述

3.2.自定义模型的渲染

【Qt3DExample】

3.3.绘制直线或者网格

【how-do-i-draw-a-simple-line-in-Qt3D】

int drawOriginGrid(const int rows,
                   const int cols,
                   const float step,
                   const QColor& color,
                   Qt3DCore::QEntity *_rootEntity)
{
    auto *geometry = new Qt3DRender::QGeometry(_rootEntity);

    QList<QVector3D> vertexList;
    // 横线
    for(int i = -rows; i <= rows; i++)
    {
        vertexList << QVector3D(cols  * step, 0, i * step);
        vertexList << QVector3D(-cols * step, 0, i * step);
    }
    // 竖线
    for(int i = -cols; i <= cols; i++)
    {
        vertexList << QVector3D(i * step, 0, rows * step);
        vertexList << QVector3D(i * step, 0, -rows * step);
    }
    QByteArray bufferBytes;
    bufferBytes.resize(3 * vertexList.length() * sizeof(float));
    float *positions = reinterpret_cast<float*>(bufferBytes.data());

    for(int i = 0; i < vertexList.length(); i++)
    {
        QVector3D vertex = vertexList.at(i);
        *positions++ = vertex.x();
        *positions++ = vertex.y();
        *positions++ = vertex.z();
    }

    auto *buf = new Qt3DRender::QBuffer(geometry);
    buf->setData(bufferBytes);

    auto *positionAttribute = new Qt3DRender::QAttribute(geometry);
    positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
    positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
    positionAttribute->setVertexSize(3);
    positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
    positionAttribute->setBuffer(buf);
    positionAttribute->setByteStride(3 * sizeof(float));
    positionAttribute->setCount(vertexList.length());
    geometry->addAttribute(positionAttribute); // We add the vertices in the geometry

    // connectivity between vertices
    QByteArray indexBytes;
    indexBytes.resize(2 * vertexList.length() * sizeof(unsigned int));
    unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
    for(int i = 0; i < vertexList.length(); i++)
    {
        *indices++ = i;
    }

    auto *indexBuffer = new Qt3DRender::QBuffer(geometry);
    indexBuffer->setData(indexBytes);

    auto *indexAttribute = new Qt3DRender::QAttribute(geometry);
    indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
    indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
    indexAttribute->setBuffer(indexBuffer);
    indexAttribute->setCount(vertexList.length());
    geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry

    // mesh
    auto *line = new Qt3DRender::QGeometryRenderer(_rootEntity);
    line->setGeometry(geometry);
    line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
    auto *material = new Qt3DExtras::QPhongMaterial(_rootEntity);
    material->setAmbient(color);
    material->setDiffuse(color);

    // entity
    auto *lineEntity = new Qt3DCore::QEntity(_rootEntity);
    lineEntity->addComponent(line);
    lineEntity->addComponent(material);

    return 0;
}

4.有待解决的一些问题

4.1.线宽的设置、背面消隐(culling)的设置

有资料说可以通过QRenderStateSet来设置,但是我设置了并没有得到有效的效果

    Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x2b2b2b)));

    if(0)
    {
        using namespace Qt3DRender;

        qDebug() << "frameGraph:" << view->defaultFrameGraph() << view->activeFrameGraph();

        Qt3DRender::QRenderSurfaceSelector *surSel;
        auto childNodeList = view->activeFrameGraph()->childNodes();
        foreach (Qt3DCore::QNode * childNode, childNodeList) {
            qDebug() << "child:" << childNode;
            if(qobject_cast<Qt3DRender::QRenderSurfaceSelector*>(childNode))
            {
                surSel = qobject_cast<Qt3DRender::QRenderSurfaceSelector*>(childNode);
            }
        }
        qDebug() << surSel->childNodes() << surSel->childNodes()[0]->childNodes()
                 << surSel->childNodes()[0]->childNodes()[0]->childNodes();

        qDebug() << surSel->childNodes()[0]->childNodes()[0]->childNodes()[0];

        ((Qt3DRender::QClearBuffers*)(surSel->childNodes()[0]->childNodes()[0]->childNodes()[0]))
            ->setBuffers(QClearBuffers::ColorDepthBuffer);

        QRenderStateSet *renderStateSet = new QRenderStateSet(surSel->childNodes()[0]->childNodes()[0]);
        QCullFace *cullFace = new QCullFace();
        cullFace->setMode(QCullFace::NoCulling);
        // renderStateSet->addRenderState(cullFace);

        QLineWidth *lineWidth = new QLineWidth();
        lineWidth->setValue(100);
        // renderStateSet->addRenderState(lineWidth);

        QPointSize *ptSize = new QPointSize();
        ptSize->setValue(100);
        // renderStateSet->addRenderState(ptSize);

        qDebug() << surSel->childNodes()[0]->childNodes()[0]->childNodes();
    }

4.2.法线的问题

目前好像是支持点法线,不支持面法线,假如使用index模式来渲染面片时,会渲染出奇怪的效果
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15.1 Zookeeper简介安装及基础使用

1. Zookeeper介绍 1.1 介绍 1.2 应用场景简介 1.3 zookeeper工作原理 1.4 zookeeper特点

低代码平台下的用户中心开发:构建高效系统的新趋势

前言 随着数字化转型的深入&#xff0c;低代码开发平台因其快速、灵活的特性越来越受到企业的青睐。用户中心作为用户管理和服务的核心模块&#xff0c;对提升用户体验和增强用户粘性具有重要作用。本文将探讨如何利用低代码平台高效地构建用户中心&#xff0c;满足快速变化的…

英伟达开始引领下一波浪潮:物理AI

这可能会是AI技术形态的一个转折点,大模型的下一个形态&#xff0c;不再是人和模型一轮一轮的即时问答了。 当地时间 7 月 29 日&#xff0c;在美国丹佛举行的第 51 届 SIGGRAPH 计算机图形学会议上&#xff0c;英伟达创始人、CEO 黄仁勋与 Meta 创始人、CEO 马克・扎克伯格进…

编程技巧:如何优雅地合并两个有序数组?

目录 题目引用描述1.直接合并 排序2.指针3.后逆向双指针进阶&#xff1a;你可以设计实现一个时间复杂度为 O(m n) 的算法解决此问题吗&#xff1f;总结 题目 来自力扣 引用 合并两个有序数组 给你两个按 **非递减顺序 **排列的整数数组 nums1 和 nums2&#xff0c;另有两个整…

用友时空KSOA 多处 SQL注入漏洞复现

0x01 产品简介 用友时空 KSOA 是建立在 SOA 理念指导下研发的新一代产品,是根据流通企业前沿的 IT 需求推出的统一的IT基础架构,它可以让流通企业各个时期建立的 IT 系统之间彼此轻松对话。 0x02 漏洞概述 用友时空KSOA系统 PrintZP.jsp、PrintZPFB.jsp、PrintZPYG.jsp、P…

单细胞|MEBOCOST·基于代谢物的细胞通讯预测(一)

import os,sys import scanpy as sc import pandas as pd import numpy as np from matplotlib import pyplot as plt import seaborn as sns from mebocost import mebocost 1. 创建 mebocost 对象 adata sc.read_h5ad(data/demo/raw_scRNA/demo_HNSC_200cell.h5ad) ## che…

鸿蒙应用框架开发【首选项】 本地数据与文件

首选项 简介 本示例使用ohos.data.preferences接口&#xff0c;展示了使用首选项持久化存储数据的功能。 效果预览 使用说明 1.点击顶部titleBar的右侧切换按钮&#xff0c;弹出主题菜单&#xff0c;选择任意主题则切换相应的主题界面&#xff1b; 2.退出应用再重新进入&a…

【简历】广东某二本大学:JAVA秋招简历指导,简历通过率比较低

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份25届二本Java同学的简历。二本同学因为学校本身不是特别出彩&#xff0c;求职目标基本是小公司。并且这个同学项目部分重复度非…

Python环境搭建与PyCharm安装激活教程

一、Python环境搭建 标题&#xff1a;下载Python解释器 步骤1&#xff1a;访问Python官网 打开浏览器&#xff0c;输入Python官方网站地址&#xff1a;Welcome to Python.org。 步骤2&#xff1a;下载Python安装包 将鼠标移动到Downloads菜单上&#xff0c;选择适合你操作…

【区块链+绿色低碳】北京:全国首例区块链 + 绿色出行项目 | FISCO BCOS应用案例

在 2021 年全国两会上&#xff0c;“碳达峰”和“碳中和”被首次写入《政府工作报告》&#xff0c;我国争取在 2030 年前实现“碳达峰”&#xff0c; 2060 年前实现“碳中和”。随着经济社会的快速发展、工业化和城镇化进程不断加快&#xff0c;交通运输领域作为碳排放“大 户”…

智能小家电的跨境渠道有哪些?入驻百思买还是选择做亚马逊?——WAYLI威利跨境助力商家

在全球化贸易背景下&#xff0c;智能小家电企业面临机遇与挑战。消费者追求高品质生活&#xff0c;智能小家电市场需求旺盛&#xff0c;跨境销售成为拓展市场、提升品牌影响力的关键。选择合适的跨境渠道至关重要。以下是智能小家电跨境销售的主要渠道&#xff0c;并深入分析了…

爆款!288页Python核心知识笔记(附思维导图,建议收藏)

不少朋友在学习Python时&#xff0c;都会做大量的笔记&#xff0c;随着学习进度的增加&#xff0c;笔记越来越厚&#xff0c;但有效内容反而越来越少。 今天就给大家分享一份288页Python核心知识笔记&#xff0c;相较于部分朋友乱糟糟的笔记&#xff0c;这份笔记更够系统地总结…

对JAVA的包package的理解

一直理解不了java中的包&#xff0c;包括下图中的这种在几乎每个java程序的开头都有的import和package。今天在实际应用中突然理解了。 第一行代码 package org.example 是用来标识当前这个Java文件属于org.example。这里说明一下&#xff0c;通常一个.java文件就是一个Java类…

【Webpack 踩坑】img 标签图片加载不出来

问题&#xff1a;在html的img标签路径解析错误&#xff0c;导致加载不出来 一直用框架开发&#xff0c;好久没用过webpack写原生代码&#xff0c;一下子踩了好多坑… 图片位置&#xff1a; 其中一个就是在html中写了图片地址&#xff1a; <!-- src/pages/index.html --&…

鸿蒙(HarmonyOS)DatePicker+TimePicker时间选择控件

一、操作环境 操作系统: Windows 11 专业版、IDE:DevEco Studio 3.1.1 Release、SDK:HarmonyOS 3.1.0&#xff08;API 9&#xff09; 二、效果图 可实现两种选择方式&#xff0c;可带时分选择&#xff0c;也可不带&#xff0c;使用更加方便。 三、代码 SelectedDateDialog…

Qt for MCUs 2.8 LTS已发布

本文翻译自&#xff1a;Qt for MCUs 2.8 LTS released 原文作者&#xff1a;Qt Group高级产品经理Yoann Lopes 我们很高兴地宣布Qt for MCUs 2.8 LTS版本已发布&#xff0c;该版本带来了激动人心的新变化&#xff0c;如GUI的构建模块、构建工具工作流程的改进、对Infineon TRA…

书生大模型实战营闯关 - 8GB显存玩转书生大模型demo

创建开发机 创建一个使用10%GPU算力&#xff0c;cuda12.2系统的开发机&#xff0c;并启动。由于开发机的IO性能较差&#xff0c;开发机共享盘中已经创建好了本次实验所需要的conda环境 # 启动共享的conda环境 conda activate /root/share/pre_envs/icamp3_demo部署cli模型 创…

解读Solana流动性质押发展现状:市场格局的悄然转变

随着区块链技术的发展和去中心化金融&#xff08;DeFi&#xff09;生态系统的壮大&#xff0c;流动性质押&#xff08;Liquid Staking&#xff09;已经成为市场中的热门话题。尽管以太坊在这一领域占据了主导地位&#xff0c;但Solana也在快速追赶&#xff0c;并展现出其独特的…

微服务事务管理(分布式事务问题 理论基础 初识Seata XA模式 AT模式 )

目录 一、分布式事务问题 1. 本地事务 2. 分布式事务 3. 演示分布式事务问题 二、理论基础 1. CAP定理 1.1 ⼀致性 1.2 可⽤性 1.3 分区容错 1.4 ⽭盾 2. BASE理论 3. 解决分布式事务的思路 三、初识Seata 1. Seata的架构 2. 部署TC服务 3. 微服务集成Se…

通俗易懂生成式人工智能(Generative AI)

生成式人工智能&#xff08;Generative AI&#xff09; 人工智能是目标&#xff0c;生成式人工智能就是我们的目标之一。 基本概念 什么是生成式人工智能&#xff1f; 生成式人工智能就是让机器产生复杂的、有结构的物件&#xff0c;如&#xff1a;文本、语音、图像等。而这…