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_PLY
function ofSurface_mesh/IO/PLY.h
, after writing the header, it will write all vertices data. If you check theoctahedron.ply
file, 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_mesh
not work correctly withExact_predicates_exact_constructions_kernel
kernel. Maybe it's a bug, or a desire behavior.I explain the current issue as bellow:
When using
CGAL::Exact_predicates_exact_constructions_kernel
kernel, each value inEPoint3
is not adouble
data 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.