c++ 如何用CGAL读写二进制PLY文件?

mzsu5hc0  于 2023-03-14  发布在  其他
关注(0)|答案(1)|浏览(517)

我可以用CGAL写一个二进制PLY文件,但是我不能读它:read_PLY要么返回false(如我的真实代码所示),要么使会话崩溃(如下面的代码所示,“内存未Map”错误)。
虽然write_PLY是成功的,但我可能没有正确使用它,因为我也无法使用其他软件读取PLY文件。
你在下面的代码中看到什么错误了吗?

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
#include <CGAL/Polygon_mesh_processing/orientation.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/IO/io.h>
#include <CGAL/Surface_mesh/IO/PLY.h>
#include <fstream>
#include <iostream>
#include <vector>

typedef CGAL::Exact_predicates_exact_constructions_kernel EK;
typedef CGAL::Surface_mesh<EK::Point_3>                   EMesh3;
typedef EK::Point_3                                       EPoint3;
namespace PMP = CGAL::Polygon_mesh_processing;

int main() {
    
  // octahedron soup ----------
  double phi = (1.0 + sqrt(5.0)) / 2.0;
  std::vector<EPoint3> vertices = {EPoint3(0.0, 0.0, phi),  EPoint3(0.0, phi, 0.0),
                                   EPoint3(phi, 0.0, 0.0),  EPoint3(0.0, 0.0, -phi),
                                   EPoint3(0.0, -phi, 0.0), EPoint3(-phi, 0.0, 0.0)};
  std::vector<std::vector<int>> faces = {{1, 0, 2}, {0, 5, 4}, {5, 1, 0},
                                         {0, 2, 4}, {3, 2, 1}, {3, 5, 1},
                                         {2, 3, 4}, {5, 3, 4}};
  bool success = PMP::orient_polygon_soup(vertices, faces);
  if(!success) {
    std::cout << "Polygon orientation failed.";
    return 1;
  }

  // make mesh ----------
  EMesh3 mesh;
  PMP::polygon_soup_to_polygon_mesh(vertices, faces, mesh);

  // write to binary PLY file ----------
  std::ofstream outfile;
  outfile.open("octahedron.ply", std::ios::binary);
  CGAL::IO::set_binary_mode(outfile);
  bool ok = CGAL::IO::write_PLY(outfile, mesh);
  outfile.close();
  if(!ok) {
    std::cout << "Writing file failed.";
    return 1;
  } else {
    std::cout << "Writing file successful.\n";
  }

  // read the PLY file ----------
  EMesh3 mesh2;
  std::ifstream infile("octahedron.ply", std::ios::in|std::ios::binary);
  std::cout << "infile is open: " << infile.is_open();
  bool ok2 = CGAL::IO::read_PLY(infile, mesh2);
  infile.close();
  if(!ok2) {
    std::cout << "Reading file failed.";
    return 1;
  }
  
  // print mesh ----------
  std::cout << mesh2;

  return 0;
}
pdsfdshx

pdsfdshx1#

Surface_mesh/IO/PLY.hwrite_PLY函数中,在写入头之后,它将写入所有顶点数据,如果您检查octahedron.ply文件,您将看到头之后的ascii数字,而不是二进制值。
要解决这个问题,你能把内核改成bellow吗?

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel EK;

我不知道为什么CGAL Surface_mesh不能在Exact_predicates_exact_constructions_kernel内核上正常工作。也许是一个bug,或者是一个欲望行为。
我对当前问题解释如下:

  • 使用CGAL::Exact_predicates_exact_constructions_kernel内核时,EPoint3中的每个值不是double数据类型,而是const CGAL::Lazy_exact_nt<boost::multiprecision...类型。
  • 本例中,数据类型为Lazy_exact_nt,写入顶点数据时,调用operator << Lazy_exact_nt(文件Lazy_exact_nt.h),因此数据写入错误。

如果数据类型为原语(检查文件io_tags.h,数据类型为io_Read_write),则将正确写入。

相关问题