Open kuaiqushangzixiba opened 1 year ago
could you please provide an example mesh with parameters you used (and the example you used)? Did you check the bool returned value?
like example diplodocus.off
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\elephant-with-holes.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\man.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\building.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\bear.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\pig.stl");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\refined_elephant.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\bunny00.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\diplodocus.off");
baishi("E:\\cppThree\\CGAL-5.6\\data\\meshes\\armadillo.off");
I tried a lot of ply, as well as off in the example folder, the return value 0 and 1, can't see any pattern, some will return itself, some will return a simplified mesh, some will return an empty mesh
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/region_growing.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/random_perturbation.h>
#include <boost/property_map/vector_property_map.hpp>
#include <iostream>
#include <fstream>
#include <iostream>
#include <chrono>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <cstdio>
#include <CGAL/Polygon_mesh_processing/stitch_borders.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface_mesh;
namespace PMP = CGAL::Polygon_mesh_processing;
int baishi(const std::string& filename)
{
Surface_mesh sm;
CGAL::IO::read_polygon_mesh(CGAL::data_file_path(filename), sm);
std::cout << sm.number_of_vertices() << std::endl;
std::vector<std::pair<unsigned, unsigned>> selfIntersections;
PMP::self_intersections(sm, std::back_inserter(selfIntersections));
std::cout << selfIntersections.size() << std::endl;
// declare vectors to store mesh properties
std::vector<std::size_t> region_ids(num_faces(sm));
std::vector<std::size_t> corner_id_map(num_vertices(sm), -1); // corner status of vertices
std::vector<bool> ecm(num_edges(sm), false); // mark edges at the boundary of regions
boost::vector_property_map<CGAL::Epick::Vector_3> normal_map; // normal of the supporting planes of the regions detected
// detect planar regions in the mesh
std::size_t nb_regions =
PMP::region_growing_of_planes_on_faces(sm,
CGAL::make_random_access_property_map(region_ids),
CGAL::parameters::cosine_of_maximum_angle(0.89).
region_primitive_map(normal_map).
maximum_distance(0.0003));
std::cout << nb_regions << "regions ";
// detect corner vertices on the boundary of planar regions
std::size_t nb_corners =
PMP::detect_corners_of_regions(sm,
CGAL::make_random_access_property_map(region_ids),
nb_regions,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::parameters::cosine_of_maximum_angle(0.9).
maximum_distance(0.0003).
edge_is_constrained_map(CGAL::make_random_access_property_map(ecm)));
std::cout << nb_corners << "corners " << std::endl;
//run the remeshing algorithm using filled properties
Surface_mesh out;
bool success = PMP::remesh_almost_planar_patches(sm,
out,
nb_regions, nb_corners,
CGAL::make_random_access_property_map(region_ids),
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map));
CGAL::IO::write_polygon_mesh(filename.substr(0, filename.size() - 4) += "_test.ply", out);
std::cout << success << std::endl;
std::cout << out.number_of_vertices() << std::endl;
std::cout << std::endl;
return 0;
}
It seems that when bool is 1, it can be simplified with high probability (sometimes it can't), but how can we guarantee that boo is 1? Is there any requirement on the input ply?
I noticed that remesh_planar_patches has input requirements and can't handle non-manifold vertices. Does remesh_almost_planar_patches also have input requirements?
Also, the function only works if maximum_distance(0.0003) is very small, which makes it nearly impossible to handle any input mesh
I will have a closer look at why the meshing part in failing as soon as I can. In the meantime, considering the input meshes you've been trying, the following package seems better suited (since they do not really have planar parts).
Ok, looking forward to your progress
Hi @kuaiqushangzixiba
This approach works pretty well for me:
#pragma once
#include "mesh_typedefs.h"
#ifdef DEBUG_PLANAR
#include "my_timer.h"
#endif // DEBUG_PLANAR
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include "remesh_almost_planar.h"
void remesh_planar(Mesh& mesh) {
#ifdef DEBUG_PLANAR
int pre = mesh.points().size();
auto ts = start("planar:");
#endif // DEBUG_PLANAR
Mesh remeshed;
PMP::remesh_planar_patches(mesh, remeshed);
mesh = remeshed;
remesh_almost_planar(mesh);
#ifdef DEBUG_PLANAR
int post = pre - mesh.points().size();
if (post != 0) {
std::cout << "d(" << post << ") ";
}
msg("planared", ts, true);
#endif // DEBUG_PLANAR
}
mesh_typedefs.h
#pragma once
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Nef_2/debug.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/Nef_3/SNC_indexed_items.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 P;
typedef K::Vector_3 V;
typedef CGAL::Polyhedron_3<K, CGAL::Polyhedron_items_with_id_3> Mesh;
typedef CGAL::Surface_mesh<P> Surface;
typedef CGAL::Exact_predicates_exact_constructions_kernel K_e;
typedef K_e::Point_3 P_e;
typedef K_e::Vector_3 V_e;
typedef CGAL::Polyhedron_3<K_e> Mesh_e;
typedef CGAL::Nef_polyhedron_3<K_e, CGAL::SNC_indexed_items> Nef;
typedef CGAL::Nef_polyhedron_3<K_e> Nef_Sum;
typedef P_e* point_iterator;
typedef std::pair<point_iterator, point_iterator> point_range;
typedef std::list<point_range> polyline;
namespace PMP = CGAL::Polygon_mesh_processing;
remesh_almost_planar.h
#pragma once
#include "mesh_typedefs.h"
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/region_growing.h>
#include <boost/property_map/vector_property_map.hpp>
void remesh_almost_planar(Mesh& mesh)
{
Surface sm;
copy(mesh, sm);
// declare vectors to store mesh properties
std::vector<std::size_t> region_ids(num_faces(sm));
std::vector<std::size_t> corner_id_map(num_vertices(sm), -1); // corner status of vertices
std::vector<bool> ecm(num_edges(sm), false); // mark edges at the boundary of regions
boost::vector_property_map<CGAL::Epick::Vector_3> normal_map; // normal of the supporting planes of the regions detected
// detect planar regions in the mesh
std::size_t nb_regions =
PMP::region_growing_of_planes_on_faces(sm,
CGAL::make_random_access_property_map(region_ids),
CGAL::parameters::cosine_of_maximum_angle(0.6).
//CGAL::parameters::cosine_of_maximum_angle(0.98).
region_primitive_map(normal_map).
maximum_distance(1));
//maximum_distance(0.011));
// detect corner vertices on the boundary of planar regions
std::size_t nb_corners =
PMP::detect_corners_of_regions(sm,
CGAL::make_random_access_property_map(region_ids),
nb_regions,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::parameters::cosine_of_maximum_angle(0.6).
//CGAL::parameters::cosine_of_maximum_angle(0.98).
//maximum_distance(0.011).
maximum_distance(1).
edge_is_constrained_map(CGAL::make_random_access_property_map(ecm)));
// run the remeshing algorithm using filled properties
Surface out;
PMP::remesh_almost_planar_patches(sm,
out,
nb_regions, nb_corners,
CGAL::make_random_access_property_map(region_ids),
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map));
copy(out, mesh);
}
Return empty mesh What is going on, I tried many mesh, some can return simplified mesh, some return empty mesh, some return the original input mesh, what is going on in the end? How can you guarantee that a simplified mesh is returned