diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx index e24ec2904..10ecdcbc4 100644 --- a/resources/profiles/PrusaResearch.idx +++ b/resources/profiles/PrusaResearch.idx @@ -1,4 +1,5 @@ min_slic3r_version = 2.6.0-beta0 +1.9.0-beta1 Updated cooling settings for some ASA filaments to increase interlayer adhesion (XL/MK4). 1.9.0-beta0 Updated start g-code script for MK4/XL. min_slic3r_version = 2.6.0-alpha5 1.9.0-alpha4 Updated XL and MK4 profiles. Updated PC Blend Carbon Fiber density. @@ -14,12 +15,14 @@ min_slic3r_version = 2.6.0-alpha1 1.6.0-alpha1 Updated FW version notification. Decreased min layer time for PLA. 1.6.0-alpha0 Default top fill set to monotonic lines. Updated infill/perimeter overlap values. Updated output filename format. Enabled dynamic overhang speeds. min_slic3r_version = 2.5.2-rc0 +1.7.5 Updated cooling settings for some ASA filaments to increase interlayer adhesion (XL/MK4). Updated LA values (XL/MK4). 1.7.4 Updated start g-code script for MK4/XL (fixed pre-print temperature for PA filaments). 1.7.3 Updated XL and MK4 profiles. Updated PC Blend Carbon Fiber density. 1.7.2 Updated compatibility condition for MMU1 filaments. 1.7.1 Added SLA materials. Updated MK4 and XL profiles. 1.7.0 Added profiles for Original Prusa MK4. min_slic3r_version = 2.5.1-rc0 +1.6.6 Updated cooling settings for some ASA filaments to increase interlayer adhesion (XL/MK4). 1.6.5 Updated start g-code script for MK4/XL (fixed pre-print temperature for PA filaments). 1.6.4 Fixed compatibility condition for MMU1 filaments. 1.6.3 Added SLA materials. diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 442f7bdeb..268171a1a 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -5,7 +5,7 @@ name = Prusa Research # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the PrusaSlicer configuration to be downgraded. -config_version = 1.9.0-beta0 +config_version = 1.9.0-beta1 # Where to get the updates from? config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/ changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1% @@ -3618,7 +3618,7 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no compatible_printers_condition = ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) and printer_notes!~/.*PG.*/ [filament:*PLAPG*] -start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.06{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.08{elsif nozzle_diameter[0]==0.35}0.07{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S36 ; set heatbreak target temp" +start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.05{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.07{elsif nozzle_diameter[0]==0.35}0.06{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.015{else}0{endif} ; Filament gcode\n\nM142 S36 ; set heatbreak target temp" compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.8 and nozzle_diameter[0]!=0.6 slowdown_below_layer_time = 8 filament_cooling_final_speed = 2 @@ -3675,7 +3675,7 @@ filament_max_volumetric_speed = 15 [filament:*PETPG*] compatible_printers_condition = printer_notes=~/.*PG.*/ and nozzle_diameter[0]!=0.6 and nozzle_diameter[0]!=0.8 filament_max_volumetric_speed = 10 -start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.08{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.1{elsif nozzle_diameter[0]==0.35}0.09{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S40 ; set heatbreak target temp" +start_filament_gcode = "M900 K{if nozzle_diameter[0]==0.4}0.07{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.09{elsif nozzle_diameter[0]==0.35}0.08{elsif nozzle_diameter[0]==0.6}0.04{elsif nozzle_diameter[0]==0.5}0.05{elsif nozzle_diameter[0]==0.8}0.02{else}0{endif} ; Filament gcode\n\nM142 S40 ; set heatbreak target temp" filament_cooling_final_speed = 1 filament_cooling_initial_speed = 2 filament_cooling_moves = 1 @@ -4498,6 +4498,8 @@ filament_type = ASA [filament:Fillamentum ASA @PG] inherits = Fillamentum ASA; *ABSPG* bed_temperature = 105 +min_fan_speed = 10 +max_fan_speed = 10 [filament:Fillamentum ASA @PG 0.6] inherits = Fillamentum ASA @PG; *ABS06PG* @@ -4507,6 +4509,8 @@ inherits = Fillamentum ASA @PG; *ABS08PG* [filament:Fillamentum ASA @MK4] inherits = Fillamentum ASA; *ABSMK4* +min_fan_speed = 10 +max_fan_speed = 10 [filament:Fillamentum ASA @MK4 0.6] inherits = Fillamentum ASA @MK4; *ABS06MK4* @@ -4541,6 +4545,8 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI inherits = Prusament ASA; *ABSPG* first_layer_bed_temperature = 100 bed_temperature = 105 +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament ASA @PG 0.6] inherits = Prusament ASA @PG; *ABS06PG* @@ -4552,6 +4558,8 @@ temperature = 265 [filament:Prusament ASA @MK4] inherits = Prusament ASA; *ABSMK4* +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament ASA @MK4 0.6] inherits = Prusament ASA @MK4; *ABS06MK4* @@ -4590,6 +4598,8 @@ start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and no [filament:Prusament PC Blend @PG] inherits = Prusament PC Blend; *PCPG* filament_max_volumetric_speed = 9 +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament PC Blend @PG 0.6] inherits = Prusament PC Blend @PG; *PC06PG* @@ -4602,6 +4612,8 @@ filament_max_volumetric_speed = 18 [filament:Prusament PC Blend @MK4] inherits = Prusament PC Blend; *PCMK4* filament_max_volumetric_speed = 9 +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament PC Blend @MK4 0.6] inherits = Prusament PC Blend @MK4; *PC06MK4* @@ -4634,24 +4646,28 @@ compatible_printers_condition = printer_notes!~/.*PRINTER_MODEL_MK(2|2.5).*/ and [filament:Prusament PC Blend Carbon Fiber @PG] inherits = Prusament PC Blend Carbon Fiber; *PCPG* +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament PC Blend Carbon Fiber @PG 0.6] -inherits = Prusament PC Blend Carbon Fiber; *PC06PG* +inherits = Prusament PC Blend Carbon Fiber @PG; *PC06PG* filament_max_volumetric_speed = 13 [filament:Prusament PC Blend Carbon Fiber @PG 0.8] -inherits = Prusament PC Blend Carbon Fiber; *PC08PG* +inherits = Prusament PC Blend Carbon Fiber @PG; *PC08PG* filament_max_volumetric_speed = 18 [filament:Prusament PC Blend Carbon Fiber @MK4] inherits = Prusament PC Blend Carbon Fiber; *PCMK4* +min_fan_speed = 10 +max_fan_speed = 10 [filament:Prusament PC Blend Carbon Fiber @MK4 0.6] -inherits = Prusament PC Blend Carbon Fiber; *PC06MK4* +inherits = Prusament PC Blend Carbon Fiber @MK4; *PC06MK4* filament_max_volumetric_speed = 13 [filament:Prusament PC Blend Carbon Fiber @MK4 0.8] -inherits = Prusament PC Blend Carbon Fiber; *PC08MK4* +inherits = Prusament PC Blend Carbon Fiber @MK4; *PC08MK4* filament_max_volumetric_speed = 18 [filament:Prusament PC Blend Carbon Fiber @MK2] @@ -7290,6 +7306,8 @@ inherits = Ultrafuse ASA; *ABSPG* first_layer_bed_temperature = 105 bed_temperature = 105 filament_max_volumetric_speed = 5 +min_fan_speed = 15 +max_fan_speed = 40 [filament:Ultrafuse ASA @PG 0.6] inherits = Ultrafuse ASA @PG; *ABS06PG* @@ -7302,6 +7320,8 @@ filament_max_volumetric_speed = 12 [filament:Ultrafuse ASA @MK4] inherits = Ultrafuse ASA; *ABSMK4* filament_max_volumetric_speed = 5 +min_fan_speed = 15 +max_fan_speed = 40 [filament:Ultrafuse ASA @MK4 0.6] inherits = Ultrafuse ASA @MK4; *ABS06MK4* diff --git a/resources/profiles/Templates.idx b/resources/profiles/Templates.idx index 297aeb1fe..728a7da35 100644 --- a/resources/profiles/Templates.idx +++ b/resources/profiles/Templates.idx @@ -1,3 +1,4 @@ min_slic3r_version = 2.6.0-alpha0 +1.0.2 Updated compatible printer conditions. 1.0.1 Added Prusament PETG Carbon Fiber, Fiberthree F3 PA-GF30 Pro. 1.0.0 Initial diff --git a/resources/profiles/Templates.ini b/resources/profiles/Templates.ini index cf7b8ebe8..d038d572d 100644 --- a/resources/profiles/Templates.ini +++ b/resources/profiles/Templates.ini @@ -2,7 +2,7 @@ [vendor] name = Templates -config_version = 1.0.1 +config_version = 1.0.2 config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Templates/ templates_profile = 1 @@ -11,12 +11,12 @@ templates_profile = 1 [filament:*common*] cooling = 1 compatible_printers = -compatible_printers_condition = +compatible_printers_condition = printer_notes!~/.*PRINTER_VENDOR_TRILAB.*/ and printer_notes!~/.*PRINTER_MODEL_MK4IS.*/ end_filament_gcode = "; Filament-specific end gcode" extrusion_multiplier = 1 filament_loading_speed = 14 filament_loading_speed_start = 19 -filament_unloading_speed = 90 +filament_unloading_speed = 20 filament_unloading_speed_start = 100 filament_toolchange_delay = 0 filament_cooling_moves = 1 @@ -1460,7 +1460,6 @@ cooling = 0 fan_always_on = 0 filament_max_volumetric_speed = 4 filament_type = METAL -compatible_printers_condition = nozzle_diameter[0]>=0.4 filament_colour = #FFFFFF [filament:Polymaker PC-Max] @@ -1519,7 +1518,6 @@ first_layer_temperature = 230 max_fan_speed = 20 min_fan_speed = 20 temperature = 230 -compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material) [filament:Prusa PETG] inherits = *PET* diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index 4ed00668c..874742ecb 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -1,9 +1,9 @@ #ifndef ARRANGE_HPP #define ARRANGE_HPP -#include "ExPolygon.hpp" - #include + +#include #include namespace Slic3r { diff --git a/src/libslic3r/Fill/FillEnsuring.cpp b/src/libslic3r/Fill/FillEnsuring.cpp index a64c0fd83..4838ad8d2 100644 --- a/src/libslic3r/Fill/FillEnsuring.cpp +++ b/src/libslic3r/Fill/FillEnsuring.cpp @@ -71,9 +71,11 @@ ThickPolylines make_fill_polylines( vertical_lines[i].a = Point{x, y_min}; vertical_lines[i].b = Point{x, y_max}; } - vertical_lines.push_back(vertical_lines.back()); - vertical_lines.back().a = Point{coord_t(bb.min.x() + n_vlines * double(scaled_spacing) + scaled_spacing * 0.5), y_min}; - vertical_lines.back().b = Point{vertical_lines.back().a.x(), y_max}; + if (vertical_lines.size() > 0) { + vertical_lines.push_back(vertical_lines.back()); + vertical_lines.back().a = Point{coord_t(bb.min.x() + n_vlines * double(scaled_spacing) + scaled_spacing * 0.5), y_min}; + vertical_lines.back().b = Point{vertical_lines.back().a.x(), y_max}; + } std::vector> polygon_sections(n_vlines); @@ -276,7 +278,7 @@ ThickPolylines make_fill_polylines( } } - reconstructed_area = closing(reconstructed_area, float(SCALED_EPSILON), float(SCALED_EPSILON)); + reconstructed_area = union_safety_offset(reconstructed_area); ExPolygons gaps_for_additional_filling = diff_ex(filled_area, reconstructed_area); if (fill->overlap != 0) { gaps_for_additional_filling = offset_ex(gaps_for_additional_filling, scaled(fill->overlap)); diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp index 348825106..786f4093c 100644 --- a/src/libslic3r/PlaceholderParser.cpp +++ b/src/libslic3r/PlaceholderParser.cpp @@ -882,14 +882,20 @@ namespace client } } if (opt == nullptr) - ctx->throw_exception("Variable does not exist", IteratorRange(opt_key.begin(), opt_key.end())); - if (opt->is_scalar()) + ctx->throw_exception("Variable does not exist", opt_key); + if (opt->is_scalar()) { + if (opt->is_nil()) + ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt_key); output = opt->serialize(); - else { + } else { const ConfigOptionVectorBase *vec = static_cast(opt); if (vec->empty()) ctx->throw_exception("Indexing an empty vector variable", opt_key); - output = vec->vserialize()[(idx >= vec->size()) ? 0 : idx]; + if (idx >= vec->size()) + idx = 0; + if (vec->is_nil(idx)) + ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key); + output = vec->vserialize()[idx]; } } @@ -917,7 +923,7 @@ namespace client ctx->throw_exception("Trying to index a scalar variable", opt_key); const ConfigOptionVectorBase *vec = static_cast(opt); if (vec->empty()) - ctx->throw_exception("Indexing an empty vector variable", IteratorRange(opt_key.begin(), opt_key.end())); + ctx->throw_exception("Indexing an empty vector variable", opt_key); const ConfigOption *opt_index = ctx->resolve_symbol(std::string(opt_vector_index.begin(), opt_vector_index.end())); if (opt_index == nullptr) ctx->throw_exception("Variable does not exist", opt_key); @@ -926,7 +932,11 @@ namespace client int idx = opt_index->getInt(); if (idx < 0) ctx->throw_exception("Negative vector index", opt_key); - output = vec->vserialize()[(idx >= (int)vec->size()) ? 0 : idx]; + if (idx >= (int)vec->size()) + idx = 0; + if (vec->is_nil(idx)) + ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt_key); + output = vec->vserialize()[idx]; } static void resolve_variable( @@ -976,6 +986,9 @@ namespace client assert(opt.opt->is_scalar()); + if (opt.opt->is_nil()) + ctx->throw_exception("Trying to reference an undefined (nil) optional variable", opt.it_range); + switch (opt.opt->type()) { case coFloat: output.set_d(opt.opt->getFloat()); break; case coInt: output.set_i(opt.opt->getInt()); break; @@ -1041,6 +1054,8 @@ namespace client if (vec->empty()) ctx->throw_exception("Indexing an empty vector variable", opt.it_range); size_t idx = (opt.index < 0) ? 0 : (opt.index >= int(vec->size())) ? 0 : size_t(opt.index); + if (vec->is_nil(idx)) + ctx->throw_exception("Trying to reference an undefined (nil) element of vector of optional values", opt.it_range); switch (opt.opt->type()) { case coFloats: output.set_d(static_cast(opt.opt)->values[idx]); break; case coInts: output.set_i(static_cast(opt.opt)->values[idx]); break; @@ -1434,6 +1449,8 @@ namespace client assert(lhs.opt->is_vector()); if (rhs.has_index() || ! rhs.opt->is_vector()) ctx->throw_exception("Cannot assign scalar to a vector", lhs.it_range); + if (rhs.opt->is_nil()) + ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range); if (lhs.opt->type() != rhs.opt->type()) { // Vector types are not compatible. switch (lhs.opt->type()) { @@ -1470,6 +1487,8 @@ namespace client if (rhs.has_index() || ! rhs.opt->is_vector()) // Stop parsing, let the other rules resolve this case. return false; + if (rhs.opt->is_nil()) + ctx->throw_exception("Some elements of the right hand side vector variable of optional values are undefined (nil)", rhs.it_range); // Clone the vector variable. std::unique_ptr opt_new; if (one_of(rhs.opt->type(), { coFloats, coInts, coStrings, coBools })) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 5d3028c8f..c6d21015b 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2186,6 +2186,7 @@ void PrintObject::bridge_over_infill() Polygon &new_poly = expanded_bridged_area.emplace_back(std::move(traced_poly.lows)); new_poly.points.insert(new_poly.points.end(), traced_poly.highs.rbegin(), traced_poly.highs.rend()); } + expanded_bridged_area = union_safety_offset(expanded_bridged_area); } polygons_rotate(expanded_bridged_area, -aligning_angle); diff --git a/src/libslic3r/Support/TreeModelVolumes.cpp b/src/libslic3r/Support/TreeModelVolumes.cpp index 5df56cd62..b726dfa27 100644 --- a/src/libslic3r/Support/TreeModelVolumes.cpp +++ b/src/libslic3r/Support/TreeModelVolumes.cpp @@ -497,7 +497,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex const bool calculate_placable = m_support_rests_on_model && radius == 0; LayerPolygonCache data_placeable; if (calculate_placable) - data_placeable.allocate(data.idx_begin, data.idx_end); + data_placeable.allocate(data.begin(), data.end()); for (size_t outline_idx : layer_outline_indices) if (const std::vector &outlines = m_layer_outlines[outline_idx].second; ! outlines.empty()) { @@ -517,9 +517,9 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex // 1) Calculate offsets of collision areas in parallel. LayerPolygonCache collision_areas_offsetted; collision_areas_offsetted.allocate( - std::max(0, data.idx_begin - z_distance_bottom_layers), - std::min(outlines.size(), data.idx_end + z_distance_top_layers)); - tbb::parallel_for(tbb::blocked_range(collision_areas_offsetted.idx_begin, collision_areas_offsetted.idx_end), + std::max(0, data.begin() - z_distance_bottom_layers), + std::min(outlines.size(), data.end() + z_distance_top_layers)); + tbb::parallel_for(tbb::blocked_range(collision_areas_offsetted.begin(), collision_areas_offsetted.end()), [&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, &collision_areas_offsetted, &throw_on_cancel] (const tbb::blocked_range &range) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) { @@ -536,7 +536,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex // 2) Sum over top / bottom ranges. const bool processing_last_mesh = outline_idx == layer_outline_indices.size(); - tbb::parallel_for(tbb::blocked_range(data.idx_begin, data.idx_end), + tbb::parallel_for(tbb::blocked_range(data.begin(), data.end()), [&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, radius, xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, processing_last_mesh, &throw_on_cancel] (const tbb::blocked_range& range) { @@ -600,7 +600,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex // 3) Optionally calculate placables. if (calculate_placable) { // Now calculate the placable areas. - tbb::parallel_for(tbb::blocked_range(std::max(z_distance_bottom_layers + 1, data.idx_begin), data.idx_end), + tbb::parallel_for(tbb::blocked_range(std::max(z_distance_bottom_layers + 1, data.begin()), data.end()), [&collision_areas_offsetted, &outlines, &anti_overhang = m_anti_overhang, processing_last_mesh, min_resolution = m_min_resolution, z_distance_bottom_layers, xy_distance, &data_placeable, &throw_on_cancel] (const tbb::blocked_range& range) { diff --git a/src/libslic3r/Support/TreeModelVolumes.hpp b/src/libslic3r/Support/TreeModelVolumes.hpp index ecfa99971..1e4386468 100644 --- a/src/libslic3r/Support/TreeModelVolumes.hpp +++ b/src/libslic3r/Support/TreeModelVolumes.hpp @@ -332,23 +332,26 @@ public: private: // Caching polygons for a range of layers. - struct LayerPolygonCache { - std::vector polygons; - LayerIndex idx_begin; - LayerIndex idx_end; - + class LayerPolygonCache { + public: void allocate(LayerIndex aidx_begin, LayerIndex aidx_end) { - this->idx_begin = aidx_begin; - this->idx_end = aidx_end; - this->polygons.assign(aidx_end - aidx_begin, {}); + m_idx_begin = aidx_begin; + m_idx_end = aidx_end; + m_polygons.assign(aidx_end - aidx_begin, {}); } - LayerIndex begin() const { return idx_begin; } - LayerIndex end() const { return idx_end; } - size_t size() const { return polygons.size(); } + LayerIndex begin() const { return m_idx_begin; } + LayerIndex end() const { return m_idx_end; } + size_t size() const { return m_polygons.size(); } - bool has(LayerIndex idx) const { return idx >= idx_begin && idx < idx_end; } - Polygons& operator[](LayerIndex idx) { return polygons[idx + idx_begin]; } + bool has(LayerIndex idx) const { return idx >= m_idx_begin && idx < m_idx_end; } + Polygons& operator[](LayerIndex idx) { assert(idx >= m_idx_begin && idx < m_idx_end); return m_polygons[idx - m_idx_begin]; } + std::vector& polygons_mutable() { return m_polygons; } + + private: + std::vector m_polygons; + LayerIndex m_idx_begin; + LayerIndex m_idx_end; }; /*! @@ -388,9 +391,9 @@ private: } void insert(LayerPolygonCache &&in, coord_t radius) { std::lock_guard guard(m_mutex); - LayerIndex i = in.idx_begin; + LayerIndex i = in.begin(); allocate_layers(i + LayerIndex(in.size())); - for (auto &d : in.polygons) + for (auto &d : in.polygons_mutable()) m_data[i ++].emplace(radius, std::move(d)); } /*! diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 5a2e6d8ec..72d1bda03 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -4649,6 +4649,7 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume // ### Precalculate avoidances, collision etc. size_t num_support_layers = precalculate(print, overhangs, processing.first, processing.second, volumes, throw_on_cancel); bool has_support = num_support_layers > 0; + bool has_raft = config.raft_layers.size() > 0; num_support_layers = std::max(num_support_layers, config.raft_layers.size()); SupportParameters support_params(print_object); @@ -4661,13 +4662,13 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume SupportGeneratorLayersPtr interface_layers; SupportGeneratorLayersPtr base_interface_layers; SupportGeneratorLayersPtr intermediate_layers(num_support_layers, nullptr); - if (support_params.has_top_contacts) + if (support_params.has_top_contacts || has_raft) top_contacts.assign(num_support_layers, nullptr); if (support_params.has_bottom_contacts) bottom_contacts.assign(num_support_layers, nullptr); - if (support_params.has_interfaces()) + if (support_params.has_interfaces() || has_raft) interface_layers.assign(num_support_layers, nullptr); - if (support_params.has_base_interfaces()) + if (support_params.has_base_interfaces() || has_raft) base_interface_layers.assign(num_support_layers, nullptr); InterfacePlacer interface_placer{ diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index d0b772197..60e7b00cc 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -159,7 +159,7 @@ BundleMap BundleMap::load() idx_path = fs::path(cache_dir / (id + ".idx")); } if (!boost::filesystem::exists(idx_path)) { - BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to missing index %1%.", id, idx_path.string()); + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to missing index %2%.", id, idx_path.string()); continue; } Slic3r::GUI::Config::Index index; @@ -167,7 +167,7 @@ BundleMap BundleMap::load() index.load(idx_path); } catch (const std::exception& /* err */) { - BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to invalid index %1%.", id, idx_path.string()); + BOOST_LOG_TRIVIAL(error) << format("Could not load bundle %1% due to invalid index %2%.", id, idx_path.string()); continue; } const auto recommended_it = index.recommended(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a5584692c..88e8f8691 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1192,6 +1192,13 @@ void ObjectList::key_event(wxKeyEvent& event) void ObjectList::OnBeginDrag(wxDataViewEvent &event) { + if (m_is_editing_started) + m_is_editing_started = false; +#ifdef __WXGTK__ + const auto renderer = dynamic_cast(GetColumn(colName)->GetRenderer()); + renderer->FinishEditing(); +#endif + const wxDataViewItem item(event.GetItem()); const bool mult_sel = multiple_selection(); @@ -1225,18 +1232,11 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event) m_objects_model->GetInstanceIdByItem(item), type); - /* Under MSW or OSX, DnD moves an item to the place of another selected item - * But under GTK, DnD moves an item between another two items. - * And as a result - call EVT_CHANGE_SELECTION to unselect all items. - * To prevent such behavior use m_prevent_list_events - **/ - m_prevent_list_events = true;//it's needed for GTK - /* Under GTK, DnD requires to the wxTextDataObject been initialized with some valid value, * so set some nonempty string */ wxTextDataObject* obj = new wxTextDataObject; - obj->SetText("Some text");//it's needed for GTK + obj->SetText(mult_sel ? "SomeText" : m_objects_model->GetItemName(item));//it's needed for GTK event.SetDataObject(obj); event.SetDragFlags(wxDrag_DefaultMove); // allows both copy and move; @@ -1300,10 +1300,8 @@ void ObjectList::OnDropPossible(wxDataViewEvent &event) { const wxDataViewItem& item = event.GetItem(); - if (!can_drop(item)) { + if (!can_drop(item)) event.Veto(); - m_prevent_list_events = false; - } } void ObjectList::OnDrop(wxDataViewEvent &event) @@ -1317,6 +1315,13 @@ void ObjectList::OnDrop(wxDataViewEvent &event) return; } + /* Under MSW or OSX, DnD moves an item to the place of another selected item + * But under GTK, DnD moves an item between another two items. + * And as a result - call EVT_CHANGE_SELECTION to unselect all items. + * To prevent such behavior use m_prevent_list_events + **/ + m_prevent_list_events = true;//it's needed for GTK + if (m_dragged_data.type() == itInstance) { Plater::TakeSnapshot snapshot(wxGetApp().plater(),_(L("Instances to Separated Objects"))); @@ -4841,6 +4846,9 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event) void ObjectList::OnEditingDone(wxDataViewEvent &event) { + if (!m_is_editing_started) + return; + m_is_editing_started = false; if (event.GetColumn() != colName) return; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 557cdee8e..7c1a816b9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -17,6 +17,7 @@ #include +#include namespace Slic3r::GUI { @@ -521,6 +522,13 @@ void GLGizmoFdmSupports::auto_generate() } ModelObject *mo = m_c->selection_info()->model_object(); + bool printable = std::any_of(mo->instances.begin(), mo->instances.end(), [](const ModelInstance *p) { return p->is_printable(); }); + if (!printable) { + MessageDialog dlg(GUI::wxGetApp().plater(), _L("Automatic painting requires printable object."), _L("Warning"), wxOK); + dlg.ShowModal(); + return; + } + bool not_painted = std::all_of(mo->volumes.begin(), mo->volumes.end(), [](const ModelVolume* vol){ return vol->type() != ModelVolumeType::MODEL_PART || vol->supported_facets.empty(); }); diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index a422d4407..6ff25923e 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -86,7 +86,7 @@ arrangement::ArrangePolygon get_arrange_poly(T obj, const Plater *plater) using ArrangePolygon = arrangement::ArrangePolygon; ArrangePolygon ap = obj.get_arrange_polygon(); - ap.bed_idx = ap.translation.x() / bed_stride(plater); + ap.bed_idx = get_extents(ap.transformed_poly()).min.x() / bed_stride(plater); ap.setter = [obj, plater](const ArrangePolygon &p) { if (p.is_arranged()) { Vec2d t = p.translation.cast(); diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp index fe57d7d5a..e267ff1e0 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.cpp +++ b/src/slic3r/GUI/ObjectDataViewModel.cpp @@ -1042,6 +1042,16 @@ int ObjectDataViewModel::GetItemIdByLayerRange(const int obj_idx, const t_layer return GetLayerIdByItem(item); } +wxString ObjectDataViewModel::GetItemName(const wxDataViewItem& item) const +{ + if (!item.IsOk()) + return wxEmptyString; + ObjectDataViewModelNode* node = static_cast(item.GetID()); + if (!node) + return wxEmptyString; + return node->GetName(); +} + int ObjectDataViewModel::GetIdByItem(const wxDataViewItem& item) const { if(!item.IsOk()) diff --git a/src/slic3r/GUI/ObjectDataViewModel.hpp b/src/slic3r/GUI/ObjectDataViewModel.hpp index 993b67842..861db3234 100644 --- a/src/slic3r/GUI/ObjectDataViewModel.hpp +++ b/src/slic3r/GUI/ObjectDataViewModel.hpp @@ -311,6 +311,7 @@ public: wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx); wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); + wxString GetItemName(const wxDataViewItem& item) const; int GetIdByItem(const wxDataViewItem& item) const; int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; int GetObjectIdByItem(const wxDataViewItem& item) const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 149c2e1db..0647737b4 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1411,27 +1411,25 @@ void Sidebar::update_sliced_info_sizer() new_label = _L("Used Filament (g)"); info_text = wxString::Format("%.2f", ps.total_weight); - const auto& extruders_filaments = wxGetApp().preset_bundle->extruders_filaments; - const PresetCollection& filaments = wxGetApp().preset_bundle->filaments; - if (ps.filament_stats.size() > 1) new_label += ":"; - for (auto filament : ps.filament_stats) { - const Preset* filament_preset = filaments.find_preset(extruders_filaments[filament.first].get_selected_preset_name(), false); - if (filament_preset) { + const auto& extruders_filaments = wxGetApp().preset_bundle->extruders_filaments; + for (const auto& [filament_id, filament_vol] : ps.filament_stats) { + assert(filament_id < extruders_filaments.size()); + if (const Preset* preset = extruders_filaments[filament_id].get_selected_preset()) { double filament_weight; if (ps.filament_stats.size() == 1) filament_weight = ps.total_weight; else { - double filament_density = filament_preset->config.opt_float("filament_density", 0); - filament_weight = filament.second * filament_density/* *2.4052f*/ * 0.001; // assumes 1.75mm filament diameter; + double filament_density = preset->config.opt_float("filament_density", 0); + filament_weight = filament_vol * filament_density/* *2.4052f*/ * 0.001; // assumes 1.75mm filament diameter; - new_label += "\n - " + format_wxstr(_L("Filament at extruder %1%"), filament.first + 1); + new_label += "\n - " + format_wxstr(_L("Filament at extruder %1%"), filament_id + 1); info_text += wxString::Format("\n%.2f", filament_weight); } - double spool_weight = filament_preset->config.opt_float("filament_spool_weight", 0); + double spool_weight = preset->config.opt_float("filament_spool_weight", 0); if (spool_weight != 0.0) { new_label += "\n " + _L("(including spool)"); info_text += wxString::Format(" (%.2f)\n", filament_weight + spool_weight); diff --git a/version.inc b/version.inc index 0eecbcdc6..f0615cbde 100644 --- a/version.inc +++ b/version.inc @@ -3,7 +3,7 @@ set(SLIC3R_APP_NAME "PrusaSlicer") set(SLIC3R_APP_KEY "PrusaSlicer") -set(SLIC3R_VERSION "2.6.0-beta1") +set(SLIC3R_VERSION "2.6.0-beta2") set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN") set(SLIC3R_RC_VERSION "2,6,0,0") set(SLIC3R_RC_VERSION_DOTS "2.6.0.0")