diff --git a/resources/data/printer_gantries/geometries.txt b/resources/data/printer_gantries/geometries.json similarity index 83% rename from resources/data/printer_gantries/geometries.txt rename to resources/data/printer_gantries/geometries.json index dabf55f65b..1d8a7b24bb 100644 --- a/resources/data/printer_gantries/geometries.txt +++ b/resources/data/printer_gantries/geometries.json @@ -281,6 +281,62 @@ ] } ] + }, + { + "printer_notes_regex": ".*PRINTER_MODEL_HT90.*", + "gantry_model_filename": "prusa3d_ht90_actuator.stl", + "slices": [ + { + "height": "0", + "type": "convex", + "polygons": [ + "-5,-5; 5,-5; 5,5; -5,5" + ] + }, + { + "height": "1", + "type": "convex", + "polygons": [ + "-33,-2; 33,-2; 33,48; -33,48", + "-46,-37; 46,-37; 46,2; -46,2" + ] + }, + { + "height": "20", + "type": "convex", + "polygons": [ + "-55,-55; 55,-55; 55,55; -55,55" + ] + }, + { + "height": "28", + "type": "convex", + "polygons": [ + "-76,-68; 76,-68; 76,65; -76,65" + ] + }, + { + "height": "40", + "type": "convex", + "polygons": [ + "-120,-118; 120,-118; 120,94; -120,94" + ] + }, + { + "height": "60", + "type": "box", + "polygons": [ + "-170,-164; 170,-164; 170,130; -170,130" + ] + }, + { + "height": "80", + "type": "box", + "polygons": [ + "-400,-400; 400,-400; 400,400; -400,400" + ] + } + ] } ] } diff --git a/resources/data/printer_gantries/prusa3d_ht90_actuator.stl b/resources/data/printer_gantries/prusa3d_ht90_actuator.stl new file mode 100644 index 0000000000..05b7fb75e2 Binary files /dev/null and b/resources/data/printer_gantries/prusa3d_ht90_actuator.stl differ diff --git a/src/libseqarrange/include/libseqarrange/seq_interface.hpp b/src/libseqarrange/include/libseqarrange/seq_interface.hpp index cfca3f6d28..261ea310b1 100644 --- a/src/libseqarrange/include/libseqarrange/seq_interface.hpp +++ b/src/libseqarrange/include/libseqarrange/seq_interface.hpp @@ -28,7 +28,6 @@ using namespace Slic3r; namespace Sequential { class ObjectTooLargeException : public std::runtime_error { public: explicit ObjectTooLargeException(const std::string& msg) : std::runtime_error(msg) {}}; - class InternalErrorException : public std::runtime_error { public: explicit InternalErrorException(const std::string& msg) : std::runtime_error(msg) {} }; diff --git a/src/libseqarrange/src/seq_interface.cpp b/src/libseqarrange/src/seq_interface.cpp index 89165ca9f4..74cde29e91 100644 --- a/src/libseqarrange/src/seq_interface.cpp +++ b/src/libseqarrange/src/seq_interface.cpp @@ -86,6 +86,7 @@ bool PrinterGeometry::convert_Geometry2PlateBounds(Slic3r::BoundingBox &plate_bo plate_bounding_polygon.points.insert(plate_bounding_polygon.points.begin() + i, Point(plate.points[i].x() / SEQ_SLICER_SCALE_FACTOR, plate.points[i].y() / SEQ_SLICER_SCALE_FACTOR)); } + plate_bounding_polygon.make_counter_clockwise(); return false; } else diff --git a/src/libseqarrange/src/seq_preprocess.cpp b/src/libseqarrange/src/seq_preprocess.cpp index aa3a846f06..8c697c8562 100644 --- a/src/libseqarrange/src/seq_preprocess.cpp +++ b/src/libseqarrange/src/seq_preprocess.cpp @@ -742,7 +742,7 @@ void prepare_ExtruderPolygons(const SolverConfiguration &solver } else { - throw InternalErrorException("MISMATCH BETWEEN OBJECT AND PRINTER SLICE HEIGHTS."); + throw std::runtime_error("MISMATCH BETWEEN OBJECT AND PRINTER SLICE HEIGHTS."); } } } diff --git a/src/libseqarrange/src/seq_sequential.cpp b/src/libseqarrange/src/seq_sequential.cpp index 5826d857c8..8aa4065ede 100644 --- a/src/libseqarrange/src/seq_sequential.cpp +++ b/src/libseqarrange/src/seq_sequential.cpp @@ -148,6 +148,19 @@ void assume_BedBoundingPolygon(z3::context &Context, { BoundingBox box = get_extents(polygon); + #ifdef DEBUG + { + printf("Polygon box: [%d,%d] [%d,%d]\n", box.min.x(), box.min.y(), box.max.x(), box.max.y()); + + printf("Bed bounding polygon: %ld\n", bed_bounding_polygon.points.size()); + for (unsigned int i = 0; i < bed_bounding_polygon.points.size(); ++i) + { + printf("[%d,%d] ", bed_bounding_polygon.points[i].x(), bed_bounding_polygon.points[i].y()); + } + printf("\n"); + } + #endif + assume_PointInsidePolygon(Context, dec_var_X + box.min.x(), dec_var_Y + box.min.y(), @@ -470,7 +483,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver #endif for (unsigned int j = 1; j < undecided.size(); ++j) { - Solver.add(dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]); + //Solver.add(dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]); + Solver.add(dec_vars_T[undecided[j]] < 0 || dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]); } } else if (is_fixed(0, fixed)) @@ -481,8 +495,9 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver } #endif for (unsigned int j = 0; j < undecided.size(); ++j) - { - Solver.add(Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]); + { + //Solver.add(Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]); + Solver.add(dec_vars_T[undecided[j]] < 0 || Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]); } } else @@ -506,7 +521,8 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver printf("Undecided --> Undecided: %d --> %d standard\n", undecided[i], next_i); } #endif - Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); + //Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); + Solver.add((dec_vars_T[undecided[i]] < 0 || dec_vars_T[next_i] < 0) || dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); } /* Undecided --> missing */ else @@ -520,12 +536,14 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver { if (i != j) { - Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]); + //Solver.add(dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]); + Solver.add(dec_vars_T[undecided[j]] < 0 || dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]); } } for (unsigned int j = 0; j < fixed.size(); ++j) { - Solver.add(Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]); + //Solver.add(Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]); + Solver.add(dec_vars_T[undecided[i]] < 0 || Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]); } } } @@ -544,8 +562,12 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver printf("Fixed --> Undecided: %d --> %d standard\n", fixed[i], next_i); } #endif + /* Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i] && Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); + */ + Solver.add(dec_vars_T[next_i] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i] + && Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i])); } /* Fixed --> Fixed */ else if (is_fixed(next_i, fixed)) @@ -557,8 +579,12 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver #endif for (unsigned int j = 0; j < undecided.size(); ++j) { + /* Solver.add( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread || Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) + temporal_spread < dec_vars_T[undecided[j]]); + */ + Solver.add(dec_vars_T[undecided[j]] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread + || Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) + temporal_spread < dec_vars_T[undecided[j]])); } } } @@ -1431,7 +1457,7 @@ void assume_PointInsidePolygon(z3::context &Context, z3::expr inside_half_plane( (normal.x() * dec_var_X) + (normal.y() * dec_var_Y) - (normal.x() * line.a.x()) - - (normal.y() * line.a.y()) < 0); + - (normal.y() * line.a.y()) < 0); if (point == polygon.points.begin()) { @@ -1442,7 +1468,6 @@ void assume_PointInsidePolygon(z3::context &Context, in_conjunction = in_conjunction && inside_half_plane; } } - constraints.push_back(in_conjunction); } } @@ -9488,8 +9513,6 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver bool size_solvable = false; - z3::expr_vector bounding_box_assumptions(Context); - coord_t box_min_x = (_outer_half_box.min.x() + _inner_half_box.min.x()) / 2; coord_t box_max_x = (_outer_half_box.max.x() + _inner_half_box.max.x()) / 2; @@ -9770,6 +9793,8 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver std::vector local_dec_values_Y = dec_values_Y; std::vector local_dec_values_T = dec_values_T; + assert(inner_half_polygon.points.size() == solver_configuration.plate_bounding_polygon.points.size()); + Polygon _inner_half_polygon = inner_half_polygon; Polygon _outer_half_polygon = solver_configuration.plate_bounding_polygon; @@ -9839,7 +9864,6 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver bool size_solvable = false; - z3::expr_vector bounding_box_assumptions(Context); Polygon bounding_polygon; for (unsigned int i = 0; i < _outer_half_polygon.points.size(); ++i) @@ -9883,7 +9907,7 @@ bool optimize_ConsequentialWeakPolygonNonoverlappingBinaryCentered(z3::solver undecided, polygons, unreachable_polygons)) - { + { switch (Solver.check(complete_assumptions)) { case z3::sat: @@ -11102,7 +11126,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So BoundingBox inner_half_box({box_center_x, box_center_y}, {box_center_x, box_center_y}); for (unsigned int curr_polygon = 0; curr_polygon < polygons.size(); /* nothing */) - { + { bool optimized = false; z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); @@ -11311,7 +11335,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So if (!optimized) { if (curr_polygon <= 0) - { + { return false; } else @@ -11328,7 +11352,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So return true; } } - assert(remaining_polygons.empty()); } assert(remaining_polygons.empty()); @@ -11398,7 +11421,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So } for (unsigned int curr_polygon = 0; curr_polygon < solvable_objects.size(); /* nothing */) - { + { bool optimized = false; z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); @@ -11477,12 +11500,11 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So polygons, lepox_to_next, trans_bed_lepox); - std::vector missing; std::vector remaining_local; while(object_group_size > 0) - { + { z3::expr_vector presence_assumptions(z_context); assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, missing, presence_assumptions); @@ -11493,6 +11515,11 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So { printf(" %d\n", undecided[j]); } + printf("Missing\n"); + for (unsigned int j = 0; j < missing.size(); ++j) + { + printf(" %d\n", missing[j]); + } printf("Decided\n"); for (unsigned int j = 0; j < decided_polygons.size(); ++j) { @@ -11579,7 +11606,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So } if (optimized) - { + { for (unsigned int i = 0; i < undecided.size(); ++i) { dec_values_X[undecided[i]] = local_values_X[undecided[i]]; @@ -11650,7 +11677,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So return true; } } - assert(remaining_polygons.empty()); } assert(remaining_polygons.empty()); diff --git a/src/libslic3r/ArrangeHelper.cpp b/src/libslic3r/ArrangeHelper.cpp index b34c7924ca..ac22083dd6 100644 --- a/src/libslic3r/ArrangeHelper.cpp +++ b/src/libslic3r/ArrangeHelper.cpp @@ -71,7 +71,7 @@ static Sequential::PrinterGeometry get_printer_geometry(const ConfigBase& config { if (! printer_notes.empty()) { try { - boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.txt"); + boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.json"); boost::property_tree::ptree pt; boost::property_tree::read_json(in, pt); for (const auto& printer : pt.get_child("printers")) { diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 86796dff5f..3ddbca80c0 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -217,12 +217,13 @@ int GCodeViewer::SequentialView::ActualSpeedImguiWidget::plot(const char* label, } #endif // ENABLE_ACTUAL_SPEED_DEBUG -void GCodeViewer::SequentialView::Marker::init(std::optional>& model_opt) +void GCodeViewer::SequentialView::Marker::init(std::optional>& model_opt, bool is_ht90) { if (! model_opt.has_value()) return; m_model.reset(); + m_is_ht90 = is_ht90; m_generic_marker = (model_opt->get() == nullptr); if (m_generic_marker) @@ -233,6 +234,85 @@ void GCodeViewer::SequentialView::Marker::init(std::optional(0,0); + transform.translation() = p1; + return transform; +} + +static void render_ht90_rods(const Vec3d& pos, GLShaderProgram* shader, const Transform3d& view_matrix, const Vec3d& bed_offset, GLModel& model) +{ + Vec3d start(30.06, 27.70, 35); // Position of the back-right ball bearing, on the extruder head. + Vec3d end(32.33, 212.92, 338.8); // The other ball bearing, on the printer. + double r=4.725; // Diameter of the rod. + double rods_spacing = 60.; + double height = (end-start).norm(); + + + if (!model.is_initialized()) { + auto t0 = its_make_sphere(r, 0.5); + auto t1 = its_make_sphere(r, 0.5); + auto t2 = its_make_cylinder(r, height); + its_translate(t1, Vec3f(0., 0., height)); + its_merge(t2, t0); + its_merge(t2, t1); + model.init_from(t2); + model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f }); + } + + + // trans transforms extruder to world coord system of the first bed + Transform3d trans = Geometry::translation_transform(pos); + + Vec3d p1 = trans * start; + Vec3d p2 = end; // already in world coords + + for (int j=0; j<6; ++j) { + if (j == 3) { + p1.x() = p1.x() - rods_spacing; + p2.x() = p2.x() - rods_spacing; + } + + p1 = trans * Geometry::rotation_transform(Vec3d(0,0,2*M_PI/3)) * trans.inverse() * p1; + p2 = Geometry::rotation_transform(Vec3d(0,0,2*M_PI/3)) * p2; + + double dx = p2.x() - p1.x(); + double dy = p2.y() - p1.y(); + double dz = std::sqrt(height * height - dx * dx - dy * dy); + p2.z() = p1.z() + dz; + + Transform3d wm = align_cylinder(p1, p2, r); + shader->set_uniform("view_model_matrix", view_matrix * wm); + shader->set_uniform("volume_world_matrix", Geometry::translation_transform(bed_offset) * wm); + model.render(); + } + +} + + + + + + void GCodeViewer::SequentialView::Marker::render() { if (!m_visible) @@ -263,7 +343,7 @@ void GCodeViewer::SequentialView::Marker::render() BoundingBoxf box = s_multiple_beds.get_build_volume_box(); box.translate(to_2d(bed_inst_offset)); // add a bit on both sides - box = box.inflated(40.0f); + box = box.inflated(m_is_ht90 ? 60.f : 40.f); clip_planes = {{ { 1.0f, 0.0f, 0.0f, -box.min.cast().x() } , { -1.0f, 0.0f, 0.0f, box.max.cast().x() }}}; } @@ -287,8 +367,12 @@ void GCodeViewer::SequentialView::Marker::render() shader->set_uniform("clipping_planes[0]", clip_planes[0]); shader->set_uniform("clipping_planes[1]", clip_planes[1]); + shader->set_uniform("volume_world_matrix", volume_world_matrix); m_model.render(); + if (m_is_ht90 && ! m_generic_marker) + render_ht90_rods(m_world_position.cast(), shader, view_matrix, bed_inst_offset, m_model_ht90_rod); + shader->stop_using(); if (curr_cull_face) @@ -1204,8 +1288,8 @@ void GCodeViewer::render() m_sequential_view.marker.set_z_offset(m_z_offset); // Following just makes sure that the shown marker is correct. - auto marker_model_opt = wxGetApp().plater()->get_current_canvas3D()->get_current_marker_model(); - m_sequential_view.marker.init(marker_model_opt); + auto [marker_model_opt, is_ht90] = wxGetApp().plater()->get_current_canvas3D()->get_current_marker_model(); + m_sequential_view.marker.init(marker_model_opt, is_ht90); if (marker_model_opt.has_value()) m_max_bounding_box.reset(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index f37cd8c70d..26efe7a59e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -115,6 +115,7 @@ public: class Marker { GLModel m_model; + GLModel m_model_ht90_rod; Vec3f m_world_position; // For seams, the position of the marker is on the last endpoint of the toolpath containing it. // This offset is used to show the correct value of tool position in the "ToolPosition" window. @@ -128,14 +129,20 @@ public: bool m_fixed_screen_size{ false }; float m_scale_factor{ 1.0f }; bool m_generic_marker{ true }; + bool m_is_ht90{false}; #if ENABLE_ACTUAL_SPEED_DEBUG ActualSpeedImguiWidget m_actual_speed_imgui_widget; #endif // ENABLE_ACTUAL_SPEED_DEBUG public: - void init(std::optional>& model_opt); + void init(std::optional>& model_opt, bool is_ht90); - const BoundingBoxf3& get_bounding_box() const { return m_model.get_bounding_box(); } + BoundingBoxf3 get_bounding_box() const { + auto bb = m_model.get_bounding_box(); + if (m_is_ht90) + bb.max.z() += scale_(400); + return bb; + } void set_world_position(const Vec3f& position) { m_world_position = position; } void set_world_offset(const Vec3f& offset) { m_world_offset = offset; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9e91642cd0..3776e41f77 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -162,9 +162,10 @@ void GLCanvas3D::select_bed(int i, bool triggered_by_user) // - nullopt = same as before // - nullptr = none available, use generic // - GLModel = the model to use -std::optional> GLCanvas3D::get_current_marker_model() const +// The other field is whether the printer is HT90. +std::pair>, bool> GLCanvas3D::get_current_marker_model() const { - std::optional> out; + auto out = std::make_pair>, bool>(std::nullopt, false); static std::string last_printer_notes; static double old_r = 0.; @@ -182,11 +183,13 @@ std::optional> GLCanvas3D::get_current_marker_model() c old_h = h; old_seq = seq; - out = std::make_optional(nullptr); + out.second = (printer_notes.find("PRINTER_MODEL_HT90") != std::string::npos); + + out.first = std::make_optional(nullptr); if (! seq) return out; try { - boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.txt"); + boost::nowide::ifstream in(resources_dir() + "/data/printer_gantries/geometries.json"); boost::property_tree::ptree pt; boost::property_tree::read_json(in, pt); for (const auto& printer : pt.get_child("printers")) { @@ -197,7 +200,7 @@ std::optional> GLCanvas3D::get_current_marker_model() c if (boost::filesystem::exists(filename)) { std::unique_ptr m = std::make_unique(); if (m->init_from_file(filename)) - out = std::make_optional(std::move(m)); + out.first = std::make_optional(std::move(m)); } break; } @@ -205,7 +208,7 @@ std::optional> GLCanvas3D::get_current_marker_model() c } catch (...) { // Whatever happened, ignore it. We will return nullptr. } - if (*out == nullptr && seq) { + if (*(out.first) == nullptr && seq) { // Generic sequential extruder model. double gantry_height = 10; auto mesh = its_make_cylinder(r, h + gantry_height - 0.001); @@ -215,7 +218,7 @@ std::optional> GLCanvas3D::get_current_marker_model() c its_merge(mesh, mesh2); std::unique_ptr m = std::make_unique(); m->init_from(mesh); - out = std::make_optional(std::move(m)); + out.first = std::make_optional(std::move(m)); } } return out; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 0a75e241bb..dbaacc3666 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -729,7 +729,7 @@ public: const libvgcode::Interval& get_gcode_view_visible_range() const { return m_gcode_viewer.get_gcode_view_visible_range(); } const libvgcode::PathVertex& get_gcode_vertex_at(size_t id) const { return m_gcode_viewer.get_gcode_vertex_at(id); } - std::optional> get_current_marker_model() const; + std::pair>, bool> get_current_marker_model() const; void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1, const ModelVolume* mv = nullptr); diff --git a/src/slic3r/GUI/Jobs/SeqArrangeJob.cpp b/src/slic3r/GUI/Jobs/SeqArrangeJob.cpp index a9d15f0b5d..bdf9964665 100644 --- a/src/slic3r/GUI/Jobs/SeqArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/SeqArrangeJob.cpp @@ -33,8 +33,11 @@ void SeqArrangeJob::process(Ctl& ctl) } ); } catch (const SeqArrangeJobException&) { - // The task was canceled. Just make sure that the progress notification disappears. - ctl.update_status(100, ""); + ctl.update_status(100, ""); // Hide progress notification. + } + catch (const std::exception&) { + ctl.update_status(100, ""); // Hide progress notification. + throw; } } @@ -60,7 +63,7 @@ void SeqArrangeJob::finalize(bool canceled, std::exception_ptr& eptr) dlg.ShowModal(); error = true; eptr = nullptr; // The exception is handled. - } catch (const Sequential::InternalErrorException& ex) { + } catch (const std::runtime_error& ex) { ErrorDialog dlg(wxGetApp().plater(), GUI::format_wxstr(_L("Internal error: %1%"), ex.what()), false); dlg.ShowModal(); error = true;