Do mesh booleans with cgal if possible.

This commit is contained in:
tamasmeszaros 2022-10-21 17:55:30 +02:00
parent 2a8c9d7462
commit 191f04568d
5 changed files with 80 additions and 29 deletions

View file

@ -5,15 +5,58 @@
#include "libslic3r/MeshBoolean.hpp"
namespace Slic3r {
namespace Slic3r { namespace csg {
// This method can be overriden when a specific CSGPart type supports caching
// of the voxel grid
template<class CSGPartT>
MeshBoolean::cgal::CGALMeshPtr get_cgalmesh(const CSGPartT &csgpart)
{
const indexed_triangle_set *its = csg::get_mesh(csgpart);
MeshBoolean::cgal::CGALMeshPtr ret;
if (its) {
indexed_triangle_set m = *its;
its_transform(m, get_transform(csgpart));
ret = MeshBoolean::cgal::triangle_mesh_to_cgal(m);
}
return ret;
}
template<class It>
void perform_csgmesh_booleans(MeshBoolean::cgal::CGALMesh &cgalm,
const Range<It> &csg)
const Range<It> &csgparts)
{
for (auto &csgpart : csgparts) {
auto m = get_cgalmesh(csgpart);
if (m) {
switch (get_operation(csgpart)) {
case CSGType::Union:
MeshBoolean::cgal::plus(cgalm, *m);
break;
case CSGType::Difference:
MeshBoolean::cgal::minus(cgalm, *m);
break;
case CSGType::Intersection:
MeshBoolean::cgal::intersect(cgalm, *m);
break;
}
}
}
}
template<class It>
MeshBoolean::cgal::CGALMeshPtr perform_csgmesh_booleans(const Range<It> &csgparts)
{
auto ret = MeshBoolean::cgal::triangle_mesh_to_cgal(indexed_triangle_set{});
if (ret)
perform_csgmesh_booleans(*ret, csgparts);
return ret;
}
} // namespace csg
} // namespace Slic3r
#endif // PERFORMCSGMESHBOOLEANS_HPP

View file

@ -52,6 +52,8 @@ std::vector<ExPolygons> slice_csgmesh_ex(
return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON);
});
// Hopefully, ExPolygons are moved, not copied to new positions
// and that is cheap for expolygons
slice.erase(it, slice.end());
}
}

View file

@ -26,16 +26,17 @@ namespace cgal {
struct CGALMesh;
struct CGALMeshDeleter { void operator()(CGALMesh *ptr); };
using CGALMeshPtr = std::unique_ptr<CGALMesh, CGALMeshDeleter>;
std::unique_ptr<CGALMesh, CGALMeshDeleter>
triangle_mesh_to_cgal(const std::vector<stl_vertex> &V,
const std::vector<stl_triangle_vertex_indices> &F);
CGALMeshPtr triangle_mesh_to_cgal(
const std::vector<stl_vertex> &V,
const std::vector<stl_triangle_vertex_indices> &F);
inline std::unique_ptr<CGALMesh, CGALMeshDeleter> triangle_mesh_to_cgal(const indexed_triangle_set &M)
inline CGALMeshPtr triangle_mesh_to_cgal(const indexed_triangle_set &M)
{
return triangle_mesh_to_cgal(M.vertices, M.indices);
}
inline std::unique_ptr<CGALMesh, CGALMeshDeleter> triangle_mesh_to_cgal(const TriangleMesh &M)
inline CGALMeshPtr triangle_mesh_to_cgal(const TriangleMesh &M)
{
return triangle_mesh_to_cgal(M.its);
}

View file

@ -18,11 +18,13 @@
#include <libslic3r/SlicesToTriangleMesh.hpp>
#include <libslic3r/CSGMesh/ModelToCSGMesh.hpp>
#include <libslic3r/CSGMesh/SliceCSGMesh.hpp>
#include <libslic3r/CSGMesh/VoxelizeCSGMesh.hpp>>
#include <libslic3r/CSGMesh/PerformCSGMeshBooleans.hpp>
#include <libslic3r/OpenVDBUtils.hpp>
#include <libslic3r/QuadricEdgeCollapse.hpp>
#include <libslic3r/ClipperUtils.hpp>
#include <libslic3r/ShortEdgeCollapse.hpp>
//#include <libslic3r/ShortEdgeCollapse.hpp>
#include <boost/log/trivial.hpp>
@ -128,48 +130,50 @@ void SLAPrint::Steps::apply_printer_corrections(SLAPrintObject &po, SliceOrigin
}
}
void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep step)
indexed_triangle_set SLAPrint::Steps::generate_preview_vdb(
SLAPrintObject &po, SLAPrintObjectStep step)
{
Benchmark bench;
bench.start();
// update preview mesh
double vscale = 1. / (2. * po.m_config.layer_height.getFloat());
auto voxparams = csg::VoxelizeParams{}
.voxel_scale(vscale)
.exterior_bandwidth(1.f)
.interior_bandwidth(1.f);
auto grid = csg::voxelize_csgmesh(range(po.m_mesh_to_slice), voxparams);
indexed_triangle_set m = grid_to_mesh(*grid);
// if (!m.empty()) {
// // simplify mesh lossless
bench.stop();
// std::cout << "simplify started" << std::endl;
// int expected_cnt = m.indices.size() * 0.8; //std::pow(po.m_transformed_rmesh.volume() / std::pow(1./vscale, 3), 2./3.);
// std::cout << "expected triangles " << expected_cnt << std::endl;
// float err = std::pow(vscale, 3);
// its_quadric_edge_collapse(m, 0U, &err);
// std::cout << "simplify ended " << m.indices.size() << " triangles" << std::endl;
std::cout << "Preview gen took: " << bench.getElapsedSec() << std::endl;
// std::cout << "cleanup started" << std::endl;
// its_compactify_vertices(m);
// its_merge_vertices(m);
// std::cout << "cleanup ended" << std::endl;
// }
return m;
}
po.m_preview_meshes[step] = TriangleMesh{std::move(m)};
void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep step)
{
MeshBoolean::cgal::CGALMeshPtr cgalptr;
try {
cgalptr = csg::perform_csgmesh_booleans(range(po.m_mesh_to_slice));
} catch(...) {}
if (cgalptr) {
po.m_preview_meshes[step] = MeshBoolean::cgal::cgal_to_triangle_mesh(*cgalptr);
} else
po.m_preview_meshes[step] = TriangleMesh{generate_preview_vdb(po, step)};
for (size_t i = size_t(step) + 1; i < slaposCount; ++i)
{
po.m_preview_meshes[i] = {};
}
bench.stop();
std::cout << "Preview gen took: " << bench.getElapsedSec() << std::endl;
using namespace std::string_literals;
report_status(-2, "Reload preview from step "s + std::to_string(int(step)), SlicingStatus::RELOAD_SLA_PREVIEW);

View file

@ -46,7 +46,8 @@ private:
void apply_printer_corrections(SLAPrintObject &po, SliceOrigin o);
void generate_preview(SLAPrintObject &po, SLAPrintObjectStep step);
indexed_triangle_set generate_preview_vdb(SLAPrintObject &po, SLAPrintObjectStep step);
public:
explicit Steps(SLAPrint *print);