From 57a66f1dfb7fed84ef6910119ce1888b931fa0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Mon, 9 Aug 2021 15:39:35 +0200 Subject: [PATCH 01/18] The offset is applied after the elephant food compensation. The value of the brim offset is now also measured from the object after the elephant foot compensation. Thus, the brim offset set to zero means that the brim will touch the object even if elephant foot compensation is enabled. --- src/libslic3r/Brim.cpp | 97 ++++++++++++++++++++++++----------- src/libslic3r/PrintConfig.cpp | 5 +- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 853c5e22e9d..e73bed2c9f4 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -45,16 +45,38 @@ static float max_brim_width(const ConstPrintObjectPtrsAdaptor &objects) })); } -static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print) +// Returns ExPolygons of the bottom layer of the print object after elephant foot compensation. +static ExPolygons get_print_object_bottom_layer_expolygons(const PrintObject &print_object) { + ExPolygons ex_polygons; + for (LayerRegion *region : print_object.layers().front()->regions()) + Slic3r::append(ex_polygons, offset_ex(offset_ex(region->slices.surfaces, float(SCALED_EPSILON)), -float(SCALED_EPSILON))); + return ex_polygons; +} + +// Returns ExPolygons of bottom layer for every print object in Print after elephant foot compensation. +static std::vector get_print_bottom_layers_expolygons(const Print &print) +{ + std::vector bottom_layers_expolygons; + bottom_layers_expolygons.reserve(print.objects().size()); + for (const PrintObject *object : print.objects()) + bottom_layers_expolygons.emplace_back(get_print_object_bottom_layer_expolygons(*object)); + + return bottom_layers_expolygons; +} + +static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print, const std::vector &bottom_layers_expolygons) +{ + assert(print.objects().size() == bottom_layers_expolygons.size()); Polygons islands; ConstPrintObjectPtrs island_to_object; - for (const PrintObject *object : print.objects()) { + for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) { Polygons islands_object; - islands_object.reserve(object->layers().front()->lslices.size()); - for (const ExPolygon &ex_poly : object->layers().front()->lslices) + islands_object.reserve(bottom_layers_expolygons[print_object_idx].size()); + for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx]) islands_object.emplace_back(ex_poly.contour); + const PrintObject *object = print.objects()[print_object_idx]; islands.reserve(islands.size() + object->instances().size() * islands_object.size()); for (const PrintInstance &instance : object->instances()) for (Polygon &poly : islands_object) { @@ -110,7 +132,7 @@ static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_lev //FIXME how about the brim type? auto brim_offset = float(scale_(object->config().brim_offset.value)); Polygons islands_object; - for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + for (const ExPolygon &ex_poly : get_print_object_bottom_layer_expolygons(*object)) { Polygons contour_offset = offset(ex_poly.contour, brim_offset); for (Polygon &poly : contour_offset) poly.douglas_peucker(SCALED_RESOLUTION); @@ -124,8 +146,12 @@ static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_lev return islands; } -static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset) +static ExPolygons top_level_outer_brim_area(const Print &print, + const ConstPrintObjectPtrs &top_level_objects_with_brim, + const std::vector &bottom_layers_expolygons, + const float no_brim_offset) { + assert(print.objects().size() == bottom_layers_expolygons.size()); std::unordered_set top_level_objects_idx; top_level_objects_idx.reserve(top_level_objects_with_brim.size()); for (const PrintObject *object : top_level_objects_with_brim) @@ -133,15 +159,16 @@ static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrint ExPolygons brim_area; ExPolygons no_brim_area; - for (const PrintObject *object : print.objects()) { - const BrimType brim_type = object->config().brim_type.value; - const float brim_offset = scale_(object->config().brim_offset.value); - const float brim_width = scale_(object->config().brim_width.value); - const bool is_top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); + for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) { + const PrintObject *object = print.objects()[print_object_idx]; + const BrimType brim_type = object->config().brim_type.value; + const float brim_offset = scale_(object->config().brim_offset.value); + const float brim_width = scale_(object->config().brim_width.value); + const bool is_top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); ExPolygons brim_area_object; ExPolygons no_brim_area_object; - for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx]) { if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) && is_top_outer_brim) append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_offset), offset(ex_poly.contour, brim_offset))); @@ -166,8 +193,12 @@ static ExPolygons top_level_outer_brim_area(const Print &print, const ConstPrint return diff_ex(brim_area, no_brim_area); } -static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, const float no_brim_offset) +static ExPolygons inner_brim_area(const Print &print, + const ConstPrintObjectPtrs &top_level_objects_with_brim, + const std::vector &bottom_layers_expolygons, + const float no_brim_offset) { + assert(print.objects().size() == bottom_layers_expolygons.size()); std::unordered_set top_level_objects_idx; top_level_objects_idx.reserve(top_level_objects_with_brim.size()); for (const PrintObject *object : top_level_objects_with_brim) @@ -176,16 +207,17 @@ static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs ExPolygons brim_area; ExPolygons no_brim_area; Polygons holes; - for (const PrintObject *object : print.objects()) { - const BrimType brim_type = object->config().brim_type.value; - const float brim_offset = scale_(object->config().brim_offset.value); - const float brim_width = scale_(object->config().brim_width.value); - const bool top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); + for(size_t print_object_idx = 0; print_object_idx < print.objects().size(); ++print_object_idx) { + const PrintObject *object = print.objects()[print_object_idx]; + const BrimType brim_type = object->config().brim_type.value; + const float brim_offset = scale_(object->config().brim_offset.value); + const float brim_width = scale_(object->config().brim_width.value); + const bool top_outer_brim = top_level_objects_idx.find(object->id().id) != top_level_objects_idx.end(); ExPolygons brim_area_object; ExPolygons no_brim_area_object; Polygons holes_object; - for (const ExPolygon &ex_poly : object->layers().front()->lslices) { + for (const ExPolygon &ex_poly : bottom_layers_expolygons[print_object_idx]) { if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner) { if (top_outer_brim) no_brim_area_object.emplace_back(ex_poly); @@ -204,7 +236,7 @@ static ExPolygons inner_brim_area(const Print &print, const ConstPrintObjectPtrs append(holes_object, ex_poly.holes); } - append(no_brim_area_object, offset_ex(object->layers().front()->lslices, brim_offset)); + append(no_brim_area_object, offset_ex(bottom_layers_expolygons[print_object_idx], brim_offset)); for (const PrintInstance &instance : object->instances()) { append_and_translate(brim_area, brim_area_object, instance); @@ -236,7 +268,7 @@ static void optimize_polylines_by_reversing(Polylines *polylines) static Polylines connect_brim_lines(Polylines &&polylines, const Polygons &brim_area, float max_connection_length) { if (polylines.empty()) - return Polylines(); + return {}; BoundingBox bbox = get_extents(polylines); bbox.merge(get_extents(brim_area)); @@ -305,16 +337,20 @@ static Polylines connect_brim_lines(Polylines &&polylines, const Polygons &brim_ } } if (end < polylines.size()) - polylines.erase(polylines.begin() + end, polylines.end()); + polylines.erase(polylines.begin() + int(end), polylines.end()); } return std::move(polylines); } -static void make_inner_brim(const Print &print, const ConstPrintObjectPtrs &top_level_objects_with_brim, ExtrusionEntityCollection &brim) +static void make_inner_brim(const Print &print, + const ConstPrintObjectPtrs &top_level_objects_with_brim, + const std::vector &bottom_layers_expolygons, + ExtrusionEntityCollection &brim) { + assert(print.objects().size() == bottom_layers_expolygons.size()); Flow flow = print.brim_flow(); - ExPolygons islands_ex = inner_brim_area(print, top_level_objects_with_brim, float(flow.scaled_spacing())); + ExPolygons islands_ex = inner_brim_area(print, top_level_objects_with_brim, bottom_layers_expolygons, float(flow.scaled_spacing())); Polygons loops; islands_ex = offset_ex(islands_ex, -0.5f * float(flow.scaled_spacing()), jtSquare); for (size_t i = 0; !islands_ex.empty(); ++i) { @@ -334,11 +370,12 @@ static void make_inner_brim(const Print &print, const ConstPrintObjectPtrs &top_ // Collect islands_area to be merged into the final 1st layer convex hull. ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area) { - Flow flow = print.brim_flow(); - ConstPrintObjectPtrs top_level_objects_with_brim = get_top_level_objects_with_brim(print); - Polygons islands = top_level_outer_brim_islands(top_level_objects_with_brim); - ExPolygons islands_area_ex = top_level_outer_brim_area(print, top_level_objects_with_brim, float(flow.scaled_spacing())); - islands_area = to_polygons(islands_area_ex); + Flow flow = print.brim_flow(); + std::vector bottom_layers_expolygons = get_print_bottom_layers_expolygons(print); + ConstPrintObjectPtrs top_level_objects_with_brim = get_top_level_objects_with_brim(print, bottom_layers_expolygons); + Polygons islands = top_level_outer_brim_islands(top_level_objects_with_brim); + ExPolygons islands_area_ex = top_level_outer_brim_area(print, top_level_objects_with_brim, bottom_layers_expolygons, float(flow.scaled_spacing())); + islands_area = to_polygons(islands_area_ex); Polygons loops; size_t num_loops = size_t(floor(max_brim_width(print.objects()) / flow.spacing())); @@ -536,7 +573,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance extrusion_entities_append_loops_and_paths(brim.entities, std::move(all_loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height())); } - make_inner_brim(print, top_level_objects_with_brim, brim); + make_inner_brim(print, top_level_objects_with_brim, bottom_layers_expolygons, brim); return brim; } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index ed7961ce108..99154f10209 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -491,10 +491,11 @@ void PrintConfigDef::init_fff_params() def = this->add("brim_offset", coFloat); def->label = L("Brim offset"); def->category = L("Skirt and brim"); - def->tooltip = L("The offset of the brim from the printed object."); + def->tooltip = L("The offset of the brim from the printed object. The offset is applied after the elephant foot compensation."); def->sidetext = L("mm"); + def->min = 0; def->mode = comSimple; - def->set_default_value(new ConfigOptionFloat(0)); + def->set_default_value(new ConfigOptionFloat(0.1f)); def = this->add("clip_multipart_objects", coBool); def->label = L("Clip multi-part objects"); From c286a0fcca5df5bb57b69efe6b8c19f9537503e6 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 27 Jul 2021 16:17:12 +0200 Subject: [PATCH 02/18] Rotfinder fixes wip --- src/libslic3r/SLA/Rotfinder.cpp | 74 ++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index b8492127935..7c1e0daef16 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -58,29 +58,6 @@ T sum_score(AccessFn &&accessfn, size_t facecount, size_t Nthreads) return execution::reduce(ex_tbb, from, to, initv, mergefn, accessfn, grainsize); } -// Try to guess the number of support points needed to support a mesh -double get_misalginment_score(const TriangleMesh &mesh, const Transform3f &tr) -{ - if (mesh.its.vertices.empty()) return std::nan(""); - - auto accessfn = [&mesh, &tr](size_t fi) { - auto triangle = get_transformed_triangle(mesh, tr, fi); - Vec3f U = triangle[1] - triangle[0]; - Vec3f V = triangle[2] - triangle[0]; - Vec3f C = U.cross(V); - - // We should score against the alignment with the reference planes - return scaled(std::abs(C.dot(Vec3f::UnitX())) + - std::abs(C.dot(Vec3f::UnitY()))); - }; - - size_t facecount = mesh.its.indices.size(); - size_t Nthreads = std::thread::hardware_concurrency(); - double S = unscaled(sum_score(accessfn, facecount, Nthreads)); - - return S / facecount; -} - // Get area and normal of a triangle struct Facestats { Vec3f normal; @@ -96,18 +73,43 @@ struct Facestats { } }; +// Try to guess the number of support points needed to support a mesh +double get_misalginment_score(const TriangleMesh &mesh, const Transform3f &tr) +{ + if (mesh.its.vertices.empty()) return std::nan(""); + + auto accessfn = [&mesh, &tr](size_t fi) { + Facestats fc{get_transformed_triangle(mesh, tr, fi)}; + + float score = fc.area + * (std::abs(fc.normal.dot(Vec3f::UnitX())) + + std::abs(fc.normal.dot(Vec3f::UnitY())) + + std::abs(fc.normal.dot(Vec3f::UnitZ()))); + + // We should score against the alignment with the reference planes + return scaled(score); + }; + + size_t facecount = mesh.its.indices.size(); + size_t Nthreads = std::thread::hardware_concurrency(); + double S = unscaled(sum_score(accessfn, facecount, Nthreads)); + + return S / facecount; +} + // The score function for a particular face inline double get_supportedness_score(const Facestats &fc) { // Simply get the angle (acos of dot product) between the face normal and // the DOWN vector. - float phi = 1. - std::acos(fc.normal.dot(DOWN)) / float(PI); + float cosphi = fc.normal.dot(DOWN); + float phi = 1.f - std::acos(cosphi) / float(PI); // Only consider faces that have slopes below 90 deg: - phi = phi * (phi >= 0.5f); + phi = (1.f + phi) * (phi >= 0.5f); // Make the huge slopes more significant than the smaller slopes - phi = phi * phi * phi; + phi = phi * phi; // Multiply with the area of the current face return fc.area * POINTS_PER_UNIT_AREA * phi; @@ -121,7 +123,7 @@ double get_supportedness_score(const TriangleMesh &mesh, const Transform3f &tr) auto accessfn = [&mesh, &tr](size_t fi) { Facestats fc{get_transformed_triangle(mesh, tr, fi)}; - return get_supportedness_score(fc); + return scaled(get_supportedness_score(fc)); }; size_t facecount = mesh.its.indices.size(); @@ -164,7 +166,7 @@ float get_supportedness_onfloor_score(const TriangleMesh &mesh, Facestats fc{tri}; if (tri[0].z() <= zlvl && tri[1].z() <= zlvl && tri[2].z() <= zlvl) - return -fc.area * POINTS_PER_UNIT_AREA; + return -2 * fc.area * POINTS_PER_UNIT_AREA; return get_supportedness_score(fc); }; @@ -353,6 +355,15 @@ Vec2d find_least_supports_rotation(const ModelObject & mo, TriangleMesh mesh = mo.raw_mesh(); mesh.require_shared_vertices(); + ModelInstance* mi = mo.instances[0]; + Vec3d rotation = mi->get_rotation(); + Transform3d trafo_instance = Geometry::assemble_transform(mi->get_offset().z() * Vec3d::UnitZ(), + rotation, + mi->get_scaling_factor(), + mi->get_mirror()); + + mesh.transform(trafo_instance); + // To keep track of the number of iterations unsigned status = 0; @@ -419,6 +430,13 @@ Vec2d find_least_supports_rotation(const ModelObject & mo, // Save the result rot = result.optimum; + std::cout << "Score was: " << result.score << std::endl; + +//auto rt = mo.instances[0]->get_rotation(); +//double score = get_supportedness_score(mesh, to_transform3f({rt(0), rt(1)})); +// std::cout << "Score was: " << score << std::endl; +// rot[0] = rt(0); +// rot[1] = rt(1); } return {rot[0], rot[1]}; From c08cdf560597dc5a30cc15b7493ad81e14caafb1 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 16 Aug 2021 11:29:09 +0200 Subject: [PATCH 03/18] Make the input mesh transformation consistent. Also add some comments --- src/libslic3r/SLA/Rotfinder.cpp | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index 7c1e0daef16..daa3154d7c2 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -105,7 +105,9 @@ inline double get_supportedness_score(const Facestats &fc) float cosphi = fc.normal.dot(DOWN); float phi = 1.f - std::acos(cosphi) / float(PI); - // Only consider faces that have slopes below 90 deg: + // Phi is raised by 1.0 to not be less than zero when squared in the next + // step. If phi is greater than 0.5 (slope is > 90 deg) make phi zero + // to not skip this face in the overall score. phi = (1.f + phi) * (phi >= 0.5f); // Make the huge slopes more significant than the smaller slopes @@ -285,6 +287,26 @@ std::array find_min_score(Fn &&fn, It from, It to, StopCond &&stopfn) } // namespace +// Assemble the mesh with the correct transformation to be used in rotation +// optimization. +TriangleMesh get_mesh_to_rotate(const ModelObject &mo) +{ + TriangleMesh mesh = mo.raw_mesh(); + mesh.require_shared_vertices(); + + ModelInstance *mi = mo.instances[0]; + auto rotation = Vec3d::Zero(); + auto offset = Vec3d::Zero(); + Transform3d trafo_instance = Geometry::assemble_transform(offset, + rotation, + mi->get_scaling_factor(), + mi->get_mirror()); + + mesh.transform(trafo_instance); + + return mesh; +} + Vec2d find_best_misalignment_rotation(const ModelObject & mo, const RotOptimizeParams ¶ms) { @@ -295,8 +317,7 @@ Vec2d find_best_misalignment_rotation(const ModelObject & mo, // We will use only one instance of this converted mesh to examine different // rotations - TriangleMesh mesh = mo.raw_mesh(); - mesh.require_shared_vertices(); + TriangleMesh mesh = get_mesh_to_rotate(mo); // To keep track of the number of iterations int status = 0; @@ -352,17 +373,7 @@ Vec2d find_least_supports_rotation(const ModelObject & mo, // We will use only one instance of this converted mesh to examine different // rotations - TriangleMesh mesh = mo.raw_mesh(); - mesh.require_shared_vertices(); - - ModelInstance* mi = mo.instances[0]; - Vec3d rotation = mi->get_rotation(); - Transform3d trafo_instance = Geometry::assemble_transform(mi->get_offset().z() * Vec3d::UnitZ(), - rotation, - mi->get_scaling_factor(), - mi->get_mirror()); - - mesh.transform(trafo_instance); + TriangleMesh mesh = get_mesh_to_rotate(mo); // To keep track of the number of iterations unsigned status = 0; @@ -430,13 +441,6 @@ Vec2d find_least_supports_rotation(const ModelObject & mo, // Save the result rot = result.optimum; - std::cout << "Score was: " << result.score << std::endl; - -//auto rt = mo.instances[0]->get_rotation(); -//double score = get_supportedness_score(mesh, to_transform3f({rt(0), rt(1)})); -// std::cout << "Score was: " << score << std::endl; -// rot[0] = rt(0); -// rot[1] = rt(1); } return {rot[0], rot[1]}; From 6b14914dd4ddd3ef2c88b1dd1a6b32da5ee92d59 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 16 Aug 2021 13:05:31 +0200 Subject: [PATCH 04/18] SLA supports: ask about saving changes when Esc is pressed --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 33 ++++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 1 + 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 15f289251f2..6d8ae36ab22 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -447,7 +447,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous } if (action == SLAGizmoEventType::DiscardChanges) { - editing_mode_discard_changes(); + ask_about_changes_call_after([this](){ editing_mode_apply_changes(); }, + [this](){ editing_mode_discard_changes(); }); return true; } @@ -879,6 +880,22 @@ CommonGizmosDataID GLGizmoSlaSupports::on_get_requirements() const +void GLGizmoSlaSupports::ask_about_changes_call_after(std::function on_yes, std::function on_no) +{ + wxGetApp().CallAfter([this, on_yes, on_no]() { + // Following is called through CallAfter, because otherwise there was a problem + // on OSX with the wxMessageDialog being shown several times when clicked into. + MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually " + "edited support points?") + "\n",_L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL ); + int ret = dlg.ShowModal(); + if (ret == wxID_YES) + on_yes(); + else if (ret == wxID_NO) + on_no(); + }); +} + + void GLGizmoSlaSupports::on_set_state() { if (m_state == m_old_state) @@ -901,18 +918,8 @@ void GLGizmoSlaSupports::on_set_state() if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off bool will_ask = m_editing_mode && unsaved_changes() && on_is_activable(); if (will_ask) { - wxGetApp().CallAfter([this]() { - // Following is called through CallAfter, because otherwise there was a problem - // on OSX with the wxMessageDialog being shown several times when clicked into. - //wxMessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually " - MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually " - "edited support points?") + "\n",_L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL ); - int ret = dlg.ShowModal(); - if (ret == wxID_YES) - editing_mode_apply_changes(); - else if (ret == wxID_NO) - editing_mode_discard_changes(); - }); + ask_about_changes_call_after([this](){ editing_mode_apply_changes(); }, + [this](){ editing_mode_discard_changes(); }); // refuse to be turned off so the gizmo is active when the CallAfter is executed m_state = m_old_state; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index 6982ecf765f..cb60c0e258c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -117,6 +117,7 @@ private: void auto_generate(); void switch_to_editing_mode(); void disable_editing_mode(); + void ask_about_changes_call_after(std::function on_yes, std::function on_no); protected: void on_set_state() override; From faeef15a4dc11091eb5e2a2b88227ce3e5e9630c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 16 Aug 2021 16:03:20 +0200 Subject: [PATCH 05/18] Add tooltips for combo items in rotation optimization dialog --- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 28 +++++++++++++------------ src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 4 ---- src/slic3r/GUI/Jobs/RotoptimizeJob.hpp | 27 ++++++++++-------------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index a495db4f136..417a6a6443d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -497,9 +497,6 @@ void GLGizmoRotate3D::on_render() m_gizmos[Z].render(); } -const char * GLGizmoRotate3D::RotoptimzeWindow::options[RotoptimizeJob::get_methods_count()]; -bool GLGizmoRotate3D::RotoptimzeWindow::options_valid = false; - GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui, State & state, const Alignment &alignment) @@ -517,19 +514,24 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui, ImGui::PushItemWidth(200.f); - size_t methods_cnt = RotoptimizeJob::get_methods_count(); - if (!options_valid) { - for (size_t i = 0; i < methods_cnt; ++i) - options[i] = RotoptimizeJob::get_method_names()[i].c_str(); + if (ImGui::BeginCombo(_L("Choose goal").c_str(), RotoptimizeJob::get_method_name(state.method_id).c_str())) { + for (size_t i = 0; i < RotoptimizeJob::get_methods_count(); ++i) { + if (ImGui::Selectable(RotoptimizeJob::get_method_name(i).c_str())) { + state.method_id = i; + wxGetApp().app_config->set("sla_auto_rotate", + "method_id", + std::to_string(state.method_id)); + } - options_valid = true; + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("%s", RotoptimizeJob::get_method_description(i).c_str()); + } + + ImGui::EndCombo(); } - int citem = state.method_id; - if (ImGui::Combo(_L("Choose goal").c_str(), &citem, options, methods_cnt) ) { - state.method_id = citem; - wxGetApp().app_config->set("sla_auto_rotate", "method_id", std::to_string(state.method_id)); - } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("%s", RotoptimizeJob::get_method_description(state.method_id).c_str()); ImGui::Separator(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index a51f900bf1e..3245c4dbe87 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -138,10 +138,6 @@ private: class RotoptimzeWindow { ImGuiWrapper *m_imgui = nullptr; - - static const char * options []; - static bool options_valid; - public: struct State { diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp index 3144f3c3e64..3f10df04478 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp @@ -15,13 +15,13 @@ class RotoptimizeJob : public PlaterJob using FindFn = std::function; - struct FindMethod { std::string name; FindFn findfn; }; + struct FindMethod { std::string name; FindFn findfn; std::string descr; }; static inline const FindMethod Methods[] = { - { L("Best surface quality"), sla::find_best_misalignment_rotation }, - { L("Least supports"), sla::find_least_supports_rotation }, + { L("Best surface quality"), sla::find_best_misalignment_rotation, L("Optimize object rotation for best surface quality.") }, + { L("Least supports"), sla::find_least_supports_rotation, L("Optimize object rotation to have minimum amount of overhangs needing support structures.") }, // Just a min area bounding box that is done for all methods anyway. - { L("Z axis only"), nullptr } + { L("Z axis only"), nullptr, L("Rotate the object only in Z axis to have the smallest bounding box.") } }; size_t m_method_id = 0; @@ -52,20 +52,15 @@ public: void finalize() override; static constexpr size_t get_methods_count() { return std::size(Methods); } - static const auto & get_method_names() + + static std::string get_method_name(size_t i) { - static bool m_method_names_valid = false; - static std::array m_method_names; + return _utf8(Methods[i].name); + } - if (!m_method_names_valid) { - - for (size_t i = 0; i < std::size(Methods); ++i) - m_method_names[i] = _utf8(Methods[i].name); - - m_method_names_valid = true; - } - - return m_method_names; + static std::string get_method_description(size_t i) + { + return _utf8(Methods[i].descr); } }; From b5f7fd8793f7b877018e0c7018bb633d903e05f5 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 16 Aug 2021 16:42:56 +0200 Subject: [PATCH 06/18] Extend tooltip texts --- src/slic3r/GUI/Jobs/RotoptimizeJob.hpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp index 3f10df04478..bb4310e638c 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp @@ -17,12 +17,19 @@ class RotoptimizeJob : public PlaterJob struct FindMethod { std::string name; FindFn findfn; std::string descr; }; - static inline const FindMethod Methods[] = { - { L("Best surface quality"), sla::find_best_misalignment_rotation, L("Optimize object rotation for best surface quality.") }, - { L("Least supports"), sla::find_least_supports_rotation, L("Optimize object rotation to have minimum amount of overhangs needing support structures.") }, - // Just a min area bounding box that is done for all methods anyway. - { L("Z axis only"), nullptr, L("Rotate the object only in Z axis to have the smallest bounding box.") } - }; + static inline const FindMethod Methods[] + = {{L("Best surface quality"), + sla::find_best_misalignment_rotation, + L("Optimize object rotation for best surface quality.")}, + {L("Least supports"), + sla::find_least_supports_rotation, + L("Optimize object rotation to have minimum amount of overhangs needing support " + "structures.\nNote that this method will try to find the best surface of the object " + "for touching the print bed if no elevation is set.")}, + // Just a min area bounding box that is done for all methods anyway. + {L("Z axis only"), + nullptr, + L("Rotate the object only in Z axis to have the smallest bounding box.")}}; size_t m_method_id = 0; float m_accuracy = 0.75; From 7b61e2f9a086867891aa9da3b96f405874649025 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 16 Aug 2021 13:26:27 +0200 Subject: [PATCH 07/18] Slightly changed 'Some objects missing' warning text --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 529056e9998..227e5ae4e5f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6380,7 +6380,7 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) case EWarning::ObjectOutside: text = _u8L("An object outside the print area was detected."); break; case EWarning::ToolpathOutside: text = _u8L("A toolpath outside the print area was detected."); error = ErrorType::SLICING_ERROR; break; case EWarning::SlaSupportsOutside: text = _u8L("SLA supports outside the print area were detected."); error = ErrorType::PLATER_ERROR; break; - case EWarning::SomethingNotShown: text = _u8L("Some objects are not visible."); break; + case EWarning::SomethingNotShown: text = _u8L("Some objects are not visible during editing."); break; case EWarning::ObjectClashed: text = _u8L("An object outside the print area was detected.\n" "Resolve the current problem to continue slicing."); From 64e06b6a17c6a2127202f62f837571b41c35ab09 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 12 Aug 2021 13:53:22 +0200 Subject: [PATCH 08/18] ObjectList: Implemented interface for delete InfoItem --- src/slic3r/GUI/GUI_ObjectList.cpp | 11 +++++++---- src/slic3r/GUI/GUI_ObjectList.hpp | 1 + src/slic3r/GUI/ObjectDataViewModel.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 07119b8de12..138eb829684 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1778,10 +1778,8 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) del_layers_from_object(obj_idx); else if (type & itLayer && obj_idx != -1) del_layer_from_object(obj_idx, m_objects_model->GetLayerRangeByItem(item)); - else if (type & itInfo && obj_idx != -1) { - Unselect(item); - Select(parent); - } + else if (type & itInfo && obj_idx != -1) + del_info_item(obj_idx, m_objects_model->GetInfoItemType(item)); else if (idx == -1) return; else if (!del_subobject_from_object(obj_idx, idx, type)) @@ -1795,6 +1793,11 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) update_info_items(obj_idx); } +void ObjectList::del_info_item(const int obj_idx, InfoItemType type) +{ + // ToDo lmFIXME :) +} + void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item) { const bool is_layer_settings = m_objects_model->GetItemType(parent_item) == itLayer; diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 71730b2c06e..0fbad191921 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -254,6 +254,7 @@ public: void del_layer_from_object(const int obj_idx, const t_layer_height_range& layer_range); void del_layers_from_object(const int obj_idx); bool del_subobject_from_object(const int obj_idx, const int idx, const int type); + void del_info_item(const int obj_idx, InfoItemType type); void split(); void merge(bool to_multipart_object); void layers_editing(); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index 96d7ca8aeda..9417364ef1d 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -1141,7 +1141,7 @@ void ObjectDataViewModel::GetItemInfo(const wxDataViewItem& item, ItemType& type if (!node || node->GetIdx() <-1 || ( node->GetIdx() == -1 && - !(node->GetType() & (itObject | itSettings | itInstanceRoot | itLayerRoot/* | itLayer*/)) + !(node->GetType() & (itObject | itSettings | itInstanceRoot | itLayerRoot | itInfo)) ) ) return; From 464b5cb2fa72278885e54fdd130b86fc38b32889 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 16 Aug 2021 09:48:29 +0200 Subject: [PATCH 09/18] Use Del key to delete custom supports etc. from the object list --- src/slic3r/GUI/GUI_ObjectList.cpp | 43 ++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 138eb829684..318705e09eb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1795,7 +1795,48 @@ void ObjectList::del_subobject_item(wxDataViewItem& item) void ObjectList::del_info_item(const int obj_idx, InfoItemType type) { - // ToDo lmFIXME :) + Plater* plater = wxGetApp().plater(); + GLCanvas3D* cnv = plater->canvas3D(); + + switch (type) { + case InfoItemType::CustomSupports: + cnv->get_gizmos_manager().reset_all_states(); + Plater::TakeSnapshot(plater, _L("Remove paint-on supports")); + for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes) + mv->supported_facets.clear(); + break; + + case InfoItemType::CustomSeam: + cnv->get_gizmos_manager().reset_all_states(); + Plater::TakeSnapshot(plater, _L("Remove paint-on seam")); + for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes) + mv->seam_facets.clear(); + break; + + case InfoItemType::MmuSegmentation: + cnv->get_gizmos_manager().reset_all_states(); + Plater::TakeSnapshot(plater, _L("Remove Multi Material painting")); + for (ModelVolume* mv : (*m_objects)[obj_idx]->volumes) + mv->mmu_segmentation_facets.clear(); + break; + + case InfoItemType::Sinking: + Plater::TakeSnapshot(plater, _L("Shift objects to bed")); + (*m_objects)[obj_idx]->ensure_on_bed(); + cnv->reload_scene(true, true); + break; + + case InfoItemType::VariableLayerHeight: + Plater::TakeSnapshot(plater, _L("Remove variable layer height")); + (*m_objects)[obj_idx]->layer_height_profile.clear(); + if (cnv->is_layers_editing_enabled()) + //cnv->post_event(SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); + cnv->force_main_toolbar_left_action(cnv->get_main_toolbar_item_id("layersediting")); + break; + + case InfoItemType::Undef : assert(false); break; + } + cnv->post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS)); } void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item) From 756e6f3a5e1389e9c797deebf278e302efbb00c8 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 17 Aug 2021 15:09:34 +0200 Subject: [PATCH 10/18] Default values for brim_offset anf elefant_foot_compensation set to zero --- src/libslic3r/PrintConfig.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 64afcf298dc..e64824d0db3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -295,7 +295,7 @@ void PrintConfigDef::init_common_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0.2)); + def->set_default_value(new ConfigOptionFloat(0.)); // Options used by physical printers @@ -495,7 +495,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0.1f)); + def->set_default_value(new ConfigOptionFloat(0.f)); def = this->add("clip_multipart_objects", coBool); def->label = L("Clip multi-part objects"); From d0bf4aaca15a9535dd3cd70eaef28eea533f689c Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Aug 2021 15:35:52 +0200 Subject: [PATCH 11/18] Add better defined names for orientation optimizer goals --- src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 2 +- src/slic3r/GUI/Jobs/RotoptimizeJob.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 417a6a6443d..04e08adc15b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -512,7 +512,7 @@ GLGizmoRotate3D::RotoptimzeWindow::RotoptimzeWindow(ImGuiWrapper * imgui, y = std::min(y, alignment.bottom_limit - win_h); ImGui::SetWindowPos(ImVec2(x, y), ImGuiCond_Always); - ImGui::PushItemWidth(200.f); + ImGui::PushItemWidth(300.f); if (ImGui::BeginCombo(_L("Choose goal").c_str(), RotoptimizeJob::get_method_name(state.method_id).c_str())) { for (size_t i = 0; i < RotoptimizeJob::get_methods_count(); ++i) { diff --git a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp index bb4310e638c..edabb7caede 100644 --- a/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp +++ b/src/slic3r/GUI/Jobs/RotoptimizeJob.hpp @@ -21,13 +21,13 @@ class RotoptimizeJob : public PlaterJob = {{L("Best surface quality"), sla::find_best_misalignment_rotation, L("Optimize object rotation for best surface quality.")}, - {L("Least supports"), + {L("Reduced overhang slopes"), sla::find_least_supports_rotation, L("Optimize object rotation to have minimum amount of overhangs needing support " "structures.\nNote that this method will try to find the best surface of the object " "for touching the print bed if no elevation is set.")}, // Just a min area bounding box that is done for all methods anyway. - {L("Z axis only"), + {L("Smallest bounding box (Z axis only)"), nullptr, L("Rotate the object only in Z axis to have the smallest bounding box.")}}; From 2b9d7c1523d3c012841341802a3ff04318291c96 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 17 Aug 2021 15:37:41 +0200 Subject: [PATCH 12/18] Some improvements to "less supports" optimizer --- src/libslic3r/SLA/Rotfinder.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index daa3154d7c2..d18d2fe6bbe 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -105,16 +105,13 @@ inline double get_supportedness_score(const Facestats &fc) float cosphi = fc.normal.dot(DOWN); float phi = 1.f - std::acos(cosphi) / float(PI); - // Phi is raised by 1.0 to not be less than zero when squared in the next - // step. If phi is greater than 0.5 (slope is > 90 deg) make phi zero - // to not skip this face in the overall score. - phi = (1.f + phi) * (phi >= 0.5f); - // Make the huge slopes more significant than the smaller slopes - phi = phi * phi; + phi = phi * phi * phi; - // Multiply with the area of the current face - return fc.area * POINTS_PER_UNIT_AREA * phi; + // Multiply with the square root of face area of the current face, + // the area is less important as it grows. + // This makes many smaller overhangs a bigger impact. + return std::sqrt(fc.area) * POINTS_PER_UNIT_AREA * phi; } // Try to guess the number of support points needed to support a mesh @@ -124,7 +121,6 @@ double get_supportedness_score(const TriangleMesh &mesh, const Transform3f &tr) auto accessfn = [&mesh, &tr](size_t fi) { Facestats fc{get_transformed_triangle(mesh, tr, fi)}; - return scaled(get_supportedness_score(fc)); }; @@ -349,7 +345,7 @@ Vec2d find_best_misalignment_rotation(const ModelObject & mo, // We are searching rotations around only two axes x, y. Thus the // problem becomes a 2 dimensional optimization task. // We can specify the bounds for a dimension in the following way: - auto bounds = opt::bounds({ {-PI/2, PI/2}, {-PI/2, PI/2} }); + auto bounds = opt::bounds({ {-PI, PI}, {-PI, PI} }); auto result = solver.to_max().optimize( [&mesh, &statusfn] (const XYRotation &rot) From 925544c71fea335ba28fe7e5349f3bcd4e3cc230 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 18 Aug 2021 08:59:56 +0200 Subject: [PATCH 13/18] Fixed cut contours after cutting an object in gizmo cut --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 707726e0805..7d3f5c3dfb7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -209,8 +209,13 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) m_imgui->end(); - if (cut_clicked && (m_keep_upper || m_keep_lower)) + if (cut_clicked && (m_keep_upper || m_keep_lower)) { perform_cut(m_parent.get_selection()); + m_cut_contours.cut_z = 0.0f; + m_cut_contours.object_idx = -1; + m_cut_contours.instance_idx = -1; + m_cut_contours.contours.reset(); + } } void GLGizmoCut::set_cut_z(double cut_z) @@ -308,9 +313,8 @@ void GLGizmoCut::update_contours() m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f }); } } - else if (box.center() != m_cut_contours.position) { + else if (box.center() != m_cut_contours.position) m_cut_contours.shift = box.center() - m_cut_contours.position; - } } else m_cut_contours.contours.reset(); From 198bbaa6ed8a830b04cbd523ef66e4b2d577e625 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 18 Aug 2021 09:08:39 +0200 Subject: [PATCH 14/18] Fixed compile warning --- src/slic3r/GUI/GUI_Preview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5f9ad5ba510..8c10fb15764 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -789,8 +789,8 @@ void Preview::update_layers_slider_mode() return false; for (ModelVolume* volume : object->volumes) - if (volume->config.has("extruder") && - volume->config.option("extruder")->getInt() != extruder || + if ((volume->config.has("extruder") && + volume->config.option("extruder")->getInt() != extruder) || !volume->mmu_segmentation_facets.empty()) return false; From b4f91cffeeeaad4436cf09f9e238edde3062efff Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 18 Aug 2021 09:36:01 +0200 Subject: [PATCH 15/18] Fix SLA support strut piercing into model --- src/libslic3r/SLA/SupportTreeBuildsteps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/SLA/SupportTreeBuildsteps.cpp b/src/libslic3r/SLA/SupportTreeBuildsteps.cpp index 3c39c64e6b7..6134e1f5ab8 100644 --- a/src/libslic3r/SLA/SupportTreeBuildsteps.cpp +++ b/src/libslic3r/SLA/SupportTreeBuildsteps.cpp @@ -519,7 +519,7 @@ bool SupportTreeBuildsteps::create_ground_pillar(const Vec3d &hjp, auto [polar, azimuth] = dir_to_spheric(dir); polar = PI - m_cfg.bridge_slope; Vec3d d = spheric_to_dir(polar, azimuth).normalized(); - double t = bridge_mesh_distance(endp, dir, radius); + double t = bridge_mesh_distance(endp, d, radius); double tmax = std::min(m_cfg.max_bridge_length_mm, t); t = 0.; From 3b9779e3c28302b70416919cdb811f8a9bbad05d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 18 Aug 2021 09:54:21 +0200 Subject: [PATCH 16/18] #6796 - Fixed crash when selecting Thick Bridges option and then slicing --- src/slic3r/GUI/3DScene.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 992ed7353f0..8ef333d69e5 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -303,13 +303,16 @@ void GLVolume::SinkingContours::render() void GLVolume::SinkingContours::update() { - if (m_parent.is_sinking() && !m_parent.is_below_printbed()) { + int object_idx = m_parent.object_idx(); + Model& model = GUI::wxGetApp().plater()->model(); + + if (0 <= object_idx && object_idx < model.objects.size() && m_parent.is_sinking() && !m_parent.is_below_printbed()) { const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box(); if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) { m_old_box = box; m_shift = Vec3d::Zero(); - const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh(); + const TriangleMesh& mesh = model.objects[object_idx]->volumes[m_parent.volume_idx()]->mesh(); assert(mesh.has_shared_vertices()); m_model.reset(); From 5f6e690a67fb0e40cea4dafc564000bdb60aa455 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 18 Aug 2021 10:05:12 +0200 Subject: [PATCH 17/18] Update build tutorial to reflect current state Reacting to suggestion in #6615 --- doc/How to build - Linux et al.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/How to build - Linux et al.md b/doc/How to build - Linux et al.md index b23fef77281..cf47c939215 100644 --- a/doc/How to build - Linux et al.md +++ b/doc/How to build - Linux et al.md @@ -2,10 +2,10 @@ # Building PrusaSlicer on UNIX/Linux PrusaSlicer uses the CMake build system and requires several dependencies. -The dependencies can be listed in `deps/deps-linux.cmake` and `deps/deps-unix-common.cmake`, although they don't necessarily need to be as recent -as the versions listed - generally versions available on conservative Linux distros such as Debian stable or CentOS should suffice. +The dependencies can be listed in the `deps` directory in individual subdirectories, although they don't necessarily need to be as recent +as the versions listed - generally versions available on conservative Linux distros such as Debian stable, Ubuntu LTS releases or Fedora are likely sufficient. -Perl is not required any more. +Perl is not required anymore. In a typical situation, one would open a command line, go to the PrusaSlicer sources (**the root directory of the repository**), create a directory called `build` or similar, `cd` into it and call: From 367c288dd2a50a6d701527ec9b2e8cf553b25cda Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 18 Aug 2021 10:23:18 +0200 Subject: [PATCH 18/18] Fixed cut contours in gizmo cut after deleting an object --- src/slic3r/GUI/3DScene.cpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 14 ++++++++++---- src/slic3r/GUI/Gizmos/GLGizmoCut.hpp | 10 ++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 8ef333d69e5..9c0341ff45e 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -306,7 +306,7 @@ void GLVolume::SinkingContours::update() int object_idx = m_parent.object_idx(); Model& model = GUI::wxGetApp().plater()->model(); - if (0 <= object_idx && object_idx < model.objects.size() && m_parent.is_sinking() && !m_parent.is_below_printbed()) { + if (0 <= object_idx && object_idx < (int)model.objects.size() && m_parent.is_sinking() && !m_parent.is_below_printbed()) { const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box(); if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) { m_old_box = box; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 7d3f5c3dfb7..40654422e8d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -55,8 +55,15 @@ std::string GLGizmoCut::on_get_name() const void GLGizmoCut::on_set_state() { // Reset m_cut_z on gizmo activation +#if ENABLE_SINKING_CONTOURS + if (get_state() == On) { + m_cut_z = bounding_box().center().z(); + m_cut_contours.reset(); + } +#else if (get_state() == On) m_cut_z = bounding_box().center().z(); +#endif // ENABLE_SINKING_CONTOURS } bool GLGizmoCut::on_is_activable() const @@ -211,10 +218,9 @@ void GLGizmoCut::on_render_input_window(float x, float y, float bottom_limit) if (cut_clicked && (m_keep_upper || m_keep_lower)) { perform_cut(m_parent.get_selection()); - m_cut_contours.cut_z = 0.0f; - m_cut_contours.object_idx = -1; - m_cut_contours.instance_idx = -1; - m_cut_contours.contours.reset(); +#if ENABLE_SINKING_CONTOURS + m_cut_contours.reset(); +#endif // ENABLE_SINKING_CONTOURS } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp index abd8793503c..ffea14ad441 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp @@ -35,6 +35,16 @@ class GLGizmoCut : public GLGizmoBase Vec3d shift{ Vec3d::Zero() }; int object_idx{ -1 }; int instance_idx{ -1 }; + + void reset() { + mesh.clear(); + contours.reset(); + cut_z = 0.0; + position = Vec3d::Zero(); + shift = Vec3d::Zero(); + object_idx = -1; + instance_idx = -1; + } }; CutContours m_cut_contours;