SLA archive import with miniz, marching square bugfixes

Fix compilation on Windows


Fix array subscript out of range error in MarchingSquares


Fix normals of mesh constructed from slices


Improve performance of mesh construction from slices
This commit is contained in:
tamasmeszaros 2020-04-23 19:12:07 +02:00
parent 247fca6d55
commit 217477a9ff
17 changed files with 690 additions and 373 deletions

View file

@ -1,23 +1,40 @@
#include "SlicesToTriangleMesh.hpp"
#include "libslic3r/TriangulateWall.hpp"
#include "libslic3r/MTUtils.hpp"
#include "libslic3r/SLA/Contour3D.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/Tesselate.hpp"
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
namespace Slic3r {
inline sla::Contour3D walls(const Polygon &lower,
const Polygon &upper,
double lower_z_mm,
double upper_z_mm)
inline sla::Contour3D wall_strip(const Polygon &poly,
double lower_z_mm,
double upper_z_mm)
{
Wall w = triangulate_wall(lower, upper, lower_z_mm, upper_z_mm);
sla::Contour3D ret;
ret.points = std::move(w.first);
ret.faces3 = std::move(w.second);
size_t startidx = ret.points.size();
size_t offs = poly.points.size();
ret.points.reserve(ret.points.size() + 2 *offs);
for (const Point &p : poly.points)
ret.points.emplace_back(to_3d(unscaled(p), lower_z_mm));
for (const Point &p : poly.points)
ret.points.emplace_back(to_3d(unscaled(p), upper_z_mm));
for (size_t i = startidx + 1; i < startidx + offs; ++i) {
ret.faces3.emplace_back(i - 1, i, i + offs - 1);
ret.faces3.emplace_back(i, i + offs, i + offs - 1);
}
ret.faces3.emplace_back(startidx + offs - 1, startidx, startidx + 2 * offs - 1);
ret.faces3.emplace_back(startidx, startidx + offs, startidx + 2 * offs - 1);
return ret;
}
@ -27,7 +44,7 @@ sla::Contour3D inline straight_walls(const Polygon &plate,
double lo_z,
double hi_z)
{
return walls(plate, plate, lo_z, hi_z);
return wall_strip(plate, lo_z, hi_z);
}
sla::Contour3D inline straight_walls(const ExPolygon &plate,
@ -43,7 +60,7 @@ sla::Contour3D inline straight_walls(const ExPolygon &plate,
sla::Contour3D inline straight_walls(const ExPolygons &slice,
double lo_z,
double hi_z)
{
{
sla::Contour3D ret;
for (const ExPolygon &poly : slice)
ret.merge(straight_walls(poly, lo_z, hi_z));
@ -51,32 +68,60 @@ sla::Contour3D inline straight_walls(const ExPolygons &slice,
return ret;
}
sla::Contour3D slices_to_triangle_mesh(const std::vector<ExPolygons> &slices,
double zmin,
const std::vector<float> & grid)
{
assert(slices.size() == grid.size());
using Layers = std::vector<sla::Contour3D>;
std::vector<sla::Contour3D> layers(slices.size());
size_t len = slices.size() - 1;
tbb::parallel_for(size_t(0), len, [&slices, &layers, &grid](size_t i) {
const ExPolygons &upper = slices[i + 1];
const ExPolygons &lower = slices[i];
ExPolygons dff1 = diff_ex(lower, upper);
ExPolygons dff2 = diff_ex(upper, lower);
layers[i].merge(triangulate_expolygons_3d(dff1, grid[i], NORMALS_UP));
layers[i].merge(triangulate_expolygons_3d(dff2, grid[i], NORMALS_DOWN));
layers[i].merge(straight_walls(upper, grid[i], grid[i + 1]));
});
sla::Contour3D ret = tbb::parallel_reduce(
tbb::blocked_range(layers.begin(), layers.end()),
sla::Contour3D{},
[](const tbb::blocked_range<Layers::iterator>& r, sla::Contour3D init) {
for(auto it = r.begin(); it != r.end(); ++it ) init.merge(*it);
return init;
},
[]( const sla::Contour3D &a, const sla::Contour3D &b ) {
sla::Contour3D res{a}; res.merge(b); return res;
});
ret.merge(triangulate_expolygons_3d(slices.front(), zmin, NORMALS_DOWN));
ret.merge(straight_walls(slices.front(), zmin, grid.front()));
ret.merge(triangulate_expolygons_3d(slices.back(), grid.back(), NORMALS_UP));
return ret;
}
void slices_to_triangle_mesh(TriangleMesh & mesh,
const std::vector<ExPolygons> &slices,
double zmin,
double lh,
double ilh)
{
sla::Contour3D cntr3d;
double h = zmin;
std::vector<sla::Contour3D> wall_meshes(slices.size());
std::vector<float> grid(slices.size(), zmin + ilh);
auto it = slices.begin(), xt = std::next(it);
cntr3d.merge(triangulate_expolygons_3d(*it, h, NORMALS_DOWN));
cntr3d.merge(straight_walls(*it, h, h + ilh));
h += ilh;
while (xt != slices.end()) {
ExPolygons dff1 = diff_ex(*it, *xt);
ExPolygons dff2 = diff_ex(*xt, *it);
cntr3d.merge(triangulate_expolygons_3d(dff1, h, NORMALS_UP));
cntr3d.merge(triangulate_expolygons_3d(dff2, h, NORMALS_UP));
cntr3d.merge(straight_walls(*xt, h, h + lh));
h += lh;
++it; ++xt;
}
for (size_t i = 1; i < grid.size(); ++i) grid[i] = grid[i - 1] + lh;
cntr3d.merge(triangulate_expolygons_3d(*it, h, NORMALS_UP));
mesh.merge(sla::to_triangle_mesh(cntr3d));
sla::Contour3D cntr = slices_to_triangle_mesh(slices, zmin, grid);
mesh.merge(sla::to_triangle_mesh(cntr));
mesh.repaired = true;
mesh.require_shared_vertices();
}