Skip to content

Commit

Permalink
fix support crash, add ascii-only output
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed Jan 24, 2024
2 parents 2053c1b + 46d51e5 commit c62503c
Show file tree
Hide file tree
Showing 32 changed files with 493 additions and 279 deletions.
5 changes: 4 additions & 1 deletion resources/ui_layout/default/printer_fff.ui
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ group:silent_mode_event:Firmware
setting:arc_fitting
setting:arc_fitting_tolerance
end_line
setting:gcode_filename_illegal_char
line:Formatting
setting:gcode_filename_illegal_char
setting:gcode_ascii
end_line
group:Cooling fan
setting:fan_printer_min_speed
line:Speedup time
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Brim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,7 @@ void make_brim_ears(const Print& print, const Flow& flow, const PrintObjectPtrs&

//push into extrusions
extrusion_entities_append_paths(
out.set_entities(),
out,
lines_sorted,
erSkirt,
float(flow.mm3_per_mm()),
Expand Down
48 changes: 48 additions & 0 deletions src/libslic3r/ExtrusionEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ double ExtrusionLoop::length() const
return len;
}

ExtrusionRole ExtrusionLoop::role() const
{
if (this->paths.empty())
return erNone;
ExtrusionRole role = this->paths.front().role();
for (const ExtrusionPath &path : this->paths)
if (role != path.role()) {
return erMixed;
}
return role;
}

bool ExtrusionLoop::split_at_vertex(const Point &point, const double scaled_epsilon)
{
for (ExtrusionPaths::iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
Expand Down Expand Up @@ -544,6 +556,42 @@ void ExtrusionVisitorRecursive::use(ExtrusionEntityCollection& collection) {
}
}

void HasRoleVisitor::use(const ExtrusionMultiPath& multipath) {
for (const ExtrusionPath& path : multipath.paths) {
path.visit(*this);
if(found) return;
}
}
void HasRoleVisitor::use(const ExtrusionMultiPath3D& multipath3D) {
for (const ExtrusionPath3D& path3D : multipath3D.paths) {
path3D.visit(*this);
if(found) return;
}
}
void HasRoleVisitor::use(const ExtrusionLoop& loop) {
for (const ExtrusionPath& path : loop.paths) {
path.visit(*this);
if(found) return;
}
}
void HasRoleVisitor::use(const ExtrusionEntityCollection& collection) {
for (const ExtrusionEntity* entity : collection.entities()) {
entity->visit(*this);
if(found) return;
}
}
bool HasRoleVisitor::search(const ExtrusionEntity &entity, HasRoleVisitor&& visitor) {
entity.visit(visitor);
return visitor.found;
}
bool HasRoleVisitor::search(const ExtrusionEntitiesPtr &entities, HasRoleVisitor&& visitor) {
for (ExtrusionEntity *ptr : entities) {
ptr->visit(visitor);
if (visitor.found) return true;
}
return visitor.found;
}

//class ExtrusionTreeVisitor : ExtrusionVisitor {
//public:
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
Expand Down
117 changes: 31 additions & 86 deletions src/libslic3r/ExtrusionEntity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,17 @@ class ExtrusionMultiEntity : public ExtrusionEntity {
ExtrusionMultiEntity& operator=(ExtrusionMultiEntity &&rhs) { this->paths = std::move(rhs.paths); return *this; }

bool is_loop() const override { return false; }
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
ExtrusionRole role() const override
{
if (this->paths.empty())
return erNone;
ExtrusionRole role = this->paths.front().role();
for (const ExtrusionPath &path : this->paths)
if (role != path.role()) {
return erMixed;
}
return role;
}
virtual const Point& first_point() const override { return this->paths.front().polyline.as_polyline().front(); }
virtual const Point& last_point() const override { return this->paths.back().polyline.as_polyline().back(); }

Expand Down Expand Up @@ -480,7 +490,7 @@ class ExtrusionLoop : public ExtrusionEntity
// Test, whether the point is extruded by a bridging flow.
// This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead.
bool has_overhang_point(const Point &point) const;
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
ExtrusionRole role() const override;
ExtrusionLoopRole loop_role() const { return m_loop_role; }
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
Expand Down Expand Up @@ -542,89 +552,6 @@ inline void extrusion_paths_append(ExtrusionPaths &dst, Polylines &&polylines, E
polylines.clear();
}

inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &polylines, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true)
{
dst.reserve(dst.size() + polylines.size());
for (Polyline &polyline : polylines)
if (polyline.is_valid()) {
if (polyline.back() == polyline.front()) {
ExtrusionPath path(role, mm3_per_mm, width, height, can_reverse);
path.polyline = polyline;
dst.emplace_back(new ExtrusionLoop(std::move(path)));
} else {
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height, can_reverse);
dst.push_back(extrusion_path);
extrusion_path->polyline = polyline;
}
}
}

inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true)
{
dst.reserve(dst.size() + polylines.size());
for (Polyline &polyline : polylines)
if (polyline.is_valid()) {
if (polyline.back() == polyline.front()) {
ExtrusionPath path(role, mm3_per_mm, width, height, can_reverse);
path.polyline = polyline;
dst.emplace_back(new ExtrusionLoop(std::move(path)));
} else {
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height, can_reverse);
dst.push_back(extrusion_path);
extrusion_path->polyline = std::move(polyline);
}
}
polylines.clear();
}

inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &loops, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true) {
dst.reserve(dst.size() + loops.size());
for (Polygon & polygon : loops) {
if (polygon.is_valid()) {
ExtrusionPath path(role, mm3_per_mm, width, height, can_reverse);
path.polyline.append(polygon.points);
path.polyline.append(path.polyline.front());
dst.emplace_back(new ExtrusionLoop(std::move(path)));
}
}
}

inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &&loops, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true)
{
dst.reserve(dst.size() + loops.size());
for (Polygon &polygon : loops) {
if (polygon.is_valid()) {
ExtrusionPath path(role, mm3_per_mm, width, height, can_reverse);
path.polyline.append(std::move(polygon.points));
path.polyline.append(path.polyline.front());
ExtrusionLoop *loop = new ExtrusionLoop(std::move(path));
//default to ccw
loop->make_counter_clockwise();
dst.emplace_back(loop);
}
}
loops.clear();
}

inline void extrusion_entities_append_loops_and_paths(ExtrusionEntitiesPtr &dst, Polylines &&polylines, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse = true)
{
dst.reserve(dst.size() + polylines.size());
for (Polyline &polyline : polylines) {
if (polyline.is_valid()) {
if (polyline.is_closed()) {
ExtrusionPath extrusion_path(role, mm3_per_mm, width, height, can_reverse);
extrusion_path.polyline = std::move(polyline);
dst.emplace_back(new ExtrusionLoop(std::move(extrusion_path)));
} else {
ExtrusionPath *extrusion_path = new ExtrusionPath(role, mm3_per_mm, width, height, can_reverse);
extrusion_path->polyline = std::move(polyline);
dst.emplace_back(extrusion_path);
}
}
}
polylines.clear();
}

class ExtrusionPrinter : public ExtrusionVisitorConst {
std::stringstream ss;
double mult;
Expand Down Expand Up @@ -674,6 +601,23 @@ class ExtrusionVisitorRecursive : public ExtrusionVisitor {
virtual void use(ExtrusionEntityCollection& collection) override;
};

class HasRoleVisitor : public ExtrusionVisitorConst{
public:
bool found = false;
void use(const ExtrusionMultiPath& multipath) override;
void use(const ExtrusionMultiPath3D& multipath3D) override;
void use(const ExtrusionLoop& loop) override;
void use(const ExtrusionEntityCollection& collection) override;
static bool search(const ExtrusionEntity &entity, HasRoleVisitor&& visitor);
static bool search(const ExtrusionEntitiesPtr &entities, HasRoleVisitor&& visitor);
};
struct HasInfillVisitor : public HasRoleVisitor{
void default_use(const ExtrusionEntity &entity) override { found = is_infill(entity.role()); };
};
struct HasSolidInfillVisitor : public HasRoleVisitor{
void default_use(const ExtrusionEntity &entity) override { found = is_solid_infill(entity.role()); };
};


//call simplify for all paths.
class SimplifyVisitor : public ExtrusionVisitorRecursive {
Expand Down Expand Up @@ -726,7 +670,8 @@ class ExtrusionModifyFlow : public ExtrusionVisitorRecursive {
#if _DEBUG
struct LoopAssertVisitor : public ExtrusionVisitorRecursiveConst {
virtual void default_use(const ExtrusionEntity& entity) override {};
virtual void use(const ExtrusionLoop& loop) override {
virtual void use(const ExtrusionPath &path) override { assert(path.length() > SCALED_EPSILON); }
virtual void use(const ExtrusionLoop &loop) override {
for (auto it = std::next(loop.paths.begin()); it != loop.paths.end(); ++it) {
assert(it->polyline.size() >= 2);
assert(std::prev(it)->polyline.back() == it->polyline.front());
Expand Down
37 changes: 4 additions & 33 deletions src/libslic3r/ExtrusionEntityCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,40 +81,11 @@ void ExtrusionEntityCollection::remove(size_t i)
this->m_entities.erase(this->m_entities.begin() + i);
}

ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const ExtrusionEntitiesPtr& extrusion_entities, const Point &start_near, ExtrusionRole role)
//ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const Point &start_near, ExtrusionRole role)
void ExtrusionEntityCollection::chained_path_from(const Point &start_near)
{
//ExtrusionEntityCollection out;
//if (this->no_sort) {
// out = *this;
//} else {
// if (role == erMixed)
// out = *this;
// else {
// for (const ExtrusionEntity *ee : this->entities()) {
// if (role != erMixed) {
// // The caller wants only paths with a specific extrusion role.
// auto role2 = ee->role();
// if (role != role2) {
// // This extrusion entity does not match the role asked.
// assert(role2 != erMixed);
// continue;
// }
// }
// out.entities().emplace_back(ee->clone());
// }
// }
// chain_and_reorder_extrusion_entities(out.entities(), &start_near);
//}
//return out;
// Return a filtered copy of the collection.
ExtrusionEntityCollection out;
out.m_entities = filter_by_extrusion_role(extrusion_entities, role);
// Clone the extrusion entities.
for (ExtrusionEntity* &ptr : out.m_entities)
ptr = ptr->clone();
chain_and_reorder_extrusion_entities(out.m_entities, &start_near);
return out;
if (this->m_no_sort)
return;
chain_and_reorder_extrusion_entities(this->m_entities, &start_near);
}

void ExtrusionEntityCollection::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const
Expand Down
Loading

0 comments on commit c62503c

Please sign in to comment.