mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-04 01:48:44 +03:00
QIDISlicer1.0.0
This commit is contained in:
116
src/libslic3r/CSGMesh/VoxelizeCSGMesh.hpp
Normal file
116
src/libslic3r/CSGMesh/VoxelizeCSGMesh.hpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef VOXELIZECSGMESH_HPP
|
||||
#define VOXELIZECSGMESH_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <stack>
|
||||
|
||||
#include "CSGMesh.hpp"
|
||||
#include "libslic3r/OpenVDBUtils.hpp"
|
||||
#include "libslic3r/Execution/ExecutionTBB.hpp"
|
||||
|
||||
namespace Slic3r { namespace csg {
|
||||
|
||||
using VoxelizeParams = MeshToGridParams;
|
||||
|
||||
// This method can be overriden when a specific CSGPart type supports caching
|
||||
// of the voxel grid
|
||||
template<class CSGPartT>
|
||||
VoxelGridPtr get_voxelgrid(const CSGPartT &csgpart, VoxelizeParams params)
|
||||
{
|
||||
const indexed_triangle_set *its = csg::get_mesh(csgpart);
|
||||
VoxelGridPtr ret;
|
||||
|
||||
params.trafo(params.trafo() * csg::get_transform(csgpart));
|
||||
|
||||
if (its)
|
||||
ret = mesh_to_grid(*its, params);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
inline void perform_csg(CSGType op, VoxelGridPtr &dst, VoxelGridPtr &src)
|
||||
{
|
||||
if (!dst || !src)
|
||||
return;
|
||||
|
||||
switch (op) {
|
||||
case CSGType::Union:
|
||||
if (is_grid_empty(*dst) && !is_grid_empty(*src))
|
||||
dst = clone(*src);
|
||||
else
|
||||
grid_union(*dst, *src);
|
||||
|
||||
break;
|
||||
case CSGType::Difference:
|
||||
grid_difference(*dst, *src);
|
||||
break;
|
||||
case CSGType::Intersection:
|
||||
grid_intersection(*dst, *src);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class It>
|
||||
VoxelGridPtr voxelize_csgmesh(const Range<It> &csgrange,
|
||||
const VoxelizeParams ¶ms = {})
|
||||
{
|
||||
using namespace detail;
|
||||
|
||||
VoxelGridPtr ret;
|
||||
|
||||
std::vector<VoxelGridPtr> grids (csgrange.size());
|
||||
|
||||
execution::for_each(ex_tbb, size_t(0), csgrange.size(), [&](size_t csgidx) {
|
||||
if (params.statusfn() && params.statusfn()(-1))
|
||||
return;
|
||||
|
||||
auto it = csgrange.begin();
|
||||
std::advance(it, csgidx);
|
||||
auto &csgpart = *it;
|
||||
grids[csgidx] = get_voxelgrid(csgpart, params);
|
||||
}, execution::max_concurrency(ex_tbb));
|
||||
|
||||
size_t csgidx = 0;
|
||||
struct Frame { CSGType op = CSGType::Union; VoxelGridPtr grid; };
|
||||
std::stack opstack{std::vector<Frame>{}};
|
||||
|
||||
opstack.push({CSGType::Union, mesh_to_grid({}, params)});
|
||||
|
||||
for (auto &csgpart : csgrange) {
|
||||
if (params.statusfn() && params.statusfn()(-1))
|
||||
break;
|
||||
|
||||
auto &partgrid = grids[csgidx++];
|
||||
|
||||
auto op = get_operation(csgpart);
|
||||
|
||||
if (get_stack_operation(csgpart) == CSGStackOp::Push) {
|
||||
opstack.push({op, mesh_to_grid({}, params)});
|
||||
op = CSGType::Union;
|
||||
}
|
||||
|
||||
Frame *top = &opstack.top();
|
||||
|
||||
perform_csg(get_operation(csgpart), top->grid, partgrid);
|
||||
|
||||
if (get_stack_operation(csgpart) == CSGStackOp::Pop) {
|
||||
VoxelGridPtr popgrid = std::move(top->grid);
|
||||
auto popop = opstack.top().op;
|
||||
opstack.pop();
|
||||
VoxelGridPtr &grid = opstack.top().grid;
|
||||
perform_csg(popop, grid, popgrid);
|
||||
}
|
||||
}
|
||||
|
||||
ret = std::move(opstack.top().grid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::csg
|
||||
|
||||
#endif // VOXELIZECSGMESH_HPP
|
||||
Reference in New Issue
Block a user