OpenMesh模型分割:区域增长实现

编程入门 行业动态 更新时间:2024-10-11 07:25:39

OpenMesh<a href=https://www.elefans.com/category/jswz/34/1771358.html style=模型分割:区域增长实现"/>

OpenMesh模型分割:区域增长实现

​ 将一个数据结构的模型OpenMesh进行分割,用区域增长的方式,来遍历所有,且此算法耗时比较短。

文章目录

    • 本博文的简述or解决问题?
    • 思路:
    • 代码:
    • 效率:
    • 更新:

本博文的简述or解决问题?

​ 将一个数据结构的模型OpenMesh进行分割,用区域增长的方式,来遍历所有,且此算法耗时比较短。

编程环境: Win10 x64 专业版

编程软件: visual studio 2015

本文初发于 “偕臧的小站“,同步转载于此。

思路:

  1. 将所有的面进行标记为-1(表示没有属于那一块)和false(表示还没有遍历过)
  2. 选择一个种子面fhSeed,然后向它的周边相邻的(三个)面进行区域增长,也给做上标
  3. 对于这三个面,也把它作为一个新的面,然后向自己周边进行增长(然后辐射周边)
  4. 然后用一个小的容器储存,正在增长的面,每次增长结束,就把自己这个已经遍历过的面,从容器中删除,当容器值为0的时候,便是一块完整的被遍历出来了
  5. 重复以上2-3-4步骤
  6. 将已经遍历了的面,打上标记,已经标记了的,不在标记;当所有的面全部都遍历结束,也就分割开了(这样的话,一个物体的面,属于哪一块,都被标记出来了)。

代码:

​ 假设其中的一个模型变量为 :RefineMesh refineMeshNew;

OpenMesh::FPropHandleT<int> FPropTriMark;    //属于那一块OpenMesh::FPropHandleT<bool> FPropTriFlag;   //是否遍历过refineMeshNew.add_property(FPropTriMark, "FPropTriMark");refineMeshNew.add_property(FPropTriFlag, "FPropTriFlag");for (auto f_it = refineMeshNew.faces_begin(); f_it != refineMeshNew.faces_end(); f_it++){refineMeshNew.property(FPropTriMark, *f_it) = -1;refineMeshNew.property(FPropTriFlag, *f_it) = false;}int nMark = 0; //标记属于哪一块Mesh//外层循环------------------------------------------------------------------------------while (true){//外层结束标志OpenMesh::FaceHandle fhSeed;for (auto f_itTemp = refineMeshNew.faces_begin(); f_itTemp != refineMeshNew.faces_end(); f_itTemp++){if (!refineMeshNew.property(FPropTriFlag, *f_itTemp)){fhSeed = *f_itTemp;break;}}if (!fhSeed.is_valid())break;refineMeshNew.property(FPropTriFlag, fhSeed) = true;refineMeshNew.property(FPropTriMark, fhSeed) = nMark;vector<OpenMesh::FaceHandle> vecMarkFH;vecMarkFH.push_back(fhSeed);//内层循环------------------------------------------------------------------------------while (true){if (vecMarkFH.size() == 0)break;OpenMesh::FaceHandle fhTemp = vecMarkFH[0];for (auto ff_it = refineMeshNew.ff_iter(fhTemp); ff_it != refineMeshNew.ff_end(fhTemp); ff_it++){if (!refineMeshNew.property(FPropTriFlag, *ff_it)){refineMeshNew.property(FPropTriFlag, *ff_it) = true;refineMeshNew.property(FPropTriMark, *ff_it) = nMark;}}vecMarkFH.erase(vecMarkFH.begin());}nMark++;}//外层循环结束------------------------------------------------------------------------------

效率:

​ 经过测试,用此算法,遍历一个有四千多万(40, 000, 000多)个面的数据模型,只需要耗费时间约6s,比我自己先前写的一个思路,耗时效率要高得多

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

更新:

更新时间: 2019-7-9 17:35:43

更新内容: 增加有分割后的多个模型导出的代码分享

将下面的mesh替换成分割之后的pMesh,分割成为多个的时候,建议使用Vector<pMesh> v来存储,然后使用1行里面的代码替换掉meshv[i]即可;

提示: 因为上面代码已经将模型做了区分,然后使用for循环,直接按照标记所属于的,直接输出;亦可以即可将各自的点、面、半边、纹理等属性赋值给一个新的pMesh即可;

if (!OpenMesh::IO::write_mesh(mesh, "output.off"))std::cerr << "Cannot write mesh to file 'output.off'" << std::endl;

更多推荐

OpenMesh模型分割:区域增长实现

本文发布于:2024-02-11 16:15:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1681953.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模型   区域   OpenMesh

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!