• 如何利用OpenMesh实现不同格式的3D文件间的转换


    可以进行的转化如下

    (出处链接见文末参考文档) 

    本文示例将文本格式(ASCII)的stl文件转化为二进制格式(Binary)。

    目录

    step 1 配置openmesh环境

    step2 代码实现

    step3 设置命令参数

    step 4 运行程序得到输出文件

    参考文档


    step 1 配置openmesh环境

    可以参考

    环境配置 | VS2017配置OpenMesh源码和环境

    step2 代码实现

    注:debug下跑得同,release下不行,也没搞清原因

    1. #include <iostream>
    2. #include <iterator>
    3. // -------------------- OpenMesh
    4. #include <OpenMesh/Core/IO/MeshIO.hh>
    5. #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
    6. #include <OpenMesh/Tools/Utils/getopt.h>
    7. // ----------------------------------------------------------------------------
    8. using namespace OpenMesh;
    9. // ----------------------------------------------------------------------------
    10. typedef TriMesh_ArrayKernelT<> MyMesh;
    11. // ----------------------------------------------------------------------------
    12. #define CHKROPT( Option ) \
    13. std::cout << " provides " << #Option \
    14. << (ropt.check(IO::Options:: Option)?": yes\n":": no\n")
    15. #define CHKWOPT( Option ) \
    16. std::cout << " write " << #Option \
    17. << (wopt.check(IO::Options:: Option)?": yes\n":": no\n")
    18. #define MESHOPT( msg, tf ) \
    19. std::cout << " " << msg << ": " << ((tf)?"yes\n":"no\n")
    20. // ----------------------------------------------------------------------------
    21. void parse_commandline(int _argc, char **_argv, MyMesh& _mesh,
    22. IO::Options &ropt, IO::Options &wopt);
    23. void usage_and_exit(int xcode);
    24. // ----------------------------------------------------------------------------
    25. int main(int argc, char **argv)
    26. {
    27. MyMesh mesh;
    28. IO::Options ropt, wopt;
    29. // -------------------- evaluate commandline
    30. parse_commandline(argc, argv, mesh, ropt, wopt);
    31. // -------------------- read mesh
    32. if (!IO::read_mesh(mesh, argv[optind], ropt))
    33. {
    34. std::cerr << "Error loading mesh from file " << argv[optind] << std::endl;
    35. return 1;
    36. }
    37. // -------------------- show options
    38. std::cout << "File " << argv[optind] << std::endl;
    39. std::cout << " is binary: "
    40. << (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n");
    41. std::cout << " byte order: ";
    42. if (ropt.check(IO::Options::Swap))
    43. std::cout << "swapped\n";
    44. else if (ropt.check(IO::Options::LSB))
    45. std::cout << "little endian\n";
    46. else if (ropt.check(IO::Options::MSB))
    47. std::cout << "big endian\n";
    48. else
    49. std::cout << "don't care\n";
    50. std::cout << " provides VertexNormal"
    51. << ( // strange layout for doxygen
    52. ropt.check(IO::Options::VertexNormal)
    53. ? ": yes\n" : ": no\n");
    54. CHKROPT(VertexColor);
    55. CHKROPT(VertexTexCoord);
    56. CHKROPT(FaceNormal);
    57. CHKROPT(FaceColor);
    58. // -------------------- mesh stats
    59. std::cout << "# Vertices: " << mesh.n_vertices() << std::endl;
    60. std::cout << "# Edges : " << mesh.n_faces() << std::endl;
    61. std::cout << "# Faces : " << mesh.n_faces() << std::endl;
    62. // -------------------- show write options
    63. std::cout << "Selected write options:\n";
    64. std::cout << " use binary: "
    65. << (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n");
    66. std::cout << " byte order: ";
    67. if (wopt.check(IO::Options::Swap))
    68. std::cout << "swapped\n";
    69. else if (wopt.check(IO::Options::LSB))
    70. std::cout << "little endian\n";
    71. else if (wopt.check(IO::Options::MSB))
    72. std::cout << "big endian\n";
    73. else
    74. std::cout << "don't care\n";
    75. std::cout << " write VertexNormal"
    76. << (wopt.check(IO::Options::VertexNormal) ? ": yes\n" : ": no\n");
    77. CHKWOPT(VertexColor);
    78. CHKWOPT(VertexTexCoord);
    79. CHKWOPT(FaceNormal);
    80. CHKWOPT(FaceColor);
    81. // -------------------- show mesh capabilities
    82. std::cout << "Mesh supports\n";
    83. MESHOPT("vertex normals", mesh.has_vertex_normals());
    84. MESHOPT("vertex colors", mesh.has_vertex_colors());
    85. MESHOPT("texcoords", mesh.has_vertex_texcoords2D());
    86. MESHOPT("face normals", mesh.has_face_normals());
    87. MESHOPT("face colors", mesh.has_face_colors());
    88. // -------------------- write mesh
    89. std::cout << "Write mesh to " << argv[optind + 1] << "..";
    90. if (!IO::write_mesh(mesh, argv[optind + 1], wopt))
    91. {
    92. std::cerr << "Error" << std::endl;
    93. std::cerr << "Possible reasons:\n";
    94. std::cerr << "1. Chosen format cannot handle an option!\n";
    95. std::cerr << "2. Mesh does not provide necessary information!\n";
    96. std::cerr << "3. Or simply cannot open file for writing!\n";
    97. return 1;
    98. }
    99. else
    100. std::cout << "Ok.\n";
    101. return 0;
    102. }
    103. // ----------------------------------------------------------------------------
    104. void parse_commandline(int _argc, char **_argv, MyMesh& _mesh,
    105. IO::Options &ropt, IO::Options &wopt)
    106. {
    107. int c;
    108. while ((c = getopt(_argc, _argv, "bhsBF:LMSV:X:")) != -1)
    109. {
    110. switch (c)
    111. {
    112. // -------------------- read options
    113. // force binary input
    114. case 'b':
    115. ropt += IO::Options::Binary;
    116. break;
    117. // force swapping the byte order, when reading a binary file
    118. case 's':
    119. ropt += IO::Options::Swap;
    120. break;
    121. // -------------------- write options
    122. // Write binary variant of format if possible
    123. case 'B':
    124. wopt += IO::Options::Binary;
    125. break;
    126. //
    127. case 'F':
    128. for (size_t i = 0; optarg[i]; ++i)
    129. switch (optarg[i]) {
    130. case 'n': wopt += IO::Options::FaceNormal; break;
    131. case 'c': wopt += IO::Options::FaceColor; break;
    132. }
    133. break;
    134. // Use little endian when writing binary data
    135. case 'L':
    136. wopt += IO::Options::LSB;
    137. break;
    138. // Use big endian when writing binary data
    139. case 'M':
    140. wopt += IO::Options::MSB;
    141. break;
    142. // Swap byte order when writing binary data
    143. case 'S':
    144. wopt += IO::Options::Swap;
    145. break;
    146. //
    147. case 'V':
    148. {
    149. for (size_t i = 0; optarg[i]; ++i)
    150. switch (optarg[i]) {
    151. case 'n': // dont't change layout!!
    152. wopt += IO::Options::VertexNormal;
    153. break;
    154. case 't': wopt += IO::Options::VertexTexCoord; break;
    155. case 'c': wopt += IO::Options::VertexColor; break;
    156. }
    157. break;
    158. }
    159. // -------------------- request mesh' standard properties
    160. case 'X':
    161. {
    162. char entity = '\0';
    163. for (size_t i = 0; optarg[i]; ++i)
    164. switch (optarg[i]) {
    165. case 'v':
    166. case 'f': entity = optarg[i]; break;
    167. case 'n':
    168. switch (entity) {
    169. case 'v': _mesh.request_vertex_normals(); break;
    170. case 'f': _mesh.request_face_normals(); break;
    171. }
    172. break;
    173. case 'c':
    174. switch (entity) {
    175. case 'v': _mesh.request_vertex_colors(); break;
    176. case 'f': _mesh.request_face_colors(); break;
    177. }
    178. break;
    179. case 't':
    180. switch (entity) {
    181. case 'v': _mesh.request_vertex_texcoords2D(); break;
    182. }
    183. break;
    184. }
    185. break;
    186. }
    187. // -------------------- help
    188. case 'h':
    189. usage_and_exit(0);
    190. default:
    191. usage_and_exit(1);
    192. }
    193. }
    194. if (_argc - optind != 2)
    195. usage_and_exit(1);
    196. }
    197. // ----------------------------------------------------------------------------
    198. void usage_and_exit(int xcode)
    199. {
    200. std::ostream &os = xcode ? std::cerr : std::cout;
    201. os << "Usage: io_options [Options] <input> <output>\n"
    202. << std::endl;
    203. os << " Read and write a mesh, using OpenMesh::IO::Options\n"
    204. << std::endl;
    205. os << "Options:\n"
    206. << std::endl;
    207. os << "a) read options\n"
    208. << std::endl
    209. << " -b\n"
    210. << "\tAssume input file is a binary file\n"
    211. << std::endl
    212. << " -s\n"
    213. << "\tSwap byte order when reading a binary file!\n"
    214. << std::endl;
    215. os << "b) write options\n"
    216. << std::endl
    217. << " -B\n"
    218. << "\tWrite binary data\n"
    219. << std::endl
    220. << " -S\n"
    221. << "\tSwap byte order, when writing binary data\n"
    222. << std::endl
    223. << " -M/-L\n"
    224. << "\tUse MSB/LSB byte ordering, when writing binary data\n"
    225. << std::endl
    226. << " -V{n|t|c}\n"
    227. << "\tWrite vertex normals, texcoords, and/or colors\n"
    228. << std::endl
    229. << " -F{n|c}\n"
    230. << "\tWrite face normals, and/or colors\n"
    231. << std::endl;
    232. os << "c) Mesh properties\n"
    233. << std::endl
    234. << " -Xv{n|c|t}\n"
    235. << "\tRequest vertex property normals|colors|texcoords\n"
    236. << std::endl
    237. << " -Xf{n|c}\n"
    238. << "\tRequest face property normals|colors\n"
    239. << std::endl;
    240. exit(xcode);
    241. }
    242. // end of file
    243. // ============================================================================

    step3 设置命令参数

    命令参数之间用空格而不是分号隔开

    这里我设置了3个参数

    -B 表示输出文件为二进制

    C:\Kings3D\OFF&STL\little_0.stl 输入文件

    C:\Kings3D\OFF&STL\little_0_out.stl 输出文件

    step 4 运行程序得到输出文件

    用一个可视化程序打开转化后的二进制stl,验证无误

    参考文档

    OpenMesh: Using IO::Options

  • 相关阅读:
    v-model的基本使用,v-model原理;v-model绑定;v-model的值绑定;v-model修饰符
    分享105个NET源码ASP源码,总有一款适合您
    二十三、CANdelaStudio深入-SnapshotData编辑
    Linux·platform驱动框架
    “会不会问为什么”是人机间的根本差异
    程序分区:全局区、常量区、栈区、堆区、代码区
    基于Java使用SpringBoot+Vue框架实现的前后端分离的美食分享平台
    认识kubenetes的核心组件之一kubelet
    业务应用前端实战经验总结
    贪心算法---两道题
  • 原文地址:https://blog.csdn.net/weixin_44997802/article/details/125516100