Open FuzhangHe opened 2 years ago
You are having issues with rounding to double. Try using this example to workaround them: https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2corefinement_consecutive_bool_op_8cpp-example.html
If speed then becomes an issue some mesh cleaning operations must probably be done instead.
Now i have changed the code based on the example "corefinement_consecutive_bool_op.cpp". It can still only run two steps.
#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/corefinement.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/transform.h>
#include <CGAL/Aff_transformation_3.h>
#include <fstream>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_exact_constructions_kernel EK;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef Mesh::Property_map<vertex_descriptor, EK::Point_3> Exact_point_map;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef typename Kernel::Vector_3 Vector_3;
typedef CGAL::Aff_transformation_3<Kernel> Affine_transformation_3;
namespace PMP = CGAL::Polygon_mesh_processing;
namespace params = PMP::parameters;
struct Exact_vertex_point_map
{
// typedef for the property map
typedef boost::property_traits<Exact_point_map>::value_type value_type;
typedef boost::property_traits<Exact_point_map>::reference reference;
typedef boost::property_traits<Exact_point_map>::key_type key_type;
typedef boost::read_write_property_map_tag category;
// exterior references
Exact_point_map exact_point_map;
Mesh* tm_ptr;
// Converters
CGAL::Cartesian_converter<K, EK> to_exact;
CGAL::Cartesian_converter<EK, K> to_input;
Exact_vertex_point_map()
: tm_ptr(nullptr)
{}
Exact_vertex_point_map(const Exact_point_map& ep, Mesh& tm)
: exact_point_map(ep)
, tm_ptr(&tm)
{
for (Mesh::Vertex_index v : vertices(tm))
exact_point_map[v] = to_exact(tm.point(v));
}
friend
reference get(const Exact_vertex_point_map& map, key_type k)
{
CGAL_precondition(map.tm_ptr != nullptr);
return map.exact_point_map[k];
}
friend
void put(const Exact_vertex_point_map& map, key_type k, const EK::Point_3& p)
{
CGAL_precondition(map.tm_ptr != nullptr);
map.exact_point_map[k] = p;
// create the input point from the exact one
map.tm_ptr->point(k) = map.to_input(p);
}
};
int main(int argc, char* argv[])
{
const std::string filename1 = (argc > 1) ? argv[1] : CGAL::data_file_path("werkzeug/VB56.off");
const std::string filename2 = (argc > 2) ? argv[2] : CGAL::data_file_path("werkzeug/Cylinder6.off");
Mesh mesh1, mesh2;
if (!PMP::IO::read_polygon_mesh(filename1, mesh1) || !PMP::IO::read_polygon_mesh(filename2, mesh2))
{
std::cerr << "Invalid input." << std::endl;
return 1;
}
for (int step = 1; step <= 2; step++) {
// Transformation
PMP::transform(Affine_transformation_3(CGAL::Translation(), Vector_3(0, 0, -1)), mesh2);
// Boolean Operation
Exact_point_map mesh1_exact_points =
mesh1.add_property_map<vertex_descriptor, EK::Point_3>("v:exact_point").first;
Exact_point_map mesh2_exact_points =
mesh2.add_property_map<vertex_descriptor, EK::Point_3>("v:exact_point").first;
Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1);
Exact_vertex_point_map mesh2_vpm(mesh2_exact_points, mesh2);
PMP::corefine_and_compute_difference(mesh1,
mesh2,
mesh1,
params::vertex_point_map(mesh1_vpm),
params::vertex_point_map(mesh2_vpm),
params::vertex_point_map(mesh1_vpm));
}
std::cout << "Intersection and union were successfully computed\n";
CGAL::IO::write_polygon_mesh("../../data/output/NewWorkpiece.off", mesh1, CGAL::parameters::stream_precision(17));
CGAL::IO::write_polygon_mesh("../../data/output/NewWerkzeug.off", mesh2, CGAL::parameters::stream_precision(17));
return 0;
}
Since you are really only updating mesh1
, define mesh1_vpm
outside of the loop (otherwise exact points will get overridden). For mesh_2
, I suggest to copy it at the beginning of the loop to avoid refining it. So define mesh_2
outside of the loop and copy it to mesh_2_for_loop
before doing the affine transformation (keep track of the number of translations of course).
As you suggested , i put the mesh1_vpm outsideof the loop, and now i got the error :
Severity Code Description Project File Line Suppression State
Error C2338 (std::is_same<typename boost::property_traits<VPM1>::value_type, typename boost::property_traits<VPM2>::value_type>::value) corefinement_consecutive_bool_op_Version C:\dev\vcpkg\installed\x64-windows\include\CGAL\Polygon_mesh_processing\corefinement.h 207
Error C2338 (std::is_same<typename boost::property_traits<VertexPointMap1>::value_type, typename boost::property_traits<VertexPointMap2>::value_type>::value) corefinement_consecutive_bool_op_Version C:\dev\vcpkg\installed\x64-windows\include\CGAL\Polygon_mesh_processing\internal\Corefinement\intersection_nodes.h 333
Exact_point_map mesh1_exact_points =
mesh1.add_property_map<vertex_descriptor, EK::Point_3>("v:exact_point").first;
Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1);
// todo: copy mesh
// mesh_copy;
for (int step = 1; step <= 2; step++) {
// Transformation
PMP::transform(Affine_transformation_3(CGAL::Translation(), Vector_3(0, 0, -1)), mesh2);
// Boolean Operation
PMP::corefine_and_compute_difference(mesh1,
mesh2,
mesh1,
params::vertex_point_map(mesh1_vpm),
params::all_default(),
params::vertex_point_map(mesh1_vpm));
}
Can you please also tell me how to copy mesh ? I am new in C++...
You are missing mesh2_vpm
do you mean code like this ?
Exact_point_map mesh1_exact_points =
mesh1.add_property_map<vertex_descriptor, EK::Point_3>("v:exact_point").first;
Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1);
for (int step = 1; step <= 3; step++) {
// todo: copy mesh
// mesh_copy;
// Transformation
PMP::transform(Affine_transformation_3(CGAL::Translation(), Vector_3(0, 0, -1)), mesh2);
// Boolean Operation
Exact_point_map mesh2_exact_points =
mesh2.add_property_map<vertex_descriptor, EK::Point_3>("v:exact_point").first;
Exact_vertex_point_map mesh2_vpm(mesh2_exact_points, mesh2);
PMP::corefine_and_compute_difference(mesh1,
mesh2,
mesh1,
params::vertex_point_map(mesh1_vpm),
params::vertex_point_map(mesh2_vpm),
params::vertex_point_map(mesh1_vpm));
}
but i still get the error assertion violation somehow.
The following works for me but you then have the runtime issue I was mentioning earlier: https://gist.github.com/sloriot/b29acaa073765dde8d79e735893e74a5
Thank you for the code. As you said, it works but very slow.
It is slower than nef Boolean Operation. For the same model, it need 1316 seconds to calculate 30 steps with corefinement, but with nef3 only 300 seconds for 100 steps.
it gets slower and slower, because the workpiece is more and more complicate.
Hello, we had a closer look at what happens. Each time the cylinder moves down it produces a new layer of vertical faces. In the next iteration all these faces are cut again by edges of the cylinder which are not vertical. And this happens for each iteration for all layers so far produced.
As only the head of the tool is cutting it is maybe a solution for you to make the cylinder only 2 * step_distance
high.
Then only the previous layer is concerned by an additional subdivision. Is that an option for you?
Hi, Afabri,
Thank you for take a closer look at this modell.
It is really intearsting, the cylinder after move down and before Corefinement Boolean Operation doesnot have so many vertices. Something strange has happend during the corefinement boolean operation.
I also want to simulate the tool deviation (deformation), that means the boolean operation is no more ideal. So it is not a good idea to cut the cylinder so short.
PS. in Nef Boolean Operation the cylinder doesnot get more vertices after boolean operation.
Hi, Afabri,
Thank you for take a closer look at this modell.
It is really intearsting, the cylinder after move down and before Corefinement Boolean Operation doesnot have so many vertices. Something strange has happend during the corefinement boolean operation.
I also want to simulate the tool deviation (deformation), that means the boolean operation is no more ideal. So it is not a good idea to cut the cylinder so short.
PS. in Nef Boolean Operation the cylinder doesnot get more vertices after boolean operation.
Hello, blogger. I have the same problem as you. Boolean operation is very slow when i use [PMP::corefine_and_compute_difference]. I want to cut the rectangular workpiece with a cylindrical cutter. Do you have any good suggestions?
Hi, Afabri,
Thank you for take a closer look at this modell.
It is really intearsting, the cylinder after move down and before Corefinement Boolean Operation doesnot have so many vertices. Something strange has happend during the corefinement boolean operation.
I also want to simulate the tool deviation (deformation), that means the boolean operation is no more ideal. So it is not a good idea to cut the cylinder so short.
PS. in Nef Boolean Operation the cylinder doesnot get more vertices after boolean operation.
Hello, blogger. I have the same problem as you. Boolean operation is very slow when i use [PMP::corefine_and_compute_difference]. I want to cut the rectangular workpiece with a cylindrical cutter. Do you have any good suggestions?
Issue Details
Hi, I am trying to do corefine_and_compute_difference operation between two objects. The goal is not just one step, but about 5000 steps together. The workspiece("VB56.off") stands still, the tool ("Cylinder6.off") moves down in every step, and a new boolean operation should be done.
My problem is that, i can only do two steps successfully. In third step, it will got the error:
Source Code
the code and file are in github uploaded: github
Environment