当前位置: 首页 > news >正文

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

virtual void apply(osg::Geode& node) {for (int i = 0; i < node.getNumDrawables(); i++){osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(node.getDrawable(i));if (geometry){//apply(*g);//***********************************************//解析顶点osg::Array* vertexArray = geometry->getVertexArray();if (vertexArray == NULL)return;//顶点数组osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(vertexArray);long lVertNum = verts->size();std::vector<osg::Vec3 >::iterator iter_ver = verts->begin();//遍历顶点值for (; iter_ver != verts->end(); iter_ver++){double x = iter_ver->x();double y = iter_ver->y();double z = iter_ver->z();  }//纹理osg::Texture2D* tex2D = dynamic_cast<osg::Texture2D*>(geometry->getStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE));osg::Image* image = tex2D->getImage();osgDB::writeImageFile(*image, "abc.jpg");int width = image->s();int height = image->t();/*osg::Vec2 color;osg::Vec4 c = image->getColor(color);*///UVosg::Array* uvArry = geometry->getTexCoordArray(0);osg::Vec2Array* vertsUV = dynamic_cast<osg::Vec2Array*>(uvArry);std::vector<osg::Vec2 >::iterator iter_verUV = vertsUV->begin();std::vector<int> greenPointIndices;int i = 0;for (; iter_verUV != vertsUV->end(); iter_verUV++){double u = iter_verUV->x();double v = iter_verUV->y();osg::Vec2 color(u, v);osg::Vec4 c = image->getColor(color);float r = c.r() * 255;float g = c.g() * 255;float b = c.b() * 255;if (r < 100 && g < 100 && b < 100 )greenPointIndices.push_back(i);i++;}//索引int numP = geometry->getNumPrimitiveSets();osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt = new osg::DrawElementsUInt(GL_TRIANGLES);for (unsigned int ipr = 0; ipr < numP; ipr++){osg::PrimitiveSet* prset = geometry->getPrimitiveSet(ipr);unsigned int ncnt = prset->getNumIndices();for (unsigned int ic = 0; ic * 3 < prset->getNumIndices(); ic++){unsigned int iIndex0 = prset->index(ic * 3);unsigned int iIndex1 = prset->index(ic * 3 + 1);unsigned int iIndex2 = prset->index(ic * 3 + 2);bool find = false;for (int i = 0; i < greenPointIndices.size(); i++){if (greenPointIndices[i] == iIndex0 || greenPointIndices[i] == iIndex1 || greenPointIndices[i] == iIndex2){find = true;break;}}if (find)continue;else{drawElemUInt->push_back(prset->index(ic * 3));drawElemUInt->push_back(prset->index(ic * 3 + 1));drawElemUInt->push_back(prset->index(ic * 3 + 2));}}}osg::ref_ptr<osg::Geometry> geometry_new = new osg::Geometry();geometry_new->setVertexArray(verts);geometry_new->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex2D, osg::StateAttribute::ON);geometry_new->setTexCoordArray(0, uvArry);geometry_new->addPrimitiveSet(drawElemUInt);osg::Geode* pGeode_new = new osg::Geode;pGeode_new->removeDrawables(0, pGeode_new->getNumDrawables());pGeode_new->addDrawable(geometry_new);osgDB::writeNodeFile(*pGeode_new, "test.osgb", new osgDB::Options("WriteImageHint=IncludeData Compressor=zlib"));//***********************************************}}}

参考博主:osgb的顶点,纹理,索引,UV读取与存储_osgb获取顶点-CSDN博客

作为C++小白看这段代码的详细解读

这段代码是用 C++ 编写的,并使用了 OpenSceneGraph (OSG) —— 一个开源的高性能 3D 图形引擎,广泛用于地理信息系统、仿真、可视化等领域。

这段代码定义了一个虚函数 apply(osg::Geode& node),该函数的作用是:遍历一个三维模型,识别纹理上颜色较暗的区域,剔除那些区域对应的三角形网格,然后将剩余的“亮色”区域导出为一个新的 3D 模型文件

一、逐行详细解析

开始遍历Geode下的Drawable对象(通常是Geometry)

for (int i = 0; i < node.getNumDrawables(); i++)

遍历Geode中所有的Drawable(通常是osg::Geometry类型)

处理每个Geometry

osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(node.getDrawable(i));

尝试将 Drawable 转为 osg::Geometry 类型,如果转换成功,表示该对象是几何体。

解析顶点信息

osg::Array* vertexArray = geometry->getVertexArray();
osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(vertexArray);

获取顶点数组并强制转换为三维坐标数组(Vec3Array)

vert存储所有顶点坐标

for (; iter_ver != verts->end(); iter_ver++)
{double x = iter_ver->x();double y = iter_ver->y();double z = iter_ver->z();  
}

遍历每个顶点,获取其三维坐标(这里没做实际操作)

提取纹理图像

osg::Texture2D* tex2D = dynamic_cast<osg::Texture2D*>(geometry->getStateSet()->getTextureAttribute(0, ...));
osg::Image* image = tex2D->getImage();
osgDB::writeImageFile(*image, "abc.jpg");

获取贴在模型上的纹理(Texture2D)

提取出其中的图像(osg::Image)

保存图像为JPG文件(调试用途)

读取UV坐标+获取纹理颜色

osg::Array* uvArry = geometry->getTexCoordArray(0);
osg::Vec2Array* vertsUV = dynamic_cast<osg::Vec2Array*>(uvArry);

获取纹理坐标(UV)数组

for (; iter_verUV != vertsUV->end(); iter_verUV++)
{double u = iter_verUV->x();double v = iter_verUV->y();osg::Vec2 color(u, v);osg::Vec4 c = image->getColor(color);...
}

遍历每个顶点对应的纹理坐标(u,v)

从image图像中获取对应像素颜色c

判断颜色是否“偏暗”,若R、G、B分量都小于100(即为暗色或黑色点)

if (r < 100 && g < 100 && b < 100)greenPointIndices.push_back(i);

这些“暗黑点”会被记录到greenPointIndices中

处理索引,剔除包含暗黑点的三角面

osg::DrawElementsUInt* drawElemUInt = new osg::DrawElementsUInt(GL_TRIANGLES);

新建一个DrawElementsUInt类型的三角形集合,保存有效三角面索引。

for (ipr ...)
{for (ic ...){unsigned int iIndex0 = prset->index(ic * 3);...if (任意一个顶点是暗色点)continue;elsedrawElemUInt->push_back(三个顶点索引);}
}

遍历所有原始三角形

若三角形中有任意一个顶点在greenPointIndices中(即暗点),跳过不加入新网格。

其他三角面则加入drawElemUInt

构建新Geometry并导出为OSGB文件

osg::Geometry* geometry_new = new osg::Geometry();
geometry_new->setVertexArray(verts);
...
geometry_new->addPrimitiveSet(drawElemUInt);

构建一个新几何体,复用原始顶点和纹理坐标,仅替换三角面为“亮色区域”

osg::Geode* pGeode_new = new osg::Geode;
pGeode_new->addDrawable(geometry_new);
osgDB::writeNodeFile(*pGeode_new, "test.osgb", ...);

将新的几何体写入.osgb文件(OpenSceneGraph二进制模式格式)

相关文章:

  • PyQt学习系列04-多线程与异步编程
  • 3362. 零数组变换 III
  • Honeywell CV-DINA-DI1624-2A 数字输入模块
  • 【Web前端】JavaScript入门与基础(一)
  • 【软件测试】第三章·软件测试基本方法(逻辑覆盖、路径覆盖)
  • Redis 缓存使用的BigKey问题
  • Cesium基础对象介绍
  • MySQL别名规则与应用场景
  • 矩阵详解:线性代数在AI大模型中的核心支柱
  • 【ICL】上下文学习
  • 英语写作中“假设”suppose, assume, presume 的用法
  • Arthas(阿尔萨斯)
  • C++高效求解非线性方程组的实践指南
  • 第一个Python程序
  • 主类网络和无类网络,什么是主类网络边界
  • 5.23 打卡
  • 淘宝卖家评价等级如何区分?如何提升信誉等级?
  • centos原系统安装了Python3.7.9兼用在安装一个python3.8
  • 【JS】vue3具名导出与默认导出
  • 人工智能在优化算法与大规模求解器中的应用与发展
  • 做网站还能赚钱吗/民生热点新闻
  • 阿里云虚拟主机怎么建立网站/开发网站的公司
  • 外链seo服务/优化提升
  • 网站建设捌金手指花总十六/网站排名靠前
  • 河南教育平台网站建设/小程序源码网
  • 如何在网站做旅游产品/广州营销seo