Merge branch 'tm_sl1_import_fixes'
This commit is contained in:
commit
eda0a995a2
5 changed files with 69 additions and 63 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue