Skip to content

Commit

Permalink
many bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed Nov 22, 2023
2 parents 7a6e06c + 4c9e5cb commit 2a34465
Show file tree
Hide file tree
Showing 20 changed files with 192 additions and 93 deletions.
4 changes: 2 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
Expand Down Expand Up @@ -46,7 +46,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 78
ColumnLimit: 118
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
Expand Down
1 change: 1 addition & 0 deletions resources/ui_layout/default/colors.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Wipe tower = B3E3AB
Mill = B3B3B3
Custom = 28CC94
Mixed = 000000
Travel =
Gui_color_dark = 275cad
Gui_color = 296acc
Gui_color_light = 3d83ed
Expand Down
1 change: 1 addition & 0 deletions resources/ui_layout/example/colors.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Wipe tower = B3E3AB
Mill = B3B3B3
Custom = 28CC94
Mixed = 000000
Travel =
Gui_color_dark = 275cad
Gui_color = 296acc
Gui_color_light = 3d83ed
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/ExtrusionEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
case erMilling : return L("Mill");
case erCustom : return L("Custom");
case erMixed : return L("Mixed");
case erTravel : return L("Travel");
default : assert(false);
}

Expand Down
4 changes: 3 additions & 1 deletion src/libslic3r/ExtrusionEntity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ enum ExtrusionRole : uint16_t {
};
*/
enum ExtrusionRole : uint8_t {
erNone, // erNone needs to be 0 (for cooling and everything that use the role as index)
erNone, // erNone needs to be 0 (for cooling and everything that use the role as index). It must not be used. Please use erTravel for not-extrusion role.
erPerimeter,
erExternalPerimeter,
erOverhangPerimeter,
Expand All @@ -72,6 +72,8 @@ enum ExtrusionRole : uint8_t {
erCustom,
// Extrusion role for a collection with multiple extrusion roles.
erMixed,
//extrusion role when there is no extrusion
erTravel,
erCount
};

Expand Down
6 changes: 5 additions & 1 deletion src/libslic3r/ExtrusionEntityCollection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ class ExtrusionEntityCollection : public ExtrusionEntity
ExtrusionRole out = erNone;
for (const ExtrusionEntity *ee : m_entities) {
ExtrusionRole er = ee->role();
out = (out == erNone || out == er) ? er : erMixed;
if (out == erNone) {
out = er;
}else if (out != er) {
return erMixed;
}
}
return out;
}
Expand Down
47 changes: 34 additions & 13 deletions src/libslic3r/Fill/FillConcentric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ FillConcentricWGapFill::fill_surface_extrusion(

double min_gapfill_area = double(params.flow.scaled_width()) * double(params.flow.scaled_width());
if (params.config != nullptr) min_gapfill_area = scale_d(params.config->gap_fill_min_area.get_abs_value(params.flow.width())) * double(params.flow.scaled_width());
// Perform offset.
// Perform offset. //FIXME: can miss gapfill outside of this first perimeter
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, double(scale_(0 - 0.5 * this->get_spacing())));
// Create the infills for each of the regions.
Polylines polylines_out;
Expand All @@ -117,9 +117,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
if (params.density > 0.9999f && !params.dont_adjust) {
distance = scale_t(this->get_spacing());
}

ExPolygons gaps;
std::vector< std::vector<Polygons>> bunch_2_shell_2_loops;
std::vector<std::vector<Polygons>> bunch_2_shell_2_loops;
bunch_2_shell_2_loops.emplace_back(); // create a new bunch before a gap
bunch_2_shell_2_loops.back().push_back(to_polygons(expolygon)); // add first shell
std::vector<ExPolygons> bunch_2_gaps; // size = bunch_2_shell_2_loops.size() (-1)
Expand All @@ -129,40 +127,63 @@ FillConcentricWGapFill::fill_surface_extrusion(
ExPolygons next_onion = offset2_ex(last, -(distance + scale_d(this->get_spacing()) / 2), +(scale_d(this->get_spacing()) / 2));
ExPolygons new_gaps = diff_ex(
offset_ex(last, -0.5f * distance),
offset_ex(next_onion, 0.5f * distance + 10)); // 10 = safety offset
offset_ex(next_onion, 0.5f * distance + 10)); // 10 = safety offset
//add next shell (into the last collection)
bunch_2_shell_2_loops.back().push_back(to_polygons(next_onion));
//if there is some gaps, then we need to create a new collection for the next shells, so they will be peirnted after the gaps.
if (!new_gaps.empty()) {
append(gaps, new_gaps);
if (first && !this->no_overlap_expolygons.empty()) {
new_gaps = intersection_ex(new_gaps, this->no_overlap_expolygons);
}
bunch_2_gaps.push_back(std::move(new_gaps));
if (!bunch_2_shell_2_loops.back().empty() && bunch_2_shell_2_loops.back().back().empty()) {
bunch_2_shell_2_loops.back().pop_back();
}
//create a new collection for next bunch.
bunch_2_shell_2_loops.emplace_back();
//create a new collection for next bunch (if the loop don't stop here).
if (!next_onion.empty()) {
bunch_2_shell_2_loops.emplace_back();
}
}
// refresh before next iteration
last = next_onion;
if (first && !this->no_overlap_expolygons.empty()) {
gaps = intersection_ex(gaps, this->no_overlap_expolygons);
}
first = false;
}
if (!bunch_2_shell_2_loops.back().empty() && bunch_2_shell_2_loops.back().back().empty()) {
bunch_2_shell_2_loops.back().pop_back();
}
if (bunch_2_shell_2_loops.back().empty()) {
assert(bunch_2_shell_2_loops.size() > bunch_2_gaps.size());
assert(bunch_2_shell_2_loops.size() >= bunch_2_gaps.size());
if (bunch_2_shell_2_loops.size() == bunch_2_gaps.size()) {
assert(bunch_2_gaps.size() > 1);
if (bunch_2_gaps.size() > 1) {
// merge last two gaps (inside the last perimeter & after the last perimeter are both extruded
// after the last perimeter)
append(bunch_2_gaps[bunch_2_gaps.size() - 2], bunch_2_gaps.back());
bunch_2_gaps.pop_back();
}
}
bunch_2_shell_2_loops.pop_back();
if (!bunch_2_shell_2_loops.empty() && !bunch_2_shell_2_loops.back().empty() && bunch_2_shell_2_loops.back().back().empty()) {
bunch_2_shell_2_loops.back().pop_back();
}
}
//check no empty shell
assert(!bunch_2_shell_2_loops.back().empty());
//check no empty gap
assert(std::find_if(bunch_2_gaps.begin(), bunch_2_gaps.end(), [](const auto &vec) { return vec.empty(); }) ==
bunch_2_gaps.end());
// check size there is 3 posibilities:
// 1) no gap: 1 shell
// 2) gap but not in the last to iteration: X xhells, x-1 gap
// 3) gap and there is some to print after the last shell: X shell, X gap
assert(bunch_2_shell_2_loops.size() == bunch_2_gaps.size() + 1 ||
bunch_2_shell_2_loops.size() == bunch_2_gaps.size());

// generate paths from the outermost to the innermost, to avoid
// adhesion problems of the first central tiny loops
//note: useless if we don't apply no_sort flag
//loops = union_pt_chained(loops, false);


//get the role
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);

Expand Down
50 changes: 34 additions & 16 deletions src/libslic3r/Fill/FillPlanePath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,46 @@ void FillPlanePath::_fill_surface_single(
coord_t(ceil(coordf_t(bounding_box.max.y()) / distance_between_lines)),
params.resolution);

if (pts.size() >= 2) {
// doing intersection_pl(polylines, expolygon); on >200k points is too inneficient.
// new version: with a "is_inside" for each point, in parallel
//note: seems like there is no need to parallelize now, too quick.
Polylines all_poly;
for (size_t istart = 0; istart < pts.size(); istart += 1000) {
const size_t iend = istart + 1000 < pts.size() ? istart + 1001 : pts.size();
// Convert points to a polyline, upscale.
Polylines polylines(1, Polyline());
Polyline &polyline = polylines.front();
polyline.points.reserve(pts.size());
for (const Vec2d &pt : pts)
polyline.points.emplace_back(
coord_t(floor(pt.x() * distance_between_lines + 0.5)),
coord_t(floor(pt.y() * distance_between_lines + 0.5)));
polyline.points.reserve(iend - istart);
//for (const Vec2d &pt : pts)
for(size_t ip = istart ; ip < iend; ++ip)
polyline.points.emplace_back(coord_t(floor(pts[ip].x() * distance_between_lines + 0.5)),
coord_t(floor(pts[ip].y() * distance_between_lines + 0.5)));
polylines = intersection_pl(polylines, expolygon);
Polylines chained;
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1)
chained = chain_polylines(std::move(polylines));
else
connect_infill(std::move(polylines), expolygon, chained, this->get_spacing(), params);
// paths must be repositioned and rotated back
for (Polyline &pl : chained) {
pl.translate(double(shift.x()), double(shift.y()));
pl.rotate(direction.first);
if (!polylines.empty()) {
assert(!polylines.front().empty());
if (!all_poly.empty() && polylines.front().front().coincides_with_epsilon(all_poly.back().back())) {
// it continue the last polyline, so just append to it
append(all_poly.back().points, std::move(polylines.front().points));
//append other polylines
if (polylines.size() > 1) {
all_poly.insert(all_poly.end(), polylines.begin() + 1, polylines.end());
}
} else {
append(all_poly, std::move(polylines));
}
}
append(polylines_out, std::move(chained));
}
Polylines chained;
if (params.dont_connect() || params.density > 0.5 || all_poly.size() <= 1)
chained = chain_polylines(std::move(all_poly));
else
connect_infill(std::move(all_poly), expolygon, chained, this->get_spacing(), params);
// paths must be repositioned and rotated back
for (Polyline &pl : chained) {
pl.translate(double(shift.x()), double(shift.y()));
pl.rotate(direction.first);
}
append(polylines_out, std::move(chained));
}

// Follow an Archimedean spiral, in polar coordinates: r=a+b\theta
Expand Down
15 changes: 11 additions & 4 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,7 @@ namespace DoExport {
excluded.insert(erCustom);
excluded.insert(erMixed);
excluded.insert(erNone);
excluded.insert(erTravel);
excluded.insert(erWipeTower);
if (config->option("perimeter_speed") != nullptr && config->get_computed_value("perimeter_speed") != 0)
excluded.insert(erPerimeter);
Expand Down Expand Up @@ -1837,7 +1838,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene
file.write(this->retract());
std::string gcode;
//go to origin of the next object (it's 0,0 because we shifted the origin to it)
Polyline polyline = this->travel_to(gcode, Point(0, 0), erNone);
Polyline polyline = this->travel_to(gcode, Point(0, 0), erTravel);
this->write_travel_to(gcode, polyline, "move to origin position for next object");
file.write(gcode);
m_enable_cooling_markers = true;
Expand Down Expand Up @@ -1914,7 +1915,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene
this->set_origin(unscale((*print_object_instance_sequential_active)->shift));
std::string gcode;
//go to origin of the next object (it's 0,0 because we shifted the origin to it)
Polyline polyline = this->travel_to(gcode, Point(0, 0), erNone);
Polyline polyline = this->travel_to(gcode, Point(0, 0), erTravel);
this->write_travel_to(gcode, polyline, "move to origin position for next object");
file.write(gcode);
}
Expand Down Expand Up @@ -5314,7 +5315,8 @@ double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double spee
}
} else if (path.role() == erIroning) {
speed = m_config.get_computed_value("ironing_speed");
} else if (path.role() == erNone) {
} else if (path.role() == erNone || path.role() == erTravel) {
assert(path.role() != erNone);
speed = m_config.get_computed_value("travel_speed");
} else if (path.role() == erMilling) {
speed = m_config.get_computed_value("milling_speed");
Expand Down Expand Up @@ -5435,6 +5437,7 @@ void GCode::cooldown_marker_init() {
_cooldown_marker_speed[erMilling] = "";
_cooldown_marker_speed[erCustom] = maybe_allow_speed_change;
_cooldown_marker_speed[erMixed] = maybe_allow_speed_change;
_cooldown_marker_speed[erTravel] = maybe_allow_speed_change;
}
}

Expand Down Expand Up @@ -5582,11 +5585,13 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}
}
goto externalPerimeter;
case erNone:
assert(false);
case erMilling:
case erCustom:
case erMixed:
case erTravel:
case erCount:
case erNone:
default:
break;
}
Expand Down Expand Up @@ -5783,6 +5788,8 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}

std::string comment;
assert(path.role() > ExtrusionRole::erNone);
assert(path.role() < ExtrusionRole::erCount);
if (m_enable_cooling_markers) {
// Send the current extrusion type to Coolingbuffer
gcode += ";_EXTRUDETYPE_"; gcode += char('A' + path.role()); gcode += "\n";
Expand Down
4 changes: 4 additions & 0 deletions src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,10 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
} else if (boost::starts_with(sline, ";_EXTRUDETYPE_") && sline.size() > 14) {
//set the extrusiontype
line.type |= CoolingLine::Type(sline[14] - 'A') | CoolingLine::Type::TYPE_EXTRUDE_START;
assert(CoolingLine::to_extrusion_role(uint32_t(line.type)) != 0);
if (CoolingLine::to_extrusion_role(uint32_t(line.type)) == 0) {
line.type |= ExtrusionRole::erCustom;
}
} else if (boost::starts_with(sline, "G4 ")) {
// Parse the wait time.
line.type = CoolingLine::TYPE_G4;
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/GCode/GCodeProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2733,7 +2733,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_extrusion_role == erExternalPerimeter)
// cross section: rectangle
m_height = static_cast<float>(delta_pos[E] * (M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_width));
else if (is_bridge(m_extrusion_role) || m_extrusion_role == erNone)
else if (is_bridge(m_extrusion_role) || m_extrusion_role == erNone || m_extrusion_role == erTravel)
// cross section: circle
m_height = static_cast<float>(m_result.filament_diameters[m_extruder_id] * std::sqrt(delta_pos[E] / delta_xyz));
else
Expand Down Expand Up @@ -2770,7 +2770,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_extrusion_role == erExternalPerimeter)
// cross section: rectangle
m_width = static_cast<float>(delta_pos[E] * (M_PI * sqr(1.05f * filament_radius)) / (delta_xyz * m_height));
else if (is_bridge(m_extrusion_role) || m_extrusion_role == erNone)
else if (is_bridge(m_extrusion_role) || m_extrusion_role == erNone || m_extrusion_role == erTravel)
// cross section: circle
m_width = static_cast<float>(m_result.filament_diameters[m_extruder_id] * std::sqrt(delta_pos[E] / delta_xyz));
else
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/GCode/ToolOrdering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
for (const ExtrusionEntity *ee : layerm->fills.entities()) {
// fill represents infill extrusions of a single island.
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
//FIXME: if first role is gapfill, please search deeper for another role
ExtrusionRole role = fill->entities().empty() ? erNone : fill->entities().front()->role();
if (is_solid_infill(role))
has_solid_infill = true;
Expand Down
Loading

0 comments on commit 2a34465

Please sign in to comment.