mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 08:39:02 +08:00
Do mesh booleans with cgal if possible.
This commit is contained in:
parent
2a8c9d7462
commit
191f04568d
@ -5,15 +5,58 @@
|
|||||||
|
|
||||||
#include "libslic3r/MeshBoolean.hpp"
|
#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>
|
template<class It>
|
||||||
void perform_csgmesh_booleans(MeshBoolean::cgal::CGALMesh &cgalm,
|
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
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif // PERFORMCSGMESHBOOLEANS_HPP
|
#endif // PERFORMCSGMESHBOOLEANS_HPP
|
||||||
|
@ -52,6 +52,8 @@ std::vector<ExPolygons> slice_csgmesh_ex(
|
|||||||
return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON);
|
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());
|
slice.erase(it, slice.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,17 @@ namespace cgal {
|
|||||||
|
|
||||||
struct CGALMesh;
|
struct CGALMesh;
|
||||||
struct CGALMeshDeleter { void operator()(CGALMesh *ptr); };
|
struct CGALMeshDeleter { void operator()(CGALMesh *ptr); };
|
||||||
|
using CGALMeshPtr = std::unique_ptr<CGALMesh, CGALMeshDeleter>;
|
||||||
|
|
||||||
std::unique_ptr<CGALMesh, CGALMeshDeleter>
|
CGALMeshPtr triangle_mesh_to_cgal(
|
||||||
triangle_mesh_to_cgal(const std::vector<stl_vertex> &V,
|
const std::vector<stl_vertex> &V,
|
||||||
const std::vector<stl_triangle_vertex_indices> &F);
|
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);
|
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);
|
return triangle_mesh_to_cgal(M.its);
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,13 @@
|
|||||||
#include <libslic3r/SlicesToTriangleMesh.hpp>
|
#include <libslic3r/SlicesToTriangleMesh.hpp>
|
||||||
#include <libslic3r/CSGMesh/ModelToCSGMesh.hpp>
|
#include <libslic3r/CSGMesh/ModelToCSGMesh.hpp>
|
||||||
#include <libslic3r/CSGMesh/SliceCSGMesh.hpp>
|
#include <libslic3r/CSGMesh/SliceCSGMesh.hpp>
|
||||||
|
#include <libslic3r/CSGMesh/VoxelizeCSGMesh.hpp>>
|
||||||
|
#include <libslic3r/CSGMesh/PerformCSGMeshBooleans.hpp>
|
||||||
#include <libslic3r/OpenVDBUtils.hpp>
|
#include <libslic3r/OpenVDBUtils.hpp>
|
||||||
#include <libslic3r/QuadricEdgeCollapse.hpp>
|
#include <libslic3r/QuadricEdgeCollapse.hpp>
|
||||||
|
|
||||||
#include <libslic3r/ClipperUtils.hpp>
|
#include <libslic3r/ClipperUtils.hpp>
|
||||||
#include <libslic3r/ShortEdgeCollapse.hpp>
|
//#include <libslic3r/ShortEdgeCollapse.hpp>
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
@ -128,48 +130,50 @@ void SLAPrint::Steps::apply_printer_corrections(SLAPrintObject &po, SliceOrigin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
indexed_triangle_set SLAPrint::Steps::generate_preview_vdb(
|
||||||
void SLAPrint::Steps::generate_preview(SLAPrintObject &po, SLAPrintObjectStep step)
|
SLAPrintObject &po, SLAPrintObjectStep step)
|
||||||
{
|
{
|
||||||
Benchmark bench;
|
Benchmark bench;
|
||||||
|
|
||||||
bench.start();
|
bench.start();
|
||||||
|
|
||||||
// update preview mesh
|
// update preview mesh
|
||||||
double vscale = 1. / (2. * po.m_config.layer_height.getFloat());
|
double vscale = 1. / (2. * po.m_config.layer_height.getFloat());
|
||||||
auto voxparams = csg::VoxelizeParams{}
|
auto voxparams = csg::VoxelizeParams{}
|
||||||
.voxel_scale(vscale)
|
.voxel_scale(vscale)
|
||||||
.exterior_bandwidth(1.f)
|
.exterior_bandwidth(1.f)
|
||||||
.interior_bandwidth(1.f);
|
.interior_bandwidth(1.f);
|
||||||
|
|
||||||
auto grid = csg::voxelize_csgmesh(range(po.m_mesh_to_slice), voxparams);
|
auto grid = csg::voxelize_csgmesh(range(po.m_mesh_to_slice), voxparams);
|
||||||
|
|
||||||
indexed_triangle_set m = grid_to_mesh(*grid);
|
indexed_triangle_set m = grid_to_mesh(*grid);
|
||||||
|
|
||||||
// if (!m.empty()) {
|
bench.stop();
|
||||||
// // simplify mesh lossless
|
|
||||||
|
|
||||||
// std::cout << "simplify started" << std::endl;
|
std::cout << "Preview gen took: " << bench.getElapsedSec() << 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 << "cleanup started" << std::endl;
|
return m;
|
||||||
// its_compactify_vertices(m);
|
}
|
||||||
// its_merge_vertices(m);
|
|
||||||
// std::cout << "cleanup ended" << std::endl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
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)
|
for (size_t i = size_t(step) + 1; i < slaposCount; ++i)
|
||||||
{
|
{
|
||||||
po.m_preview_meshes[i] = {};
|
po.m_preview_meshes[i] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bench.stop();
|
|
||||||
|
|
||||||
std::cout << "Preview gen took: " << bench.getElapsedSec() << std::endl;
|
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
report_status(-2, "Reload preview from step "s + std::to_string(int(step)), SlicingStatus::RELOAD_SLA_PREVIEW);
|
report_status(-2, "Reload preview from step "s + std::to_string(int(step)), SlicingStatus::RELOAD_SLA_PREVIEW);
|
||||||
|
@ -46,7 +46,8 @@ private:
|
|||||||
void apply_printer_corrections(SLAPrintObject &po, SliceOrigin o);
|
void apply_printer_corrections(SLAPrintObject &po, SliceOrigin o);
|
||||||
|
|
||||||
void generate_preview(SLAPrintObject &po, SLAPrintObjectStep step);
|
void generate_preview(SLAPrintObject &po, SLAPrintObjectStep step);
|
||||||
|
indexed_triangle_set generate_preview_vdb(SLAPrintObject &po, SLAPrintObjectStep step);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Steps(SLAPrint *print);
|
explicit Steps(SLAPrint *print);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user