请求提供CGAL读写含法线与UV的OBJ文件代码及复用方案
用CGAL读写包含法线与UV的OBJ文件解决方案
CGAL的OBJ读写器完全支持扩展处理法线(vn)和UV(vt)记录,不需要自行编写完整读写器,只需通过命名参数将UV、法线数据绑定到网格对象的属性中即可复用现有逻辑。
核心实现代码
#include <CGAL/Simple_cartesian.h> #include <CGAL/Surface_mesh.h> #include <CGAL/IO/read_obj.h> #include <CGAL/IO/write_obj.h> #include <iostream> typedef CGAL::Simple_cartesian<double> Kernel; typedef Kernel::Point_3 Point; typedef Kernel::Vector_3 Vector; typedef CGAL::Surface_mesh<Point> Mesh; // 定义顶点描述符类型 typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor; int main() { Mesh mesh; // 为网格添加UV和法线的属性存储(键名需符合CGAL约定) auto uv_map = mesh.add_property_map<vertex_descriptor, std::pair<double, double>>("v:uv").first; auto normal_map = mesh.add_property_map<vertex_descriptor, Vector>("v:normal").first; // 读取OBJ文件,自动解析vn、vt记录并绑定到对应属性 std::ifstream input("mesh-in.obj"); if (!CGAL::read_obj(input, mesh, CGAL::parameters::vertex_normal_map(normal_map) .vertex_uv_map(uv_map))) { std::cerr << "读取OBJ文件失败!" << std::endl; return EXIT_FAILURE; } // 写入OBJ文件,自动输出vn、vt记录 std::ofstream output("mesh-out.obj"); if (!CGAL::write_obj(output, mesh, CGAL::parameters::vertex_normal_map(normal_map) .vertex_uv_map(uv_map))) { std::cerr << "写入OBJ文件失败!" << std::endl; return EXIT_FAILURE; } std::cout << "已成功保留法线和UV完成OBJ读写!" << std::endl; return EXIT_SUCCESS; }
关键说明
- 推荐使用
CGAL::Surface_mesh作为网格类型,它比Polyhedron_3更灵活,支持动态添加顶点属性(UV、法线) - 属性键名
v:uv和v:normal是CGAL的约定名称,确保读写器能正确关联OBJ的vt、vn记录 - 读写时通过
CGAL::parameters命名参数传递属性映射,让CGAL自动完成vt、vn的解析与输出,无需手动处理OBJ语法 - 你之前的示例未保留
vt,正是因为没有将UV属性传递给写函数,按上述方式绑定后即可解决问题
内容的提问来源于stack exchange,提问作者user3713345
相关产品推荐
相关产品推荐

