I can write a binary PLY file with CGAL but I'm not able to read it: either read_PLY returns false (as in my true code), or it crashes the session (as in the code below, "memory not mapped" error).
While write_PLY is successful, it's possible that I don't correctly use it, because I'm not able to read the PLY file with another software as well.
Do you see something wrong in my code below?
#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;
}
In
write_PLYfunction ofSurface_mesh/IO/PLY.h, after writing the header, it will write all vertices data. If you check theoctahedron.plyfile, you will see the ascii number after header, not binary value.To solve the problem, could you change the kernel to bellow?
I don't know why
CGAL Surface_meshnot work correctly withExact_predicates_exact_constructions_kernelkernel. Maybe it's a bug, or a desire behavior.I explain the current issue as bellow:
When using
CGAL::Exact_predicates_exact_constructions_kernelkernel, each value inEPoint3is not adoubledata type, but aconst CGAL::Lazy_exact_nt<boost::multiprecision...type.In this case, the data type is
Lazy_exact_nt, then, when writing vertices data, it call tooperator << Lazy_exact_nt(fileLazy_exact_nt.h), so the data is written wrongly.If the datatype is primitive (check file
io_tags.h, the datatype withio_Read_write) will be written correctly.