首页 > 其他分享 >OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo

OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo

时间:2024-09-18 19:51:03浏览次数:3  
标签:Demo elementShellIndex qint64 kMode partIndex OSG listPart osg 加载

前言

  Osg需要打开模型文件,但是遇到显示动力学仿真的K模型文件,.k文件是一种描述材料属性的文件,比如密度、弹性模量等,该模型文件不是常规中间开放格式,无法直接支持,需要自定义解析并且重建三维模型。

<br>

Demo

  实际非常流程,因为视频转gif导致部分看起来不行:   请添加图片描述

  请添加图片描述

  请添加图片描述

<br>

交互流畅性测试

  实际研发需要用不同的策略进行在不影响视觉观感的前提下,进行模型展示优化处理,本次测试直接copy多份模型加载:

  • 172万多个四边形,丝滑   在这里插入图片描述

  • 344万多个四边形,丝滑   在这里插入图片描述

  • 518万多个四边形,开始稍微有点卡顿了   在这里插入图片描述

  • 691万多个四边形,开始更不利索了   此时翻倍就在加载场景崩溃,这个崩溃确认代码没问题,是运行内存较大了,加大运行时内存配置:

QMAKE_LFLAGS_WINDOWS += /LARGEADDRESSAWARE

  运行成功,交互更卡一点。   在这里插入图片描述

  更大又不行了:   在这里插入图片描述

<br>

注意

  分析的是本文件解析,可能包含数据格式关键字不全。   在这里插入图片描述

  实际遇到的为:*TITLE,*PART,*ELEMENT_SHELL,*NODE, *END。   (PS:以后项目上遇到了再另起篇章补充。)

<br>

K文件

概览

  .k文件是一种描述材料属性的文件,比如密度、弹性模量等。   打开其的软件LS-DYNA和LSPREPOST

  • LS-DYNA   LS-DYNA程序(最新版本17.2版)是功能齐全的几何非线性(大位移、大转动和大应变)、材料非线性(140多种材料动态模型)和接触非线性(50多种)程序。它以Lagrange算法为主,兼有ALE和Euler算法;以显式求解为主,兼有隐式求解功能;以结构分析为主,兼有热分析、流体-结构耦合功能;以非线性动力分析为主,兼有静力分析功能(如动力分析前的预应力计算和薄板冲压成型后的回弹计算);军用和民用相结合的通用结构分析非线性有限元程序,是显式动力学程序的鼻祖和先驱。
  • LSPREPOST   lsprepost是一套专为LS-DYNA开发的高级有限元前后处理软件,上线时间是1976年1月1日。   文件内容概览   文件整体概览如下:   在这里插入图片描述

  以上所知,分为六个关键字,分割为五个区域,归属关系如下:   在这里插入图片描述

关键字:*KEYWORK

关键字:*TITLE

关键字:*PART

  PART关键字来定义部件及其相关特性   在这里插入图片描述

  第一行为title属性,为标题,没有实际意义。   在这里插入图片描述

关键字:*ELEMENT_SHELL

  SECTION系列关键字指定所采用的单元算法、积分分规则及各种几何参数(壳单元的厚度、梁单元的截面信息参数等),对不同的单元类型,或者需要相应的SECTION关键字段来定义单元的算法和参数。   *SECTION_SEHLL定义单壳体单元的特性。这些属性对于模拟如汽车碰撞、航空航天结构、以及任何涉及薄壳结构动态响应的模拟都至关重要。然而,具体到ELEMENT_SHELL属性在K文件中的详细内容和格式,可能因LS-DYNA的版本和具体应用而有所不同。   在这里插入图片描述

  在这里插入图片描述

关键字:*NODE

  *NODE关键字来定义结构模型的每一节点及其在总体直角坐标系中的坐标及受约束情况,该关键字段包含如下的变量信息:   在这里插入图片描述   在这里插入图片描述

  然后部件与node的对应关系,通过索引对应:   在这里插入图片描述

  解析文件即可。

关键字:*END

  表示文件结束。

<br>

测试加载K文件

  在这里插入图片描述

  在这里插入图片描述

<br>

Demo关键源码

模型结构体

// 模型结构体
    struct Element_Shell    // *ELEMENT_SHELL
    {
        Element_Shell() {
        }
        qint64 eid;         // 单元id
        qint64 pid;         // 材料id
        qint64 n1;          // 节点1,定义几何形状
        qint64 n2;          // 节点2,定义几何形状
        qint64 n3;          // 节点3,定义几何形状
        qint64 n4;          // 节点4,定义几何形状
        qint64 n5;          // 厚度,额外的节点在标准的LS-DYNA四边形壳单元定义中是没有意义的。
        qint64 n6;          // 积分点数,额外的节点在标准的LS-DYNA四边形壳单元定义中是没有意义的。
        qint64 n7;          // 额外的节点在标准的LS-DYNA四边形壳单元定义中是没有意义的。
        qint64 n8;          // 额外的节点在标准的LS-DYNA四边形壳单元定义中是没有意义的。
    };
    struct Part             // *PART
    {
        Part() {
        }
        qint64 pid;         // 部件的id号,唯一
        qint64 secid;       // 有*section关键字定义的section的id号
        QList<Element_Shell> listElementShell;  // 部件片元
        qint64 mid;         // 部件的材料号
        qint64 eosid;       // 部件所属材料涉及的状态方程号,由*EOS关键字定义
        qint64 hgid;        // 沙漏或体积粘性参数编号,由*HOURGLASS关键字定义,取0表示将采用默认的数值:
        qint64 grav;        // 仅对实体单元有效,取0表示对所有PART进行重力初始化,取1表示仅对当前材料初始化
        qint64 adpopt;      // 标识该部件是否采用自适应网格划分,取0表示不采用
        qint64 tmid;        // 标识该部件是否采用自适应网格划分,取0表示不采用
    };
    struct Node {
        Node() {
        }
        qint64 nid;         // 结点号,唯一
        double x;           // 三维x坐标(全局)
        double y;           // 三维y坐标(全局)
        double z;           // 三维z坐标(全局)
        int tc;             // 平动自由度受约束状态,枚举值:0-无平动约束,1-X方向平动约束,2-Y方向平动约束
        int rc;             // 转动自由度收约束状态,枚举值:0-无转动约束,1-X方向转动约束,2-Y方向转动约束
    };
    struct K_Mode
    {
        K_Mode() {}
        QList<Part> listPart;
        QList<Node> listNode;
        QHash<int, Node> hashNid2Node;
    };

绘制部分

osg::ref_ptr<osg::Group> pGroup = new osg::Group;
// 绘图
{
    for(int partIndex = 0; partIndex < kMode.listPart.size(); partIndex++)
    {
        // 创建一个用户保存几何信息的对象
        osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry;
        // 创建四个顶点的数组
        osg::ref_ptr<osg::Vec3Array> pVec3Array = new osg::Vec3Array;
        // 添加四个顶点
        pGeometry->setVertexArray(pVec3Array.get());

        // 创建四种颜色的数据
        osg::ref_ptr<osg::Vec4Array> pVec4Array = new osg::Vec4Array;
        // 添加四种颜色
        pGeometry->setColorArray(pVec4Array.get());
        // 绑定颜色
        pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

        double r, g, b;
        r = qrand() % 100 * 1.0f / 100;
        g = qrand() % 100 * 1.0f / 100;
        b = qrand() % 100 * 1.0f / 100;
        for(int elementShellIndex = 0; elementShellIndex < kMode.listPart.at(partIndex).listElementShell.size(); elementShellIndex++)
        {
            //                               x     y     z
#if 0
            pVec3Array->push_back(osg::Vec3( 1.0, 0.0, 0.0));
            pVec3Array->push_back(osg::Vec3( 3.0, 0.0, 0.0));
            pVec3Array->push_back(osg::Vec3( 3.0, 0.0, 1.0));
            pVec3Array->push_back(osg::Vec3( 1.0, 0.0, 1.0));
#endif
            pVec3Array->push_back(osg::Vec3(kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n1).x,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n1).y,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n1).z));
            pVec3Array->push_back(osg::Vec3(kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n2).x,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n2).y,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n2).z));
            pVec3Array->push_back(osg::Vec3(kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n3).x,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n3).y,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n3).z));
            pVec3Array->push_back(osg::Vec3(kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n4).x,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n4).y,
                                            kMode.hashNid2Node.value(kMode.listPart.at(partIndex).listElementShell.at(elementShellIndex).n4).z));


            //                               r    g    b    a(a设置无效,估计需要其他属性配合)
            pVec4Array->push_back(osg::Vec4(r, g, b, 1.0));
            pVec4Array->push_back(osg::Vec4(r, g, b, 1.0));
            pVec4Array->push_back(osg::Vec4(r, g, b, 1.0));
            pVec4Array->push_back(osg::Vec4(r, g, b, 1.0));

        }
        // 注意:此处若不绑定画笔,则表示使用之前绑定的画笔

        // 为唯一的法线创建一个数组    法线: normal
        osg::ref_ptr<osg::Vec3Array> pVec3ArrayNormal = new osg::Vec3Array;
        pGeometry->setNormalArray(pVec3ArrayNormal.get());
        pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
        pVec3ArrayNormal->push_back(osg::Vec3(0.0, -1.0, 0.0));

        // 由保存的数据绘制四个顶点的多边形
        pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, kMode.listPart.at(partIndex).listElementShell.size() * 4));
//            pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

        // 向Geode类添加几何体(Drawable)
        osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
        pGeode->addDrawable(pGeometry.get());

        {
            osg::ref_ptr<osg::StateSet> pStateSet = pGeometry->getOrCreateStateSet();
            osg::ref_ptr<osg::PolygonMode> pPolygonMode = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
            pStateSet->setAttribute(pPolygonMode);
        }

        pGroup->addChild(pGeode);
    }
}

<br>

工程模板:对应版本号v1.32.0

  在这里插入图片描述

<br>

入坑

入坑一:绑定颜色不出来

问题

  去掉纹理后颜色不出来,显示一直灰色。

原理

  开启光照,就颜色不出来,需要关闭

解决

// 始终是灰色,这里需要设置关闭光照:OFF
osg::StateSet *pStateSet = pGroup->getOrCreateStateSet();
pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
//pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);

  在这里插入图片描述

  在这里插入图片描述

   在这里插入图片描述

入坑二:运行起来就崩溃

问题

  数据都加载绘制时,运行就崩溃

解决过程

  • 步骤一:先减少面数量,发现小于一档数量可以没问题,初步怀疑绘制太多,但是osg本身做深度测试相关很不错,除非时内存爆了,所以应然需要继续。
  • 步骤二:使用绘制四边形的,绘制10000个也会崩,加重了内存怀疑。
  • 步骤三:由于之前对于顶点颜色没有进行全部点绑定,其他的看纹理的方式都是重复的,所以这块就直接只设置了4个点,但本次去掉颜色之后,发现是可以的。
  • 步骤四:将颜色给他赋值上,一个部件一个纯色,把对应绑定点都补上,发现没问题

原因

  就是因为绑定颜色角点,只绑定了四个,按道理来说就算其越界也只是读取的乱值,颜色是乱的,但是点多了就不行了,所以这里还是需要一一对应,不偷懒。

解决

  颜色单独,每一个部件一个颜色,然后循环内一一对应:   在这里插入图片描述

标签:Demo,elementShellIndex,qint64,kMode,partIndex,OSG,listPart,osg,加载
From: https://blog.51cto.com/hongpangzi/12048195

相关文章

  • JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
    文章目录一、类加载器1.1什么是类加载器、类加载器作用1.2应用场景1.3类加载时机1.4类加载器分类1.4.1概述1.4.2JDK8及之前的版本1.4.3JDK9之后的类加载器二、双亲委派模型2.1什么是双亲委派模型2.2JVM为什么采用双亲委派机制2.3打破双亲委派机制2.4总结三......
  • 【北京迅为】iTOP-LS2K0500开发板快速使用编译环境ubuntu20.04第一章加载迅为提供 Ubu
    iTOP-LS2K0500开发板从CPU自主指令系统到开发板每一个元器件,做到100%全国产化。        【公众号】迅为电子,了解更多资讯-----------------------  第一章 加载迅为提供 Ubuntu20.041.1安装虚拟机VMware软件这里我们使用的是VMware15.5版本,当然其他版本也是可以,比如......
  • 【北京迅为】iTOP-LS2K0500开发板快速使用编译环境ubuntu20.04第一章加载迅为提供 Ubu
      iTOP-LS2K0500开发板从CPU自主指令系统到开发板每一个元器件,做到100%全国产化。        【公众号】迅为电子,了解更多资讯-----------------------  第一章加载迅为提供Ubuntu20.041.1安装虚拟机VMware软件这里我们使用的是VMware15.5版本,当然......
  • Electron加载服务器端JS:高效打造跨平台桌面应用与本地 API 交互
    在现代桌面应用开发中,使用Electron加载远程服务器托管的前端资源,再与本地API交互,能够带来灵活的部署和强大的本地功能支持。这种方式不仅提升了开发效率,还能充分利用PC端的资源和性能。本文将深入解析如何使用Electron实现这一架构,并探讨其背后的关键技术,包括ipcMain和......
  • 解决ZBLOG网站运行中出现"JavaScript加载失败"问题
    当Z-Blog网站运行中出现“JavaScript加载失败”的问题时,可能的原因有几个方面,包括但不限于插件冲突、HTTPS配置问题、CDN问题等。以下是针对这些问题的一些解决方案:1.插件冲突问题描述:某些插件可能与Z-Blog核心或其他插件存在冲突,导致JavaScript无法正常加载。解决......
  • zblog提示“JavaScript加载失败”的原因和解决办法
    当您在使用Z-Blog时遇到“JavaScript加载失败”的提示,这通常表明浏览器在加载某个或某些JavaScript文件时遇到了问题。以下是一些可能的原因及相应的解决方法:1.浏览器版本过低问题描述:使用的浏览器版本过低,不支持某些JavaScript功能。解决方法:升级到最新版本的浏览......
  • Selenium等待机制:理解并应用显式等待与隐式等待,解决页面加载慢的问题
    引言在Web自动化测试和网页数据抓取中,Selenium是一款非常流行的工具。然而,由于网络延迟、页面元素异步加载等原因,直接执行操作可能会导致元素未找到或操作失败。为了解决这个问题,Selenium提供了多种等待机制,其中最常用的是显式等待(ExplicitWait)和隐式等待(ImplicitWait)。本文将详......
  • ELF加载内存
    当一个ELF(ExecutableandLinkableFormat)文件加载到内存后,它的各个段会根据文件中的描述被映射到内存的不同区域。ELF文件被广泛用于Unix/Linux系统中的可执行文件、共享库和目标文件。典型的ELF文件包含多个段(sections),这些段被加载到内存中用于不同的目的,例如代码、数据、......
  • 请解释什么是CDN,以及它如何提高网站加载速度。
    CDN是什么?CDN(ContentDeliveryNetwork,内容分发网络)是一种广泛使用的网络基础设施,旨在提高互联网内容的传输效率。CDN通过在全球范围内布置多个边缘节点服务器(EdgeServers),将内容缓存到离用户最近的地方,从而减少了因地理位置造成的延迟,提高了内容的加载速度。CDN的工作原......
  • Qt加载天地图离线api开发包/从官网趴地图js代码/费了九牛二虎之力终于搞定
    一、前言说明网上关于如何趴天地图离线api文件的文章,只有少量的两三篇,而且几乎没有说全和说对,搞得评论也是一片懵逼,这里不行那你不行,思路可以借鉴就是。索性花了点时间,自己研究了如何从官网一步步趴下来js文件,最终所有离线能使用的功能全部搞定,也根本不会有http等访问的情况出现,......