NodeVisitor的使用-遍历Geode节点下的Geometry并获取顶点、法向量等数据

OSG获取模型坐标点、索引、法向量、纹理等数据 (文章很长,如果想直接看源码不想听我啰嗦的话,请直接跳到最后下载源码) 如果要做针对模型的算法,获取模型中所有图元(由于OSG多边形只支持三角形图元,而且自己做的科研也是针对三角网模型的,本文就针对三角形模型来说明)的坐标、纹理、法向量等数据,然后再进行处理是非常重要的,但是网上关于获取图元属性的教程实在太少,而且有的说的也不是很清楚,自己在做科研的过程中,探索以后,记录在此,希望能帮助到有需要... 阅读详情
struct Subset
{
    std::vector<float> vertexs;//位置
    std::vector<float> normals;//法向
    std::vector<float> texCoords;//纹理
    std::vector<unsigned int> indices;//索引下标
    std::vector<unsigned int> faceMtrls;//面材质索引
};

class GetSimplifySTLDataVisitor : public osg::NodeVisitor
{
public:
    GetSimplifySTLDataVisitor(Subset &s):dstSubset(s),
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
    {
    }

    virtual void apply(osg::Geode& geode)
    {
        unsigned int count = geode.getNumDrawables();
        for ( unsigned int i = 0; i < count; i++ )
        {
            osg::Geometry *geometry = geode.getDrawable( i )->asGeometry();
            if ( !geometry )
                continue;
            // 顶点数据
            osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
            int vertexlNum = vertices->size();
            for ( int i=0; i<vertexlNum; i++) {
                dstSubset.vertexs.push_back( vertices->at(i).x() );
                dstSubset.vertexs.push_back( vertices->at(i).y() );
                dstSubset.vertexs.push_back( vertices->at(i).z() );
            }
            // 法向量
            osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
            int normalNum = normals->size();
            for (int i=0; i<normalNum; i++) {
                dstSubset.normals.push_back( normals->at(i).x() );
                dstSubset.normals.push_back( normals->at(i).y() );
                dstSubset.normals.push_back( normals->at(i).z() );
            }
            normalBindKinds.insert(geometry->getNormalBinding());
            if(osg::Geometry::BIND_PER_VERTEX != geometry->getNormalBinding() )
            {
                std::string msg="未处理的法向量绑定方式";
                MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
            }
            // 索引数组
            for ( unsigned int i = 0; i < geometry->getNumPrimitiveSets(); ++i )
            {
                osg::PrimitiveSet* ps = geometry->getPrimitiveSet( i );
                if ( !ps ) continue;
                pts.insert(ps->getType());
                modes.insert(ps->getMode());
                switch( ps->getType() )
                {
                case osg::PrimitiveSet::DrawElementsUIntPrimitiveType :
                    {
                        osg::DrawElementsUInt* deui = dynamic_cast<osg::DrawElementsUInt*>(ps);
                        const unsigned indexNum = deui->getNumIndices();
                        switch( deui->getMode() )
                        {
                        case osg::PrimitiveSet::TRIANGLES :
                            {
                                for (unsigned int i=0; i<indexNum; i++) 
                                {
                                    dstSubset.indices.push_back( deui->at(i) );
                                }
                                break;
                            }
                        default:
                            {
                                std::string msg="未处理的绘制模式";
                                MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                            }
                        }
                        break;
                    }
                case osg::PrimitiveSet::DrawElementsUShortPrimitiveType :
                    {
                        osg::DrawElementsUShort* de = dynamic_cast<osg::DrawElementsUShort*>(ps);
                        const unsigned indexNum = de->getNumIndices();
                        switch( de->getMode() )
                        {
                        case osg::PrimitiveSet::TRIANGLES :
                            {
                                for (unsigned int i=0; i<indexNum; i++) 
                                {
                                    dstSubset.indices.push_back( de->at(i) );
                                }
                                break;
                            }
                        case osg::PrimitiveSet::TRIANGLE_STRIP :
                            {
                                for (unsigned int i=0; i<indexNum-2; i++) 
                                {
                                    //此处索引为何与基数偶数有关,可百度GL_TRIANGLE_STRIP
                                    if (i%2==0)
                                    {
                                        dstSubset.indices.push_back( de->at(i) );
                                        dstSubset.indices.push_back( de->at(i+1) );
                                        dstSubset.indices.push_back( de->at(i+2) );
                                    }
                                    else
                                    {
                                        dstSubset.indices.push_back( de->at(i) );
                                        dstSubset.indices.push_back( de->at(i+2) );
                                        dstSubset.indices.push_back( de->at(i+1) );
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                std::string msg="未处理的绘制模式";
                                MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                            }
                        }
                        break;
                    }
                case osg::PrimitiveSet::DrawArraysPrimitiveType :
                    {
                        osg::DrawArrays* da = dynamic_cast<osg::DrawArrays*>(ps);
                        int first=da->getFirst();
                        int count=da->getCount();
                        switch( da->getMode() )
                        {
                        case osg::PrimitiveSet::TRIANGLES :
                            {
                                for ( int i=first; i<first+count; i++) {
                                    dstSubset.indices.push_back( i );
                                }
                                break;
                            }
                        case osg::PrimitiveSet::TRIANGLE_STRIP :
                            {
                                for ( int i=first; i<first+count-2; i++) {
                                    if(i%2==0)
                                    {
                                        dstSubset.indices.push_back( i );
                                        dstSubset.indices.push_back( i+1 );
                                        dstSubset.indices.push_back( i+2 );
                                    }
                                    else
                                    {
                                        dstSubset.indices.push_back( i );
                                        dstSubset.indices.push_back( i+2 );
                                        dstSubset.indices.push_back( i+1 );
                                    }
                                }
                                break;
                            }
                        default:
                            {
                                std::string msg="未处理的绘制模式";
                                MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                            }
                        }
                        break;
                    }
                default:
                    {
                        std::string msg="未处理的图元类型";
                        MessageBox(0, LPCTSTR(msg.c_str()), "警告", MB_OK);
                    }
                }
            }
        }
    }
private:
    Subset &dstSubset;
    //以下三个数组用来测试
    std::set<osg::Geometry::AttributeBinding> normalBindKinds;
    std::set<osg::PrimitiveSet::Type> pts;
    std::set<GLenum> modes;
};

 

OSG得到OSGB中几何体顶点、法向量、三角形数据并可视化 得到OSGB中几何体顶点、法向量、三角形数据过程如下: 首先将osgb文件读取到node中 osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(name); 然后自己编写Positionvisitor类,继承于NodeVisitor PositionVisitor visitor = PositionVisitor(modelName,textSize); 然后node的accept函数可以调用visitor的apply函数,.. 阅读详情

相关推荐

osgEarth拾取点、线、面(借助于osgEarth::IntersectionPicker)

进行人机交互时,经常需要拾取场景中的点、线、面,而osg中提供了LineSegmentIntersector和PolytopeIntersector两种相交检测方法。 LineSegmentIntersector的实现原理是利用射线与场景求交,因此只能检测射线与平面是否相交; PolytopeIntersector的实现原理是构造一个五个面的视锥体,检测在场景中与视锥体相交的物体。 本文中使用osgEarth::IntersectionPicker实现点、线、面的求交。 下面的代码既可以拾取单个物体

weixin_44847667的博客 4105

osgb的顶点,纹理,索引,UV读取与存储

geode中顶点对应UV色彩在阈值范围内的三角形删除,并生成新的geode保存成osgb文件输出

whl0071的专栏 1806

OSG拾取点、线和面 -- 实现点云拾取

在计算机图形学中,点云是由大量的离散点组成的集合,常用于三维重建、模型生成等领域。在源代码中,我们首先创建了一个包含点云的场景,并将其渲染到视图中。然后,我们实现了一个拾取事件处理器,在用户点击时进行拾取操作,并得到被点击位置的坐标。点云拾取是指在三维场景中,根据用户鼠标点击位置确定其所在的点云位置,并进行相应的操作。综上所述,本文介绍了如何在OSG中实现对点云的拾取功能,并提供了相关的源代码。通过这些步骤,开发者可以方便地在三维场景中与点云进行交互,并进行相应的操作。希望本文能对您有所帮助!

QfcaLinux的博客 1183

OSG使用Geometry绘制自定义图形、更新修改绘制数据、绘制带边线图形(多 PrimitiveSet 绘制)

OSG使用Geometry绘制自定义图形、更新修改绘制数据、绘制带边线图形(多 PrimitiveSet 绘制)

qq_45523399的博客 1356

OSG编程指南<十>:OSG几何体的绘制

OSG场景基本绘图类讲解、几何体的绘制、OSG预定义几何体及多边形分格化。

欧特GO 2893

ad新版本学习笔记(基本包含一套流程)Altium Designer(ad20/ad21/ad22/ad23)

ad20-ad23学习笔记,逐渐补全

安和的博客 4万+

osg::NodeVisitor

[1]osg::Group        [2]osg::PositionAttitudeTransform        [2]osg::MatrixTransform                [3]osg::Geode        [2]osg::MatrixTransform        [2]osg::MatrixTransform        [2]osg::MatrixTr...

weixin_30361641的博客 267

eNSP网络构建—建立小型局域网

企业私有网络构建运维 实战案例——使用模拟器构建局域网络 案例分析 1.架构分析 (1)需求分析 本实验的目的在于建立小型局域网。由于公司由不同部门组成,并分布在不同地点,因此需要划分不同网络实现互联互通。设计以下网络:两个部门各使用一台交换机连接,然后连接到总交换机,再通过路由器与外网以及其他部门网络相连。为了控制网络上的广播风暴,增加网络的安全性,在交换机上需要设置VLAN,在路由器与交换机之...

_ 4万+

osg::NodeVisitor example

[0]osg::Group    [1]osg::MatrixTransform    [1] osg::MatrixTransform    [1]osg::MatrixTransform        [2] osg::Geode            [3]osg::Geometry            [3]osg::Geometry            [3] osg::Geomet...

weixin_30296405的博客 211

别再为数据发愁了!盘点5个公开可用的医学图像数据集(含MRI/CT/PET合成任务)

本文详细介绍了5个高质量的公开医学图像数据集,涵盖MRI、CT和PET三大模态,适用于深度学习模型训练和医学图像合成任务。每个数据集均提供下载指南、预处理技巧和PyTorch加载示例,帮助研究人员快速获取和处理数据,解决医学AI开发中的数据瓶颈问题。

weixin_30689307的博客 523

FDTD超表面仿真详细教程,几何相位,共振相位,传播相位

FDTD的超表面主要几何相位型(PB型)和共振型两种类型,其中PB型每个cell中的纳米棒的长宽相同,旋转角度不同,共振型长宽不同,旋转角度相同。本博文中以最常见的长方形纳米棒为例,用FDTD演示两种超表面实现的聚焦透镜的功能,包含详细步骤,其他形状,材料的超表面可自行尝试。

wuyuerhhg的博客 3万+

OSG学习:纹理映射(五)——计算纹理坐标

以下内容来自:  1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社  2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社 3、自己的总结 下载完整工程OSG_13_TextureCoords 创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第...

韶光 7119

2026年运维工程师常见面试选择题

这篇文章总结了30道Linux运维面试常见问题及解析,涵盖基础命令、系统监控、故障排查、数据库、缓存、容器编排等多个方面。主要内容包括: 基础命令使用:如df查看磁盘、free查看内存、top监控进程等 系统监控与故障排查:负载判断、端口检查、进程管理等 中间件相关:Nginx状态码、MySQL主从复制、Redis缓存问题 容器技术:Docker优势、Kubernetes作用 运维理念:高可用、监控告警、发布策略、备份容灾 工作原则:故障处理优先级、运维工程师核心能力 文章不仅提供标准答案,还解析了各命令的

不务正业的猿 193

osg visitor 扩展

#include "stdafx.h" #include <iostream> #include <osg/NodeVisitor> #include <osg/Node> #include "osg/Group" #include "osgDB/readfile" #include <osg/Geode> using namespace std; ...

artisans的专栏 266

【推荐100个unity插件】在unity快速生成3D人物自然姿势和动作,且支持按图像生成姿势—— Pose AI

PoseAI是一款基于肌肉的智能动画创作工具,通过神经网络和逆运动学技术实现自然姿势生成。主要功能包括:自动/手动角色设置、神经控制装备、姿态估计与预览等。工具支持从2D图像生成3D姿势,并能在编辑器中实时预览动画效果。其神经网络架构采用前馈网络与ResNet结合的方式,通过多层全连接和ReLU激活函数处理输入数据。PoseAI简化了动画制作流程,提供高效的姿势创作解决方案,适用于Unity游戏开发。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1358

在 SAP Fiori 中正确配置 Group 角色:从 PFCG 分配到首页呈现的完整链路

摘要:SAP Fiori项目中,用户登录后能否看到应用往往取决于角色配置而非前端开发。关键在于通过PFCG角色将launchpad designer中创建的tile group关联到用户角色。Catalog是应用池,group是用户首页可见的工作区。正确配置后,用户会看到角色对应的默认分组,同时保留个性化调整能力。项目实施中常见问题是应用开发完成但未正确配置group与角色关联,导致业务用户无法在首页看到应用入口。(150字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 164

Auto.js实现视频号点赞自动化

摘要:本文介绍了一个微信视频号自动化点赞的实现方案。通过定位点赞图标和数量容器,点击点赞按钮后检测点赞数变化,若发现取消点赞则自动补点。核心代码包括:1)获取点赞容器和图标;2)记录点赞前后数量;3)判断是否误取消并补点;4)循环执行点赞和滑动页面操作。该方案解决了滑动页面可能导致误取消点赞的问题,实现了自动化批量点赞功能。文章强调仅供学习参考,提醒勿滥用该技术。

分享前端工程化、AI 应用、Agent 开发与大模型实践! 2574

osg几何体的图元的遍历

转载用于:观察OSG的OPENGL下的顶点索引封装,组织方式

whl0071的专栏 966

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

osg_输出场景中的顶点

事实上不仅是绘制的图形有顶点,模型也是有顶点的 接下来用visitor取顶点,visitor和回调有所区别的是visitor是直接调用,不需要开始渲染就可以完成计算。 class VertexExtractor : public osg::NodeVisitor { public: osg::ref_ptr extracted_verts; VertexExtractor() : osg:

Scarlett_OHara的博客 1917

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

详解osgb的顶点,纹理,索引,UV读取与存储

详解osgb的顶点,纹理,索引,UV读取与存储中的C++代码

ganggun的博客 793

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

NodeVisitor的使用-遍历Geode节点并在它与父节点之间添加一个LOD节点

#include <osg\NodeVisitor>#include <osg\MatrixTransform>#include <osg\PagedLOD>#include <osgDB\FileNameUtils>#include <osg\Geode>#include <strstream> //只能处理osgExp插...

weixin_30709635的博客 214

osg节点遍历

简述     osg提供了一个遍历节点的类。osg::NodeVisitor,它提供一系列apply的 重载函数,用于访问某类型结点。  virtual void apply (LightSource &node) virtual void apply (Transform &node) virtual void apply (Camera &node) virtual void a

先锋小牛 4691

6、osg::Geode,osg::Drawable,osg::Shape,osg::Geometry,

一、osg::Geode类 类说明:Geode结点,是个几何结点,可以说是一个几何Group结点,一般的可绘制几何体都是通过它来传向root进行渲染。是OSG几何绘制的最高管理结点。 1、Geode ()       Geode (const Geode &, const CopyOp &copyop=CopyOp::SHALLOW_COPY) 说明:构造函数,第二个构造函数意思为从一

sxj的专栏 4611

osg节点统计方法(点数 面数)

void CMy3dsExportDlg::statusNode(osg::ref_ptr node,int& verNum,int& faceNum) {  osg::ref_ptr sv=new osgUtil::StatsVisitor();  sv->apply(*node);  sv->totalUpStats();  unsigned int unique_primitive

shui_zhi_lian的专栏 1346
上一篇: Qt5 QOpenGLWidget类
下一篇: 判断多边形边界曲线顺/逆时针 两种方法
HelloEarth_
博客等级 码龄9年 38粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值