Merge branch 'dev' of https://github.com/prusa3d/PrusaSlicer into et_reload_from_disk

This commit is contained in:
Enrico Turri 2019-09-11 09:01:44 +02:00
commit b383d9581a
25 changed files with 244 additions and 149 deletions

View file

@ -546,7 +546,12 @@ public:
inline explicit _NofitPolyPlacer(const BinType& bin): inline explicit _NofitPolyPlacer(const BinType& bin):
Base(bin), Base(bin),
norm_(std::sqrt(sl::area(bin))) {} norm_(std::sqrt(sl::area(bin)))
{
// In order to not have items out of bin, it will be shrinked by an
// very little empiric offset value.
// sl::offset(bin_, 1e-5 * norm_);
}
_NofitPolyPlacer(const _NofitPolyPlacer&) = default; _NofitPolyPlacer(const _NofitPolyPlacer&) = default;
_NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default; _NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default;
@ -1179,7 +1184,14 @@ private:
} }
void setInitialPosition(Item& item) { void setInitialPosition(Item& item) {
Box&& bb = item.boundingBox(); auto sh = item.rawShape();
sl::translate(sh, item.translation());
sl::rotate(sh, item.rotation());
Box bb = sl::boundingBox(sh);
bb.minCorner() += item.translation();
bb.maxCorner() += item.translation();
Vertex ci, cb; Vertex ci, cb;
auto bbin = sl::boundingBox(bin_); auto bbin = sl::boundingBox(bin_);

View file

@ -550,16 +550,7 @@ public:
return ret; return ret;
}; };
// Safety test: try to pack each item into an empty bin. If it fails this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
// then it should be removed from the not_packed list
{ auto it = store_.begin();
while (it != store_.end() && !this->stopcond_()) {
Placer p(bin); p.configure(pconfig);
if(!p.pack(*it, rem(it, store_))) {
it = store_.erase(it);
} else it++;
}
}
int acounter = int(store_.size()); int acounter = int(store_.size());
std::atomic_flag flg = ATOMIC_FLAG_INIT; std::atomic_flag flg = ATOMIC_FLAG_INIT;

View file

@ -30,6 +30,7 @@ public:
TBin&& bin, TBin&& bin,
PConfig&& pconfig = PConfig()) PConfig&& pconfig = PConfig())
{ {
using Placer = PlacementStrategyLike<TPlacer>;
store_.clear(); store_.clear();
auto total = last-first; auto total = last-first;
@ -58,9 +59,11 @@ public:
return i1.area() > i2.area(); return i1.area() > i2.area();
}; };
this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
std::sort(store_.begin(), store_.end(), sortfunc); std::sort(store_.begin(), store_.end(), sortfunc);
PlacementStrategyLike<TPlacer> placer(bin); Placer placer(bin);
placer.configure(pconfig); placer.configure(pconfig);
auto it = store_.begin(); auto it = store_.begin();

View file

@ -78,16 +78,7 @@ public:
auto& cancelled = this->stopcond_; auto& cancelled = this->stopcond_;
// Safety test: try to pack each item into an empty bin. If it fails this->template remove_unpackable_items<Placer>(store_, bin, pconfig);
// then it should be removed from the list
{ auto it = store_.begin();
while (it != store_.end() && !cancelled()) {
Placer p(bin); p.configure(pconfig);
if(!p.pack(*it)) {
it = store_.erase(it);
} else it++;
}
}
auto it = store_.begin(); auto it = store_.begin();

View file

@ -26,6 +26,22 @@ public:
protected: protected:
template<class Placer, class Container, class Bin, class PCfg>
void remove_unpackable_items(Container &c, const Bin &bin, const PCfg& pcfg)
{
// Safety test: try to pack each item into an empty bin. If it fails
// then it should be removed from the list
auto it = c.begin();
while (it != c.end() && !stopcond_()) {
Placer p{bin};
p.configure(pcfg);
const Item& itm = *it;
Item cpy{itm};
if (!p.pack(cpy)) it = c.erase(it);
else it++;
}
}
PackGroup packed_bins_; PackGroup packed_bins_;
ProgressFunction progress_ = [](unsigned){}; ProgressFunction progress_ = [](unsigned){};
StopCondition stopcond_ = [](){ return false; }; StopCondition stopcond_ = [](){ return false; };

View file

@ -350,6 +350,12 @@ public:
m_pck.configure(m_pconf); m_pck.configure(m_pconf);
} }
AutoArranger(const TBin & bin,
std::function<void(unsigned)> progressind,
std::function<bool(void)> stopcond)
: AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
{}
template<class It> inline void operator()(It from, It to) { template<class It> inline void operator()(It from, It to) {
m_rtree.clear(); m_rtree.clear();
m_item_count += size_t(to - from); m_item_count += size_t(to - from);
@ -553,13 +559,21 @@ BedShapeHint &BedShapeHint::operator=(const BedShapeHint &cpy)
return *this; return *this;
} }
template<class Bin> void remove_large_items(std::vector<Item> &items, Bin &&bin)
{
auto it = items.begin();
while (it != items.end())
sl::isInside(it->transformedShape(), bin) ?
++it : it = items.erase(it);
}
template<class BinT> // Arrange for arbitrary bin type template<class BinT> // Arrange for arbitrary bin type
void _arrange( void _arrange(
std::vector<Item> & shapes, std::vector<Item> & shapes,
std::vector<Item> & excludes, std::vector<Item> & excludes,
const BinT & bin, const BinT & bin,
coord_t minobjd, coord_t minobjd,
std::function<void(unsigned)> prind, std::function<void(unsigned)> progressfn,
std::function<bool()> stopfn) std::function<bool()> stopfn)
{ {
// Integer ceiling the min distance from the bed perimeters // Integer ceiling the min distance from the bed perimeters
@ -569,16 +583,13 @@ void _arrange(
auto corrected_bin = bin; auto corrected_bin = bin;
sl::offset(corrected_bin, md); sl::offset(corrected_bin, md);
AutoArranger<BinT> arranger{corrected_bin, 0, prind, stopfn}; AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
auto infl = coord_t(std::ceil(minobjd / 2.0)); auto infl = coord_t(std::ceil(minobjd / 2.0));
for (Item& itm : shapes) itm.inflate(infl); for (Item& itm : shapes) itm.inflate(infl);
for (Item& itm : excludes) itm.inflate(infl); for (Item& itm : excludes) itm.inflate(infl);
auto it = excludes.begin(); remove_large_items(excludes, corrected_bin);
while (it != excludes.end())
sl::isInside(it->transformedShape(), corrected_bin) ?
++it : it = excludes.erase(it);
// If there is something on the plate // If there is something on the plate
if (!excludes.empty()) arranger.preload(excludes); if (!excludes.empty()) arranger.preload(excludes);
@ -674,7 +685,7 @@ void arrange(ArrangePolygons & arrangables,
_arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn); _arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn);
break; break;
} }
}; }
for(size_t i = 0; i < items.size(); ++i) { for(size_t i = 0; i < items.size(); ++i) {
clppr::IntPoint tr = items[i].translation(); clppr::IntPoint tr = items[i].translation();

View file

@ -116,7 +116,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
has_internal_voids = true; has_internal_voids = true;
else { else {
FlowRole extrusion_role = (surface.surface_type == stTop) ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill); FlowRole extrusion_role = (surface.surface_type == stTop) ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill);
bool is_bridge = layerm.layer()->id() > 0 && surface.is_bridge(); bool is_bridge = layer.id() > 0 && surface.is_bridge();
params.extruder = layerm.region()->extruder(extrusion_role); params.extruder = layerm.region()->extruder(extrusion_role);
params.pattern = layerm.region()->config().fill_pattern.value; params.pattern = layerm.region()->config().fill_pattern.value;
params.density = float(layerm.region()->config().fill_density); params.density = float(layerm.region()->config().fill_density);
@ -141,11 +141,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
// calculate the actual flow we'll be using for this infill // calculate the actual flow we'll be using for this infill
params.flow = layerm.region()->flow( params.flow = layerm.region()->flow(
extrusion_role, extrusion_role,
(surface.thickness == -1) ? layerm.layer()->height : surface.thickness, // extrusion height (surface.thickness == -1) ? layer.height : surface.thickness, // extrusion height
is_bridge || Fill::use_bridge_flow(params.pattern), // bridge flow? is_bridge || Fill::use_bridge_flow(params.pattern), // bridge flow?
layerm.layer()->id() == 0, // first layer? layer.id() == 0, // first layer?
-1, // auto width -1, // auto width
*layerm.layer()->object() *layer.object()
); );
// Calculate flow spacing for infill pattern generation. // Calculate flow spacing for infill pattern generation.
@ -156,7 +156,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
// layer height // layer height
params.spacing = layerm.region()->flow( params.spacing = layerm.region()->flow(
frInfill, frInfill,
layerm.layer()->object()->config().layer_height.value, // TODO: handle infill_every_layers? layer.object()->config().layer_height.value, // TODO: handle infill_every_layers?
false, // no bridge false, // no bridge
false, // no first layer false, // no first layer
-1, // auto width -1, // auto width
@ -199,12 +199,14 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
Polygons all_polygons; Polygons all_polygons;
for (SurfaceFill &fill : surface_fills) for (SurfaceFill &fill : surface_fills)
if (! fill.expolygons.empty()) { if (! fill.expolygons.empty()) {
if (fill.expolygons.size() > 1 || ! all_polygons.empty()) {
Polygons polys = to_polygons(std::move(fill.expolygons)); Polygons polys = to_polygons(std::move(fill.expolygons));
if (fill.expolygons.size() > 1 || ! all_polygons.empty())
// Make a union of polygons, use a safety offset, subtract the preceding polygons. // Make a union of polygons, use a safety offset, subtract the preceding polygons.
// Bridges are processed first (see SurfaceFill::operator<()) // Bridges are processed first (see SurfaceFill::operator<())
fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true); fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true);
append(all_polygons, std::move(polys)); append(all_polygons, std::move(polys));
} else if (&fill != &surface_fills.back())
append(all_polygons, to_polygons(fill.expolygons));
} }
} }
@ -259,7 +261,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
region_id = region_some_infill; region_id = region_some_infill;
const LayerRegion& layerm = *layer.regions()[region_id]; const LayerRegion& layerm = *layer.regions()[region_id];
for (SurfaceFill &surface_fill : surface_fills) for (SurfaceFill &surface_fill : surface_fills)
if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layerm.layer()->height - surface_fill.params.flow.height) < EPSILON) { if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layer.height - surface_fill.params.flow.height) < EPSILON) {
internal_solid_fill = &surface_fill; internal_solid_fill = &surface_fill;
break; break;
} }
@ -273,9 +275,9 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
// calculate the actual flow we'll be using for this infill // calculate the actual flow we'll be using for this infill
params.flow = layerm.region()->flow( params.flow = layerm.region()->flow(
frSolidInfill, frSolidInfill,
layerm.layer()->height, // extrusion height layer.height, // extrusion height
false, // bridge flow? false, // bridge flow?
layerm.layer()->id() == 0, // first layer? layer.id() == 0, // first layer?
-1, // auto width -1, // auto width
*layer.object() *layer.object()
); );
@ -294,15 +296,48 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
return surface_fills; return surface_fills;
} }
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
void export_group_fills_to_svg(const char *path, const std::vector<SurfaceFill> &fills)
{
BoundingBox bbox;
for (const auto &fill : fills)
for (const auto &expoly : fill.expolygons)
bbox.merge(get_extents(expoly));
Point legend_size = export_surface_type_legend_to_svg_box_size();
Point legend_pos(bbox.min(0), bbox.max(1));
bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
for (const auto &fill : fills)
for (const auto &expoly : fill.expolygons)
svg.draw(expoly, surface_type_to_color_name(fill.surface.surface_type), transparency);
export_surface_type_legend_to_svg(svg, legend_pos);
svg.Close();
}
#endif
// friend to Layer // friend to Layer
void Layer::make_fills() void Layer::make_fills()
{ {
for (LayerRegion *layerm : m_regions) for (LayerRegion *layerm : m_regions)
layerm->fills.clear(); layerm->fills.clear();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
// this->export_region_fill_surfaces_to_svg_debug("10_fill-initial");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
std::vector<SurfaceFill> surface_fills = group_fills(*this); std::vector<SurfaceFill> surface_fills = group_fills(*this);
const Slic3r::BoundingBox bbox = this->object()->bounding_box(); const Slic3r::BoundingBox bbox = this->object()->bounding_box();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
export_group_fills_to_svg(debug_out_path("Layer-fill_surfaces-10_fill-final-%d.svg", iRun ++).c_str(), surface_fills);
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (SurfaceFill &surface_fill : surface_fills) { for (SurfaceFill &surface_fill : surface_fills) {
// Create the filler object. // Create the filler object.
std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern)); std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));

View file

@ -329,6 +329,28 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
} }
} }
// If the model contains empty layers (such as https://github.com/prusa3d/Slic3r/issues/1266), there might be layers
// that were not marked as has_wipe_tower, even when they should have been. This produces a crash with soluble supports
// and maybe other problems. We will therefore go through layer_tools and detect and fix this.
// So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder),
// we'll mark it with has_wipe tower.
for (unsigned int i=0; i+1<m_layer_tools.size(); ++i) {
LayerTools& lt = m_layer_tools[i];
LayerTools& lt_next = m_layer_tools[i+1];
if (lt.extruders.empty() || lt_next.extruders.empty())
break;
if (!lt_next.has_wipe_tower && (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1))
lt_next.has_wipe_tower = true;
// We should also check that the next wipe tower layer is no further than max_layer_height:
unsigned int j = i+1;
double last_wipe_tower_print_z = lt_next.print_z;
while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower)
if (m_layer_tools[j+1].print_z - last_wipe_tower_print_z > max_layer_height) {
m_layer_tools[j].has_wipe_tower = true;
last_wipe_tower_print_z = m_layer_tools[j].print_z;
}
}
// Calculate the wipe_tower_layer_height values. // Calculate the wipe_tower_layer_height values.
coordf_t wipe_tower_print_z_last = 0.; coordf_t wipe_tower_print_z_last = 0.;
for (LayerTools &lt : m_layer_tools) for (LayerTools &lt : m_layer_tools)

View file

@ -82,7 +82,7 @@ public:
} }
WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) { WipeTowerWriter& change_analyzer_mm3_per_mm(float len, float e) {
static const float area = M_PI * 1.75f * 1.75f / 4.f; static const float area = float(M_PI) * 1.75f * 1.75f / 4.f;
float mm3_per_mm = (len == 0.f ? 0.f : area * e / len); float mm3_per_mm = (len == 0.f ? 0.f : area * e / len);
// adds tag for analyzer: // adds tag for analyzer:
char buf[64]; char buf[64];
@ -100,7 +100,7 @@ public:
return *this; return *this;
} }
WipeTowerWriter& set_initial_tool(const unsigned int tool) { m_current_tool = tool; return *this; } WipeTowerWriter& set_initial_tool(size_t tool) { m_current_tool = tool; return *this; }
WipeTowerWriter& set_z(float z) WipeTowerWriter& set_z(float z)
{ m_current_z = z; return *this; } { m_current_z = z; return *this; }
@ -311,7 +311,7 @@ public:
return *this; return *this;
} }
WipeTowerWriter& set_tool(unsigned tool) WipeTowerWriter& set_tool(size_t tool)
{ {
m_current_tool = tool; m_current_tool = tool;
return *this; return *this;
@ -406,7 +406,7 @@ private:
Vec2f m_current_pos; Vec2f m_current_pos;
float m_current_z; float m_current_z;
float m_current_feedrate; float m_current_feedrate;
unsigned int m_current_tool; size_t m_current_tool;
float m_layer_height; float m_layer_height;
float m_extrusion_flow; float m_extrusion_flow;
bool m_preview_suppressed; bool m_preview_suppressed;
@ -417,7 +417,7 @@ private:
float m_y_shift = 0.f; float m_y_shift = 0.f;
float m_wipe_tower_width = 0.f; float m_wipe_tower_width = 0.f;
float m_wipe_tower_depth = 0.f; float m_wipe_tower_depth = 0.f;
unsigned m_last_fan_speed = 0.f; unsigned m_last_fan_speed = 0;
int current_temp = -1; int current_temp = -1;
const float m_default_analyzer_line_width; const float m_default_analyzer_line_width;
float m_used_filament_length = 0.f; float m_used_filament_length = 0.f;
@ -568,7 +568,7 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
// Iterate over all priming toolchanges and push respective ToolChangeResults into results vector. // Iterate over all priming toolchanges and push respective ToolChangeResults into results vector.
for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) { for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
int old_tool = m_current_tool; size_t old_tool = m_current_tool;
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar); WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
writer.set_extrusion_flow(m_extrusion_flow) writer.set_extrusion_flow(m_extrusion_flow)
@ -617,8 +617,8 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
ToolChangeResult result; ToolChangeResult result;
result.priming = true; result.priming = true;
result.initial_tool = old_tool; result.initial_tool = int(old_tool);
result.new_tool = m_current_tool; result.new_tool = int(m_current_tool);
result.print_z = this->m_z_pos; result.print_z = this->m_z_pos;
result.layer_height = this->m_layer_height; result.layer_height = this->m_layer_height;
result.gcode = writer.gcode(); result.gcode = writer.gcode();
@ -653,12 +653,12 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
return results; return results;
} }
WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_in_layer) WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool last_in_layer)
{ {
if ( m_print_brim ) if ( m_print_brim )
return toolchange_Brim(); return toolchange_Brim();
int old_tool = m_current_tool; size_t old_tool = m_current_tool;
float wipe_area = 0.f; float wipe_area = 0.f;
bool last_change_in_layer = false; bool last_change_in_layer = false;
@ -751,8 +751,8 @@ WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_
ToolChangeResult result; ToolChangeResult result;
result.priming = false; result.priming = false;
result.initial_tool = old_tool; result.initial_tool = int(old_tool);
result.new_tool = m_current_tool; result.new_tool = int(m_current_tool);
result.print_z = this->m_z_pos; result.print_z = this->m_z_pos;
result.layer_height = this->m_layer_height; result.layer_height = this->m_layer_height;
result.gcode = writer.gcode(); result.gcode = writer.gcode();
@ -765,7 +765,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(unsigned int tool, bool last_
WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_offset) WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_offset)
{ {
int old_tool = m_current_tool; size_t old_tool = m_current_tool;
const box_coordinates wipeTower_box( const box_coordinates wipeTower_box(
Vec2f::Zero(), Vec2f::Zero(),
@ -809,8 +809,8 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
ToolChangeResult result; ToolChangeResult result;
result.priming = false; result.priming = false;
result.initial_tool = old_tool; result.initial_tool = int(old_tool);
result.new_tool = m_current_tool; result.new_tool = int(m_current_tool);
result.print_z = this->m_z_pos; result.print_z = this->m_z_pos;
result.layer_height = this->m_layer_height; result.layer_height = this->m_layer_height;
result.gcode = writer.gcode(); result.gcode = writer.gcode();
@ -1115,7 +1115,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
// Otherwise the caller would likely travel to the wipe tower in vain. // Otherwise the caller would likely travel to the wipe tower in vain.
assert(! this->layer_finished()); assert(! this->layer_finished());
int old_tool = m_current_tool; size_t old_tool = m_current_tool;
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar); WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
writer.set_extrusion_flow(m_extrusion_flow) writer.set_extrusion_flow(m_extrusion_flow)
@ -1198,8 +1198,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
ToolChangeResult result; ToolChangeResult result;
result.priming = false; result.priming = false;
result.initial_tool = old_tool; result.initial_tool = int(old_tool);
result.new_tool = m_current_tool; result.new_tool = int(m_current_tool);
result.print_z = this->m_z_pos; result.print_z = this->m_z_pos;
result.layer_height = this->m_layer_height; result.layer_height = this->m_layer_height;
result.gcode = writer.gcode(); result.gcode = writer.gcode();

View file

@ -148,7 +148,7 @@ public:
// Returns gcode for a toolchange and a final print head position. // Returns gcode for a toolchange and a final print head position.
// On the first layer, extrude a brim around the future wipe tower first. // On the first layer, extrude a brim around the future wipe tower first.
ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer); ToolChangeResult tool_change(size_t new_tool, bool last_in_layer);
// Fill the unfilled space with a sparse infill. // Fill the unfilled space with a sparse infill.
// Call this method only if layer_finished() is false. // Call this method only if layer_finished() is false.
@ -194,7 +194,7 @@ private:
const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
const float WT_EPSILON = 1e-3f; const float WT_EPSILON = 1e-3f;
const float filament_area() const { float filament_area() const {
return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point
} }

View file

@ -121,7 +121,6 @@ void Layer::make_perimeters()
for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) { for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) {
LayerRegion* other_layerm = *it; LayerRegion* other_layerm = *it;
const PrintRegionConfig &other_config = other_layerm->region()->config(); const PrintRegionConfig &other_config = other_layerm->region()->config();
if (config.perimeter_extruder == other_config.perimeter_extruder if (config.perimeter_extruder == other_config.perimeter_extruder
&& config.perimeters == other_config.perimeters && config.perimeters == other_config.perimeters
&& config.perimeter_speed == other_config.perimeter_speed && config.perimeter_speed == other_config.perimeter_speed
@ -130,7 +129,8 @@ void Layer::make_perimeters()
&& config.overhangs == other_config.overhangs && config.overhangs == other_config.overhangs
&& config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width") && config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width")
&& config.thin_walls == other_config.thin_walls && config.thin_walls == other_config.thin_walls
&& config.external_perimeters_first == other_config.external_perimeters_first) { && config.external_perimeters_first == other_config.external_perimeters_first
&& config.infill_overlap == other_config.infill_overlap) {
layerms.push_back(other_layerm); layerms.push_back(other_layerm);
done[it - m_regions.begin()] = true; done[it - m_regions.begin()] = true;
} }
@ -142,12 +142,17 @@ void Layer::make_perimeters()
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces); (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
} else { } else {
SurfaceCollection new_slices; SurfaceCollection new_slices;
// Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
LayerRegion *layerm_config = layerms.front();
{ {
// group slices (surfaces) according to number of extra perimeters // group slices (surfaces) according to number of extra perimeters
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ] std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
for (LayerRegion *layerm : layerms) for (LayerRegion *layerm : layerms) {
for (Surface &surface : layerm->slices.surfaces) for (Surface &surface : layerm->slices.surfaces)
slices[surface.extra_perimeters].emplace_back(surface); slices[surface.extra_perimeters].emplace_back(surface);
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
layerm_config = layerm;
}
// merge the surfaces assigned to each group // merge the surfaces assigned to each group
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices) for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front()); new_slices.append(union_ex(surfaces_with_extra_perimeters.second, true), surfaces_with_extra_perimeters.second.front());
@ -155,7 +160,7 @@ void Layer::make_perimeters()
// make perimeters // make perimeters
SurfaceCollection fill_surfaces; SurfaceCollection fill_surfaces;
(*layerm)->make_perimeters(new_slices, &fill_surfaces); layerm_config->make_perimeters(new_slices, &fill_surfaces);
// assign fill_surfaces to each layer // assign fill_surfaces to each layer
if (!fill_surfaces.surfaces.empty()) { if (!fill_surfaces.surfaces.empty()) {

View file

@ -365,26 +365,23 @@ void LayerRegion::prepare_fill_surfaces()
// if no solid layers are requested, turn top/bottom surfaces to internal // if no solid layers are requested, turn top/bottom surfaces to internal
if (this->region()->config().top_solid_layers == 0) { if (this->region()->config().top_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) for (Surface &surface : this->fill_surfaces.surfaces)
if (surface->surface_type == stTop) if (surface.is_top())
surface->surface_type = (this->layer()->object()->config().infill_only_where_needed) ? surface.surface_type = this->layer()->object()->config().infill_only_where_needed ? stInternalVoid : stInternal;
stInternalVoid : stInternal;
} }
if (this->region()->config().bottom_solid_layers == 0) { if (this->region()->config().bottom_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) { for (Surface &surface : this->fill_surfaces.surfaces)
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge) if (surface.is_bottom()) // (surface.surface_type == stBottom)
surface->surface_type = stInternal; surface.surface_type = stInternal;
}
} }
// turn too small internal regions into solid regions according to the user setting // turn too small internal regions into solid regions according to the user setting
if (this->region()->config().fill_density.value > 0) { if (this->region()->config().fill_density.value > 0) {
// scaling an area requires two calls! // scaling an area requires two calls!
double min_area = scale_(scale_(this->region()->config().solid_infill_below_area.value)); double min_area = scale_(scale_(this->region()->config().solid_infill_below_area.value));
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) { for (Surface &surface : this->fill_surfaces.surfaces)
if (surface->surface_type == stInternal && surface->area() <= min_area) if (surface.surface_type == stInternal && surface.area() <= min_area)
surface->surface_type = stInternalSolid; surface.surface_type = stInternalSolid;
}
} }
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING #ifdef SLIC3R_DEBUG_SLICE_PROCESSING

View file

@ -37,6 +37,7 @@ void PerimeterGenerator::process()
// internal flow which is unrelated. // internal flow which is unrelated.
coord_t min_spacing = perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); coord_t min_spacing = perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE);
coord_t ext_min_spacing = ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); coord_t ext_min_spacing = ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE);
bool has_gap_fill = this->config->gap_fill_speed.value > 0;
// prepare grown lower layer slices for overhang detection // prepare grown lower layer slices for overhang detection
if (this->lower_slices != NULL && this->config->overhangs) { if (this->lower_slices != NULL && this->config->overhangs) {
@ -105,7 +106,7 @@ void PerimeterGenerator::process()
// leads to overflows, as in prusa3d/Slic3r GH #32 // leads to overflows, as in prusa3d/Slic3r GH #32
offset_ex(last, - distance); offset_ex(last, - distance);
// look for gaps // look for gaps
if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0) if (has_gap_fill)
// not using safety offset here would "detect" very narrow gaps // not using safety offset here would "detect" very narrow gaps
// (but still long enough to escape the area threshold) that gap fill // (but still long enough to escape the area threshold) that gap fill
// won't be able to fill but we'd still remove from infill area // won't be able to fill but we'd still remove from infill area
@ -132,6 +133,11 @@ void PerimeterGenerator::process()
} }
} }
last = std::move(offsets); last = std::move(offsets);
if (i == loop_number && (! has_gap_fill || this->config->fill_density.value == 0)) {
// The last run of this loop is executed to collect gaps for gap fill.
// As the gap fill is either disabled or not
break;
}
} }
// nest loops: holes first // nest loops: holes first

View file

@ -202,9 +202,9 @@ void Snapshot::export_selections(AppConfig &config) const
config.clear_section("presets"); config.clear_section("presets");
config.set("presets", "print", print); config.set("presets", "print", print);
config.set("presets", "filament", filaments.front()); config.set("presets", "filament", filaments.front());
for (int i = 1; i < filaments.size(); ++i) { for (unsigned i = 1; i < filaments.size(); ++i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%u", i);
config.set("presets", name, filaments[i]); config.set("presets", name, filaments[i]);
} }
config.set("presets", "printer", printer); config.set("presets", "printer", printer);
@ -373,9 +373,9 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot:
snapshot.print = app_config.get("presets", "print"); snapshot.print = app_config.get("presets", "print");
snapshot.filaments.emplace_back(app_config.get("presets", "filament")); snapshot.filaments.emplace_back(app_config.get("presets", "filament"));
snapshot.printer = app_config.get("presets", "printer"); snapshot.printer = app_config.get("presets", "printer");
for (unsigned int i = 1; i < 1000; ++ i) { for (unsigned i = 1; i < 1000; ++ i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%u", i);
if (! app_config.has("presets", name)) if (! app_config.has("presets", name))
break; break;
snapshot.filaments.emplace_back(app_config.get("presets", name)); snapshot.filaments.emplace_back(app_config.get("presets", name));

View file

@ -243,7 +243,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
"infill_speed", "bridge_speed" }) "infill_speed", "bridge_speed" })
toggle_field(el, have_infill || have_solid_infill); toggle_field(el, have_infill || have_solid_infill);
toggle_field("gap_fill_speed", have_perimeters && have_infill); // Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
toggle_field("gap_fill_speed", have_perimeters);
bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0; bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" }) for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })

View file

@ -854,7 +854,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value))); text_value = wxString::Format(_T("%i"), int(boost::any_cast<int>(value)));
else else
text_value = boost::any_cast<wxString>(value); text_value = boost::any_cast<wxString>(value);
auto idx = 0; size_t idx = 0;
for (auto el : m_opt.enum_values) for (auto el : m_opt.enum_values)
{ {
if (el == text_value) if (el == text_value)

View file

@ -861,11 +861,10 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
float left = m_layout.left + scaled_border; float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border; float top = m_layout.top - scaled_border;
int id = -1;
for (GLToolbarItem* item : m_items) for (size_t id=0; id<m_items.size(); ++id)
{ {
++id; GLToolbarItem* item = m_items[id];
if (!item->is_visible()) if (!item->is_visible())
continue; continue;
@ -936,11 +935,9 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
float left = m_layout.left + scaled_border; float left = m_layout.left + scaled_border;
float top = m_layout.top - scaled_border; float top = m_layout.top - scaled_border;
int id = -1; for (size_t id=0; id<m_items.size(); ++id)
for (GLToolbarItem* item : m_items)
{ {
++id; GLToolbarItem* item = m_items[id];
if (!item->is_visible()) if (!item->is_visible())
continue; continue;

View file

@ -422,7 +422,7 @@ DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) cons
(*m_objects)[obj_idx]->config; (*m_objects)[obj_idx]->config;
} }
wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count) wxDataViewColumn* ObjectList::create_objects_list_extruder_column(size_t extruders_count)
{ {
wxArrayString choices; wxArrayString choices;
choices.Add(_(L("default"))); choices.Add(_(L("default")));
@ -435,9 +435,9 @@ wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_
return column; return column;
} }
void ObjectList::update_extruder_values_for_items(const int max_extruder) void ObjectList::update_extruder_values_for_items(const size_t max_extruder)
{ {
for (int i = 0; i < m_objects->size(); ++i) for (size_t i = 0; i < m_objects->size(); ++i)
{ {
wxDataViewItem item = m_objects_model->GetItemById(i); wxDataViewItem item = m_objects_model->GetItemById(i);
if (!item) continue; if (!item) continue;
@ -453,7 +453,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder)
m_objects_model->SetValue(extruder, item, colExtruder); m_objects_model->SetValue(extruder, item, colExtruder);
if (object->volumes.size() > 1) { if (object->volumes.size() > 1) {
for (auto id = 0; id < object->volumes.size(); id++) { for (size_t id = 0; id < object->volumes.size(); id++) {
item = m_objects_model->GetItemByVolumeId(i, id); item = m_objects_model->GetItemByVolumeId(i, id);
if (!item) continue; if (!item) continue;
if (!object->volumes[id]->config.has("extruder") || if (!object->volumes[id]->config.has("extruder") ||
@ -468,7 +468,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder)
} }
} }
void ObjectList::update_objects_list_extruder_column(int extruders_count) void ObjectList::update_objects_list_extruder_column(size_t extruders_count)
{ {
if (!this) return; // #ys_FIXME if (!this) return; // #ys_FIXME
if (printer_technology() == ptSLA) if (printer_technology() == ptSLA)
@ -2565,7 +2565,14 @@ static double get_min_layer_height(const int extruder_idx)
static double get_max_layer_height(const int extruder_idx) static double get_max_layer_height(const int extruder_idx)
{ {
const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
return config.opt_float("max_layer_height", extruder_idx <= 0 ? 0 : extruder_idx-1); int extruder_idx_zero_based = extruder_idx <= 0 ? 0 : extruder_idx-1;
double max_layer_height = config.opt_float("max_layer_height", extruder_idx_zero_based);
// In case max_layer_height is set to zero, it should default to 75 % of nozzle diameter:
if (max_layer_height < EPSILON)
max_layer_height = 0.75 * config.opt_float("nozzle_diameter", extruder_idx_zero_based);
return max_layer_height;
} }
void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range) void ObjectList::add_layer_range_after_current(const t_layer_height_range& current_range)
@ -3262,7 +3269,7 @@ void ObjectList::change_part_type()
void ObjectList::last_volume_is_deleted(const int obj_idx) void ObjectList::last_volume_is_deleted(const int obj_idx)
{ {
if (obj_idx < 0 || obj_idx >= m_objects->size() || (*m_objects)[obj_idx]->volumes.size() != 1) if (obj_idx < 0 || size_t(obj_idx) >= m_objects->size() || (*m_objects)[obj_idx]->volumes.size() != 1)
return; return;
auto volume = (*m_objects)[obj_idx]->volumes.front(); auto volume = (*m_objects)[obj_idx]->volumes.front();

View file

@ -182,15 +182,15 @@ public:
void create_objects_ctrl(); void create_objects_ctrl();
void create_popup_menus(); void create_popup_menus();
wxDataViewColumn* create_objects_list_extruder_column(int extruders_count); wxDataViewColumn* create_objects_list_extruder_column(size_t extruders_count);
void update_objects_list_extruder_column(int extruders_count); void update_objects_list_extruder_column(size_t extruders_count);
// show/hide "Extruder" column for Objects List // show/hide "Extruder" column for Objects List
void set_extruder_column_hidden(const bool hide) const; void set_extruder_column_hidden(const bool hide) const;
// update extruder in current config // update extruder in current config
void update_extruder_in_config(const wxDataViewItem& item); void update_extruder_in_config(const wxDataViewItem& item);
// update changed name in the object model // update changed name in the object model
void update_name_in_model(const wxDataViewItem& item) const; void update_name_in_model(const wxDataViewItem& item) const;
void update_extruder_values_for_items(const int max_extruder); void update_extruder_values_for_items(const size_t max_extruder);
void init_icons(); void init_icons();
void msw_rescale_icons(); void msw_rescale_icons();

View file

@ -883,7 +883,7 @@ void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) {
sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1); sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1);
} }
void Sidebar::remove_unused_filament_combos(const int current_extruder_count) void Sidebar::remove_unused_filament_combos(const size_t current_extruder_count)
{ {
if (current_extruder_count >= p->combos_filament.size()) if (current_extruder_count >= p->combos_filament.size())
return; return;
@ -926,9 +926,9 @@ void Sidebar::update_presets(Preset::Type preset_type)
switch (preset_type) { switch (preset_type) {
case Preset::TYPE_FILAMENT: case Preset::TYPE_FILAMENT:
{ {
const int extruder_cnt = print_tech != ptFFF ? 1 : const size_t extruder_cnt = print_tech != ptFFF ? 1 :
dynamic_cast<ConfigOptionFloats*>(preset_bundle.printers.get_edited_preset().config.option("nozzle_diameter"))->values.size(); dynamic_cast<ConfigOptionFloats*>(preset_bundle.printers.get_edited_preset().config.option("nozzle_diameter"))->values.size();
const int filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size(); const size_t filament_cnt = p->combos_filament.size() > extruder_cnt ? extruder_cnt : p->combos_filament.size();
if (filament_cnt == 1) { if (filament_cnt == 1) {
// Single filament printer, synchronize the filament presets. // Single filament printer, synchronize the filament presets.
@ -1051,7 +1051,7 @@ wxButton* Sidebar::get_wiping_dialog_button()
return p->frequently_changed_parameters->get_wiping_dialog_button(); return p->frequently_changed_parameters->get_wiping_dialog_button();
} }
void Sidebar::update_objects_list_extruder_column(int extruders_count) void Sidebar::update_objects_list_extruder_column(size_t extruders_count)
{ {
p->object_list->update_objects_list_extruder_column(extruders_count); p->object_list->update_objects_list_extruder_column(extruders_count);
} }
@ -4697,7 +4697,7 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou
out_text = ""; out_text = "";
} }
void Plater::on_extruders_change(int num_extruders) void Plater::on_extruders_change(size_t num_extruders)
{ {
auto& choices = sidebar().combos_filament(); auto& choices = sidebar().combos_filament();
@ -4706,7 +4706,7 @@ void Plater::on_extruders_change(int num_extruders)
wxWindowUpdateLocker noUpdates_scrolled_panel(&sidebar()/*.scrolled_panel()*/); wxWindowUpdateLocker noUpdates_scrolled_panel(&sidebar()/*.scrolled_panel()*/);
int i = choices.size(); size_t i = choices.size();
while ( i < num_extruders ) while ( i < num_extruders )
{ {
PresetComboBox* choice/*{ nullptr }*/; PresetComboBox* choice/*{ nullptr }*/;
@ -4893,7 +4893,7 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
if (object_idxs.empty()) if (object_idxs.empty())
return; return;
for (int obj_idx : object_idxs) for (size_t obj_idx : object_idxs)
{ {
if (obj_idx < p->model.objects.size()) if (obj_idx < p->model.objects.size())
// recenter and re - align to Z = 0 // recenter and re - align to Z = 0

View file

@ -89,7 +89,7 @@ public:
~Sidebar(); ~Sidebar();
void init_filament_combo(PresetComboBox **combo, const int extr_idx); void init_filament_combo(PresetComboBox **combo, const int extr_idx);
void remove_unused_filament_combos(const int current_extruder_count); void remove_unused_filament_combos(const size_t current_extruder_count);
void update_all_preset_comboboxes(); void update_all_preset_comboboxes();
void update_presets(Slic3r::Preset::Type preset_type); void update_presets(Slic3r::Preset::Type preset_type);
void update_mode_sizer() const; void update_mode_sizer() const;
@ -105,7 +105,7 @@ public:
ConfigOptionsGroup* og_freq_chng_params(const bool is_fff); ConfigOptionsGroup* og_freq_chng_params(const bool is_fff);
wxButton* get_wiping_dialog_button(); wxButton* get_wiping_dialog_button();
void update_objects_list_extruder_column(int extruders_count); void update_objects_list_extruder_column(size_t extruders_count);
void show_info_sizer(); void show_info_sizer();
void show_sliced_info_sizer(const bool show); void show_sliced_info_sizer(const bool show);
void enable_buttons(bool enable); void enable_buttons(bool enable);
@ -209,7 +209,7 @@ public:
void enter_gizmos_stack(); void enter_gizmos_stack();
void leave_gizmos_stack(); void leave_gizmos_stack();
void on_extruders_change(int extruders_count); void on_extruders_change(size_t extruders_count);
void on_config_change(const DynamicPrintConfig &config); void on_config_change(const DynamicPrintConfig &config);
// On activating the parent window. // On activating the parent window.
void on_activate(); void on_activate();

View file

@ -366,7 +366,7 @@ void PresetBundle::load_selections(const AppConfig &config, const std::string &p
this->filament_presets = { filaments.get_selected_preset_name() }; this->filament_presets = { filaments.get_selected_preset_name() };
for (unsigned int i = 1; i < 1000; ++ i) { for (unsigned int i = 1; i < 1000; ++ i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%u", i);
if (! config.has("presets", name)) if (! config.has("presets", name))
break; break;
this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name))); this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
@ -388,11 +388,12 @@ void PresetBundle::export_selections(AppConfig &config)
config.clear_section("presets"); config.clear_section("presets");
config.set("presets", "print", prints.get_selected_preset_name()); config.set("presets", "print", prints.get_selected_preset_name());
config.set("presets", "filament", filament_presets.front()); config.set("presets", "filament", filament_presets.front());
for (int i = 1; i < filament_presets.size(); ++i) { for (unsigned i = 1; i < filament_presets.size(); ++i) {
char name[64]; char name[64];
sprintf(name, "filament_%d", i); sprintf(name, "filament_%u", i);
config.set("presets", name, filament_presets[i]); config.set("presets", name, filament_presets[i]);
} }
config.set("presets", "sla_print", sla_prints.get_selected_preset_name()); config.set("presets", "sla_print", sla_prints.get_selected_preset_name());
config.set("presets", "sla_material", sla_materials.get_selected_preset_name()); config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
config.set("presets", "printer", printers.get_selected_preset_name()); config.set("presets", "printer", printers.get_selected_preset_name());
@ -779,7 +780,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
Preset *loaded = nullptr; Preset *loaded = nullptr;
if (is_external) if (is_external)
loaded = &this->filaments.load_external_preset(name_or_path, name, loaded = &this->filaments.load_external_preset(name_or_path, name,
(i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "", (i < int(old_filament_profile_names->values.size())) ? old_filament_profile_names->values[i] : "",
std::move(cfg), i == 0); std::move(cfg), i == 0);
else { else {
// Used by the config wizard when creating a custom setup. // Used by the config wizard when creating a custom setup.
@ -1262,7 +1263,7 @@ void PresetBundle::update_multi_material_filament_presets()
// Now verify if wiping_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator): // Now verify if wiping_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator):
std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values; std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values;
size_t old_number_of_extruders = int(sqrt(old_matrix.size())+EPSILON); size_t old_number_of_extruders = size_t(sqrt(old_matrix.size())+EPSILON);
if (num_extruders != old_number_of_extruders) { if (num_extruders != old_number_of_extruders) {
// First verify if purging volumes presets for each extruder matches number of extruders // First verify if purging volumes presets for each extruder matches number of extruders
std::vector<double>& extruders = this->project_config.option<ConfigOptionFloats>("wiping_volumes_extruders")->values; std::vector<double>& extruders = this->project_config.option<ConfigOptionFloats>("wiping_volumes_extruders")->values;

View file

@ -232,7 +232,7 @@ void Tab::create_preset_tab()
//! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data()); //! select_preset(m_presets_choice->GetStringSelection().ToUTF8().data());
//! we doing next: //! we doing next:
int selected_item = m_presets_choice->GetSelection(); int selected_item = m_presets_choice->GetSelection();
if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty()) if (m_selected_preset_item == size_t(selected_item) && !m_presets->current_is_dirty())
return; return;
if (selected_item >= 0) { if (selected_item >= 0) {
std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
@ -489,7 +489,7 @@ template<class T>
void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, Tab *tab, const int& value) void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, Tab *tab, const int& value)
{ {
T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key)); T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key));
for (int i = 0; i < opt_cur->values.size(); i++) for (size_t i = 0; i < opt_cur->values.size(); i++)
map.emplace(opt_key + "#" + std::to_string(i), value); map.emplace(opt_key + "#" + std::to_string(i), value);
} }
@ -1808,7 +1808,7 @@ void TabPrinter::build_fff()
optgroup->append_single_option_line("single_extruder_multi_material"); optgroup->append_single_option_line("single_extruder_multi_material");
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) { optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) {
size_t extruders_count = boost::any_cast<int>(optgroup->get_value("extruders_count")); size_t extruders_count = boost::any_cast<size_t>(optgroup->get_value("extruders_count"));
wxTheApp->CallAfter([this, opt_key, value, extruders_count]() { wxTheApp->CallAfter([this, opt_key, value, extruders_count]() {
if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") { if (opt_key == "extruders_count" || opt_key == "single_extruder_multi_material") {
extruders_count_changed(extruders_count); extruders_count_changed(extruders_count);
@ -2228,7 +2228,7 @@ void TabPrinter::build_unregular_pages()
// Add/delete Kinematics page according to is_marlin_flavor // Add/delete Kinematics page according to is_marlin_flavor
size_t existed_page = 0; size_t existed_page = 0;
for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already for (size_t i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) { if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) {
if (!is_marlin_flavor || m_rebuild_kinematics_page) if (!is_marlin_flavor || m_rebuild_kinematics_page)
m_pages.erase(m_pages.begin() + i); m_pages.erase(m_pages.begin() + i);
@ -2253,7 +2253,7 @@ void TabPrinter::build_unregular_pages()
(m_has_single_extruder_MM_page && m_extruders_count == 1)) (m_has_single_extruder_MM_page && m_extruders_count == 1))
{ {
// if we have a single extruder MM setup, add a page with configuration options: // if we have a single extruder MM setup, add a page with configuration options:
for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already for (size_t i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) {
m_pages.erase(m_pages.begin() + i); m_pages.erase(m_pages.begin() + i);
break; break;
@ -2399,8 +2399,8 @@ void TabPrinter::on_preset_loaded()
{ {
// update the extruders count field // update the extruders count field
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter")); auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
int extruders_count = nozzle_diameter->values.size(); size_t extruders_count = nozzle_diameter->values.size();
set_value("extruders_count", extruders_count); set_value("extruders_count", int(extruders_count));
// update the GUI field according to the number of nozzle diameters supplied // update the GUI field according to the number of nozzle diameters supplied
extruders_count_changed(extruders_count); extruders_count_changed(extruders_count);
} }
@ -2538,7 +2538,7 @@ void TabPrinter::update_fff()
DynamicPrintConfig new_conf = *m_config; DynamicPrintConfig new_conf = *m_config;
if (dialog.ShowModal() == wxID_YES) { if (dialog.ShowModal() == wxID_YES) {
auto wipe = static_cast<ConfigOptionBools*>(m_config->option("wipe")->clone()); auto wipe = static_cast<ConfigOptionBools*>(m_config->option("wipe")->clone());
for (int w = 0; w < wipe->values.size(); w++) for (size_t w = 0; w < wipe->values.size(); w++)
wipe->values[w] = false; wipe->values[w] = false;
new_conf.set_key_value("wipe", wipe); new_conf.set_key_value("wipe", wipe);
} }

View file

@ -940,7 +940,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
// node can be deleted by the Delete, let's check its type while we safely can // node can be deleted by the Delete, let's check its type while we safely can
bool is_instance_root = (node->m_type & itInstanceRoot); bool is_instance_root = (node->m_type & itInstanceRoot);
for (int i = node->GetChildCount() - 1; i >= (is_instance_root ? 1 : 0); i--) for (int i = int(node->GetChildCount() - 1); i >= (is_instance_root ? 1 : 0); i--)
Delete(wxDataViewItem(node->GetNthChild(i))); Delete(wxDataViewItem(node->GetNthChild(i)));
return parent; return parent;
@ -1020,7 +1020,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
{ {
int vol_cnt = 0; int vol_cnt = 0;
int vol_idx = 0; int vol_idx = 0;
for (int i = 0; i < node_parent->GetChildCount(); ++i) { for (size_t i = 0; i < node_parent->GetChildCount(); ++i) {
if (node_parent->GetNthChild(i)->GetType() == itVolume) { if (node_parent->GetNthChild(i)->GetType() == itVolume) {
vol_idx = i; vol_idx = i;
vol_cnt++; vol_cnt++;
@ -1059,7 +1059,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
else else
{ {
auto it = find(m_objects.begin(), m_objects.end(), node); auto it = find(m_objects.begin(), m_objects.end(), node);
auto id = it - m_objects.begin(); size_t id = it - m_objects.begin();
if (it != m_objects.end()) if (it != m_objects.end())
{ {
// Delete all sub-items // Delete all sub-items
@ -1230,7 +1230,7 @@ void ObjectDataViewModel::DeleteSettings(const wxDataViewItem& parent)
wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx) wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx)
{ {
if (obj_idx >= m_objects.size()) if (size_t(obj_idx) >= m_objects.size())
{ {
printf("Error! Out of objects range.\n"); printf("Error! Out of objects range.\n");
return wxDataViewItem(0); return wxDataViewItem(0);
@ -1241,7 +1241,7 @@ wxDataViewItem ObjectDataViewModel::GetItemById(int obj_idx)
wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx) wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_idx)
{ {
if (obj_idx >= m_objects.size() || obj_idx < 0) { if (size_t(obj_idx) >= m_objects.size()) {
printf("Error! Out of objects range.\n"); printf("Error! Out of objects range.\n");
return wxDataViewItem(0); return wxDataViewItem(0);
} }
@ -1265,7 +1265,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volume_id
wxDataViewItem ObjectDataViewModel::GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type) wxDataViewItem ObjectDataViewModel::GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type)
{ {
if (obj_idx >= m_objects.size() || obj_idx < 0) { if (size_t(obj_idx) >= m_objects.size()) {
printf("Error! Out of objects range.\n"); printf("Error! Out of objects range.\n");
return wxDataViewItem(0); return wxDataViewItem(0);
} }
@ -1294,7 +1294,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByLayerId(int obj_idx, int layer_idx)
wxDataViewItem ObjectDataViewModel::GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range) wxDataViewItem ObjectDataViewModel::GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range)
{ {
if (obj_idx >= m_objects.size() || obj_idx < 0) { if (size_t(obj_idx) >= m_objects.size()) {
printf("Error! Out of objects range.\n"); printf("Error! Out of objects range.\n");
return wxDataViewItem(0); return wxDataViewItem(0);
} }
@ -1411,13 +1411,13 @@ int ObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const
int row_num = 0; int row_num = 0;
for (int i = 0; i < m_objects.size(); i++) for (size_t i = 0; i < m_objects.size(); i++)
{ {
row_num++; row_num++;
if (item == wxDataViewItem(m_objects[i])) if (item == wxDataViewItem(m_objects[i]))
return row_num; return row_num;
for (int j = 0; j < m_objects[i]->GetChildCount(); j++) for (size_t j = 0; j < m_objects[i]->GetChildCount(); j++)
{ {
row_num++; row_num++;
ObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j); ObjectDataViewModelNode* cur_node = m_objects[i]->GetNthChild(j);
@ -1429,7 +1429,7 @@ int ObjectDataViewModel::GetRowByItem(const wxDataViewItem& item) const
if (cur_node->m_type == itInstanceRoot) if (cur_node->m_type == itInstanceRoot)
{ {
row_num++; row_num++;
for (int t = 0; t < cur_node->GetChildCount(); t++) for (size_t t = 0; t < cur_node->GetChildCount(); t++)
{ {
row_num++; row_num++;
if (item == wxDataViewItem(cur_node->GetNthChild(t))) if (item == wxDataViewItem(cur_node->GetNthChild(t)))
@ -1503,7 +1503,7 @@ bool ObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewIte
bool ObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) bool ObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col)
{ {
if (item_idx < 0 || item_idx >= m_objects.size()) if (size_t(item_idx) >= m_objects.size())
return false; return false;
return m_objects[item_idx]->SetValue(variant, col); return m_objects[item_idx]->SetValue(variant, col);
@ -1662,7 +1662,7 @@ wxDataViewItem ObjectDataViewModel::GetItemByType(const wxDataViewItem &parent_i
if (node->GetChildCount() == 0) if (node->GetChildCount() == 0)
return wxDataViewItem(0); return wxDataViewItem(0);
for (int i = 0; i < node->GetChildCount(); i++) { for (size_t i = 0; i < node->GetChildCount(); i++) {
if (node->GetNthChild(i)->m_type == type) if (node->GetNthChild(i)->m_type == type)
return wxDataViewItem((void*)node->GetNthChild(i)); return wxDataViewItem((void*)node->GetNthChild(i));
} }
@ -2145,7 +2145,7 @@ void DoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int hig
wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1; wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1;
wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1; wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1;
for (int id = 0; id < m_line_pens.size(); id++) for (size_t id = 0; id < m_line_pens.size(); id++)
{ {
dc.SetPen(*m_line_pens[id]); dc.SetPen(*m_line_pens[id]);
dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y); dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y);
@ -2494,7 +2494,7 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
dc.SetBrush(clr); dc.SetBrush(clr);
dc.DrawRectangle(main_band); dc.DrawRectangle(main_band);
int i = 1; size_t i = 1;
for (auto tick : m_ticks) for (auto tick : m_ticks)
{ {
if (i == colors_cnt) if (i == colors_cnt)