Replies: 5 comments 3 replies
-
As you pointed out, the union is returning The input are not invalid so there is nothing to "fix". I don't understand why you are using the experimental Or even the one operating on triangle soups: |
Beta Was this translation helpful? Give feedback.
-
I get |
Beta Was this translation helpful? Give feedback.
-
The problem was solved by using union rather than difference, as well as using bounding_box for some complex Meshes |
Beta Was this translation helpful? Give feedback.
-
Although we previously managed to find a workaround for this problem by increasing one of the Mesh in all directions, I think it is not optimal, so I think we should continue the discussion here on what to do when PMP::corefine_and_compute_union() it returns false
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/IO/read_off_points.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <CGAL/Polygon_mesh_processing/orientation.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_exact_constructions_kernel K;
typedef K::Point_3 P;
typedef K::Vector_3 V;
typedef std::vector<std::size_t> Face;
typedef CGAL::Polyhedron_3<K> Mesh;
typedef CGAL::Surface_mesh<P> Surface;
typedef Surface::Halfedge_index Halfedge_index;
typedef Surface::Vertex_index Vertex_index;
typedef CGAL::Nef_polyhedron_3<K, CGAL::SNC_indexed_items> Nef;
namespace PMP = CGAL::Polygon_mesh_processing;
struct VectorHash {
template <class T>
std::size_t operator()(const T& v) const {
// Èñïîëüçóåì õýø-ôóíêöèþ äëÿ x, y è z
std::size_t seed = 0;
seed ^= std::hash<double>()(CGAL::to_double(v.x())) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<double>()(CGAL::to_double(v.y())) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= std::hash<double>()(CGAL::to_double(v.z())) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
};
struct VectorEqual {
bool operator()(const V& lhs, const V& rhs) const {
// Îïðåäåëèòå ñðàâíåíèå äëÿ íîðìàëåé
return lhs == rhs; // èëè èñïîëüçóéòå ñðàâíåíèå ñ îïðåäåëåííîé òî÷íîñòüþ
}
};
struct PointEqual {
bool operator()(const P& lhs, const P& rhs) const {
// Îïðåäåëèòå ñðàâíåíèå äëÿ íîðìàëåé
return lhs == rhs; // èëè èñïîëüçóéòå ñðàâíåíèå ñ îïðåäåëåííîé òî÷íîñòüþ
}
};
inline bool load_from(Mesh& output, const std::string& path) {
output.clear();
std::ifstream input;
input.open(path);
if (!input) {
return false;
}
else{
input >> output;
}
input.close();
if (!CGAL::is_triangle_mesh(output)) {
if (!PMP::triangulate_faces(output)) {
std::cout << "no_triangulate\n";
}
}
if (!output.is_closed()) {
std::cout << "no_closed\n";
}
if (!PMP::does_bound_a_volume(output)) {
std::cout << "no_bound\n";
}
if (PMP::does_self_intersect(output)) {
std::cout << "self_inter\n";
}
return CGAL::is_valid_polygon_mesh(output);
}
inline bool save_to(const Mesh& input, const std::string path) {
if (!CGAL::is_valid_polygon_mesh(input)) {
return false;
}
if (CGAL::IO::write_polygon_mesh(path, input, CGAL::parameters::stream_precision(17))) {
return true;
}
return false;
} Archive with original off-files needed to union off-file of Polyhedron_3 where need remove degenerated faces inline void union_meshes(
const std::string& path_meshes,
const std::string& path_mesh_output) {
std::vector<Mesh> meshes;
if (!load_dir(path_meshes, meshes)) {
return;
}
Mesh first = meshes[0];
for (size_t i = 1; i < meshes.size(); i++) {
Mesh result;
if (PMP::corefine_and_compute_union(first, meshes[i], result)) {
first = result;
}
else {
// problem here
}
std::cout << i + 1 << '/' << meshes.size() << std::endl;
}
remesh_planar(first, first);
save_to(first, path_mesh_output);
} inline bool load_dir(const std::string& directory, std::vector<Mesh>& meshes) {
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
if (entry.is_regular_file() && entry.path().extension() == ".off") {
Mesh loaded;
if (load_from(loaded, entry.path().string())) {
meshes.push_back(loaded);
}
}
}
return meshes.size() > 0;
} |
Beta Was this translation helpful? Give feedback.
-
I get a lot of similar cases (44 union-operations out of 1718 fail) As you can see from the screenshots below, the problem lies in the edges that lie on top of each other: Based on this, the question arises - is it technically possible for Polyhedron_3 to combine such meshes, or is expansion in all directions generally the only option to combine them? Thanks @sloriot for the help! |
Beta Was this translation helpful? Give feedback.
-
After an unsuccessful attempt to perform a Boolean union operation via C++ code, I tried to perform it via CGAL_PMP.exe , but apparently I get similar results there
[18:45:06] WARNING: The result of the requested operation is not manifold and has not been computed.
Source Code
I'm trying to use this:
But it for this two meshes - 59-one and 59-two.zip
<59-one.off - mesh1>
<59-two.off - mesh2>
always returns false, because inside
Previously, I have already checked mesh1 and mesh2 in the special FixMesh.h method
Environment
Can I correct the input data using some additional method to get the result of the union?
Thanks!
Updated (07.08)
At the moment, I managed to get rid of the error of performing a Boolean operation on a Mesh only by applying this method with all its methods inside for both meshes as well as for the result. This is very strong (especially the PMP::experimental::autorefine(mesh) method) performance was hit.
Is there a better way (equally reliable, but less costly) to correct geometry before and after a Boolean operation?
Beta Was this translation helpful? Give feedback.
All reactions