From 58f83b5e6aa6de23fce28bedd718517a3029f481 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 853c5e22e..e73bed2c9 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 ed7961ce1..99154f102 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 11b994a7021fc949ed9e18fa422648f7c7c7c457 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 b84921279..7c1e0daef 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 8b5a63eaf8f42f18bf27d3365ed8c23a4c59a22b 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 7c1e0daef..daa3154d7 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 0b2ee3bb460a6b7768c7b363589441012a0401a9 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 15f289251..6d8ae36ab 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 6982ecf76..cb60c0e25 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 900814ff475a4c1b1c2411eb7ef13e5704012286 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 a495db4f1..417a6a644 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 a51f900bf..3245c4dbe 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 3144f3c3e..3f10df044 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 c37bb0cdd1bf463c0afab4d6d4c889d743c26544 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 3f10df044..bb4310e63 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 5a005e8e0afa60f34073f5aa038252e552c98c6b 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 529056e99..227e5ae4e 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 08e2e29afdd459b0b392b2a082e1e7b599cfe294 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 07119b8de..138eb8296 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 71730b2c0..0fbad1919 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 96d7ca8ae..9417364ef 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 dd1e1307bebc2558dd79e05389401854f3e36879 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 138eb8296..318705e09 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 86c1e5c50fa145cdd23a2578cecacf891d827a3b 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 64afcf298..e64824d0d 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 1a2e58e521b030f14daf78cede926131e3b6738c 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 417a6a644..04e08adc1 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 bb4310e63..edabb7cae 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 24815381d2e3f266e30a7cb6aa08bed0e695ec41 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 daa3154d7..d18d2fe6b 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 e645f4a4eeff19b40268ad62307f845453a972c7 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 707726e08..7d3f5c3df 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 432629ec97c522efa76a9914ffdbbb4d80c768df 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 5f9ad5ba5..8c10fb157 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 5e0cbbef836746dd51fcaf4c1267bc89b778cfd9 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 3c39c64e6..6134e1f5a 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 9767747b3b75f99081070cd1e870d4924502184f 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 992ed7353..8ef333d69 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 ad0902e44e74727936dbc3eb057fb8b2bf4b3ed7 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 b23fef772..cf47c9392 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 740067c576a2f4c8c6eb7097c51c85fa1c3ff38d 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 8ef333d69..9c0341ff4 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 7d3f5c3df..40654422e 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 abd879350..ffea14ad4 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;