詳解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二進制模式格式)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82490.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82490.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82490.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS闖關指南:從手寫地獄到“類”積木之旅|得物技術

一、背景 在Web開發網頁設計中&#xff0c;CSS&#xff08;層疊樣式表&#xff09;扮演著至關重要的角色&#xff0c;它用于控制網頁的布局、外觀和視覺效果。CSS不僅可以美化網頁的視覺表現&#xff0c;還可以提高網頁的可訪問性、可維護性和響應式設計。在我們進行網頁開發的…

【大模型應用開發】Qwen2.5-VL-3B識別視頻

0. 編寫代碼并嘗試運行 克隆以下代碼 git clone https://gitee.com/ai-trailblazer/qwen-vl-hello.git 嘗試運行qwen-vl-hello.py&#xff0c;報錯原因缺少modelscope&#xff1a; 1. 安裝qwen-vl-utils工具包 pip install qwen-vl-utils[decord]0.0.8 嘗試運行&#xff0c;…

MySQL 窗口函數深度解析:語法、應用場景與性能優化

一、窗口函數核心概念 ??本質??&#xff1a;對一組與當前行相關聯的行執行計算&#xff0c;??不改變原表行數?? ??與聚合函數的區別??&#xff1a; SELECT department, AVG(salary) -- 普通聚合&#xff1a;每個部門一行 FROM employees GROUP BY department;SE…

新版Chrome瀏覽器加載eDrawings 3D Viewer控件網頁查看DWG、DXF

eDrawings是一款由達索系統&#xff08;DASSAULT SYSTMES&#xff09;開發的免費跨平臺CAD看圖工具&#xff0c;專注于3D模型和2D工程圖的查看、協作與共享。其核心功能包括多格式支持、動態模型展示、跨平臺適配及輕量化操作體驗&#xff0c;適用于工程設計、教育培訓等領域。…

阿姆斯特朗數

阿姆斯特朗數也就是俗稱的水仙花數&#xff0c;是指一個n位數&#xff0c;其各位數字的n次方之和等于該數本身。例如&#xff0c;153是一個水仙花數&#xff0c;因為153&#xff1d;13&#xff0b;53&#xff0b;33。請問100-10000所有水仙花數有哪些。 采用窮舉法對范圍之間的…

vmvare 虛擬機內存不足

centos 擴展物理卷df -hT / sudo du -hx --max-depth1 / | sort -rh | head -n 20 // 查看前20個的大文件 # 清理舊日志&#xff08;保留最近7天&#xff09; sudo find /var/log -type f -mtime 7 -delete sudo journalctl --vacuum-time7d # 清理yum緩存 sudo yum clean …

C++?繼承!!!

一、引言 代碼的復用對于代碼的質量以及程序員的代碼設計上都是非常重要的&#xff0c;C中的許多特性都體現了這一點&#xff0c;從函數復用、模板的引入到今天我們將一起學習的&#xff1a;繼承 二、什么是繼承&#xff1f; 1、繼承的概念 繼承(inheritance)機制是面向對象程…

Android設置界面層級為最上層實現

Android設置界面層級為最上層實現 文章目錄 Android設置界面層級為最上層實現一、前言二、Android設置界面層級為最上層實現1、主要代碼2、后遺癥 三、其他1、Android設置界面層級為最上層小結2、懸浮框的主要代碼懸浮框 注意事項&#xff08;1&#xff09;權限限制&#xff08…

Linux 了解篇

一、GNU 項目與 GPL 許可 &#xff08;一&#xff09;GNU 項目 GNU &#xff1a;GNU 是一個遞歸縮寫&#xff0c;代表 "GNUs Not Unix"。GNU 項目旨在開發一個完全自由的操作系統&#xff0c;該操作系統基于 Unix 的設計理念但不包含 Unix 的代碼。GNU 項目提供了大…

word 如何讓公式居中,公式編號右對齊

問題&#xff1a; 如何讓輸入的公式居中&#xff0c;公式編號右對齊&#xff1f; 解決方法&#xff1a; 方法一&#xff1a;使用制表符 1、輸入內容&#xff1a;先按一次“Tab”鍵&#xff08;制表符&#xff09;&#xff0c;然后鍵入公式&#xff0c;然后再按一次“Tab”鍵…

華為OD機試真題——最小循環子數組 (2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳實現

2025 B卷 100分 題型 本專欄內全部題目均提供Java、python、JavaScript、C、C++、GO六種語言的最佳實現方式; 并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析; 本文收錄于專欄:《2025華為OD真題目錄+全流程解析+備考攻略+經驗分…

OpenCv高階(十七)——dlib庫安裝、dlib人臉檢測

文章目錄 前言一、dlib庫簡介二、dlib庫安裝1、本地安裝&#xff08;離線&#xff09;2、線上安裝 三、dlib人臉檢測原理1、HOG 特征提取2、 SVM 分類器訓練3、 滑動窗口搜索4、非極大值抑制&#xff08;NMS&#xff09; 四、dlib人臉檢測代碼1、導入OpenCV計算機視覺庫和dlib機…

AD-PCB--AD20軟件安裝及中英文切換 DAY 2

1.軟件安裝 1.1 軟件包下載 給你一個捷徑&#xff1a; 1.2 安裝過程&#xff08;安裝過的人跳過就好&#xff0c;一般很多都支持懶人安裝&#xff09; 雙擊其中的exe文件 點擊下一步 選擇中文 接受用戶協議 下面這個彈窗有的沒有。 建議勾選導入導出 安裝目錄&#xff0c…

單向循環鏈表與雙向鏈表

單向循環鏈表的原理與應用 思考&#xff1a;對于單向鏈表而言&#xff0c;想要遍歷鏈表&#xff0c;則必須從鏈表的首結點開始進行遍歷&#xff0c;請問有沒有更簡單的方案實現鏈表中的數據的增刪改查&#xff1f; 回答&#xff1a;是有的&#xff0c;可以使用單向循環的鏈表進…

Windows鼠標掉幀測試與修復

前言 這兩天突然發現鼠標似乎有掉幀&#xff0c;但是掉的又不太明顯&#xff0c;用著感覺似乎快速移動的時候會有一瞬間卡一下&#xff0c;但是眼睛又看不清楚&#xff0c;不太確定是不是自己的心理作用&#xff0c;非常難受。 如何判斷鼠標是否掉幀 根據我的經驗&#xff0…

U 盤數據恢復全攻略

目錄 &#x1f4be; U盤數據誤刪怎么辦&#xff1f;兩款實用工具助你找回丟失文件&#xff01;1?? Recover My Files&#xff1a;數據恢復的得力助手&#x1f4cc; 主要特點&#x1f6e0; 使用步驟詳解1. 下載與安裝2. 啟動軟件并選擇恢復類型3. 選擇U盤所在分區4. 選擇文件恢…

HarmonyOS NEXT~鴻蒙系統運維:全面解析與最佳實踐

HarmonyOS NEXT&#xff5e;鴻蒙系統運維&#xff1a;全面解析與最佳實踐 摘要 本文深入探討鴻蒙(HarmonyOS)系統的運維管理&#xff0c;從架構特點到日常維護操作&#xff0c;全面分析這一全場景分布式操作系統的運維要點。文章將介紹鴻蒙系統特有的分布式能力運維管理、性能…

基于 STM32 的智慧農業溫室控制系統設計與實現

摘要 本文提出一種基于 STM32 微控制器的智慧農業溫室控制系統設計方案,通過集成多類型環境傳感器、執行機構及無線通信模塊,實現對溫室內溫濕度、光照、土壤濕度等參數的實時監測與自動調控。文中詳細闡述硬件選型、電路連接及軟件實現流程,并附關鍵代碼示例,為智慧農業領…

Appium+python自動化(五)- 模擬器

簡介 Appium是做安卓自動化的一個比較流行的工具&#xff0c;對于想要學習該工具但是又局限于沒 android 手機來說&#xff0c;可以通過安卓模擬器來解決該問題&#xff0c;下面就講解使用appium連接安卓模擬器的操作步驟。而是由于手機數據線問題&#xff0c;也只好先用模擬器…

汽車充電樁專用ASCP210系列電氣防火限流式保護器

1.概述汽車充電樁專用電氣防火限流式保護器 電氣防火限流式保護器可有效克服傳統斷路器、空氣開關和監控設備存在的短路電流大、切斷短路電流時間長、短路時產生的電弧火花大&#xff0c;以及使用壽命短等弊端&#xff0c;發生短路故障時&#xff0c;能以微秒級速度快速限制短…