Do mesh booleans with cgal if possible.
This commit is contained in:
parent
2a8c9d7462
commit
191f04568d
5 changed files with 80 additions and 29 deletions
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue