当前位置:网站首页>如何利用OpenMesh实现不同格式的3D文件间的转换
如何利用OpenMesh实现不同格式的3D文件间的转换
2022-06-29 16:18:00 【CSU迦叶】
可以进行的转化如下

(出处链接见文末参考文档)
本文示例将文本格式(ASCII)的stl文件转化为二进制格式(Binary)。
目录
step 1 配置openmesh环境
可以参考
step2 代码实现
注:debug下跑得同,release下不行,也没搞清原因
#include <iostream>
#include <iterator>
// -------------------- OpenMesh
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Tools/Utils/getopt.h>
// ----------------------------------------------------------------------------
using namespace OpenMesh;
// ----------------------------------------------------------------------------
typedef TriMesh_ArrayKernelT<> MyMesh;
// ----------------------------------------------------------------------------
#define CHKROPT( Option ) \
std::cout << " provides " << #Option \
<< (ropt.check(IO::Options:: Option)?": yes\n":": no\n")
#define CHKWOPT( Option ) \
std::cout << " write " << #Option \
<< (wopt.check(IO::Options:: Option)?": yes\n":": no\n")
#define MESHOPT( msg, tf ) \
std::cout << " " << msg << ": " << ((tf)?"yes\n":"no\n")
// ----------------------------------------------------------------------------
void parse_commandline(int _argc, char **_argv, MyMesh& _mesh,
IO::Options &ropt, IO::Options &wopt);
void usage_and_exit(int xcode);
// ----------------------------------------------------------------------------
int main(int argc, char **argv)
{
MyMesh mesh;
IO::Options ropt, wopt;
// -------------------- evaluate commandline
parse_commandline(argc, argv, mesh, ropt, wopt);
// -------------------- read mesh
if (!IO::read_mesh(mesh, argv[optind], ropt))
{
std::cerr << "Error loading mesh from file " << argv[optind] << std::endl;
return 1;
}
// -------------------- show options
std::cout << "File " << argv[optind] << std::endl;
std::cout << " is binary: "
<< (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n");
std::cout << " byte order: ";
if (ropt.check(IO::Options::Swap))
std::cout << "swapped\n";
else if (ropt.check(IO::Options::LSB))
std::cout << "little endian\n";
else if (ropt.check(IO::Options::MSB))
std::cout << "big endian\n";
else
std::cout << "don't care\n";
std::cout << " provides VertexNormal"
<< ( // strange layout for doxygen
ropt.check(IO::Options::VertexNormal)
? ": yes\n" : ": no\n");
CHKROPT(VertexColor);
CHKROPT(VertexTexCoord);
CHKROPT(FaceNormal);
CHKROPT(FaceColor);
// -------------------- mesh stats
std::cout << "# Vertices: " << mesh.n_vertices() << std::endl;
std::cout << "# Edges : " << mesh.n_faces() << std::endl;
std::cout << "# Faces : " << mesh.n_faces() << std::endl;
// -------------------- show write options
std::cout << "Selected write options:\n";
std::cout << " use binary: "
<< (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n");
std::cout << " byte order: ";
if (wopt.check(IO::Options::Swap))
std::cout << "swapped\n";
else if (wopt.check(IO::Options::LSB))
std::cout << "little endian\n";
else if (wopt.check(IO::Options::MSB))
std::cout << "big endian\n";
else
std::cout << "don't care\n";
std::cout << " write VertexNormal"
<< (wopt.check(IO::Options::VertexNormal) ? ": yes\n" : ": no\n");
CHKWOPT(VertexColor);
CHKWOPT(VertexTexCoord);
CHKWOPT(FaceNormal);
CHKWOPT(FaceColor);
// -------------------- show mesh capabilities
std::cout << "Mesh supports\n";
MESHOPT("vertex normals", mesh.has_vertex_normals());
MESHOPT("vertex colors", mesh.has_vertex_colors());
MESHOPT("texcoords", mesh.has_vertex_texcoords2D());
MESHOPT("face normals", mesh.has_face_normals());
MESHOPT("face colors", mesh.has_face_colors());
// -------------------- write mesh
std::cout << "Write mesh to " << argv[optind + 1] << "..";
if (!IO::write_mesh(mesh, argv[optind + 1], wopt))
{
std::cerr << "Error" << std::endl;
std::cerr << "Possible reasons:\n";
std::cerr << "1. Chosen format cannot handle an option!\n";
std::cerr << "2. Mesh does not provide necessary information!\n";
std::cerr << "3. Or simply cannot open file for writing!\n";
return 1;
}
else
std::cout << "Ok.\n";
return 0;
}
// ----------------------------------------------------------------------------
void parse_commandline(int _argc, char **_argv, MyMesh& _mesh,
IO::Options &ropt, IO::Options &wopt)
{
int c;
while ((c = getopt(_argc, _argv, "bhsBF:LMSV:X:")) != -1)
{
switch (c)
{
// -------------------- read options
// force binary input
case 'b':
ropt += IO::Options::Binary;
break;
// force swapping the byte order, when reading a binary file
case 's':
ropt += IO::Options::Swap;
break;
// -------------------- write options
// Write binary variant of format if possible
case 'B':
wopt += IO::Options::Binary;
break;
//
case 'F':
for (size_t i = 0; optarg[i]; ++i)
switch (optarg[i]) {
case 'n': wopt += IO::Options::FaceNormal; break;
case 'c': wopt += IO::Options::FaceColor; break;
}
break;
// Use little endian when writing binary data
case 'L':
wopt += IO::Options::LSB;
break;
// Use big endian when writing binary data
case 'M':
wopt += IO::Options::MSB;
break;
// Swap byte order when writing binary data
case 'S':
wopt += IO::Options::Swap;
break;
//
case 'V':
{
for (size_t i = 0; optarg[i]; ++i)
switch (optarg[i]) {
case 'n': // dont't change layout!!
wopt += IO::Options::VertexNormal;
break;
case 't': wopt += IO::Options::VertexTexCoord; break;
case 'c': wopt += IO::Options::VertexColor; break;
}
break;
}
// -------------------- request mesh' standard properties
case 'X':
{
char entity = '\0';
for (size_t i = 0; optarg[i]; ++i)
switch (optarg[i]) {
case 'v':
case 'f': entity = optarg[i]; break;
case 'n':
switch (entity) {
case 'v': _mesh.request_vertex_normals(); break;
case 'f': _mesh.request_face_normals(); break;
}
break;
case 'c':
switch (entity) {
case 'v': _mesh.request_vertex_colors(); break;
case 'f': _mesh.request_face_colors(); break;
}
break;
case 't':
switch (entity) {
case 'v': _mesh.request_vertex_texcoords2D(); break;
}
break;
}
break;
}
// -------------------- help
case 'h':
usage_and_exit(0);
default:
usage_and_exit(1);
}
}
if (_argc - optind != 2)
usage_and_exit(1);
}
// ----------------------------------------------------------------------------
void usage_and_exit(int xcode)
{
std::ostream &os = xcode ? std::cerr : std::cout;
os << "Usage: io_options [Options] <input> <output>\n"
<< std::endl;
os << " Read and write a mesh, using OpenMesh::IO::Options\n"
<< std::endl;
os << "Options:\n"
<< std::endl;
os << "a) read options\n"
<< std::endl
<< " -b\n"
<< "\tAssume input file is a binary file\n"
<< std::endl
<< " -s\n"
<< "\tSwap byte order when reading a binary file!\n"
<< std::endl;
os << "b) write options\n"
<< std::endl
<< " -B\n"
<< "\tWrite binary data\n"
<< std::endl
<< " -S\n"
<< "\tSwap byte order, when writing binary data\n"
<< std::endl
<< " -M/-L\n"
<< "\tUse MSB/LSB byte ordering, when writing binary data\n"
<< std::endl
<< " -V{n|t|c}\n"
<< "\tWrite vertex normals, texcoords, and/or colors\n"
<< std::endl
<< " -F{n|c}\n"
<< "\tWrite face normals, and/or colors\n"
<< std::endl;
os << "c) Mesh properties\n"
<< std::endl
<< " -Xv{n|c|t}\n"
<< "\tRequest vertex property normals|colors|texcoords\n"
<< std::endl
<< " -Xf{n|c}\n"
<< "\tRequest face property normals|colors\n"
<< std::endl;
exit(xcode);
}
// end of file
// ============================================================================step3 设置命令参数
命令参数之间用空格而不是分号隔开

这里我设置了3个参数
-B 表示输出文件为二进制
C:\Kings3D\OFF&STL\little_0.stl 输入文件
C:\Kings3D\OFF&STL\little_0_out.stl 输出文件
step 4 运行程序得到输出文件
用一个可视化程序打开转化后的二进制stl,验证无误

参考文档
边栏推荐
- 同样是做测试,为什么别人年薪30W+?
- Stable currency risk profile: are usdt and usdc safe?
- 贪婪的苹果计划提高iPhone14的价格,这将为中国手机提供机会
- The understanding of industrial Internet is directly related to how we view it
- Key sprite fighting monsters - window binding skill
- Sophon base 3.1 launches mlops function to provide wings for enterprise AI capability operation
- STM32 key chattering elimination -- Thinking of entry state machine
- Implement a ThreadLocal by yourself
- 水球图-利用动态波纹展示百分比
- CompletableFuture的入门
猜你喜欢

BOE: with the arrival of the peak season in the second half of the year, the promotion and the release of new products, the demand is expected to improve

A tour of gRPC:02 - 从proto生成代码

C语言——printf打印进制前缀

Small programs have a "big" role in the industrial Internet

C# Winfrom Chart图表控件 柱状图、折线图

美国芯片再遭重击,Intel或将被台积电击败而沦落至全球第三

Picture and text show you how to thoroughly understand the atomicity of MySQL transaction undolog

The rooster Electronic Society graphical programming real questions and answers analysis of the scratch grade test level 1 June 2022

八年测开经验面试28K公司后,吐血整理出高频面试题和答案

暑期数据可视化分析展示效果
随机推荐
Huaxia Fund: sharing of digital transformation practice achievements in the fund industry
新股民如何网上开户?究竟网上开户是否安全么?
[proteus simulation] nixie tube +4x4 keyboard matrix key simple calculator
同样是做测试,为什么别人年薪30W+?
BOE: with the arrival of the peak season in the second half of the year, the promotion and the release of new products, the demand is expected to improve
代码大全读后感
如何配置 logback?30分鐘讓你徹底學會代碼熬夜敲
Sophon autocv: help AI industrial production and realize visual intelligent perception
It's also a test. Why do others get an annual salary of 30w+?
The understanding of industrial Internet is directly related to how we view it
leetcode:42. Rain water [double hands are elegant]
分片信息调哪个参数呢?用的是MySQLsource stream api,不是table api
STM32按键消抖——入门状态机思维
Redis布隆过滤器和布谷鸟过滤器
实践 | 移动端图片上传旋转、压缩的解决方案
redolog和binlog
Sophon AutoCV:助力AI工业化生产,实现视觉智能感知
[proteus simulation] 8-bit nixie tube dynamic scanning display change data
What are the financial products suitable for the poor in 2022?
Tutorial | fNIRS data processing toolkit homer2 download and installation