如何在CGAL中加载含颜色信息的COFF网格文件?
读取带颜色的COFF文件并生成含颜色信息的CGAL网格
我刚好处理过类似的需求,CGAL的read_OFF()其实是支持读取COFF格式的颜色信息的,只是需要用正确的重载版本,再手动把颜色绑定到网格属性里就行。下面是具体的步骤和代码示例:
1. 定义支持颜色属性的网格类型
首先我们需要用CGAL::Surface_mesh作为基础网格类型,它可以通过CGAL内置的属性映射来添加顶点/面颜色,不需要自定义复杂的结构体:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Surface_mesh.h> #include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h> #include <CGAL/IO/read_OFF.h> #include <vector> #include <fstream> #include <iostream> // 定义内核和点类型 typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; // 基础网格类型 typedef CGAL::Surface_mesh<Point> Mesh; // 顶点颜色属性映射类型 typedef boost::property_map<Mesh, CGAL::vertex_color_t>::type VertexColorMap; // 如果你的COFF是面颜色,就用下面这个: // typedef boost::property_map<Mesh, CGAL::face_color_t>::type FaceColorMap;
2. 读取COFF文件的几何与颜色信息
使用read_OFF()的重载版本,传入存储顶点、面、颜色的容器,它会自动解析COFF中的颜色数据:
int main() { std::vector<Point> vertices; std::vector<std::vector<std::size_t>> faces; std::vector<CGAL::Color> vertex_colors; // 存储读取到的顶点颜色 // 如果是面颜色,就定义std::vector<CGAL::Color> face_colors; // 打开COFF文件 std::ifstream input("your_mesh.coff"); if (!input.is_open()) { std::cerr << "无法打开文件!" << std::endl; return EXIT_FAILURE; } // 读取COFF:最后两个参数分别是顶点颜色和面颜色容器,不需要的传nullptr if (!CGAL::read_OFF(input, vertices, faces, vertex_colors, nullptr)) { std::cerr << "读取COFF文件失败!" << std::endl; return EXIT_FAILURE; }
3. 将多边形汤转换为网格并绑定颜色
polygon_soup_to_polygon_mesh()确实只处理拓扑结构,所以我们需要手动把颜色赋值到网格的属性中:
// 创建网格拓扑结构 Mesh mesh; CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(vertices, faces, mesh); // 绑定顶点颜色到网格 VertexColorMap v_color_map = get(CGAL::vertex_color, mesh); for (Mesh::vertex_index v_idx : mesh.vertices()) { // 注意:网格顶点的顺序和读取的vertices容器顺序完全一致,直接对应赋值即可 put(v_color_map, v_idx, vertex_colors[v_idx]); } // 如果是面颜色,就用下面这段: // FaceColorMap f_color_map = get(CGAL::face_color, mesh); // for (Mesh::face_index f_idx : mesh.faces()) { // put(f_color_map, f_idx, face_colors[f_idx]); // } // 现在mesh就包含完整的几何、拓扑和颜色信息了,可以进行后续处理 std::cout << "成功加载带颜色的网格,顶点数:" << mesh.number_of_vertices() << std::endl; return EXIT_SUCCESS; }
关键注意事项
- 确保你的COFF文件第一行是
COFF(不是OFF),否则read_OFF()不会解析颜色信息。 - 如果你的COFF文件同时包含顶点和面颜色,可以同时传入
vertex_colors和face_colors容器,不需要的参数传nullptr即可。 - 网格的顶点/面索引和读取的
vertices/faces容器的顺序是一一对应的,所以可以直接按索引赋值颜色。
内容的提问来源于stack exchange,提问作者A. Fasih
相关产品推荐
相关产品推荐

