Merge branch 'tm_sl1_import_fixes'

This commit is contained in:
tamasmeszaros 2021-11-05 15:49:38 +01:00
commit eda0a995a2
5 changed files with 69 additions and 63 deletions

View file

@ -135,7 +135,7 @@ ArchiveData extract_sla_archive(const std::string &zipfname,
ExPolygons rings_to_expolygons(const std::vector<marchsq::Ring> &rings,
double px_w, double px_h)
{
ExPolygons polys; polys.reserve(rings.size());
auto polys = reserve_vector<ExPolygon>(rings.size());
for (const marchsq::Ring &ring : rings) {
Polygon poly; Points &pts = poly.points;
@ -147,7 +147,7 @@ ExPolygons rings_to_expolygons(const std::vector<marchsq::Ring> &rings,
polys.emplace_back(poly);
}
// reverse the raster transformations
// TODO: Is a union necessary?
return union_ex(polys);
}
@ -270,11 +270,11 @@ std::vector<ExPolygons> extract_slices_from_sla_archive(
png::ReadBuf rb{arch.images[i].buf.data(), arch.images[i].buf.size()};
if (!png::decode_png(rb, img)) return;
auto rings = marchsq::execute(img, 128, rstp.win);
uint8_t isoval = 128;
auto rings = marchsq::execute(img, isoval, rstp.win);
ExPolygons expolys = rings_to_expolygons(rings, rstp.px_w, rstp.px_h);
// Invert the raster transformations indicated in
// the profile metadata
// Invert the raster transformations indicated in the profile metadata
invert_raster_trafo(expolys, rstp.trafo, rstp.width, rstp.height);
slices[i] = std::move(expolys);
@ -310,7 +310,18 @@ ConfigSubstitutions import_sla_archive(
std::string exclude_entries{"thumbnail"};
ArchiveData arch = extract_sla_archive(zipfname, exclude_entries);
DynamicPrintConfig profile_in, profile_use;
ConfigSubstitutions config_substitutions = profile_in.load(arch.profile, ForwardCompatibilitySubstitutionRule::Enable);
ConfigSubstitutions config_substitutions =
profile_in.load(arch.profile,
ForwardCompatibilitySubstitutionRule::Enable);
if (profile_in.empty()) { // missing profile... do guess work
// try to recover the layer height from the config.ini which was
// present in all versions of sl1 files.
auto lh_str = arch.config.find("layerHeight")->second.data();
double lh = std::stod(lh_str); // TODO replace with std::from_chars
profile_out.set("layer_height", lh);
profile_out.set("initial_layer_height", lh);
}
// If the archive contains an empty profile, use the one that was passed as output argument
// then replace it with the readed profile to report that it was empty.

View file

@ -1,3 +1,4 @@
#include <numeric>
#include "SlicesToTriangleMesh.hpp"
@ -22,11 +23,16 @@ inline indexed_triangle_set wall_strip(const Polygon &poly,
ret.vertices.reserve(ret.vertices.size() + 2 *offs);
// The expression unscaled(p).cast<float>().eval() is important here
// as it ensures identical conversion of 2D scaled coordinates to float 3D
// to that used by the tesselation. This way, the duplicated vertices in the
// output mesh can be found with the == operator of the points.
// its_merge_vertices will then reliably remove the duplicates.
for (const Point &p : poly.points)
ret.vertices.emplace_back(to_3d(unscaled<float>(p), float(lower_z_mm)));
ret.vertices.emplace_back(to_3d(unscaled(p).cast<float>().eval(), float(lower_z_mm)));
for (const Point &p : poly.points)
ret.vertices.emplace_back(to_3d(unscaled<float>(p), float(upper_z_mm)));
ret.vertices.emplace_back(to_3d(unscaled(p).cast<float>().eval(), float(upper_z_mm)));
for (size_t i = startidx + 1; i < startidx + offs; ++i) {
ret.indices.emplace_back(i - 1, i, i + offs - 1);
@ -84,12 +90,14 @@ indexed_triangle_set slices_to_mesh(
const ExPolygons &upper = slices[i + 1];
const ExPolygons &lower = slices[i];
ExPolygons dff1 = diff_ex(lower, upper);
ExPolygons dff2 = diff_ex(upper, lower);
its_merge(layers[i], triangulate_expolygons_3d(dff1, grid[i], NORMALS_UP));
its_merge(layers[i], triangulate_expolygons_3d(dff2, grid[i], NORMALS_DOWN));
// Small 0 area artefacts can be created by diff_ex, and the
// tesselation also can create 0 area triangles. These will be removed
// by its_remove_degenerate_faces.
ExPolygons free_top = diff_ex(lower, upper);
ExPolygons overhang = diff_ex(upper, lower);
its_merge(layers[i], triangulate_expolygons_3d(free_top, grid[i], NORMALS_UP));
its_merge(layers[i], triangulate_expolygons_3d(overhang, grid[i], NORMALS_DOWN));
its_merge(layers[i], straight_walls(upper, grid[i], grid[i + 1]));
});
auto merge_fn = []( const indexed_triangle_set &a, const indexed_triangle_set &b ) {
@ -99,37 +107,30 @@ indexed_triangle_set slices_to_mesh(
auto ret = execution::reduce(ex_tbb, layers.begin(), layers.end(),
indexed_triangle_set{}, merge_fn);
// 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;
// });
its_merge(ret, triangulate_expolygons_3d(slices.front(), zmin, NORMALS_DOWN));
its_merge(ret, straight_walls(slices.front(), zmin, grid.front()));
its_merge(ret, triangulate_expolygons_3d(slices.back(), grid.back(), NORMALS_UP));
// FIXME: these repairs do not fix the mesh entirely. There will be cracks
// in the output. It is very hard to do the meshing in a way that does not
// leave errors.
its_merge_vertices(ret);
its_remove_degenerate_faces(ret);
its_compactify_vertices(ret);
return ret;
}
void slices_to_mesh(indexed_triangle_set & mesh,
const std::vector<ExPolygons> &slices,
double zmin,
double lh,
double ilh)
const std::vector<ExPolygons> &slices,
double zmin,
double lh,
double ilh)
{
std::vector<indexed_triangle_set> wall_meshes(slices.size());
std::vector<float> grid(slices.size(), zmin + ilh);
for (size_t i = 1; i < grid.size(); ++i)
grid[i] = grid[i - 1] + lh;
for (size_t i = 1; i < grid.size(); ++i) grid[i] = grid[i - 1] + lh;
indexed_triangle_set cntr = slices_to_mesh(slices, zmin, grid);
its_merge(mesh, cntr);
}

View file

@ -7,10 +7,10 @@
namespace Slic3r {
void slices_to_mesh(indexed_triangle_set & mesh,
const std::vector<ExPolygons> &slices,
double zmin,
double lh,
double ilh);
const std::vector<ExPolygons> &slices,
double zmin,
double lh,
double ilh);
inline indexed_triangle_set slices_to_mesh(
const std::vector<ExPolygons> &slices, double zmin, double lh, double ilh)

View file

@ -705,22 +705,16 @@ void its_flip_triangles(indexed_triangle_set &its)
int its_remove_degenerate_faces(indexed_triangle_set &its, bool shrink_to_fit)
{
int last = 0;
for (int i = 0; i < int(its.indices.size()); ++ i) {
const stl_triangle_vertex_indices &face = its.indices[i];
if (face(0) != face(1) && face(0) != face(2) && face(1) != face(2)) {
if (last < i)
its.indices[last] = its.indices[i];
++ last;
}
}
int removed = int(its.indices.size()) - last;
if (removed) {
its.indices.erase(its.indices.begin() + last, its.indices.end());
// Optionally shrink the vertices.
if (shrink_to_fit)
its.indices.shrink_to_fit();
}
auto it = std::remove_if(its.indices.begin(), its.indices.end(), [](auto &face) {
return face(0) == face(1) || face(0) == face(2) || face(1) == face(2);
});
int removed = std::distance(it, its.indices.end());
its.indices.erase(it, its.indices.end());
if (removed && shrink_to_fit)
its.indices.shrink_to_fit();
return removed;
}

View file

@ -122,7 +122,9 @@ public:
std::string err;
ConfigSubstitutions config_substitutions;
priv(Plater *plt) : plater{plt} {}
ImportDlg import_dlg;
priv(Plater *plt) : plater{plt}, import_dlg{plt} {}
};
SLAImportJob::SLAImportJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
@ -176,14 +178,12 @@ void SLAImportJob::prepare()
{
reset();
ImportDlg dlg{p->plater};
if (dlg.ShowModal() == wxID_OK) {
auto path = dlg.get_path();
if (p->import_dlg.ShowModal() == wxID_OK) {
auto path = p->import_dlg.get_path();
auto nm = wxFileName(path);
p->path = !nm.Exists(wxFILE_EXISTS_REGULAR) ? "" : nm.GetFullPath();
p->sel = dlg.get_selection();
p->win = dlg.get_marchsq_windowsize();
p->sel = p->import_dlg.get_selection();
p->win = p->import_dlg.get_marchsq_windowsize();
p->config_substitutions.clear();
} else {
p->path = "";
@ -236,7 +236,7 @@ void SLAImportJob::finalize()
if (!p->mesh.empty()) {
bool is_centered = false;
p->plater->sidebar().obj_list()->load_mesh_object(TriangleMesh{p->mesh},
p->plater->sidebar().obj_list()->load_mesh_object(TriangleMesh{std::move(p->mesh)},
name, is_centered);
}